Programming Languages: Chapter 12: Parameter Passing


Variable Assignment


    • now:
      • denoted value = reference to expressed value
      • expressed value = integer ∪ closure
      • similar to Scheme
    • references are called L-values
    • expressed values are known as R-values, based on the side of the assignment statement in which they appear
    • new production rule and constructor on p. 98
    • difference between binding and variable assignment
      • binding associates a name with a value
      • assignment changes the value of an existing binding
      • binding is all about the association of names to values
      • ``assignment is all about the sharing of values between different procedures'' [EOPL2] p. 98

    Illustrative example programs

    • program on p. 99
      • notice novel use of let is to simulate sequential execution
      • notice that even and odd share variable x
      • the procedures communicate by changing the state of x
      • x is a so-called global variable
    • alternative is to inter-procedure communication through parameter passing
      • consider the idea of redirecting standard I/O
      • print ("hello") vs. print (port, "hello")
      • latter may pass the port through a long sequence of additional procedures to eventually print the string to the port
      • use of a a global variable avoids the need to pass data through intermediate procedures
      • achieve less overhead by compromising protection
    • ``another use of assignment is to create hidden state directly through the use of private variables,'' [EOPL2] p. 100 (e.g., see sample program on p. 100)
      • count is a private variable which keeps track of how many times g is called
      • this expression returns 3
    • in our language, ``we will choose to create a new reference for each formal parameter at every procedure call'' [EOPL2] p. 100
      • this parameter-passing mechanism is called pass-by-value (or pass-by-value) [EOPL2] p.100
      • ``when we assign to a formal parameter, the assignment is local to the procedure'' [EOPL2] p. 100
      • second example program on p. 100 illustrates the effect of passing parameters by value (i.e., here, as opposed to the previous example, x is not shared)

    Reference data type

    • deref and assignreference!
    • deref is the analog of the * (star) in C when preceding a variable reference
    • however, dereferencing is implicit in our language akin to Scheme or Java, but in contrast to C
    • ``we assume the familiar environment representation with a value vector in each rib'' [EOPL2] p. 100
    • ``references will be elements of rib vectors, which are assignable using vector-set!'' (a function built into Scheme) [EOPL2] p. 100
    • see abstract-syntax implementation on p. 101
    • ``we define deref and assignreference! in terms of primitive-deref and primitive-assignreference! because we will reuse the latter two procedures in our later implementations of references'' [EOPL2] p. 101

    • (regenerated, with minor modifications, from [EOPL2] Fig. 3.13 on p. 101)

    Environment revisited

    • to make use of references
    • ``we assume that the denoted values in an environment are of the form Ref(X) for some X'' [EOPL2] p. 102
    • ``the procedure apply-envioronment-reference is similar to apply-environment, except that when it finds the matching identifier, it returns the reference instead of its value'' [EOPL2] p. 102
    • then ``the procedure apply-env and be defined in terms of apply-environment-reference and deref'' [EOPL2] p. 102
    • see code in [EOPL2] Fig. 3.14 on p. 102
    • augmented evaluate-expr procedure to accommodate variable-assignment-expr variant of expr (see p. 102)
    • notice the use of (begin ...) syntactic form; built into Scheme to achieve sequential execution
    • notice that a value must be returned; typically that return value will be ignored (as in C), especially if assignment is used with a let expression to simulate sequential execution

