lambdafunctional-programmingschemeclosuresdep

Do Lambda Expressions and DEP work together?


I'm trying to understand how dynamically allocated code can run with dep.

Let's take the example if a compiled Scheme program. As I understand it, When it's time to evaluate a lambda expression, the run-time HAS to allocate memory in order to store the code (actually store a closure which has also code). Since it can't know in advance what is the size of the code, it has to be dynamic. So, it must use the heap for that.

How come, there is no run-time exception from the DEP mechanism when trying to execute this code from the heap?

And more generally, How does the whole "Code is data and data is code" idea is working when DEP is around?


Solution

  • Lambda expressions or, to be more general, "functions that are generated and returned by other functions", seemingly require dynamic code generation, but they do not: instead, such functions are usually represented by a data structure called function closures.

    A function closure is a pair of

    For instance, consider the following JavaScript-like code:

        function make_adder(x) {
          function adder(y) {
            return x + y;
          }
          return adder;
          // equivalent to "return function(y) { return x + y; };"
        }
    
        var add42 = make_adder(42);
        add42(3); // 45
    

    When make_adder is called with argument 42, its implementation returns a closure <adder, 42> which is the pair of (a pointer to) the function adder and the integer 42. When this closure is applied to 3, the function part is applied to the value 42 of its free variable x in addition to the visible argument 3.

    Conceptually, you can think that the code above is implemented like:

        function make_adder(x) {
          function adder(x, y) {
            return x + y;
          }
          return { func : adder, free : x };
        }
    
        var add42 = make_adder(42);
        add42.func(add42.free, 3); // 45
    

    In Scheme, the first code is

        (define (make_adder x)
          (lambda (y) (+ x y)))
        (define add42 (make_adder 42))
        (add42 3) ; 45
    

    and the second would be:

        (define (make_adder x)
          (define (adder x y)
            (+ x y))
          (cons adder x))
        (define add42 (make_adder 42))
        ((car add42) (cdr add42) 3) ; 45
    

    For further details, see: https://en.wikipedia.org/wiki/Closure_(computer_programming)