Surprise list

From Erights

(Difference between revisions)
Jump to: navigation, search
(Rationale)
(Accumulator operator is lowest-precedence)
Line 48: Line 48:
To avoid being vulnerable to this type of misbehavior, do not use a sameness test (<code>==</code>) or Map key lookup in order to decide on the reliability of the response to a ''previously'' sent message. This might involve using a when-catch/whenResolved construct to wait until the reference is resolved.
To avoid being vulnerable to this type of misbehavior, do not use a sameness test (<code>==</code>) or Map key lookup in order to decide on the reliability of the response to a ''previously'' sent message. This might involve using a when-catch/whenResolved construct to wait until the reference is resolved.
-
==Accumulator operator is lowest-precedence==
+
You've hit the ball out the park! Icnredbile!
-
 
+
-
As you can see in the following expansion, the operator following the “_” is always lowest-precedence (as it is the one effectively rewritten into an assignment form):
+
-
 
+
-
    ? e`pragma.enable("accumulator"); accum 0 while (a) { _ * b + c }`
+
-
    # value: e`null
+
-
    ...
+
-
    #                            accum__1 := accum__1.multiply(b.add(c))
+
-
    ...
+
-
 
+
-
NVXbEU Touchdown! That's a really cool way of ptuitng it!
+
-
 
+
-
===Alternative===
+
-
 
+
-
Avoid accumulator syntax when the accumulation cannot be expressed as a single call.
+
-
 
+
-
 
+
== Shadowing function arguments ==
== Shadowing function arguments ==

Revision as of 13:36, 20 April 2011

Potentially surprising parts of the E language.

Current as of E 0.8.33o.

Very true! Makes a chagne to see someone spell it out like that. :)

Contents

def x doesn't return x

The forward declaration expression, def var, does not return var but rather the Resolver for it.

Examples

 # E sample
 
 ? def x
 # value: <Resolver>
 
 ? x
 # value: <Promise>

Rationale

If you want to pass a resolver as an argument, using it as an “out parameter”, this syntax is helpful:

 x.hereIsAResolver(def y)
 ... use y

Alternative

If you want the actual promise, simply write (def x; x).

Unresolved references do not necessarily behave as their future resolved identity

— messages sent before the reference is resolved may be reacted to however the current holder of the reference “arrow-head” chooses, which does not necessarily correspond to the reference to which the unresolved reference resolves.

This has been discussed in an e-lang thread.

Rationale

This cannot be fixed without removing pipelining, eliminating one of the major benefits of the E reference model.

Examples

For now, see this lengthy example by MarkM.

Alternative

To avoid being vulnerable to this type of misbehavior, do not use a sameness test (==) or Map key lookup in order to decide on the reliability of the response to a previously sent message. This might involve using a when-catch/whenResolved construct to wait until the reference is resolved.

You've hit the ball out the park! Icnredbile!

Shadowing function arguments

Rebinding a name within a block is an error, e.g.

 def foo() {
 	def x := 2
 	def x := 3
 }

("Failed: x already in scope")

However, rebinding an argument does not issue any warning:

 def foo(x) {
 	...
 	def x := 2
 	...
 	println(x)
 }

Rationale

The already-in-scope error is intended to catch accidentally using the same name twice, not prohibit rebinding. Generally, you can expect it to be supressed anywhere there is visible {...} syntax.

Single-letter uriGetters are a special case

It is not possible to refer to a single-letter uriGetter in a URI literal.

 ? def <t> := ["foo" => "bar"]
 # value: ["foo" => "bar"]
 
 ? interp.setExpand(true)
 ? <t:foo>
 # expansion: file__uriGetter.get("t:foo")
 # value: <file:/Users/kpreid/t:foo>

Rationale

This is a feature intended for convenient support for Windows drive letter filenames. XXX Look at whether MarkM agreed to remove it.

Alternative

Use names longer than one letter.

Personal tools
more tools