forellana
forellana

Reputation: 957

What is "Call By Name"?

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"?

Upvotes: 21

Views: 34892

Answers (5)

John Glen
John Glen

Reputation: 932

An important aspect of call-by-name is that, yes, the parameter is evaluated every single time it is come across during the callee's execution, but it is evaluated IN THE CALLER'S SCOPE, not the scope where the parameter is evaluated.

This is important to understand because variables in the caller's scope can change during the callee's execution meaning that the parameter's evaluation can lead to different values during the execution of the calle's execution.

Upvotes: 0

Evgeny Umansky
Evgeny Umansky

Reputation: 121

Call-by-name strategy does not evaluate arguments of the function until using them.

Example of call-by-name steps in Scala:

def square(a: Int) = a * a

// (b: => Int, c: => Int means that Scala will evaluate b and c with call-by-name startegy
def sumSquare(b: => Int, c: => Int ): Int = square(b) + square(c)

sumSquare(2, 3+3)
square(2) + square(3+3)
2 * 2 + square(3+3)
4 + square(3+3)
4 + (3+3) * (3+3) // duplicate evaluation
4 + 9 * (3+3)
4 + 9 * 9
85

Call-by-name can produce duplicates of evaluations. Also, the side effects of this strategy are less predictable. That's why the default Scala strategy is call-by-value.

You can read about the call-by-name strategy and the difference between call-by-value strategy here:
https://www.scaler.com/topics/call-by-name/

Call-by-need strategy, also known as a lazy evaluation strategy, evaluates an expression the first time it called, and uses a dictionary to keep the result of the evaluation for a specific expression.

More about lazy evaluation (call-by-need) here:
https://medium.com/background-thread/what-is-lazy-evaluation-programming-word-of-the-day-8a6f4410053f

Upvotes: 0

Vijay Mathew
Vijay Mathew

Reputation: 27164

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.

Upvotes: 3

Richard Pennington
Richard Pennington

Reputation: 19965

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.

Upvotes: 19

Doug Currie
Doug Currie

Reputation: 41170

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.

Upvotes: 31

Related Questions