Is it possible to use/implement tacit programming (also known as point-free programming) in Lisp? And in case the answer is yes, has it been done?
相关问题
- Generating powerset in one function, no explicit r
- Drakma and Dexador both fails at USocket call whil
- Forming Lisp code to task — related to flatten lis
- clisp 2.49: asdf cannot find asd
- unfold function in scheme
相关文章
- Does learning one Lisp help in learning the other?
- Common Lisp: Why does my tail-recursive function c
- What is the definition of “natural recursion”?
- How do I write a macro-defining macro in common li
- How can I unintern a qualified method?
- Changing the nth element of a list
- Is a “transparent” macrolet possible?
- sleep in emacs lisp
YES, it's possible and @danlei already explained very well. I am going to add up some examples from the book ANSI Common Lisp by Paul Graham, chapter 6.6 on function builders:
you can define a function builder like this:
and use it like this
returns
The
compose
function call:is equlvalent to
This means compose can take any number of arguments, yeah.
Make a function which add 3 to argument:
See more in the book.
This style of programming is possible in CL in principle, but, being a Lisp-2, one has to add several
#'
s andfuncall
s. Also, in contrast to Haskell for example, functions are not curried in CL, and there is no implicit partial application. In general, I think that such a style would not be very idiomatic CL.For example, you could define partial application and composition like this:
(Those are just quick examples I whipped up – they are not really tested or well thought-through for different use-cases.)
With those, something like
map ((*2) . (+1)) xs
in Haskell becomes:The
sum
example:(In this example, you could also set the function cell of a symbol instead of storing the function in the value cell, in order to get around the funcall.)
In Emacs Lisp, by the way, partial application is built-in as
apply-partially
.In Qi/Shen, functions are curried, and implicit partial application (when functions are called with one argument) is supported:
There is also syntactic threading sugar in Clojure that gives a similar feeling of "pipelining":
Yes, this is possible in general with the right functions. For example, here is an example in Racket implementing
sum
from the Wikipedia page:Since procedures are not curried by default, it helps to use
curry
or write your functions in an explicitly curried style. You could abstract over this with a newdefine
macro that uses currying.You could use something like (this is does a little more than
->
in Clojure):(you must be careful to also export the symbol
$
from the package in which you place->
- let's call that packagetacit
- and puttacit
in theuse
clause of any package where you plan to use->
, so->
and$
are inherited)Examples of usage:
This is more like F#'s
|>
(and the shell pipe) than Haskell's.
, but they are pretty much the same thing (I prefer|>
, but this is a matter of personal taste).To see what
->
is doing, just macroexpand the last example three times (in SLIME, this is accomplished by putting the cursor on the first(
in the example and typingC-c RET
three times).