Lisp : how to use recursion to defun a function that given a nonnegative integer N, produce the list of all integers from 1 up to and including N? - syntax

write a function in lisp called number(N) that you have to use a nonnegative integer N, and produce the list of all integers from 1 up to and including N.
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
I checked some questions, but most of them use loop and range, but this question doesn't allowed me to do this, so I have to use recursion instead:
here is my code, but this code keeps giving me warning:
; caught STYLE-WARNING:
; The variable N is defined but never used.
;
; compilation unit finished
; caught 1 ERROR condition
; caught 1 STYLE-WARNING condition
I think my algorithm is correct ,but because I am new to lisp, I still don't know how to write the function properly. It is grateful if anyone could gave me any help.

IF has generally a common syntax, but there are exceptions
Generally in Lisps like Common Lisp the if operator allows the following syntax:
IF test-form then-form [else-form]
This means that in Lisp usually zero or one else-form are allowed. An example is if in Common Lisp.
In Emacs Lisp multiple else-forms are allowed. Emacs Lisp has the following syntax:
IF test-form then-form else-form*
This means that in Emacs Lisp zero or more else-forms are allowed.
Thus: it's important to mention which language&dialect you are actually using.
Your code
a) Let's assume that you use Common Lisp with its IF syntax.
Your code:
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
Your code has the problem, that there are more than one else clauses. You need to write a version which has a single else clause.
b) Let's assume that you use Emacs Lisp with its IF syntax with multiple else forms.
Your code:
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
Here the (cons N nil) form is allowed, but has no effect. Its return value is not used and it has no side effect. You could delete it and it would make no difference. Again: you would need how to combine its effect with the form (numbers (- N 1)).
Syntax error: missing closing parenthesis
There is another problem in your code. The s-expressions are not complete -> a closing parenthesis is missing:
(defun numbers (N)
(if (<= N 0)
nil
(cons N nil)
(numbers (- N 1)))
As you can see a closing parenthesis is missing at the end.
Thus your code can not be read by Lisp.
There are two ways one generally can avoid this problem:
count the parentheses and set them accordingly
use the editor to count the parentheses
Most people prefer the latter.

The way to think about this is to think about what the algorithm should be:
To compute the numbers from 1 to n:
if n is less than 1 then there are no numbers, so this is the empty list;
otherwise we want a list which looks like (... n), where ... is all the numbers from 1 to n-1.
Note that we want the numbers in forward order: this is going to be critical.
Doing this is slightly difficult in Lisp because we want the number to be at the end of the list, and access to the ends of lists is hard.
Here is the start of a version which builds the list backwards (so this is not the right answer).
(defun numbers (n)
(if (< n 1)
'() ;the empty list
;; n 1 or more, so build a list which is (n . ...)
(cons n <some function involving n>)))
Well, OK, what function should we call recursively? Do we have a function which returns the list we want? Well, yes: it's numbers, with an argument which is one less than n!
(defun numbers (n)
(if (< n 1)
'()
(cons n (numbers (- n 1)))))
And this function works. But it gets the wrong answer: the list is backwards:
> (numbers 10)
(10 9 8 7 6 5 4 3 2 1)
There are two fixes to this problem: the first is to build the list forwards, using append. This version looks like this (remember append wants to append two lists: it doesn't append an element to the end of a list):
(defun numbers (n)
(if (< n 1)
'()
(append (numbers (- n 1)) (list n))))
This gets the right answer:
> (numbers 10)
(1 2 3 4 5 6 7 8 9 10)
but it's a terrible answer: append has to walk all the way down the list (lists in Lisp are chains of conses: there is no fast access to the end of a list), copying it as it goes, to append the new element. So this has absolutely terrible space & time complexity. Programs written like this are why 'Lisp is slow'.
A better approach is to build the list backwards and then reverse it.
(defun numbers (n)
(reverse (numbers-backwards n)))
(defun numbers-backwards (n)
(if (< n 1)
'()
(cons n (numbers-backwards (- n 1)))))
The problem with this, from the homework perspective, might be that using reverse is not allowed. That's OK, we can write it, recursively. The implementation is slightly fiddly, but this is going to help us below.
(defun reverse-list (l)
;; in real life reverse-list-accumulator would be a local function
(reverse-list-accumulator l '()))
(defun reverse-list-accumulator (l accum)
(if (null l)
accum
(reverse-list-accumulator (rest l) (cons (first l) accum))))
The way this works is that reverse-list calls this auxiliary function with an extra argument. The auxiliary function then checks the list, and if it's not empty it calls itself with the tail of the list and the head of the list consed onto the auxiliary argument. If it is empty, it returns the auxiliary argument. It's a little subtle but you can see that this in fact reverses the list.
So now we can write our function using only recursive functions we wrote:
(defun numbers (n)
(reverse-list (numbers-backwards n)))
But now there should be a moment of inspiration: why are we doing this whole
build-it-backwards-and-reverse-it thing? Why don't we just make numbers do the accumulator trick itself! Well, we can do that:
(defun numbers (n)
(numbers-accumulator n '()))
(defun numbers-accumulator (n accum)
(if (< n 1)
accum
(numbers-accumulator (- n 1) (cons n accum))))
And now we don't need to reverse the list, and for added value our
function is 'tail recursive' and will generally be compiled much more
efficiently.
A real-life version of numbers might look more like this, using a local function:
(defun numbers (n)
(labels ((numbers-accumulator (m accum)
(if (< m 1)
accum
(numbers-accumulator (- m 1) (cons m accum)))))
(numbers-accumulator n '())))
Here is a comparison between the version of numbers using append and the above function, on an argument small enough that the append version does not overflow the stack.
> (time (progn (numbers/append 2000) (values)))
Timing the evaluation of (progn (numbers/append 2000) (values))
User time = 0.024
System time = 0.001
Elapsed time = 0.017
Allocation = 32176304 bytes
97 Page faults
> (time (progn (numbers 2000) (values)))
Timing the evaluation of (progn (numbers 2000) (values))
User time = 0.000
System time = 0.000
Elapsed time = 0.001
Allocation = 32000 bytes
0 Page faults
You can see how terrible the append version is, and how good the other one is: this is a 64-bit Lisp, and conses are two words or 16 bytes: it has allocated precisely 2000 cons cells which is the minimum it could do.

Related

Why is the empty list produced here in this iteration?

Let's take the following function to get a pair of numbers:
; (range 1 3) --> '(1 2 3)
(define (range a b)
(if (> a b) nil
(cons a (range (+ 1 a) b))))
; generate pair of two numbers with 1 <= i < j <= N
(define (get-pairs n)
(map (lambda (i)
(map (lambda (j) (list i j))
(range 1 (- i 1))))
(range 1 n)))
(get-pairs 2)
; (() ((2 1)))
(get-pairs 3)
(() ((2 1)) ((3 1) (3 2)))
Why does the above produce '() as the first element of the output? Comparing this with python, I would expect it to just give the three pairs, something like:
>>> for i in range(1,3+1): # +1 because the range is n-1 in python
... for j in range(1,i-1+1):
... print (i,j)
...
(2, 1)
(3, 1)
(3, 2)
I suppose maybe it has to do with when i is 1?
(map (lambda (j) (list 1 j)) '())
; ()
Is that just an identity in Scheme that a map with an empty list is always an empty list?
When i is 1, the inner map is over (range 1 0), which is () by your own definition. Since map takes a procedure and a list (or lists) of values, applies the procedure to each value in the list in turn, and returns a list containing the results, mapping any procedure over a list containing no values will return a list containing no values.
It might help to create a simple definition for map to see how this might work. Note that this definition is not fully featured; it only takes a single list argument:
(define (my-map proc xs)
(if (null? xs)
'()
(cons (proc (car xs))
(my-map proc (cdr xs)))))
Here, when the input list is empty, there are no values to map over, so an empty list is returned. Otherwise the procedure proc is applied to the first value in the input list, and the result is consed onto the result of mapping over the rest of the list.
A couple of observations:
First, the empty list is not represented by nil in either standard Scheme or vanilla Racket, and you should not be using it. In the early days of Scheme nil was allowed as a crutch for programmers coming from other lisps, but this has not been the case for a long time. I don't think that it was ever in any of the RnRS standards, but nil may have survived in some specific implementations until maybe R4RS (1991). SICP was from that era. Today you should use '() to represent empty list literals in Scheme so that your code can run on any Scheme implementation. Racket's #lang sicp allows code directly from the book to be run, but that should not keep you from using the common notation. Note that Common Lisp does use nil as a self-evaluating symbol to represent both the empty list, and boolean false. Seeing this in Scheme just doesn't look right today.
Second, you will probably be led astray more often than to wisdom by thinking in terms of Python when trying to understand Scheme code. In this particular case, map is an iteration construct, but it is not the same thing as a for loop. A for loop is usually used for side-effects, but map is used to transform a list. Scheme has a for-each form which is meant to be used for its side-effects, and in that sense is more like a for loop. The Python version that is posted above is not at all like the Scheme version, though. Instead of returning the results in a list, the results are printed. In the Scheme code, when i is 1, the inner mapping is over (range 1 0) --> (). But, in the Python code, when i is 1, the inner loop is over range(1, 1), so the body of this for loop is not executed and nothing is printed.
Better to think carefully about the Scheme code you want to understand, falling back on basic definitions, than to cobble together a model based on Python that has possibly unconsidered corner cases.

Modified Sieve for finding Prime Numbers in Scheme

I am working on coming up with a solution for coming with a list of prime numbers using the Sieve of Eratosthenes. So the program is supposed to find prime numbers up to a specific number "n". I believe I have come up with an incomplete solution but not sure how to proceed from here.
;;;This is a helper function
(define sievehelper
(lambda (list)
;;; This is the base condition where we are comparing
;;; that the divisor is less than the square root of n""
(if (> (car list) (sqrt (car (reverse list))))
'()
;;; If the base condition has not be reached, then send it through
;;; this filter function where not-divisible by will go through
;;; the specified list and only output the list which contains
;;; the numbers that are not divisible by (car list)
(filterfunc (not-divisible-by (car list))
list)))
I have tested the other helper function fliterfunc on its own and it works fine.
;;;; This is the main function that calls the above helper function
(define sieve
(lambda (n)
;;; `makelist` is a helper function to generate the list from 2 to n
(sievehelper (makelist n))))
I have tested the makelist helper function separately and it works fine.
My question is with the helper function "sievehelper" in terms of how to iterate through the different elements in the list as the divisor.
Any help is appreciated. Thank you.
One piece of code that leads to getting stuck is (if ( > (car list) (sqrt (car(reverse list)))), which looks a lot like the loop condition you might use in other languages (and the word "iterate" hints at peeking at other languages, as well).
I would recommend that you start over, with a different strategy.
When you work with lists, you usually want to recurse on their structure alone.
Assume that you have the list of all integers, starting with 2.
As a first step, you want to keep the two, and remove all its multiples from the remainder of the list.
Now, the result of that removal will give you a list that starts with the next prime number - i.e. 3 - so you can repeat the procedure with that partial result which will remove all multiples of 3, and repeat again with that partial result, and so on until there is no more list.
(Note that this is far from as efficient as it could be, but is more a "get started with thinking recursively" level of suggestion. Read Will's answer for more.)
Applying some wishful thinking and assuming that there is a procedure remove-multiples-of which does what it sounds like, this could look like this:
(define (my-sieve-helper ls)
(if (null? ls)
'()
(cons (car ls)
(my-sieve-helper (remove-multiples-of (car ls) (cdr ls))))))
So, remove-multiples-of...
This is the same as keeping all the numbers that are not divisible by a number, so let's dream up another function:
(define (remove-multiples-of x ls) (filter (not-divisible-by x) ls))
where (not-divisible-by x) is a procedure that takes a number and returns whether that number is not divisible by x.
(define (not-divisible-by n) (lambda (x) (not (zero? (remainder x n)))))
And now we can add a suitable wrapper.
I did this:
(define (from-to m n)
(if (> m n)
'()
(cons m (from-to (+ m 1) n))))
(define (my-sieve n) (my-sieve-helper (from-to 2 n)))
Test:
> (my-sieve 100)
'(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97)
Well, your question presents an interesting case of under-specification that can be advantageous, delaying the actual specification -- not just implementation as usual -- of subroutines used by your piece of code.
Here we have sievehelper which uses the non-implemented non-specified filterfunc and not-divisible-by. Despite their suggestive names these function can do anything, as long as they work, when used together, and make the function using them, sievehelper, also do its work as intended. Delayed specification for the win!
So let's first see what can be intended with the sievehelper as given, what does it do? Assuming the obvious meaning of the two subroutines, it seems to be intended to perform a one-step filtering of its working sequence, culling it from any multiples of its "head" element, the one in its car position.
It would signal the stopping condition by returning (). That stopping condition is a*a > z, for the input list of [a,b,c,...,z].
Otherwise, it does not perform the looping, but just the one step of it. Your sieve doesn't account for that at all, so will need to be changed to continually call this helper, performing step after step as is usual in sieving algorithms, until the square of the first element is bigger than the last element in the working sequence, when it is indeed safe to stop the culling as all the multiples in the sequence will have already been removed from it as multiples of the smaller primes ...... provided that those smaller primes were present in the initial sequence.
So this discovered requirement falls on the third non-implemented subrouting in use, makelist. You do mention that it must create the list of sequential natural numbers from 2 to n, and now we understand why we needed it to do so.
So then, in order to iterate through the different versions of the input list as each divisor is filtered out from it in turn, using your sievehelper definition as given, your sieve function must be changed as e.g.
(define sieve
(lambda (n)
(let ((init (makelist n)))
(let loop ((this init )
(next (sievehelper init)))
(if (null? next)
this
(cons (car this)
(loop next
(sievehelper next))))))))
(The above code incorporates the fix by ad-absurdum from the followup Q&A entry, to the error that this code originally contained).
This code comes from the perspective of working with a pair -- the current sequence, and its next iteration. On each step the next version of the list is found after all the multiples of its head element are removed from it by sievehelper (including the head element itself, the next found prime) -- or the empty list is instead returned to signal the end of processing when all the numbers in the list are known to already be prime, by construction.
Trying it out in Racket:
> (sieve 50)
'(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47)
To run it, further definitions had to be made:
(define filterfunc filter)
(define (not-divisible-by n) ; NB! this critically depends on
(let ((m n)) ; filterfunc working over its
(lambda (x) ; argument list _in order_ NB!
(let ((ret (not (= x m))))
(if (>= x m) (set! m (+ m n)) #f)
ret))))
(define (makelist n)
(range 2 (+ 1 n))) ; in Racket
Defining the not-divisible-by as we did here, enumerating the multiples of each prime internally by iterated additions, makes it be the sieve of Eratosthenes indeed. And stopping early (at the square root of the limit), as in your original code, keeps its time complexity on the sane side, closer to optimal.

Using a counter within a function Scheme

I want to find a way to use a counter within a function where the counter is also a variable within the recursive function. An example of this is with a program that takes a list and then "sifts" through it until it finds all the numbers within it that are multiples of i:
(define (multiples-of lst) (lambda (i) (if (> i 3))
'()
(multiplefilter (ismultipleof (+ i 1)) (lst)))))
where ismultipleof checks if the car of each list is a multiple of i + 1 (with i starting at 1) and then the multiplefilter is a separate function that scraps any values of the list that are not multiples of i. So that if I put in the list (1 2 3 4 5 6 7 8 9 10 11 12) the output would just be (6 12). The biggest issue is getting said counter to work within the function.
Well, here's a simple function that uses a counter in its execution. range just returns a list of integers from 0 up to (- n 1). It's just as easy to write something that increments a counter.
(define (range n)
(let loop ((acc '())
(list-start (- n 1)))
(if (negative? list-start)
acc
(loop (cons list-start acc) (- list-start 1)))))
This function counts down rather than up because recursion usually builds lists "backwards". Counting down just avoids the need call reverse on the acc when the recursion is finished.
Iteration is usually accomplished with recursion in Scheme instead of for loops as in some languages. In particular, recursion from the tail is something to strive for since it will not "blow the stack".

Scheme - Return list of N Repetitions of said list

First off, this is a homework question so just looking for guidance and not an answer.
Write a function named (cycle ALIST N) that accepts a list of elements ALIST and an integer N. This function returns a list containing N repetitions of the elements of ALIST. If N is non-positive, this function returns the empty list.
I will be honest in that I'm not sure how to begin solving this problem. I've been thinking of writing a helper function then using cons calling this n times but just looking if I'm on the correct track here.
One of the more common ways to tackle recursive problems is to begin thinking about it at the end. In other words, under what conditions should you stop? —When are you done? If you can write this base case down, then you only need to ask, what do I do when I am one step away from stopping? This is the recursive step, and for relatively simple recursive problems you are done as the whole problem is either "continue" to do the same thing or "stop."
Knowing the base case usually tells you what kind of extra information you may need to carry around, if any.
In the case of scheme and racket, which support tail call optimization, you may end up with different kinds of recursion. For example:
(define (normal-factorial n)
(if (zero? n)
1
(* n (normal-factorial (- n 1)))))
(define (tail-factorial n)
(letrec ((tf (lambda (product index)
(if (zero? index)
product
(tf (* product index) (- index 1))))))
(tf n (- n 1))))
In the first case, we build up a product without ever multiplying until the very end, while in the second we multiply as soon as possible and carry around this temporary product the whole time.
Not all problems easily lend themselves to one kind of recursion or the other.
You have different strategies you can make. The simplest is probably not the most effiecent but the one that produces less code:
(require srfi/26) ; cut
(define (cycle lst n)
(define dup-lst (map (cut make-list n <>) lst))
(foldr append '() dup-lst))
So what this does is that the map creates a list of lists where each is n elements of each. The foldr flattens it by using append.
With more hands on you can make it more efficient. I'm thinking roll your own recursion consing the elements from end to beginning in an accumulator:
(define (cycle lst n)
(let helper ((lst (reverse lst)) (c n) (acc '()))
(cond ((null? lst) acc)
((<= c 0) (helper ...))
(else (helper ...)))))
I've left out the recursive parts. What this does is a base case on the empty list, a reset recur with a c reset to n and the cdr when c is zero and the default case keeping lst while reducing c and cons-ing the first element of lst to acc. This is a O(n) solution.

Continuation Passing Style In Common Lisp?

In an effort to find a simple example of CPS which doesn't give me a headache , I came across this Scheme code (Hand typed, so parens may not match) :
(define fact-cps
(lambda(n k)
(cond
((zero? n) (k 1))
(else
(fact-cps (- n 1)
(lambda(v)
(k (* v n))))))))
(define fact
(lambda(n)
(fact-cps n (lambda(v)v)))) ;; (for giggles try (lambda(v)(* v 2)))
(fact 5) => 120
Great, but Scheme isn't Common Lisp, so I took a shot at it:
(defun not-factorial-cps(n k v)
(declare (notinline not-factorial-cps)) ;; needed in clisp to show the trace
(cond
((zerop n) (k v))
((not-factorial-cps (1- n) ((lambda()(setq v (k (* v n))))) v))))
;; so not that simple...
(defun factorial(n)
(not-factorial-cps n (lambda(v)v) 1))
(setf (symbol-function 'k) (lambda(v)v))
(factorial 5) => 120
As you can see, I'm having some problems, so although this works, this has to be wrong. I think all I've accomplished is a convoluted way to do accumulator passing style. So other than going back to the drawing board with this, I had some questions: Where exactly in the Scheme example is the initial value for v coming from? Is it required that lambda expressions only be used? Wouldn't a named function accomplish more since you could maintain the state of each continuation in a data structure which can be manipulated as needed? Is there in particular style/way of continuation passing style in Common Lisp with or without all the macros? Thanks.
The problem with your code is that you call the anonymous function when recurring instead of passing the continuation like in the Scheme example. The Scheme code can easily be made into Common Lisp:
(defun fact-cps (n &optional (k #'values))
(if (zerop n)
(funcall k 1)
(fact-cps (- n 1)
(lambda (v)
(funcall k (* v n))))))
(fact-cps 10) ; ==> 3628800
Since the code didn't use several terms or the implicit progn i switched to if since I think it's slightly more readable. Other than that and the use of funcall because of the LISP-2 nature of Common Lisp it's the identical code to your Scheme version.
Here's an example of something you cannot do tail recursively without either mutation or CPS:
(defun fmapcar (fun lst &optional (k #'values))
(if (not lst)
(funcall k lst)
(let ((r (funcall fun (car lst))))
(fmapcar fun
(cdr lst)
(lambda (x)
(funcall k (cons r x)))))))
(fmapcar #'fact-cps '(0 1 2 3 4 5)) ; ==> (1 1 2 6 24 120)
EDIT
Where exactly in the Scheme example is the initial value for v coming
from?
For every recursion the function makes a function that calls the previous continuation with the value from this iteration with the value from the next iteration, which comes as an argument v. In my fmapcar if you do (fmapcar #'list '(1 2 3)) it turns into
;; base case calls the stacked lambdas with NIL as argument
((lambda (x) ; third iteration
((lambda (x) ; second iteration
((lambda (x) ; first iteration
(values (cons (list 1) x)))
(cons (list 2) x)))
(cons (list 3) x))
NIL)
Now, in the first iteration the continuation is values and we wrap that in a lambda together with consing the first element with the tail that is not computed yet. The next iteration we make another lambda where we call the previous continuation with this iterations consing with the tail that is not computed yet.. At the end we call this function with the empty list and it calls all the nested functions from end to the beginning making the resulting list in the correct order even though the iterations were in oposite order from how you cons a list together.
Is it required that lambda expressions only be used? Wouldn't a named
function accomplish more since you could maintain the state of each
continuation in a data structure which can be manipulated as needed?
I use a named function (values) to start it off, however every iteration of fact-cps has it's own free variable n and k which is unique for that iteration. That is the data structure used and for it to be a named function you'd need to use flet or labels in the very same scope as the anonymous lambda functions are made. Since you are applying previous continuation in your new closure you need to build a new one every time.
Is there in particular style/way of continuation passing style in
Common Lisp with or without all the macros?
It's the same except for the dual namespace. You need to either funcall or apply. Other than that you do it as in any other language.

Resources