gelisam / klister

an implementation of stuck macros
BSD 3-Clause "New" or "Revised" License
128 stars 11 forks source link

section syntax? #222

Open gelisam opened 8 months ago

gelisam commented 8 months ago

I recently encountered a bug in which I had written:

(filter (< 10) (list 1 11 111 2 22 222 3 33 333))

to mean

(filter
  (lambda (x) (< x 10))
  (list 1 11 111 2 22 222 3 33 333))

But in Klister, (< 10) means (lambda (x) (< 10 x)), not (lambda (x) (< x 10)). I made that mistake because (< 10) means the latter in Haskell, but the former in Klister. Since target audience is Haskellers, I think our users are likely to make that mistake very often. Is there something we could do to make it less common?

gelisam commented 8 months ago

Hackett supports infix syntax as {x < 10}, but it doesn't look like it supports section syntax as {< 10}. It would be tricky to implement, because in the absence of Haskell's restriction on naming binary operators, it is not clear whether < or 10 is supposed to be the infix operator.

gelisam commented 8 months ago

The same issue prevents a user-defined the user from defining a user-defined macro (section (< 10)) which does the right thing, unless that macro hardcodes a few specific infix operators. Maybe that would be enough though?

gelisam commented 8 months ago

Some other languages support the syntax (_ < 10) for quickly defining lambdas. I don't like that syntax because in those languages, it's not clear whether 1 + (2 + _) means \x -> 1 + (2 + x) or 1 + (\x -> 2 + x).

Maybe we could introduce a limited version of that syntax which is only meant for sections, and thus the lambda is always introduced at the innermost parens? So (+ 1 (+ _ 2)) would unambiguously mean (+ 1 (lambda (x) (+ x 2))).

gelisam commented 8 months ago

Or, since we're not yet using curly parens for anything, the lambda could be bound at the closest enclosing curlies? So (+ 1 {+ 2 (+ _ 3)}) would mean (+ 1 (lambda (x) (+ 2 (+ x 3)))).

david-christiansen commented 8 months ago

The final option there would be a nice little macro to define :) I think Haskell-style sections don't fit well into a language with Lispy syntax and auto-currying, though - it's too much of a special case.