recursion in Array.join/toString

2013-04-22 Thread Michael Day

Hi,

Apologies if I've missed something obvious, but is there any explicit 
specification of how this works in Mozilla:


xs = [1, 2, 3];
xs[1] = xs;
alert(xs.join()) // prints 1,,3

It even works when the recursion is less direct, like this:

xs = [1, 2, 3];
ys = [1, xs, 3];
xs[1] = ys;
alert(xs.join()) // prints 1,1,,3,3

Apparently Array.toString() returns empty string if it detects it is 
already inside an invocation of itself?


Best regards,

Michael
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


for-in evaluation order

2010-12-27 Thread Michael Day

Hi,

Some quick testing with Firefox seems to show that for-in returns 
properties in the order they were added to the object, and some scripts 
on the web (eg. RaphaelJS) seem to depend on that, unless I'm 
horrendously misinterpreting them. This seems... bad?


Are objects implicitly ordered, by implementation convention?

Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: for-in evaluation order

2010-12-27 Thread Michael Day

Thanks Boris, Dmitry,


Are objects implicitly ordered, by implementation convention?


For implementations that have to deal with the web, yes.


Okay, now I know what we have to do then :)

Might I suggest that this be added to the spec, if only in an 
informative note, to save future implementers the trouble?


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: for-in evaluation order

2010-12-27 Thread Michael Day

Hi Andreas,


Note that almost all implementations break for-in enumeration order for dense 
arrays, for some definition of dense.


This is understandable and very sensible.


If we try to specify something, implementors will probably object, and each 
implementation will have specific objections depending on their particular 
array and object representation.


Ugh. Tempting to randomise the order for non-dense objects, or just beat 
developers with the clue-bat until they stop writing code that depends 
upon a consistent order :)


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Function declarations as statements

2010-11-11 Thread Michael Day

Hi,

In ECMAScript, function declarations are SourceElements, but not 
Statements. This means that they can only occur at the top level, and 
may not be nested inside a block.


However, browsers support function declarations as statements, and many 
scripts on the web seem to make use of this ability, especially after 
they have been minified.


Is there a spec anywhere for how functions as statements should behave?

Can they be rewritten to var + function expression, so that this:

{
function f() { return 17 }
}

becomes this:

{
var f = function() { return 17 }
}

When implementing non-standard features, it would be nice to do so in a 
standard manner :)


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Function declarations as statements

2010-11-11 Thread Michael Day

Hi Brendan and Allen,

Thanks for the pointers.


So for Harmony, we are reclaiming function in block (must be a direct child of 
a braced block) to bind a block-local name on block entry (so hoisting lives, 
but only to top of block -- so you can't emulate with var f = function ...).


If we implemented this behaviour now, I think that would be sufficient 
to make JQuery and Raphaël work. Here is an example from JQuery that is 
giving us trouble:


if (condition) {
var val, props, ... ;

function getWH() { ... this is the function ... }

if ( elem.offsetWidth !== 0 ) {
getWH();
} else {
jQuery.swap( elem, props, getWH );
}

return Math.max(0, Math.round(val));
}

The getWH() function is declared in the block and only used in the 
block, so if we hoisted the definition to the top of the block there 
would not be any problems with this usage.


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


{ and } in regexps

2010-11-11 Thread Michael Day

Hi,

Browsers seem to allow { and } to occur in regexps unescaped, if the 
position does not conflict with their use as a quantifier. For example:


/foo|{bar}/

However, ES3 and ES5 forbid this, as PatternCharacter does not include { 
or } or any of the other significant punctuation.


Given that every new implementation ends up having to do what all the 
existing implementations do, is there any reason for the spec to differ?


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


\$ in regexps

2010-10-30 Thread Michael Day

[sent this to es3.x-discuss by mistake, sorry for any duplicates]

Hi,

Is \$ valid inside regexps? For example:

xs = /foo\$bar/.exec(foo$bar);

This matches in Firefox. However, the spec would appear to forbid this 
interpretation, unless I'm confused again:


IdentifierStart :: $

IdentifierPart :: IdentifierStart

IdentityEscape :: SourceCharacter but not IdentifierPart

CharacterEscape :: IdentityEscape

AtomEscape :: CharacterEscape

Atom :: \ AtomEscape

From these rules it seems that \$ is forbidden, and the only way to 
match a $ is to use a HexEscapeSequence or UnicodeEscapeSequence.


So is this a spec bug? It seems to be present in ES3 and ES5.

Or a Firefox extension?

Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Assigning to empty array/object literals

2010-08-18 Thread Michael Day

Hi,

Firefox 3.6.8 supports the following expressions:

[] = 3;

and:

{} = 3;

Although this object-literal version will trigger a syntax error at 
block scope, and so needs to be written like this:


x = ({} = 3);

In any case, shouldn't both of these expressions be early syntax errors, 
as the left hand side can never be a reference?


For comparison, non-empty array and object literals throw an error:

[1] = 3; // SyntaxError
x = ({foo: 1} = 3); // SyntaxError

Bug in Firefox? Or subtlety of the spec that's gone over my head? :)

Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Assigning to empty array/object literals

2010-08-18 Thread Michael Day

Hi Dmitry,


Destructuring (or, regarding JS -- Non-strict pattern matching).


Thanks, I was fooled by the fact the left hand side was empty :)

Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


