is it possible to create an anonymous recursive function in racket - recursion

If I have a recursive function like this:
(define (double-n-times x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1))))
How can I make a lambda version of it and never give it a name? ... like if i want to inline it somewhere. Is that possible? (I mean in this case I could use fold - so maybe the example isn't that great) - Is there some kind of symbol or placeholder for "self" that I haven't been able to find? Or do you just have to give it a name.

The Y-Combinator in Racket is:
(lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda args (apply (g g) args))))))
This function can take any anonymous function and apply it on themselves recursively.
Let us define your function's part. double-n-times-part written only with lambdas:
(lambda (f)
(lambda (x n)
(if (= n 0) x (f (* 2 x) (- n 1))))))
where f we could name as we want - so we could also call it double-n-part.
If we apply the Y-Combinator on this, we get:
((lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda args (apply (g g) args))))))
(lambda (f)
(lambda (x n)
(if (= n 0) x (f (* 2 x) (- n 1))))))
This spits out a function which takes the arguments x and n and applies the inner function of the second definiton on them.
So now, without any named functions - only using lambda expressions - you can apply on your arguments - let's say x=3 and n=4:
(((lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda args (apply (g g) args))))))
(lambda (f)
(lambda (x n)
(if (= n 0) x (f (* 2 x) (- n 1))))))
3 4)
;;=> 48 ; as expected (3 * 2 * 2 * 2 * 2)
This is more convenient to read.
But we could also define the Y combinator without apply and args when we allow only monadic functions (functions with one arguments) instead of variadic ones. Then it looks like this (and we have to give the arguments one after another like this):
((((lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda (x) ((g g) x))))))
(lambda (f)
(lambda (x)
(lambda (n)
(if (= n 0) x ((f (* 2 x)) (- n 1)))))))
3) 4)
;;=> 48

The answer to your question is yes, by using macros. But before I talk about that, I have to ask this first: do you ask because you are just curious? Or do you ask because there are some issues, like you don't want to pollute the namespace with names?
If you don't want to pollute the namespace with names, you can simply use local constructs like named let, letrec, or even Y combinator. Alternatively, you can wrap define inside (let () ...).
(let ()
(define (double-n-times x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1))))
(double-n-times 10 10))
;; double-n-times is not in scope here
For the actual answer: here's a macro rlam that is similar to lambda, but it allows you to use self to refer to itself:
#lang racket
(require syntax/parse/define)
(define-syntax-parse-rule (rlam args body ...+)
#:with self (datum->syntax this-syntax 'self)
(letrec ([self (λ args body ...)])
self))
;; compute factorial of 10
((rlam (x)
(if (= 0 x)
1
(* x (self (sub1 x))))) 10) ;=> 3628800

