Clojure, can macros do something that couldn't be done with a function - function

I'm learning Clojure macros, and wonder why we can't use just functions for metaprogramming.
As far as I know the difference between macro and function is that arguments of macro are not evaluated but passed as data structures and symbols as they are, whereas the return value is evaluated (in the place where macro is called). Macro works as a proxy between reader and evaluator, transforming the form in an arbitrary way before the evaluation takes place. Internally they may use all the language features, including functions, special forms, literals, recursion, other macros etc.
Functions are the opposite. Arguments are evaluated before the call, return value is not after return. But the mirroring nature of macros and functions makes me wonder, couldn't we as well use functions as macros by quoting their arguments (the form), transforming the form, evaluating it inside the function, finally returning it's value. Wouldn't this logically produce the same outcome? Of course this would be inconvenient, but theoretically, is there equivalent function for every possible macro?
Here is simple infix macro
(defmacro infix
"translate infix notation to clojure form"
[form]
(list (second form) (first form) (last form)))
(infix (6 + 6)) ;-> 12
Here is same logic using a function
(defn infix-fn
"infix using a function"
[form]
((eval (second form)) (eval (first form)) (eval (last form))))
(infix-fn '(6 + 6)) ;-> 12
Now, is this perception generalizable to all situations, or are there some corner cases where macro couldn't be outdone? In the end, are macros just a syntactic sugar over a function call?

It would help if I read the question before answering it.
Your infix function doesn't work except with literals:
(let [m 3, n 22] (infix-fn '(m + n)))
CompilerException java.lang.RuntimeException:
Unable to resolve symbol: m in this context ...
This is the consequence of what #jkinski noted: by the time eval acts, m is gone.
Can macros do what functions cannot?
Yes. But if you can do it with a function, you generally should.
Macros are good for
deferred evaluation;
capturing forms;
re-organizing syntax;
none of which a function can do.
Deferred Evaluation
Consider (from Programming Clojure by Halloway & Bedra)
(defmacro unless [test then]
(list 'if (list 'not test) then)))
... a partial clone of if-not. Let's use it to define
(defn safe-div [num denom]
(unless (zero? denom) (/ num denom)))
... which prevents division by zero, returning nil:
(safe-div 10 0)
=> nil
If we tried to define it as a function:
(defn unless [test then]
(if (not test) then))
... then
(safe-div 10 0)
ArithmeticException Divide by zero ...
The potential result is evaluated as the then argument to unless, before the body of unless ignores it.
Capturing Forms and Re-organizing Syntax
Suppose Clojure had no case form. Here is a rough-and-ready substitute:
(defmacro my-case [expr & stuff]
(let [thunk (fn [form] `(fn [] ~form))
pairs (partition 2 stuff)
default (if (-> stuff count odd?)
(-> stuff last thunk)
'(constantly nil))
[ks vs] (apply map list pairs)
the-map (zipmap ks (map thunk vs))]
(list (list the-map expr default))))
This
picks apart the keys (ks) and corresponding expressions (vs),
wraps the latter as parameterless fn forms,
constructs a map from the former to the latter,
returns a form that calls the function returned by looking up the
map.
The details are unimportant. The point is it can be done.
When Guido van Rossum proposed adding a case statement to Python, the committee turned him down. So Python has no case statement. If Rich didn't want a case statement, but I did, I can have one.
Just for fun, let's use macros to contrive a passable clone of the if form. This is no doubt a cliche in functional programming circles, but took me by surprise. I had thought of if as an irreducible primitive of lazy evaluation.
An easy way is to piggy-back on the the my-case macro:
(defmacro if-like
([test then] `(if-like ~test ~then nil))
([test then else]
`(my-case ~test
false ~else
nil ~else
~then)))
This is prolix and slow, and it uses stack and loses recur, which gets buried in the closures. However ...
(defn fact [n]
(if-like (pos? n)
(* (fact (dec n)) n)
1))
(map fact (range 10))
=> (1 1 2 6 24 120 720 5040 40320 362880)
... it works, more or less.
Please, dear reader, point out any errors in my code.

Related

Using parameters as operators in LISP lambda function (The Roots of Lisp)

I'm teaching myself lisp, mostly because I like the idea of being able to build programs from small axiomatic blocks. Learning lisp is a hobby project for me because i) it seems fun and ii) I want to see if it really does let me look at problems in a new way. To this end I'm working through Paul Graham's The Roots of Lisp article. I am using the SBCL implementation, though my issue occurs on other implementations also. I've encountered a problem trying to use parameters as operators in a lambda function:
((lambda (f) (f '(b c)))
'(lambda (x) (cons 'a x)))
Per section 2 of The Roots of Lisp, this should evaluate to (a b c). This makes sense, the second lambda is a parameter to the first. Assuming my understanding is correct, the expression simplifies to:
((lambda (x) (cons 'a x)) '(b c))
Fine. Running the latter works as expected. However, running the former, unsimplified, expression results in the error: The function COMMON-LISP-USER::F is undefined. Other SO questions (here and here) lead me to believe this is something to do with the function vs variable namespaces in CL, and I've tried the #' syntax in various ways, but I can't seem to get it to work the way I'd expect. What should I do?
Thanks!
You have two errors here:
You shouldn't quote this expression '(lambda (x) (cons 'a x)), it has to evaluate to function.
As Common Lisp is Lisp-2, you have to use funcall to get the function value of a symbol.
Correct code:
((lambda (f) (funcall f '(b c)))
(lambda (x) (cons 'a x)))
Having to quote lambdas is a feature in the articles lisp eval.. eval. is not Common Lisp but a lisp intepreter that works like the every first lisp from McCarthy's lisp paper.
In the roots of Lisp, just like McCarthy original paper, Paul Graham bootstraps a language description by showing properties of the language and under 2. Denoting functions also shows that functions can be parameters and that they are indeed quoted.
The reason for this is that the eval. does not have a term that evaluates lambda forms. Eg. if you were to not quote the evaluator will try to evaluate it as code and fail. This could be avoided by just adding one line making all lambda forms self evaluating. There is a commercial lisp called PicoLisp that has dynamic bindings and use very similar way to make anonymious functions today.
McCarthy defines eval in its own language since there was no excisting lisp to run it in. Paul uses Common Lisp since that is what he chose. Thus there is a big difference between the code language and what is expected as code to the eval. function. The very first Scheme was made under a Common Lisp predecessor and while the host language didn't have closures the interpreter had them as a core feature. In Lisp in small pieces you get to see lot of rewriting of a interpreter where you see giving a language some features often by its design will give it some disadvantages as well.
Just for fun, adding this to the eval. as first cond term will make it accept lamdbas unquoted:
((eq (car e) 'lambda) e)
Then this should work:
(eval. '((lambda (f) (f '(b c)))
(lambda (x) (cons 'a x)))
'())
Now you could change that line to store the environment a and use that instead of the dynamic a when appying. That would make it a lexical lisp.

Is there a standard argument sequence identity function in Clojure?

Is there a function in the Clojure standard library equivalent to the following?
(fn [& args] args)
If not, why?
Example usage:
(take 10 (apply (fn [& args] args) (range)))
;=> (0 1 2 3 4 5 6 7 8 9)
;; ironically, map isn't lazy enough, so let's take it up to 11
(defn lazy-map [f & colls]
(lazy-seq (cons (apply f (map first colls))
(apply lazy-map f (map rest colls)))))
(defn transpose [m]
(apply lazy-map (fn [& args] args) m))
(defn take-2d [rows cols coll]
(take rows (map (partial take cols) coll)))
(take-2d 3 3 (transpose (map (partial iterate inc) (range))))
;=> ((0 1 2) (1 2 3) (2 3 4))
Please note that I am not asking for a transformative, eager function such as vector or list.
There is no such function, you are free to implement and use it as you like:
(defn args [& args] args)
(set (map type (apply map args [[1 2 3][4 5 6][7 8 9]])))
=> #{clojure.lang.ArraySeq}
Why isn't it already available?
This is rarely fruitful question: not only we don't know what happens in the mind of implementors, it is impracticable to ask them to justify or document why they did not do something. Was adding this function ever considered? How can we know? Is there really a reason, or did it just happen?
On the other hand, I agree that args feels simpler because it passes around an already existing immutable sequence.
I also can understand if you think that not converting the arguments as a persistent list in the first place is better, if only for the sake of parcimony.
But this is not how it is implemented, and the overhead of using list is really negligible (and specialized when building from an instance of ArraySeq).
You are supposed to code to an interface and never look behind the curtain, and from this point of view, list and args are equivalent, even though they do not return identical results.
You added a remark about laziness, and you are right: if you ever need to take the arguments from a variadic function and pass it to a function which operates on sequences, The version with list will consume all the given arguments whereas args will not. In some cases, as with (apply list (range)), where you literally pass an infinite number of arguments, this might hang forever.
From that point of view, the little args function is in fact interesting: you can move from arguments to actual sequences without introducing potential problems.
I am however not sure how often this case happens in practice.
In fact, I have a hard time finding a use case where laziness in the argument list really matters as far as args is concerned.
After all, in order to pass an infinite sequence, the only way (?) is to use apply:
(apply f (infinite))
In order to have a use-case for args, that means that we want to convert from an argument list back to a single list so that another function g can use it as a sequence, like so:
(g (apply args (infinite)))
But in that case, we could directly call:
(g (infinite))
In your example, g would stand for cons inside lazy-map, but since f is given in input, we cannot write (cons (map ...) ...) directly. The example thus looks like a genuine use case for args, but you should document the function heavily because the snippet you gave is quite complex. I tend to think that giving an unbounded number of arguments to a function is a code smell: should every function with an [& args] signature avoid consuming all arguments because the given sequence might in fact be infinite, like lazy-map does? I'd rather have a single argument be a lazy sequence for this kind of usage (and pass identity where needed) instead of the whole argument list, to clarify the intent. But in the end, I am not strongly opposed to the use of args either.
So to conclude, unless you manage to convince Rich Hickey to add args as a core function, I am confident that almost nobody will want to depend on an external library which does just this1: it is unfamiliar, but also trivial to implement and mostly useless. The only reward is knowing that you skip a little transformation step which costs nothing in most cases. Likewise, do not worry about having to choose between a vector and a list: it has practically no influence on your code and you can still modify the code later if you can prove it is necessary.
Regarding laziness, while I agree that wrapping arguments in lists or vectors can be problematic with unbounded argument lists, I am not sure the problem actually arises in practice.
1. Of course, if it ever reaches clojure.core, everybody will be quick to say that is is a fundamental operation which is most useful and definitely idiomatic </cynic>
There's identity function. It takes an argument and just returns that argument. Clojure's identity is single arity though.
usage:
(identity 4) ;=> 4
(identity [1 2 3 4]) ;=> [1 2 3 4]
I don't think there's much sense in having the identity function with variable arity since Clojure functions return only one value. If you want to return multiple values from a function, then you can wrap them in a seq which you can later destructure. In that case you can have something like this:
(defn varity-identity [& args]
(map identity args))
(varity-identity 1 2 3 4 5) ;=> (1 2 3 4 5)
Hope this helps.

What is the advantage of a symbol that binds to a value and function at the same time?

In lisp, a symbol can be bound to both a value and a function at the same time.
For example,
Symbol f bound to a function
(defun f(x)
(* 2 x))
Symbol f bound to a value
(setq f 10)
So i write something like this:
(f f)
=> 20
What is the benefit of such a feature?
The symbol can have both a function and a value. The function can be retrieved with SYMBOL-FUNCTION and the value with SYMBOL-VALUE.
This is not the complete view. Common Lisp has (at least) two namespaces, one for functions and one for variables. Global symbols participate in this. But for local functions the symbols are not involved.
So what are the advantages:
no name clashes between identifiers for functions and variables.
Scheme: (define (foo lst) (list lst))
CL: (defun foo (list) (list list))
no runtime checks whether something is really a function
Scheme: (define (foo) (bar))
CL: (defun foo () (bar))
In Scheme it is not clear what BAR is. It could be a number and that would lead to a runtime error when calling FOO.
In CL BAR is either a function or undefined. It can never be anything else. It can for example never be a number. It is not possible to bind a function name to a number, thus this case never needs to be checked at runtime.
It's useful for everyday tasks, but the main reason is because of macros, you'll understand why once you study it.

Idiomatic way to pass a method name for evaluation in Clojure?

I'm passing the name of a function for use in another method.
(defn mapper [m function]
(cond
(= '() m) '()
true (cons (function (first m))
(mapper (rest m) function))))
(println (mapper '((blue red)(green red)(white red)) #'first))
Is there a more idiomatic way to do this in clojure?
Prefer vectors to lists. You don't have to quote a vector most of the time, and it has better performance for a lot of things, like random access. Lists are used much more rarely in Clojure than in other Lisps.
Prefer keywords to quoted symbols. Keywords stand out as "constant strings" or enumerated values. Keywords in Clojure can belong to a namespace, so they have all the advantages of symbols. And again, there's no need to quote keywords, which is nice. Quoted symbols are used pretty rarely in Clojure, unless you're writing macros.
#'first is the var called "first"; first is the value of the var called "first", i.e. the fn. In this case (#'first foo) and (first foo) give the same answer, but #'first does an extra dereference every time you call it. So don't do this unless you want that dereference to happen over and over. There's usually no need to use #'.
The built-in map is lazy, whereas yours isn't. The built-in map takes advantage of chunked seqs for better performance, whereas yours doesn't. Idiomatic code doesn't have to be lazy or use chunked seqs, but keep in mind that the builtins have some of this magic going on. So it's good to take advantage.
Rather than (= '() x), the idiomatic test for an empty seq is (seq x), which returns nil if x is empty. Note that in Clojure, (= '() nil) is false.
If you do ever need to use the empty list (which you should rarely need to do), you don't have to quote it. Just use ().
Built-in map takes the function argument first because it accepts multiple collection arguments. When a function takes multiple arguments, those arguments have to go last in the argument list. I think it reads better the other way too: "(map f coll): map this function across this collection".
There's no need to use cond if you only have two options. You can use if instead. And if one of the branches in your if returns nil, you can use when. It's nice to use when and if when appropriate, because they signal your intentions to the reader immediately, whereas cond could do anything and forces the reader to read more.
RafaƂ Dowgird's version is idiomatic, except I'd flip the order of arguments around. And I'd call it like this:
user> (mapper first [[:blue :red] [:green :red] [:white :red]])
(:blue :green :white)
I believe you got it mostly idiomatic. Clojure's own map uses:
(defn mapper [coll f]
(when-let [s (seq coll)]
(cons (f (first s)) (mapper (rest s) f))))
I have shortened it severely - the original produces a lazy sequence, deals with multiple collections, chunked-seqs, etc. By the way - I assume you want to pass the actual function, not it's name.
The coll and f are idiomatic arg names to represent collections and functions, respectively.
Your version looks good to me. The usual names you will see in the clojure code base is 'coll' for collections. I have also seen 'xs' which is the Haskell style, I think. You may also refer to the Clojure library coding standards on various conventions.
Coming back to the example: Two observations.
Use :else for 'cond' as the escape condition, instead of the Common Lisp style 'T'.
Instead of assuming lists, think sequences.
With these two in mind, if I rewrite your code:
user> (defn mapper [coll f]
(cond
(not (seq coll)) nil
:else (conj (mapper (next coll) f)
(f (first coll)))))
#'user/mapper
user> (mapper '(1 2 3) #(* % %))
(1 4 9)
user> (mapper [1 2 3] #(* % %))
(1 4 9)
Note that conj does the "right thing" as far as collections are concerned. It adds the new element to the head of a list, to the tail of a vector and so on. Also note the use of 'next' instead of the first/rest idioms in traditional lisp. 'next' returns a sequence of elements after the first element. So, empty-ness can be checked by seq'ing on the collection which will return nil for an empty list or an empty vector. This way it works for all collections.

What fun can be had with lambda-definitions?

Not having them used them all that much, I'm not quite sure about all the ways
lambda-definitions can be used (other than map/collect/do/lightweight local function syntax). For anyone interested in posting some examples:
provide explanations to help readers understand how lambda-definitions are being used;
preferred languages for the examples: Python, Smalltalk, Haskell.
You can make a functional data structure out of lambdas. Here is a simple one - a functional list (Python), supporting add and contains methods:
empty = lambda x : None
def add(lst, item) :
return lambda x : x == item or lst(x)
def contains(lst, item) :
return lst(item) or False
I just coded this quickly for fun - notice that you're not allowed to add any falsy values as is. It also is not tail-recursive, as a good functional structure should be. Exercises for the reader!
You can use them for control flow. For example, in Smalltalk, the "ifTrue:ifFalse:" method is a method on Boolean objects, with a different implementation on each of True and False classes. The expression
someBoolean ifTrue: [self doSomething] ifFalse: [self doSomethingElse]
uses two closures---blocks, in [square brackets] in Smalltalk syntax---one for the true branch, and one for the false branch. The implementation of "ifTrue:ifFalse:" for instances of class True is
ifTrue: block1 ifFalse: block2
^ block1 value
and for class False:
ifTrue: block1 ifFalse: block2
^ block2 value
Closures, here, are used to delay evaluation so that a decision about control flow can be taken, without any specialised syntax at all (besides the syntax for blocks).
Haskell is a little different, with its lazy evaluation model effectively automatically producing the effect of closures in many cases, but in Scheme you end up using lambdas for control flow a lot. For example, here is a utility to retrieve a value from an association-list, supplying an optionally-computed default in the case where the value is not present:
(define (assq/default key lst default-thunk)
(cond
((null? lst) (default-thunk)) ;; actually invoke the default-value-producer
((eq? (caar lst) key) (car lst))
(else (assq/default key (cdr lst) default-thunk))))
It would be called like this:
(assq/default 'mykey my-alist (lambda () (+ 3 4 5)))
The key here is the use of the lambda to delay computation of the default value until it's actually known to be required.
See also continuation-passing-style, which takes this to an extreme. Javascript, for instance, relies on continuation-passing-style and closures to perform all of its blocking operations (like sleeping, I/O, etc).
ETA: Where I've said closures above, I mean lexically scoped closures. It's the lexical scope that's key, often.
You can use a lambda to create a Y Combinator, that is a function that takes another function and returns a recursive form of it. Here is an example:
def Y(le):
def _anon(cc):
return le(lambda x: cc(cc)(x))
return _anon(_anon)
This is a thought bludgeon that deserves some more explanation, but rather than regurgitate it here check out this blog entry (above sample comes from there too).
Its C#, but I personally get a kick out of this article every time I read it:
Building Data out of Thin Air - an implementation of Lisp's cons, car, and cdr functions in C#. It shows how to build a simple stack data structure entirely out of lambda functions.
It isn't really quite the same concept as in haskell etc, but in C#, the lambda construct has (optionally) the ability to compile to an objcet model representing the code (expression-trees) rather than code itself (this is itself one of the cornerstones of LINQ).
This in turn can lead to some very expressive meta-programming opportunities, for example (where the lambda here is expressing "given a service, what do you want to do with it?"):
var client = new Client<ISomeService>();
string captured = "to show a closure";
var result = client.Invoke(
svc => svc.SomeMethodDefinedOnTheService(123, captured)
);
(assuming a suitable Invoke signature)
There are lots of uses for this type of thing, but I've used it to build an RPC stack that doesn't require any runtime code generation - it simply parses the expression-tree, figures out what the caller intended, translates it to RPC, invokes it, gathers the response, etc (discussed more here).
An example in Haskell to compute the derivative of a single variabled function using a numerical approximation:
deriv f = \x -> (f (x + d) - f x) / d
where
d = 0.00001
f x = x ^ 2
f' = deriv f -- roughly equal to f' x = 2 * x