Newsgroups: comp.lang.dylan
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!newsfeed.pitt.edu!gatech!usenet.eel.ufl.edu!arclight.uoregon.edu!nntp.primenet.com!netcom.com!netcom9.netcom.com!haahr
From: haahr@netcom.com (Paul Haahr)
Subject: Re: Simulating call-by-reference with Dylan macros
In-Reply-To: phinely@Hawaii.Edu's message of 18 Sep 1996 18:45:53 GMT
To: phinely@Hawaii.Edu (Peter Hinely)
Message-ID: <HAAHR.96Sep23162029@netcom9.netcom.com>
Sender: haahr@netcom9.netcom.com
Organization: #f
References: <51pg11$2lu@news.Hawaii.Edu>
Date: Mon, 23 Sep 1996 23:20:29 GMT
Lines: 55

Peter Hinely <phinely@Hawaii.Edu> wrote:
> It seems to me that there are certain instances when "call-by-reference" 
> is a handy feature that can make a program shorter and more elegant.  My
> question is this:  "Is there a way to simulate "call-by-reference" in
> Dylan?  (using macros perhaps)  When one wanted to "call-by-reference",
> you would use a different syntax:
> 
>   Syntax for normal Dylan parameter passing:
> 	  increment(a);
>   Possible syntax for "call-by-reference" parameter passing:
> 	  increment(&a);

If you want call by reference in Dylan, you're out of luck.  (Though, as
this list may remember, some people think Dylan's call-by-value is
call-by-reference.  But enough on terminology...)

Macros can give you what you want, I think, except you get exactly the
same syntax for both types of parameter passing and there's a problem
with side-effects.

A simple macro for this purpose might be

  define macro increment
    { increment(?:expression, #key ?by:expression = 1) }
    => { ?expression := ?expression + ?by }
  end macro increment;

So, given this definition

  define method plus3(n)
    increment(n);
    increment(n, by: 2);
    n
  end method plus3;

plus3(1) should be 4, assuming I've remembered Dylan properly.

The problem is with side effects in the first parameter to increment.
A call to

  increment(a[i := i + 1])

would expand to

  a[i := i + 1] := a[i := i + 1] + 1

where what one wants is something closer to

  let index = (i := i + 1);
  a[index] := a[index] + 1;

Common LISP handles this problem (from memory) define-modifier-macro,
but Dylan really doesn't have an easy solution, as far as I know.

Paul
