
PureScript: a statically typed language which compiles to JavaScript - bpierre
https://github.com/purescript/purescript
======
paf31
PureScript developer here. Happy to see this here, and happy to answer any
questions.

~~~
alkonaut
Is there any particular reason why PureScript was designed with a single
number type (so no proper ints)? I know that's how JS sees things, but now
with a whole proper type system it would seem like we should have proper
numbers? I admit I haven't read the entire docs, is there a way to e.g. have
the type checker ensure a number field such as a year in a date isn't assigned
a non integer?

~~~
paf31
It has been discussed before:
[https://github.com/purescript/purescript/issues/396](https://github.com/purescript/purescript/issues/396)

The reason I have been against the idea so far is that an integer type is
easily accomplished using the FFI and user code. Here is one example (not
quite what you're asking for, but hopefully instructive):
[https://github.com/darinmorrison/purescript-
int64](https://github.com/darinmorrison/purescript-int64)

~~~
alkonaut
As long as it is efficient and compiler supported (I.e an int add ends up as
the proper instruction, and improper assignment ends up as a meaningful
compiler error) I think the implementation doesn't matter. Going to Natural
numbers and such feels like a separate topic from just having efficient and
type safe (modulo overflow) integers.

------
BinaryIdiot
Seeing these types of experiments are always interesting but just like
CoffeeScript it requires learning two languages instead of one [so you an
debug] which makes it a hard sale. Why not just write clean JavaScript? I know
many want to make JavaScript the assembly language of the web but JavaScript
is so much more complex than assembly I'm not sure that's necessarily a good
goal to have.

Granted I would love for more languages to be usable on the web; even if I
thought JavaScript was the best language it's always good to have competition
and alternatives. But I think that has to come through browser support. I
wonder how feasible it would be to generate some sort of byte code similar to
how Java and others work with the JVM.

~~~
Tloewald
I wish a fraction of the effort going into "fixing" javascript went into
fixing the real abomination: the DOM API (and CSS). Then everyone would
benefit, even people using Dart, Coffeescript, and TypeScript.

~~~
chadillac
I wish people would just realize that JavaScript isn't going anywhere and make
the effort to understand it instead of trying to gloss over the quirks of it.

Understanding the key parts of writing JS (closures, scope, GC, etc.) isn't
all that hard and it seems like more efforts are geared towards an abstraction
layer and/or framework than just learning the language in the first place.

I think it's syntax and familiar looking and feeling environment cheerfully
misleads people into thinking they are in a comfort zone, while they thrash
around throwing sand in their own eyes, albeit with a familiar looking bucket
and shovel.

~~~
samstokes
It's rather condescending to assume the only reason somebody might dislike
Javascript is because they didn't understand it.

~~~
bstrom
Condescending yes, but more importantly, entirely wrong.

------
rtfeldman
It's been picking up a lot of steam lately! Bodil gave a great talk on it at
Strange Loop last week:
[http://www.youtube.com/watch?v=yIlDBPiMb0o](http://www.youtube.com/watch?v=yIlDBPiMb0o)

------
romaimperator
Here's a gem to use PureScript files with Rails and the asset pipeline. It
let's you add and compile PureScript files similar to how CoffeeScript files
are added. [https://github.com/romaimperator/purescript-
rails](https://github.com/romaimperator/purescript-rails)

------
tisue
Saw two great talks about PureScript at Strange Loop last week, one by the
language designer, Phil Freeman, and another by Bodil Stokke. Both the
language and — almost equally importantly! — the accompanying book seem really
well done to me.

~~~
agumonkey
Indeed, the book covers a large set of very interesting topics without
ceremony.

------
giulianob
What's the advantage over something like TypeScript which is a superset of
JavaScript but supports types as well?

~~~
moomin
If you want types like Java, TypeScript's probably a good choice. However, if
you want the flexibility or the guarantees a powerful type system gives you,
TypeScript's not going to cut it.

------
noelwelsh
Typescript vs Elm? Fight!

(I.e. what are the relative strengths and weaknesses of these two "modern
languages targeting JS" offerings?)

~~~
gregwebs
I think you meant Purescript vs Elm. disclaimer: I have used neither.

Elm has its own package manager, not sure if that is good or bad!

The biggest difference is that Elm is almost incidentally a similar strongly
typed functional programming language and its biggest focus has always been on
FRP (functional reactive programming) to simplify UI programming in the
browser.

~~~
noelwelsh
Yes, I meant Purescript.

------
boothead
Just bought the book today ($10 is too low!). After a few nixos hiccups today,
so far so good :-)

------
derengel
From the project docs: "Generate simple readable Javascript" \- isn't this
more of a disadvantage than an advantage? the created Javascript code won't be
high performance, which matters a lot in mobile today.

~~~
paf31
"Simple readable JavaScript" as opposed to the sort of output you might expect
from compilers for other Haskell-like languages which attempt to preserve
Haskell's semantics. Certainly there are cases where using techniques from
pure functional programming can lead to poor performance (monadic recursion
jumps to mind), but it is perfectly possible to write fast code using
PureScript. And if you really need to squeeze out every last bit of
performance, you can always write code in JavaScript and use the FFI.

~~~
eru
What's monadic recursion?

~~~
paf31
Consider a recursive function like factorial:

    
    
      fact :: Number -> Number
      fact 0 = 1
      fact n = n * fact (n - 1)
    

This will build stack frames and fail with a stack overflow for large inputs.
We can fix this by using tail recursion and an accumulator:

    
    
      fact :: Number -> Number
      fact = go 1
        where
        go acc 0 = acc
        go acc n = go (acc * n) (n - 1)
    

The PureScript compiler will recognize that every recursive call is in tail
position, and will convert the function to a while loop.

If we want to perform side-effects during the recursion, we typically use a
monad to track the type of side effect in use. For example, we can use
PureScript's Eff monad to trace information to the console:

    
    
      fact :: Number -> Eff (trace :: Trace) Number
      fact = go 1
        where
        go acc 0 = do
          trace "Done!"
          return acc
        go acc n = do
          trace "Keep going ..."
          go (acc * n) (n - 1)
    

In the case of the Eff monad, the PureScript compiler employs some special
tricks in the optimizer to enable the tail call optimization, so we're still
OK. But this is only possible because Eff is defined in the standard library
(at least until we implement custom rewrite rules).

In the general case, the compiler only sees applications to the monadic bind
function of the underlying monad. For example, if we use the Writer monad
instead:

    
    
      fact :: Number -> Writer String Number
      fact = go 1
        where
        go acc 0 = do
          tell "Done!"
          return acc
        go acc n = do
          tell "Keep going ..."
          go (acc * n) (n - 1)
      

which is equivalent after desugaring to the following code:

    
    
      fact :: Number -> Writer String Number
      fact = go 1
        where
        go acc 0 = tell "Done!" >>= \_ -> return acc
        go acc n = tell "Keep going ..." >>= \_ -> go (acc * n) (n - 1)
    

This is an example of "monadic recursion" \- a recursive function whose return
type uses some monad. In this case, the recursive calls are no longer in tail
position, so the compiler cannot apply the tail call optimization. The result
is that the compiled JavaScript might blow the stack for large inputs.

The point is that idiomatic Haskell code is often not appropriate in
JavaScript because of the different semantics, so it might not be appropriate
in PureScript either. The good news is that many Haskell idioms have
corresponding PureScript idioms (often using the Eff monad).

~~~
eru
Thanks! Another trick I've seen used is `naked' avoiding recursion in your
code, and relying on combinators implemented in some optimized lower level
code. Would that work with PureScript?

~~~
paf31
Yes - in fact, that's the approach we encourage for working with immutable
arrays: [https://github.com/purescript/purescript-
arrays](https://github.com/purescript/purescript-arrays)

------
billpg
I find JS a thoroughly unpleasant language to work with. When will we reach
the point where JS could be abstracted away entirely? (Just like how I never
need to interact with assembly language any more.)

~~~
bru
There are several paths:

1\. JS as an assembly language. This is what emscripten[0], a LLVM bytecode-
to-JS does, by following the asm.js specification[1]. This is for CPU-
intensive tasks, not DOM manipulation. You can use any language that has a
LLVM frontend.

2\. JS as a target language, from a specific, new language. Those include
cleaner variants that keep the same semantics (CoffeeScript, TypeScript, maybe
Dart, ...) or more innovative ones, such as Elm[2], which is written in
Haskell too. I'd say that a big innovation that makes the life easier is FRP
(which is at the heart of Elm or React.js).

I fail yet to see what advantages PureScript brings compared to Elm.

0:
[https://github.com/kripken/emscripten](https://github.com/kripken/emscripten)
1: [http://asmjs.org](http://asmjs.org) 2: [http://elm-lang.org/](http://elm-
lang.org/)

~~~
paf31
> I fail yet to see what advantages PureScript brings compared to Elm.

I think they fit different use cases. Elm is excellent at interactive web apps
using FRP. PureScript is a little more general purpose and has a few type
system features which Elm currently does not (type classes and rank N
polymorphism). Also, PureScript's generated code is a bit simpler and doesn't
need a runtime library.

------
zak_mc_kracken
For those of you who want to see some code:

[https://leanpub.com/purescript/read](https://leanpub.com/purescript/read)

------
cmdrfred
I'm new to this but can someone enlighten me about what is the advantage of
using this over pure JS?

~~~
gamegoblin
Type correctness can help eliminate an entire class of bugs (type mismatch
bugs) found in dynamically typed languages, or various gotchas with implicit
typecasting.

~~~
toadkicker
This is where I find programmers who are comfortable with static languages
struggle with dynamic languages. There is a lack of understanding and this is
yet another language trying to fix something that isn't fundamentally broken.

~~~
paf31
I think it really depends what you're trying to do. There's definitely a class
of problems where the impact of a runtime type error would be low. But there
are plenty of other cases where you want to constrain what you or your users
can do at compile time.

------
lemming
One thing I couldn't see anywhere - is PureScript strict rather than lazy?

~~~
paf31
It uses JavaScript's evaluation model - i.e. strict, but you can write lazy
code using libraries, such as purescript-lazy.

~~~
lemming
Interesting, thanks - I've been interested in a language like the Haskell.Next
that SPJ described: strict evaluation but with effects controlled by monads.
I'll give it a look!

------
sassyalex
Great language, but javascript code is clean, why not only keeping javascript
style and adding typechecking and es6 by default..

~~~
andrewchambers
Javascript being clean is your own (possibly misinformed) opinion.

~~~
pmontra
I agree that's a matter of opinions but I think that the OP has a point.
JavaScript is easy to understand for everybody coming from C, Java or PHP even
if its core is very different from those two languages. Haskell might be
cleaner but it's difficult to get for people that used only procedural
languages, which are most of the programmers working today (especially if the
expected domain for PureScript is web programming, frontend or backend).

There is a functional language called Elixir which runs on the Erlang virtual
machine. Elixir has been designed to look like Ruby even if it's very
different. That makes Ruby programmers (and maybe Python ones too) feel at
ease in their first approaches with the language. When you realize how
different the two languages really are you already grokked enough of Elixir to
keep you going. There isn't that feeling of "oh my, I can't make it" one might
have when looking at code like this
[http://svn.openfoundry.org/pugs/src/Pugs/Eval.hs](http://svn.openfoundry.org/pugs/src/Pugs/Eval.hs)
when knowing only about C/Java/PHP/Python/Ruby

Anybody knowing Ruby or possibly Python should compare that with this
[https://github.com/elixir-
lang/plug/blob/master/lib/plug/con...](https://github.com/elixir-
lang/plug/blob/master/lib/plug/conn.ex)

So, my take is that if a language designer wants to create a functional
language that will lure really many procedural programmers into it, s/he has
to design something that looks like C or Java. PureScript is too much like
Haskell (plus I hate indentation-sensitiveness, but that's _almost_ only a
subjective matter). Time will tell.

~~~
Sirenos
Easy to understand != clean

Javascript has enough implicit behavior and then some to make working with it
a nightmare unless you remain extremely diligent with your coding practices.
To a large extent, it's been around long enough for this to not be a major
problem anymore, but is this an acceptable state of affairs for a language
that dominates web programming? I'd expect most people to say "no".

------
pjmlp
Looks nice, but my employer will never use anything other than JavaScript as
browser language, unless a customer asks to do so.

~~~
lmm
Get a better employer. I can understand thinking that e.g. existing options
are not mature enough, but "never" is a stupid policy.

~~~
pjmlp
Quoting myself

> unless a customer asks to do so.

which I agree with.

Since 1986 I already have seen too much technology come and go, to be
convinced to use "language of the month" at work.

------
hawleyal
Ew

