Surprise list
From Erights
(Single-letter uriGetters get overridden by the parser) |
Kevin Reid (Talk | contribs) (add missing info about rationales) |
||
Line 122: | Line 122: | ||
} | } | ||
+ | === Reason and Uses === | ||
- | == Single-letter uriGetters | + | 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 <code>{...}</code> 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"] | ? def <t> := ["foo" => "bar"] | ||
# value: ["foo" => "bar"] | # value: ["foo" => "bar"] | ||
- | ? <t:foo> | + | ? interp.setExpand(true) |
- | # value: | + | ? <t:foo> |
+ | # expansion: file__uriGetter.get("t:foo") | ||
+ | |||
+ | # value: <file:/Users/kpreid/t:foo> | ||
+ | |||
+ | ===Reason and Uses=== | ||
+ | |||
+ | 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. | |
[[Category:E language]] | [[Category:E language]] |
Revision as of 23:26, 3 February 2011
Potentially surprising parts of the E language.
Current as of E 0.8.33o.
Contents |
For-loop pattern failure is not an error
If the key or value pattern of a for
loop does not match, then the loop simply skips that element of the collection. This can be useful, but is unlike all other non-explicit pattern match operations (def
and parameter lists).
Examples
# E sample ? def things := [1, "two", 3] # value: [1, "two", 3] ? for x :int in things { > println(x) > } # stdout: 1 # 3 #
Alternative
Move the pattern into a def
:
# E sample ? for thing in things { > def x :int := thing > println(x) > } # stdout: 1 # # problem: <ClassCastException: String doesn't coerce to an int>
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>
Reason and Uses
If you want to pass a resolver as an argument, 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.
Reason and Uses
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.
Accumulator operator is lowest-precedence
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)) ...
Reason and Uses
None known; this is probably an accident of the definition of the expansion of accumulator syntax.
Alternative
Avoid accumulator syntax when the accumulation cannot be expressed as a single call.
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) }
Reason and Uses
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>
Reason and Uses
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.