ES5: typo in Error.prototype.toString()

2010-08-04 Thread Michael Day

Hi,

In ES5 15.11.4.4 Error.prototype.toString() states:

6. If msg is undefined, then let R be msg.

I'm pretty sure that should say:

6. If msg is undefined, then let R be name.

ie. if an Error object does not have a message property, then toString() 
will return the value of the name property, or Error if it doesn't 
have a name property either. This is what Mozilla currently does.


Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Catching eval

2010-08-03 Thread Michael Day

Hi all,

Any comments on this code:

try
{
throw eval;
}
catch (x)
{
alert(x(3));
}

It does not appear to throw an EvalError in Firefox 3.6.7, even though 
many other indirect uses of eval will.


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Basic Lambdas and Explicit Tail Calls Repackaged

2008-12-09 Thread Michael Day

Hi Yuh-Ruey,


I was also under the impression that since lambdas were lighter
functions that would be more efficient in time and/or space.


Is there any optimisation that could be performed for lambdas, but 
couldn't be performed for normal functions?


For example, it is easy to statically check that a function does not 
refer to 'this', or 'arguments' (right?) so in theory a function that 
does not use these features should not have to pay for them.


Functions are mutable objects and could perhaps gain a potential speed 
boost in some circumstances by being immutable. But that could be 
achieved by a generic mechanism for making immutable objects, and does 
not require introducing a new type of function.


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Simple tail calls

2008-12-07 Thread Michael Day

Hi Peter,


From what I understand, if lambdas are supposed obey Tenent's
principle, then they cannot have a return statement/expression.
Wrapping an expression in a lambda must not change the meaning of the
program. the following would need to be equivalent.


Right, I personally think this is unnecessary; functions don't follow 
this principle, after all.


I think it makes sense for expressions to have the same meaning, but not 
control flow statements when moved into a new execution context.


Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Basic Lambdas and Explicit Tail Calls Repackaged

2008-12-07 Thread Michael Day

Hi,

I thought it might be good to package these two proposals together, as 
they are interrelated.


It would be very much appreciated if anyone could point out major use 
cases that these proposals don't cover, or any other important issues 
that they might currently neglect.


BASIC LAMBDAS

Lambdas are similar to functions, but use the lambda keyword instead 
of function, always have a this value of undefined, and do not 
have an arguments object in scope.


LAMBDA EXAMPLES:

var x = lambda(n) { return n + 1 }

var x = lambda fact(n) {
if (n = 1)
return 1;
else
return n * fact(n-1);
};

EXPLICIT TAIL CALLS

The JavaScript specification should require implementations to
treat any ReturnStatement containing a CallExpression as a tail call, 
except in cases when the ReturnStatement is within a WithStatement or 
within a TryStatement.


TAIL CALL EXAMPLES:

