paf31's comments

paf31 | 11 years ago | on: PureScript: a statically typed language which compiles to JavaScript

> 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.

paf31 | 11 years ago | on: PureScript: a statically typed language which compiles to JavaScript

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).

paf31 | 11 years ago | on: PureScript: a statically typed language which compiles to JavaScript

I think it's definitely possible to put knowledge of Haskell to use in PureScript, but it's not like Fay, Haste, GHCJS etc. where you can copy code verbatim. I think of PureScript as "an environment in which to write principled JavaScript". That requires that, to a certain extent, you should have JavaScript's semantics in the back of your mind while developing. For that price, you get ease of debugging and some tools which you don't have in many other compile-to-JS languages (an expressive type system, type classes, ability to refactor with confidence etc.)

Of course, one of the best things about AltJS is the interoperability with other languages. PureScript won't be the best tool for every case, but it has a simple FFI. It's possible to write complete front-ends in PureScript, but I'd love to see more examples where PureScript is used alongside something else (I've used TypeScript with PureScript successfully, for example).

paf31 | 11 years ago | on: PureScript: a statically typed language which compiles to JavaScript

"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.

paf31 | 11 years ago | on: How to hire engineering talent in LA?

You couldn't pay me enough to work on some stacks.

Also, certain technologies do a good job of convincing potential employees that you know what you're doing and committed to using the best tools available IMO.

paf31 | 11 years ago | on: λ Lessons

Very nice. It took me a while to realize that array literals aren't supported, but once I did that I was able to write concatMap and watch it being evaluated.

A couple of points:

- If there is a syntax error, the box just turns red. It would be nice to see what the issue is.

- You could probably make it clearer that it's possible to execute arbitrary expressions, by editing the map term, for example.

page 1