What does the following function do in Scheme programming language - functional-programming

(define (unknown (lambda (x y)
(cond
((null? y) y)
((x (car y)) (unknown x (cdr y))))
(else (cons (car y) (unknown x (cdr y)))))))
I'm a newbie when it comes to scheme and wanted to know the purpose of this function which I came across in a textbook. My main doubt lies as to what ((x (car y)) does. How does this expression get executed without any operators and yet I don't come across any errors while compiling. Although I'm unable to run the program because the values I input for x are apparently not applicable for the function. Please help.

Scheme functions can take functions as arguments, and can return functions. Your code makes sense if you pass in a function as an argument.
If you call the code like this:
(unknown even? '(1 2 3 4 5))
then it should return the list (1 3 5). This is a filtering function that returns members of y where the result of applying the function x to the member is false.

Related

Why does this not evaluate in Scheme?

I am using the DrRacket environment to try out the Scheme language.
I defined sum+1 as follows:
(define sum+1 '(+ x y 1))
I was wondering why the following expression does not evaluate:
(let ([x 1] [y 2]) (eval sum+1))
whereas doing this returns the correct value:
(define x 1)
(define y 2)
(eval sum+1)
eval does not work with lexical variables at all unless the lexical variable was created in the same expression:
#!r7rs
(import (scheme base)
(scheme eval))
(define env (environment '(scheme base)))
(let ((x 10))
(eval 'x env)) ; ERROR! `x` is not defined
You can think of it as eval always happening top level with the global bindings of the environment you pass to the second argument. You can perhaps trick it by passing values from your lexical environment like this:
(eval '(let ((x 10))
x)
env) ; ==> 10
(let ((x 10))
(eval `(let ((x ,x))
x)
env) ; ==> 10
By the time most Scheme implementations run code local variables are usually stack allocated. Thus something imagine this code:
(define (test v)
(display v)
(newline)
(eval 'v))
Might turn into this at runtime:
(define (test 1 #f) ; indicates 1 argument, no rest
(display (ref 0)) ; fetches first argument from stack
(newline)
(eval 'v)) ; but what is v?, certainly not the first argument
Also you can make corner cases. What happens if you mutate?
(define (test v)
(eval '(set! v 10))
v)
The structure to eval might come from user input so it's not obvious that v gets mutated, also many compiling Scheme implementations need to treat variables that mutate differently so it needs to know before the code runs that v needs special treatment, but it is not decidable because the (set! v 10) might come from the database or user input. Thus by not including local bindings you save yourself a lot of trouble and the language gets easier to optimize and compile.
There are lisp languages that can only be interpreted since it allows for passing macros as first class objects. These languages are impossible to reason about at compile time.
The reason that the command with let does not work is that let creates local variables. This means that the variables it creates can NOT be accessed from just anywhere - only from within let's body argument.
In your example, you defined:
(define sum+1 '(+ x y 1))
Then you commanded this:
(let ([x 1] [y 2]) (eval sum+1))
This doesn't work because x and y are only being defined in the eval statement, not within the procedure sum+1. This may seem counter-intuitive, but it prevents many errors with other inputs.
Your second example was:
(define x 1)
(define y 2)
(eval sum+1)
This does works because x and y are defined globally. This means that they CAN be accessed anywhere, and by anything. They are then applied to the sum+1 definition and are able to be printed. Please respond with any questions or feedback you have!

Scheme Recursion and Updated Condition

I'm having trouble incorporating a recursive function that squares a number.
Basically I am trying to write a function that keeps calling the Add function x number of times to square it. So if it is 7 it should call it seven times to get 49.
(define (Add a b)
(if (and (number? a) (number? b))
(+ a b)
(lambda (x)
(+ (a x) (b x)))))
(define i 0)
(define ans 0)
(define (Square a)
(when (> i a)
((Add a ans) (+ i 1 ))))
The main issue I'm running into is that the square function only goes through the loop once, I'm not sure why the condition won't update/keep going through the loop till it reaches that condition.
Writing square directly is a big pain. It's much easier to write a recursive multiply function and then just have your square function call multiply. Follow the design recipe for recursion on the natural numbers, as it appears in section 9.3 of HtDP.
By the way, if you haven't already written a bunch of recursive functions on more standard self-referential data definitions (e.g. lists), then, well, I claim that your instructor is doing in wrong.
You should make everything that changes parameters. Imagine you want to make the factorial then two values change. It's the result and the iteration of the number down to zero.
(define (factorial value)
(define (helper cur ans)
(if (zero? cur)
ans ; finished. return the answer
(helper (- cur 1) ; recur by updating n
(* cur ans)))) ; and update the answer
(helper value 1))
Again. It's exactly the same as my example in the comment except it does something else at each step. The basic building blocks are the same and something that would square the argument is very similar.

The mechanism of anonymous function to call itself in Scheme?

I'm reading The Little Schemer and feel confused about the following code:
((lambda (len)
(lambda (l)
(cond
((null? l) 0)
(else
(+ 1 (len (cdr l)))))))
eternity)
(define eternity
(lambda (x)
(eternity x)))
The code is to determine the empty list, otherwise it never stops.
Why is the "len" not recursion?
Although it can be dangerous to apply textual substitution to Lisp forms (since there are dangers of multiple evaluation, etc.), in this case it may help to look at this form and see how it fits together:
((lambda (len)
(lambda (l)
...))
eternity)
is an application, i.e., a function call. The function getting called takes one argument, called len, and returns another function that takes a single argument l. The function getting called is called with eternity. When the call completes, the result is this function:
(lambda (l)
(cond
((null? l) 0)
(else (+ 1 (eternity (cdr l))))))
Now, this function takes a list l and if it's empty, returns 0. Otherwise, it computes (cdr l) (the rest of the list), and calls eternity with that value. When that returns, 1 is added to the result, and that's the return value of the whole function. The problem, of course, is that eternity
(define eternity
(lambda (x)
(eternity x)))
which could also be written as
(define (eternity x)
(eternity x))
simply takes an argument x, and then calls eternity with x. That's an infinite loop. In the above, I wrote "When that returns", but in fact, (eternity (cdr l)) never returns. So,
((lambda (len)
(lambda (l)
(cond
((null? l) 0)
(else (+ 1 (len (cdr l)))))))
eternity)
is a function call that returns a function (lambda (l) …) that returns 0 if called with an empty list, and goes into an infinite loop with a non-empty list.
From a program analysis side of things, it's worth noting that there are other values for which this won't go into an infinite loop. For instance, if you call it with a string, then (cdr l) will be an error.
Like you say, this is a definition of a length function as a partial function where it only completes for the empty list. But this hasn't gotten to the y-combinator part yet, it isn't an example of an anonymous function calling itself.
l is a list of atoms, it is the argument to the function returned when (lambda (len) ...) is evaluated.
len is a function passed into the outer lambda as an argument.
The outer expression creates a lambda with eternity passed in as its argument. The outer lambda returns a function created by evaluating the inner lambda, the returned function is the thing that takes eternity as an argument.
If the code is passed an empty list (meaning wrap the whole first part followed by a '() in another set of parens) then it will evaluate to 0, of course. len never gets evaluated.
If the code is passed a nonempty lat then it will try to evaluate the len argument and you get an infinite recursion.

towers of hanoi in common lisp

I think this is going to be a vague question because I don't know exactly what I am doing in the first place but here it goes.
I have to do a towers of hanoi problem in common lisp using lists. Basically a function takes a list of strings (names) and then moves them from peg A to peg C using peg B for storage, keeping them in the same order as they were in the list.
I have never used lisp before and I find the syntax very hard to understand.
This is my code so far
goo function is the hanoi work
(defparameter A '())
(defparameter B '())
(defparameter C '())
(defun findPeg (p1 p2) (cond ((= 0 (- 3 p1 p2))A)
((= 1 (- 3 p1 p2))B) ((= 2 (- 3 p1 p2))C)))
(defun getnum (x) (cond ((equalp x A) 0)((equalp x B)1)((equalp x C) 2)))
(defun hanoi (x) (defparameter A x) (setlength A)(goo len A C B))
(defun setlength(x) (defparameter len (list-length x)))
(defun goo (leng from to via)
(cond ((= leng 1)(push (pop A) C)) ;base case
((goo (1- leng) from via to)(push (pop A) B) ;say/do something i think
((goo (1- leng) via to from)(push (pop B) C) ;say/do something i think
))))
My problem is with the recursive calls. I am very confused as to what exactly I should be doing. I know I obviously have to move the first string in the first list to another peg, but I don't know which peg or even how to manipulate the lists. I feel like I should be using the variables that were passed into the goo function, but I cant figure out how to edit them because when I change them in the function the variables outside do not change.
Right now I am running into the error
* - SYSTEM::%EXPAND-FORM: (GOO (1- LENG) FROM VIA TO) should be a lambda expression
This is a recursive call so I don't know why it is saying that.
Basically I just want some tips or tricks on where do continue or ever where to restart because I don't even know if my approach is a good one.
Anything is greatly appreciated. Thanks
First off, using defparameter inside a DEFUN is almost never the right thing to do.
If you want to have a lexically-scoped variable, use LET (or simply name your formal parameters as you'd like them named).
Second, you have something on the form ((fun arg ..) (fun arg ...)) inside your GOO function. You want to lose the outermost parentheses.

Flatten a list two ways: (i) using MAPCAN and (ii) using LOOP

My professor has given us a refresher assignment in clisp. One exercise is to achieve the same thing in three ways: Return a flattened list of all positive integers in a given list.
Now, there's only one way I really like doing this, using cons and recursion, but he wants me to do this using mapcan and a loop (I suspect lisp is not his first choice of language because this style of coding feels extremely resistant to the nature of lisp). I'm having a hard time working out how one would do this using a loop...I need to first start a list, I suppose?
I apologize for vague language as I'm not really sure how to TALK about using a functional language to write procedurally. Following is my first attempt.
(defun posint-loop (l)
(loop for i in l
do (if (listp i)
(posint-loop i)
(if (integerp i)
(if (> i 0)
(append i) ; this doesn't work because there's nothing to
; start appending to!
nil)
nil))))
In order to establish a new lexical binding, use let or the with keyword of loop. In order to extend an existing list, you might want to use push; if you need the original order, you can nreverse the new list finally.
Another way would be to use the when and collect keywords of loop.
Another hint: mapcan implicitly creates a new list.
Mapcan applies a function to each element of a list, expecting the function to return a list, and then concatenates those resulting lists together. To apply it to this problem, you just need to process each element of the toplevel list. If the element is a list, then you need to process it recursively. If it's not, then you either need to return an empty list (which will add no elements to the final result) or a list of just that element (which will add just that element to the final result):
(defun flatten2 (list)
(mapcan (lambda (x)
(cond
((listp x) (flatten2 x))
((and (integerp x) (plusp x)) (list x))
(t '())))
list))
(flatten2 '((a 1 -4) (3 5 c) 42 0))
;=> (1 3 5 42)
With loop, you can do just about the same thing with the recognition that (mapcan f list) is functionally equivalent to (loop for x in list nconc (funcall f x)). With that in mind, we have:
(defun flatten3 (list)
(loop for x in list
nconc (cond
((listp x) (flatten3 x))
((and (integerp x) (plusp x)) (list x))
(t '()))))

Resources