I'm learning lisp and have a question about a simple list:
(setq stuff '(one two three (+ 2 2)))
stuff ; prints "one two three (+ 2 2)"
(setq stuff (list `one `two `three (+ 2 2)))
stuff ; prints "one two three 4"
The first setq creates a list "one two three (+ 2 2)". The second list creates "one two three 4". Why does the first list not evaluate the (+ 2 2), but the second one does? I read in the Emacs Lisp intro documentation that when the list is built that it evaluates from the inside out. Why doesn't the first list evaluate the addition before adding it to the list?
This is elisp in emacs 24.
' is not equivalent to list, it's shorthand for quote. You're really doing this:
(setq stuff (quote (one two three (+ 2 2))))
The argument to quote is the expression (one two three (+ 2 2)).
From http://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html: "The special form quote returns its single argument, as written, without evaluating it".
Looks like you're coming to grips with the evaluation semantics of Lisp, so keep playing around!
You can think of quote as suppressing evaluation of its argument. This allows you to write expressions that you can manipulate or pass around. It is also used to write data structures that should not be evaluated as function calls.
Data structures:
'(1 2 3) ; => '(1 2 3)
(1 2 3) ; => Lisp error: (invalid-function 1)
;; The Lisp reader sees the number 1 in the function position and tries to call it, signalling an error.
Syntax transformations:
(setq x '(string-to-int "123"))
(setf (car x) 'string-to-list)
x ; => '(string-to-list "123")
Delayed evaluation:
(setq x '(message "Hello World")) ; => '(message "Hello World")
(eval x) ; => "Hello World"
There is a closely related special operator called syntax quote, written using the backtick. It allows you to evaluate individual forms in a quoted expression using the comma ( , ) operator. It is like quote with an escape hatch.
`(1 2 (+ 3 4)) ; => '(1 2 (+ 3 4))
`(1 2 ,(+ 3 4)) ; => '(1 2 7) ;; Note the comma!
Syntax quote also permits list splicing using the ,# syntax:
`(1 2 ,#(+ 3 4)) ; => '(1 2 + 3 4)
As you can see, it splices the subsequent expression into the containing one. You probably won't see it all that often until you start writing macros.
list on the other hand is a simple function. It evaluates its arguments, then returns a new data structure containing these items.
(list 1 2 (+ 3 4)) ; => '(1 2 7)
Related
As far as I understand #' <object> is an abbreviation for (function <object>).
But I noticed different behaviour while using #' in apply function.
Example
(apply '+ '(1 2)) => Works and give 3
(apply (function +) '(1 2 ) ) => 3
However
(apply '# '(1 2)) => Err!!
As described in the reference:
The notation #'name may be used as an abbreviation for (function name).
Note that the syntax used is #', not '#, which is just a way a quoting the symbol #, since 'a is equivalent to (quote a).
So you should use:
(apply #'+ '(1 2))
In general the character # followed by a character has a special meaning for inputting values. For instance #\ is for reading characters (like in #\Space), #( for reading vectors, (like in #(1 2 3)), etc.
The #' notation is implemented by the reader.
If you want to see the effect, you can for example use this:
CL-USER 1 > (read-from-string "#'+")
(FUNCTION +)
3
CL-USER 2 > '#'+
(FUNCTION +)
Some output from the CLISP REPL:
[1]> (list 'list 1 2 3)
(LIST 1 2 3)
[2]> (list 'list '(1 2 3))
(LIST (1 2 3))
[3]> (list 'quote 1 2 3)
(QUOTE 1 2 3)
[4]> (list 'quote '(1 2 3))
'(1 2 3)
The first three, I understand exactly what's going on: The list function is passed a symbol ('list or 'quote) and so the result is a list that begins with the list or quote symbol. It's the fourth that confuses me. Why doesn't it return (QUOTE (1 2 3))?
I realise that if you enter (QUOTE '(1 2 3)) into the REPL, you get '(1 2 3) back, so the expression are equivalent in that sense. But (LIST 1 2 3) is equivalent to (1 2 3), and yet the first expression doesn't return that.
It seems inconsitent that (list 'quote 1 2 3) returns a list with the first item being a quote symbol, but (list 'quote (1 2 3)) returns a quoted list. Especially since expressions like (list 'list ...) seem to always return a list beginning with the symbol - so far, at least, quote is the only 'special case' like this.
It's not the easiest question to articulate, so I'm hoping I've managed to get my confusion across. Can anyone explain why quote gets treated in this seemingly-unique way?
'something is the same as (quote something) for the lisp reader. Even when nested it will be the case. The next expressions I will double quote so that after evaluation one of the quotes are still in there.
When printing the implementations can choose what to output where there are several possible representations, so some implementations would print the evaluation of ''something as
(quote something) while others may use the abbreviation 'something.
'(quote 1 2 3) cannot be abbreviated since a quoted form only has one argument. Thus here both lisp systems would print (quote 1 2 3).
Here is a way to look at your last expression:
(let ((data (list 'quote '(1 2 3))))
(format nil
"whole thing: ~a first element: ~a second-element: ~a"
data
(car data)
(cadr data)))
This will either evaluate to "whole thing: '(1 2 3) first element: QUOTE second-element: (1 2 3)" or "whole thing: (QUOTE (1 2 3)) first element: QUOTE second-element: (1 2 3)".
Since the printer never sees if the input is abbreviated and the data has the same structure in memory the output is never affected by how you input the data. Thus (quote (quote (1 2 3))) will print the same as ''(1 2 3).
You have the same behaviour with cons cells but the standard dictates how the rules are. (cons 1 (cons 2 (cons 3 '()))) would be (1 . (2 . (3 . ()))) but is actually just printed (1 2 3) However if you (cons 1 2) you get (1 . 2) showing that print treats the output differently based on the cdr. However the reader can read any of these and they will all print the same eg. '(1 . (2 . (3 . ()))) ==> (1 2 3) and (+ . (2 . ( 3 . ()))) ; ==> 5
Numbers can have as many visual forms as there are bases below the number in question.
(let ((*print-base* 16))
(print 255)) ; prints FF (255 in hexadecimal)
list does not have any abbreviation or specialness in Lisp. It's not even a primitive function but it's very helpful as it removes the inconvenience of having to cons by hand everytime. It can be defined like this:
(defun my-list (&rest lst)
lst)
(my-list 1 2 3 4) ; ==> (1 2 3 4)
Note that a REPL (the READ-EVAL-PRINT-LOOP) does three things:
reading using the function READ
evaluating using the function EVAL
and printing the result using something like the function PRINT
To understand what is going on you have to look at all three functions.
Let's look at the third form:
(list 'quote 1 2 3)
This is read as a list of five elements:
LIST
(QUOTE QUOTE)
1
2
3
EVAL then evaluates the arguments, and calls the function list with the four results and returns a new result, a list of four elements:
QUOTE
1
2
3
PRINT then takes this list and writes it as: (QUOTE 1 2 3). There is no abbreviated way to print it.
Let's look at the fourth form:
(list 'quote '(1 2 3))
This is read as a list of three elements:
LIST
(QUOTE QUOTE)
(QUOTE (1 2 3))
eval calls list with two arguments:
QUOTE
(1 2 3)
eval then returns a list of length two:
QUOTE
(1 2 3)
print now can print this list in two different ways:
(QUOTE (1 2 3)) or the abbreviated form '(1 2 3). Here a quote character is in front of a single expression.
Your implementation used the first version.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I need to write a program in Lisp to see the number of occurrences of a specific character in a list. For example the occurrences of 1 in the following list [1, 2, 3, 1,1]
A list in Lisp is a sequence of cons nodes: pairs of pointers - the first to the payload datum, and the second to the rest of the list. E.g. for [1,2,3,1,1],
.
/ \
1 .
/ \
2 .
/ \
3 ...... .
/ \
1 NIL
NIL is a special value signaling the empty list, such that the system knows not to try to explore it any further. In Scheme,
(define NIL '())
Recursive list processing paradigm is captured by the notion of fold, where each node . is "replaced" with a binary function f, and the special node NIL is replaced with some special "zero" value z, to create an application chain (f 1 (f 2 (f 3 (... (f 1 z) ...)))). In Scheme,
(define (myfold f z list)
(cond
((null? list) z) ; replace NIL with the initial ("zero") value
(else
(f ; combine
(car list) ; the payload datum, and the delayed,
(lambda () ; by creating a function to calculate it,
(myfold f z ; result of recursively folding
(cdr list))))))) ; the rest of list
That way, the combining function f must process two values: one is a node's payload datum, the other is the (delayed) result of recursively folding, with the same f and z, the rest of the list after that node.
(define (keep-equals v list)
(myfold
(lambda (a r) ; combine ...
(if (equal? v a)
(cons a ... ) ; the same thing goes over the dots, here
... )) ; and here
'() ; replace the NIL of the argument list with this
list))
Since the recursive folding results' calculation is delayed by creating a function to-be-called when the results are needed, we need to "force" that calculation to be performed, when we indeed need those results, by calling that function.
And if you want to count the number of occurrences instead of collecting them in a list, you just need to use a different combining function with a different initial ("zero") value.
In particular, we build a list by consing a value onto the rest of list (with NIL as the initial value, the empty list); whereas we count by incrementing a counter (with 0 as the initial value of that counter).
Calculating e.g. a list's length by folding, we essentially turn its elements each into 1: length [a,b,c,d,e] == 1 + (1 + (1 + (1 + (1 + 0)))). Here, the combining function will need to increment the counter conditionally, only when the payload data are such that we want to count them.
I like pretty well the answers already posted to this question. But it seems like they both involve a fair bit more than the necessary amount of work. On the other hand, given all the thought everyone's put into this, I'm almost embarrassed of how simple my answer is. Anyway, here's what I did:
(defun count-things-in (needle haystack)
"Count the number of NEEDLEs in HAYSTACK."
(reduce '+
(map 'list
#'(lambda (straw)
(if (equalp straw needle) 1 0))
haystack)))
(count-things-in 1 '(1 2 3 1 1))
;; => 3
It's pretty straightforward: you just map over HAYSTACK a function which returns 1 for an element which is EQUALP to NEEDLE or 0 for an element which isn't, and then reduce the resulting list by +. For the given example list, the map operation results in a list (1 0 0 1 1), which the reduce operation then treats as (1 + (0 + (0 + (1 + 1)))), which evaluates to 3.
Benefits of this approach include the use of an equality predicate loose enough to work with strings as well as numbers, and with numbers of different types but the same value -- that is, (equalp 1 1.0) => t; if you desire different behavior, use another equality predicate instead. Using the standard MAP and REDUCE functions, rather than implementing your own, also gives you the benefit of whatever optimizations your Lisp system may be able to apply.
Drawbacks include being not nearly as impressive as anyone else's implementation, and being probably not low-level enough to satisfy the requirements of the asker's homework problem -- not that that latter especially dismays me, given that this answer does satisfy the stated requirement.
I'm new to lisp myself but here is how I would do it. I haven't looked at the other answer yet from Will so I'll check that out after I post this. The member function has the utility of both telling you if it found something in a list, and also returning the rest of that list starting from where it found it:
CL-USER> (member '1 '(0 1 2 3))
(1 2 3)
You could then recursively call a function that uses member and increment a counter from returned values in a variable from a let:
(defun find1 (alist)
(let ((count 0))
(labels ((findit (list)
(let ((part (member '1 list)))
(if part
(progn (incf count)
(findit (rest part)))
0))
count))
(findit alist))))
Here is the result:
CL-USER> (find1 '(1 2 3 4 5))
1
CL-USER> (find1 '(1 1 2 3 4 5))
2
CL-USER> (find1 '(1 1 1 2 3 1 4 5 1 1))
6
You could get rid of that unattractive progn by using cond instead of if
UPDATE: Here is an updated and more elegant version of the above, based on the comments, that I think would qualify as tail recursive as well:
(defun find1 (alist &optional (accum 0))
(let ((part (member '1 alist)))
(if part
(find1 (rest part) (+ accum 1))
accum)))
Here it is in action:
CL-USER> (find1 '(1 2 3 4))
1
CL-USER> (find1 '(1 1 1 1))
4
CL-USER> (find1 '(1 1 0 1 1))
4
CL-USER> (find1 '(0 2 1 0 1 1 0 1 1))
5
I am trying define symbols a and b in following way
a + 1 1 b
2
I am trying to do this by using define-symbol-macro
(define-symbol-macro a '( )
(define-symbol-macro b ') )
but this way is not working.
What Lisp does with source code
Common Lisp is an incredibly flexible language, in part because its source code can be easily represented using the same data structures that are used in the language. The most common form of macro expansion transforms the these structures into other structures. These are the kind of macros that you can define with define-symbol-macro, define-compiler-macro, defmacro, and macrolet. Before any of those kind of macroexpansions can be performed, however, the system first needs to read the source from an input stream (typically a file, or an interactive prompt). That's the reader's responsibility. The reader also is capable of executing some special actions when it encounters certain characters, such ( and '. What you're trying to do probably needs to be happening down at the reader level, if you want to have, e.g., (read-from-string "a + 1 1 b") return the list (+ 1 1), which is what you want if you want (eval (read-from-string "a + 1 1 b")) to return 2. That said, you could also define a special custom language (like loop does) where a and b are treated specially.
Use set-macro-character, not define-symbol-macro
This isn't something that you would do using symbol-macros, but rather with macro characters. You can set macro characters using the aptly named set-macro-character. For instance, in the following, I set the macro character for % to be a function that reads a list, using read-delimited-list that should be terminated by ^. (Using the characters a and b here will prove very difficult, because you won't be able to write things like (set-macro-character ...) afterwards; it would be like writing (set-m(cro-ch(r(cter ...), which is not good.)
CL-USER> (set-macro-character #\% (lambda (stream ignore)
(declare (ignore ignore))
(read-delimited-list #\^ stream)))
T
CL-USER> % + 1 1 ^
2
The related set-syntax-from-char
There's a related function that almost does what you want here, set-syntax-from-char. You can use it to make one character behave like another. For instance, you can make % behave like (
CL-USER> (set-syntax-from-char #\% #\()
T
CL-USER> % + 1 1 )
2
However, since the macro character associated with ( isn't looking for a character that has the same syntax as ), but an actual ) character, you can't simply replace ) with ^ in the same way:
CL-USER> (set-syntax-from-char #\^ #\))
T
CL-USER> % + 1 1 ^
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "unmatched close parenthesis" {1002C66031}>.
set-syntax-from-char is more useful when there's an existing character that, by itself does something that you want to imitate. For instance, if you wanted to make ! an additional quotation character:
CL-USER> (set-syntax-from-char #\! #\')
T
CL-USER> (list !a !(1 2 3))
(A (1 2 3))
or make % be a comment character, like it is in LaTeX:
CL-USER> (set-syntax-from-char #\% #\;)
T
CL-USER> (list 1 2 % 3 4
5 6)
(1 2 5 6)
But consider why you're doing this at allā¦
Now, even though you can do all of this, it seems like something that would be utterly surprising to anyone who ran into it. (Perhaps you're entering an obfuscated coding competition? ;)) For the reasons shown above, doing this with commonly used characters such as a and b will also make it very difficult to write any more source code. It's probably a better bet to define an entirely new readtable that does what you want, or even write a new parser. even though (Common) Lisp lets you redefine the language, there are still things that it probably makes sense to leaveĀ alone.
A symbol-macro is a symbol that stands for another form. Seems like you want to look at reader macros.
http://clhs.lisp.se/Body/f_set__1.htm
http://dorophone.blogspot.no/2008/03/common-lisp-reader-macros-simple.html
I would second Rainer's comment though, what are you trying to make?
Ok so I love your comment on the reason for this and now I know this is for 'Just because it's lisp' then I am totally on board!
Ok so you are right about lisp being great to use to make new languages because we only have to 'compile' to valid lisp code and it will run. So while we cant use the normal compiler to do the transformation of the symbols 'a and 'b to brackets we can write this ourselves.
Ok so lets get started!
(defun symbol-name-equal (a b)
(and (symbolp a) (symbolp b) (equal (symbol-name a) (symbol-name b))))
(defun find-matching-weird (start-pos open-symbol close-symbol code)
(unless (symbol-name-equal open-symbol (nth start-pos code))
(error "start-pos does not point to a weird open-symbol"))
(let ((nest-index 0))
(loop :for item :in (nthcdr start-pos code)
:for i :from start-pos :do
(cond ((symbol-name-equal item open-symbol) (incf nest-index 1))
((symbol-name-equal item close-symbol) (incf nest-index -1)))
(when (eql nest-index 0)
(return i))
:finally (return nil))))
(defun weird-forms (open-symbol close-symbol body)
(cond ((null body) nil)
((listp body)
(let ((open-pos (position open-symbol body :test #'symbol-name-equal)))
(if open-pos
(let ((close-pos (find-matching-weird open-pos open-symbol close-symbol body)))
(if close-pos
(weird-forms open-symbol close-symbol
`(,#(subseq body 0 open-pos)
(,#(subseq body (1+ open-pos) close-pos))
,#(subseq body (1+ close-pos))))
(error "unmatched weird brackets")))
(if (find close-symbol body :test #'symbol-name-equal)
(error "unmatched weird brackets")
(loop for item in body collect
(weird-forms open-symbol close-symbol item))))))
(t body)))
(defmacro with-weird-forms ((open-symbol close-symbol) &body body)
`(progn
,#(weird-forms open-symbol close-symbol body)))
So there are a few parts to this.
First we have (symbol-name-equal), this is a helper function because we are now using symbols and symbols belong to packages. symbol-name-equal gives us a way of checking if the symbols have the same name ignoring what package they reside in.
Second we have (find-matching-weird). This is a function that takes a list and and index to an opening weird bracket and returns the index to the closing weird bracket. This makes sure we get the correct bracket even with nesting
Next we have (weird-forms). This is the juicy bit and what it does is to recursively walk through the list passed as the 'body' argument and do the following:
If body is an empty list just return it
if body is a list then
find the positions of our open and close symbols.
if only one of them is found then we have unmatched brackets.
if we find both symbols then make a new list with the bit between the start and end positions inside a nested list.
we then call weird forms on this result in case there are more weird-symbol-forms inside.
there are no weird symbols then just loop over the items in the list and call weird-form on them to keep the search going.
OK so that function transforms a list. For example try:
(weird-forms 'a 'b '(1 2 3 a 4 5 b 6 7))
But we want this to be proper lisp code that executes so we need to use a simple macro.
(with-weird-forms) is a macro that takes calls the weird-forms function and puts the result into our source code to be compiled by lisp. So if we have this:
(with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
Then it macroexpands into:
(PROGN (+ 1 2 3 (- (+ 1 2 3) 10 5) 11 23))
Which is totally valid lisp code, so it will run!
CL-USER> (with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
31
Finally if you have settled on the 'a' and 'b' brackets you could write another little macro:
(defmacro ab-lang (&rest code)
`(with-weird-forms (a b) ,#code))
Now try this:
(ab-lang a let* a a d 1 b a e a * d 5 b b b a format t "this stupid test gives: ~a" e b b)
Cheers mate, this was great fun to write. Sorry for dismissing the problem earlier on.
This kind of coding is very important as ultimately this is a tiny compiler for our weird language where symbols can be punctuation. Compilers are awesome and no language makes it as effortless to write them as lisp does.
Peace!
Suppose I have a function
CL-USER> (defun trimmer (seq) "This trims seq and returns a list"
(cdr
(butlast seq)))
TRIMMER
CL-USER> (trimmer '(1 2 3 VAR1 VAR2))
(2 3 VAR1)
CL-USER>
Notice how, due to QUOTE, VAR1 and VAR2 are not resolved. Suppose I want to resolve the symbols VAR1 and VAR2 to their values - is there a standard function to do this?
Do not use quote to create a list with variables; use list instead:
CL-USER> (trimmer (list 1 2 3 var1 var2))
(2 3 value-of-var1)
(where value-of-var1 is the value of var1).
Quote only prevents evaluation of whatever its argument is. If its argument happens to be a list literal, then that is returned. However, to create lists that are not just literals, use list. You can use backquote syntax, but that is rather obfuscation in such a case.
Backquote is the usual way to interpolate values into a quoted list:
> (setq var1 4 var2 5)
5
> `(1 2 3 ,var1 ,var2)
(1 2 3 4 5)
Edited to add: if you want to process a list so that symbols are replaced with their symbol-value, then you need a function something like this:
(defun interpolate-symbol-values (list)
"Return a copy of LIST with symbols replaced by their symbol-value."
(loop for x in list
collect (if (symbolp x) (symbol-value x) x)))
> (interpolate-variables '(1 2 3 var1 var2))
(1 2 3 4 5)
This seems like a strange thing to want to do, however. Can you say more about what you are trying to achieve? Almost certainly there's a better way to do it than this.