function f()
{
return g(); // -- tail call!
}

function f()
{
g(); // -- not a tail call, no return keyword
}

function f(x)
{
with (x)
{
return g(); // -- not a tail call, inside with
}
}

ADVANTAGE: Very easy to specify and very easy to implement.

It does not require tail calls for CallExpressions which occur outside
of a ReturnStatement, eliminating a big chunk of specification devoted
to figuring out exactly what is or isn't a tail call position.

It does not require scanning through a function to identify tail
positions, so even the most basic interpreter operating directly on
abstract syntax trees could still implement them easily.

ADVANTAGE: It makes tail calls explicit.

Using return f() is as close as you can get to introducing a new
keyword, without introducing a new keyword. It makes it immediately
obvious whether a call is a tail call or not. EIBTI.

ADVANTAGE: Explicit tail calls preserve correctness.

The only point of requiring tail call optimisation rather than leaving
it optional is because the correctness of some code depends upon it.
However, implicit tail calls are easily lost as code changes. Consider a
tail call within a deeply nested block:

function f()
{
if (cond)
{
if (cond)
{
...
g(); // -- supposed to be a tail call, but is it?
}
}

minorCleanup(); // -- oh no! someone added this!
}

If tail calls use an explicit return, it is much harder to accidentally
break them, or overlook them. If tail calls are essential to ensure the
correctness of some code, they should be explicit in that code.

NOTE: Does not preclude fancier optimisations.

Implementations would be required to treat return calls as tail calls.
However, they would be free to treat other calls as tail calls as well,
or perform more complex optimisations such as introducing accumulator
arguments to transform code into tail-recursive form.

Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com

___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Basic Lambdas and Explicit Tail Calls Repackaged

2008-12-07 Thread Michael Day

Hi Eugene,

Is your lambda proposal competing with 
http://wiki.ecmascript.org/doku.php?id=strawman:lambdas (gave me by 
Brendon)?


It is a different proposal, I think it helps to have more than one 
proposal, in order to clearly see the different trade offs involved.


Why would anybody want to use a lambda instead of a function? 2 
characters less to type? What is the compelling reason, the super idea 
behind the lambda besides confusing programmers, and more things to 
implement by compiler writers?


Well, that's a really good question, as lambdas don't sound sufficiently 
different to regular functions in this proposal to be worth doing.


The lambda proposal on the wiki gives the following Why reasons:

A simpler primitive underlying the language’s first-class functions.

Removing 'this' and 'arguments' also gives a simpler primitive, but is 
it enough to bother with?


Supports defining other features via desugaring without breaking 
equivalence with implicit features (arguments, this, return) — this is 
sometimes described as Tennent’s Correspondence Principle [ 1, 2 ].


Not clear what this means, or what benefit it brings to either 
JavaScript programmers or implementors.


A well-tested feature of programming languages since time immemorial.

JavaScript already has higher-order functions, and much fewer languages 
have lambdas where a return returns from the enclosing function.


Supports tail calls more naturally than function.

I don't see what's unnatural about explicit tail calls in functions.

Simple, composable features like lambda are useful for other language 
features defined via desugaring/compiling other languages to ES/macros


What do lambdas in the wiki have that lambdas-as-functions-without-this 
do not have? They seem to have more complexity, but I can't see how they 
are significantly more useful.


Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Allen's lambda syntax proposal

2008-12-05 Thread Michael Day

Hi Brendan,

This is the other hazard with lambdas. The program equivalences 
Tennent's Correspondence Principle enables are  good for refactoring, 
but bad for thinkos like the above.


It seems like most of the problems come from lambdas being able to 
contain statements as well as expressions. If there were only lambda 
expressions, I think they would be much easier to reason about, but 
currently there is no way to embed loops in expressions, right?


Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Allen's lambda syntax proposal

2008-12-05 Thread Michael Day
This is all speculation, but here's my non-speculative claim: lambda 
syntax should not look so much like function syntax if return within the 
body behaves completely differently. We would want syntax very different 
from function (i.e., not lambda (args) {body} -- sorry, Peter Michaux). 
Or else we should revisit the wisdom of applying TCP to lambdas.


