Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Algebraic datatypes and pattern matching #19

Closed
littledan opened this issue Jul 4, 2017 · 4 comments
Closed

Algebraic datatypes and pattern matching #19

littledan opened this issue Jul 4, 2017 · 4 comments

Comments

@littledan
Copy link
Member

If we want to take JS in a more functional direction, one way is to continue with using object literals each time we want to construct something, and another way would be to use something more like algebraic data types which are constructed explicitly. For example, you could have a class with two constructors: Cons(car, cdr) and Nil. Nil would fit cleanly into this pattern matching system, but to pattern match on Cons, it seems pretty tough: the arguments passed in would be evaluated, rather than bound to. Do you think this could be fixed in a follow-on extension, if we decide to go down a path of having algebraic data types?

@Jamesernator
Copy link

Personally I'm wanting to see expression based patterns instead of syntactic ones which would make things like this easy to implement without having to specifically support algebraic data types in pattern matching.

const { Nil, Cons } = makeUnion({ Nil: [], Cons: ['head', 'tail'] })

function sum(seq) {
    return match (seq) {
        Nil: 0,
        // Assuming Cons(head, tail) is an iterable able to be destructured
        Cons: [head, tail] -> head + sum(tail)
    }
}

@littledan
Copy link
Member Author

That's an interesting idea for how to make it work! I hadn't understood that implication before. However, I don't see how to make this work with nested destructuring.

For what it's worth, I previously implemented a pattern matching library in Factor which was based on this sort of thing, but working with nesting. But, it never really caught on, probably because it felt too complicated, unintuitive and magical.

@littledan
Copy link
Member Author

In particular, to elaborate: It seems like it'd be great if you could match something like this:

match (seq) {
  Cons(Cons(caar, Cons(cadr, cddr)): blah
}

@zkat
Copy link
Collaborator

zkat commented Mar 25, 2018

Hey y'all! #65 has gotten merged, and a lot of issues have become irrelevant or significantly changed in context. Because of the magnitude of changes and subtle differences in things that seem similar, we've decided to just nuke all existing issues so we can start fresh. Thank you so much for the contributions and discussions and feel free to create new issues if something seems to still be relevant, and link to the original, related issue so we can have a paper trail (but have the benefit of that clean slate anyway).

In re this specific proposal: extractors are a feature that should allow this:

class Maybe {}
class Just { constructor (val) { this.value = val } }
Just[Symbol.patternValue] = function (just) { return {[Symbol.patternValue]: this.value } }
class NoneClass {}
const Nothing = new NoneClass()

match (x) {
  Just a => console.log('the value inside the Just is', a),
  Nothing {} => console.log('got nothing')
}

@zkat zkat closed this as completed Mar 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants