Side-effect free containers for E

Tyler Close tjclose@yahoo.com
Thu, 10 Aug 2000 11:00:28 -0400


Me (Tyler) elaborating my response to Markm:
> > However, we can have our familiarity
> > cake and eat it too
> > by having the syntax
> >
> >      container [key]= newValue
> >
> > expand to
> >
> >      container := container with(key, newValue)
>
> This is fine for associative containers but not so good for
> non-associative containers. Specifically, what does adding
> an element
> to a set, or a list, look like?
>
> This is going to temporarily mix your discussion guidelines, but if
> "+" was "with" then:
>
> 	container += key
>
> expands to
>
> 	container := container + key
>
> expands to
>
> 	container := container with(key)
>
> For associative containers:
>
> 	container += (key, value)
>
> expands to
>
> 	container := container + (key, value)
>
> expands to
>
> 	container := container with(key, value)
>
> I think this is a clean and accurate syntax.

Maybe I should just pull back all of the covers now in order to
further the discussion. We can then pick at individual pieces
according to Markm's outline.

Using an assignment syntax is not what you want, since it's not what
you're doing. You are doing container arithmetic. Container arithmetic
has some qualities that makes it sometimes look like assignment. For
example, if a map already contains a mapping for a given key, and you
add a new (key, value) pair that has the same key, are you assigning a
new value to the old key, or are you subtracting the old (key, value)
mapping and adding a new one? The latter is (part of) the more general
and correct answer.

For associative containers (i.e.: containers that attach meaning to a
key in a (key, value) pair), addition of a duplicate element has three
possible correct answers:

1) Add another mapping.
In this case, the addition succeeds and the resulting container would
have two elements with equal keys. This is a multi container (i.e.:
multimap or multiset).

2) Reject the new element.
In this case, the addition fails and an exception is thrown,
indicating that the element cannot be added to the container. This is
a map or set.

3) Replace the existing element with the new element.
In this case, the addition succeeds by removing an element. The
resulting container is the same size as the original container. The is
a replace map or replace set.

In Hydro, you specify the addition logic that you would like to use
for a specific container at construction time by calling one of:
asMultimap, asMap, asReplaceMap. All three methods return a Map that
has the same interface, but different behaviour for addition.

Container subtraction is much easier:

	container -= key

expands to

	container := container - key

expands to

	container := container without(key)

For pair associative containers:

	container -= (key, value)

expands to

	container := container - (key, value)

expands to

	container := container without(key, value)

Subtraction means "remove one element equal to the given (key, value)
pair". This definition applies smoothly to all of replace, multi and
normal associative containers.

Associative containers also respond to set operations:

Intersection:

	container_a & container_b

This returns a container with all elements from container_a whose key
is also mapped in container_b. (This is the same as the current EMap
behaviour.) For multi- containers, the result contains an element for
each of the elements in container_a that has "it's own" mapping in
container_b.

For example:

	[ "red" => 1, "blue" => 2, "blue" => 3, "blue" => 4, "green" => 5]
		& [ "green" => 6, "blue" => 7, "blue" => 8 ]

returns:

	[ "green" => 5, "blue" => 2, "blue" => 3 ]

(The order of the elements in the return value is something I'll get
to in another post).

Union:

	container_a | container_b

This returns a container with all elements from container_a and all
elements from container_b that are not in the intersection of the two
containers. (This is again the same as the EMap behaviour, but more
general.)

For example:

	[ "red" => 1, "blue" => 2, "blue" => 3, "green" => 4]
		| [ "green" => 5, "blue" => 6, "blue" => 7, "blue" => 8 ]

returns:

	[ "red" => 1, "blue" => 2, "blue" => 3, "blue" => 8, "green" => 4 ]

Symmetric difference:

	container_a ^ container_b

This returns all elements from container_a and container_b that are
not in the intersection. (EMap does not have this.)

For example:

	[ "red" => 1, "blue" => 2, "blue" => 3, "green" => 4]
		| [ "green" => 5, "blue" => 6, "blue" => 7, "blue" => 8 ]

returns:

	[ "red" => 1, "blue" => 8 ]

Difference:

	container_a &! container_b

EMap has this operator, Hydro currently does not. The logic for this
operator flows naturally from the "^" operator.

Some other operators:

Concatenation:

	container_a | container_b

This returns a container with the elements of container_a and
container_b. What exactly this means is dependent on container_a.

In another post, Markm was thinking that "|" cannot be used for
concatenation of containers because it is being used for intersection
of containers. The key thing to realize here is that for association
containers, the intersection is the concatenation. Non-associative
containers are then free to use the same operator for concatenation
and still be "in sync" with the logic for associative containers.

Reversing:

	-container

This returns a container that has the same elements in reverse order.

For example:

	-[ "red" => 1, "blue" => 2, "blue" => 3, "green" => 4 ]

returns:

	[ "green" => 4, "blue" => 3, "blue" => 2, "red" => 1 ]

Other methods that we might want operators for:

(Check the Hydro 2.0 docs for method descriptions.
http://www.waterken.com/Hydro/2.0/)

Method		Possible operator
------		-----------------
withMany		+*
withoutMany		-*
withoutFront	-- (prefix)
split			[key]
isEmpty		!
peek			.
includes		>=
within		<=

I think this cast of methods and associated operators should make
answering question #1 from Markm's post a slam dunk for yes.

Tyler


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com