Why in lisp (Emacs Lisp and Scheme as I know) construction like (*) returns 1?
What I multiply here? How can I call this function * without arguments?
This is a mathematical convention: the product of an empty sequence of numbers is one, by definition; note that one is the identity element for multiplication (1×a = a×1 = a). This is convenient because you can call * with a variable number of arguments without worrying about the case where there are no arguments present.
Similarly, the sum of an empty sequence of numbers is zero, the identity element for addition. Try issuing (+) at your Lisp prompt.
It's a property inherited from mathematics. It's like addition, you can add together any number of numbers, with the special case that adding no numbers together give you the sum zero.
Likewise for multiplication, if you multiply an arbitrary number of numbers, you will get the product. To get this to work for no numbers, 1 is used as the base value (which has some fancy name in mathematics, which I have forgotten many years ago).
So, do you have any practical use for this in a programming language. Yes, as you can call a functions like + and * with arbitrary number of arguments, I would say yes. For example:
(apply '+ '(2 3 4)) => 9
(apply '+ '(2 3)) => 5
(apply '+ '(2)) => 2
(apply '+ '()) => 0
(apply '* '(2 3 4)) => 24
(apply '* '(2 3)) => 6
(apply '* '(2)) => 2
(apply '* '()) => 1
Related
I am familiar with how to set elements in a 2D array, which can be done using the following statement.
(setf (aref array2D 0 0) 3)
However, I am not familiar how to set elements in a list of lists, such as the following input: '((1) (2) (2) (1)). I can't use aref, since it only works on arrays.
As mentioned, while aref works on arrays, elt works on sequences which can be:
an ordered collection of elements
a vector or a list.
* (setf test-list '((1) (2) (2) (1)))
((1) (2) (2) (1))
* (setf (elt test-list 2) 'hi)
HI
* test-list
((1) (2) HI (1))
You can indeed use variables in place of fixed offsets:
* (setf test-list '((1) (2) (2) (1)))
((1) (2) (2) (1))
* (setf offset 2)
2
* (setf (elt test-list offset) 'hi)
HI
* test-list
((1) (2) HI (1))
To access the nth element of a list, there are (at least) two functions: nth and elt. The order of the parameters is different, and nth only work on lists while elt works on any sequence (i.e. lists, vector, strings ...):
(nth 1 '(foo bar baz)) => BAR
(nth 1 #(foo bar baz)) => ERROR
(elt '(foo bar baz) 1) => BAR
(elt #(foo bar baz) 1) => BAR
Now, in general, the way to set a value (as opposed to simply access it) is very straightforward, and at least for built-in functions this is almost always the case: whenever you have some form FORM which retrieves some value from what is called a place, the form (setf FORM <value>) will set this element to the given <value>. This works for functions such as car, cdr, gethash, aref, slot-value, symbol-function and many others, and any combination of those.
In your example, you have a list of lists. So, for example, to modify the "inner integer" in say the third list:
* (setf test-list '((0) (1) (2) (3))) ; changed the values to have something clearer
((0) (1) (2) (3))
* (car (nth 2 test-list)) ; this accesses the integer in the second list
2
* (setf (car (nth 2 test-list)) 12) ; this modifies it. Notice the syntax
12
* test-list
((0) (1) (12) (3))
On a side note, you should avoid modifying literal lists (created using the quote symbol '). If you want to modify lists, create them at runtime using the list function.
EDIT:
What happens is that setf knows, by "looking" at the form you give it, how to actually find the place that you want to modify, potentially using functions in this process.
If you look at other languages, such as Python, you also have some kind of duality in the syntax used both to get and to set values. Indeed, if you have a list L or a dictionary d, then L[index] and d[thing] will get the corresponding element while L[index] = 12 and d[thing] = "hello" will modify it.
However, in Python, those accessors use a special syntax, namely, the squares brackets []. Other types of objects use another syntax, for example, the dot notation to access slots/attributes of an object as in my-object.attr. A consequence is that the following code is invalid in Python:
>>> L = [1, 2, 3, 2, 1]
>>> max(L)
3
>>> max(L) = 12
Traceback (most recent call last):
File "<string>", line 9, in __PYTHON_EL_eval
File "/usr/lib/python3.8/ast.py", line 47, in parse
return compile(source, filename, mode, flags,
File "<string>", line 1
SyntaxError: cannot assign to function call
You have to write an other function, for example, setMax(L, val), to change the maximum of a list. This means that you now have to functions, and no symmetry anymore.
In Common Lisp, everything is (at least syntactically) a function call. This means that you can define new ways to access and modify things, for any function ! As a (bad) example of what you could do:
* (defun my-max (list)
(reduce #'max list))
MY-MAX
* (my-max '(1 2 3 8 4 5))
8
* (defun (setf my-max) (val list)
(do ((cur list (cdr cur))
(cur-max list (if (< (car cur-max) (car cur))
cur
cur-max)))
((endp (cdr cur)) (setf (car cur-max) val))))
(SETF MY-MAX)
* (setf test-list (list 0 4 5 2 3 8 6 3))
(0 4 5 2 3 8 6 3)
* (setf (my-max test-list) 42)
42
* test-list
(0 4 5 2 3 42 6 3)
This way, the syntax used to both set and get the maximum of a list is identical (FORM to get, (setf FORM val) to set), and combines automatically with every other "setter". No explicit pointers/references involved, it's just functions.
I am new to lisp and I had a question about this LISP syntax:
(defparameter *binary-operators*
'((+ 1 +) (- 1 -) (* 2 *)
(x 2 *) (/ 2 %) (^ 3 expt)))
From what I understand, defparameter allows the binary operators variable to be reassigned but I am confused as to how the (+ 1 +), (- 1 -) ... are evaluated. I know in LISP that (+ 4 6) would result in (4 + 6) = 10 but the same logic would result in (1 + +) which does not make sense. What does the above syntax represent?
In Common Lisp,
(defparameter name initial-value)
(see the manual) introduces a new special (global) variable name with a new value, given by evaluating initial-value.
So, in the example above, the special variable *binary-operators* is assigned a list of triples, each of them constitued by a symbol, a number, and another symbol. In other words, it assigns some data to a variable, and not, as you were thinking, redefines the syntax of the language.
Guessing from the values present in the list, this seems a variable that is assigned a list of arithmetic operators, each of them with the priority, and with the equivalent Common Lisp operator/function. Maybe this is a line of some program that maps arithmetic expressions in lisp s-expressions, or something like that.
Lisp: lists and symbols are used in data and in code
This is one of the applications where code is data. In Lisp symbols and lists are data. But they are also used to write programs: the symbols then are used for variable names, function names and much more. Lists are used to write expressions in the Lisp language - these are called forms.
In a Lisp program
(+ 1 2)
is a function call of the function named + with two values.
'(+ 1 2)
or
(quote (+ 1 2))
then is data -> the list of the symbol + and the numbers 1 and 2.
Example: infix to prefix conversion
The form you used defines a mapping from a symbol denoting a mathematical function to the weight and the actual Lisp function it represents for the conversion.
See Lispology: Infix to prefix
(defparameter *binary-operators*
; operator weight Lisp function
'((+ 1 +)
(- 1 -)
(* 2 *)
(x 2 *)
(/ 2 %)
(^ 3 expt)))
We can use it to convert infix mathematical expressions to prefix Lisp expressions (see the above linked article for the code):
CL-USER 52 > (infix-prefix '(2 * 3 ^ 4))
(* 2 (EXPT 3 4))
When we change that assoc list, then the conversion will be different. Let's change the weight of the ^ operator:
CL-USER 53 > (defparameter *binary-operators*
'((+ 1 +)
(- 1 -)
(* 2 *)
(x 2 *)
(/ 2 %)
(^ 1 expt))) ; weight changed to 1
*BINARY-OPERATORS*
Now we can convert the example from above and we get a different Lisp form:
CL-USER 54 > (infix-prefix '(2 * 3 ^ 4))
(EXPT (* 2 3) 4)
So, *binary-operators* is data, which drives the conversion from infix mathematical expressions to Lisp forms. Instead of hardwiring the rules into the code, here we are using an assoc list to keep the mappings. Thus allows us to add new operators by changing the assoc list, without changing the actual code.
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
(defun sum-n-numbers(n)(if(=n 1)
1
(+N(sum-n-numbers(-n 1)))))
Edit 2:(defun sum-n-numbers(n)
(if(=n 1)
1
(+N(sum-n-numbers(-n 1))
)
)
)
The above code runs but when I type (SUM-N-NUMBERS 1 3 2) for the output,it does not work and I get errors.
I know this simple code can also be executed by the inbuild lisp function (+ 1 3 2) that automatically calculates the sum of the numbers,but I have an exam question where it is asked to calculate the sum of n numbers using the defun function.
Edit 1: This is the error that I am getting:
Error: Call ((LAMBDA (#:N) (DECLARE (SPECIAL:SOURCE #) (LAMBDA-NAME SUM-N-NUMBERS)) (BLOCK #:SUM-N-NUMBERS (IF # 1 #))) 1 3 2) has the wrong number of arguments.
1 (abort) Return to level 1.
2 Return to debug level 1.
3 Return to level 0.
4 Return to top loop level 0.
What's wrong with:
(apply '+ '(1 3 2))
??
(defun sum (numbers)
(if (null numbers)
0
(+ (first numbers) (sum (rest numbers)))))
(sum '(1 3 2))
Didn't test. I don't have a lisp interpreter at hand.
To get exactly what you want:
(defun sum-n-numbers (&rest nums)
(if (null nums) 0
(+ (car nums) (apply #'my-sum (cdr nums)))))
This will take an arbitrary number of arguments and recursively compute their sum. For instance:
(sum-n-numbers 1 2 3) => 6
Using iteration, not recursion:
(defun sum-n-numbers (&rest nums)
(loop for num in nums summing num))
From the user's point of view, these are the same, just a little bit different in how they work inside. And I've tested both of these to ensure they work.
The function you wrote accepts one argument and returns the sum of of numbers from 1 to the argument (note that it will never return - theoretically - and fail with a stack overflow - in practice - for negative arguments).
That function cannot accept 3 arguments you passed to it, so you got an error.
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)