8 ms·
Selecting a platform: JavaScript vs Elm vs PureScript vs GHCjs
- wmfiv 10y agoIn addition to the options identified in the article definitely take a look at ScalaJS and ClojureScript. I've used ScalaJS quite a bit and it's a more or less flawless experience.
- pkasireddy 10y agoHow does ScalaJS compare to these other libs in terms of building browser UIs?
- edko 10y agoIt compares pretty well. It is possible to define Scala bindings to JS libraries, so you can use them more or less seamlessly. Bindings to the most popular ones (jQuery, React, etc.) are already defined, and actively maintained. It is relatively simple to add your own. A nice thing is that, since Scala is a strongly-typed language, you get code-completion and refactoring "for free". However, if you prefer to use dynamic typing, ScalaJS lets you do that easily too. Also, like the grandparent comment said, ClojureScript is a very nice language too, with powerful tooling. The nice thing about ScalaJS and ClojureScript is that they both can run on the browser, and on a JVM backend. Scala also has an LLVM backend that is being actively developed, but on its early stages. (ScalaJS is very mature and performant)
- paulddraper 10y agoWhen did every blog start having 22pt body and 62pt headers? Those are the font sizes I used as a 4th grader trying to write a four page essay with 500 words.
- cholantesh 10y agoVery distracting; makes me long for the academic style of sites like Kernighan's [1] or Stallman's[2]. [1] http://www.cs.princeton.edu/courses/archive/fall14/cos109/ http://www.cs.princeton.edu/courses/archive/fall14/cos109/ [2]https://www.stallman.org/archives/2016-nov-feb.html https://www.stallman.org/archives/2016-nov-feb.html They'd be even nicer if the text was inverted, though.
- boubiyeah 10y agoHappy user of typescript here. imo, pure FP is just like pure OO: it's just not very good. Why constraint ourselves? The world is not pure, our programs don't become ANY better because of the IO monad (Task in Elm); Let's stop wankering or at least, just do it for the math and the research value but let's not kid ourselves it's very useful.
- daxfohl 10y agoYeah, being a math person I jumped on the pure FP bandwagon full time for four years. But my experience has been that in anything but pet projects, it gets to the point of replacing impurity with incompatible layers of abstractions to create the illusion of some minimal level of allowed impurity and awkward buggy glue code in hopes to hold everything together. Working with an illusion of impurity on top of purity isn't any better than working with impurity directly. Or in Greenspun's Tenth Rule Of Programming terms: Any sufficiently complicated Haskell/PureScript program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a Python VM trying to share state with an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a JS VM trying to communicate with an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a .Net VM. Anyway I like typescript now too.
- bfung 10y ago"...in Greenspun's Tenth Rule Of Programming terms...slow implementation of half of a .Net VM"... ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.[1] So we're back to FP... =P 1. https://en.wikipedia.org/wiki/Greenspun's_tenth_rule https://en.wikipedia.org/wiki/Greenspun's_tenth_rule
- rubber_duck 10y agoAgree somewhat - I like the balance something like clojure and F# strike, immutability and high level abstractions by default but interoperability with OO and imperative code as needed - if they fit your problem domain they can be a huge productivity boost - typescript still has that C#/Java style verbosity when doing data manipulation and all the pitfalls of shared mutable state + all the pitfalls of insane JS semantics.
- leshow 10y ago"TEA is not composable, but through brute force. ... you are stuck building and maintaining some giant types, and writing a ton of boilerplate. The ways around this problem are fairly weak, and amount to, “don’t write components” ..." This has basically been my experience with Elm. But don't say that Elm is boilerplate heavy to any elm-acolytes, they will stick their fingers in their ears and go "nananananana"
- deleted 10y ago[deleted]
- gjem97 10y agoCan you be more specific about what boilerplate is necessary?
- leshow 10y agoAnything that is usually solved with something like typeclasses, or module functors, or inheritance can only be solved in Elm with typing lots and lots of concrete implementations. Other things can't be solved at all, since Elm is so tightly coupled to TEA.
- hongbo_zhang 10y agoIt is very cool to see different type safe Alt-JS compared, I made a gist here which includes Elm, PureScript, BuckleScript and ClojureScript, add your favorite one here: https://gist.github.com/bobzhang/9f27a5a0bd730e8d3503bf5d058a58a7 https://gist.github.com/bobzhang/9f27a5a0bd730e8d3503bf5d058...
- sjrd 10y agoI added Scala.js in the comments.
- floatboth 10y agoBuckleScript (OCaml) https://github.com/bloomberg/bucklescript https://github.com/bloomberg/bucklescript is the only one that produces reasonable output that doesn't require large runtime libraries all the time. Koka https://github.com/koka-lang/koka https://github.com/koka-lang/koka is a very interesting research language that focuses on explicitly specifying effects in types. It even deconstructs Haskell's notion of purity into "throws exceptions" + "may never terminate". Unfortunately, the code generation (which BTW exists for both JS and C#) is uh… not very good. But honestly, I haven't felt the need to use a functional language in frontend development. JavaScript (ES6) is good enough, and it's actually supported in browsers, so you can develop without any compiling, and only use Babel to make production builds. If the project is not small, use TypeScript to add some type safety.
- deleted 10y ago[deleted]
- dhucerbin 10y agoCurrently I'm writing in Purescript but I'm constantly checking BuckleScript and I'm liking direction of it. What is OCaml polymorphism story? Does it have analogue of typeclasses? I'm currently using Purescript for writing build steps for webpack and I benefit from Haskell ideas like lenses, refolds and free monads. It would be great if I could transfer those tools. Maybe you could point me to some literature about transforming recursive data structures (ASTs) in OCaml? Maybe thera are some interesting tools and techniques?
- chrislloyd 10y agoI'd be very curious to hear about the OPs specific experience with Flow. I've found the opposite to be true of Flow vs Typescript with the added benefit that Flow is easy to integrate into an existing codebase.
- lloyd-christmas 10y ago> with the added benefit that Flow is easy to integrate into an existing codebase. I converted our Node codebase to Typescript and had no problems at all. I don't know much about Flow, but what is it that makes you think it's easy comparative to Typescript?
- mlmlmasd 10y agoBoth are pretty trivial to integrate, because you can essentially white-list the rules you want applied, but the documentation on how to properly do this is lacking for typescript in my opinion. There is also a lot of contradictory information on best approaches when using Typescript.
- tomphoolery 10y ago> Here are some reasons to not choose JavaScript: It’s JavaScript. Was this really necessary? I stopped reading your post after I saw this because I got bored and no longer take you seriously.
- keithnz 10y agoFrom a functional programming point of view, the fact it is javascript is almost the opposite of everything you tend to appreciate about your functional language of choice. So that simply counts it out for some people. However you an still do functional programming in js, and making use of typescript and ramda is a pretty good base for doing it. (well, this is what I do anyways). I find this a much easier approach when blending all kinds of javascript libraries together than using a cross compiler .
- graphememes 10y agoIt also makes the writer hard to take seriously. Low blows never shine brightly.
- iLemming 10y agoThe problem with Javascript is that it enables you many ways to screw up. Unless you already know how not to screw up, If you are a good functional programmer, like Brian Lonsdorf aka DrBoolean, then yes - you can compose some extremely mind blowing crazy stuff without shooting yourself in the foot. Languages like Clojurescript, Elm and Purescript are better simply because they enforce you specific discipline and that helps you to write arguably better code.
- Vinnl 10y agoExcellent overview. I wonder if the author also had a reason for skipping tslint, other than perhaps not knowing about it? Edit: Also, why do fewer and fewer sites have an RSS feed? :(
- dualogy 10y ago> Edit: Also, why do fewer and fewer sites have an RSS feed? :( Bit sad, that. Somehow it happened that a critical mass of bloggers/readers moved over Google Reader while during the same period all those social-feed web apps kept gaining momentum, then Reader shut off.. things can change like that over a decade or so. A 20-year-old today was perhaps 7-10 when XML feeds were hot currency. I'm still content with my numerous working subscribed feeds in Thunderbird though, can't catch up as it is.
- boothead 10y agoPurescript does have very workable solution for client and server sharing code: https://hackage.haskell.org/package/servant-purescript https://hackage.haskell.org/package/servant-purescript I'm using this with Halogen and it works great
- sk1pper 10y ago> I’m not even going to consider a system valid without managing IO in some way. So yes, all flavors of Lisp are off the table as well. We're talking functional in the context of JavaScript, I think ClojureScript deserves more of an explanation on why it doesn't even qualify. That is, if you're trying to hold to the "neutral as possible" thing in the beginning.
- pka 10y agoClojurescript doesn't have a way of managing IO (i.e. types.)
- retrogradeorbit 10y agoYep. And with that closed mindedness he cuts himself off from trying what IMHO is the best reactive front end ecosystem around today. That is one of the react based clojurescript frontend systems. Sorry, but your amazing, functional, pragamatic system is INVALID. Because I have deemed it so! Good one!
- iLemming 10y agoI agree - Clojurescript is extremely pragmatic, yet quite functional. Tooling is extremely nice, FFI to existing Javascript simple, can be used on both back-end and front-end.
- banashark 10y agoI'd like to put forth Fable as a recommendation. It was briefly mentioned in another comment, but was written off for it's lack of momentum, community, and libraries. I'll respond to these important concerns one by one: Momentum: The fable project began last year. There are still active discussions about tweaks getting it to v1.0, but already there is enough there to make complete applications. There isn't hackernews/reddit hype, but the gitter is busy and there are some using it in production already. Community: I assume that the concern with the community is that it isn't large. F# has never had as large of a community in any of its incarnations compared to mainstream OO-first languages, but the community has always been there to help me out and I've never gone more than a day or two waiting on an answer to a library/language question (most fable related questions are answered very quickly on gitter). The latter fact alone makes it more impressive to me than some other communities. Community is also important because of the amount and variety of libraries that are created for a language. I'd argue that this isn't as important for transpiled languages as it is for separate compiled languages, where for example a ruby library can't be used in python, but I can use any javascript library in fable. Libraries: Library usage is interesting when talking about transpiled languages, and mostly depends on the Dynamic and Foreign interfaces available. Because of Fable's dynamic abilities, I can dynamically call any javascript code I need to. I use this for a couple of libraries in the React-Native application I'm building using Exponent. The other method is Foreign interfaces, which is fantastic in fable because of how the F# type system (and inference) works in the first place. There is a utility to convert from typescript definitions to fable definitions (some will need tweaking afterwards for greater type safety) which adds a ton of libraries itself. I'd argue because of that fact that Fable has more libraries than any other functional-first transpile-to-js language! Here is a example repo I put up earlier with full-stack F# with live-reloading on the client and server. https://github.com/Banashek/Universal-FSharp-Samples https://github.com/Banashek/Universal-FSharp-Samples I'm using a setup like this on a current project deployed with docker-compose to digitalocean. Full-stack F# has been nice to work with so far. One really nice experience I had was being able to reuse viewmodels and their validators. Android/iOS -> Exponent Web -> Fable-Elmish Server -> Suave I had viewmodels and partial validation functions which could sit in a shared folder and be referenced by all of the projects. I change it in one place, and I can update all 3 instantly. All of the rest calls depend on the types definition, so I didn't have to do anything after adding a new property to the type and saving the document. The server reloaded, the frontend reloaded, the mobile app reloaded. I'm not sure If I'll keep it that way, as coordinating production updates is something I haven't fully figured out yet, but for now it's neat to explore. Would I recommend someone who doesn't know functional programming to switch their applications to fable? No. Would I recommend fable to someone familiar with functional programming looking for a better way to manage their ui? Yes.
- ruethewhirled 10y agoCan anyone explain what is meant by "managing IO" in the statement "I’m not even going to consider a system valid without managing IO in some way. So yes, all flavors of Lisp are off the table as well."? Is that like monads?
- damncabbage 10y agoIt means restricting to where you can perform IO actions, eg. printing to a log, writing to a shared area of memory, etc. Haskell does this by representing IO actions as values, eg. "IO String" (something like "IO<String>", for people more familiar with that syntax), representing an IO action that, when later evaluated, will yield a string that you can use in subsequent actions. Haskell's "main" (entry-point) function is a value of type "IO ()" (IO of a value representing nothing useful; you don't get anything out of it, so you just have a nothing placeholder). When a Haskell program is run, it ostensibly (hand-waving here) takes that IO value and interprets it, performing the action IO. You have functions like putStrLn (print a line) that takes a String, and returns an "IO ()" . Accordingly, if you have main = putStrLn "Hello, World!" ... you have a value that lines up with the expected return value of main "IO ()". More complicated examples, like main = readLn >>= (\x -> putStrLn ("Hello, " ++ x)) ... are doing the same thing (checking the types line up), just with more moving parts (the Monad thing you mentioned, which we're using to relate the "read line" function with the "print line" function). The key bit is that it's just "IO Blah" values standing in for IO actions, and like jigsaw pieces, these IO-returning functions only fit together where the types line up, restricting how you can use them. Monads are tangential to this; the type-checking of that jigsaw puzzle is what matters here.
- nilkn 10y agoI've recently used Elm for a real-world internal tool and was looking over the PureScript documentation today to see whether it'd be worth looking at PureScript in the future. I was disillusioned with the boilerplate of writing JSON decoders and encoders in Elm. I quickly stumbled across this: https://github.com/slamdata/purescript-halogen/blob/master/GUIDE.md https://github.com/slamdata/purescript-halogen/blob/master/G... This is pretty much the Elm Architecture, except fully understanding every detail there requires the reader to be conversant with some pretty hairy concepts, including free monads and the Free functor. That's not just something that's under the hood. It's built right into the user-facing API, and the user even has to tend to this free construction when writing `eval` functions by manually writing lines like `pure next` or `pure (continue value)`, which occur in the first example. It seriously concerns me that the user will have to write lines that they couldn't truly understand without understanding free monads, because frankly nobody new to Haskell and PureScript is going to be comfortable with free monads until they've spent some serious time with the language. I happen to be very well-versed in Haskell so this stuff is not an issue for me -- in fact the use of Free here is not only clever but kind of beautiful -- but I wouldn't really want to onboard someone onto a PureScript project who'd never used Haskell or PureScript before and didn't even know what a functor was. "Why do I have to write this `pure (continue value)` line? What does that mean?" -- "Oh boy... grab a seat and clear your schedule." Some boilerplate for JSON decoding looks pretty tame in comparison, to be honest.
- purescript 10y agoHalogen is not the only option for building web applications with PureScript. There are simpler options like Pux and Thermite, which are possibly much easier to teach. Halogen is optimized for a different use case.
- nilkn 10y agoThanks! Both of those definitely look more beginner-friendly or at least easier to teach. I'm going to have to look more into PureScript in the coming days.