How to generate a list of lambdas in scheme? - scheme

I am trying to make a procedure which takes a list of lambdas, and uses the return value of these lambdas. In order to create and populate this list, I made the procedure:
(define generate-list-of-numbers-lambdas
(lambda (function)
(if (= (function) 3)
(list (lambda () 2))
(cons (lambda () (- (function) 1))
(generate-list-of-numbers (lambda () (- (function) 1)))))))
This procedure takes a procedure as an argument, and generates a list of numbers from the return value of the argument procedure until 2 (IE the original argument is a procedure which returns 20, the generate-list-of-numbers makes a list (19 18 17... 3 2)
This procedure takes a procedure as an argument (the argument procedure has no arguments, itself, and just returns an integer), however, this generate-list-of-numbers-lambdas procedures generates a list, but only the first element is a lambda.

Your procedure works just fine if you recur using generate-list-of-numbers-lambdas instead of generate-list-of-numbers; you simply forgot the -lambas part of the name.
A couple more things though. Your procedure calls (function) 3 times in the body. If the result needs to be used in more than one place, you should use a let binding.
(define generate-list-of-numbers
(lambda (function)
(let ((x (function))) ;; bind `x` to `(function)`
(if (= x 3) ;; use x
(list (lambda () 2))
(cons (lambda () (- x 1)) ;; use x
(generate-list-of-numbers (lambda () (- x 1)))))))) ;; use x
Next we see (lambda () ...) littered all about the code. A tiny dose of data abstraction goes a long way here -
(define num
(lambda (x)
(lambda () x)))
(define generate-list-of-numbers
(lambda (function)
(let ((x (function)))
(if (= x 3)
(list (num 2)) ;; use num
(cons (num (- x 1)) ;; use num
(generate-list-of-numbers (num (- x 1)))))))) ;; use num
;; calling our procedure is nicer too
(generate-list-of-numbers (num 20))
We see (num (- x 1)) twice again. It should be a let binding.
(define generate-list-of-numbers
(lambda (function)
(let ((x (function)))
(if (= x 3)
(list (num 2))
(let ((next (num (- x 1)))) ;; bind `next`
(cons next (generate-list-of-numbers next)))))) ;; use `next` twice
We used num to put numbers into our container. We will use val to take numbers out.
(define val
(lambda (n)
(n)))
(map val (generate-list-of-numbers (num 20)))
;; '(19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2)
Going back, we see we can use val in our procedure too. Lastly, we rename function to n. This allows us to think purely in terms of our numbers and forget that the values are wrapped a function (thunk), or some other data container.
(define generate-list-of-numbers
(lambda (n) ;; `function` renamed to `n`
(let ((x (val n))) ;; use `val` to read value of `n`
(if (= x 3)
(list (num 2))
(let ((next (num (- x 1))))
(cons next (generate-list-of-numbers next)))))))
(map val (generate-list-of-numbers (num 20)))
;; '(19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2)
All of that said, this is a weird procedure. I can only guess it is a homework assignment or something. It almost seems like you're trying to implement a lazy list of numbers, but it's not quite right. Starting the list at n - 1 and ending at 2 is another obscure choice and red flag. If you can provide a broader goal, I may be able to update the answer and provide additional help.

Related

Calling a function that takes no parameter with a parameter in scheme

How does this code work? It does not seem like any of these functions have a parameter but yet you are able to call it with a parameter
(define (make-add-one)
(define (inc x) (+ 1 x))
inc)
(define myfn (make-add-one))
(myfn 2)
This runs and returns 3.
Lets use substitution rules. make-add-one can be rewritten like this:
(define make-add-one (lambda ()
(define inc (lambda (x) (+ 1 x))
inc))
Since inc is just returned we can simplify it further to this:
(define make-add-one (lambda ()
(lambda (x) (+ 1 x)))
Now myfn we can replace the call to make-add-one with the code that the lambda has inside:
(define myfn (make-add-one)) ; ==
(define myfn (lambda (x) (+ 1 x)))
And at last, we can use substitution rules on the last call:
(myfn 2) ; ==
((lambda (x) (+ 1 x)) 2) ; ==
(+ 1 2) ; ==
3
Now make-add-one makes a new function that is identical to all other functions it makes. It doesn't really add anything. A good example of where this is useful is this example:
(define (make-add by-what)
(lambda (value) (+ value by-what)))
(define inc (make-add 1))
(define add5 (make-add 5))
(map add5 '(1 2 3)) ; ==> (6 7 8)
(map inc '(1 2 3)) ; ==> (2 3 4)
Just to see it's the same:
(add5 2) ; ==
((make-add 5) 2) ; ==
((lambda (value) (+ value 5)) 2) ; ==
(+ 2 5) ; ==
; ==> 7
And how does this work. In a lexically scoped language, all lambda forms captures the variables that are not bound in their own parameter list from the scope which it was created. This is known as a closure. A simple example of this is here:
(define x 10)
(define test
(let ((x 20)
(lambda (y) (+ x y))))
(test 2) ; ==> 22
So in Scheme test uses x from the let even after the scope is out since the lambda was created in that scope. In a dynamically scoped language (test 2) would return 12 and the two previous examples would also produce other results and errors.
Lexical scoping came first to Algol, which is the predecessor to all the C language family languages like C, java, perl. Scheme was proably the first lisp and it was the essential design of the language itself. Without closure first version of Scheme was the same as its host langugage, MacLisp.
Lift the definition of inc out of make-add-one:
(define (inc x) (+ 1 x))
(define (make-add-one)
inc)
Now it's clearer that the expression (make-add-one) is the same as inc, and inc is clearly a procedure with one parameter.
In other words, invoking make-add-one with no arguments produces a procedure that takes one argument.
You can use the substitution method to follow the evaluation:
(myfn 2)
==> ((make-add-one) 2)
==> (inc 2)
==> (+ 1 2)
==> 3

(Scheme) Is it possible to return one of two values depending on input, using only define or math statements?

The user inputs a number. When the number is above a specified amount, something happens. Something else happens if the number is below the specified amount, instead. Is it possible to achieve this without using any booleans/conditionals/ifs? As in purely through mathematical operations or function definitions?
You can do that with sgn and a hash table, for example (in Racket):
(define trigger-value 42) ; this is the reference value
(define action ; defines the actions that should happen
(hash
-1 (lambda () (displayln "below"))
0 (lambda () (displayln "BINGO"))
+1 (lambda () (displayln "above"))))
(define (test n) ; calls the right action procedure depending on n
((hash-ref action (sgn (- n trigger-value)))))
The expression (- n trigger-value) is negative when n < trigger-value, positive when n > trigger- value, and 0 if they are the same. Applying sgn to that value yields in -1, 0 or 1, respectively. That value is then used to look in the hash table which procedure should be called.
Here, the procedures just display a line, but they could also return a value, for example, which could then be used for further calculations.
testing
> (test 11)
below
> (test 90)
above
> (test 42)
BINGO
EDIT
This is the solution mentioned by #Chris in the comments:
(define action
(list
(lambda () (displayln "below"))
(lambda () (displayln "BINGO"))
(lambda () (displayln "above"))))
(define (test n) ; calls the right action procedure depending on n
((list-ref action (add1 (sgn (- n trigger-value))))))
and this is based on alists:
(define action
(list
(list -1 (lambda () (displayln "below")))
(list 0 (lambda () (displayln "BINGO")))
(list +1 (lambda () (displayln "above")))))
(define (test n) ; calls the right action procedure depending on n
((second (assv (sgn (- n trigger-value)) action))))

Scheme operation on a function

Is it possible to do an operation on a previous function, i have a list of values say (1,2,3,4,5), first function needs to multiply them by 2, while 2nd function adds 1 to result of previous function, so first we would get (2,4,6,8,10), and then (3,5,7,9,11) i got this, function g does extra work, is it possible nstead of doing operations on the element do it on function F or results from function F
#lang racket
(define test (list 1 1 2 3 5))
(define (F)
(map (lambda (element) (* 2 element))
test))
(define (G)
(map (lambda (element) (+ 1 (* 2 element)))
test))
First you need to correctly define your procedures to take a list parameter (called lst in this case):
(define (F lst)
(map (lambda (e) (* 2 e)) lst))
(define (G lst)
(map add1 lst))
Then
> (F '(1 2 3 4 5))
'(2 4 6 8 10)
> (G '(2 4 6 8 10))
'(3 5 7 9 11)
or, if you need to combine both procedures:
> (G (F '(1 2 3 4 5)))
'(3 5 7 9 11)
This is a follow-up to your previous question. As stated in my answer there, you should pass the right parameters to the functions - in particular, pass the input lists as parameter, so you can use the result from one function as input for the next function:
(define test (list 1 1 2 3 5))
(define (multiply-list test)
(map (lambda (element) (* 2 element))
test))
(define (add-list test)
(map (lambda (element) (+ 1 element))
test))
Now, if we want to add one to each element in the input list:
(add-list test)
=> '(3 3 5 7 11)
Or if we want to multiply by two each element in the input list:
(multiply-list test)
=> '(2 2 4 6 10)
And if we want to add one first, then multiply by two we can chain the functions! the result from one becomes the input for the other, and the final result will be as follows:
(multiply-list (add-list test))
=> '(6 6 10 14 22)
NB! You have tagged scheme but you use racket (the language). Not all of my examples will work in scheme.
Yes! you even do it yourself in your definition of G where you add a value and the result of a multiplication.
Its possible to chain map
(map f3 (map f2 (map f1 lst)))
Thus if you instead make a function that takes a list and doubles it:
(define (list-double lst)
(map (lambda (x) (* x 2)) lst))
You can chain it to quadruple it:
(define (list-quadruple lst)
(list-double (list-double lst)))
Now it's not optimal to chain map if you can avoid it. Instead you can compose the procedures together:
(define (double x) (* x 2))
(define (list-quadrouple lst)
(map (compose1 double double) lst))
compose1 here is the same as making a anonymous function where you chain the arguments. Eg. the last would be (lambda (x) (double (double x))). A more complex one compose can do more than one value between procedures. eg. (compose + quotient/remainder)

Print value -and- call function?

I am new to scheme, and have the following question:
If I want a function to also print -the value- of an expression and then call a function, how would one come up to doing that?
For example, I need the function foo(n) to print the value of n mod 2 and call foo(n/2), I would've done:
(define foo (lambda (n) (modulo n 2) (foo (/ n 2))))
But that, of course, would not print the value of n mod 2.
Here is something simple:
(define foo
(lambda (n)
(display (modulo n 2))
(when (positive? n)
(foo (/ n 2)))))
Note the check of (positive? n) to ensure that you avoid (/ 0 2) forever and ever.
I'm terrible at Lisp, but here's an idea: Maybe you could define a function that prints a value and returns it
(define (debug x) (begin (display x) (newline) x))
Then just call the function like
(some-fun (debug (some expression)))
As #Juho wrote, you need to add a display. But, your procedure is recursive without a base case, so it will never terminate.
Try this:
(define foo
(lambda (n)
(cond
((integer? n) (display (modulo n 2))
(newline)
(foo (/ n 2)))
(else n))))
then
> (foo 120)
0
0
0
1
7 1/2
Usually when dealing with more than one thing it's common to build lists to present a solution when the procedure is finished.
(define (get-digits number base)
(let loop ((nums '()) (cur number))
(if (zero? cur)
nums
(loop (cons (remainder cur base) nums)
(quotient cur base)))))
(get-digits 1234 10) ; ==> (1 2 3 4)
Now, since you use DrRacket you have a debugger so you can actually step though this code but you rather should try to make simple bits like this that is testable and that does not do side effects.
I was puzzled when you were taling about pink and blue output until I opened DrRacket and indeed there it was. Everything that is pink is from the program and everything blue is normally not outputed but since it's the result of top level forms in the IDE the REPL shows it anyway. The differences between them are really that you should not rely on blue output in production code.
As other has suggested you can have debug output with display within the code. I want to show you another way. Imagine I didn't know what to do with the elements so I give you the opportunity to do it yourself:
(define (get-digits number base glue)
(let loop ((nums '()) (cur number))
(if (zero? cur)
nums
(loop (glue (remainder cur base) nums)
(quotient cur base)))))
(get-digits 1234 10 cons) ; ==> (1 2 3 4)
(define (debug-glue a d)
(display a)
(newline)
(cons a d))
(get-digits 1234 10 debug-glue) ; ==> (1 2 3 4) and displays "4\n3\n2\n1\n"

build-list (error - expects a procedure) Racket/Scheme

Trying to make a function that produces a n by n board
(new-board 2)
is supposed to produce
(list (make-posn 0 0) (make-posn 0 1) (make-posn 1 0) (make-posn 1 1))
The current rendition of my code is as follows:
(define (new-board y)
(build-list y (lambda (x) (build-list x (make-posn y x))))
)
I was pretty certain that it would work, but given my current knowledge and experience in Racket, I couldn't find the error.
I typed in:
> (new-board 3)
and got the error:
build-list: expects a procedure (arity 1); given (make-posn 3 0)
Am I committing a heinous crime by invoking build list inside of a build-list?
Please let me know. Thanks!
About this procedure:
(define (new-board y)
(build-list y (lambda (x) (build-list x
(make-posn y x))))) ;error!
Let's see what build-list receives as parameters. The first parameter is y, a number and the second parameter is a procedure, but you're passing the result of evaluating make-posn, which is not a procedure, it's a value. And that's the reason for the error you're getting.
EDIT 1 :
Now I understand what you intended. I can think of a solution, but it's a bit more elaborated than what you had in mind:
(define (new-board n)
(flatten
(map (lambda (x)
(map (lambda (y)
(make-posn x y))
(build-list n identity)))
(build-list n identity))))
(define (flatten lst)
(if (not (list? lst))
(list lst)
(apply append (map flatten lst))))
Here's how it works:
build-list is just being used for generating numbers from 0 to n-1, and I'm passing identity as the procedure, because no further processing is required for each number
For each number in the list, we also want to generate another list, again from 0 to n-1 because all the coordinates in the board are required. For example if n is 3 the coordinates are '((0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2))
I'm using a map inside a map for building the nested lists, a technique borrowed from here (see: "nested mappings")
Finally, I had to flatten the generated lists, and that's what flatten does (otherwise, we'd have ended with a list of lists of lists)
EDIT 2 :
Come to think of it, I found an even simpler way, closer to what you had in mind. Notice that the flatten procedure is unavoidable:
(define (new-board n)
(flatten
(build-list n
(lambda (x)
(build-list n
(lambda (y)
(make-posn x y)))))))
Now, when you type this:
(new-board 2)
The result is as expected:
(#(struct:posn 0 0) #(struct:posn 0 1) #(struct:posn 1 0) #(struct:posn 1 1))
If you look up the signature (contract) of build-list1, you see that it is
build-list : Nat (Nat -> X) -> (listof X)
So it takes a (natural) number, and then a function that expects a natural number and gives back an element of the type (X) that you want included in the list. So in your case, what specific type do you want X to be for each call you're making to build-list (it can be different in each case). In the case of the inner build-list, it looks like you're trying to make a list of posns. However, (make-posn y x) immediately makes a single posn and is not a function as build-list expects. So just as you provide a function (lambda (x) ...) to the outer build-list, you should also provide a function (lambda (...) ...) to the inner function.
Choosing the name x for the parameter of the first lambda might be a little confusing. What I might do is change the name of the new-board function's parameter to N, in that it seems like you want to create a board of N rows (and columns). And the purpose of the first build-list is to create each of those rows (or columns, depending how you want to think of it). So if you had:
(define (new-board N)
(build-list N (lambda (x) ...)))
And then you use it like:
(new-board 5)
it will reduce/simplify/evaluate as follows:
==> (build-list 5 (lambda (x) ...))
==> (list ( (lambda (x) (build-list ... x ...)) 0 )
( (lambda (x) (build-list ... x ...)) 1 )
( (lambda (x) (build-list ... x ...)) 2 )
( (lambda (x) (build-list ... x ...)) 3 )
( (lambda (x) (build-list ... x ...)) 4 )
==> (list (build-list ... 0 ...)
(build-list ... 1 ...)
(build-list ... 2 ...)
(build-list ... 3 ...)
(build-list ... 4 ...))
So, there's nothing wrong with nesting build-list. See if you can figure out now how to have the inner build-list work on producing a list of posns once the current row is fixed to a particular x value.
By the way, if you're allowed to use full Racket, there's a nice way to express the computation with for loops:
(define (new-board n)
(for*/list ([i n]
[j n])
(make-posn i j)))
Another way to get the same result but with a different approach is to use an arithmetic trick with quotient and remainder.
(define (new-board n)
(build-list (* n n)
(lambda (k)
(make-posn (quotient k n)
(remainder k n)))))

Resources