Yes. Being a placeholder for a name is what lambda function's parameters are there for:
(define (double-n-times x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1))))
=
(define double-n-times (lambda (x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1)))))
=
(define double-n-times (lambda (self) ;; received here
(lambda (x n)
(if (= n 0)
x
(self (* 2 x) (- n 1)))))) ;; and used, here
but what is this "self" parameter? It is the lambda function itself :
= ;; this one's in error...
(define double-n-times ((lambda (u) ;; call self with self
(u u)) ;; to receive self as an argument
(lambda (self)
(lambda (x n)
(if (= n 0)
x
(self (* 2 x) (- n 1)))))))
;; ...can you see where and why?
= ;; this one isn't:
(define double-n-times ((lambda (u) (u u))
(lambda (self)
(lambda (x n)
(if (= n 0)
x
((self self) (* 2 x) (- n 1)))))))
;; need to call self with self to actually get that
;; (lambda (x n) ... ) thing to be applied to the values!
And now it works: (double-n-times 1.5 2) returns 6.0.
This is already fine and dandy, but we had to write ((self self) ... ...) there to express the binary recursive call. Can we do better? Can we write the lambda function with the regular (self ... ...) call syntax as before? Let's see. Is it
= ;; erroneous
(define double-n-times ((lambda (u) (u u))
(lambda (self)
(lambda (x n)
(lambda (rec body) (self self)
(if (= n 0)
x
(rec (* 2 x) (- n 1))))))))
(no) Or is it
= ;; also erroneous...
(define double-n-times ((lambda (u) (u u))
(lambda (self)
(lambda (x n)
((lambda (rec body) body)
(self self)
(if (= n 0)
x
(rec (* 2 x) (- n 1)))))))) ;; ...can you see why?
(still no) Or is it perhaps
= ;; still erroneous...
(define double-n-times ((lambda (u) (u u))
(lambda (self)
((lambda (rec)
(lambda (x n)
(if (= n 0)
x
(rec (* 2 x) (- n 1)))))
(self self) ))))
(no yet again ... in an interesting way) Or is it actually
=
(define double-n-times ((lambda (u) (u u))
(lambda (self)
((lambda (rec)
(lambda (x n)
(if (= n 0)
x
(rec (* 2 x) (- n 1)))))
(lambda (a b) ((self self) a b)) ))))
(yes!) such that it can be abstracted and separated into
(define (Y2 g) ((lambda (u) (u u))
(lambda (self)
(g
(lambda (a b) ((self self) a b))))))
(define double-n-times (Y2
(lambda (rec) ;; declare the rec call name
(lambda (x n)
(if (= n 0)
x
(rec (* 2 x) (- n 1))))))) ;; and use it to make the call
and there we have it, the Y combinator for binary functions under strict evaluation strategy of Scheme.
Thus we first close over our binary lambda function with our chosen recursive call name, then use the Y2 combinator to transform this "rec spec" nested lambdas into a plain callable binary lambda function (i.e. such that expects two arguments).
Or course the name rec itself is of no importance as long as it does not interfere with the other names in our code. In particular the above could also be written as
(define double-n-times ;; globally visible name
(Y2
(lambda (double-n-times) ;; separate binding,
(lambda (x n) ;; invisible from
(if (= n 0) ;; the outside
x
(double-n-times (* 2 x) (- n 1))))))) ;; original code, unchanged
defining exactly the same function as the result.
This way we didn't have to change our original code at all, just close it over with another lambda parameter with the same name as the name of our intended recursive call, double-n-times, thus making this binding anonymous, i.e. making that name unobservable from the outside; and then passing that through the Y2 combinator.
Of course Scheme already has recursive bindings, and we can achieve the same effect by using letrec:
(define double-n-times ;; globally visible name
(letrec ((double-n-times ;; internal recursive binding:
(lambda (x n) ;; its value, (lambda (x n) ...)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1))))))
double-n-times)) ;; internal binding's value
Again the internal and the global names are independent of each other.

Related

How to make recursion using only lambdas in Racket?

