
Pun: A small library to enable pattern matching in JavaScript and CoffeeScript - unignorant
https://github.com/CRogers/pun
======
jlongster
Very cool! You might also want to check out sparkler, which uses macros to let
you do this with a little better syntax:
[https://github.com/natefaubion/sparkler](https://github.com/natefaubion/sparkler)

~~~
unignorant
I'd heard of sparkler, but my impression was that macros prevent it from
working with CoffeeScript.

There's also matches.js, which is the deprecated precursor to sparkler:
[https://github.com/natefaubion/matches.js](https://github.com/natefaubion/matches.js)

------
d0m
What I'd like is a small library to complement lodash/underscore with utility
functions required when using high-level ones. It's very annoying to have
verbose

    
    
        _.each([1,2,3], function(x) { something(x, 'param'); }
    

when it could be

    
    
       _.each([1,2,3], $.call(something, _, 'param'))
    
    

It seems like the current solution is to use _.pluck() or similar functions
for common use-cases, or use _.partial which I find even more verbose than
standard functions.

e.g.

    
    
        _.map(objs, $.pluck('person.age'))    
        promise.then($.ret(some_fn, _, 'a'))
    
    

promise.then(some_fn) doesn't work because what we want is to _return_ some_fn
from within a function.

    
    
        promise.then(function(x) { return some_fn(x, 'a'); })
    

I know there are ways around, but those are not unified in a standard and
coherent library that could complement other high-level libraries.

~~~
klibertp
Use LiveScript.

No, seriously, LiveScript is great and I used it in production already,
without any problems. Your first example would look like this in LS:

    
    
        _.each [1 to 3], (something _, 'param')
    

where "_" in this context means partial application.

Even better, LS has special syntax for accessing an object method and binding
it at the same time, this is a bit of code I wrote recently:

    
    
        httpify-promise = (promise) ->
            # add `success` and `error` methods to the promise, making it into
            # $http-compatible one
            promise with
                success: (promise~then _, null)
                error:   (promise~then null, _)
    

Now this is really beautiful and powerful.

I also played with promises some time ago, in Node, where I used q library and
LiveScript. Partial application and curried functions from prelude-ls let me
write code like this:

    
    
        read-dir(directory)
            .then map (path.join directory, _)
            .then get-stats
            .then tee (collect-files-into accum)
            .then filter (at 1)
            .then walk-subdirs
            .thenResolve accum
    

(the whole file here:
[http://klibert.pl/walkfiles.html](http://klibert.pl/walkfiles.html))

In short, having support for many higher-level idioms as part of a language,
as opposed to library, makes it MUCH more pleasant to work with.

~~~
agumonkey
That tee + thenResolve pattern is a first for me. Is this from LS or did they
take it from another lang/lib ?

~~~
klibertp
It's actually a very little function I wrote, based on `tee` Unix shell
command: [http://unixhelp.ed.ac.uk/CGI/man-
cgi?tee](http://unixhelp.ed.ac.uk/CGI/man-cgi?tee)

It looks like this:

    
    
        tee = (func, val) --> func(val); val
    

which could be equivalently written as:

    
    
        tee = (func) -> (val) -> func(val); val
    

In other words it's an identity function which additionally executes some
other function for side-effects. In the shell the `tee` command always writes
to the file, while my version can execute any side-effect, but I think my
version is just a generalization of the standard Unix command and so I named
it like this.

I'm sure this function has its own, formal name, with the word "monad" or
"combinator" (maybe K combinator?) in it, but I wasn't patient enough to
research it :)

`thenResolve` is a standard method on a promise object implemented by the Q
library ([https://github.com/kriskowal/q/wiki/API-
Reference#promisethe...](https://github.com/kriskowal/q/wiki/API-
Reference#promisethenresolvevalue)) I used, it's equivalent to

    
    
       .then () -> accum
    

In other words, `thenResolve` appends a success callback which discards
previous value and always returns another value.

Once again, take a look at the full source at
[http://klibert.pl/walkfiles.html](http://klibert.pl/walkfiles.html) \- I'm
going to update it with a full explanation of what's going on, but even right
now it's only 90 lines with including comments, and should be a good example
of main LS strengths. I'm probably going to write another example which makes
use of even more (and more advanced) LS features when I'm done with explaining
this one.

~~~
agumonkey
Actually my reflection started with using tee and pipes in bash, having a
desire to sync/join on the multiple paths created by tees. Interesting job
that you did.

------
andybak
A quick comparison of some Python implementations I found via quick Googling:

[https://gist.github.com/andybak/45e3155420d18420a34a](https://gist.github.com/andybak/45e3155420d18420a34a)

~~~
unignorant
Nice, that's a clever use of decorators. A bit annoying that you need repeated
"defs", though.

Here's another approach based on Macropy (basically, macros for Python):
[https://github.com/lihaoyi/macropy#pattern-
matching](https://github.com/lihaoyi/macropy#pattern-matching).

------
ilaksh
Very awesome.

Also see LiveScript [http://livescript.net/](http://livescript.net/)

------
rubiquity
This is cool but I would love if these features were implemented at compile
time instead of using functions. Great work either way!

------
elwell
I love this kind of stuff.

------
tkubacki
Every time I see things like this I'm grateful for Dart SDK

