[E-Lang] Hydro & E operator expansions
Mark S. Miller
markm@caplet.com
Tue, 20 Mar 2001 15:34:20 -0800
The most concrete issue in integrating Hydro & E is syntax, which is mostly
a matter of deciding what the operators expand to, and what these expansions
mean.
The following are some proposed changes to the expansion from Tyler, which I
believe are the same as those he proposed in the earlier Hydro discussion on
the list. I don't believe I'd responded then. The following are my
initial responses. At the bottom of this message are thoughts since this
back-and-forth with Tyler.
Tyler wrote:
>Following are the operator renamings:
>
>Unary Operators E with Hydro E as it is
>--------------- ------------ -----------
>() evaluate() run()
"evaluate" is simply wrong. An expression evaluates in a scope to a value.
In the old eval/apply duality, this is closer to apply. A lambda expression
evaluates to a function, and a function is applied to arguments. But
"apply" would be a lousy name as a message to a function with the arguments
as arguments, since it is the function being applied to the arguments, not
the other way around. And I won't call it "applyYourselfTo".
What's wrong with "run"? It's what java.lang.Runnable uses.
>! isEmpty() not()
"isEmpty" sounds specific to collections. When "b" is a boolean, the expression
"!b" would expand to "b isEmpty()". It is perverse to think about testing
whether a boolean is empty of truth.
>~ inverted() complement()
I don't currently have a strong reaction, but what's wrong with "complement"?
>- reversed() negate()
Same objection as with isEmpty(). Having "-i" expand to "i reversed()" is
just too strange. In what sense can we think of negating an integer as
reversing it?
>Binary Operators
>----------------
>+ with() add()
It's strange for "3 + 5" to expand to "3 with(5)" in order to mean the sum
of 3 and 5, but I might be able to live with it if there were compelling
reasons to.
However, to have "[1, 2] + [3, 4]" evaluate to "[1, 2, [3, 4]]" destroys the
"+" operator. My generalized sense of "+" is that if it's two operands are
both of type T, then the result is of type T. If the operands are of
different types, then one or both are coerced to reduce it to the first
case. The computation performed by this first case should be associative
(modulo roundoff errors). Arithmetic addition and sequence concatenation
both satisfy this general sense of "+". Using this general sense of "+",
the equivalent of your
[1, 2] with(3) # which evaluates to [1, 2, 3]
could sensibly be written as
[1, 2] + [3] # which doesn't expand to "with", but has the same effect
but not
[1, 2] + 3
>- without() subtract()
Same objection as with "+".
>/ divide() approxDivide()
This may be a good idea. But what would you have divide() do on integers?
>[] search() get()
Why? What's wrong with "get"?
>Composite Operators
>-------------------
>&~ mask() currently uses &! for butNot()
I think "mask" is plausible either as a replacement for the name "butNot",
or, if we need both operations (I hope not), then "mask" is a fine expansion
of "&~", while "butNot" can remain the expansion of "&!".
As to whether "&~" should replace "&!", this is also plausible. I remember
thinking about this and choosing "&!" rather than "&~" for a reason, but I
don't currently recall it. If I continue to fail to recall it, I'll assume the
old reason no longer applies.
-----------------------------------
After this message, Dean pointed out Python's convention of naming the
operator expansions in a distinct fashion. So instead of expanding "a + b"
to "a add(b)" as we now do, or "a with(b)" as Tyler proposes above, we could
instead expand to "a op__plus(b)" or some such. The method name "op__plus"
is clearly not primarily making a statement about semantics, but instead
makes it clear that it's participating in the expansion of an operator.
This should help de-couple language design from library design, which is a
good thing. Of course, we still need common agreement on what "+" means
when applied to a primitive datatype that's considered part of the language,
so most of the original problem remains.
Does anyone object to this Python-like style of naming operator expansions?
Cheers,
--MarkM