Re: Metalanguages in environments where code is data.

Larry Wall (lwall@netlabs.com)
Wed, 16 Nov 1994 03:24:39 GMT

In article <id.57ME1.GJ5@nmti.com> peter@nmti.com (Peter da Silva) writes:
: In article <1994Nov9.194316.14800@netlabs.com>,
: Larry Wall <lwall@netlabs.com> wrote:
: > You can do it almost exactly the same in Perl, except there's no
: > need to "eval" the final argument to "rule".
:
: > use Make;
:
: > $CFLAGS = "-O -g";
: > $OBJS = "main.o frob.o";
: > $LIBS = "-lreadline";
:
: > rule "frob", $OBJS, sub {
: > system "$CC $CFLAGS $OBJS -o frob $LIBS";
: > };
:
: > make;
:
: OK, point to perl. How would you manipulate something like:
:
: event_wait {
: {control $door close} {
: signal $alarm "Door $door closed"
: }
: {control $door open} {
: signal $alarm "Door $door opened"
: }
: }

Well, a wooden translation using eval semantics might be

event_wait [
'control $door "close"' => 'signal $alarm "Door $door closed',
'control $door "open"' => 'signal $alarm "Door $door opened',
];

Using anonymous subs for early compilation, you might get

event_wait [
sub {control $door "close"} =>
sub { signal $alarm "Door $door closed" },
sub {control $door "open"} =>
sub { signal $alarm "Door $door opened" },
];

I'm not sure whether you want to use doors and alarms as objects
there. I've written control() and signal() as if they're methods
calls. You'd need an extra comma after $door and $alarm if they
are mere subroutine calls.

: Easy enough, but now you want to add user-defined events to the end of
: this structure:
:
: set default_event_list {
: {control $door "close"} {
: signal $alarm "Door $door closed"
: }
: {control $door "open"} {
: signal $alarm "Door $door opened"
: }
: }
: set event_list $default_event_list

$default_event_list = [
sub {control $door "close"} =>
sub { signal $alarm "Door $door closed" },
sub {control $door "open"} =>
sub { signal $alarm "Door $door opened" },
];
$event_list = $default_event_list;

: Then later
:
: lappend event_list {
: {control $door "open"} {
: set last_event [list $door opened]
: }
: }
:
: event_wait $event_list

push( @$event_list,
sub {control $door "open"} =>
sub { $last_event = [$door, 'opened'] }
);
event_wait $event_list;

Or someph'n like that. There are more degress of freedom in Perl,
which means you have to (but also get to) specify explicitly where you
want interpolation, and where you don't, where you want opaque variable
processing, and where you want references to be created or dereferenced.
There's little contextual magic at this level of Perl. What you see
is what it does.

This both a strength and a weakness. It greatly aids in the
understandability of any random bit of code, but it hinders when you
want to define a little language within the larger language. Macro
processors like Tcl and Scheme have an edge over Perl and Python here.
Yes, you can use the C preprocessor on Perl, but that's not whatcha call
well-integrated. Someday...

Larry