I'm working on a homework assignment where we are asked to implement an evaluation strategy called "call by name" in a certain language that we developed (using Scheme).
We were given an example in Scala, but I don't understand how "call by name" works and how it is different to "call by need"?
Call-by-need is a memoized version of call-by-name (see wikipedia).
In call-by-name, the argument is evaluated every time it is used, whereas in call-by-need, it is evaluated the first time it is used, and the value recorded so that subsequently it need not be re-evaluated.
Call by name is a a parameter passing scheme where the parameter is evaluated when it is used, not when the function is called. Here's an example in pseudo-C:
int i;
char array[3] = { 0, 1, 2 };
i = 0;
f(a[i]);
int f(int j)
{
int k = j; // k = 0
i = 2; // modify global i
k = j; // The argument expression (a[i]) is re-evaluated, giving 2.
}
The argument expression is lazily evaluated when accessed using the current values of the argument expression.
Add this to the above answers:
Work through the SICP section on Streams. It gives a good explanation of both call-by-name and call-by-need. It also shows how to implement those in Scheme. BTW, if you are looking for a quick solution here is a basic call-by-need implemented in Scheme:
;; Returns a promise to execute a computation. (implements call-by-name)
;; Caches the result (memoization) of the computation on its first evaluation
;; and returns that value on subsequent calls. (implements call-by-need)
(define-syntax delay
(syntax-rules ()
((_ (expr ...))
(let ((proc (lambda () (expr ...)))
(already-evaluated #f)
(result null))
(lambda ()
(if (not already-evaluated)
(begin
(display "computing ...") (newline)
(set! result (proc))
(set! already-evaluated #t)))
result)))))
;; Forces the evaluation of a delayed computation created by 'delay'.
(define (my-force proc) (proc))
A sample run:
> (define lazy (delay (+ 3 4)))
> (force lazy)
computing ... ;; Computes 3 + 4 and memoizes the result.
7
> (my-force lazy)
7 ;; Returns the memoized value.
Related
What exactly is different between these implementations of 'when'?
(define-syntax when
(syntax-rules ()
((_ pred b1 ...)
(if pred (begin b1 ...)))))
vs.
(define (my-when pred b1 ...)
(if pred (begin b1 ...)))
For example, when 'my-when' is used in this for loop macro:
(define-syntax for
(syntax-rules ()
((_ (i from to) b1 ...)
(let loop((i from))
(my-when (< i to)
b1 ...
(loop (+ i 1)))))))
an error occurs:
(for (i 0 10) (display i))
; Aborting!: maximum recursion depth exceeded
I do not think 'when' can be implemented as a function, but I do not know why...
Scheme has strict semantics.
This means that all of a function's parameters are evaluated before the function is applied to them.
Macros take source code and produce source code - they don't evaluate any of their parameters.
(Or, well, I suppose they do, but their parameters are syntax - language elements - rather than what you normally think of as values, such as numbers or strings. Macro programming is meta-programming. It's important to be aware of which level you're programming at.)
In your example this means that when my-when is a function, (loop (+ i 1)) must be evaluated before my-when can be applied to it.
This leads to an infinite recursion.
When it's a macro, the my-when form is first replaced with the equivalent if-form
(if (< i to)
(begin
b1 ...
(loop (+ i 1))))
and then the whole thing is evaluated, which means that (loop (+ i 1)) only gets evaluated when the condition is true.
If you implement when as a procedure like you did, then all arguments are evaluated. In your for implementation, the evaluation would be processed like this:
evaluate (< i to)
evaluate expansion result of b1 ...
evaluate (loop (+ i 1)) <- here goes into infinite loop!
evaluate my-when
Item 1-3 can be reverse or undefined order depending on your implementation but the point is nr. 4. If my-when is implemented as a macro, then the macro is the first one to be evaluated.
If you really need to implement with a procedure, then you need to use sort of delaying trick such as thunk. For example:
(define (my-when pred body) (if (pred) (body)))
(my-when (lambda () (< i 10)) (lambda () (display i) (loop (+ i 1))))
So I'm slightly confused on an introduction to Racket.
I need to write a function called "extend" that takes an element and a predicate, and "extends" the predicate to include the element. For example:
((extend 1 even?) 1)
#t
((extend 3 even?) 3)
#f
I'm fairly new to the language but I don't understand how to get a function to be used or return as a predicate. Not sure if I'm overthinking it or what.
A function is just a value and extend is just a variable like + and cons that evaluate to a function value. functions can be passed as arguments and you just use whatever name you have given it as if it's a function, by using parentheses, and it just works.
A function returns the value the last expression evaluate to. To get it to be a function it either needs to be a variable that evaluate to a function or a lambda that also evaluate to a function.
(define (double-up fn)
(lambda (value)
(fn (fn value)))) ; see. Just use fn as if it is a procedure
((double-up add1) 4) ; ==> 6
(define add2 (double-up add1))
(add2 4) ; ==> 6
(define error-use (double-up 5)) ; works like a charm
(error-use 4)
; Signals "application: not a procedure"
; since `5` isn't a procedure.
Here is another example which is more similar to your assignment. It takes a number, then returns a function that takes another number and then adds them together. Here I choose to define it locally and then leave it as the last expession so that it becomes the result.
(define (make-add initial-value)
(define (adder new-value)
(+ initial-value new-value))
adder) ; this is the result
((make-add 5) 7) ; ==> 12
A predicate is what we call functions often called in predicate position in conditionals (like if and cond). Thus just a function that either return #t or #f and often bound to variables ending with question mark as a naming convention.
I am a novice in Lisp, learning slowly at spare time... Months ago, I was puzzled by the error report from a Lisp REPL that the following expression does not work:
((if (> 2 1) + -) 1 2)
By looking around then I knew that Lisp is not Scheme...in Lisp, I need to do either:
(funcall (if (> 2 1) '+ '-) 2 1), or
(funcall (if (> 2 1) #'+ #'-) 2 1)
I also took a glimpse of introductary material about lisp-1 and lisp-2, although I was not able to absort the whole stuff there...in any case, I knew that quote prevents evaluation, as an exception to the evaluation rule.
Recently I am reading something about reduce...and then as an exercise, I wanted to write my own version of reduce. Although I managed to get it work (at least it seems working), I realized that I still cannot exactly explain why, in the body of defun, that some places funcall is needed, and at some places not.
The following is myreduce in elisp:
(defun myreduce (fn v lst)
(cond ((null lst) v)
((atom lst) (funcall fn v lst))
(t (funcall fn (car lst) (myreduce fn v (cdr lst))))))
(myreduce '+ 0 '(1 2 3 4))
My questions are about the 3rd and 4th lines:
The 3rd line: why I need funcall? why not just (fn v lst)? My "argument" is that in (fn v lst), fn is the first element in the list, so lisp may be able to use this position information to treat it as a function...but it's not. So certainly I missed something here.
The 4th line in the recursive call of myreduce: what kind of fn be passed to the recursive call to myreduce? '+ or +, or something else?
I guess there should be something very fundamental I am not aware of...I wanted to know, when I call myreduce as shown in the 6th/last line, what is exactly happening afterwards (at least on how the '+ is passed around), and is there a way to trace that in any REPL environment?
Thanks a lot,
/bruin
Common Lisp is a LISP-2 and has two namespaces. One for functions and one for variables. Arguments are bound in the variable namespace so fn does not exist in the function namespace.
(fn arg) ; call what fn is in the function namespace
(funcall fn ...) ; call a function referenced as a variable
'+ is a symbol and funcall and apply will look it up in the global function namespace when it sees it's a symbol instead of a function object. #'+ is an abbreviation for (function +) which resolves the function from the local function namespace. With lots of calls #'+ is faster than '+ since '+ needs a lookup. Both symbol and a function can be passed as fn to myreduce and whatever was passed is the same that gets passed in line 4.
(myreduce '+ 0 '(1 2 3 4)) ; here funcall might lookup what '+ is every time (CLISP does it while SBLC caches it)
(myreduce #'+ 0 '(1 2 3 4)); here funcall will be given a function object looked up in the first call in all consecutive calls
Now if you pass '+ it will be evaluated to + and bound to fn.
In myreduce we pass fn in the recursion and it will be evaluated to + too.
For #'+ it evaluates to the function and bound to fn.
In myreduce we pass fn in the recursion and it will be evaluated to the function object fn was bound to in the variable namespace.
Common Lisp has construct to add to the function namespace. Eg.
(flet ((double (x) (+ x x))) ; make double in the function namespace
(double 10)) ; ==> 20
But you could have written it and used it on the variable namespace:
(let ((double #'(lambda (x) (+ x x)))) ; make double in the variable namespace
(funcall double 10))
Common Lisp has two (actually more than two) namespaces: one for variables and one for functions. This means that one name can mean different things depending on the context: it can be a variable and it can be a function name.
(let ((foo 42)) ; a variable FOO
(flet ((foo (n) (+ n 107))) ; a function FOO
(foo foo))) ; calling function FOO with the value of the variable FOO
Some examples how variables are defined:
(defun foo (n) ...) ; n is a variable
(let ((n 3)) ...) ; n is a variable
(defparameter *n* 41) ; *n* is a variable
So whenever a variable is defined and used, the name is in the variable namespace.
Functions are defined:
(defun foo (n) ...) ; FOO is a function
(flet ((foo (n) ...)) ...) ; FOO is a function
So whenever a function is defined and used, the name is in the function namespace.
Since the function itself is an object, you can have function being a variable value. If you want to call such a value, then you need to use FUNCALL or APPLY.
(let ((plus (function plus)))
(funcall plus 10 11))
Now why are things like they are? ;-)
two namespaces allow us to use names as variables which are already functions.
Example: in a Lisp-1 I can't write:
(defun list-me (list) (list list))
In Common Lisp there is no conflict for above code.
a separate function namespace makes compiled code a bit simpler:
In a call (foo 42) the name FOO can only be undefined or it is a function. Another alternative does not exist. So at runtime we never have to check the function value of FOO for actually being a function object. If FOO has a function value, then it must be a function object. The reason for that: it is not possible in Common Lisp to define a function with something other than a function.
In Scheme you can write:
(let ((list 42))
(list 1 2 3 list))
Above needs to be checked at some point and will result in an error, since LIST is 42, which is not a function.
In Common Lisp above code defines only a variable LIST, but the function LIST is still available.
I'm working on a homework assignment where we are asked to implement an evaluation strategy called "call by name" in a certain language that we developed (using Scheme).
We were given an example in Scala, but I don't understand how "call by name" works and how it is different to "call by need"?
Call-by-need is a memoized version of call-by-name (see wikipedia).
In call-by-name, the argument is evaluated every time it is used, whereas in call-by-need, it is evaluated the first time it is used, and the value recorded so that subsequently it need not be re-evaluated.
Call by name is a a parameter passing scheme where the parameter is evaluated when it is used, not when the function is called. Here's an example in pseudo-C:
int i;
char array[3] = { 0, 1, 2 };
i = 0;
f(a[i]);
int f(int j)
{
int k = j; // k = 0
i = 2; // modify global i
k = j; // The argument expression (a[i]) is re-evaluated, giving 2.
}
The argument expression is lazily evaluated when accessed using the current values of the argument expression.
Add this to the above answers:
Work through the SICP section on Streams. It gives a good explanation of both call-by-name and call-by-need. It also shows how to implement those in Scheme. BTW, if you are looking for a quick solution here is a basic call-by-need implemented in Scheme:
;; Returns a promise to execute a computation. (implements call-by-name)
;; Caches the result (memoization) of the computation on its first evaluation
;; and returns that value on subsequent calls. (implements call-by-need)
(define-syntax delay
(syntax-rules ()
((_ (expr ...))
(let ((proc (lambda () (expr ...)))
(already-evaluated #f)
(result null))
(lambda ()
(if (not already-evaluated)
(begin
(display "computing ...") (newline)
(set! result (proc))
(set! already-evaluated #t)))
result)))))
;; Forces the evaluation of a delayed computation created by 'delay'.
(define (my-force proc) (proc))
A sample run:
> (define lazy (delay (+ 3 4)))
> (force lazy)
computing ... ;; Computes 3 + 4 and memoizes the result.
7
> (my-force lazy)
7 ;; Returns the memoized value.
From the Question How do I pass a function as a parameter to in elisp? I know how to pass a function as a parameter to a function. But we need to go deeper...
Lame movie quotes aside, I want to have a function, which takes a function as a parameter and is able to call itself [again passing the function which it took as parameter]. Consider this snippet:
(defun dummy ()
(message "Dummy"))
(defun func1 (func)
(funcall func))
(defun func2 (func arg)
(message "arg = %s" arg)
(funcall func)
(func2 'func (- arg 1)))
Calling (func1 'dummy) yields the expected output:
Dummy
"Dummy"
Calling (func2 'dummy 4) results in an error message:
arg = 4
Dummy
arg = 3
funcall: Symbol's function definition is void: func
I had expected four calls to dummy, yet the second iteration of func2 seems to have lost its knowledge of the function passed to the first iteration (and passed on from there). Any help is much appreciated!
There probably is a better way to do this with lexical scoping. This is more or less a translation from Rosetta Code:
(defun closure (y)
`(lambda (&rest args) (apply (funcall ',y ',y) args)))
(defun Y (f)
((lambda (x) (funcall x x))
`(lambda (y) (funcall ',f (closure y)))))
(defun factorial (f)
`(lambda (n)
(if (zerop n) 1
(* n (funcall ,f (1- n))))))
(funcall (Y 'factorial) 5) ;; 120
Here's a link to Rosetta code: http://rosettacode.org/wiki/Y_combinator with a bunch of other languages immplementing the same thing. Y-combinator is a construct, from the family of fixed-point combinators. Roughly, the idea is to eliminate the need for implementing recursive functions (recursive functions require more sophistications when you think about how to make them compile / implement in the VM). Y-combinator solves this by allowing one to mechanically translate all functions into non-recursive form, while still allowing for recursion in general.
To be fair, the code above isn't very good, because it will create new functions on each recursive step. This is because until recently, Emacs Lisp didn't have lexical bindings (you couldn't have a function capture its lexical environment), in other words, when the Emacs Lisp function is used outside the scope it was declared, the values of the bound variables will be taken from the function's current scope. In the case above such bound variables are f in the Y function and y in the closure function. Luckily, those are just symbols designating an existing function, so it is possible to mimic that behaviour using macros.
Now, what Y-combinator does:
Captures the original function into variable f.
Returns a wrapper function of one argument, which will call f, when called in its turn, used by Y-combinator to
Return a wrapper function of unbounded number of arguments which will
call the original function passing it all the arguments it was called with.
This structure also dictates you the structure of the function to be used with Y-combinator: it has to take single argument, which must be a function (which is this same function again) and return a function (of any number of arguments) which calls the function inherited from outer scope.
Well, it is known to be a little mind-boggling :)
That's because you're trying to call the function func not the function dummy.
(Hence the error "Symbol's function definition is void: func".)
You want:
(func2 func (- arg 1)))
not:
(func2 'func (- arg 1)))
You do not need to quote func in the func2 call
You are missing a recursion termination condition in func2
Here is what works for me:
(defun func2 (func arg)
(message "arg = %s" arg)
(funcall func)
(when (plusp arg)
(func2 func (- arg 1))))