I need some help trying to figure out how to make the code below recursive using only lambdas.
(define (mklist2 bind pure args)
(define (helper bnd pr ttl lst)
(cond [(empty? lst) (pure ttl)]
[else (define (func t) (helper bnd pr (append ttl (list t)) (rest lst)))
(bind (first lst) func)])
)
(helper bind pure empty args))
Given a sample factorial program -
(define fact
(lambda (n)
(if (= n 0)
1
(* n (fact (- n 1)))))) ;; goal: remove reference to `fact`
(print (fact 7)) ; 5040
Above fact is (lambda (n) ...) and when we call fact we are asking for this lambda so we can reapply it with new arguments. lambda are nameless and if we cannot use top-level define bindings, the only way to bind a variable is using a lambda's parameter. Imagine something like -
(lambda (r)
; ...lambda body...
; call (r ...) to recur this lambda
)
We just need something to make our (lambda (r) ...) behave this way -
(something (lambda (r)
(print 1)
(r)))
; 1
; 1
; 1
; ... forever
introducing U
This something is quite close to the U combinator -
(define u
(lambda (f) (f f)))
(define fact
(lambda (r) ;; wrap in (lambda (r) ...)
(lambda (n)
(if (= n 0)
1
(* n ((r r) (- n 1))))))) ;; replace fact with (r r)
(print ((u fact) 7))
; => 5040
And now that recursion is happening thru use of a parameter, we could effectively remove all define bindings and write it using only lambda -
; ((u fact) 7)
(print (((lambda (f) (f f)) ; u
(lambda (r) ; fact
(lambda (n)
(if (= n 0)
1
(* n ((r r) (- n 1)))))))
7))
; => 5040
Why U when you can Y?
The U-combinator is simple but having to call ((r r) ...) inside the function is cumbersome. It'd be nice if you could call (r ...) to recur directly. This is exactly what the Y-combinator does -
(define y
(lambda (f)
(f (lambda (x) ((y f) x))))) ;; pass (y f) to user lambda
(define fact
(lambda (recur)
(lambda (n)
(if (= n 0)
1
(* n (recur (- n 1))))))) ;; recur directly
(print ((y fact) 7))
; => 5040
But see how y has a by-name recursive definition? We can use u to remove the by-name reference and recur using a lambda parameter instead. The same as we did above -
(define u
(lambda (f) (f f)))
(define y
(lambda (r) ;; wrap in (lambda (r) ...)
(lambda (f)
(f (lambda (x) (((r r) f) x)))))) ;; replace y with (r r)
(define fact
(lambda (recur)
(lambda (n)
(if (= n 0)
1
(* n (recur (- n 1)))))))
(print (((u y) fact) 7)) ;; replace y with (u y)
; => 5040
We can write it now using only lambda -
; (((u y) fact) 7)
(print ((((lambda (f) (f f)) ; u
(lambda (r) ; y
(lambda (f)
(f (lambda (x) (((r r) f) x))))))
(lambda (recur) ; fact
(lambda (n)
(if (= n 0)
1
(* n (recur (- n 1)))))))
7))
; => 5040
need more parameters?
By using currying, we can expand our functions to support more parameters, if needed -
(define range
(lambda (r)
(lambda (start)
(lambda (end)
(if (> start end)
null
(cons start ((r (add1 start)) end)))))))
(define map
(lambda (r)
(lambda (f)
(lambda (l)
(if (null? l)
null
(cons (f (car l))
((r f) (cdr l))))))))
(define nums
((((u y) range) 3) 9))
(define squares
((((u y) map) (lambda (x) (* x x))) nums))
(print squares)
; '(9 16 25 36 49 64 81)
And as a single lambda expression -
; ((((u y) map) (lambda (x) (* x x))) ((((u y) range) 3) 9))
(print (((((lambda (f) (f f)) ; u
(lambda (r) ; y
(lambda (f)
(f (lambda (x) (((r r) f) x))))))
(lambda (r) ; map
(lambda (f)
(lambda (l)
(if (null? l)
null
(cons (f (car l))
((r f) (cdr l))))))))
(lambda (x) (* x x))) ; square
(((((lambda (f) (f f)) ; u
(lambda (r) ; y
(lambda (f)
(f (lambda (x) (((r r) f) x))))))
(lambda (r) ; range
(lambda (start)
(lambda (end)
(if (> start end)
null
(cons start ((r (add1 start)) end)))))))
3) ; start
9))) ; end
; => '(9 16 25 36 49 64 81)
lazY
Check out these cool implementations of y using lazy
#lang lazy
(define y
(lambda (f)
(f (y f))))
#lang lazy
(define y
((lambda (f) (f f)) ; u
(lambda (r)
(lambda (f)
(f ((r r) f))))))
#lang lazy
(define y
((lambda (r)
(lambda (f)
(f ((r r) f))))
(lambda (r)
(lambda (f)
(f ((r r) f))))))
In response to #alinsoar's answer, I just wanted to show that Typed Racket's type system can express the Y combinator, if you put the proper type annotations using Rec types.
The U combinator requires a Rec type for its argument:
(: u (All (a) (-> (Rec F (-> F a)) a)))
(define u
(lambda (f) (f f)))
The Y combinator itself doesn't need a Rec in its type:
(: y (All (a b) (-> (-> (-> a b) (-> a b)) (-> a b))))
However, the definition of the Y combinator requires a Rec type annotation on one of the functions used within it:
(: y (All (a b) (-> (-> (-> a b) (-> a b)) (-> a b))))
(define y
(lambda (f)
(u (lambda ([g : (Rec G (-> G (-> a b)))])
(f (lambda (x) ((g g) x)))))))
Recursion using only lambdas can be done using fixed point combinators, the simplest one being Ω.
However, take into account that such a combinator has a type of infinite length, so if you program with types, the type is recursive and has infinite length. Not every type checker is able to compute the type for recursive types. The type checker of Racket I think it's Hindley-Miller and I remember typed racket it's not able to run fixed point combinators, but not sure. You have to disable the type checker for this to work.

