In Common Lisp I can define a two-level macro and expand the macro like this:
(defmacro calc (a op b)
(list op a b))
(defmacro twice (x)
(list 'calc x '+ x))
(twice 10)
(macroexpand-1 '(twice 10))
(macroexpand '(twice 10))
Output:
20
(CALC 10 + 10)
(+ 10 10)
Now I am trying to do the same thing in MIT Scheme:
(define-syntax calc
(syntax-rules ()
((_ a op b)
(op a b))))
(define-syntax twice
(syntax-rules ()
((_ x)
(calc x + x))))
(twice 10)
How can I do the equivalent of macroexpand-1 and macroexpand in MIT Scheme?
In Racket, macroexpand would be
(syntax->datum
(expand-to-top-form '(twice 10)))
;; '(+ 10 10)
and macroexpand-1 would be
(syntax->datum (expand-once '(twice 10)))
;; '(calc 10 + 10)
There are papers for macro-debugging in scheme by M. Felleisen.
See here.
Related
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.
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.
I have a scheme function like so that generates a hash value for a given input
(define hash
(lambda (c)
(cond
((null? c) 600)
(else
(reduce + (map (lambda (x) (cv x)) c) (* 12 (hash (cdr c))))))))
cv(x) is where each letter maps to a number a = 1, b = 2, c = 3 ... z = 26.
600 is the base value.
12 is a unique number.
My problem is I'm doing something wrong that my values are a bit off and can't find where the problem relies.
Expected Output
(hash '(h i))
==> 86516
My Output
(hash '(h i))
==> 86525
This is what I'm trying to do :
600 * 12 + 9(val for i) = 7209
then,
7209 * 12 + 8(val for h) = 86516
As you can see my values are a bit off, I suspect how I'm using the reduce function.
You have a recursion inside reduce, while reduce is a high level function. No.
A simple recursion will suffice:
(define hash
(lambda (c)
(if (null? c)
600
(+ (cv (car c)) (* 12 (hash (cdr c)))))))
(hash '(h i)) ; => 86516
If, on the other hand, you want to use a high level function, you could use either foldr, as in:
(define hash
(lambda (c)
(foldr (lambda (x y) (+ (cv x) (* 12 y))) 600 c)))
or foldl, as in:
(define hash
(lambda (c)
(foldl (lambda (x y) (+ (cv x) (* 12 y))) 600 (reverse c))))
I'm looking to create a function that returns a list of 'n' functions each of which increments the input by 1, 2, 3... n respectively.
I use DrRacket to try this out. A sample of expected outcome :
> (map (lambda (f) (f 20)) (func-list 5))
(21 22 23 24 25)
I'm able to write this down in a static-way :
> (define (func-list num)
> (list (lambda (x) (+ x 1)) (lambda (x) (+ x 2)) (lambda (x) (+ x 3)) (lambda (x) (+ x 4)) (lambda (x) (+ x 5)))
[Edit]
Also that a few restrictions are placed on implementation :
Only 'cons' and arithmetic operations can be used
The func-list should take as input only one parameter ('n' being the number of functions to be returned in this case)
It would be great if somebody can help me out. Thanks in advance.
Instead of explicitly writing out the list, a better approach would be to recursively construct it for an arbitrary n, as follows:
(define (func-list n)
(define (func-lst a n)
(if (> a n)
empty
(cons (lambda (x) (+ x a))
(func-lst (add1 a) n))))
(func-lst 1 n))
For example:
> (map (lambda (f) (f 20)) (func-list 0))
'()
> (map (lambda (f) (f 20)) (func-list 5))
'(21 22 23 24 25)
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