|
|
|
|
|
by baggers
3668 days ago
|
|
I found them useful when I looked at clojure and saw their shorthand syntax for lambdas where #(* % %) is a lambda that takes one argument and squares it. You can get some tidy things that are similar with regular macros but to make it actually equivalent your need to hook into the reader..and that's what reader macros are for. So within the hour I had something that let me write λ(* _ _) The best bit though, is that this isn't some nasty hack. This is supported by the spec, so I can package this up and let other people us it just like any other functionality we care to ship around. That's my favorite thing really, being able to treat approaches to writing code in the same way we treat the functionality we make using code. |
|
You mean ... programming the programming language?
> I can package this up ...
Not really; it will clash with someone else's use of λ. Read macros do not "package" particularly well. (Racketlang has a good solution for this: you put a #lang whatever directive at the top of a file and then the rest of the file uses the special syntax associated with that lang name).
It's very easy to overestimate the usefulness of read syntax.
This feature of Common Lisp is used far less than newcomers might imagine, though there are some famous examples of it. If you randomly sample Lisp code, you are much more likely to find a macro than a read macro.
> So within the hour I had something that let me write λ( _ _)*
Do you plan to type "lambda" with args enough times to eventually that hour of your life back? Ha.
Useful syntax for writing anonymous functions can be had, without relying on read macros at all.
cl-op: https://code.google.com/archive/p/cl-op/
Note how if we take λ(* _ _) and then just move the parenthesis over the Greek symbol, we get (λ * _ _). This saves almost the same amount of typing. If your Lisp recognizes λ as a symbol token, then all you have to do now is write a regular macro. Basically, just get the cl-op package and then set up λ as an alias for op: (defmacro λ (&rest args) `(op ,@args)).
In TXR Lisp, I implemented a more powerful op which has numbered arguments, and an escape syntax for inner ops to refer to outer ops.
Y combinator with TXR Lisp op:
Combinators return us to your topic of writing a function which squares its argument. Instead of a condensed lambda notation like (op * _ _) for doing this with syntax, we can have a combinator, like (dup #'). This is nicer in a Lisp-1 language where we can just do (dup ). Dup takes its argument, which is a two-argument function, and returns a one-argument function which calls that function with two copies of the argument: