Related
I would like to have a clear understanding, what is 'Atom' in LISP?
Due to lispworks, 'atom - any object that is not a cons.'.
But this definition is not enough clear for me.
For example, in the code below:
(cadr
(caddar (cddddr L)))
Is 'L' an atom? On the one hand, L is not an atom, because it is cons, because it is the list (if we are talking about object, which is associated with the symbol L).
On the other hand, if we are talking about 'L' itself (not about its content, but about the symbol 'L'), it is an atom, because it is not a cons.
I've tried to call function 'atom',
(atom L) => NIL
(atom `L) => T
but still I have no clue... Please, help!
So the final question: in the code above, 'L' is an atom, or not?
P.S. I'm asking this question due to LISP course at my university, where we have a definition of 'simple expression' - it is an expression, which is atom or function call of one or two atomic parameters. Therefore I wonder if expression (cddddr L) is simple, which depends on whether 'L' is atomic parameter or not.
Your Lisp course's private definition of "simple expression" is almost certainly rooted purely in syntax. The idea of "atomic parameter" means that it's not a compound expression. It probably has nothing to do with the run-time value!
Thus, I'm guessing, these are simple expressions:
(+ 1 2)
42
"abc"
whereas these are not:
(+ 1 (* 3 4)) ;; (* 3 4) is not an atomic parameter
(+ a b c) ;; parameters atomic, but more than two
(foo) ;; not simple: fewer than one parameter, not "one or two"
In light of the last counterexample, it would probably behoove them to revise their definition.
On the one hand, L is not an atom, because it is cons, because it is the list (if we are talking about object, which is associated with the symbol L).
You are talking here about the meaning of the code being executed, its semantics. L here stands for a value, which is a list in your tests. At runtime you can inspect values and ask about their types.
On the other hand, if we are talking about 'L' itself (not about its content, but about the symbol 'L'), it is an atom, because it is not a cons.
Here you are looking at the types of the values that make up the syntax of your code, how it is being represented before even being evaluated (or compiled). You are manipulating a tree of symbols, one of them being L. In the source code, this is a symbol. It has no meaning by itself other than being a name.
Code is data
Lisp makes it easy to represent source code using values in the language itself, and easy to manipulate fragments of code at one point to build code that is executed later. This is often called homoiconicity, thought it is somewhat a touchy word because people don't always think the definition is precise enough to be useful. Another saying is "code is data", something that most language designers and programmers will agree to be true.
Lisp code can be built at runtime as follows (> is the prompt of the REPL, what follows is the result of evaluation):
> (list 'defun 'foo (list 'l) (list 'car 'l))
(DEFUN FOO (L) (CAR L))
The resulting form happens to be valid Common Lisp code, not just a generic list of values. If you evaluate it with (eval *), you will define a function named FOO that takes the first element of some list L.
NB. In Common Lisp the asterisk * is bound in the REPL to the last value being successfully returned.
Usually you don't build code like that, the Lisp reader turns a stream of characters into such a tree. For example:
> (read-from-string "(defun foo (l) (car l))")
(DEFUN FOO (L) (CAR L))
But the reader is called also implicitly in the REPL (that's the R in the acronym).
In such a tree of symbols, L is a symbol.
Evaluation model
When you call function FOO after it has been defined, you are evaluating the body of FOO in a context where L is bound to some value. And the rule for evaluating a symbol is to lookup the value it is bound to, and return that. This is the semantics of the code, which the runtime implements for you.
If you are using a simple interpreter, maybe the symbol L is present somewhere at runtime and its binding is looked up. Usually the code is not interpreted like that, it is possible to analyze it and transform it in an efficient way, during compilation. The result of compilation probably does not manipulate symbols anymore here, it just manipulates CPU registers and memory.
In all cases, asking for the type of L at this point is by definition of the semantics just asking the type for whatever value is bound to L in the context it appears.
An atom is anything that is not a cons cell
Really, the definition of atom is no more complex than that. A value in the language that is not a cons-cell is called an atom. This encompasses numbers, strings, everything.
Sometimes you evaluate a tree of symbols that happens to be code, but then the same rule applies.
Simple expressions
P.S. I'm asking this question due to LISP course at my university, where we have a definition of 'simple expression' - it is an expression, which is atom or function call of one or two atomic parameters. Therefore I wonder if expression (cddddr L) is simple, which depends on whether 'L' is atomic parameter or not.
In that course you are writing functions that analyze code. You are given a Lisp value and must decide if it is a simple expression or not.
You are not interested in any particular interpretation of the value being given, at no point you are going to traverse the value, see a a symbol and try to resolve it to a value: you are checking if the syntax is a valid simple expression or not.
Note also that the definitions in your course might be a bit different than the one from any particular exising flavor (this is not necessarily Common Lisp, or Scheme, but a toy LISP dialect). Follow in priority the definitions from your course.
Imagine we have a predicate which tells us if an object is not a number:
(not-number-p 3) -> NIL
(not-number-p "string") -> T
(let ((foo "another string))
(not-number-p foo)) -> T
(not-number '(1 2 3)) -> T
(not-number (first '(1 2 3)) -> NIL
We can define that as:
(defun not-number-p (object)
(not (numberp object))
Above is just the opposite of NUMBERP.
NUMBERP -> T if object is a number
NOT-NUMBER-P -> NIL if object is a number
Now imagine we have a predicate NOT-CONS-P, which tells us if an object is not a CONS cell.
(not-cons-p '(1 . 2)) -> NIL
(let ((c '(1 . 2)))
(not-cons-p c)) -> NIL
(not-cons-p 3) -> T
(let ((n 4))
(not-cons-p n)) -> T
(not-cons-p NIL) -> T
(not-cons-p 'NIL) -> T
(not-cons-p 'a-symbol) -> T
(not-cons-p #\space) -> T
The function NOT-CONS-P can be defined as:
(defun not-cons-p (object)
(if (consp object)
NIL
T))
Or shorter:
(defun not-cons-p (object)
(not (consp object))
The function NOT-CONS-P is traditionally called ATOM in Lisp.
In Common Lisp every object which is not a cons cell is called an atom. The function ATOM is a predicate.
See the Common Lisp HyperSpec: Function Atom
Your question:
(cadr (caddar (cddddr L)))
Is 'L' an atom?
How would we know that? L is a variable. What is the value of L?
(let ((L 10))
(atom L)) -> T
(let ((L (cons 1 2)))
(atom L) -> NIL
(atom l) answers this question:
-> is the value of L an atom
(atom l) does not answer this question:
-> is L an atom? L is a variable and in a function call the value of L is passed to the function ATOM.
If you want to ask if the symbol L is an atom, then you need to quote the symbol:
(atom 'L) -> T
(atom (quote L)) -> T
symbols are atoms. Actually everything is an atom, with the exception of cons cells.
I’m trying to get get my macro to do an extra evaluation of its result before returning it. Can this be done without eval?
I'm trying to solve the problem in exercise 4 below:
Define a macro nth-expr that takes an integer n and an arbitrary number of expressions, evaluates the nth expression and returns its value. This exercise is easy to solve, if you assume that the first argument is a literal integer.
4. As exercise 3, but assume that the first argument is an expression to be evaluated.
It's easy to get the macro to pick the right expression:
(defmacro nth-expr% (n &rest es)
`(nth ,n ',es))
CL-USER> (defvar i 1)
I
CL-USER> (nth-expr% (1+ i) (+ 2 3) (- 4 3) (+ 3 1))
(+ 3 1)
The expression (+ 3 1) is the one we want, but we want the macro to evaluate it to 4 before returning it.
It can of course be done with eval:
(defmacro nth-expr%% (n &rest es)
`(eval (nth ,n ',es)))
CL-USER> (nth-expr%% (1+ i) (+ 2 3) (- 4 3) (+ 3 1))
4
But is there another way?
It feels like the solution should be to put the body of nth-expr% in a helper macro and have the top level macro only contain an unquoted call to this helper:
(defmacro helper (n es)
`(nth ,n ',es))
(defmacro nth-expr (n &rest es) ; doesn't work!
(helper n es))
The idea is that the call to helper would return (+ 3 1), and this would then be the expansion of the call to nth-expr, which at run-time would evaluate to 4. It blows up, of course, because N and ES get treated like literals.
That's not that easy.
Using eval is not good, since eval does not evaluate the code in the local lexical environment.
Remember, if we allow an expression to be evaluated to determine the number of another expression to execute, then we don't know this number at macro expansion time - since the expression could be based on a value that needs to be computed - for example based on some variable:
(nth-expression
foo
(bar)
(baz))
So we might want to think about code which does that:
(case foo
(0 (bar))
(1 (baz)))
CASE is evaluating foo and then uses the result to find a clause which has the same value in its head. The consequent forms of that clause then will be evaluated.
Now we need to write code which expands the former into the latter.
This would be a very simple version:
(defmacro nth-expression (n-form &body expressions)
`(case ,n-form
,#(loop for e in expressions
and i from 0
collect `(,i ,e))))
Question: what might be drawbacks of using CASE like that?
Knuto: Rainer Joswig may be asking you to think about how the case statement works. Namely, that after evaluating the keyform (ie, the first argument), it will be compared sequentially to the key in each clause until a match is found. The comparisons could be time consuming if there are many clauses. You can discover this by carefully reading the entry for case in the Hyperspec (as he more than once has insisted I do):
The keyform or keyplace is evaluated to produce the test-key. Each of
the normal-clauses is then considered in turn.
Also note that constructing many case clauses will add to the time to expand and compile the macro at compile time.
Regarding your use of eval in nth-expr%%, you can still achieve the effect of an eval by switching to apply:
(defmacro nth-expr%% (n &rest es)
`(let ((ne (nth ,n ',es)))
(apply (car ne) (cdr ne))))
But see Plugging the Leaks at http://www.gigamonkeys.com/book/macros-defining-your-own.html about a more robust treatment.
In general, a more efficient way to process the expressions is as a simple vector, rather than a list. (The problem statement does not rule out a vector representation.) While nth and case involve searching through the expressions one-by-one, a function like aref or svref can directly index into it. Assuming a vector of expressions is passed to the macro along with an index, perhaps first requiring (coerce expressions 'simple-vector) if a list, then the result can be computed in constant time no matter how many expressions there are:
(defmacro nth-expr%%% (n es)
`(let ((ne (svref ',es ,n)))
(apply (car ne) (cdr ne))))
so that now
(defvar i 1)
(nth-expr%%% (1+ i) #((+ 2 3) (- 4 3) (+ 3 1))) -> 4
I am using Racket and Dr. Racket.
There is built-in function called andmap.
The built-in version of andmap works this way:
> (andmap positive? '(1 2 3))
#t
Function number usually works as:
(number? 3)
> #t
(number? '())
>#f
I do not get why this happens:
(andmap number? '())
> #t
I think the result should be false.
The documentation says:
*If the lsts are empty, then #t is returned.*
Why on earth would that make sense? I do not see it. I am curious about the design choices of languages, specially new ones, like Racket.
The reason (andmap pred '()) returns #t is exactly the same reason (and) returns #t… but that’s perhaps not the most useful explanation, is it? The real answer is that #t is the identity for logical AND, just like 0 is the additive identity and 1 is the multiplicative identity:
> (+)
0
> (*)
1
> (and)
#t
> (or)
#f
The idea here is that the identity will not change the output when combined with any given input. For example, just like (+ 0 x) is always x and (* 1 x) is always x, (and #t x) is always x and (or #f x) is always x. This is a useful property to have, since it cooperates well with the idiomatic way to sum a list in Scheme, (apply + lst):
> (apply + '(1 2 3))
6
> (apply + '())
0
Similarly, (apply * lst) can be used instead of a separate product function. The and and or operators cannot be used with apply, since they are short-circuiting and are thus implemented as macros instead of functions, but andmap and ormap implement that functionality instead.
If that argument doesn’t seem satisfying enough to you, you can also think about these things in their plain English definitions to come to the same conclusion. What does the andmap operation mean? Well, it asks a question: “Do all of the elements in this list satisfy a predicate?” On an empty list, the answer will always be yes, given that you cannot possibly produce a counterexample to that claim.
In contrast, ormap is the dual: “Does at least one of the elements in this list satisfy a predicate?” The answer will always be no, since it’s impossible to produce any element at all, so producing one that satisfies a predicate is surely impossible.
If Racket's match macro were a function I could do this:
(define my-clauses (list '[(list '+ x y) (list '+ y x)]
'[_ 42]))
(on-user-input
(λ (user-input)
(define expr (get-form-from-user-input user-input)) ; expr could be '(+ 1 2), for example.
(apply match expr my-clauses)))
I think there are two very different ways to do this. One is to move my-clauses into macro world, and make a macro something like this (doesn't work):
(define my-clauses (list '[(list '+ x y) (list '+ y x)]
'[_ 42]))
(define-syntax-rule (match-clauses expr)
(match expr my-clauses)) ; this is not the way it's done.
; "Macros that work together" discusses this ideas, right? I'll be reading that today.
(on-user-input
(λ (user-input)
(define expr (get-form-from-user-input user-input)) ; expr could be '(+ 1 2), for example.
(match-clauses expr)))
The alternative, which might be better in the end because it would allow me to change my-clauses at runtime, would be to somehow perform the pattern matching at runtime. Is there any way I can use match on runtime values?
In this question Ryan Culpepper says
It's not possible to create a function where the formal parameters and body are given as run-time values (S-expressions) without using eval.
So I guess I'd have to use eval, but the naive way won't work because match is a macro
(eval `(match ,expr ,#my-clauses) (current-namespace))
I got the desired result with the following voodoo from the guide
(define my-clauses '([(list'+ x y) (list '+ y x)]
[_ 42]))
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(eval `(match '(+ 1 2) ,#my-clauses) ns) ; '(+ 2 1)
Is the pattern matching happening at runtime now? Is it a bad idea?
To answer the first part of your question (assuming you don't necessarily need the match clauses to be supplied at runtime):
The key is to:
Define my-clauses for compile time ("for syntax").
Reference that correctly in the macro template.
So:
(begin-for-syntax
(define my-clauses (list '[(list '+ x y) (list '+ y x)]
'[_ 42])))
(define-syntax (match-clauses stx)
(syntax-case stx ()
[(_ expr) #`(match expr #,#my-clauses)]))
The pattern matching is happening at runtime in the last example.
One way to check is to look at the expansion:
> (syntax->datum
(expand '(eval `(match '(+ 1 2) ,#my-clauses) ns)))
'(#%app eval (#%app list* 'match ''(+ 1 2) my-clauses) ns)
Whether is a good idea...
Using eval is rather slow, so if you call it often it might be better to find another solution. If you haven't seen it already you might want to read "On eval in dynamic languages generally and in Racket specifically." on the Racket blog.
Thank you both very much, your answers gave me much food for thought. What I am trying to do is still not very well defined, but I seem to be learning a lot in the process, so that's good.
The original idea was to make an equation editor that is a hybrid between paredit and a computer algebra system. You enter an initial math s-expression, e.g. (+ x (* 2 y) (^ (- y x) 2). After that the program presents you with a list of step transformations that you would normally make by hand: substitute a variable, distribute, factor, etc. Like a CAS, but one step at a time. Performing a transformation would happen when the user presses the corresponding key combination, although one possibility is to just show a bunch of possible results, and let the user choose the new state of the expression amongst them. For UI charterm will do for now.
At first I thought I would have the transformations be clauses in a match expression, but now I think I'll make them functions that take and return s-expressions. The trouble with choosing compile time vs runtime is that I want the user to be able to add more transformations, and choose his own keybindings. That could mean that they write some code which I require, or they require mine, before the application is compiled, so it doesn't force me to use eval. But it may be best if I give the user a REPL so he has programmatic control of the expression and his interactions with it as well.
Anyway, today I got caught up reading about macros, evaluation contexts and phases. I'm liking racket more and more and I'm still to investigate about making languages... I will switch to tinkering mode now and see if I get some basic form of what I'm describing to work before my head explodes with new ideas.
In elisp I can evaluate or as a function just like +.
(or nil 0 nil) ==> 0
(+ 1 0 1) ==> 2
I can use apply to apply + to a list
(apply '+ '(1 0 1)) ==> 2
So, I would think or would work the same way, but it doesn't.
(apply 'or '(nil 0 nil)) ==> error: (invalid-function or)
I imagine this comes from some internal magic used to implement the short-circuit evaluation. How can I use apply to execute the or operation over a list?
P.S. my desired application is to find out whether any elements on the command line match a particular pattern, so the important part of what I am writing is:
(apply 'or (mapcar (lambda (x) (string-match-p "pattern" x)) command-line-args))
But it doesn't work
The problem is that or is a macro (which is the "internal magic" in question), and you're right that that's done so it can do short-circuiting. If or was a function, then calling it would need to follow the usual rules for evaluating a function call: all the arguments would need to get evaluated before the call is made.
See also this question -- it's about Scheme but it's the exact same issue.
As for a solution, you should probably use some, as in:
(some (lambda (x) (string-match-p "pattern" x)) command-line-args)
Note: this uses common lisp that is not included in emacs by default. Just use (require 'cl)
If it makes you feel any better, you're in good company! This is the third question in the "Common Pitfalls" section of the Lisp FAQ:
Here's the simple, but not necessarily satisfying, answer: AND and OR are
macros, not functions; APPLY and FUNCALL can only be used to invoke
functions, not macros and special operators.
...and Eli is of course right on the money with his suggestion to use SOME:
The Common Lisp functions EVERY and SOME can be used to get the
functionality you intend when trying to apply #'AND and #'OR.
(The FAQ and this answer are mostly about Common Lisp but in this case if you omit the # character the answer is the same.)
If you don't care performance, use (eval (cons 'or '(nil 0 nil)))
When I was trying to 'apply' a macro to an argument list, I got an error that the function is unbound, which means that, 'apply' only receives a function, instead of a macro, as its first argument.
In order to fix this, I wrote a new function 'apply-macro' as follows:
(defun apply-macro (macro arg-list)
(eval
`(,macro ,#(loop for arg in arg-list
collect `(quote ,arg)))))
For instance, I wrote a macro to concatenate multiple lists together:
(defmacro conc-lists (&rest lists)
`(funcall #'concatenate 'list ,#lists))
e.g.
(conc-lists '(a b) '(c d) '(e f)) ;;=> (A B C D E F)
Now try 'apply-macro':
(apply-macro 'conc-lists '((a b) (c d) (e f)))
It works and returns the same output.
In fact, it will be expanded into:
(eval
(conc-lists (quote (a b)) (quote (c d)) (quote (e f))))
You can also pass a form to a macro:
(apply-macro 'conc-lists (maplist #'list '(a b c)))
;;=> ((A B C) (B C) (C))
Get back to your question, it's solved:
(apply-macro 'or '(nil 0 nil)) ;;=> 0
I'm only guessing here, but I think or might be one of these 20-odd 'functions' in lisp that are not really functions, since they don't always evaluate all parameters.
This makes sense to make or one of these, since if you have found one TRUE, you can stop searching. In other words, or is not a function as a form of optimization. Still only guessing though.
Eli Barzilay's answer is correct and idiomatic. I want to provide an alternative answer based on dash.el, the library I use to write terse functional-style code, when I have to work with lists. or returns the first non-nil element, nil otherwise, due to short-circuiting. Therefore simply use -first:
(-first 'identity '(nil 0 1 nil)) ; 0
(-first 'identity '(nil nil)) ; nil
identity function simply returns its argument. Which is clever, because -first applies a predicate until it returns non-nil. identity returns non-nil if the argument is itself non-nil. If you simply want to test whether there is non-nil elements in a list, use -any? instead:
(-any? 'identity '(nil 0 1 nil)) ; t
(-any? 'identity '(nil nil)) ; nil