greghendershott / rackjure

Provide a few Clojure-inspired ideas in Racket. Where Racket and Clojure conflict, prefer Racket.
BSD 2-Clause "Simplified" License
236 stars 17 forks source link

Implementing Clojure lamda macro? #35

Closed cmpitg closed 10 years ago

cmpitg commented 10 years ago

Hi,

I had a quick chat with @greghendershott on IRC about Clojure lambda macro. I thought it'd be nice to have a similar thing in Rackjure. What's your opinion on this? Anyone interested in implementing lambda macro in Rackjure? I don't mind rolling my own version but I've just been using Racket for a short while and probably need lots of help.

greghendershott commented 10 years ago

Although on IRC I said I thought I wouldn't have time to do this, it caught my interest. I sketched out an initial implementation.

One question: The Racket reader already uses #( . . . ) for vector literals. So we need to pick something else[^1].

Would #lambda( . . . ) be too verbose?

How about #λ( . . . ) and/or #y( . . . )?


[^1]: I think picking something else is fine. The "slogan" for #lang rackjure is, "Where Racket and Clojure conflict, prefer Racket". One precedent is using ~> instead of -> for the threading macro.

samth commented 10 years ago

See also https://github.com/samth/fancy-app

cosmez commented 10 years ago

λ looks better imho

Im interested in how this feature is going to be implemented.

greghendershott commented 10 years ago

Hmm, actually I could combine this with the existing meaning of #( ... ): If the contents do not include any %, %n, or %&, then treat as a vector literal as usual.

I'm not sure whether that's elegant, or, a horrible kludge waiting to go wrong.

So far the code in this gist seems to work well.

cmpitg commented 10 years ago

Nice code, works great! However, I don't think adding meaning to #(...) is a good idea. The semantics is different and it might cause conflict when one, for some reason, wants to use %* symbols. I concur with #y and .

myguidingstar-zz commented 10 years ago

y is quite confusing and I prefer #fn() to it

λ is great of course. A little off-topic, what about Clojure-like fn alias for the lambda symbol?

cmpitg commented 10 years ago

@myguidingstar y is an inverted λ. #fn would also be a good choice since its meaning is clear. Let's make another issue for the fn thing?

greghendershott commented 10 years ago

/cc @qerub in case you have any opinions?

qerub commented 10 years ago

@greghendershott: Thanks for the poke. I have now added Rackjure to my GitHub watch list.

@myguidingstar:

λ is great of course. A little off-topic, what about Clojure-like fn alias for the lambda symbol?

Do you know that λ is already an alias for lambda in Racket?

@samth: See also https://github.com/samth/fancy-app

I strongly prefer Clojure's #(…) because it can handle arguments in nested forms and can reorder arguments.

.

I concur with the previously expressed opinions on #y and .

I'm a little bit worried about having a non-ASCII symbol for such an useful form. Could we perhaps have an ASCII-alternative/alias for for the (few) occasions where the environment makes it hard to type λ? Using #lambda for that would create a great symmetry with how lambda/λ is already used in Racket even though it's a long name. An alternative would be to use \ (λ with a missing leg) like the Haskell folks.

#fn would be totally OK with me too as long as it comes with a fn alias for lambda for symmetry.

greghendershott commented 10 years ago

I'm a little bit worried about having a non-ACII symbol for such an useful form. Could we perhaps have an ASCII-alternative/alias for #λ for the (few) occasions where the environment makes it hard to type λ?

I agree. In fact I meant that #y be an ASCII alternative for . In other words, both would work.

An alternative would be to use \ (λ with a missing leg) like the Haskell folks.

I agree that's a good idea because I thought of that, too. :) Seriously, the problem that occurred to me is that #\ is the reader notation for character literals: #\a, #\b, and so on -- including #\(, the ( character. So that's awkward.

If we don't want #( ... ) to be overloaded based on whether any %s are present[^1], then we probably really don't want #\( to be overloaded based on whether it's followed by a space vs. what looks like the rest of a lambda literal.

It seems like the best option to make both #y( .... ) or #λ( .... ) be a lambda literal.

[^1]: I actually don't mind that, but will gladly defer to wiser heads.

qerub commented 10 years ago

In fact I meant that #y be an ASCII alternative for #λ. In other words, both would work.

Sorry, I read too fast to notice your "and/or". :)

[…] the problem that occurred to me is that #\ is the reader notation for character literals […]

Oh, right, definitely no to #\ then.

It seems like the best option to make both #y( .... ) or #λ( .... ) be a lambda literal.

I understand that #y is a mirrored , but it looks so arbitrary… I even prefer #lambda, but I'm a real sucker for symmetry.

greghendershott commented 10 years ago

Yeah although #y is good in theory it looks kind of ugly and arbitrary.

I could see #lambda. Since Clojure's lambda is fn I could also see #fn, as @myguidingstar suggested above.