I am working on these two functions that differ only in how ret and curr are assigned their value while the loop runs. In the first function ret and curr are bound in parallel; in the second function they are bound sequentially.
parallel binding
(defun maxpower (base maximum)
"returns base ^ k such that it is <= maximum"
(do ((ret 1 curr) ; parallel
(curr base (* base curr))) ; binding
((> curr maximum) ret)))
sequential binding
(defun maxpower* (base maximum)
"returns base ^ k such that it is <= maximum"
(do* ((ret 1 curr) ; sequential
(curr base (* base curr))) ; binding
((> curr maximum) ret)))
Question: is the 1st function is somehow wrong (*) because curr is both updated and evaluated at the same time (in parallel)?
IOW: if I change the order of the bindings there should be no difference in the parallel version?
How does Lisp decide about the parallelization of the bindings?
In my tests, both functions return the same value, as they are.
(*): I come from C background; I'd say 1st function invokes Undefined Behaviour.
It's probably best to look at let versus let* first. If you understand that, then do versus do* follows from that, except for the additional consideration of the step-forms.
Common Lisp is a strictly evaluated language. In both let and let*, the variable init-forms are evaluated left to right. The difference is in the scope and binding. Under let, all of the init forms are evaluated in a scope in which none of the variables are visible, whereas under let*, the forms are evaluated in an environment under which all the previous variables are visible. Secondly, since under let*, the previous variables are visible, their values are also established.
Using let we can create a scope in which the values of two variables appear swapped:
(let ((x y)
(y x))
...)
The initializing expressions y and x are evaluated first, in that order, and then the new values x and y are bound to the resulting values, which makes this possible.
On the other hand:
(let* ((a 1)
(b (+ a 2)))
Here, 1 is evaluated, and a is bound. This a is then visible to the (+ a 2) expression whose value is computed, and bound to b.
Now, onto do/do*. These macros perform, prior to the first iteration, binding of the variables that is exactly like let/let*. In binding the variables, the difference between do and do* is exactly like between let and let*.
The do/do* macros also have step-forms, which give the next value to their corresponding iteration variables. These step-forms are all in the scope of all of the variables, regardless of whether the macro operator is do or do*. Whether you're using do or do*, you can refer to any variable in any step form. The difference is when the assignment takes place. Under do, all of the step forms are evaluated from top to bottom, and then their corresponding variables are assigned new values for the next iteration. Under do*, the behavior is "assign as you go". As each step-form is evaluated, the corresponding variable is assigned. Therefore under do, when the step-form refers to any variable, it refers to its value from the prior iteration. Under do*, if the step-form refers to a lexically earlier variable, it's picking up the new value. If it refers to a lexically later variable, it's still seeing the old value from the prior iteration.
We have to emphasize that although let and do have some "parallel" behavior, in a sense, there is no parallel evaluation. All visible effects are performed left to right. What appears to happen in parallel is the variables coming into existence, or being assigned new values in the new iteration. But this is only parallel in the sense that the program cannot observe the intermediate progress. For instance, the passage of function arguments into a function is likewise "parallel"; the program doesn't observe a state in which the function call is partially in progress, and only half the arguments have been passed.
In the case of maxpower it is not correct that "curr is both updated and evaluated at the same time". The step forms in do are all evaluated before any assignment takes place. For do, the Hyperspec says that "the assignment of values to vars is done in parallel, as if by psetq," and for psetq it says that "first all of the forms are evaluated, and only then are the variables set to the resulting values."
In the posted code, both definitions should produce the same results because the step forms are evaluated before any assignments are done. But, if the order of the bindings were reversed things would be different:
(defun maxpower (base maximum)
(do ((curr base (* base curr))
(ret 1 curr))
((> curr maximum) ret)))
(defun maxpower* (base maximum)
(do* ((curr base (* base curr))
(ret 1 curr))
((> curr maximum) ret)))
Now for the first function, (* base curr) and curr are evaluated at the same time, and the values of curr and ret are updated in parallel. But, for the second function, (* base curr) is evaluated and the result assigned to curr, and then curr is evaluated and assigned to ret.
For these new definitions you can see that the results differ, where in the original definitions both functions would have returned 4 for both (maxpower 2 5) and (maxpower* 2 5):
CL-USER> (maxpower 2 5)
4
CL-USER> (maxpower* 2 5)
8
Related
I am trying to do Recursive method to find max value in list.
Can anyone explain where I made the mistake on this code and how to approach it next time.
(defun f3 (i)
(setq x (cond (> (car (I)) (cdr (car (I))))
(f3 (cdr (I)))))
)
(f3 '(33 11 44 2) )
also I tried this following method and didn't work:
(defun f3 (i)
(cond ((null I )nil )
(setq x (car (i))
(f3(cdr (i)))
(return-from max x)
)
Thanks a lot for any help. I am coming from java if that helps.
If you're working in Common Lisp, then you do this:
(defun max-item (list)
(loop for item in list
maximizing item))
That's it. The maximizing item clause of loop determines the highest item value seen, and implicitly establishes that as the result value of loop when it terminates.
Note that if list is empty, then this returns nil. If you want some other behavior, you have to work that in:
(if list
(loop for item in list
maximizing item))
(... handle empty here ...))
If the number of elements in the list is known to be small, below your Lisp implementation's limit on the number of arguments that can be passed to a function, you can simply apply the list to the max function:
(defun max-item (list)
(apply #'max list))
If list is empty, then max is misused: it requires one or more arguments. An error condition will likely be signaled. If that doesn't work in your situation, you need to add code to supply the desired behavior.
If the list is expected to be large, so that this approach is to be avoided, you can use reduce, treating max as a binary function:
(defun max-item (list)
(reduce #'max list))
Same remarks regarding empty list. These expressions are so small, many programmers will avoid writing a function and just use them directly.
Regarding recursion, you wouldn't use recursion to solve this problem in production code, only as a homework exercise for learning about recursion.
You are trying to compute the maximum value of a list, so please name your function maximum and your parameter list, not f3 or i. You can't name the function max without having to consider how to avoid shadowing the standard max function, so it is best for now to ignore package issues and use a different name.
There is a corner case to consider when the list is empty, as there is no meaningful value to return. You have to decide if you return nil or signal an error, for example.
The skeleton is thus:
(defun maximum (list)
(if (null list)
...
...))
Notice how closing parentheses are never preceded by spaces (or newlines), and opening parentheses are never followed by spaces (or newlines). Please note also that indentation increases with the current depth . This is the basic rules for Lisp formatting, please try following them for other developers.
(setq x <value>)
You are assigning an unknown place x, you should instead bind a fresh variable if you want to have a temporary variable, something like:
(let ((x <value>))
<body>)
With the above expression, x is bound to <value> inside <body> (one or more expressions), and only there.
(car (i))
Unlike in Java, parentheses are not used to group expressions for readability or to force some evaluation order, in Lisp they enclose compound forms. Here above, in a normal evaluation context (not a macro or binding), (i) means call function i, and this function is unrelated to your local variable i (just like in Java, where you can write int f = f(2) with f denoting both a variable and a method).
If you want to take the car of i, write (car i).
You seem to be using cond as some kind of if:
(cond (<test> <then>) <else>) ;; WRONG
You can have an if as follows:
(if <test> <then> <else>)
For example:
(if (> u v) u v) ;; evaluates to either `u` or `v`, whichever is greater
The cond syntax is a bit more complex but you don't need it yet.
You cannot return-from a block that was undeclared, you probably renamed the function to f3 without renaming that part, or copied that from somewhere else, but in any case return-from is only needed when you have a bigger function and probably a lot more side-effects. Here the computation can be written in a more functionnal way. There is an implicit return in Lisp-like languages, unlike Java, for example below the last (but also single) expression in add evaluates to the function's return value:
(defun add-3 (x)
(+ x 3))
Start with smaller examples and test often, fix any error the compiler or interpreter prints before trying to do more complex things. Also, have a look at the available online resources to learn more about the language: https://common-lisp.net/documentation
Although the other answers are right: you definitely need to learn more CL syntax and you probably would not solve this problem recursively in idiomatic CL (whatever 'idiomatic CL' is), here's how to actually do it, because thinking about how to solve these problems recursively is useful.
First of all let's write a function max/2 which returns the maximum of two numbers. This is pretty easy:
(defun max/2 (a b)
(if (> a b) a b))
Now the trick is this: assume you have some idea of what the maximum of a list of numbers is: call this guess m. Then:
if the list is empty, the maximum is m;
otherwise the list has a first element, so pick a new m which is the maximum of the first element of the list and the current m, and recurse on the rest of the list.
So, we can write this function, which I'll call max/carrying (because it 'carries' the m):
(defun max/carrying (m list)
(if (null list)
m
(max/carrying (max/2 (first list) m)
(rest list))))
And this is now almost all we need. The trick is then to write a little shim around max/carrying which bootstraps it:
to compute the maximum of a list:
if the list is empty it has no maximum, and this is an error;
otherwise the result is max/carrying of the first element of the list and the rest of the list.
I won't write that, but it's pretty easy (to signal an error, the function you want is error).
Here is the snippet that confuses me:
(setq lexical-binding t)
(defvar x 0)
(setq test (let ((x 1))
(lambda ()
x)))
(funcall test)
My understanding is that since lexical-binding is true, then the x of value 1 should cover the scope of let, which should include the x in the definition of lambda, as such, the test should return value of 1 instead of 0, but it turns out to return 0, which is the value of x by defvar.
Did I misunderstand anything?
UPDATE
Just for clarification, I would like to put my understanding here. Dynamical bounding means it only have one symbol and the value is popped in and out in a stack. As such, when the definition of lambda is done, the value used in let is popped out.
lexical/static bounding means the value is always been checked in the context of the lexical environment, so as long there is let before lambda definition, the value in let is used.
variable defined by defvar is always dynamically bound, as such, lexical-binding control here does not make any difference.
According to https://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Lexical-Binding.html, even when lexical-binding is non-nil, special variables (like x since it was defined with defvar) are still dynamically bound.
It prints 1 on the screen even though I increased its value in the function. Is there a way to call the parameter by reference so I can use it after the function call?
(defparameter a 1)
(defun foo (x)
(+ x 1))
(foo a)
(print a)
Your code doesn't contain any traces of an operator that modifies a storage location in-place. Neither the variable a nor x are subject to mutation.
The function foo returns a number that is greater than the input number by 1.
Note that a and x are distinct variables; if we were to increment x, that has no effect on a.
Numbers are not mutable objects in ANSI Lisp; if we increment a variable x with (incf x) what is happening is that the value (+ 1 x) is calculated, and this new value stored back into the x variable.
ANSI Lisp function parameters use "pass by value", like most major Lisp dialects. When (foo a) is invoked, the argument expression a is reduced to a value: it produces the value 1. This value is no longer associated with the variable. It is passed into the function without any memory of having come from a. Inside the function, a new variable x is instantiated that is local to the function; this receives a copy of the argument value: it is initialized with 1. So x has nothing to do with a; it has just received the same value.
General solution - destructive access to variable
I think, what you wanted to know is actually this:
(defparameter a 1)
(defmacro foo (x)
`(setf ,x (+ ,x 1))) ;; this macro takes the variable given for x
;; accesses its memory location using `setf`
;; and changes its value to 2
;; by increasing the accessed value by 1
(foo a) ;; a's value becomes 2
a ;; 2
However, as a beginner in common lisp, be careful to mutate wildly values around. Although I don't want to take you the joy of the power of Lisp. :)
Special solution - foo = incf
But foo (which increments a given value by 1)
is exactly incf in common lisp, because this increment by one is often needed. So for this very special case, you can just use incf.
(defparameter a 1)
a ;; => 1
(incf a) ;; incf mutates a to 2 - in exactly the way foo does
a ;; => 2 ;; a ist after that changed.
Note, there is also decf which decrements the variable by 1 - the opposite of incf.
Secial solution for global variables
But for global variables, you can use very normal defparameter to reassign the value to a:
(defparameter a 1)
(defparameter a (foo a)) ;; reassigns new value `2` to `a`
a ;; returns 2, since mutated now
Comment to the very first version:
(setf <var> <new-value>) is like a pointer access to the variable's memory location and writing to it what is given for <new-value>.
So in Lisp, you have to use a combination of defmacro and setf to imitate or actually do call-by-reference like in C or Python.
But you know from Python or C already, how un-anticipated side-effects call-by-reference can provoke. Python does by default call-by-reference due to performance reasons (because Python is interpreted and it would become very slow if doing call-by-value everytime a function is called). But with Lisp, you are/you can be at least whenever you want magnitudes faster than interpreted Python (Okay, I am simplifying - Python can of course call C function an be also super fast - however, pure Python of course would be by magnitudes slower than compiled Lisp). And you have many other possibilities to program the same thing. So don't try to imitate Python or other programs function call behaviour in Lisp - that is the wrong track.
Learn functional programming (FP) rules, which tries to not to mutate any values, but to do always call-by-value (like your function foo does). It produces 2 but leaves a the same. To reason about such programs is much more brain-friendly, thus can save you in many cases from avoidable bugs. FP is definitely sth you should learn, when dealing with Lisp btw. FP is amongst many other concepts sth what you learn when you learn Lisp - and I wouldn't want to miss it.
Destructive functions make only sense if state is really unavoidable and desired, and especially if performance is important.
I thought racket does inner reduction always for evaluation but I found out e.g. "if" (and cond?!) is lazy evaluation in racket...why is this needed?
Is it impossible to realize an if-statement via inner reduction?
I can not figure out where lazy evaluation is better than inner and vice versa? Could someone supply an example?
if and cond are not "lazy", they just have different evaluation rules. For example, in the following expression only the consequent part of the if is executed, because the condition happens to be true:
(if (= 1 1)
'ok
(/ 1 0))
=> 'ok
If the alternative part were executed, we'd have a division by zero error. This is not lazy evaluation, it's just the way an if expression works in Scheme. Compare the above example with this one:
(define (my-if condition consequent alternative)
(if condition
consequent
alternative))
(my-if (= 1 1) 'ok (/ 1 0))
=> /: division by zero
Now we're using the standard evaluation rules for procedures, which in a non-lazy interpreter specify that all the arguments are evaluated before executing the procedure's body - hence an error is raised. That's why if can not be implemented as a normal procedure, it has to be a special form because it requires different evaluation rules.
Consider this piece of code:
(defvar lst '(1 1))
(defmacro get-x (x lst)
`(nth ,x ,lst))
(defun get-y (y lst)
(nth y lst))
Now let us assume that I want to change the value of the elements of the list called lst, the car with get-x and the cdr with get-y.
As I try to change the value with get-x (with setf) everything goes fine but if I try it with get-y it signals an error (shortened):
; caught STYLE-WARNING:
; undefined function: (SETF GET-STUFF)
Why does this happen?
I myself suspect that this happens because the macro simply expands and the function nth simply returns a reference to the value of an element in the list and the function on the other hand evaluates the function-call to nth and returns the value of the referenced value (sounds confusing).
Am I correct in my suspicions?
If I am correct then how will one know what is simply a reference to a value and an actual value?
The error does not happen with the macro version, because, as you assumed, the expression (setf (get-x some-x some-list) some-value) will be expanded (at compile-time) into something like (setf (nth some-x some-list) some-value) (not really, but the details of setf-expansion are complex), and the compiler knows, how to deal with that (i.e., there is a suitable setf expander defined for function nth).
However, in the case of get-y, the compiler has no setf expander, unless you provide one. The easiest way to do so would be
(defun (setf get-y) (new-value x ls) ; Note the function's name: setf get-y
(setf (nth x ls) new-value))
Note, that there are a few conventions regarding setf-expanders:
The new value is always provided as the first argument to the setf function
All setf functions are supposed to return the new value as their result (as this is, what the entire setf form is supposed to return)
There is, BTW, no such concept as a "reference" in Common Lisp (at least not in the C++ sense), though there once were Lisp dialects which had locatives. Generalized place forms (ie., setf and its machinery) work very differently from plain C++ style references. See the CLHS, if you are curious about the details.
SETF is a macro.
The idea is that to set and read elements from data structures are two operations, but usually require two different names (or maybe even something more complex). SETF now enables you to use just one name for both:
(get-something x)
Above reads a datastructure. The inverse then simply is:
(setf (get-something x) :foobar)
Above sets the datastructure at X with :FOOBAR.
SETF does not treat (get-something x) as a reference or something like that. It just has a database of inverse operations for each operation. If you use GET-SOMETHING, it knows what the inverse operation is.
How does SETF know it? Simple: you have to tell it.
For The NTH operation, SETF knows how to set the nth element. That's builtin into Common Lisp.
For your own GET-Y operation SETF does not have that information. You have to tell it. See the Common Lisp HyperSpec for examples. One example is to use DEFUN and (SETF GET-Y) as a function name.
Also note following style problems with your example:
lst is not a good name for a DEFVAR variable. Use *list* as a name to make clear that it is a special variable declared by DEFVAR (or similar).
'(1 2) is a literal constant. If you write a Common Lisp program, the effects of changing it are undefined. If you want to change a list later, you should cons it with LIST or something like COPY-LIST.