How to implement optional arguments in CHICKEN?

I'm new to CHICKEN and Scheme. In my quest to understanding tail recursion, I wrote:
(define (recsum x) (recsum-tail x 0))
(define (recsum-tail x accum)
(if (= x 0)
accum
(recsum-tail (- x 1) (+ x accum))))
This does what I expect it to. However, this seems a little repetitive; having an optional argument should make this neater. So I tried:
(define (recsum x . y)
(let ((accum (car y)))
(if (= x 0)
accum
(recsum (- x 1) (+ x accum)))))
However, in CHICKEN (and maybe in other scheme implementations), car cannot be used against ():
Error: (car) bad argument type: ()
Is there another way to implement optional function arguments, specifically in CHICKEN 5?
I think you're looking for a named let, not for optional procedure arguments. It's a simple way to define a helper procedure with (possibly) extra parameters that you can initialize as required:
(define (recsum x)
(let recsum-tail ((x x) (accum 0))
(if (= x 0)
accum
(recsum-tail (- x 1) (+ x accum)))))
Of course, we can also implement it with varargs - but I don't think this looks as elegant:
(define (recsum x . y)
(let ((accum (if (null? y) 0 (car y))))
(if (= x 0)
accum
(recsum (- x 1) (+ x accum)))))
Either way, it works as expected:
(recsum 10)
=> 55
Chicken has optional arguments. You can do it like this:
(define (sum n #!optional (acc 0))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
However I will vote against using this as it is non standard Scheme. Chicken say they support SRFI-89: Optional positional and named parameters, but it seems it's an earlier version and the egg needs to be redone. Anyway when it is re-applied this should work:
;;chicken-install srfi-89 # install the egg
(use srfi-89) ; imports the egg
(define (sum n (acc 0))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
Also your idea of using rest arguments work. However keep in mind that the procedure then will build a pair on the heap for each iteration:
(define (sum n . acc-lst)
(define acc
(if (null? acc-lst)
0
(car acc-lst)))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
All of these leak internal information. Sometimes it's part of the public contract to have an optional parameter, but in this case it is to avoid writing a few more lines. Usually you don't want someone to pass a second argument and you should keep the internals private. The better way would be to use named let and keep the public contract as is.
(define (sum n)
(let loop ((n n) (acc 0))
(if (= n 0)
acc
(loop (- n 1) (+ acc n))))

Recursive call in Scheme language

I am reading sicp, there's a problem (practice 1.29), I write a scheme function to solve the the question, but it seems that the recursive call of the function get the wrong answer. Really strange to me. The code is following:
(define simpson
(lambda (f a b n)
(let ((h (/ (- b a) n))
(k 0))
(letrec
((sum (lambda (term start next end)
(if (> start end)
0
(+ (term start)
(sum term (next start) next end)))))
(next (lambda (x)
(let ()
(set! k (+ k 1))
(+ x h))))
(term (lambda (x)
(cond
((= k 0) (f a))
((= k n) (f b))
((even? k) (* 2
(f x)))
(else (* 4
(f x)))))))
(sum term a next b)))))
I didn't get the right answer.
For example, if I try to call the simpson function like this:
(simpson (lambda (x) x) 0 1 4)
I expected to get the 6, but it returned 10 to me, I am not sure where the error is.It seems to me that the function "sum" defined inside of Simpson function is not right.
If I rewrite the sum function inside of simpson using the iteration instead of recursive, I get the right answer.
You need to multiply the sum with h/3:
(* 1/3 h (sum term a next b))

scheme recursive function with multiple lambdas

How do I make a procedure from a function that makes procedures recursive?
for example, lets have a function that returns a procedure, the returned procedure will take two arguments (x and y). When called with z as an argument it will recursively call itself until z fulfills some requirements
(define test
(lambda (x y)
(lambda z
(if (> z 100)
z
(RecursiveCallToChangeValueOfZ (+ x y z))))))
Here are three variations:
#lang racket
;; use internal definition
(define test
(lambda (x y)
(define f
(lambda z
(if (> z 100)
z
(f (+ x y z)))))
f))
;; use letrec (which internal definition expands to
(define test2
(lambda (x y)
(letrec ([f (lambda z
(if (> z 100)
z
(f (+ x y z))))])
f)))
(require mzlib/etc)
;; use rec (a little syntactic sugar that expands to the previous solution)
(define test3
(lambda (x y)
(rec f (lambda z
(if (> z 100)
z
(f (+ x y z)))))))

passing function as a parameter to another function in scheme

Basicly,what I want to do is this:
I have a function square(x) (define (square x) (* x x))(f(x)=x*x),and another function mul_two (define (mul_two x) (* 2 x))(g(x)=2*x), I want to construct a new function based on the above two functions, what the new function does is this: 2*(x*x)(p(x)=g(f(x))), how can I write this new function in scheme? Although its a pretty straight thing in mathmatical form I'm totally stuck on this .
The usual way to do what you're asking is by using compose, which according to the linked documentation:
Returns a procedure that composes the given functions, applying the last proc first and the first proc last.
Notice that compose is quite powerful, it allows us to pass an arbitrary number of functions that consume and produce any number of values. But your example is simple to implement:
(define (square x) ; f(x)
(* x x))
(define (mul_two x) ; g(x)
(* 2 x))
(define p ; g(f(x))
(compose mul_two square))
(p 3) ; same as (mul_two (square 3))
=> 18
If for some reason your Scheme interpreter doesn't come with a built-in compose, it's easy to code one - and if I understood correctly the comments to the other answer, you want to use currying. Let's write one for the simple case where only a single value is produced/consumed by each function, and only two functions are composed:
(define my-compose ; curried and simplified version of `compose`
(lambda (g)
(lambda (f)
(lambda (x)
(g (f x))))))
(define p ; g(f(x))
((my-compose mul_two) square))
(p 3) ; same as (mul_two (square 3))
=> 18
(define (new_fun x) (mul_two (square x)))
EDIT:
(define (square x) (* x x))
(define (mul_two x) (* 2 x))
(define (new_fun fun1 fun2) (lambda (x) (fun2 (fun1 x))))
((new_fun square mul_two) 10)
And you will get 200. (10 * 10 * 2)
Also, you can implement a general purpose my-compose function just as the compose in racket:
(define (my-compose . funcs)
(let compose2
((func-list (cdr funcs))
(func (lambda args (apply (car funcs) args))))
(if (null? func-list)
func
(compose2
(cdr func-list)
(lambda args (func (apply (car func-list) args)))))))
And you can obtain new-fun by:
(define new-fun (my-compose mul_two square))
In #!racket (the language) you have compose such that:
(define double-square (compose double square))
Which is the same as doing this:
(define (double-square . args)
(double (apply square args)))
If you want to use Scheme (the standard) you can roll your own:
#!r6rs
(import (rnrs))
(define (compose . funs)
(let* ((funs-rev (reverse funs))
(first-fun (car funs-rev))
(chain (cdr funs-rev)))
(lambda args
(fold-left (lambda (arg fun)
(fun arg))
(apply first-fun args)
chain))))
(define add-square (compose (lambda (x) (* x x)) +))
(add-square 2 3 4) ; ==> 81

Resources