gkz / LiveScript

LiveScript is a language which compiles to JavaScript. It has a straightforward mapping to JavaScript and allows you to write expressive code devoid of repetitive boilerplate. While LiveScript adds many features to assist in functional style programming, it also has many improvements for object oriented and imperative programming.
http://livescript.net
MIT License
2.32k stars 155 forks source link

Feature request: Algebraic Data Types like in Haskell #317

Open utkarshkukreti opened 11 years ago

utkarshkukreti commented 11 years ago

Bits of LiveScript's syntax is inspired by Haskell, so I thought what you guys think about adding ADT's to LiveScript, arguably one of the most useful features of Haskell?

@natefaubion has two excellent libraries adt.js, and matches.js which could be used as references. adt.js could be implemented with native syntax, possibly like Haskell's, and matches.js in the experimental pattern matching match's syntax.

vendethiel commented 11 years ago

That's a lib's work

natefaubion commented 11 years ago

Hi, lib author here. I've actually written the api so it works especially well with coffeescript-like languages. Here are a few examples:

{data, only, any} = require 'adt'

Maybe = data ->
  Nothing : null
  Just : 
    value : any

List = data ->
  Nil : null
  Cons :
    head : any
    tail : only this

Tree = data ->
  Leaf : null
  Branch :
    value : any
    left  : only this
    right : only this

In fact, I don't know if you could get much terser with native support unless you adopted full on haskell syntax.

Edit: fixed an error in the example.

michaelficarra commented 11 years ago

@natefaubion: I don't see a need for the function literals.

natefaubion commented 11 years ago

@michaelficarra You're right! For simple ADT definitions, the function literal is unnecessary and can be left out. But it's there for recursive types. Notice the only this. only is a constraint factory that does type/value checking at runtime. With recursive types, it will check that the value you are using is an instance of List/Tree/etc. Check out the examples for another way to define recursive types without the function literal.

There are actually several ways in which you can define ADTs with my lib. The examples I provided above are actually API sugar for the following expanded, "safe" api (it doesn't rely on insertion order of object literals).

List = data (type, List) ->
  type 'Nil'
  type 'Cons', (field, Cons) ->
    field 'head', any
    field 'tail', only(List)
jiriknesl commented 11 years ago

The second possible implementation can be inspired (merged) support of contracts.coffee http://disnetdev.com/contracts.coffee/

jasonkuhrt commented 11 years ago

The javascript library that powers contracts.coffee: https://npmjs.org/package/contracts-js