Scheme how to create a list - list

Okay this may sound like a ridiculous question, but how do you return a list in scheme.?

Based on seeing some of your other questions, I think you may be having trouble getting your head wrapped around the concepts central to a functional language such as Scheme.
At the level you're learning Scheme (novice), every function you write has an input and an output, and the body of every function is a single expression. Whatever value that expression evaluates to is returned by the function. There is no need to explicitly "return" anything as you would in an imperative language like Java or C; it just happens as a direct consequence of evaluating the expression.
The body of a function is a single expression. It's not like Java where the body of a method consists of a series of instructions:
do this
then do that
then do something else
then return something (maybe)
Scheme functions evaluate a single expression; nothing more. Here's a simple function that adds 5 to whatever number is passed as an argument:
(define (add5 x)
(+ x 5))
The body of the function is (+ x 5), which is just an expression to be evaluated. The value of x is plugged in, the + (addition) function is applied to x and 5, and the result is returned.
Lists aren't much different. All you need is an expression that will construct a list. Two have already been mentioned: list is used to build a list from scratch if you already have all the elements; cons is used to add a single element to an existing list and is often used recursively.
Here's a function that consumes a number n and builds the list (n n-1 n-2 ... 0)
(define (makelist n)
(if (= n 0)
(list 0) ; base case. Just return (0)
(cons n (makelist (- n 1))))) ; recursive case. Add n to the head of (n-1 n-2 ... 0)
In both the base and recursive cases, a list is returned by simply evaluating an expression that uses one of the list-building functions.
Here's another example. This one uses our add5 function to add 5 to each element of a list of numbers (lon):
(define (add5list lon)
(if (null? lon)
`() ; base case: lon is empty. Return an empty list.
(cons (add5 (car lon)) (add5list (cdr lon))))) ; recursive case.
; Add 5 to the head of lon and prepend it to the tail of lon
Again, both the base and recursive cases are returning lists by evaluating expressions that result in lists.
The key thing to remember about Scheme is all functions return something, and that something is simply the result of evaluating an expression. The body of a Scheme function is a single expression.

You probably want simply: '(2 3 5 7 11) or (list 2 3 5 7 11)?
You can also construct lists by specifying an element and a list to add it to: (cons 2 (cons 3 '()))
Here's an example of returning a list from a function:
(define returnlist
(lambda(a b c)
(cons a (cons b (cons c '())))
))
(returnlist 2 3 4)
Return value will be the list: (list 2 3 4)

Another not-so-well known way to do this:
> ((lambda x x) 2 3 5 7 11)
(2 3 5 7 11)
that is, the "list" function itself can be defined as:
> (define list (lambda x x))

Related

I need help to understand a lisp program that finds the depth of a list

I need help to understand my code theoretically. Here is my lisp program:
(defun depth (lst)
(if (or (null lst) (atom lst)) 0
(+ 1 (apply 'max (mapcar #'depth lst)))
))
I know it works with this example:
(write (depth '((a (b c) d r ((t))))) -> 3
I just can't understand the else statement of the IF statement that I tried.
If you can help me, it will be very much appreciated. Thank you in advance.
Here is your code, slightly reformatted:
(defun depth (value)
(if (or (null value) (atom value))
0
(+ 1 (apply 'max (mapcar #'depth value)))))
I renamed lst (you could have written it list, by the way) to value, because the name is confusing as it suggest that the variable is always a list, which is not true. The function depth can be called on any value:
(depth "hello")
=> 0
(depth 100)
=> 0
The then branch of the if is evaluated when value is NIL or any atom. Since NIL is also an atom, the test expression could be simplified as (atom value). When value is an atom, the depth is zero.
The else branch of the if is evaluated when value is not an atom, which by definition of atom means value here is a cons. The function also assumes that it is a proper list, and not some circular list.
Since value is a list in that branch, we can call mapcar on it: (mapcar #'depth value); this is where the function assumes the list is proper.
This computes (depth v) for each v in value. More precisely if value is a list of length n, then that call to mapcar evaluates as a list of numbers (D1 ... Dn) where Di is (depth Vi) for all i between 1 and n.
So we know that (apply 'max (mapcar ...)) is (apply 'max depths) for some list depths of numbers. In general:
(apply fn v1 ... vn list)
... is a way to call the function object denoted by the fn expression with at least n elements (v1 to vn), as well as an arbitrary number of additional elements stored in list. When you quote the function, as 'max, or when you write #'max, you refer to a function by its name in the function namespace.
Contrast this to the usual way of calling a function:
(f x y z)
The function name and the number of arguments being passed is fixed: as soon the form is read we knows there is a call to f with 3 arguments.
The apply function is a built-in that allows you to pass additional arguments in a list, in the last call argument. The above call could be written:
(apply #'f x y z ()) ;; note the empty list as a last argument
This could also be written:
(apply #'f (list x y z)) ;; all arguments in the last list
The only difference is probably a matter of runtime efficiency (and with good compilers, maybe there is no difference).
In your example, you do:
(apply max depths)
Which would be the same as writing (pseudo-code):
(max d1 d2 d3 ... dn)
... where depths is the list (list d1 d2 ... dn).
But we can't literally write them all directly, since the content of the list is only known at runtime.
Thus, the call to apply computes the max depths among all the depths computed recursively. Note that the above is a somewhat improper use of apply, since apply should not be called with lists of arbitrary size: there is a limit in the standard named CALL-ARGUMENTS-LIMIT that is allowed to be as low as 50 in theory, the maximum size of such a list (we will see an alternative below).
Finally, depth evaluates (+ 1 ...) on this result. In other words, the whole expression can be summarized as: the depth of a list is 1 added to the maximum depth of all its elements.
Using reduce
Instead of apply, you can use REDUCE to compute max successively on a list. This is preferable to apply because:
there is no limitation for the number of elements, like apply
(reduce 'max depths) ;; works the same, but more reliably
there is no need need to build an intermediate list of depths, you iterate over the list of values, call depth and directly use the result to compute the max. The skeleton is:
(reduce (lambda (max-so-far item) ...)
value
:initial-value 0)
Declarative approach
Instead of reduce, the loop macro can be used as a more readable alternative to express the same computation. I also use typecase which in my opinion makes the intent clearer:
(defun depth (value)
(typecase value
(atom 0)
(cons (1+ (loop for v in value maximize (depth v))))))

Insertion into a list doesn't reflect outside function whereas deletion does?

I am new to Lisp. Deletion of an item in a list by a function gets reflected outside the function but insertion doesn't. How can I do the same for insertion?
For example
(defun test (a b)
(delete 1 a)
(delete 5 b)
(append '(5) b)
(member '5 b))
(setq x '(2 3 1 4))
(setq y '(8 7 5 3))
(test x y)
;;x and y after function ends
x
(2 3 4)
y
(8 7 3)
Why doesn't append affect list y? How can I insert something into y from within the function?
Append isn't supposed to modify anything
Why doesn't append affect list y?
The first sentence of the documentation on append is (emphasis added):
append returns a new list that is the concatenation of the copies.
No one ever said that append is supposed to modify a list.
You can't change the value of a lexical binding outside its scope
How can I insert something into y from within the function?
In the most general sense, you cannot. What happens if the value of y is the empty list? There's no way with a function (as opposed to a macro) to make something like this work in Common Lisp:
(let ((list '())
(insert list 1)
l)
;=> (1)
A function cannot change the lexical binding of a variable outside its scope1, so there's no way for insert to change the value of list.
You can, of course, modify the internal structure of an object, so if the value of list is some non-empty list, then you could modify the structure of that list. The value of list wouldn't change (i.e., it would still the same cons cell), but the list represented by that cons cell would change. E.g.,
(defun prepend (list element)
(let ((x (first list)))
(setf (rest list) (list* x (rest list))
(first list) element)))
(let ((list (list 1 2)))
(prepend list 'a)
list)
;=> (a 1 2)
Save return values
In general, you need to get into the habit of saving the results of functions. Most functions won't modify their arguments, so you need to save their results. Some functions are permitted, but not required, to modify their arguments, and they don't have to modify in a predictable way, so you need to save their results too. E.g., your code could be:
(defun test (a b)
(setf a (delete 1 a))
(setf b (delete 5 b))
(setf b (append '(5) b))
(member 5 b))
(test ...)
;=> true
1 You could work around this by giving it a setter function that closed over the binding, etc. But those kind of techniques would be workarounds.

Evaluate function from list in lisp

I need to write a function in lisp with two arguments - list of argumentless functions and list of integers.
I need to evaluate functions from first list in order given by a second, i.e. (fun '(#'a #'b #'c) '(2 0 1)) should evaluate c, a, b.
I tried such function:
(defun z4(funs kols)
(funcall (nth (first kols) funs))
(z4 funs (rest kols))
)
but in funcall I am geting error
NIL is not of type CONS.
What does it means? I am getting same error by calling simply
(funcall (first funs))
so I assume it is something with with getting function from the list of functions. How can I evaluate function get from list of functions?
With each recursive call you reduce the kols parameter untill it becomes nil. When kols becomes nil you should terminate the recursion, so you should add the test for the terminating condition (i.e., for empty list):
(defun foo (funcs order)
(unless (endp order)
(funcall (nth (first order) funcs))
(foo funcs (rest order))))
I suggest a more readable solution (it's also more preferrable since ANSI Common Lisp Standard doesn't force implementations to perform tail call optimization):
(defun foo (funcs order)
(loop for n in order do (funcall (nth n funcs))))
In the previous examples I assume that you run your functions for their side effects, not for the return values.
Edit 1
As Vatine noted, using nth and lists to provide a collection with random access is not good for the performance, so it might be worth to store functions in a vector (that is a one-dimensional array) rathen than in a list. So, assuming that funcs is a vector of functions, the function can be defined as follows:
(defun foo (funcs order)
(loop for n in order do (funcall (aref funcs n))))
Moreover, we can replace aref with svref if the array of functions is a simple vector (glossary entry). The former is more general, but the latter may be faster in some implementations.
One can create a simple vector of functions using either
(vector #'func-a #'func-b ...)
or
#(func-a func-b ...)
A simple vector of functions can be created using the make-array function as well, but only if :adjustable and :fill-pointer keyword arguments are unspecified or nil.
'(#'a #'b #'c)
is not a list of functions A, B, C. It is this:
((FUNCTION A) (FUNCTION B) (FUNCTION C))
Above are not functions, but lists with the first symbol FUNCTION and then another symbol.
Use either
(list #'a #'b #'c)
or
'(a b c)

Lisp Exercises Involving List Manipulation

I trying to complete this exercise;
Write a Lisp function that takes as input a list of elements, such as (A B C)
, and returns a list in which the position of each element follows it, such as (A 1 B 2 C 3)
I'm trying to do it with two functions, however its not working correctly, I'm just getting the same list. Here is my code:
(defun insert (index var userList)
(if (or (eql userList nil) (eql index 1))
(cons var userList)
(cons (car userList) (insert (- index 1) var (cdr userList)))))
(defun insertIndex (userList)
(setq len (length userList))
(loop for x from 1 to len
do (insert x x userList)))
The insert functions seems to work fine on its own, but it seems like it doesn't do anything with loop. I'm new lisp and any help would be appreciated, thanks in advance.
Positions in Lisp start with 0. In insertIndex the variable len is not defined. The LOOP does not return any useful value.
If you want to solve it with recursion, the solution is much simpler.
You need to test for the end condition. If the list is empty, return the empty list.
Otherwise create a new list with the FIRST element, the current position and the result of calling the function on the rest of the list and the position increased by one.
(LIST* 1 2 '(3 4)) is shorter for (cons 1 (cons 2 '(3 4))).
Here is the example with a local function. To create a top-level function with DEFUN is now your task. You only need to rewrite the code a bit. LABELS introduces a potentially recursive local function.
(labels ((pos-list (list pos)
(if (null list)
'()
(list* (first list)
pos
(pos-list (rest list) (1+ pos))))))
(pos-list '(a b c d e f) 0))
The main problem with your insertIndex function is that the do clause of loop is for side-effects only, it doesn't change the return value of the loop. (And your insert is side-effect free.) The right loop clause to add elements to a list return value is collect. (There are also append and nconc to join multiple lists.)
This is a working function:
(defun insert-index (list)
(loop for elt in list and i from 1
collect elt
collect i))
Your whole expectations about the behaviour of the insert and insertIndex functions seem to be flawed. You need to get a clearer mental model about which functions are side-effecting, which are not, and whether you need side-effects or not to solve some particular problem.
Also, you shouldn't call setq on an undefined variable in Common Lisp. You need to first use let to introduce a new local variable.
Minor points: CamelCase is very unidiomatic in Lisp. The idiomatic way to seperate words in identifiers is to use dashes, like I did in my code example. And you don't need to do (eql something nil), there's the special null function to check if something's nil, e.g. (null something).

How do you find list of a list inside the Scheme list?

I am working on an assignment and I need to find a list inside of a list. For example, if we have
(has-list? '(1 2 (3 4) 5))
than it will return true because (3 4) is a list inside of a bigger list.
The function (list? l) will return #t if l is a list, and #f if it's not
(define (has-list l)
(if (null? l)
_____
(or (________) (_________))))
fill in the blanks!
Well, if the Scheme implementation in hand provides a library function like any which expects a predicate and a list as arguments to test any existence of an element in the list satisfying the predicate, you can simply write (any list? '(1 2 (3 4) 5)), otherwise, do fill the blanks prelic left for you.