Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Haste language (haste-lang.org)
259 points by kruipen on April 2, 2014 | hide | past | favorite | 73 comments


Meta-comment: this is an excellently written landing page. All the comments about the explanation prose you usually see on HN when a language or library is introduced could be rewritten as "Make it more like Haste's landing page".


I think it says a lot about the web when a simple, mostly text-only page giving an accurate description of what something is gets viewed as excellent due to how uncommon it is.


Personally I think it could definitely do with some small code examples in between paragraphs. Makes me more likely to read my way through the whole thing, but also gives me the option of scanning the examples for something interesting and reading that paragraph first.

While on the topic of the landing page, it doesn't scale well in chrome on linux. I use two windows side by side and the navigation bar breaks around 938px width, which is just short for me.

The text itself is well written and clearly thought through though, with the right amount of detail.


Agree. If it had a list of "Awesome stuff made with haste" at the bottom, I'd be more inclined to proclaim it perfect. Perhaps it's just a matter of time!


I don't know. I think language landing pages look better with a little bit of code at least.


well... I mean it's Haskell.

code samples can really only give you a feel for the language, any more and it belongs in tutorials and API documents.


> In essence, Haste lets you write your client-server web application as a single, type-safe program, rather than two separate programs that just happen to talk to each other over some web API as is traditional.

I've been thinking about this same idea recently and find it very attractive. As programmers we don't explicitly control how our RAM communicates with the CPU; we let the underlying abstractions handle it. Why don't we have similar abstractions for when a client-side program (CPU) needs to access something on the server (RAM)?

Does anyone know of other tools trying to accomplish this? I'm not a Haskeller but am tempted to dive in just for this feature.


Ur/Web's [0] pretty obscure but also does this. As does Opa [1].

[0] http://impredicative.com/ur/

[1] http://opalang.org/


Isn't this exactly the idea of the big RPC suites from 10 years ago?

It is possible, somewhat, but you get very ugly web api's, because they are 'implementation before contract' instead of designing an api first, and then letting both sides adhere to it.


I would argue that GWT is an example of how it can be done, and it's very hard to beat a well-written GWT app (for the client-server part it's bloody hard to beat a badly written GWT app too).

The problem is that those ancient web api's were effectively javascript windows.forms emulators running on the client getting their calls from the server side. That, of course, sucks, because of the latency. Stuff that actually pulls your program apart into server and client pieces is beautiful.

The problem, of course, is that doing it the right way requires rewriting a compiler from scratch. Doing the "emulate the UI library and hang it behind an RPC" is easy, but sucks.

You get what you pay for.


"As programmers we don't explicitly control how our RAM communicates with the CPU; we let the underlying abstractions handle it."

Except for when we don't, because the underlying abstractions sometimes do the wrong thing. Random paper on cache-optimizing and the hassles thereof: http://research.microsoft.com/en-us/um/people/trishulc/paper...

The challenge is that even the memory abstraction leaks a little, and the network is nowhere near as fast or reliable as the frontside bus: "abstracting away" a 100ms+ link latency and/or nontrivial packet loss means hitting that leak much sooner.


This is a core philosophy of DerbyJS[0]. It even takes it one step further by rendering pages on both the server and the client.

I'd love to find out more about how Haste manages the intersection between client and server since it is capable of existing as a client-side only app. Hopefully it has a well defined API and writing plugins for different sources of data is clear and simple.

[0] http://derbyjs.com


I think it comes down to two questions:

(a) Does the abstraction actually lead to productivity gains in the long run, including time spent on debugging a possibly leaky abstraction?

(b) Does controlling these things manually enable you to provide a user experience that is sufficiently better to at least cover the costs of any lost productivity?

For any particular abstraction to be viable the answers need to be yes/no.

For abstracting away CPU/RAM communications the answers are clearly yes/no. But what are the answers for the abstraction that the OP referred to?


I think the main feature haste is providing is Haskell to JavaScript compilation. That will increase your productivity by

1. Enabling you to lean on the compiler when refactoring.

2. Decreasing the time you spend debugging.

The fact that it will split your program into client and server side parts is scary though, and interesting. I'll have to investigate further.


(a) Does the abstraction actually lead to productivity gains in the long run, including time spent on debugging a possibly leaky abstraction?

It does if you're able to share libraries between client and server. Writing one module for a particular data structure and using it on both client and server is a huge boon.


