What is the functionality of this code? [closed] - lisp

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Can anyone help me with this program in LISP:
(defun callie(x y) (if x (callie (cdr x) y))
(if (= (mod (car x) y) 0) (format t "~a~%" (car x))))
I have to understand the functionality and repair it. What does this program do?

When trying to understand that program, you should probably start by fixing the formatting:
(defun callie (x y)
(if x
(callie (cdr x) y))
(if (= (mod (car x) y) 0)
(format t "~a~%" (car x))))
Replacing ifs without a else-branch with whens, and the comparison with 0 with the specific zerop predicate, can further clarify things:
(defun callie (x y)
(when x
(callie (cdr x) y))
(when (zerop (mod (car x) y))
(format t "~a~%" (car x))))
The expected parameter types seem to be a list of integers for x, and an integer for y. The purpose of the function seems to be to print all elements of x that are multiples of y.
A problem seems to be that the function recurses until x is empty, and then tries to do the check on the first element of that version of x (which obviously doesn't exist). So, to fix this, you would have to make sure that the function won't try to process the empty list further. The preferable approach, in my opinion, would be to make use of a standard function or macro for processing a list for side-effects, like mapc or dolist.

Looks like the code tries to print all possible values from the list X where the value is exact-divisible by Y.
It has some errors in it, though.

The usual way to write that in Common Lisp is to use a function which returns a new list, where all items, which don't divide to zero with the given number, are removed.
Typically this test is written as a predicate function which returns a boolean. This functions then is used to remove the unwanted items from the list.
See REMOVE-IF and REMOVE-IF-NOT.
Your task is to get the recursion right. But in real Lisp code, the recursion is not used directly.

Related

Defining a "minimum" function to return the minimum of a list using another function that returns the smaller of two numbers

(defun *smaller* (x y)
( if (> x y) y
x))
(defun *minimum* (lst)
(do ((numbers lst (cdr numbers))
(result (car numbers) (*smaller* result (car numbers))))
((null numbers) result)))
LISP says that variable "numbers" in "minimum" function is an unbound one although I think I've bound it to "lst". What am I missing?
Do binds in parallel. The expression for the initial value of result is (cdr numbers), and numbers is unbound there. Do* would work here.
Another approach to this problem is to try and think about it inductively.
an empty list has no minimum;
if the list is not empty, its first element is a candidate minimum:
if the rest of the list is empty it's the answer
else the candidate minumum is the smaller of the current candidate and the first element of the list, and carry on through the rest of the list.
This translates very naturally into Lisp:
(defun smaller (x y)
(if (< x y) x y))
(defun running-minimum (candidate tail)
(if (null tail)
candidate
(running-minimum (smaller candidate (first tail)) (rest tail))))
(defun minimum (list)
(when (null list)
(error "?")) ;ed is the standard text editor
(running-minimum (first list) (rest list)))
Notes
For good, if now mostly historical, reasons, CL makes no guarantees that code like this will be turned into an iterative process. Many implementations do so, but a conforming implementation need not, and even implementation which do so may not always do so, for instance in interpreted code or code compiled for ease of debugging. So a minimum function like the above is not really very idiomatic CL, and is certainly not completely safe if the code is meant to be portable.
However that is not my goal in this answer: one of the important things that you should get from learning lisp, in my opinion, is the ability to think inductively about solving problems. In other words to think about a class of problems which can be solved by starting from a simple base case and then steps which get from some general case closer to the base case, and then expressing this in code. This is a very different approach to programming than the approach which is natural in more imperative languages, and once you understand it it's a very powerful way of thinking.
As someone whose first serious language was FORTRAN (in the days when that was the correct way of writing its name even!) I think that this inductive approach is very important, and it's that which I wanted to get across here.
(defun smaller (x y)
"returns the smaller number"
(if (> x y)
y
x))
(defun minimum (list)
"returns the smallest number of a list"
(do* ((numbers list (rest numbers))
(result
(first numbers)
(if numbers
(smaller result (first numbers))
result)))
((null numbers) result)))
First of all, as pointed above, you should use do* instead of do, in order to bind the variables sequentially.
Second, you are testing (null numbers) to end the loop. However, when only one element is left to process, numbers is not nil but then it becomes (cdr numbers) which is nil. This nil value is what is being passed to *smaller* as second argument, and that's why you get the error message. To avoid this, you should test for (null (cdr numbers)) instead:
(defun *smaller* (x y)
( if (> x y) y
x))
(defun *minimum* (lst)
(do* ((numbers lst (cdr numbers))
(result (car numbers) (*smaller* result (car numbers))))
((null (cdr numbers)) result)))
This exits the loop when there is only one item left in the list.

Stack overflow regarding two functions

So I am new to lisp, and I am quite confused about the problem I have:
(defun factorial (x)
(if (>= x 1)
(* x (factorial (- x 1)))
1))
The factorial function can output 3000! without a problem, however
(defun sum (x)
(if (<= x 1)
1
(+ x (sum (- x 1)))))
Stack overflows at (sum 10000), I am using clisp.
Could anyone please clarify why this is happening?
Your functions are not tail-recursive, so the compiler (and interpreter) increase stack for each iteration, eventually running out of it.
Your options are enumerated in FAQ How do I avoid stack overflow?; the relevant are:
Compile the functions
Increase Lisp stack size
Rewrite using iteration instead of recursion
Rewrite using tail-recursion and compile

Drracket lists adding only numbers while ignoring other data types [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Hello I need to create a function that consumes a list that sums up only numbers within the list and ignores any other type of data (strings etc)
Example (adding-only-numbers (cons 5 (cons "b" ( cons 2 (cons "whatsup" empty)))))
should come out to (cons 7 (cons "b" (cons "whatsup" empty)))
Keeping all the strings or other data types in order while collecting the numbers and adding them all up.
If there are no numbers, and only strings then it should be 0 at the front
Example (adding-only-numbers (cons "eb" (cons "b" ( cons (make posn 5 0) (cons "whatsup" empty)))))
should come out to (cons 0 (cons "eb" (cons "b" ( cons (make posn 5 0) (cons "whatsup" empty)))))
your help is much appreciated!
Since this smells a little like homework, I'll set you on the right track:
#!/usr/bin/racket
#lang racket
(define (sum lst)
(foldl (lambda (num sum)
(if (number? num) (+ sum num) sum))
0
lst))
(sum '(1 2 "hello"))
So this will return the summation of a flat list... Should be one more simple step to push this to the front of the list.
Note that the foldl function takes a function to apply for each element, the starting value and the list.

Temporary edits global variable [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
LISP - Global variable keep their old value after reinitialization
I'm currently doing some coursework with Lisp (using Common Lisp) and have nowhere else to turn with this problem I'm having.
It's tricky to explain but here goes..
The situation:
I've got two global variables, p1 & p2, which are polynomial expressions. My task is to create a polynomial calculator, which is going well so far.
I keep my polynomial elements in a specific format: 3x^2 == ((x 2) 3), and I've created two functions which recursively run through both lists of polynomial elements.
If I wanted to add together 3x^2 and 2x^2, the answer would be 5x^2 (or "((x 2) (3+2))").
I have a third list, the result, which is appended to whenever an element is calculated/can't be calculated.
The problem:
With two elements I can add together, I create a temporary variable to be added to the result. However, the global variable is changed despite what I do.
I've tried let, lambda, various functions, etc. I've been stuck for a couple of days now and would greatly appreciate any help you could give me :)
Here's a small example of what I mean:
(setf p1 '((x 2) 2))
;2x^2
(setf p2 '((x 2) 3))
;3x^2
(if (equal (first p1) (first p2))
(progn
(setf temp p1)
(setf (second temp) (+ (second p1) (second p2)))
(append-to-result temp)
(print p1)
(print temp)))
Output:
((x 2) 5)
((x 2) 5)
When you do:
(setf temp p1)
you are not_making a copy of the list structure that p1 refers to. Both variables now refer to the same cons cells. Then when you do:
(setf (second temp) ...)
you're modifying that list structure, which both variables still refer to. Change to:
(setf temp (copy-tree p1))

Racket Lisp : comparison between new-if and if

(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter(improve guess x)
x)))
(define (improve guess x)
(average guess(/ x guess)))
(define (average x y)
(/ (+ x y) 2))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.0001))
(define (square x)
(* x x))
(define (sqrt-g x)
(sqrt-iter 1.0 x))
This is a program for sqrt. And the question is what happens when you attempts to use new-if to replace if with new-if.
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter(improve guess x)
x)))
This is new if
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
My opinion is the result of two program gonna be the same. because new-if and if can produce the same results.
However, new-if proved wrong, because it is a dead circle when I tried.
So, why?
new-if is a function. All the arguments to a function are evaluated before calling the function. But sqrt-iter is a recursive function, and you need to avoid making the recursive call when the argument is already good enough.
The built-in if is syntax, and only evaluates the then-branch or else-branch, depending on the value of the condition.
You can use a macro to write new-if.
This is the perfect example for demonstration the algebraic stepper!
In the the algebraic stepper you can see how the course of the computation differs from your expectation. Here you must pay notice to the differences in evaluation of, say, (new-if 1 2 3) and (if 1 2 3).
If you haven't tried the algebraic stepper before, see this answer to see what it looks like.
Since racket is an applicative procedure the 3rd argument to the new-if is (sqrt-iter(improve guess x) x)). Since sqrt-iter is recursive the 3rd argument never has a value assigned to it. Therefore you never move into the procedure of new-if to evaluate the function.