Reputation: 207
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.
Upvotes: 0
Views: 317
Reputation: 135415
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.
Upvotes: 1