I am studying the Emacs-Lisp by following the introduction.
I can understand the below defun print out a list in left-to-right order because the print command comes before recursion (as I understood):
(defun print-elements-recursively (list)
"Print each element of LIST on a line of its own.
Uses recursion."
(when list ; do-again-test
(print (car list)) ; body
(print-elements-recursively ; recursive call
(cdr list)))) ; next-step-expression
E.g. for a list of '(gazelle giraffe lion tiger). The print order is gazelle, giraffe, lion, tiger.
However, I could not understand why the same order still holds when I switch the position of the two expression within the when body:
(defun print-elements-recursively (list)
"Print each element of LIST on a line of its own.
Uses recursion."
(when list ; do-again-test
; body
(print-elements-recursively ; recursive call
(cdr list))
(print (car list)))) ; next-step-expression
Per my expectation, the recursion happens before the print function, therefore, the order should be reversed. May I know why?
You probably did not evaluate the second defun after defining it, and that is why the items of the input list are still being printed in the original order. Adding a second function with the same name to the global namespace does not mean that the definition of the first function is automatically overwritten.
I suggest you
rename one of the defuns
evaluate them both
and then call each one of them separately.
The behavior should not persist when you do that.
Aside from printing the elements of the list in a different order, note also that the original function returns nil and the second function returns a printed representation of the last (non-nil) item of the input list. This is because (when list) returns nil and is the last expression that gets evaluated when the base case is reached in the first function. In the second function all invocations of print are evaluated after the base case is reached.
Related
Needs to be created Using the functions and values cons, first, second, rest, empty, empty?, length, append, list, list-ref, and make-list
Since no looping functions are listed, that means we will have to use recursion to iterate over the list. This can be done by repeatedly calling our function on the list with its first value removed. We also cannot use other function calls to manipulate a variable to store the last positive value we have encountered, so we can instead track it with a parameter passed into the function. This gives us the following function:
#lang racket
(define (get-last-positive lastPositive lst)
(cond [(empty? lst) lastPositive]
[(positive? (first lst)) (get-last-positive (first lst) (rest lst))]
[else (get-last-positive lastPositive (rest lst))]))
(get-last-positive -1 '(1 -2 2 5 -1 0)) ;example call
To explain the code more concretely, if the list is empty we will have found the last positive value if it exists and can return it. If there was no positive value, then -1 will have been passed to lastPositive all the way through the call stack. In the second condition, if we have found a positive value, recursively call get-last-positive with the that value passed into lastPositive and the list without its first value. In the third condition we have not found a positive value, so recursively call get-last-positive so do not change the value for lastPositive and pass in the rest of the list to be checked.
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).
I am designing a simple function (for class, so please no complete done-for-you answers) that returns the first odd integer in a list, or 'none if there are none.
I have a working code for finding the odd number:
(defun first-odd (lst)
(do ((numbers lst (cdr numbers)))
((oddp (car numbers)) (car numbers))))
but what I can't seem to figure out is where to place the IF conditional (which is required for the assignment) to produce "NONE" if the list is only even #s, or presumably NIL.
Do I make the exit point of the DO itself the IF conditional? Or does it go before/after?
I'm working on something like this (although I have a feeling it's wrong):
(defun first-odd (lst)
(do ((numbers lst (cdr numbers)))
((if (oddp (car numbers))
(car numbers)
(print 'none)))))
Or can someone advise me on 'where' to place the IF? Sorry for the truly beginner takes, but the prof didn't provide much documentation for DO and I've been scratching my head all weekend. Thanks in advance.
DO takes three arguments: the first one is the list of variables with their initial values and the subsequent values; the second is the terminating condition, i.e. when to exit the loop and the result to return; the third one is the body of the loop, and it's optional.
The second element contains an implicit if.
Your first code looks good with one exception: have you considered what happens if there are no odd elements in the list? You need then to test for the end of the list (i.e. when list is nil). Then, the result will depend on whether you exited the loop because an odd number was found, or a nil list. That's where you can use IF.
I am trying to write my own maximum function (with 2 elements in list at present) but getting error while executing simple function as:
(defun max_for_vararg (list)
(if (null list)
(nil))
(if (> (car list) (cdr list))
(car list)
(cdr list)))
Error as:
? (max_for_vararg '(2 4))
> Error: The value (4) is not of the expected type REAL.
> While executing: CCL::>-2, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
I appreciate if someone can help me understand it. Error seems confusing to me as similar function like below is running fine but not returning max value.
(defun max_for_vararg (list)
(if (null list)
(nil))
(if (> (car list))
(car list)
(cdr list)))
Use cadr instead of cdr. Cdr gets you the rest of the list, which is a single element list. Thus, you have to call car on that list (car (cdr list)). Since this is a common thing to want to do, they made cadr a function that evaluates out to that.
There are several errors in you code. I'll give you some pointers on how to improve it.
You try to call a function named nil.
The first if has a consequence that does (nil), thus call nil as if it is a defined function. nil in other positions is the empty list so this might be an error unless you have made a function called nil.
The first if is dead code
As long as the result of the first if does not throw you into the debugger, the second if will run. Thus when the first if is fixed it will be redundant code. You really should try to have both a consequence and an alternative even though the standard doesn't require it.
(if test-1 ; predicate
test-1-true-expression ; consequent
test-1-false-expression) ; alternative
The second if should of course be one of those expressions and not something that happens unconditional to the first.
In the updated code > needs at least two arguments to be useful.
You can think of > as a function that tests if all the arguments are in descending order. (> 4) is T since all arguments are in descending order. If you find car, cadr and caddr cryptic you may want to try the aliases first, second, third instead. eg
(> (first list) (second list)) ; is first element greater than second element?
Trying my hand at Lisp. I wonder though, why does:
(defun hello(x)
(print x)
)
work fine, but:
(defun hello (x)
(print(x)) ; Fails with EVAL: undefined function X.
)
not?
In LISPs, non-empty, unquoted lists are considered (function, macro, or special form) calls.
So,
(print x)
is a function call to print with an argument x.
But,
(print (x))
is a function call to print with an argument equal to the value of (x). But since (x) is also non-empty list, in order to get the value of (x) there is an attempt to make a call to a non-existent function x with no arguments.
It's key to note that parentheses are not simply grouping syntax as they are in many other languages; they invoke function as well, similar to how X.val is not the same as X.val() in e.g. Python.
So in this case, you are trying to call x as though it were a function. But, depending on what you've passed to hello, x is not a function, and as such cannot be called.