There are enough differences to warrant using different abstractions when appropriate. RAM never fails. Or, it never fails in a way that application code is expected to handle. RAM is cached, and cache is so fast that accessing small amounts of it is often negligible cost, and there's no need to count round trips. RAM is far less likely to be the connection point between different versions or implementations of an application. Are some examples.


Go play with ASP.NET WebForms, then do the same thing in any MVC equivalent. Abstracting away the way the browser and server and HTTP work just leads to painting yourself into a corner where changes that should be quick take waaayyy too long.

Who knows, maybe Haste will be different, but I really don't think so.


Ocsigen does something similar: http://ocsigen.org/tuto/manual/tutowidgets



Isn't the result of this class of solutions a service on the web that can _only_ (easily) be accessed by the client code that was specifically written to use that service (by virtue of being built out of the same lump)?

Doesn't that kill one of the best aspects of the web: client independence?


isn' that what GWT is?


What is meteor.js?



[deleted]


What is a leaky abstraction? Inevitable, I think.


I don't exactly understand why Haste was made into a separate dialect when it "just" has a different stdlib?

> with a different set of standard libraries

Is there a technical reason why it would be ill advised to just make Haste itself into a separate library that can be included into the regular Haskell ecosystem? Doesn't this type of fragmentation cause huge delays in the progress of a language, ultimately?

Hopefully it's obvious that I'm entirely not knowledgeable about these things and that I'd love for someone to explain this to me.


This is a definitional issue more than a technical one - if you follow the link to the Haskell package documentation [1], the project actually consists of aforementioned standard library, plus a Haskell-to-JS compiler. This is a "dialect" of Haskell in the same way that we can speak of the GCC and Intel dialects of C and C++ - both compilers support the same standard, but each supports a different set of non-standard extensions. In this case, the Haste front page notes that it supports most, but not all, GHC extensions to the Haskell standard.

[1] http://hackage.haskell.org/package/haste-compiler


I'm a bit disappointed this is getting so little response here. It's clearly trying to improve the state of the art of web app dev, and in a powerful language, to boot.

Do you really think we're going to be writing raw JS the whole time? The trajectory of computing has always been to build higher levels of abstraction, especially when the implementation technology is kludgy.


Haste is looking more and more awesome! However, we've taken the route of clojurescript/om for building on top of a Haskell web app. cljs just seems a bit more "there" as a compiles to js language. I would have loved to have used something like Haste or Fay, but for right now (taking a deep breath and giving up the type safety) I think the clojurescript eco-system looks the stronger for functional programming in the browser. The browser repl from emacs/lighttable is also a pretty impossible feature to beat!