I'm unconvinced that TCP needs to apply to statements; it seems like a 
more valuable property when applied to expressions, even though 
JavaScript is not referentially transparent to begin with.


Anyway, these three options look good to me:

(1) Expression lambdas: lambdas whose body is an expression.

var x = lambda(y, z) y + z

Solves the problem with completion leakage, solves the nested 
return/break/continue issue. However, quite limited in usage, and makes 
it difficult to use lambdas to replace functions as they can't contain 
loop statements. (Hello, recursion! :)


(2) Function lambdas: objects just like functions, except no this or 
arguments, and perhaps some guarantees about tail calls?


var x = lambda(y, z) { return y + z }

This seems the easiest for programmers to understand, and avoids the 
return/break issues. It violates TCP for statements, but I don't think 
that really matters in practice; after all, so do functions.


(3) Parametric blocks: where a block, possibly taking arguments, can be 
passed around as an object. The key use-case for this seems to be 
creating new control abstractions. I would argue that blocks should not 
be usable as expressions, and the completion value cannot be captured 
(unless using eval) for consistency with existing statement behaviour.


var a = block { ... statements ... }
var b = block(x, y) { ... statements using x and y ... }

call b(1, 2);   // this is a statement, not an expression

Unfortunately, object literals also look like blocks, and there is no 
perfect syntax for this that fits neatly into the existing language. 
without using bulky keywords. While this option preserves TCP, I don't 
think JavaScript really needs this feature, and the power/complexity 
ratio doesn't measure up.


I agree if lambda looks like function or is sold as a better function. 
If it looks more like a block, or something else, that might mitigate 
the return hazard. Michael Day wondered if we confined the body to an 
expression language -- that would eliminate the return hazard.


I like options (1) and (2) above. The current proposal on the wiki feels 
like all three options mashed together, and I find it difficult make 
sense of it as a basic construct.


Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Allen's lambda syntax proposal

2008-12-04 Thread Michael Day

Hi Brendan,


Please read

http://wiki.ecmascript.org/doku.php?id=strawman:lambdas


There is a lot of discussion over whether it is necessary to introduce 
syntax sugar instead of a lambda keyword, but is there any remaining 
controversy over the semantics of lambdas in JavaScript, or is that 
considered settled at this point?


(To throw some more kerosene on the syntax fire, I would point out that 
fun for function nicely resembles var for variable:


var x = fun y z = y + z;

but it's not big deal :)

Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Allen's lambda syntax proposal

2008-12-04 Thread Michael Day

Hi Brendan,

The main contention about lambdas ignoring syntax is whether the 
completion-value creates a hazard that needs to be treated somehow, or 
even judged as fatal to the proposal.


Completion value, like the last thing to be evaluated in the lambda? 
What exactly is the nature of the hazard?


(To throw some more kerosene on the syntax fire, I would point out 
that fun for function nicely resembles var for variable:


   var x = fun y z = y + z;

but it's not big deal :)


Not bad but you lost the necessary (destructuring, default parameters) 
parenthesized formal list.


Right, an arguments list should still look like an arguments list:

var x = fun (y, z) = y + z

or with an identifier:

var x = fun fact(n) = (x  2 ? 1 : n * fact(n-1))

I toyed with 'fun' instead of 'function' in 1995 but it would have been 
a misfit in the Java-esque/C-like keyword set, even with 'var' included.


In an alternate universe, you might have used 'method' for functions 
with a 'this' value, saving two characters and the name function for 
real functions :)


Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why continue is not allowed outside iteration statements

2008-11-25 Thread Michael Day

Yes, you're right here. But why not write
'label: while (true) { ... continue label ...; break; }', to make it
clear that there is an iteration?


Yes, this would be clearer.


Forward jumps are less problematic than backward jumps -- in terms of
Dijkstra's argument, they do not require an index to keep track of the
number of iterations.


I agree. They are unnecessary though, given that one could write:

label: do { ... break label; ... } while (false);

Cheers,

Michael

--
Print XML with Prince!
http://www.princexml.com
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss