How can I cause a Clojure macro to act as a function, so I can pass it as an argument for example? I would expect to have to wrap it somehow.
I would not expect the wrapped version to behave exactly the same as the original macro (differences of call by name vs call by value), but it would be useful in a few cases where this wasn't important.
If I'm understanding you correctly, you can just wrap it in a function.
Consider this (silly) implementation of a squaring function as a macro:
(defmacro square [x]
(list * x x))
Passing it directly as an arg won't work, as you know:
user=> (map square [1 2 3 4 5])
java.lang.Exception: Can't take value of a macro: #'user/square (NO_SOURCE_FILE:8)
But wrapping it in a function will do the trick:
user=> (map #(square %) [1 2 3 4 5])
(1 4 9 16 25)
Alternatively (and quite a bit more evil-ly), you could make another macro to do a more generic wrapping:
(defmacro make-fn [m]
`(fn [& args#]
(eval `(~'~m ~#args#))))
user=> (map (make-fn square) [1 2 3 4 5])
(1 4 9 16 25)
I'd stick with the normal function wrapping, and skip this last hack! :)
There is a dangerous, deprecated macro that you should not ever use. :-P
http://clojure.github.com/clojure-contrib/apply-macro-api.html
For the crazy macro make-fn, how about the one below?
It should work as well, and hopefully easier to understand.
(defmacro make-fn [m]
`(fn [& args#]
(eval
(cons '~m args#))))
Related
I am seeing different behavior of coerce between different versions of Common Lisp - wondering which one is "right" or is the standard ambiguous on this seemingly simple question:
is
(coerce '(1 2 3) 'array)
correct lisp? It works fine in Clozure Common Lisp but not in sbcl.
And when it does not work what is the easiest way to coerce a list into an array?
Thanks
The specification says:
If the result-type is a recognizable subtype of vector, and the object is a sequence, then the result is a vector that has the same elements as object.
array is not a subtype of vector -- vectors are 1-dimensional arrays, but array includes arrays with any number of dimensions.
You can use one of these
(coerce '(1 2 3) 'vector)
(coerce '(1 2 3) '(array t (*)))
In the second version, (*) specifies a single dimension whose size is unspecified.
Your use is unspecified, so implementations are free to implement it as they please. If it returns a value, the value has to be an ARRAY of some kind.
To add to Barmar's answer (this is really a comment, but it's too long), while it's fine for CCL to do what it does, I think it's clear that something like this would be very hard to define in a standard.
Consider something like this:
(coerce '((1 2 3) (4 5 6) (7 8 9)) 'array)
What is the result of this meant to be? Should it be:
a vector each of whose elements is a three-element list?
the equivalent of (make-array '(3 3) :initial-contents '((1 2 3) (4 5 6) (7 8 9)))?
the transpose of that array?
I think either of the first two are reasonable interpretations: sometimes you will want one, sometimes the other. The third is probably not reasonable given CL is a row-major language.
So if (coerce ... 'array) were in the standard, how would you specify which of these you wanted? If you just chose one, which should it be (and how do you now reach agreement with the people on the committee who think it should be the other!)?
I was reading Roots of Lisp by Paul Graham where he claims that any lisp functionality can be build with the combination of this 7 base functions: quote, atom, eq, cond, cons, car, cdr.
Question: are Lisp dialects really based solely on those functions? How can we define a 'sum' or 'plus' function using the aforementioned 7 primitive functions? e.g. Our own (+ 1 2) function
Note: I'm totally newbie to Lisp but I'm also starting to get very excited about the language. The purpose of this question is purely genuine interest
The author refers to a very famous paper written in 1960 by the Turing Award and Lisp inventor John McCarthy “Recursive Functions of Symbolic Expressions and Their Computation by Machine”, in which he defined the semantics of Lisp as a new computational formalism, equivalent in power to the Turing Machine.
In the paper (and in the Lisp 1.5 Manual) McCarthy described the interpreter for the language, that can be completely written by using only the seven primitive functions mentioned by Graham.
The language was devoted primarily to symbolic computations, and the interpreter presented in the papers concerned only those computations, without resorting to numbers or other data types different from atoms and pairs.
As Graham says in a note at page 11 of Root of Lisp, “It is possible to do arithmetic in McCarthy's 1960 Lisp by using e.g. a list of n atoms to represent the number n”, so performing a sum is simply equivalent to appending two lists.
Of course this way of doing is very inefficient: it is presented only to show the equivalence with other computational formalisms, and in the real interpreters/compilers integers are represented as usual, and have the usual operators.
as far as i remember, there was also an approach to do this using list nesting level (don't really remember, where). Starting from () as zero, (()) == 1 and so on. Then you can simply define inc as list and dec as car:
CL-USER> (defun zero? (x) (eq () x))
ZERO?
CL-USER> (zero? nil)
T
CL-USER> (zero? 1)
NIL
CL-USER> (defparameter *zero* ())
*ZERO*
CL-USER> (defun inc (x) (list x))
INC
CL-USER> (defun dec (x) (car x))
DEC
CL-USER> (defun plus (x y)
(if (zero? y) x (plus (inc x) (dec y))))
PLUS
CL-USER> (plus *zero* (inc (inc *zero*)))
((NIL))
CL-USER> (defparameter *one* (inc *zero*))
*ONE*
CL-USER> (defparameter *two* (inc *one*))
*TWO*
CL-USER> (defparameter *three* (inc *two*))
*THREE*
CL-USER> (plus *two* *three*)
(((((NIL)))))
CL-USER> (equal *two* (dec (dec (dec (plus *two* *three*)))))
T
TL; DR: No. Modern lisp systems have many more primitives than the first lisp and a new primitives are needed for each new primitive data type.
The first Lisp didn't have numbers but it was turing complete. That means it can do any computation that is possible in any other language, but it doesn't mean it would be practical to do so. Number were not hard to mimic, but calculations were slow. There are rumers today about slow arithmetic dating back pre Lisp 1.5.
When I made my first lisp interpreter I couldn't care much for numbers. It's not really an interesting aspect of an interpreter. I did however implement fibonacci as an example and this is how it looks like:
;; This is NOT Common Lisp code. It's Zozotez
(setq + (lambda (x y)
(if x (cons (car x)
(+ (cdr x) y))
y)))
(setq - (lambda (z w)
(if w (- (cdr z)
(cdr w))
z)))
(setq fibonacci
(lambda (n a1 a2)
(if n
(fibonacci (- n '(1))
a2
(+ a2 a1))
a1)))
(fibonacci '(1 1 1 1 1 1 1 1 1) () '(1))
; ==> (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
No numbers! (1 in my language is a symbol so it needs to be quoted or else it will be evaluated like a variable)
As alternative number system I have implemented a positional system, pretty much like how we write numbers with the same rules for adding/multiplying etc. Perhaps a tad faster than lits of length n but more complex to make.
If the Lisp has closures you can do church numerals. Using the same as lambda calculus you can compute anything with just closures. You only need one primitive, lambda. (Again, not the easiest to work with)
I'm trying to write a function that can calculate GPA. Now I can do limited calculation(only 3 ),but I stuck on how to calculate more , without using loop or recursion (that's the requirement of subject) how to expend nth function? like: (nth n) ,if so ,is that mean i need to write a lambda expression? As an newbie, I maynot describe the question clearly, really need some help..
Glist is grade points Clist is credit hours.
GPA=( gradepoint *credithour + gradepoint *credithour) / ( the sum of credithour) like: (3*1+3*2+4*1)/(1+2+1)
here is my code:
(defun gpa (Glist Clist)
(format t "~3,2f~%"
(/
(+(nth 0 (mapcar #' * Glist Clist))
(nth 1 (mapcar #' * Glist Clist))
(nth 2 (mapcar #' * Glist Clist)))
(+ (nth 0 Clist)
(nth 1 Clist)
(nth 2 Clist))
);end "/"
);end "format"
(values) );end
EDIT
This seems like a good opportunity to emphasize some common (little c) Lisp ideas, so I fleshed out my answer to illustrate.
As mentioned in another answer, you could use a sum function that operates on lists (of numbers):
(defun sum (nums)
(reduce #'+ nums))
The dot product is the multiplicative sum of two (equal-length) vectors:
(defun dot-product (x y)
(sum (mapcar #'* x y)))
The function gpa is a simple combination of the two:
(defun gpa (grades credits)
(/ (dot-product grades credits) (sum credits)))
The example from the question results in the answer we expect (minus being formatted as a float):
(gpa '(3 3 4) '(1 2 1))
> 13/4
There are a few things worth mentioning from this example:
You should learn about map, reduce, and their variants and relatives. These functions are very important to Lisp and are very useful for operating on lists. map* functions generally map sequences to a sequence, and reduce usually transforms a sequence into to a single value (you can however use forms like (reduce #'cons '(1 2 3))).
This is a good example of the "bottom-up" approach to programming; by programming simple functions like sum that are often useful, you make it easy to write dot-product on top of it. Now the gpa function is a simple, readable function built on top of the other two. These are all one-liners, and all are easily readable to anyone who has a basic knowledge of CL. This is in contrast to the methodology usually applied to OOP.
There is no repetition of code. Sure, sum is used more than once, but only where it makes sense. You can do very little more to abstract the notion of a sum of the elements of a list. It's more natural in Scheme to write functions with functions, and that's a whole different topic. This is a simple example, but no two functions are doing the same thing.
If you're using nth to traverse a list, you're doing it wrong. In this case, you might want to write a summing function:
(defun sum (items)
(reduce #'+ items))
I never really thought about this until I was explaining some clojure code to a coworker who wasn't familiar with clojure. I was explaining let to him when he asked why you use a vector to declare the bindings rather than a list. I didn't really have an answer for him. But the language does restrict you from using lists:
=> (let (x 1) x)
java.lang.IllegalArgumentException: let requires a vector for its binding (NO_SOURCE_FILE:0)
Why exactly is this?
Mostly readability, I imagine. Whenever bindings are needed in Clojure, a vector is pretty consistently used. A lot of people agree that vectors for bindings make things flow better, and make it easier to discern what the bindings are and what the running code is.
Just for fun:
user=> (defmacro list-let [bindings & body] `(let ~(vec bindings) ~#body))
#'user/list-let
user=> (macroexpand-1 '(list-let (x 0) (println x)))
(clojure.core/let [x 0] (println x))
user=> (list-let (x 0 y 1) (println x y))
0 1
nil
This is an idiom from Scheme. In many Scheme implementations, square brackets can be used interchangeably with round parentheses in list literals. In those Scheme implementations, square brackets are often used to distinguish parameter lists, argument lists and bindings from S-expressions or data lists.
In Clojure, parentheses and brackets mean different things, but they are used the same way in binding declarations.
Clojure tries very hard to be consistent. There is no technical reason with a list form could not have been used in let, fn, with-open, etc... In fact, you can create your own my-let easily enough that uses one instead. However, aside from standing out visibly, the vector is used consistently across forms to mean "here are some bindings". You should strive to uphold that ideal in your own code.
my guess is that it's a convention
fn used it, defn used it, loop uses.
it seems that it's for everything that resembles a block of code that has some parameters; more specific, the square brackets are for marking those parameters
other forms for blocks of code don't use it, like if or do. they don't have any parameters
Another way to think about this is that let is simply derived from lambda. These two expressions are equivalent:
((fn [y] (+ y 42)) 10)
(let [y 10] (+ 42 y))
So as an academic or instructional point, you could even write your own very rudimentary version of let that took a list as well as a vector:
(defmacro my-let [x body]
(list (list `fn[(first x)]
`~body)
(last x)))
(my-let (z 42) (* z z))
although there would be no practical reason to do this.
Embarrassingly enough, I'm having some trouble designing this macro correctly.
This is the macro as I have it written:
(defmacro construct-vertices
[xs ys]
(cons 'draw-line-strip
(map #(list vertex %1 %2) xs ys)))
It needs to take in two collections or seqs, xs and ys, and I need it to give me…
(draw-line-strip (vertex 0 1) (vertex 1 1)
(vertex 3 3) (vertex 5 6)
(vertex 7 8))
…for xs = [0 1 3 5 7] and ys = [1 1 3 6 8].
This works just fine if I give my macro plain 'n' simple vectors (e.g. [1 2 3 4] and [2 3 4 5]) but doesn't work if I give it a lazy-seq/anything that needs to be evaluated like (take 16 (iterate #(+ 0.1 %1) 0)) and (take 16 (cycle [0 -0.1 0 0.1])))).
I realize that this is because these are passed to the macro unevaluated, and so I get, for example, (vertex take take) as my first result (I do believe). Unfortunately, everything I've tried to first evaluate these and then carry out my macro-rewriting has failed/looked terribly hacky.
I'm sure I'm missing some sort of basic syntax-quote/unquote pattern here–I'd love some help/pointers!
Thanks so much.
EDIT I should mention, draw-line-strip is a macro, and vertex creates an OpenGL vertex; they are both part of the Penumbra Clojure+OpenGL library.
EDIT 2 This is for a custom graphing tool I need, and the primary motivation for creating it was to be faster than JFreeCharts and company.
EDIT 3 I suppose I should note that I do have a macro version working, it's just horrid and hacky as I mentioned above. It uses eval, as demonstrated below, but like this:
(defmacro construct-vertices
[xs ys]
(cons 'draw-line-strip
(map #(list vertex %1 %2) (eval xs) (eval ys))))
Unfortunately, I get…
error: java.lang.ClassFormatError: Invalid this class index 3171 in constant pool in class file tl/core$draw_l$fn__9357 (core.clj:14)
…when using this with a few thousand-item long list(s). This is because I'm writing far too much into the pre-compiled code, and the classfile can't handle (I suppose) that much data/code. It looks like I need to, somehow, obtain a function version of draw-line-strip, as has been suggested.
I'm still open, however, to a more elegant, less hackish, macro solution to this problem. If one exists!
I looked at the macro expansion for draw-line-strip and noticed that it just wraps the body in a binding, gl-begin, and gl-end. So you can put whatever code inside it you want.
So
(defn construct-vertices [xs ys]
(draw-line-strip
(dorun (map #(vertex %1 %2) xs ys))))
should work.
Why not something like this, using function instead of macro:
(defn construct-vertices [xs ys]
(apply draw-line-strip (map #(list vertex %1 %2) xs ys)))
That should call draw-line-strip with required args. This example is not the best fit for macros, which shouldn't be used where functions can do.
Note: I didn't try it since I don't have slime set up on this box.
EDIT: Looking again, I don't know if you want to evaluate vertex before calling draw-line-strip. In that case function will look like:
(defn construct-vertices [xs ys]
(apply draw-line-strip (map #(vertex %1 %2) xs ys)))
If you really need draw-line-strip to be a macro and you want a fully general method of doing what the question text describes and you don't care too much about a bit of a performance hit, you could use eval:
(defn construct-vertices [xs ys]
(eval `(draw-line-strip ~#(map #(list 'vertex %1 %2) xs ys))))
; ^- not sure what vertex is
; and thus whether you need this quote
Note that this is terrible style unless it is really necessary.
This looks like a typical problem with some of the macro systems in Lisp. The usual Lisp literature applies. For example On Lisp by Paul Graham (uses Common Lisp).
Usually a macro uses the source it encloses and generates new source. If a macro call is (foo bar), and the macro should generate something different based on the value of bar, then this is generally not possible, since the value of bar is generally not available for the compiler. BAR really has only a value at runtime, not when the compiler expands the macros. So one would need to generate the right code at runtime - which might be possible, but which is usually seen as bad style.
In these macro systems macros can't be applied. A typical solution looks like this (Common Lisp):
(apply (lambda (a b c)
(a-macro-with-three-args a b c))
list-of-three-elements)
It is not always possible to use above solution, though. For example when the number of arguments varies.
It's also not a good idea that DRAW-LINE-STRIP is a macro. It should better be written as a function.