top | item 4276625

The Fay Programming Language

157 points| nandemo | 13 years ago |chrisdone.com | reply

101 comments

order
[+] perfunctory|13 years ago|reply
The combined man-hours spent on producing various compilers targeting JS would be enough to:

  * Build the next generation browser that supports a proper programming language.
  * Write migration instructions.
  * Convince major web-app providers that they need to migrate.
  * Help with migration.
[+] jballanc|13 years ago|reply
Browsers don't need a programming language. Browsers need a standardized bytecode. The problem is, bytecode can have a significant impact on potential performance. So, as long as browsers are still competing on JS performance, they are actively disincentivized from pursuing standardization of a bytecode...
[+] mistercow|13 years ago|reply
I think you vastly underestimate the number of man-hours that some of those steps would take. I'm talking specifically about steps 1, 2, 3, and 4.
[+] gmac|13 years ago|reply
Nope.

* Lots of people are going to be on current and previous versions of IE for years to come, no matter how many hours you put in.

* People enjoy finding clever ways around constraints, and I'm not sure those same man-hours would be available for your alternative tasks.

* IMHO, JS really isn't so bad.

[+] jodrellblank|13 years ago|reply
And the combined person-hours spent on many non-essentials (from gardening to sun bathing to gaming) would be enough to solve world hunger, reduce human casualties in natural disaster zones to approximately nothing with notifications and infrastructure reinforcements, detect and stem disease outbreaks in days or hours, provide good public transports in all urban areas, and probably much much more.

Incentives matter.

[+] comex|13 years ago|reply
Problem is that there is no proper programming language - you will never find one language that even comes close to suiting everyone. Even a VM would be hard to optimize for all the different kinds of languages people would want to run on it, or at least people seem to think so:

http://www.dartlang.org/articles/why-not-bytecode/

[+] olavk|13 years ago|reply
Compilers targeting JS exist because it is possible and because people prefer various other languages. Replacing JS with another language would just mean people would write various compilers targeting this new language.
[+] VMG|13 years ago|reply
You can't convince people and companies with man-hours.
[+] bzbarsky|13 years ago|reply
The fact that you refer to "man-hours" makes me suspect you underestimate the magnitude of the problem.

The correct measuring unit for the things you're talking about is man-centuries (and not one, but several), as far as I can see, just for the first item in your list.

People have been making compilers targeting JS for several years now. Do you really think there are 200-300 people doing this full-time?

[+] it|13 years ago|reply
Not everyone agrees on what it means for a programming language to be proper, and that's unlikely to change.
[+] drcode|13 years ago|reply
This really looks fantastic: All code is run through the GHC compiler for static type checking and then translated to javascript. This means:

   1. It has full Hindley-Milner type inference
  
   2. It produces readable javascript that is reasonably debuggable
I could imagine using this for real projects in the near future.
[+] epidemian|13 years ago|reply

  > It produces readable javascript that is reasonably debuggable
The examples on the page don't seem readable and reasonably debuggable to me. The simple square definition:

  square x = x * x
Compiles into:

  var square = function($_a) {
    return new $(function() {
      var x = $_a;
      return _(x) * _(x);
    });
  };
Which, in turn, has all the "$" and "_" indirections.

This is basically why i think that trans-compilation to JS from a semantically very different language is not a good idea, unless a way of debugging _in the source language_ is provided. The success of CoffeeScript, i think, comes from it not differing too much from JS semantically; yes, it adds things like classes or everything-is-an-expression semantics, but the step of trans-compiling those things into JS is pretty trivial.

I hope the advent of source maps will help in the ease of use of these languages.

[+] Xcelerate|13 years ago|reply
A lot of people seem to be questioning whether we need a new programming language. Nobody needs a new anything most of the time. At least for me, I enjoy it when people create all sorts of new programming languages. It gives me a new way to try things and interesting insights into something I would have never thought about before. I think all of these languages that compile to Javascript are great.
[+] spicyj|13 years ago|reply
I don't know very much about Haskell, but this looks really great from a quick glance. I wonder how performance compares to plain JS – surely all the laziness and resulting JS closures have a cost.
[+] mekwall|13 years ago|reply
What do you mean? The performance will be exactly the same as if you implemented it in plain JS. The laziness and closures sure has an impact, but they fill their purposes and the resulting application wouldn't work the same without them.
[+] clvv|13 years ago|reply
I wonder if there're any plans to make it self-hosting. It would be more appealing if it can run in browsers and node like CoffeeScript.
[+] nandemo|13 years ago|reply
Not sure if I understand your suggestion... I suppose if one wants to write server-side code in a Haskell-ish language then one would simply use standard Haskell plus Yesod or another web framework.
[+] chrisdone|13 years ago|reply
I do have some plans to make a JSON Fay-in-JS-out service. Possibly with some “export compressed as .tar.gz” feature to give you a production-ready export.

It would even be quite cool to make a REPL and development environment, but that's a little far off.

