Subject: Re: "untyped" (was: What's gone wrong with Scheme Macros? Why all the debate?)
From: (Rob Warnock)
Date: Sun, 08 Sep 2002 06:55:31 -0000
Newsgroups: comp.lang.scheme
Message-ID: <>
Brian Harvey <> wrote:
| (Rob Warnock) writes:
| >But in BLISS-10 at least, these "byte pointers" were first-class values.
| Neato!  I never programmed in BLISS; did it have first-class aobjn
| pointers too?

Nope, sorry.  Hmmm... Although... Now that you ask...  ;-}  ;-}

Since BLISS "structures" were really a kind of user-defined macro,
and a structure reference could expand into completely arbitrary code
(as long as it returned an L-value), I suppose you *could* do a form
of auto-{in,de}crementing, at that! Though instead of writing "x = *p++;"
it'd probably look like "x = .p[post_incr]".

BLISS structures were kind of like Common Lisp's "defsetf" or
"define-setf-expander" features, except that (1) since a structure
reference returned a byte-pointer, the same form could be used for
both accessing (with a dot in front) and setting, and (2) the code
was *always* inlined, meaning that the compiler would optimize away
any constant tests in the structure code. So you could write something
like this, I think (please pardon the rust on my BLISS skills):

	! Define some helper constants to pretty up the accesses.
	bind pre_incr = 0,
	     post_incr = 1,
	     pre_decr = 2,
	     post_decr = 3;

	! In a BLISS structure definition, the dot ("contents of")
	! operator is overloaded a bit (one might even say perverted!).
	! Undotted uses of a structure's formal arguments represent the
	! instantiation-time actuals, while dotted uses are bound to the
	! access-time actuals. The structure name itself is a "zeroth"
	! formal which provides access to the variable that's mapped
	! using the structure.

	structure auto_incdec[kind] =
	    (case .kind in
		(.auto_incdec = ..auto_incdec + 1; .auto_incdec);
		(.auto_incdec = ..auto_incdec + 1; .auto_incdec - 1);
		(.auto_incdec = ..auto_incdec - 1; .auto_incdec);
		(.auto_incdec = ..auto_incdec - 1; .auto_incdec + 1);

Now to define a subroutine that uses that to add up an integer vector:

	routine sumvec(vec,size) =
	    local ptr = .vec,
	          limit = .vec + .size;
	          sum = 0;
	    map auto_incdec ptr;

	    while .ptr lt .limit do
	        sum = .sum + .ptr[post_incr];

The form "ptr[post_incr]" triggers an expansion of the "auto_incdec"
structure, with ".auto_incdec" replaced by "ptr" and ".size" replaced
by the value of "post_incr". It's expanded at compile time and the
unused braches of the constant "case" expression optimized away [BLISS
was *very* good at that], so that the summation line ends up being simply:

	        sum = .sum + .(ptr = .ptr + 1; ptr - 1);

| But I don't see how even assembler can truly be called untyped;
| it's just strange answers.  Assembler is full of things like
| 	ASCIZ	"Hi, there."
| 	SIXBIT	/..NEW./
| so it certainly knows about types.

Actually, no, it doesn't!! Those aren't "types", they're just syntactic
sugar for lexical processing. All three of these:

	ASCII	"Hello"
	XWD	443135,466336

produce (if I did my arithmetic correctly!) *exactly* the same result
(39081897182 in decimal), and any of them should be accepted anywhere
the others are.


Rob Warnock, PP-ASEL-IA		<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607