GHCJS - Haskell in the Browser
weblog.luite.com
weblog.luite.com
Nice thing about Fay is you can read the generated javascript and see the 1:1 correspondance to the haskell code. This can be a nice way to get an intuition abvout how thunks are used to implement eg, infinite length lazy lists in haskell. There is also a live IDE <http://ide.fay-lang.org/>. I think this makes Fay an excellent teaching tool.
The way it seems to be shaping up is that ghcjs will be used for big serious projects where a javascript runtime that is measured in (IIRC) megabytes is acceptable and the full power of haskell is needed. While fay will be used as glue code for projects that are mostly written in server side Haskell and want to run some code in the browser, with access to the same types used on sever-side to eg, make AJAX nicer. Fay's entire runtime is 16 kb (unminified; with minification and other size optimisations a complete program can be as small as 3 kb) <https://github.com/faylang/fay/blob/master/js/runtime.js> which makes it work well in these niches.
[1] http://www.haskellforall.com/2012/05/scrap-your-type-classes...
data ApplicativeI f =
AI { pure :: forall a. a -> f a
, ap :: forall a b. f (a -> b) -> f a -> f b
, _FunctorI :: FunctorI f }
data MonadI m =
AI { bind :: forall a b. (a -> m b) -> m a -> m b
, _ApplicativeI :: ApplicativeI m }
return :: _MonadI m -> a -> m a
return (MonadI { _ApplicativeI = ApplicativeI { pure = fn } }) = fnFor the folks who swear by static typing, I expect core.typed will eventually provide that: http://github.com/clojure/core.typed
Turing completeness → computation, but the converse is not valid (i.e. computation → Turing completeness is not necessarily true). e.g. GADTs allow for some amount of type-level computation, but they do not in and of themselves form a Turing complete system.
Alas, looking at your link, it does seem that Haskell's type system is sadly Turing-complete.
I don't know if I feel joy or sadness, but I have the feeling that if type level computation is allowed, then it's better to be turing complete than falling short while giving the illusion to be useful.
As for the practical applications of a powerful type system, I know about this (but I would be interested into finding more examples, as most of the information about that is very theoretical):
http://hackage.haskell.org/package/HList (http://userpages.uni-koblenz.de/~laemmel/TheEagle/dl/Kiselyo...)
(Although Haskell also has type-classes which make my statement not quite true)
It is true that Haskell & its type system evolve together whereas core.typed must follow Clojure wherever it may go.
I think ghcjs does have a traditional runtime of a sort, but don't quote me on that. :)
We haven't really spent much time optimizing for code size yet, and there's still lots of low hanging fruit. We will never reach 3kB minified though, for example the JSBN library (that we use to implement Integer) alone is a lot bigger than that.
The GHCJS linker does tree shaking: Only functions that are reachable from main are included in the result. We have some plans to extend this a bit, an old version already had incremental loading, but that has not yet been implemented for the new code generator.
Ahh, so does this mean we can shake out entire libraries like JSBN if we avoid using Integer?
Currently non-Haskell dependencies are managed per package, so if anything from integer-gmp is linked, it will include the whole JSBN.
If you want to weed out the unused JSBN part, you can use closure compiler (although the new code generator will probably still have a few incompatibilities with it).
But Integer is really hard to avoid in general, for example the Show instance for Double depends on it.
Also threading in Haskell isn't a first-class thing. I'm not sure what you mean by that. How does one omit threading if it's not really part of the language spec to begin with? Care to expand?
Not the OP but I can't resist answering. Threading isn't really part of the language proper, but as a lazy language can make flow control from language or library indistinguishable that isn't a very important distinction.
What matters is that GHC has an excellent threading implementation in its runtime and that the compiler has the primitives to build the Haskell concurrency libraries on.
Truly awesome and very promising.
GHCJS currently uses a trampoline, but all calls are in tail position, so when this gets implemented we can easily generate code that uses native JS tail calls.
Like GHC, GHCJS uses its own stack for non-tail calls.
Trampolines still work, albeit with a pretty substantial perf penalty.
Manual tail calls can perfectly well be implemented without breaking anything.
http://hackage.haskell.org/trac/ghc/wiki/Building/CrossCompi... https://github.com/ghc-ios/ghc
As someone who is very familiar with purely functional languages and with multiprocessor synchronization, I must ask, why would anyone want to use any of these things in Haskell? Aren't two of the primary benefits of Haskell the ability to auto-parallelize, and not needing to reason about state?
Haskell is actually quite good at it, and jokingly referred to as "the world's finest imperative language".
Luite also has a vagrant image available that has a working ghcjs patched build available for down load.
Unfortunately, GHCJS is not quite Safe Haskell code, so we are still working on sandboxing the compiler with SELinux.
his weblog, more updates will follow: http://parenz.wordpress.com/