Coming from languages like Actionscript/Javascript/Typescript/PHP I have found the whole Elm experience quite mindblowing; if it compiles, then it just seems to work. I hardly ever find myself poring over bits of code trying to debug a subtle error, and if I do the problem is going to be in the Javascript/Typescript bit.
Basically, I'm sold :)
That's exactly been my experience with Elm.
For example, on a web project I had been working on I decided to add the 'search' feature; the very first change[1] actually worked! This is generally not possible with JavaScript.
[1] https://github.com/srid/chronicle/commit/4a6c18147bf1596b234...
This. I spent the first 14 years of my career in statically typed languages and only this year began working professionally on a Rails app... I really miss the compiler.
C++ on the other hand compiles stuff that may or may not work at all, it doesn't care, which can lead to all sorts of undefined behaviour down the road.
Compilers are not all created equal.
You might also be interested in Elixir which ties in to the Erlang ecosystem, but if you are super into OOP (like me) you might find it slightly more difficult, but since you have experience with static-types, you probably know some FP stuff, and so it's not that bad.
Either way, best of luck. It takes a brave soul to fight with Rails. I've been writing Ruby for about three years now and still haven't touched Rails just because I can imagine how little fun it is to try and debug dynamic-typed web stuff. Noooooo thanks.
My mindblowing experience was facilitated by referential transparency where I had a page of code that became half a page after extracting some functions and restructuring the code and then have that half page collapse into several lines of boring code because I realized that the functionality can be re-expressed in terms of standard functions.
It is amazing to be able to think about an entire branch of code in isolation and be able to understand it in its entirety.
TL;DR its pretty easy once you've done it a few times
You can post and receive messages from ports (depending on type). Type checking is done at runtime to make sure nothing breaks.
Cljs interop is easier (can just call a function directly).
In 0.17, commands and subscriptions mean that, not matter how deep you nest components, you can still send and receive messages to/from the outside world (i.e. ports).
So first person experiences like yours help me continue and understand where I can be if I continue on the path I am.
Also, I would like to add that I really liked Signals and felt that they are good abstraction, but looking at Subscriptions and they also on surface level make sense.
Perhaps you are using Elm to compile to HTML / CSS / JS which Cordova compiles to native code?
My mind was blown but never really got enough time to study it since it was low on my priority list.
I think you just pushed it to #2!
> Note: Interested readers may find Lucid Synchrone interesting. Unfortunately for me, I had no idea my thesis had so much in common with synchronous programming languages at the time, but the connections are quite striking. I might argue that Elm was never about FRP.
My thesis was related to synchronous programming languages and articles about FRP tend to have too little to say about them, for my taste. Yes, there is a word or two in the related work, but also it looks like some wheels are being reinvented.
The subscriptions model reminds me of Esterel, which is imperative and uses await/emit pairs. In the domain of GUIs, which is related to Elm, there is ReactiveML (see "ReactiveML, Ten Years Later" (https://www.di.ens.fr/~pouzet/bib/ppdp15.pdf)). Look also at Lustre or Signal, with Signal allowing directives to define multiple execution units: this is used to generate concurrent programs exchanging values with message passing.
The domain is different, though. Synchronous languages do not target web interfaces. They are about embedded systems and as such, they are mostly static. On the other hand, they are compilable into a simple event loop with static memory usage and constant execution time. Maybe some of the existing research could be useful to something like Elm, even if it does not target the same problems.
The two languages I was most interested in were Lustre and Esterel.
Synchronous Languages for Hardware and Software Reactive Systems, Berry
Designing Embedded Systems with the SIGNAL Programming Language, Gamatié
The Synchronous Languages 12 Years Later (http://www-verimag.imag.fr/~halbwach/PS/iee03.pdf)
There are some resources at Verimag (http://www-verimag.imag.fr/Tempo,32.html?lang=en) and the Esterel website (https://www-sop.inria.fr/meije/esterel/esterel-eng.html). You can search the HAL database too (hal.inria.fr) and maybe have a look at SCADE (http://www.esterel-technologies.com/products/scade-suite/).
Then you can try it yourself.
What would you expect them to say exactly? Synchronous languages are first-order reactive programming, but FRP is about higher-order reactive programming.
Not only is the elm code I write reliable, but I've found that adding more features does not bloat my code. Refactoring a codebase as it grows in elm is pleasant, and following the Elm Architecture guides me on the correct structure for the app.
Over the weekend I made a small site to show all Elm conference videos in one place. If you want to play around with 0.17 this project is just a bit above a "Hello World" example. Send a PR! https://elmvids.groob.io/
Last time I tried Elm, (1 or 1 1/2 years ago) tutorials and docs were kinda outdated. Got errors in this REPL thing they got for beginners on the webpage and nothing from the examples worked :\
Rx.Observable.fromTime().subscribe(tick)
Rx.Observable.fromSocket(mySocket).subscribe(handleEvent)
https://github.com/Reactive-Extensions/RxJSRegardless of the exact library or pattern, the broader concept of treating data sources as asynchronous event streams you can subscribe and react to definitely simplifies data flow and makes systems very robust.
An additional benefit of this pattern is the natural way it makes it easy to filter, chain, map, etc onto these subscriptions. Once again from the Rx world, http://rxmarbles.com/ does a great job visualizing these patterns.
When ELM came along with its signals, im like, meh, why not Rx? Im not even going to bother to learn it, your at v0.1 and ur gonna see why u need it soon enough. Subcritiption? Dont reinvent the wheel like Redux? Why not Rx? A few months later, everyone is going "how we we handle async actions properly?" Well thats an Observable my dear friend!
Just like when Flux "came out". They just rebranded Event Sourcing in the client UI.
Im getting pretty fed up with all this mumbo jumbo. I write C# mostly, i like FRP, ES, unidirectional flows. Im going to bring a slim universal c# solution with a typescript/JS bridge to the OSS community. The main philosphy is, one client/server architecture, to build scable responsive apps. With builtin backpressure handling.
If ppl had just embraced Rx like 6years ago when it was first V1'd, imagine how much further along the road we would be now? Like seriously, get over urself OSS fanboys, just cause its MS, doesnt mean its bad.
These Elm subscriptions sound like "half" of Rx, and from what I can is still 'missing' thus far some of the "higher order" Observable tools such as filter, chain, map, throttle, et al.
I also offer an analysis of "higher order" observables in https://youtu.be/DfLvDFxcAIA, and the big difference is the underlying thread architecture you get using these two.
I hope I'll be able to make these sorts of things clearer in time!
I'd love to make the Elm jump, but it still has the Haskell stigma (not enough engineers making hiring difficult, too 'academic', etc) where my clients (enterprise) won't let me dev with it. They do however let F# in some projects. MS should do what they did for OCaml -> F#, but for Elm -> something_I_can_say_is_first_party_MS_supported.
In ClojureScript, we have the re-frame pattern/framework, which is built on Reagent, which is a ClojureScript wrapper of React.
re-frame is all about subscriptions, using a "big atom" to hold application state client-side. Seeing Elm implement the same subscription pattern makes it look pretty tempting.
My understanding is that ClojureScript and Elm have some similarities - functional, pleasant to work with - with one significant difference being that Elm is typed.
Wondering if you could make a lisp where `lambda` or `fn` required type annotations, such as
(defn add
[int -> int -> int] ;; type annotation
[x y] ;; arguments list
(+ x y))
Then it would be homoiconic - something that has saved me hundreds of lines of code (and the less code, the less bugs as a rule of thumb).Then every function down to the very basic lisp functions would have types. Dunno how doable this is - but it doesnt matter. Someone implemented it in Common Lisp in the 80s I'm sure.
[1] https://docs.racket-lang.org/ts-guide/ [2] https://github.com/clojure/core.typed [3] https://github.com/plumatic/schema
A Lisp with types, built-in Prolog, optional lazy evaluation and more. It scratches my Lisp/Haskell love affair.
(defun foo (bar)
(if (numberp bar)
(car bar)
x))
should error out in SBCL because BAR is a number but CAR takes values.…
> Someone implemented it in Common Lisp in the 80s I'm sure.
Even better, it's a standard part of Common Lisp: functions default to being 'typed' to take the universal type, but annotations can be used to declare any types you want (to include types like (integer 3 27), which specifies an integer between 3 and 27), which can be compiler-enforced.
I really don't understand why Common Lisp doesn't see more use. It's modelling clay for computation.
\* add.shen *\
(define add
{number --> number --> number} \* type annotation *\
X Y -> \* arguments list *\
(+ X Y))The re-frame readme is epic and worth reading just for its own sake: https://github.com/Day8/re-frame
Not to get off-topic though! I am used to working with dynamic languages, but I really should work with a typed language. Elm looks like it offers many of the benefits of ClojureScript, but with typing as well.
Also, ClojureScript lets you write HTML and CSS in your code, but a quick web search indicates Elm may have gone further with incorporating CSS (?).
It feels like it's stabilizing. I expect that over the next year or so this will change dramatically and it will become much more community driven.
If you go to http://elm-lang.org/ they make it looks like its production ready. No mention of breaking changes/beta ect. You have to choose one or the other .
much better than having bugs sneak up on you in production
Dropped elm for react and co. Now I have serverside rendering, code splitting, working debugger ect which was impossible with elm.
This was last year though so not sure if it is still the process. YMV.
And for everything else, there's Ports. You can't use them in libraries, but for your own projects they're a much better JS FFI.
I've been doing backend work for a while and I'd like to see what is possible these days with elm.
On an unrelated note, I haven't found much prior work here but I think Elm on the backend (via Node.js) could be fantastic.
Since you mentioned NoRedInk, they had a sample project that bundled several available technologies: https://github.com/NoRedInk/take-home
It is worth noting that with the advent of 0.17, Elm on server is getting closer to reality. The issue now is for Evan to properly understand what the best approach is. My hope is that we will end up with something like Servant in Elm.
In a lot of things Elm is not aiming at WOM but WOFO. In other words, not for libraries that gets most word of mouth but libraries that get word of f-ing obvious. That requires a more deliberate and slower process but the payout is huge.
On a slightly more serious note, I wonder if Haskell and Elm are similar enough that model-style code could be written in a shared subset and run on both sides.
http://builtwithelm.co is a good place to start. My favourite big example is Dreamwriter (https://dreamwriter.co) by Richard Feldman. Warning not updated since e0.15.1 ~ https://github.com/rtfeldman/dreamwriter
If you haven't yet tried Elm, give it a shot. A co-worker (hi Heath!) showed it to me 4(?) years before I got interested in it, and I brushed it off as a toy because I was against Functional Programming at the time for terrible reasons. It's actually one of the 'this feels like the future' technologies that's re-shaping how I think about programming these days. Huge kudos for the release!
Time.every second Tick
vs. Time.on('everySecond', tick)
Beyond baking an event emitter into the Time module and having a nice looking API, is there something I'm missing?Things like:
* When an event/action/etc comes through, does it always call listeners synchronously? Can you change that and schedule events manually?
* How do you compose subscriptions/event handlers? This is usually the hardest part, and where simple event emitters really start breaking
* What about the lifecycle of the listener? What happens when it subscribes or unsubscribes? More importantly, what happens when the source that it subscribed to "shuts down"?
All of these things get pretty complicated and is the reason why various fields like FRP exist. Simple event emitters work immediately, yes, but they are a pretty terrible abstraction to build an app on.
I really wonder if Elm got a generic solution that fits all possible usage scenarios.
So basically, the difference is in resource management. The web socket example makes this clearer. You never have to ask "who owns the connection?" to use the connection.
To be fair you can do this in javascript as well using a messaging pattern similar to elm. Many libraries like postal.js (synchronous) and msngr.js (asynchronous) support a messaging pattern where you can access resources without caring who owns them.
It turned something that is in real life difficult to manage, compose and scale, into something not just easy to grasp, but also simple to read and safe to execute.
Congrats on everyone involved in making this release happen.
> No runtime errors in practice. No null. No undefined is not a function.
> Friendly error messages that help you add features more quickly.
> Well-architected code that stays well-architected as your app grows.
> Automatically enforced semantic versioning for all Elm packages.
I am sure the new idea is good, but as grandparent said, the examples fail to convey why this is better than what we had before.
[1]: http://erlang.org/doc/apps/dialyzer/dialyzer_chapter.html [2]: http://elixir-lang.org/docs/stable/elixir/typespecs.html
Not sure it helps, it's on my todo list.
@spec foo[a: SomeProtocol & SomeBehaviour](a, a) :: a
I've also noticed that it lets through stuff that I would expect to fail to compile, so it's hard to trust as I would a type system like Elm's, Haskell's or Rust's. The Elixir devs have done a great job with the language, and it's great to see the resurgence of interest in BEAM as a result, but I still really wish they had taken the opportunity to build in a decent type system...Also, even if Elm were to get all that stuff, it'd still be compiling to JavaScript and aimed at web apps.
(Don't get me wrong, I'm super excited to see Elm getting support for message-passing lightweight processes. I love Elm, have used it myself for several projects, and think this looks great for web development. I just want something like Elm, but specifically geared towards large-scale backend services instead of front-end apps.)
"Making the Web Functional with Phoenix and Elm"
It's not, Elm doesn't use cursors and transactional mutations, I'd say the Elm architecture is closer to a pure single-store Redux: user actions are dispatched as Sub Action which are run through an update reducer (Action -> Model -> Model), which is then run through the view (Model -> Html) resulting in the new UI state.
"Synchronous languages are based on the synchronous hypothesis. This hypothesis comes from the idea of separating the functional description of a system from the constraints of the architecture on which it will be executed. The functionality of the system can be described by making an hypothesis of instantaneous computations and communications, as long as it can be verified afterward that the hardware is fast enough for the constraints imposed by the environment."
That sounds a lot like how functional programming works in a browser. If you assume function calls take zero time (or can be optimized so they're fast enough) then you end up with event handling and asynchronous I/O. Preemptive multitasking becomes a non-issue. But long-running computations (where you actually want to keep some CPUs busy for a while) need to be handled outside the system.
(Such was the case for my senior project, studying the viability of Arrowized FRP in Elm. In short, I concluded that it was nothing but hell and nobody should bother.)
I am happy to seem Elm drop FRP, even if I wished it could be the savior of the method. At this point I think it's a troubled concept and should be limited to old theses.
[edit] Looks like a solid change driving Elm towards easier usage, Signals and Mailboxes were definitely something that took a while to wrangle correctly.
I will say that Elm is the best JavaScript-targeting platform I have tried! I have hopes for GHCJS, but it's not near Elm's level of readiness yet.
Moreover, Tasks are absolutely monadic, with `andThen` being the bind operator. Elm just chooses to focus on the individual use-case, as opposed to focusing on the broader abstraction.
Which abstraction does elm use? As far as I can see, there is no abstraction. This is the problem. Effectful code in elm looks syntactically just like pure code.
Also, I'm still new to FP, so if you go outside of the Elm architecture, you're going to run into problems, which you're use to solving with specific tools, but they won't be available. So you'll have to spend time learning how to compose things in a new way.
Strange, because debugging subtle state errors seems far more time consuming to me than fixing compile-time errors. You have to launch debugging sessions or insert logging commands and step through reams of code, where compile-time errors tell you exactly where the problems are.
However, when it runs, it usually does work. I think I'm just not as use to structuring my programs in FP yet.
This is a very good change for Elm.
Instead of cobbling together disparate libraries for a virtual dom (React), state (Redux), immutability (Immutable.js), and types (Flow / TypeScript), the entire language and its core libraries are developed as a holistic (but still modular) unit. In this way, Elm is the BSD to JavaScript's GNU/Linux.
Strong typing and immutability are baked directly into the core language, elm-lang/html includes an efficient Virtual DOM, and Redux-style action / reducer cycles tend to naturally arise from "The Elm Architecture," and don't need significant support beyond what's already in the core language.
If you've bought into the React/Redux paradigm, it's worth giving Elm a shot: the entire language and core libraries are intentionally designed to more cleanly, reliably, and maintainably implement the same structure.
Is there X such that X is the Plan9 to Elm's BSD?
https://evancz.gitbooks.io/an-introduction-to-elm/content/in...
In the main article: "I do not expect to be compiling to JavaScript forever, especially with WebAssembly on the horizon. The smaller the interface between Elm and JS, the easier it will be to support other platforms."
While I don't want to sound doom and gloom, the JavaScript support according to article is anomaly of today's browsers. So if you want to rely on two parts JS and one parts Elm type of thing, it's good to know it maybe gone.
The course is still in development, but let us know if you're interested!
> gen/pages/blog/farewell-to-frp.html: getFileStatus: does not exist (No such file or directory)
Some caching problem, it seems?
If not, which parts changed / how would you revise it?
It's more that real programs need real effects: you need to send HTTP requests, read from user input, etc. Elm gives you a managed way to deal with those effects, while keeping the program declarative, and making as much of the logic side-effect free as is possible.
An Introduction to Elm
https://www.gitbook.com/book/evancz/an-introduction-to-elm/d...
> Use the browser API — To get started you just create a new web socket! Well, then you need to open the connection. But do not forget to add an onerror listener to detect when the connection goes down and try to reconnect with an exponential backoff strategy. And ......
How does handling errors happen I wonder. If you take FB messenger for example, you would queue up a message but if the sending failed you would get an opportunity to retry/not send it at all.
I suppose in FB's case you could write your own subscription provider...
According to Rx, it's the magazine company. Which one subscribes? The magazine company subscribes. It took me a while to realize this when trying to learn Rx concepts, which made it really confusing, since I've always seen the customer as being the subscriber, subscribing and owning the subscription.
It looks like Elm is the other way around compared to Rx, I think.
> When I started working on my thesis in 2011, I stumbled upon this academic subfield called Functional Reactive Programming (FRP). By stripping that approach down to its simplest form, I ended up with something way easier to learn than similar functional languages. Signals meant piles of difficult concepts just were not necessary in Elm.
The biggest difference is that the Elm version of "start a simple application" encapsulates more boilerplate, but I guess pux can do server-side rendering?
Examples of this would be web-socket , http-requests , etc.
however elm and cycle.js try to shoe-horn this idea everywhere - which I think is not needed.
Not every event needs to be subscribed to - it pollutes your global stream. Use global stream only when you need to deal with things that move out the execution context of your program.
I'm excited to give elm another shot, and I yearn for the future he describes where web assembly makes elm a viable js replacement.
These subscriptions from Elm kind-of remind me the signals and slots mechanism of Qt..