anko / eslisp

un-opinionated S-expression syntax and macro system for JavaScript
ISC License
528 stars 31 forks source link

Livescript piping operator in eslisp? #39

Closed ktodyruik closed 8 years ago

ktodyruik commented 8 years ago

I was wondering, how would you write the livescript pipe operator |>, in eslisp?

4
|> (+ 1)
|> even
#=> false

Thanks, Kerry

dead-claudia commented 8 years ago

@ktodyruik Try a macro:

;; Lambda helper
(macro # (lambda (params ret)
  (return `(lambda ,params (return ,ret)))

;; Pipe operator
(macro |> (# ()
  ((. Array prototype reduce call) arguments
    (# (arg f) `(,f ,arg))))

(|> 4
    (# (x) (+ x 1))
    even
    (# (x) ((. assert equal) x false)))

That might be all you need.

anko commented 8 years ago

@ktodyruik

That exact syntax isn't possible in eslisp, because it's not an S-expression.

I'm working on read macros as a proposed feature (https://github.com/anko/eslisp/issues/24) though: if that exact syntax is really important for you, it might become possible in the future. Follow there if you're interested.

For now, @isiahmeadows' suggestion of a |> macro that folds its arguments into nested function calls basically expresses that as an S-expression. I noticed that some parentheses were missing: the following version compiles

;; Lambda helper
(macro # (lambda (params ret)
  (return `(lambda ,params (return ,ret)))))

;; Pipe operator
(macro |> (# ()
  ((. Array prototype reduce call) arguments
    (# (arg f) `(,f ,arg)))))

;; Example of use
(|> 4
    (# (x) (+ x 1))
    even
    (# (x) ((. assert equal) x false)))

and produces

(function (x) {
    return assert.equal(x, false);
}(even(function (x) {
    return x + 1;
}(4))));
dead-claudia commented 8 years ago

@anko

Yeah... I typed that off the top of the top of my head, didn't even bother trying to verify that with the compiler. :smile:

anko commented 8 years ago

Woah, I was sure you'd copied it from existing code! :smile:

I'm closing this issue, because @isiahmeadows' solution works very well, and is the idiomatic way of doing this in eslisp. Reader macros (#24) might possibly eventually allow the exact syntax, but it's still a little too far to constructively discuss right now.

dead-claudia commented 8 years ago

@anko -> is the equivalent in Clojure. It's been there a while, and it has the same semantics. I don't think it would be very Lispy to make it a reader macro, but that's just my opinion.