So out of all these options for Haskell (http://www.haskell.org/haskellwiki/The_JavaScript_Problem), what's currently got the most momentum behind it?


My impression is that Fay has been in (at least moderate) use the longest. GHCJS seems to be getting a lot more viable lately. Elm (which is only Haskellish rather than fully Haskell-compatible) isn't listed on that page, but is getting quite nice.


I usually hear that Haste produces the nicest target Javascript and GHCJS perhaps the worst... but GHCJS will probably continue to get more momentum.


Does anyone know of any well-known applications that are using any of the various Haskell -> JS convertors?

It's not useful information regarding the usefulness of this but I am curious.


Elm is a "Haskell-like" to JS compiler, and implemented in Haskell. It's used at Prezi [1], a company that was impressed enough by it to hire Elm's lead developer to work on the language there, and probably make use of it for their site.

[1]: https://prezi.com/


I've been thinking for a while about reimplementing a large CoffeeScript (horrible language) project that we have at my work in Haskell, just to see if it could work, how easy it would be, how much smaller it would be, and if I could get the same or better performance out of it without going crazy. One of the demands of the existing software is that it both run in the browser, and server-side. This project is awesome because I could reimplement it in Haskell, and run a binary version on the server, with a JS version in the browser. Very cool! Now if I could only convince my company to switch...

By the way, on the "Try Haste" project, it would be nice to see the generated JS output, as they do on the "Try CoffeeScript" page. Even though it's not really meant to be looked at in javascript, it's informative for those who know a bit about both languages to see what kind of transformations are taking place.


Youre probably well aware of this but I do gather that:

One of the biggest problems with coffeescript is that when you are troubleshooting production code you need to decipher the generated JS back to what was actually written in coffee.

It strongly suggests haste will present the exact same problem perhaps in greater scale.


If you're still suffering that pain you need to switch to better build tools. Source map support is pretty mainstream now.

If I open Chrome Dev Tools on my production site, it automatically grabs source map files from my server (accessible only to me), and I see the whole source tree of original coffeescript files, with complete access to breakpoints and stack traces.


With the kind of guarantees that Haskell's type system provides, I'd imagine that wouldn't be much of an issue. It's certainly an issue in CoffeeScript because that language has barely any more safety than JavaScript. Once the Haskell were compiled, the generated JavaScript would be necessary to read in the same way that the generated object code is when using GHC - that is, essentially never. I never use the debugger in Haskell, anyway, and I don't think most do. The type system and a strong suite of tests will suffice for most things. Although I'd be concerned about laziness, especially in a language without Haskell's GC.


http://ocsigen.org/js_of_ocaml/ is a similar project for OCaml.


My big worry here is debugging. With, say, CoffeeScript, my code translates trivially and it's easy to map my JS back to the source. But it seems like it'd be a lot more complicated here. I'd love to hear the perspective of someone who's used this for real -- was that an issue?


It's important to stress that JS is really just the target language "instead of ASM" for Haskell-to-JS compilers, not just a convenient preprocessor. Development happens in Haskell (or Core, an intermediate representation, "the final human-readable step before compilation") land, and very rarely in the JS (or ASM).


But bugs happen everywhere, and I don't expect Haste to abstract and fix all possible browser bugs. When <experimental feature X> changes subtly and you get an exception, how do you track it down? How about when the browser just freaks out and inserts a NaN in a place type safety says it can't?


Whatever the cause - code, compiler, browser - what you have is a NaN in the wrong place, so the usual techniques apply: Test your code (which usually consists of fairly small functions) using Haskell's excellent testsuites, figure out error location with Debug.Trace, etc.

In the end, this is like asking what happens when the assembler "freaks out" (inserts 0 at a random location), or your architecture is wrong (Pentium FDIV bug): things may become difficult. (There is no type safety to help you on the JS level, much like there is no type safety in machine code. When you insert a wrong value, your code will misbehave in an unpredictable way.)


Except that such things happen a lot more often on browsers. And "softer" errors, like experimental features being subtly different because user X toggled checkbox Y (which you don't know about and cannot reproduce) are not going to be caught by test suites.

They can be caught by client-side crash logging / reporting. But if they're useless, you just lost the ability to fix bugs you don't see yourself in your nice up-to-date dev environment. These bugs happen with surprising frequency in any reasonably-used site.


I've used Elm a fair bit which is, in many ways, similar (compile-to-JS, statically typed, purely fuctional language). Between expressive types, a REPL, etc., I have never felt compelled to try to debug the generated Javascript.


Well, ghcjs, a "competitor" to haste that has even better ghc compatibility, is slated to have 2-3 student projects this summer to write some pretty amazing profiling / debugging tools


Yeah, I'm all in favor of compiling better languages into Javascript, but it requires a degree of maturity and completeness from the surrounding toolchain.


This is interesting (and exciting). I would love to see an implementation of TodoMVC (http://todomvc.com/) in Haste.


How is it more useful than Yesod (http://www.yesodweb.com/) and other existing web app frameworks in Haskell?


Presumably because you can write in-browser apps that you would typically write in JS, in Haskell. AFAIK Yesod is just another web framework a la rails, django, etc.


Yesod does not compile Haskell to JS. It works well with Fay though (another way to compile Haskell to JS).

Haste is not "more useful"; but it's approach is quite different.

Read my other comment on this page for more info on the differences.


There have been attempts to integrate fay[0] (a similar attempt of Haskell -> JS like Haste) with yesod, but it hasn't gained much traction.

Yesod is server side, it has Julius, but that's just JS with safe inserts from the outside.

[0]: http://www.yesodweb.com/blog/2012/10/yesod-fay-js


Haste is a great approach to compile Haskell to JS. But I yet have to play with it...

I did play with an alternative approach Yesod+Fay; where Yesod is the webframework and Fay the compiler of Haskell to JS. This approach is a bit more traditional in sense that the server-side app and the client-side app are separate (with some code shared by both).

I wrote a blog on how to get a Yesod+Fay example app setup on a recent Ubuntu:

http://www.hoppinger.com/blog/haskell-in-the-browser-setting...

With Haste the server-side and client-side code live side-by-side in the same files. I "got it" by reading this code:

https://github.com/valderman/haste-compiler/blob/master/exam...

For what I understand Haste does client-sever communication over websockets and yields webapps that are full-JS (therefore difficult to do SEO).

I often read the people are afraid of debugging with compiled JS; I must say that since I need a lot less debugging when using when compiling Haskell to JS. So far all my debugging needs are fulfilled with simple print/alert/console.log statements.


This is one way to use Haste but you can also use it similar to how you are using Fay. It does not yet have plugins like Yesod and Snap do for Fay.


In the example you posted it shows an HTML page which I guess would be an easy place to put your SEO content.


    While a certain increase in code size over hand-rolled Javascript is
    unavoidable, an optimized but uncompressed Haste program is normally less than
    3x the size of an equivalent hand-written program, making the latency penalty of
    using Haste minimal.
A type safe environment is most useful for large(r) applications; you don't really need it for your 200 or 2000 SLOC jQuery script.

But larger applications quickly grow quite a bit, reaching a megabyte or multiple is not uncommon in the land of GMail and similar apps.

Growing your JavaScriot "binary" size by a factor of three might be a problem for such applications. It doesn't sound that much, but the difference between download, parsing, and running 1 MB of JS vs 3 MB of JS is several hundred milliseconds on a very good connection and a beefy desktop machine.


We use Fay at FP Complete, which produces similar sizes as Haste, and our 15K line Haskell codebase compiles down to 1.3MB plain text → 386K through uglifyjs → 36K gzip'd. Actually, Haste uses GHC's STG backend, which desugars and greatly simplifies, so it should output code even smaller (and more efficient) than Fay. It's true that parsing is heavier when you go above the 1MB range. When I open plus.google.com my browser temporarily freezes, and I'm on a recent MacBook Pro. At least transfer-wise, generated code compresses well because it's the same repeated patterns over and over which gzip is good at. In the end, though, we prefer the issue of "our page loads a bit slowly, how can we compress or segment our .js files better?" is a much easier and isolated problem to solve than writing such a big codebase in plain JavaScript.


Thanks Chris, that is interesting.

BTW, I am a happy customer of FP Complete. I have bought four Haskell books in the past, but Haskell has never really clicked for me (but studying Haskell has helped using Clojure). Whenever I get some free time I use your IDE and online lessons. My hope is that by the time my one year subscription is up, that I will be comfortable sometimes using Haskell instead of Clojure or Java on large projects.


Hi, Mark. I'm curious at what point Haskell lost you, if you can identify that. I'm asking, because I'm also learning Haskell at the moment, but because I'm also interested in teaching and I'm thinking about how certain topics could be taught better.


The "problem" I have had has been not setting aside enough time to use Haskell exclusively for a while. I need to do one reasonably large project in Haskell, which is a problem in setting aside the time.


I have the same problem with Agda and Idris. ;-)


Should really have a link to the great examples: https://github.com/valderman/haste-compiler/tree/master/exam...


Was the Haste site made with Haste? The top links do nothing when viewing it on my (somewhat older) phone so I'm curious how well sites degrade in different browsers and devices.


It looks like: http://haste-lang.org/main.js

...and yes, I tried disabling JavaScript and it doesn't work.



That code... so much function.


Yeah, I visited it on my windows 7 phone and it didn't work out.

Makes me not want to use it professionally.


These layers upon layers just seem painful to me.


Then you may want to consider staying out of the software business. It's layers all the way down.

The relevant question is only how leaky each layer of abstraction is.


What exactly is the use-case for this? Can't quite get it from the site.


Making a JavaScript app with type safety guarantees. Also the pleasure of haskell in general. Same reason people use CoffeeScript. It compiles to JS, but you get several advantages of not using JS directly. Either syntactical, or abstraction of idioms.

Haste of course goes WAY further than CoffeeScript. But the rationale is the same. I enjoy writing Haskell much more than JS. If I can write Haskell and convert it to JS, I'll do it every time.


It compiles a sizable portion of GHC Haskell to Javascript. Since it's a general purpose language, the use-cases are basically anything that requires some custom logic to run and interact in the browser.


See here for the general Haskeller's attitude to this: http://www.haskell.org/haskellwiki/The_JavaScript_Problem


I'm a bit baffled which part of "Haste lets you write your client-server web application as a single, type-safe program" is unclear to you.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: