Re: [stack] Digest Number 85

Soren Renner — 2000-09-05 14:11:21

> I had considered a certain extension of Joy, something like
> a macro preprocessor. Louis said it would not be necessary because
> "Joy is its own macro language". While it is true that Joy can
> manipulate its own programs, that isn't quite the same as being
> its own macro language. In a later message I suggested looking at
> M4 as a suitable testbed. (Whether M4 is the best is debateable,
> but if it was good enough for Ratfor, then it is good enough for
> some experiments here).
> For ease of reading, I'll define macro names with a capital
> letter. Then the joy definition of square and the M4 definition
> of Square look like this:
> square == dup *
> define(Square, dup *)
> Both can be used in the same way:
> 3 square == 9
> 3 Square == 9
> But Square is an in-line version of square. For example
> [square] size == 1
> [Square] size == [dup *] size == 2
> Some people want inline definitions for efficiency, since it saves
> a call. I am not all that keen on it.

The second kind of definition can easily be implemented in the interpreter. If the interpreter keeps a dictionary and looks up each name encountered to find the corresponding op -- instead of just using a case statement or if-elsif series to match names to ops -- then "macro definition" can be done in the language itself with one primitive:

[dup mul] "square" define


define takes a quotation and a string and adds an entry to the interpreter dictionary (key, value) is (string, contents of quotation). After the above code is executed,

[2 3 4] [square] map

will be parsed as

[2 3 4] [dup mul] map

Now for the confession: this is the only kind of definition my machine has. I hadn't realized before this morning that there were two kinds. The machine is written in Oberon.

sr

phimvt@lurac.latrobe.edu.au — 2000-09-07 02:11:59

On Date: Tue, 05 Sep 2000 18:11:21 +0400
Soren Renner <srenner@...> wrote
>
>> For ease of reading, I'll define macro names with a capital
>> letter. Then the joy definition of square and the M4 definition
>> of Square look like this:
>> square == dup *
>> define(Square, dup *)
>> Both can be used in the same way:
>> 3 square == 9
>> 3 Square == 9
>> But Square is an in-line version of square. For example
>> [square] size == 1
>> [Square] size == [dup *] size == 2
>> Some people want inline definitions for efficiency, since it saves
>> a call. I am not all that keen on it.
>
>The second kind of definition can easily be implemented in the interpreter. If the interpreter keeps a dictionary and looks up each name encountered to find the corresponding op -- instead of just using a case statement or if-elsif series to match names to ops -- then "macro definition" can be done in the language itself with one primitive:
>
>[dup mul] "square" define
>
>
>define takes a quotation and a string and adds an entry to the interpreter dictionary (key, value) is (string, contents of quotation). After the above code is executed,
>
>[2 3 4] [square] map
>
>will be parsed as
>
>[2 3 4] [dup mul] map
>
>Now for the confession: this is the only kind of definition my machine has. I hadn't realized before this morning that there were two kinds. The machine is written in Oberon.
>
>sr

1. There are two possible styles:
[dup mul] "square" define
"square" [dup mul] define
I have a suspicion (just a suspicion) that the second style would be
more useful. Of course one could always do a swap first to get the
other style.

2. If your definitions always do the textual replacement as you
indicated, then you will not be able to have simple recursive
definitions, and even less mutually recursive definitions. For
recursion you do need the notion of a function calling itself,
so the functions need to be _called_ at run time. In that case
[square] size == 1
of course.

3. In my prototype I use a particular method of garbage collection
and a small device which saves some collection time. It would take
long to explain what the device is, but I regret it already. The
upshot is that the two dynamic styles of definitions would not
fit easily into my prototype implementation. This is just a warning
in case anybody tries to add dynamic definitions to my prototype
implementation.

Best wishes for your own Oberon implementation, and stay in touch,
Manfred