[+] shaunxcode|13 years ago|reply
There is no reason it would not work in node and browser currently is there?
[+] fuzzythinker|13 years ago|reply
Instead of comparing to Roy/Elm, which I have never heard of (has anyone?), he should compare it to livescript, a fork of coffeescript that has quite a few syntactic similarity to Haskell (it's inspired by it).

http://gkz.github.com/LiveScript/

[+] tikhonj|13 years ago|reply
I think this is targeted at Haskell people looking to compile to JavaScript rather than JavaScript people looking to use a new language.

Roy and Elm are new languages that people who follow Haskell are probably familiar with. Comparing to them makes more sense than comparing to LiveScript if your audience is Haskell programmers.

LiveScript is not really anything like Haskell at all except in some entirely superficial ways. Even the syntax isn't all that similar. Essentially, it's a slightly more functional CoffeeScript. While certainly interesting to the same people and for the same reasons as CoffeeScript, it's not very interesting to people who primarily use Haskell.

[+] spacemanaki|13 years ago|reply
I've heard of Roy, and even though I know very little about it or about LiveScript, comparing Haskell to Roy immediately makes more sense than comparing it to a language that "has a relatively straightforward mapping to JavaScript."
[+] fuzzythinker|13 years ago|reply
I noticed the use of $, _, and globals like enumFromTo in the compiled js. It says $ means "thunk" and _ means "force". Does this means this compiled js further compiled so $, _, and globals are further replaced with something like Fay$$...?
[+] chrisdone|13 years ago|reply
Those two symbols are merely to make the code easier to read as there are a lot of thunks and forcing. Previously it was Fay$$force and Fay$$thunk.

Technically these are global within the Fay output, but that is all wrapped up in a closure, so it won't interfere with anything outside.

Additionally, _ is not a valid function name in Haskell, and $ (and any other non-letter symbols) are encoded as $123$ where 123 is the unicode point.

So these two symbols are free to use, if that bothered you at all. enumFromTo is defined in the Prelude.

[+] samstokes|13 years ago|reply
I think he's just defined functions called $ and _ which implement the thunking and forcing. No need for another compilation round.
[+] bdg|13 years ago|reply
Lovely article but I'd like to ask that we call things that "compile to javascript" transpilers. JS is not "web assembly" and if we keep communicating that message in the community it will be believed to be.
[+] tree_of_item|13 years ago|reply
Projects like this are motivated by a belief that JavaScript _is_ web assembly, though.
[+] yoklov|13 years ago|reply
I disagree, as that's silly, and semantically incorrect.

Calling the Fay compiler a "transpiler" would imply that it is a source->source compilation, like CoffeeScript.

From what I can tell, it _actually compiles some of Haskell to JavaScript_, so the term does not really apply.

Besides, what's wrong with JS being web assembly? You like JS? Fine, use JS. Nobody is taking that away from you.

[+] postfuturist|13 years ago|reply
What's wrong with calling them compilers? Compilation does not imply an assembly language target.
[+] it|13 years ago|reply
This is great. Now Haskellers can not only develop in a single language on the browser and server, but it looks like this could make it possible to leverage existing Node.js code on the server side. chrisdone, is there anything more that needs to be done to support using Node modules?
[+] angeladur|13 years ago|reply
What does getSquare (Math _ square _) = square mean?
[+] chrisdone|13 years ago|reply
That's a pattern match. Math is a data constructor, it makes a Math object. It takes three arguments. So (Math 1 2 3) is a Math object.

A pattern is a way of deconstructing an object into its constituent parts and bringing some of those into scope.So (Math x y z) is a valid pattern, which would bring these values into scope: x=1, y=2, z=3. In this case I'm bringing only the second argument into scope. In a pattern, _ means "ignore this argument".

Here is a short interactive lesson on pattern matching: http://tryhaskell.org/#19

[+] notime|13 years ago|reply
Hearing the words "compiling to Javascript" here, from Google, and elsewhere drives me nuts. Generating code in a dynamic and uncompiled language is NOT compilation! It is just a type of translation. If you want to make up a word, call it "relanguifying"- I don't care- just don't call it compilation.
[+] edsrzf|13 years ago|reply
Wikipedia describes a compiler as "a computer program that transforms source code written in a programming language into another computer language".

That certainly seems to describe what's going on here.

[+] chipsy|13 years ago|reply
Compilation does not have that meaning.
[+] combataircraft|13 years ago|reply
Very cool except it has no NodeJS example. By the way, JavaScript does not suck. It has module and package systems, check out NPM, and OneJS for using all NodeJS utilities in client-side; http://github.com/azer/onejs
[+] jerf|13 years ago|reply
"Very cool except it has no NodeJS example."

Fay will never be used for Node.js. If you're going to write Haskell to run in a multithreaded code environment, you'd simply run it in the superior-in-every-way GHC runtime, which has proper 21st century support for a wide variety of modern concurrency constructs, instead of warmed over event-loop ideas from the 1980s. (Or 1970s.) Haskell : Node :: Node : raw select loop code.

[+] almost|13 years ago|reply
Of course it sucks, in lots of ways. That doesn't mean it isn't also good in lots of other ways. Don't get so attached to your tools, recognise that most things suck in at least a few ways and life will be easier :)

Once you recognise the suckyness you can start thinking about ways it might be reduced. You can also start reasoning about whether things that reduce some dimensions of suck are worth the cost of the other dimensions of suck that they increase.

[+] chrisdone|13 years ago|reply
Technically the console.hs example works in node, and node is how I test Fay and run my test suite and benchmark. Example:

    $ fay -autorun examples/console.hs
    $ node examples/console.js
    Hello, World!
You're free to use it on node if you like.