Parameter-passing Mechanisms


      Pass-by-value in C

        C only supports pass-by-value.

        /* swap pass-by-value */
        void swap (int a, int b) {
           int temp = a;
           a = b;
           b = temp;
        main() {
           int x = 1;
           int y = 2;
           swap (x, y);
           printf ("    pass-by-value: ");
           printf ("x = %d, y = %d\n\n", x, y);

      Pass-by-value in Java

        Java only supports pass-by-value.


      Pass-by-value in Scheme

      • Scheme only supports pass-by-value.
      • sample program on [EOPL2] p. 108
      • references a and x are distinct
      • graphical depiction of pass-by-value (result is 3)


    • sample program on [EOPL2] p. 108
    • references a and x are distinct
    • graphical depiction of pass-by-reference (result is 4)

    Pass address by value

      In C we simulate pass-by-reference by passing the address of a variable by value
      /* swap pass address by value (simulated pass-by-reference) */
      void swap (int* a, int* b) {
         int temp = *a;
         *a = *b;
         *b = temp;
      main() {
         int x = 1;
         int y = 2;
         swap (&x, &y);
         printf ("pass address by value: ");
         printf ("x = %d, y = %d\n\n", x, y);

      (demical, rather than hexidecimal, numbers are used for memory addresses for purposes of simplicity)
  • why cannot a swap function be written in Java?
  • why might we want to use pass-by-reference? to simulate the return of more than one value
  • FORTRAN was the first language to use pass-by-reference

  • Java, Scheme, C, and C++


    • how does the caller reference the computed value if it is a literal or an expression?
    • parameter collision [COPL6]
         fun(x,y) {
           x = 1;
           y = 2;
    • when should address of actual parameters be evaluated? at time of the call or at time of the return?


    • combination of pass-by-value and pass-by-result, and shares the problems of both
    • sometimes referred to as pass-by-copy-restore

    Sample code snippet

      note: Pascal-style code is used only for illustration; use not intended to convey that Pascal uses these mechanisms.
      procedure p (integer x, integer y) begin
         x = x + 1;
         y = y + 1;
         a = 1;
         p (a, a);
         (* what is the value of a here? *)
         print a;
        (* if pass-by-value used, a=1
           if pass-by-value-result, a=2
           if pass-by-reference used, a=3

    Simple classification

    to think about each of the parameter-passing mechanisms
    • pass-by-value (IN)
    • pass-by-result (OUT)
    • pass-by-value-result (also called pass-by-copy)
      • IN at the front
      • OUT at the back
    • pass-by-reference (IN-OUT)
    • pass-by-name
      • lazy evaluation
      • akin to #define in C

    • pass-by-value-result (IN-OUT) != pass-by-reference (IN-OUT)

Implementing pass-by-reference in ChAmElEoN

    • currently are interpreter only supports pass-by-value. why? because every time we encounter an operand, we create a new reference
      • pass-by-value: create new reference for every evaluation of an operand
      • pass-by-reference: create new reference for only evaluation a non-variable operands
    • let us retain
        denoted value = reference to expressed value
        expressed value = integer ∪ closure
    • we only create a new reference for non-variable operands (e.g., literals)

    New implementation of references

    • now the vector element to which reference refers can contain either an expressed value or denoted value (i.e., a reference to an expressed value)
    • the former is called a direct target while the latter is called an indirect target
    • new reference implementation in [EOPL2] Fig. 3.17 on p. 111

    • (regenerated with modifications from [EOPL2] Fig. 3.18 on p. 113)

    Re-instrumentation of eval-rand

    • the procedures extend-env and apply-env-ref need not change
    • consider where subexpressions are evaluated:
      • primitive applications,
      • lets, and
      • user-defined procedure applications
    • we use pass-by-value for the first two and pass-by-reference for the last
      • code for primitive applications on p. 110 (essentially same as original)
      • code for lets on p. 112 (essentially same as original)
      • code for user-defined procedure applications on p. 112 (now eval-rand has changed):
        (define eval-rand
           (lambda (rand env)
              (cases expression rand
                 ;; if the operand is a variable, then it denotes a location
                 ;; containing an expressed value, so we want to return an
                 ;; _indirect target_ pointing to that location
                 (var-exp (id)
                       (let ((ref (apply-env-ref env id)))
                          (cases target (primitive-deref ref)
                             ;; if the variable is bound to a _location_ which
                             ;; contains a direct target, we return
                             ;; an indirect target to that location
                             (direct-target (expval) ref)
                             ;; but if the variable is bound to a _location_
                             ;; which contains an indirect target, then
                             ;; we return the same indirect target
                             (indirect-target (ref1) ref1)))))
                 ;; if the operand is a non-variable, then we create a new
                 ;; location, as before, by returning a _direct target_ to it
                 ;; (i.e., pass-by-value)
                 (else (direct-target (eval-expression rand env))))))
        3 cases:
        • operand is a non-variable (e.g., literal): return a direct target to it
        • operand is a var-exp which points to a direct target: return an indirect target to it
        • operand is a var-exp which points to a indirect target: return an copy of the same indirect target

    Illustrative example on p. 113

Lazy Evaluation and Thunks

Parameter passing: language examples

    • before 77: pass-by-reference
    • 77 and after: scalar variables are often passed by value-result
  • LISP, ML, and Smalltalk: pass-by-sharing (since these languages use a reference model of variables)
    • pass-by-value for immutable objects (numbers, characters)
    • pass-by-reference for addresses
  • ALGOL 60:
    • pass-by-name is default
    • pass-by-value is optional
  • ALGOL W: pass-by-value-result
  • Simula-67: pass-by-value-result
  • Pascal and Modula-2:
    • pass-by-value is default
    • pass-by-reference is optional
  • C: pass-by-value
  • Ada:
    • all three semantic modes are available (by-value, by-result, by-value-result)
    • if out, it cannot be referenced
    • if in, it cannot be assigned
  • C++:
    • like C, uses pass-by-value
    • but also allows reference type parameters, which provide the efficiency of pass-by-reference with in-mode semantics
  • Java: pass-by-value
  • Miranda (predecessor of Haskell): uses pass-by-name
  • Haskell: uses pass-by-need
  • R scripting language (statistical package used by scientists, including biologists): uses pass-by-name


    [COPL6] R.W. Sebesta. Concepts of Programming Languages. Addison-Wesley, Boston, MA, Sixth edition, 2003.
    [EOPL2] D.P. Friedman, M. Wand, and C.T. Haynes. Essentials of Programming Languages. MIT Press, Cambridge, MA, Second edition, 2001.
    [PIH] G. Hutton. Programming in Haskell. Cambridge University Press, Cambridge, 2007.
    [PLP] M.L. Scott. Programming Language Pragmatics. Morgan Kaufmann, Amsterdam, Second edition, 2006.
    [PLPP] K.C. Louden. Programming Languages: Principles and Practice. Brooks/Cole, Pacific Grove, CA, Second edition, 2002.

Return Home