Lists/Maps/Sets (Was Re: The story of E, part 2 (fwd))

Mark S. Miller markm@erights.org
Sun, 11 Oct 1998 20:39:41 -0700


At 09:48 AM 10/9/98 -0700, Dan Bornstein wrote:
>ScriptX lists had the syntax:
>
>  [v1, v2, v3]
>
>ScriptX mappings had the syntax:
>
>  [k1 -> v1, k2 -> v2, k3 -> v3]
>
>ScriptX had no raw syntax for sets, however ...
>  [v1, v2, v3] as HashedSet
>  [v1, v2, v3] as SortedArray


I like this direction a lot.  One weird thing that I'm doing though is that
I don't have a separate "set" data type.  Rather, most purposes should be
served by the following 2x2 matrix of collection types:

	              Table			List
	       ----+----------------------------
	Immutable  |  Mapping		Tuple
	           |
	Mutable    |  TableEditor		Vector


(Btw, I'm *not* attached to these names.)

The suggested convention for representing a set is as a Mapping from the
elements of the set as keys to null as the value.  All the set operations,
when applied to general mappings, do the "set thing" on the domains of the
mappings, and do something sensible (and often useful) to the range, for
example,
http://erights.org/doc/javadoc/org.erights.e.elib.tables.Mapping.html#and

So adopting this suggestion,

	[v1, v2, v3] asSet

would be shorthand for

	[v1 => null, v2 => null, v3 => null]

while

	[v1, v2, v3] asMapping

would be shorthand for

	[0 => v1, 1 => v2, 2 => v3]

I can certainly define the syntax such that, between square brackets, there
is either a list of expressions or a list of "expr => expr" pairs, ie, to
forbid mixing these.  This leaves the ugly issue of "[]".  Is this the
empty tuple or the empty mapping?  I say the empty tuple, and if you want
the empty mapping, you'd say

	[] asSet

or the equivalent

	[] asMapping

depending on what reading you're trying to suggest.


Here's a proposal for the flip side, patterns.  In patterns I can currently
use a syntax suggestively borrowed from tuple expressions.  A silly example:

	define car([x] + _) {x}
	define cdr([_] + y) {y}

Such tuple patterns extract and bind elements of a Tuple positionally,
while also making the rest of the Tuple available.  Similarly, here's a
pattern syntax as syntactic sugar (not kernel!) for extracting elements
from a Mapping associatively, while also making the rest of the Mapping
available.  First, the conventional expression side:

	define props := ["foo" => 3, "bar" => 4] | oldProps

Then, on the pattern side,

	define [=="foo" => fooVal, =="bar" => barVal] | rest := props

would bind fooVal to 3, barVal to 4, and rest to the non-occluded part of
oldProps, ie, to 

	oldProps - ["foo", "bar"] asSet

I think I'll reserve this in the bnf and define its meaning, but not
implement it for a long time.

(Btw, the pattern "==<expr>" is syntactic sugar for the pattern 
"<temp> ? <temp> == <expr>".)


	Thanks for the cool direction,
	--MarkM