Discussion on possible lambda syntax: Good or Evil?
Posted: Mon Sep 22, 2008 10:41 am
One of the few things I've been coding in CL is a shorthand form of the dearly loved lambda functions. While my own code proved to work only in CLISP, and not entirely as well as I had hoped, I thought I'd share my experience and ideas about this whole thing.
The idea came from either a blog or comp.lang.lisp, I don't remember. Here's how it looks:
Other versions of this syntax have been discussed. For example, sbcl supports unicode, and the lambda character could be used instead of $:
I like the first suggestion the best since I can do pretty function calls:
The lambda character is pretty awesome, albeit cumbersome.
This would support nested lambda calls by adding multiple $'s before the argument count. $1 would be a 'first-layer' argument, $$1 a 'second-layer', $$3 a third, and so on. Let me show you:
This can be done for any amount of nested lambda calls. Each lambda function will then have it's own unique set of arguments.
It supports &rest arguments by using $rest.
$rest is also supported in nesting. $$rest would be a second layer lambda &rest argument etc.
Arguments are sorted by using #'< (with $rest being weighted to the end). Any numbers can theoretically be used.
All these 'features' can be mixed and matched.
My own version gensymmed the names of the arguments, and this is probably necessary for it to work.
My question: Is this Good, or is this Evil? I like it. It keeps my code short. I don't have to come up with redundant names for my arguments (maybe we could even find a way so i don't have to come up with names for the variables in my closures? Or maybe not.). This makes it a valid abstraction. Finally, IMHO, It looks good.
Really, I just don't see why I have to name my arguments when I don't name my function.
What do you think? Good or Evil?
The idea came from either a blog or comp.lang.lisp, I don't remember. Here's how it looks:
Code: Select all
{and $1 $2} expands to (lambda ($1 $2) (and $1 $2))
Code: Select all
#$(and $1 $2)
Using brackets and a dispatch character.
λ(and λ1 λ2)
Using the lambda character.
Code: Select all
#'{and $1 $2}
This would support nested lambda calls by adding multiple $'s before the argument count. $1 would be a 'first-layer' argument, $$1 a 'second-layer', $$3 a third, and so on. Let me show you:
Code: Select all
{let ((count $1)) {incf count $2}}
Returns a pre-initialized lambda closure depending on the arguments passed. (Note, $2 is an argument to the FIRST lambda call, not the second.)
{if $1 {+ $2 $$1} {* $2 $$1}}
Returns a lambda function that either multiplies or adds by a set amount, depending on the arguments passed.
It supports &rest arguments by using $rest.
Code: Select all
{* $1 (apply #'+ $rest)} expands to (lambda ($1 &rest $rest) (* $1 (apply #'+ $rest)))
Multiplies the first argument by the sum of the remaining arguments.
Arguments are sorted by using #'< (with $rest being weighted to the end). Any numbers can theoretically be used.
Code: Select all
{/ (- $234931) $0}
Divides the negative of the second argument by the first.
My own version gensymmed the names of the arguments, and this is probably necessary for it to work.
My question: Is this Good, or is this Evil? I like it. It keeps my code short. I don't have to come up with redundant names for my arguments (maybe we could even find a way so i don't have to come up with names for the variables in my closures? Or maybe not.). This makes it a valid abstraction. Finally, IMHO, It looks good.
Really, I just don't see why I have to name my arguments when I don't name my function.
What do you think? Good or Evil?