Mark S. Miller wrote:
> Since ES is not an expression language, it's useful to divide the question
> into
>
> * TC for expressions
> expr equiv (function(){return expr;})()
> ES violations: this, arguments.
> 'this' breakage can possibly be addressed with '.bind(this)' as in
> my previous message.
> expr equiv (function(){return expr;}).call(this)
>
> * TC for blocks
> {stats} equiv (function(){stats})();
> Same issues re this, arguments
> Additional ES violations: return, break, continue, var hoisting
>
> Note: The above litany of problems are not fixable in ES. But we
> should try to avoid digging this hole any deeper.
Any procedural language will have issues with TC then. The only longterm
solution to this that I can think of is to add Ruby-like code blocks to
the language, which inherit this, arguments, var scope, and
return/break/continue continuations.
Not ever having dealt with implementing continuations, I have no idea
how simple it would be to add code block semantics to the language.
There are two styles to code blocks that I know of, which are not
mutually exclusive:
1) adding a new type of function
2) denoting that a parameter to a function is a block, and treating any
function passed in as that parameter to be a block
In either style, the function artifacts (this, arguments, etc.) would be
determined lexically.
The first style would require some new syntax to define blocks.
Redefining |this| via function.call and function.apply should also be
disallowed. We have several options to choose from. Some examples:
Ruby-like:
do(...) { ... }
do { ... }
Usage of Java keywords:
function(...) inherits { ... }
Some obscure yet convenient syntax:
#(...) { ... }
The second style would require some sort of block annotation to a
parameter, e.g.
function(x: block} { ... }
function(block x) { ... }
function(&x) { ... }
One advantage of the second style is that we can add new types of
control abstractions relatively seamlessly with some more Ruby-like
sugar. If the last parameter to a function is annotated to be a block,
then the following:
function control(..., block f) { ... }
control(...) statement
would pass in a 0-parameter code block composed of |statement| (which
could be a {...} block) to the function |control| as the parameter f.
Example:
function read(openArg, block f) {
try {
this.open(openArg);
f();
} finally {
this.close();
}
}
FileInputStream.prototype.read = read;
function findInFiles(files, x) {
for each (let file in files) {
input = new FileInputStream();
input.read(file) {
let lineNum = 0;
for (let line in input.readLines()) {
if (line == x)
return [file, lineNum];
lineNum++;
}
}
}
}
Hope that all made sense.
-Yuh-Ruey Chen
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss