Old documents marked New

2008-08-13 Thread Ingvar von Schoultz
On the page http://www.ecmascript.org/docs.php three documents
are marked New!, but the documents are from October and November.

-- 
Ingvar von Schoultz


___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Picking property by attribute

2008-08-10 Thread Ingvar von Schoultz
YR Chen wrote:
 There's no separate namespace for enumerable properties.

This is about something else, something that's come up several
times in the discussion archives. See for example this post:
https://mail.mozilla.org/pipermail/es4-discuss/2007-March/000578.html

 Also, let's not add syntax for things that can easily be done with 
 functions.

Several syntaxes have been discussed. It seems to me that this
syntax would solve several problems that were discussed, and is
simple in implementation, very flexible and nicely readable.

Whether people still feel a need for a syntax, I don't know.

Ingvar



YR Chen wrote:
 There's no separate namespace for enumerable properties. They are 
 properties with a hidden enumerable flag set. With that said, in ES4, 
 only non-fixed properties in the public namespace will be enumerable by 
 default. That means that properties defined in classes will not be 
 enumerable unless prefixed with |prototype|, and only custom 
 properties defined in the public namespace (which is the default 
 namespace) are enumerable. So if you don't want a property to be 
 enumerable, just define it in another namespace and also open that 
 namespace (via |use namespace|). Or you can toggle the enumerable flag 
 off via some new method whose name escapes me.
 
 Also, let's not add syntax for things that can easily be done with 
 functions. You can create your own iterator functions and use them, e.g.:
 
 // assuming pythonic generators are in ES4 (there's an equivalent, 
 albeit uglier, non-generator way)
 myDictClass.prototype.own = function() {
 for (var x in this.iterator::get()) {
 if (this.hasOwnProperty(x))
 yield x;
 }
 }
 
 for (var x in myDict.own()) ...
 
 -Yuh-Ruey Chen
 
 On Fri, Aug 8, 2008 at 1:07 PM, Ingvar von Schoultz 
 [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote:
 
 I think this would be useful:
 
 Get an enumerable property:
 
 var x = myDict [*enumerable] .someName;
 
 var x = myDict [*enumerable] [someVariable];
 
 Call the non-enumerable .toString():
 
 var x = myDict [*!enumerable] .toString();
 
 Distinguish between owned and inherited properties:
 
 var x = myDict [*own] .someName;
 
 var x = myDict [*!own] .toString();
 
 Loop through a subset:
 
 for (var x in myDict [*own]) {...}
 
 The syntax is meant to suggest that we pick a subset, such as
 all the enumerable properties, and then pick a property from
 this subset.
 
 Here's an alternate syntax, more logical but less readable
 in my opinion:
 
 var x = myDict .:enumerable .someName;
 
 var x = myDict .!enumerable .toString();
 
 --
 Ingvar von Schoultz
 
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org mailto:Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss
 
 


-- 
Ingvar von Schoultz

--- (My unusual use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-08-06 Thread Ingvar von Schoultz
Yuh-Ruey Chen wrote:
 FWIW, I definitely like this proposal more than any convoluted 
 var-scoping block proposal.
 
 I just don't see the value of adding var-scoping blocks for the added 
 parser complexity, and problematic return/break/continue.

Unfortunately it seems people dislike the notation too much.
But the complexity that you discuss must be supported anyway.
Regardless whether it's written {let} or {{var}}, they both
say the same thing, and what they say is supported in ES4.

My code looks convoluted only because it's an odd trick.
Not only does it add {let} functionality to ES3.1, it also
strives very hard to make the tiniest possible change.

That tiny code is also conclusive proof that {{var}} is
extremely simple and has no capture problems, despite many
vague claims to the contrary.

Unfortunately it seems people dislike the notation so much,
they prefer having no {let} functionality at all in ES3.1.

-- 
Ingvar von Schoultz

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-08-01 Thread Ingvar von Schoultz


Okay then, even shorter.


Brendan Eich wrote:
 But it is not what you proposed.

In what way? Please be more specific, because I don't know what
this supposed proposal of mine is.

For example, those scope questions mention rebinding in a visible
scope, midway through its code block, but that's unrelated to
anything I've proposed and unrelated to how JavaScript works.

I've tried to guess what you think I've proposed from the scope
questions, but the guessing has made my answers long. Stupid
mistake, I should have asked instead, sorry.

So please say something specific that I can address.

 Waldemar wrote a while back: Keep in mind that function assignments  
 hoist to the beginning of the scope in which the function is defined,
 so your proposal won't work.

It works perfectly well. The initial |undefined| is fully intentional,
it protects against capture problems. It's a minor limitation, certainly
not a showstopper.

-- 
Ingvar von Schoultz

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-30 Thread Ingvar von Schoultz
Regarding my explanations quoted below, did they clarify
things?

It would be a relief to know that things are now clear and
understandable, if they are. If there are still things
that seem unclear, strange, incompatible or impractical,
please ask about them!

After some thinking I've found that I could have explained
some of the things below better, making them clearer. Should
I post better explanations?

I'm really very curious about that rebinding problem! Both
what it means, and where I seem to propose it (or actually
propose it, inadvertently).

Ingvar



Ingvar von Schoultz wrote:
 Sorry about the length of this, but I'm trying to cover the
 unclear things, and often I don't know which things are unclear.
 
 Brendan Eich wrote:
 On Jul 26, 2008, at 2:07 PM, Ingvar von Schoultz wrote:

 You can't get away from supporting this:

   {
   function a(){}
   var b = a;
   }

 ES4 is planning to support function declarations locally
 bound in blocks, so the above is valid ES4 code.

 What you see above is function b() hoisting like var.

 (I said b, not a.)
 What you said does not make sense.  It's true that var b is hoisted to
 the top of the program or function body. But it is not initialized  
 until control flows through the assignment b = a that is part of the  
 var declaration. So there is no capture problem.
 
 That's my point! There isn't any capture problem. That's exactly
 what I'm showing here. And, more importantly, you can't insert a
 capture problem while keeping the structure intact. The arrangement
 is inherently well-behaved.
 
 I'm trying to show that you can support functions that hoist like
 var in a well-behaving way, and that this is /not/ complicated.
 And the snippet is intended as proof.
 
 But perhaps I should interpret what you said somewhat differently.
 
 The snippet, as shown here, does not have a capture problem.
 But if you improve the hoisting carelessly, there's a threat
 of a capture problem lurking within it. (That's assuming that
 I understand capture problem correctly -- this is a rare
 case of Wikipedia not explaining a computing term.)
 
 Somebody might want to improve the hoisting by making it so
 that the function is assigned (is callable) from before we enter
 the global scope.
 
 Let's assume, for the argument, that the above code magically
 starts to behave that way. Then it will work fine as long as it
 stays the same. But later the programmer might decide to add a
 local variable:
 
  {
  function a(){}
  var b = a;
  let c = 3;
  }
 
 c is now visible from inside a(), but exists only when we enter
 the block. So in this situation a() must not be called before
 we enter the block. The function must no longer be assigned
 (callable) at the top of the global scope.
 
 I would consider it extremely surprising semantics if I can call
 a() above the block, but only before I add that local variable,
 and this suddenly changes just because I add c. It's a huge change,
 it's far away, and it's unrelated.
 
 So for the sake of consistency and predictability we must assign
 |undefined| whenever the code structure allows a capture problem
 to be inserted as a side effect of doing something unrelated,
 like adding |let c|.
 
 That's why I said this, in the email where I first showed this
 snippet:
 
 ,---
 |  Assigning |undefined| is correct for any function whose
 |  assignment depends on sequential code. The above is such a
 |  sequential dependency, even though it may not look that way.
 `---
 
 It may not look sequential, but that's just because I left out
 a lot of details, in an attempt to keep it as brief as ever
 possible, to minimize any misunderstandings.
 
 As you can see, in my opinion, what I'm saying does make perfect
 sense!
 
 The claim that just because of this limitation my proposal
 doesn't work is in my opinion quite mistaken. I consider
 this functionality fully acceptable. It's simple, understandable
 and predictable. Sure it's a limitation, but a minor one. It's
 /far/ better and more useful and intuitive than having functions
 not hoisting out at all.
 
 The usual use case will be an if() or some such. Then the
 programmer fully expects the function to be available only
 afterward. Very useful. Using it in a bare block like the
 above will be unusual, but if used, the rules are simple.
 
 There is no far-too-complicated split-scope complexity. There
 is no capturing of variables that haven't been declared yet.
 It's simple, intuitive, well-defined and well-behaved.
 Thanks, I agree. But it is not what you proposed.
 
 Sorry, I don't understand. What is not what I proposed, and
 in which one of my proposals did I not propose it?
 
 Again, from  
 Waldemar's original reply, but with your proposed {{}} interpolated  
 and the elided code amended to say what the consequence is:

 // outer scope
 function c() ...;

 // inner scope
 {{
if (foo) {
  const c = 37;
}
... c

Re: A simple translation of the scoping-block syntax sugar -- Was: Re: function hoisting like var

2008-07-30 Thread Ingvar von Schoultz
Ingvar von Schoultz wrote:
 Any variable
 that you declare anywhere will simply splash out of any { } and
 attach itself to the nearest surrounding {{ }}, becoming visible
 in the entire space between them.

Int this splashing out of { }, function declarations are
a special case. Although implementations differ, I think
{{ }} could serve as an opt-in where they become specified
to follow clear rules.

In my opinion the most useful rules would be:

The name is visible in the entire space between the nearest
surrounding {{ }}. Usually it's also callable in that entire
space, but there are a few exceptions.

If you put the declaration in a sequential construct,
for example under if(), then at the {{ you can't call it
(it's |undefined|), and it becomes callable only from the
sequential construct and onward. If there is a { at the
beginning of the sequential construct, the function becomes
callable from the { and onward.

If you make more than one declaration with the same name,
this makes all the declarations of that name sequential.
Then at {{ you can't call any of the versions of the
function (again |undefined|). Each version becomes callable
at the spot of declaration.

In all other cases the function is callable in the entire
space between {{ }}.

(This is not intended as an exhaustively detailed description,
just an overview.)

(The rules will have to be changed a little if let declarations
are allowed between {{ }}, or if allowing them there in a
future version should be possible. And reserving the possibility
might be a good idea -- who knows what people will want or
will invent. To allow that, the rules become slightly more
limiting.)

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


A simple translation of the scoping-block syntax sugar -- Was: Re: function hoisting like var

2008-07-29 Thread Ingvar von Schoultz
The simple translation of {{ }} that I posted yesterday needs
an improvement. It must pass |this| and |arguments| to the scoping
function.

I still think it looks quite small and simple, and that it would
be a very useful addition to the language.

 try
 {   var _ReturnValue = (function (arguments)
 {
 // Any governing for(), while() or switch() goes here.
 {
 // The code between {{ }} goes here.
 }
 throw _NormalEndSignal;
 }).call (this, arguments);
 return _ReturnValue;
 }
 catch (_Sig)
 {
 if (_Sig != _NormalEndSignal)
 throw _Sig;
 }

We must use .call(), not .apply(), so that we pass the arguments
object as such, with the outer function as arguments.callee.

In the global scope, |arguments| will be undefined, unless the
programmer has defined it. It should remain undefined inside the
scoping function.

As an alternative to the above parameter passing, I suppose the
implementation can simply remove the scope function's arguments
object, thereby making the outer arguments object visible.

Initial underscore means hidden, invisible.

For a description of the translation, see the quoted text below.

Ingvar



Ingvar von Schoultz wrote:
 Ingvar von Schoultz wrote:
 In theory {{ code }} could be converted to a function that
 returns information about whatever break/continue/return was
 reached.
 
 I now think this could be made very simple.
 
 The solution is to make this version slightly limited. Don't
 support break/continue statements that mention any label
 outside {{ }}. Leave that for a future version.
 
 This simplifies things tremendously! And you don't need that
 kind of break/continue all that often. (But a future version
 must include it.)
 
 This limited solution only needs break/continue functionality
 that is already supported. Even the necessary label checking
 is already supported. An unsupported break such as the following
 gives a syntax error if you translate {{ }} to a one-shot
 function:
 
  Outer:
  for (var OutName in OutThing)
  for (var InName in InThing)
  {{
  break Outer;
  }}
 
 The error message that I get says undefined label, which
 is misleading, but apart from that it works perfectly.
 
 If people find the above limited support for break/continue
 acceptable for this version, all that remains is the return
 statement.
 
 It seems easiest to use a solution that leaves all the return
 statements in the original code intact. This makes the translation
 from {{ }} to function a little elaborate and odd, but everything
 is nicely contained at one spot.
 
 Within the created function, if control reaches the final }},
 throw a special error that isn't really an error, rather the
 opposite, it's a signal that indicates that this is a normal
 termination. When this signal is received, continue below }}.
 
 If instead, within the created function, control reaches a
 return statement that appears in the original code, the result
 is a regular return, without the above thrown signal. This
 indicates that whatever value was returned should be passed
 along as return value of the enclosing function.
 
 This means that {{ }} is essentially translated into this:
 
  try
  {   var ReturnValue = (function()
  {   // The code that was written between {{ }} goes here.
  throw NormalEndSignal;
  })();
  return ReturnValue;
  }
  catch (Sig)
  {   if (Sig != NormalEndSignal)
  throw Sig;
  }
 
 It seems to me that this becomes very nicely contained,
 very manageable.
 
 Implementations will probably want to optimize away this
 entire elaborate arrangement and replace it with plain and
 simple scoping blocks. But they can take their time. The
 above provides the functionality in a simple way.
 
 That is, unless I've missed something, and the above solution
 doesn't work the way I think it does.
 

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: A simple translation of the scoping-block syntax sugar -- Was: Re: function hoisting like var

2008-07-29 Thread Ingvar von Schoultz
If the simple translation of {{ }} is used, any governing
for(), while() or switch() must be moved inside the scoping
function.

A very simple, very minimalistic approach may be enough.

 for (var Name in Thing)
 {{
 }}

Name is locally contained inside {{ }} while Thing is outside.
But maybe the compiler doesn't have to make this distinction.

Personally I'd never use the same name with different meanings
so close together, like this:

 var Thing = ...;
 for (var Name in Thing)
 {{  var Thing = ...;
 }}

I find that obscure and error-prone.

If the limitation is acceptable, a very minimalistic translation
of {{ }} could simply move the entire for (...) inside the
scoping function, and leave it at that. As long as Thing isn't
redeclared inside, the outer Thing is visible and it works.

Does this make it simple enough for ES3.1?

As an added bonus, the functionality becomes very easy to explain.
The rules become very plain and simple.

I don't know if a let statement with this limitation would be
useful. Every description of let that I can find re-uses names.
But if it's useful, it could be trivially implemented as syntax
sugar:

 let (a = x, b = y)
 {{
 }}

would be syntax sugar for

 {{  var a = x, b = y;
 }}

However let has different semantics in at least one existing
implementation (it does distinguish between same-name variables
in the two scopes), so if a minimalistic let is introduced, it
should probably use a different keyword.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: A simple translation of the scoping-block syntax sugar -- Was: Re: function hoisting like var

2008-07-29 Thread Ingvar von Schoultz
I'd like to summarize some clarifications and arguments.

I'm thinking of what it might be like if {{ }} should become
available in ES3.1.



=== Intuitive ===

The proposed {{ }} mean exactly the same thing as { } in C, Java etc.

If switching between languages causes you any difficulties, simply
use {{ }} everywhere in your ES3.1 code. This way you get the braces
that you're used to from C and Java, apart from a slightly different
notation.

Think of it as JavaScript having a small difference in brace notation
while the functionality is the same.



=== Control flow ===

In ES3 you can use { } for plain control flow, without any scoping.
This is very useful for small projects.

If this is not a good fit for your projects, it's still very useful
elsewhere. Please don't deprecate this functionality.

For more on the usefulness of this plain control flow, see:
https://mail.mozilla.org/pipermail/es4-discuss/2008-July/003353.html



=== Difference ===

If you want the full flexibility of using both {{ }} and { },
first decide which type of brace you want to use most in your
program. Stick with that almost everywhere. Make an exception
only when you have a clear and specific reason, because you
need the functionality of the other type.

This way your code will be consistent and readable.

You can view the {{ }} as containers for variables. Any variable
that you declare anywhere will simply splash out of any { } and
attach itself to the nearest surrounding {{ }}, becoming visible
in the entire space between them.

If you prefer a more low-level view, { } are plain jumps and
branches, and only {{ }} affect the scope chain.



=== Ugly ===

The proposed {{ }} will inevitably look horrible in emails if
you use a proportional font such as Times New Roman. Real code
is never displayed in such a font. Try a programmer's editor
with a suitable font and syntax coloring. It looks completely
different!

If people still find it ugly, I hope a good alternative can be
found, because the functionality would be very useful.



=== Let declarations ===

There are existing implementations that support let.

My proposal is that /let declarations/ should be completely disabled
between {{ }}. This of course includes all { } that are nested between
{{ }}.

The only reason is simplicity, mainly for the script programmer.

Outside {{ }} they should be enabled, for compatibility and to satisfy
those who prefer the let and var combination.



-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: A simple translation of the scoping-block syntax sugar -- Was: Re: function hoisting like var

2008-07-29 Thread Ingvar von Schoultz
The translation can be made simpler.

First, define a unique value, to be returned when the end of
the scoping block is reached. If done in JavaScript:

 var _EndOfBlock = {};

Then each {{ }} can be translated to this:

 var _ReturnValue = (function (arguments)
 {
 // Any governing for(), while() or switch() goes here.
 {
 // The code between {{ }} goes here.
 }
 return _EndOfBlock;
 }).call (this, arguments);
 if (_ReturnValue != _EndOfBlock)
 return _ReturnValue;

Ingvar



Ingvar von Schoultz wrote:
 The simple translation of {{ }} that I posted yesterday needs
 an improvement. It must pass |this| and |arguments| to the scoping
 function.
 
 I still think it looks quite small and simple, and that it would
 be a very useful addition to the language.
 
  try
  {   var _ReturnValue = (function (arguments)
  {
  // Any governing for(), while() or switch() goes here.
  {
  // The code between {{ }} goes here.
  }
  throw _NormalEndSignal;
  }).call (this, arguments);
  return _ReturnValue;
  }
  catch (_Sig)
  {
  if (_Sig != _NormalEndSignal)
  throw _Sig;
  }
 
 We must use .call(), not .apply(), so that we pass the arguments
 object as such, with the outer function as arguments.callee.
 
 In the global scope, |arguments| will be undefined, unless the
 programmer has defined it. It should remain undefined inside the
 scoping function.
 
 As an alternative to the above parameter passing, I suppose the
 implementation can simply remove the scope function's arguments
 object, thereby making the outer arguments object visible.
 
 Initial underscore means hidden, invisible.
 
 For a description of the translation, see the quoted text below.
 
 Ingvar
 
 
 
 Ingvar von Schoultz wrote:
 Ingvar von Schoultz wrote:
 In theory {{ code }} could be converted to a function that
 returns information about whatever break/continue/return was
 reached.
 I now think this could be made very simple.

 The solution is to make this version slightly limited. Don't
 support break/continue statements that mention any label
 outside {{ }}. Leave that for a future version.

 This simplifies things tremendously! And you don't need that
 kind of break/continue all that often. (But a future version
 must include it.)

 This limited solution only needs break/continue functionality
 that is already supported. Even the necessary label checking
 is already supported. An unsupported break such as the following
 gives a syntax error if you translate {{ }} to a one-shot
 function:

  Outer:
  for (var OutName in OutThing)
  for (var InName in InThing)
  {{
  break Outer;
  }}

 The error message that I get says undefined label, which
 is misleading, but apart from that it works perfectly.

 If people find the above limited support for break/continue
 acceptable for this version, all that remains is the return
 statement.

 It seems easiest to use a solution that leaves all the return
 statements in the original code intact. This makes the translation
 from {{ }} to function a little elaborate and odd, but everything
 is nicely contained at one spot.

 Within the created function, if control reaches the final }},
 throw a special error that isn't really an error, rather the
 opposite, it's a signal that indicates that this is a normal
 termination. When this signal is received, continue below }}.

 If instead, within the created function, control reaches a
 return statement that appears in the original code, the result
 is a regular return, without the above thrown signal. This
 indicates that whatever value was returned should be passed
 along as return value of the enclosing function.

 This means that {{ }} is essentially translated into this:

  try
  {   var ReturnValue = (function()
  {   // The code that was written between {{ }} goes here.
  throw NormalEndSignal;
  })();
  return ReturnValue;
  }
  catch (Sig)
  {   if (Sig != NormalEndSignal)
  throw Sig;
  }

 It seems to me that this becomes very nicely contained,
 very manageable.

 Implementations will probably want to optimize away this
 entire elaborate arrangement and replace it with plain and
 simple scoping blocks. But they can take their time. The
 above provides the functionality in a simple way.

 That is, unless I've missed something, and the above solution
 doesn't work the way I think it does.

 

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels

Re: function hoisting like var

2008-07-28 Thread Ingvar von Schoultz
Ingvar von Schoultz wrote:
 In theory {{ code }} could be converted to a function that
 returns information about whatever break/continue/return was
 reached. But I'd be quite surprised if that is easy.
 
 Something like this. Written with syntax sugar:
 
  Outer:
  for (var OutName in OutThing)
  for (var InName in InThing)
  {{
  break Outer;
  }}
 
 Translation:
 
  Outer:
  for (var OutName in OutThing)
  {
  var _Result = (function (_InThing)
  {
  for (var InName in _InThing)
  {
  return ({JumpSpot: 'break Outer'})
  }
  })(InThing);
  if (_Result.JumpSpot == 'break Outer')
  break Outer;
  }
 
 The inner for() is part of the scoping block, so it belongs
 inside, even though the original code has it above.
 
 We must make sure the value of InThing is available inside
 even if the name is declared for a different variable inside.
 
 I use initial underscore to indicate something internal and
 invisible.
 
 It doesn't look complicated here! Unfortunately these things
 have a terrible tendency to grow in complexity...

I now think this could be made very simple.

The solution is to make this version slightly limited. Don't
support break/continue statements that mention any label
outside {{ }}. Leave that for a future version.

This simplifies things tremendously! And you don't need that
kind of break/continue all that often. (But a future version
must include it.)

This limited solution only needs break/continue functionality
that is already supported. Even the necessary label checking
is already supported. An unsupported break such as the following
gives a syntax error if you translate {{ }} to a one-shot
function:

 Outer:
 for (var OutName in OutThing)
 for (var InName in InThing)
 {{
 break Outer;
 }}

The error message that I get says undefined label, which
is misleading, but apart from that it works perfectly.

If people find the above limited support for break/continue
acceptable for this version, all that remains is the return
statement.

It seems easiest to use a solution that leaves all the return
statements in the original code intact. This makes the translation
from {{ }} to function a little elaborate and odd, but everything
is nicely contained at one spot.

Within the created function, if control reaches the final }},
throw a special error that isn't really an error, rather the
opposite, it's a signal that indicates that this is a normal
termination. When this signal is received, continue below }}.

If instead, within the created function, control reaches a
return statement that appears in the original code, the result
is a regular return, without the above thrown signal. This
indicates that whatever value was returned should be passed
along as return value of the enclosing function.

This means that {{ }} is essentially translated into this:

 try
 {   var ReturnValue = (function()
 {   // The code that was written between {{ }} goes here.
 throw NormalEndSignal;
 })();
 return ReturnValue;
 }
 catch (Sig)
 {   if (Sig != NormalEndSignal)
 throw Sig;
 }

It seems to me that this becomes very nicely contained,
very manageable.

Implementations will probably want to optimize away this
entire elaborate arrangement and replace it with plain and
simple scoping blocks. But they can take their time. The
above provides the functionality in a simple way.

That is, unless I've missed something, and the above solution
doesn't work the way I think it does.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-27 Thread Ingvar von Schoultz
Brendan Eich wrote:
 On Jul 26, 2008, at 2:06 PM, Ingvar von Schoultz wrote:
 
 How sad! It seemed such a simple and intuitive notation!
 
 Opinions vary, but all the ones I heard at the Ecma TC39 meeting  
 found it neither simple nor intuitive, and some abhorred it on  
 aesthetic grounds to boot.

Not simple? How is that possible?

There have been several misunderstandings. Did they spread
that far?

{{ }} is just the same as a scoping function used on ES3:

 (function() { code })()

Everything works just the way I meant if you take ES3, or any
platform that does /not/ support let declarations, and make
it so that {{ }} becomes syntax sugar for the above one-shot
scoping function.

Of course, the way I think about {{ }}, I don't see it as a
function, I see it as a name-binding scope. But the scoping
effect is just that.

For me, having a single scoping block is simpler than having
two, and having a single visibility keyword is simpler than
having two. And I think my notation is /much/ simpler than
the one-shot function!

 {{ code }}  (function() { code })()

I do find my notation slightly ugly. But the one-shot function
is worse in my view. Charming but very kludgey.

(Thanks Igor for noticing that {{ }} are synonymous with one-shot
scoping functions. Why didn't I think of that!)

 I think all of these would be unambiguous:

  {. code .}

  {: code :}

  {| code |}

  {[ code ]}

  [[ code ]]

  [ code ]
 
 These are either syntax errors without opt-in versioning,

Yes, and this should guarantee that they are unique.

I now have the impression that, on the client side, opt-in
by version would be necessary in any case, with any notation.
If old platforms accept the syntax, it changes existing
semantics; if they don't, it requires opt-in to avoid errors.

 or (the  
 last three) do create incompatible ambiguity (consider array  
 initialisers).

It seems to me that they could be disambiguated easily. I
comment on this in a reply to Igor.

 What's more, as Waldemar pointed out many threads (and too many  
 words) ago, they create capture problems.

There were misunderstandings.

If there are fundamental differences in this regard between {{ }}
and one-shot scoping functions, I can't find them.

 Please work through the  
 last mail I sent before replying; if some vocabulary or infelicitous  
 word choice is causing any confusion, feel free to mail me privately  
 and ask pointed questions. Thanks,

Thanks for the invitation. I'll certainly take you up on it
if the need or urge arises.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-27 Thread Ingvar von Schoultz


Mike Shaver wrote:
 On Sun, Jul 27, 2008 at 7:51 PM, Ingvar von Schoultz
 [EMAIL PROTECTED] wrote:

 Igor Bukanov wrote:
 eval('[]') is a valid and, in fact, useful ES3 code. Similarly eval('{[]}').
 Yes, and by my rules they both create and return a new, empty
 array, which is intuitively expected and compatible.
 
 And the latter only does because the { is parsed as starting a block;
 if it were to start out assuming a literal, you would get an illegal
 object initializer.

I meant that [ would follow those rules, not {. The rules I
sketched are definitely not usable for {.

 I get the impression that the parser always must start out
 assuming it's a literal, and backtrack if the syntax doesn't
 fit. The only exception would be at a spot where a literal
 isn't possible while a block is possible, but I don't think
 any such spot is possible.
 
 if { block; }
 
 would seem to be such a spot, no?

These are valid literals (immediately discarded, but valid
syntax):

 if (true) [10, 20];

 if (true) { [10, 20] };

Likewise valid:

 if (true) 10;

 Regardless, I'm pretty sure ES3
 compat requires that a statement starting with a { be taken as a block
 and not a literal, with no backtracking.
 
 js {a:5, b:6}
 typein:4: SyntaxError: invalid label:
 typein:4: {a:5, b:6}
 typein:4: ..^
 
 Mike
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss
 

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-27 Thread Ingvar von Schoultz
Igor Bukanov wrote:
 2008/7/28 Ingvar von Schoultz [EMAIL PROTECTED]:
 If [...] is preceded by =, or enclosed in ( ), or in some other
 position where you can't have a block, it's a literal. If it's
 a literal it must contain a comma-separated list of values, so
 if the syntax doesn't match this, it's a block.
 
 Such rules require an arbitrary look ahead in the parser so it can
 distinguish that in cases like
 
   if (x) [arbitrary_expression;]
 
 [] means a block while in
 
   if (x) [arbitrarily_expression];
 
 [] would mean a literal.
 
 This would require a mayor change in most if not all current ES parser
 implementations. There were some proposals for ES4 syntax that would
 require such look ahead, but they were rejected not only technical
 grounds but also on the grounds that such look ahead poses
 comprehension problem for a human brain! And here are we talking about
 a minimalistic sugar for ES3.1.
 
 Regards, Igor
 ___
 Es3.x-discuss mailing list
 [EMAIL PROTECTED]
 https://mail.mozilla.org/listinfo/es3.x-discuss
 

I wasn't aware that backtracking was a difficulty. That makes
quite a difference!

In theory this could be overcome. Often the ambiguity doesn't matter:

 if (x) [a(), b(), c()];

Block or throwaway array, the end result is the same. So in principle
you could start out building an array, and on the first nonmatching
syntax you discard the half-built array and build a scope block
instead:

 if (x) [a(), b(), c(), d(), e(), let f = g;]

Of course in practice such a solution is too messy, unless you have
some extremely thorny problem that just can't be solved in any other
way. And this certainly isn't that kind of problem. So [ ] are out.

Unless they're reincarnated as:

 [: code :]

Ah, now I know! I have the perfect solution, guaranteed to be
unambiguous. Happy code!

 (-: Scoping blocks are delimited by smileys! :-)

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-27 Thread Ingvar von Schoultz


Richard Cornford wrote:
 Ingvar von Schoultz wrote:
 Igor Bukanov wrote:
 2008/7/28 Ingvar von Schoultz wrote:
 snip
 Any of this can be a valid ES3 code as [] always means an
 array literal.
 I get the impression that disambiguation would be easy.
 eval('[]') is a valid and, in fact, useful ES3 code. Similarly
 eval('{[]}').
 Yes, and by my rules they both create and return a new, empty
 array, which is intuitively expected and compatible.
 
 Are you saying that a block then may never be empty as a syntax
 rule? ES 3 blocks are allowed to be empty and I bet there are
 examples where blocks contain nothing but an IE/JScript
 conditional comment and so are going to be interpreted as
 being empty by other ES 3 implementations. (Comments are
 allowed inside array literal definitions at present).

Does it matter whether it's interpreted as an empty block or
an empty discarded array?

 When I said that an array is a comma-separated list of values,
 the fact that I left out the empty and the single-value cases
 didn't mean that they should be seen as blocks! I just didn't
 want to write a lengthy, exhaustive full grammar...
 snip
 
 {
1,2,3,4,5
 }
 
 - is a valid ES 3 Program (even if a pointless one); A Block
 statement containing an Expression statement (with automatic
 semi-colon insertion making the Expression statement
 into - 1,2,3,4,5; -).
 
 eval('{1,2,3,4,5}') - results in the value 5, while -
 eval('[1,2,3,4,5]') - returns a 5 element array.

Yes. And if the rules for { remain unchanged, and [ starts out
assuming it's a literal, you get the same result with my rules.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-27 Thread Ingvar von Schoultz


Mike Shaver wrote:
 On Sun, Jul 27, 2008 at 9:15 PM, Ingvar von Schoultz
 [EMAIL PROTECTED] wrote:
 Does it matter whether it's interpreted as an empty block or
 an empty discarded array?
 
 It's not always discarded:
 
 js var x = 1
 js eval (if (x) [1, 2, 3])
 1,2,3

That becomes an array, no problem. My Does it matter was
about empty blocks only, in reply to your question:

 Are you saying that a block then may never be empty as a syntax
 rule?
 Does it matter whether it's interpreted as an empty block or
 an empty discarded array?

Array is the default. An empty block gets misinterpreted as an
empty array.

So a code generator that produces an eval that returns a scoping
block must deal with the special case that the block may be empty
or contain a comma-separated list of values. It's the generator's
own fault for producing such silly code, so I don't feel sorry
for that generator. :-)

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-27 Thread Ingvar von Schoultz


Richard Cornford wrote:
 Ingvar von Schoultz wrote:
 Richard Cornford wrote:
 snip
 {
1,2,3,4,5
 }

 - is a valid ES 3 Program (even if a pointless one); A Block
 statement containing an Expression statement (with automatic
 semi-colon insertion making the Expression statement
 into - 1,2,3,4,5; -).

 eval('{1,2,3,4,5}') - results in the value 5, while -
 eval('[1,2,3,4,5]') - returns a 5 element array.
 Yes. And if the rules for { remain unchanged, and [ starts
 out assuming it's a literal, you get the same result with my rules.
 
 And if I wanted that block scope this -
 
 eval({[\n eval('var a = 1'),eval('var b = 2'),eval('a + b')\n]});
 
 - will still give me an array (and side effects in the containing scope)?

Goodness, if the code generator writes that, it deserves to melt!

I'd say if you're aware of scoping blocks, and want to have a
scoping block, and despite this insist on separating with commas
rather than semicolons or bare newlines, well, then you deserve
the array that you get!

So the solution is to use semicolon or newline as separator,
preferably somewhere near the beginning.

Of course the real solution to all this is to use my original
{{ }} instead. You get used to them. And they're very easy to
type!

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-27 Thread Ingvar von Schoultz


Igor Bukanov wrote:
 2008/7/28 Ingvar von Schoultz [EMAIL PROTECTED]:
 {{ }} is just the same as a scoping function used on ES3:

(function() { code })()
 
 As Lars Hansen has pointed out any proposal for a shorthand for
 (function() { code })() has to deal with break/continue/return inside
 the code.

Indeed I wasn't thinking of that in my description.

 This is the the reason if anything I would prefer in ES3.1
 just shorthands for function definitions like
 
 function() expr  - equivalent to function () { return expr; }. This is
 already in ES4 and is implemented by at least on implementation
 (SpiderMonkey).

I rarely feel a need for such tiny scoping blocks, but often
long for big scoping blocks with intuitive syntax.

 function optional_name { code } - equivalent to function
 optional_name() { code } - a hypothetical shortcut that would allow to
 write a pseudo-blocks like
 
 function {
 }();
 
 with clear emphasis that this is a lambda with usual rules for
 break/continue/return.

Yes, we can't have syntax that looks like a block but forbids
or misunderstands break/continue/return.

In theory {{ code }} could be converted to a function that
returns information about whatever break/continue/return was
reached. But I'd be quite surprised if that is easy.

Something like this. Written with syntax sugar:

 Outer:
 for (var OutName in OutThing)
 for (var InName in InThing)
 {{
 break Outer;
 }}

Translation:

 Outer:
 for (var OutName in OutThing)
 {
 var _Result = (function (_InThing)
 {
 for (var InName in _InThing)
 {
 return ({JumpSpot: 'break Outer'})
 }
 })(InThing);
 if (_Result.JumpSpot == 'break Outer')
 break Outer;
 }

The inner for() is part of the scoping block, so it belongs
inside, even though the original code has it above.

We must make sure the value of InThing is available inside
even if the name is declared for a different variable inside.

I use initial underscore to indicate something internal and
invisible.

It doesn't look complicated here! Unfortunately these things
have a terrible tendency to grow in complexity...

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-26 Thread Ingvar von Schoultz
Igor Bukanov wrote:
 2008/7/26 Ingvar von Schoultz [EMAIL PROTECTED]:
 Do you really think {{ }} appears in existing code, correctly
 enclosing statement blocks, with the {{ and the }} placed tightly
 together both at the beginning and at the end?
 
 Yes: I have seen the code like
 
 if (x) {
{
   code
}
 }
 
 Now pass through a JS compressor that removes redundant whitespace and
 you get precizelly {{ }}.
 
 In addition, those {{ can happen in a code generator.
 
 Regards, Igor
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss
 

How sad! It seemed such a simple and intuitive notation!

I think all of these would be unambiguous:

 {. code .}

 {: code :}

 {| code |}

 {[ code ]}

 [[ code ]]

 [ code ]

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-26 Thread Ingvar von Schoultz
Brendan Eich wrote:
 Waldemar meant precisely what he wrote: ES3 and draft ES3.1 -- the 
 specifications, not random JS implementations.

Oops, I got lost in details and strayed far away from the
point that I wanted to make. In fact I should have said
this from the beginning:

You can't get away from supporting this:

  {
  function a(){}
  var b = a;
  }

ES4 is planning to support function declarations locally
bound in blocks, so the above is valid ES4 code.

What you see above is function b() hoisting like var.

(I said b, not a.)

There is no far-too-complicated split-scope complexity. There
is no capturing of variables that haven't been declared yet.
It's simple, intuitive, well-defined and well-behaved.

The above is the /exact/ functionality of function hoisting
like var, apart from using two names. You can refuse the
clearer syntax, but you can't refuse the above code and
functionality.

In other words, complexity is not a problem. ES4 can easily
choose whatever semantics people prefer.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-26 Thread Ingvar von Schoultz
Sorry about the length of this, but I'm trying to cover the
unclear things, and often I don't know which things are unclear.

Brendan Eich wrote:
 On Jul 26, 2008, at 2:07 PM, Ingvar von Schoultz wrote:
 
 You can't get away from supporting this:

   {
   function a(){}
   var b = a;
   }

 ES4 is planning to support function declarations locally
 bound in blocks, so the above is valid ES4 code.

 What you see above is function b() hoisting like var.

 (I said b, not a.)
 
 What you said does not make sense.  It's true that var b is hoisted to
 the top of the program or function body. But it is not initialized  
 until control flows through the assignment b = a that is part of the  
 var declaration. So there is no capture problem.

That's my point! There isn't any capture problem. That's exactly
what I'm showing here. And, more importantly, you can't insert a
capture problem while keeping the structure intact. The arrangement
is inherently well-behaved.

I'm trying to show that you can support functions that hoist like
var in a well-behaving way, and that this is /not/ complicated.
And the snippet is intended as proof.

But perhaps I should interpret what you said somewhat differently.

The snippet, as shown here, does not have a capture problem.
But if you improve the hoisting carelessly, there's a threat
of a capture problem lurking within it. (That's assuming that
I understand capture problem correctly -- this is a rare
case of Wikipedia not explaining a computing term.)

Somebody might want to improve the hoisting by making it so
that the function is assigned (is callable) from before we enter
the global scope.

Let's assume, for the argument, that the above code magically
starts to behave that way. Then it will work fine as long as it
stays the same. But later the programmer might decide to add a
local variable:

 {
 function a(){}
 var b = a;
 let c = 3;
 }

c is now visible from inside a(), but exists only when we enter
the block. So in this situation a() must not be called before
we enter the block. The function must no longer be assigned
(callable) at the top of the global scope.

I would consider it extremely surprising semantics if I can call
a() above the block, but only before I add that local variable,
and this suddenly changes just because I add c. It's a huge change,
it's far away, and it's unrelated.

So for the sake of consistency and predictability we must assign
|undefined| whenever the code structure allows a capture problem
to be inserted as a side effect of doing something unrelated,
like adding |let c|.

That's why I said this, in the email where I first showed this
snippet:

,---
|  Assigning |undefined| is correct for any function whose
|  assignment depends on sequential code. The above is such a
|  sequential dependency, even though it may not look that way.
`---

It may not look sequential, but that's just because I left out
a lot of details, in an attempt to keep it as brief as ever
possible, to minimize any misunderstandings.

As you can see, in my opinion, what I'm saying does make perfect
sense!

The claim that just because of this limitation my proposal
doesn't work is in my opinion quite mistaken. I consider
this functionality fully acceptable. It's simple, understandable
and predictable. Sure it's a limitation, but a minor one. It's
/far/ better and more useful and intuitive than having functions
not hoisting out at all.

The usual use case will be an if() or some such. Then the
programmer fully expects the function to be available only
afterward. Very useful. Using it in a bare block like the
above will be unusual, but if used, the rules are simple.

 There is no far-too-complicated split-scope complexity. There
 is no capturing of variables that haven't been declared yet.
 It's simple, intuitive, well-defined and well-behaved.
 
 Thanks, I agree. But it is not what you proposed.

Sorry, I don't understand. What is not what I proposed, and
in which one of my proposals did I not propose it?

 Again, from  
 Waldemar's original reply, but with your proposed {{}} interpolated  
 and the elided code amended to say what the consequence is:
 
 // outer scope
 function c() ...;
 
 // inner scope
 {{
if (foo) {
  const c = 37;
}
... c in your proposal must be hoisted to the {{,
so it can't be function c -- yet it can't be
initialized to 37 if foo is falsy ...
 }}

Yes, c exists in the inner scope {{ }}. It exists there from
before you enter the scope and throughout. It shadows the outer
c() throughout. If foo is false, the constant c is never initialized.

 You could reply that const is new (sort of -- two browsers already  
 implement it one way, another treats it as var) and therefore should  
 always scope to { or {{, whichever is closer. But the point stands if  
 you replace const with function or var and hoist to the {{.

Which point? Forgive me, I didn't see any point. I

Re: function hoisting like var

2008-07-25 Thread Ingvar von Schoultz


Igor Bukanov wrote:
 I guess that proposal can be summarized in a very short form:
 
 make
 
   {{ code }}
 
 a syntax sugar for
 
   (function() { code })()

Indeed you're right.

When I proposed {{ }} my intent was simplicity, but I didn't
realize that implementing it could be made that simple, the
change that small.

By the way, your translation

 (function() { code })()

can also be expressed as

 new function() { code }

Less parentheses!

(But I haven't explored possible drawbacks.)

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-25 Thread Ingvar von Schoultz
Igor Bukanov wrote:
 Of cause, if desired, such shortcut should be
 pure syntax extension over ES3, not {{ }} as that silently changes the
 meaning of the existing code.

Do you really think {{ }} appears in existing code, correctly
enclosing statement blocks, with the {{ and the }} placed tightly
together both at the beginning and at the end?

I find this somewhat unlikely, since it's a redundant repetition
that means exactly the same as { }.

Ingvar



Igor Bukanov wrote:
 2008/7/25 Lars Hansen [EMAIL PROTECTED]:
 Is

  {{ return }}

 syntactic sugar for

  (function() {{ return }})()

 too?
 
 I have forgot about the return or break/continue. But this is not a
 point since a syntax sugar for (function() { code })() can require
 that code must not contain return or break/continue outside the code
 effectively making it a let expression on steroids. The point is that
 is it worth to provide a shortcut for (function() { code })() since
 that is used on web. Of cause, if desired, such shortcut should be
 pure syntax extension over ES3, not {{ }} as that silently changes the
 meaning of the existing code.
 
 One way to get that extension comes from an observation that ES4
 allows to drop the  braces around function body and the return keyword
 if the body is the single return exp. If ES3.1 would support it, then
 to simulate an effect of let expression like
 
   let (a = arg1, b = arg2) expression
 
 one could write
 
   (function(a, b) expression)(arg1, arg2)
 
 or
 
   (function(a, b) a = arg1, b = arg2, expression)()
 
 If, in addition to this shortcut, ES4 would allow to drop an empty
 argument list from a function with a requirement that function { }
 always means an expression and ES3.1 would also support that, then in
 place of a block with let variables one can write:
 
 function {
 
 }();
 
 Regards, Igor
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss
 

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: function hoisting like var

2008-07-25 Thread Ingvar von Schoultz
[EMAIL PROTECTED] wrote:
 Ingvar von Schoultz wrote:
 [EMAIL PROTECTED] wrote:
 I'm trying to keep the language relatively simple.
 You can't get away from supporting this:

 {
 function a(){}
 var b = a;
 }
 
 What do you mean?  This is a syntax error in both ES3 and ES3.1.

It works fine in Firefox 2, Konqueror 3, Opera 9, Internet
Explorer 6, and server-side Rhino with JavaScript 1.6.

Five platforms out of five. Can you throw a syntax error here
and claim to be compatible?

You can test it in browsers at http://test-a-1.appjet.net/

Below is a more detailed example that also includes let. It
uses JavaScript 1.7 and works in Firefox 2. You can test it
at http://test-a-2.appjet.net/

 alert (b);
 {
 function a(){}
 var b = a;
 let c = 3;
 alert (c);
 }
 alert (b);
 alert (typeof c);

 On the contrary, the functionality already exists, as shown
 above.
 
 It does not already exist in ES3 or ES3.1.

It exists on platforms as described above. I assumed that ES4
would be compatible.

 Keep in mind that function assignments hoist to the beginning of the
 scope
 in which the function is defined, so your proposal won't work.
 When the programmer explicitly says that the assignment depends
 on sequential code, then do what the programmer says. Anything
 else is an error. Do it by assigning |undefined| before scope
 entry. This is the only correct thing to do.
 
 I don't understand.

In all normal cases the function is assigned at the beginning
of the scope. However, there are some special cases where this
would be an incorrect interpretation of the source code.

If the programmer clearly says that the assignment is /unknown/
at the beginning of the scope, then assigning prematurely would
be wrong.

For example, the programmer might say:

 if (Math.random()  0.5)
 function f() {return 1}
 else
 function f() {return 2}

Implementations vary here, but let's assume that it is defined
to mean what it says.

Then f will be assigned either the first or the second body,
depending on the random number. This decision comes /after/
you enter the scope. The assignment depends on something that
happens /inside/ the scope. Therefore, here the programmer
is saying quite clearly that the assignment is /unknown/ at
the beginning of the scope.

It would be wrong for the compiler to guess. The solution is
to assign |undefined| at the beginning of the scope.

This situation is unusual. It happens only when the programmer
says that the assignment is unknown at the beginning of the
scope, as above.

 The function /body/ stays where it is. The hoisting doesn't
 affect it in any way. Moving the body would change its context
 and meaning catastrophically. Don't touch it.
 
 That doesn't answer the question.  The problem is that the body can
 capture variables that haven't been declared yet.

With suitable arrangements this becomes impossible.

Of course if you /insist/ on setting everything up and assigning
to the function name before the body's context exists, then you
can't expect it to work. Then you get an incorrect program that
will act as you say. That's to be expected if you allow calling
a function whose context doesn't exist.

But if you accept that when the context doesn't exist you should
assign |undefined| at the beginning of the scope, and only assign
the body later, when its context does exist, then you get a well-
defined and well-behaved program.

Then any premature call to the function will throw an error as
a call to undefined(). This will work in ways that the programmer
can understand well.

As far as I can tell, this is correct by definition. Can you find
an example where it breaks?

 The /name/ becomes a var. Treat it like any other var. Hoist
 it and assign |undefined|, exactly like you do with other vars.
 
 That's incompatible with how functions are defined in ES3.

Incompatible? Your comment on my tiny two-line program says
that you want to throw a syntax error in these cases. Breaking
five platforms out of five is less compatible than what I
describe.

It certainly doesn't break JavaScript 1.7 in Firefox. It's
almost exactly what Firefox does in this special situation.

According to at least one discussion in the ES3.1 archives,
ES3 does not specify how you should treat a function in this
special situation. Here's one of these comments:
https://mail.mozilla.org/pipermail/es4-discuss/2008-July/003142.html

 Are you saying that because this var is related to a function
 it can't be treated like other vars? Is this var fundamentally
 different from other vars? At least above it isn't.
 
 Huh?  Do you understand how ES3 works?

Yes, I know it quite well. I've been using JavaScript near
full-time on the client since Netscape 3, and on both server
and client since Microsoft ASP with JScript first appeared.

But why do you refer to ES3? ES3 doesn't have any scoping
blocks with var hoisting out of them.

Could you

function hoisting like var -- Was: Re: Surprising semantics

2008-07-24 Thread Ingvar von Schoultz
[EMAIL PROTECTED] wrote:
 I'm trying to keep the language relatively simple. 

You can't get away from supporting this:

 {
 function a(){}
 var b = a;
 }

What you see above is function b() hoisting like var. This
is the /exact/ functionality, apart from using two names.
You can refuse the clearer syntax, but you can't refuse
the above code and functionality.

b is bound to the global scope and assigned |undefined|
before you enter the global scope.

Assigning |undefined| is correct for any function whose
assignment depends on sequential code. The above is such a
sequential dependency, even though it may not look that way.

 What you're proposing
 is far too complicated.

On the contrary, the functionality already exists, as shown
above.

 Keep in mind that function assignments hoist to the beginning of the scope
 in which the function is defined, so your proposal won't work. 

When the programmer explicitly says that the assignment depends
on sequential code, then do what the programmer says. Anything
else is an error. Do it by assigning |undefined| before scope
entry. This is the only correct thing to do.

 You're
 trying to do a complex split-scope approach where each function definition
 has *two* scopes, one in which it is declared and one in which it is
 defined, but even that won't work with const, typed functions and
 variables, etc. 

Are you saying that the function /body/ gets into trouble,
or the function /name/?

The function /body/ stays where it is. The hoisting doesn't
affect it in any way. Moving the body would change its context
and meaning catastrophically. Don't touch it.

The /name/ becomes a var. Treat it like any other var. Hoist
it and assign |undefined|, exactly like you do with other vars.

Are you saying that because this var is related to a function
it can't be treated like other vars? Is this var fundamentally
different from other vars? At least above it isn't.

Or is the problem in the type declarations? Are datatypes of
vars and functions fundamentally different?

Or is it because functions have parameters? You're not saying
anything about parameters, so if that's the problem you're
being very vague indeed.

 See my previous email as to why. 

That email is about some wildly unworkable dynamic scoping.
It has nothing to do with anything I ever said. You jumped
to that conclusion.

Please stop insisting that I'm proposing that nonsense. I'm
not. I never did.

 You'd then have to
 introduce extra rules about some definitions only being possible within
 {{}} blocks, which would then affect the behavior of existing definitions
 like var if one of the other definitions within the same block was a const
 or function, which would snowball into a complex mess.

Unrelated, I believe.

Ingvar



 Ingvar von Schoultz wrote:
 I'm astonished that you interpreted my text in such a weird
 way! That's completely foreign to JavaScript!

 var is always unconditional in JavaScript. An if() before a
 declaration doesn't make the declaration conditional.

 The var takes effect long before you reach that if(). It takes
 effect before you enter the scope in which the variable resides.
 You can consider the declaration glued to the opening brace of
 that scope. Or better, glued to both braces and stretched between
 them.

 The assignment, on the other hand, stays in place and is
 conditional. But only the assignment.

 With your surprising interpretation things would be much worse
 than what your examples suggest. Much worse. Consider assigning
 to the unpredictable variable:

 function Outer()
 {
 var Test = 1;
 function Inner()
 {
 if (Unknown)
 var Test = 2; // Weird conditional declaration
 // Many
 // lines
 // of
 // code
 Test = 3;  // Semantics totally unpredictable
 }
 }

 Is the outer Test set to three, or has an inner Test been
 created that can take the value? Every program would become
 impossible to understand, an unintelligible mess.

 With my subject line surprising semantics I didn't mean to
 advocate more surprises, I wanted less!

 I assumed that ES3.1 and ES4 declarations would work like
 ES3 declarations do: The declaration spans the entire scope
 from before you enter the scope and throughout. The value
 is unassigned (undefined) until you reach an assignment.

 I took it for granted that making it constant and/or giving it
 a type would follow the same pattern. The name gets associated
 with the constantness and/or type before you enter the scope,
 and it's in effect throughout.

 In your examples with dual scopes, the result depends on whether
 you mean that the inner c is bound to the outer scope or the
 inner. If it's the outer you have conflicting, irreconcilable
 bindings that collide before you enter that outer scope, a clear
 declaration error. If it's the inner, then the inner declaration
 shadows the outer, so

{{ ... }} -- Was: Re: Surprising semantics

2008-07-22 Thread Ingvar von Schoultz
With {{ }} there are only let declarations. Var becomes let.
Hoisting to higher scopes disappears completely. The language
only supports let.

There is only one type of scope. This is the {{ }} scope.
Everything resides in a {{ }} scope, let-declared there.

When this is enabled, { } serve only to show which statements
are affected by an if(), for() etc. They have nothing at all
to do with any scoping. They don't affect any declaration in
any way whatsoever. Regarding declarations, please consider
the { } nonexistent.

For scoping, {{ }} completely replaces { }.

[EMAIL PROTECTED] wrote:
 I'm trying to keep the language relatively simple.

I agree wholeheartedly about simplicity.

  What you're proposing
 is far too complicated.

Apparently my explanations have been complicated and confusing.

 Keep in mind that function assignments hoist to the beginning of the scope
 in which the function is defined,

Yes, at the {{.

 so your proposal won't work.  You're
 trying to do a complex split-scope approach where each function definition
 has *two* scopes, one in which it is declared and one in which it is
 defined, but even that won't work with const, typed functions and
 variables, etc.

Is this about {{ }}? If so, I suppose you agree that the problem
does not appear when every declaration is a let declaration.

  See my previous email as to why.  You'd then have to
 introduce extra rules about some definitions only being possible within
 {{}} blocks, which would then affect the behavior of existing definitions
 like var if one of the other definitions within the same block was a const
 or function, which would snowball into a complex mess.

You're mixing different problems that can never appear together.

The proposal that function hoist like var is completely unrelated
to {{ }}. It doesn't apply when you use {{ }} and everything becomes
let.

I'll reply about that in a separate email. And to avoid the above
mixing and confusion, I'll put it aside for a while. Let's reduce
the confusion.

Ingvar



 Ingvar von Schoultz wrote:
 I'm astonished that you interpreted my text in such a weird
 way! That's completely foreign to JavaScript!

 var is always unconditional in JavaScript. An if() before a
 declaration doesn't make the declaration conditional.

 The var takes effect long before you reach that if(). It takes
 effect before you enter the scope in which the variable resides.
 You can consider the declaration glued to the opening brace of
 that scope. Or better, glued to both braces and stretched between
 them.

 The assignment, on the other hand, stays in place and is
 conditional. But only the assignment.

 With your surprising interpretation things would be much worse
 than what your examples suggest. Much worse. Consider assigning
 to the unpredictable variable:

 function Outer()
 {
 var Test = 1;
 function Inner()
 {
 if (Unknown)
 var Test = 2; // Weird conditional declaration
 // Many
 // lines
 // of
 // code
 Test = 3;  // Semantics totally unpredictable
 }
 }

 Is the outer Test set to three, or has an inner Test been
 created that can take the value? Every program would become
 impossible to understand, an unintelligible mess.

 With my subject line surprising semantics I didn't mean to
 advocate more surprises, I wanted less!

 I assumed that ES3.1 and ES4 declarations would work like
 ES3 declarations do: The declaration spans the entire scope
 from before you enter the scope and throughout. The value
 is unassigned (undefined) until you reach an assignment.

 I took it for granted that making it constant and/or giving it
 a type would follow the same pattern. The name gets associated
 with the constantness and/or type before you enter the scope,
 and it's in effect throughout.

 In your examples with dual scopes, the result depends on whether
 you mean that the inner c is bound to the outer scope or the
 inner. If it's the outer you have conflicting, irreconcilable
 bindings that collide before you enter that outer scope, a clear
 declaration error. If it's the inner, then the inner declaration
 shadows the outer, so the value can be unassigned or 37.

 Regarding the plethora of ways to define things, by including
 or excluding let you simply change which one of two possible
 scope opening braces the declaration is glued to for the purpose
 of name visibility. You get the same effect if you just move the
 declaration to that spot yourself, without moving the assignment.
 By including or excluding let you're simply telling the compiler
 where you want this move to go.

 Ingvar



 Waldemar Horwat wrote:
 We've been down this road before, and the arguments you present have
 been hashed out over years.  This approach doesn't work.  Read the
 archives of the ES4 group.

 The problem is that you then get a plethora of ways to define things:

 var
 const
 function
 type

Re: Opt-in versioning

2008-07-21 Thread Ingvar von Schoultz
Michael Haufe wrote:
 The entire concept of {{ ... }} irks me, and probably quite a few 
 others. This would add a level of syntax complexity and confusion 
 non-intuitive to most developers.
 
 Object literal {{ foo : bar}}?
 
 function(){{...}} ?
 
 if(){{
 ...
 }}
 else {{
 ...
 }}
 
 switch()? with()? Imagine JSON with these rules. thats abhorrent. I 
 understand the concern with scoping but this would be too far of a shift 
 to be considered I would hope.

They'd be entirely optional. If you prefer to use single braces
throughout your file, no problem, do that. Then you have the
complicated rules and hidden semantics to deal with, but if
you prefer that to the double braces it'll work just fine.

The double braces are for people who want simplicity and regularity.

I'm surprised that you think they'll be confusing. They have
just one very simple, clear, specific meaning: Enclose variables.
Everybody knows about enclosing variables. As I see it they
remove confusion.

You'd use double braces only when you want to enclose variables
locally. When you have no local variables there's no need:

 if
 {{  local variables
 }}

 if
 {   no local variables
 }

If you seldom enclose local variables you'll seldom need
the doubling, even if you choose to enable it.

An object literal wouldn't use double braces because it isn't
a scoping block (it doesn't enclose local variables). JSON
doesn't have any scoping blocks.

I you find the doubling abhorrent, do you find this more
palatable?

 if
 {   local stuff
 }

 if
 [   no local stuff
 ]

This would require good syntax coloring. It wouldn't work in
old browsers. Personally I prefer the double braces.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: Surprising semantics

2008-07-21 Thread Ingvar von Schoultz
 |undefined|. Any call
throws an error. Only deep down among the nested blocks is Fn
assigned the function object. This happens at the spot where
the programmer wrote the declaration-and-definition (or, more
precisely, shortly before entry into that block). Like this:

 var Fn;   // Automatically assigned the value |undefined|.
 Fn();
 if (Unknown)
 {   let LetVal = 3;
 if (Maybe)
 {   Fn = function Fn()
 {   return LetVal;
 }
 }
 }

As far as I can see, any attempt to call Fn at any point in time
when LetVal doesn't exist will fail as a call to undefined(). And
at any point in time where the value of Fn is a function object,
Fn will have access to an existing LetVal.

I don't know if I've missed something. Maybe the problem is in a
different program structure. I'd be very interested to know.

 for (i = 0; i  foo.length; i++) {
   const v = foo[i];
 }
 
 You'll catch everyone off-guard if you make folks do a
 let const instead of a const here.

What does this mean? (English isn't my first language.) Are you
saying that everyone will forget to type let?

On the contrary, that can only happen to those who are not used
to JavaScript. And of course also to those who feel so uncomfortable
with the scoping rules of JavaScript that they have to put all
their var declarations out in the function block. This of course
perpetuates their difficulties.

But for us real javascripters, who fully embrace and enjoy its
scoping, and put our var declarations anywhere and everywhere,
the above is very, very obviously a repeated assignment to
one and the same v. That const before it leaps out at you as
a contradiction. Really, there's no way at all that you can
miss it.

Your solution will only trip up us real javascripters. It will
cater only to those who can't or won't embrace the language for
real. But their problem is temporary. Catering to them by creating
complicated oddities makes the language permanently complicated.

For them it's just a simple detail to learn, the meaning of the
JavaScript brace. A single really simple detail, versus a complicated
set of oddities and hidden semantics.

There may be other reasons to infest the language with complications,
but the short-lived minor effort for some people to learn one detail
is not one of them.

Ingvar



Waldemar Horwat wrote:
 We've been down this road before, and the arguments you present have been 
 hashed out over years.  This approach doesn't work.  Read the archives of the 
 ES4 group.
 
 The problem is that you then get a plethora of ways to define things:
 
 var
 const
 function
 type
 namespace
 let
 let const
 let function
 let type
 let namespace
 
 Furthermore, some of them don't make sense (such as function without let) 
 because they can conditionally capture variables that may not even exist.
 
 The example you give of conditional definitions:
 
 if (foo) {
   const c = 37;
 } else {
   const c = abc;
 }
 ... do something with c ...
 
 is particularly disruptive.  You must then support conditional holes:
 
 // outer scope
 function c() ...;
 
 // inner scope
 {
   if (foo) {
 const c = 37;
   }
   ... c can be either 37 or the outer scope function here ...
 }
 
 
 It gets worse:
 
 // outer scope
 function c() ...;
 
 // inner scope
 {
   function f() {
 return c;
   }
   a = f();
   if (foo) {
 const c = 37;
   }
   b = f();
   ... just what do a and b hold here?  Was f's captured variable rebound by 
 the if statement? ...
 }
 
 
 Also consider:
 
 for (i = 0; i  foo.length; i++) {
   const v = foo[i];
 }
 
 You'll catch everyone off-guard if you make folks do a let const instead of a 
 const here.
 
 
 In E4 it gets worse still because c can have a type:
 
 type c = ...
 {
   if (foo) {
 const c:Number = 37;
   } else if (bar) {
 var c:String = abc;
   }
 }
 ... do something with c, which is either a type, a constant, or a variable, 
 and can be statically typed as either a Number or a String ...
 
 const d:c = ... // Conditional definition requires variable types to be 
 evaluated at run-time, which is not somewhere we want to go in the first 
 version
 
 I don't know of anyone here who wants to support something like that.
 
 Waldemar
 
 
 Ingvar von Schoultz wrote:
 These are some impressions looking at what I expect from the
 language, and how some things in the specification can cause
 confusion.

 I would have contributed here during the discussions, but I
 discovered the mailing lists just a couple of days ago.

 I expect the compiler's interpretation of program-code text
 to be close to my intuitive understanding of what the text
 says. It's very unfortunate if keywords have unexpected
 meanings that cause mysterious side effects.

 If I learn that ECMAScript will let me change my var(iables)
 into const(ants) I expect this to turn them into constants, in
 the sense that trying to change their value will be considered
 an error. It's very disappointing

Re: Surprising semantics

2008-07-19 Thread Ingvar von Schoultz
I'm astonished that you interpreted my text in such a weird
way! That's completely foreign to JavaScript!

var is always unconditional in JavaScript. An if() before a
declaration doesn't make the declaration conditional.

The var takes effect long before you reach that if(). It takes
effect before you enter the scope in which the variable resides.
You can consider the declaration glued to the opening brace of
that scope. Or better, glued to both braces and stretched between
them.

The assignment, on the other hand, stays in place and is
conditional. But only the assignment.

With your surprising interpretation things would be much worse
than what your examples suggest. Much worse. Consider assigning
to the unpredictable variable:

 function Outer()
 {
 var Test = 1;
 function Inner()
 {
 if (Unknown)
 var Test = 2; // Weird conditional declaration
 // Many
 // lines
 // of
 // code
 Test = 3;  // Semantics totally unpredictable
 }
 }

Is the outer Test set to three, or has an inner Test been
created that can take the value? Every program would become
impossible to understand, an unintelligible mess.

With my subject line surprising semantics I didn't mean to
advocate more surprises, I wanted less!

I assumed that ES3.1 and ES4 declarations would work like
ES3 declarations do: The declaration spans the entire scope
from before you enter the scope and throughout. The value
is unassigned (undefined) until you reach an assignment.

I took it for granted that making it constant and/or giving it
a type would follow the same pattern. The name gets associated
with the constantness and/or type before you enter the scope,
and it's in effect throughout.

In your examples with dual scopes, the result depends on whether
you mean that the inner c is bound to the outer scope or the
inner. If it's the outer you have conflicting, irreconcilable
bindings that collide before you enter that outer scope, a clear
declaration error. If it's the inner, then the inner declaration
shadows the outer, so the value can be unassigned or 37.

Regarding the plethora of ways to define things, by including
or excluding let you simply change which one of two possible
scope opening braces the declaration is glued to for the purpose
of name visibility. You get the same effect if you just move the
declaration to that spot yourself, without moving the assignment.
By including or excluding let you're simply telling the compiler
where you want this move to go.

Ingvar



Waldemar Horwat wrote:
 We've been down this road before, and the arguments you present have been 
 hashed out over years.  This approach doesn't work.  Read the archives of the 
 ES4 group.
 
 The problem is that you then get a plethora of ways to define things:
 
 var
 const
 function
 type
 namespace
 let
 let const
 let function
 let type
 let namespace
 
 Furthermore, some of them don't make sense (such as function without let) 
 because they can conditionally capture variables that may not even exist.
 
 The example you give of conditional definitions:
 
 if (foo) {
   const c = 37;
 } else {
   const c = abc;
 }
 ... do something with c ...
 
 is particularly disruptive.  You must then support conditional holes:
 
 // outer scope
 function c() ...;
 
 // inner scope
 {
   if (foo) {
 const c = 37;
   }
   ... c can be either 37 or the outer scope function here ...
 }
 
 
 It gets worse:
 
 // outer scope
 function c() ...;
 
 // inner scope
 {
   function f() {
 return c;
   }
   a = f();
   if (foo) {
 const c = 37;
   }
   b = f();
   ... just what do a and b hold here?  Was f's captured variable rebound by 
 the if statement? ...
 }
 
 
 Also consider:
 
 for (i = 0; i  foo.length; i++) {
   const v = foo[i];
 }
 
 You'll catch everyone off-guard if you make folks do a let const instead of a 
 const here.
 
 
 In E4 it gets worse still because c can have a type:
 
 type c = ...
 {
   if (foo) {
 const c:Number = 37;
   } else if (bar) {
 var c:String = abc;
   }
 }
 ... do something with c, which is either a type, a constant, or a variable, 
 and can be statically typed as either a Number or a String ...
 
 const d:c = ... // Conditional definition requires variable types to be 
 evaluated at run-time, which is not somewhere we want to go in the first 
 version
 
 I don't know of anyone here who wants to support something like that.
 
 Waldemar
 
 
 Ingvar von Schoultz wrote:
 These are some impressions looking at what I expect from the
 language, and how some things in the specification can cause
 confusion.

 I would have contributed here during the discussions, but I
 discovered the mailing lists just a couple of days ago.

 I expect the compiler's interpretation of program-code text
 to be close to my intuitive understanding of what the text
 says. It's very unfortunate if keywords have unexpected
 meanings

Re: Opt-in versioning

2008-07-19 Thread Ingvar von Schoultz
 understood it was for IE to be handled via scripted 
 user-agent sniffing, presumably controlling document.write or DOM 
 creation of script src= loading the const-ful or const-less code (or 
 possibly eval, but eval does not scale). This is opt-in versioning by 
 another name (the page author still has to opt and control script src, 
 if not script type), and it's a bad idea to boot. User agent string 
 contents are hard enough to parse, and overloaded for too many 
 content-negotiation purposes already.
 
 My hope in this follow-up is twofold:
 
 * To highlight the need for opt-in versioning to clean up and evolve the 
 language beyond certain points where it otherwise gets stuck.
 
 * To point out that script content type depends on in-page type 
 selection mechanism, relieving the worry that was expressed recently 
 during an ES3.1 conference call about server file-suffix-to-MIME-type 
 mis-configuration.
 
 There are other possible ways to select version, including use version 
 N pragma-strings. We haven't talked much about these, but they can be 
 considered if their effects can be committed before the rest of the 
 source following such a pragma is parsed. In light of all the possible 
 ways before us, and the precedent in Mozilla for JS script types, the 
 conclusion that opt-in versioning is infeasible or impractical needs to 
 be demonstrated, not assumed.
 
 /be
 
 
 
 
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES3.1 Object static methods rationale document

2008-07-18 Thread Ingvar von Schoultz

Allen Wirfs-Brock wrote:
 Object.create's heritage is Doug Crockford's beget function and its primary 
 purpose is to provide a more direct way to create an object with an 
 explicitly specified prototype.

I think the name Object.createHeir would clarify its use better.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES3.1 Object static methods rationale document

2008-07-17 Thread Ingvar von Schoultz
 thing we did
 not include, it would be quite a long document. What is the argument for
 adding Object.extend()? A pointer to Resig's message or a prior discussion
 is an adequate response.

 --
 Cheers,
 --MarkM
 ___
 Es3.x-discuss mailing list
 [EMAIL PROTECTED]
 https://mail.mozilla.org/listinfo/es3.x-discuss

 
 
 
 --
 
 Robert Sayre
 
 I would have written a shorter letter, but I did not have the time.
 ___
 Es3.x-discuss mailing list
 [EMAIL PROTECTED]
 https://mail.mozilla.org/listinfo/es3.x-discuss
 
 ___
 Es3.x-discuss mailing list
 [EMAIL PROTECTED]
 https://mail.mozilla.org/listinfo/es3.x-discuss
 ___
 Es3.x-discuss mailing list
 [EMAIL PROTECTED]
 https://mail.mozilla.org/listinfo/es3.x-discuss
 

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Surprising semantics

2008-07-17 Thread Ingvar von Schoultz
construct would make it simpler and easier to learn, but
if it's built this way it becomes conceptually clear, free
of hidden intricacies, easy to explain. The delimiters
{{ and }} suggest that you are walling things in with thicker
walls, so that hoisting can't get past. Nicely intuitive.
Especially for programmers who put braces at left it becomes
very clear indeed. And I'm sure syntax-coloring editors will
help making the scoping clear at a glance.

The terminology might distinguish between the two types of
block by talking about strong and weak blocks, where strong
means thick walls that you can't hoist out of, and weak means
that the block can only capture things that are marked local
(or let), and everything else gets hoisted out.

In fact I think a terminology with strong versus weak blocks
is clearer than the current terminology, where one type of
block is called block and the other is called variable object.

I'm sorry if this comes across as a series of complaints. All
in all I'm delighted with the many enticing improvements! But
listing all the nice things here wouldn't make for interesting
reading. And so it may sound much more negative than my overall
delighted and enthusiastic feelings.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)

___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


A read/write __proto__ that can vanish

2008-07-16 Thread Ingvar von Schoultz
Some people yearn hotly for __proto__, preferrably writable if
at all possible, while others point to problems with security
and software privacy.

I get the impression that this could be solved by adding a fourth
flag among the property flags Enumerable, Writable and Flexible.
There might be a flag called Visible, so you could make __proto__
apparently vanish by setting Visible to false.

As an added bonus, this solution would let code hide the prototype
property on constructors if desired.

Personally I'd love to see it defined in such a way that I could
set prototype inheritance in a simple, straightforward way at the
beginning of a constructor function:

 function $MyConstructor()
 {  this.proto = MySuperInstance;
 // Here you can hide proto if desired.
 ...
 }

If a visible proto is standardized, the name should be proto, not
__proto__, in my opinion. The underscores indicate nonstandard.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES3.1 Object static methods rationale document

2008-07-16 Thread Ingvar von Schoultz
Brendan Eich wrote:
 That was unclear, sorry. I meant to suggest that lookupProperty is  
 a shorter alternative to getPropertyDescriptor. Using lookup or  
 query relieves the need for Descriptor at the end to disambiguate  
 value- from descriptor-getting. So:

I find inspectProperty() a little more descriptive and intuitive.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: A read/write __proto__ that can vanish

2008-07-16 Thread Ingvar von Schoultz
Brendan Eich wrote:
 There's no point in Visible if the property could be deleted  
 altogether. What would be the difference?

Oops! Sorry! Lacking low-level insight I didn't think of that.

So my idea has no bearing at all on the inherent problems, much
less solved them. Too bad.

 That's not this __proto__ case, which anyway  
 depends on a suspect predicate (the need for __proto__). Better to  
 settle the predicate issue first, and avoid adding general mechanism  
 prematurely.

I think the only situation where I repeatedly feel a real,
serious need for something like a writable __proto__ is
the one I showed. Specifying inheritance is too spread out
and too intricate. Most of all I want the constructor to
define its own inheritance, not some outside code. Having
to set .prototype in an unrelated expression outside, with
the constructor reduced to a powerless bystander, feels like
I'm writing a goto. It's too unstructured.

Is your objection to __proto__ similar to this? Is __proto__
an inheritance goto? If that's the kind of problem it creates
I agree that it doesn't belong in this language.

If that's the case, would a writable __proto__ become well-
structured if it could be accessed only from inside the
constructor, and not by any other code? That's the only
way I'd use it anyway.

I'd love to have constructors that could write to their
[[Prototype]]. But if that isn't possible I'd be almost
as happy if we simply had the option to set both the
prototype and its constructor property in one compound
statement:

 function $MyConstructor()
 prototype MySuperInstance
 {  ...
 }

For me this would generally be the best arrangement, and
I suppose it's the same for most people. Not having analyzed
all the details, it /seems/ to me that the ideal would be
that the above syntax lock and hide [[Prototype]], while a
different syntax for exotic use would allow the constructor
added freedom.

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: ES3.1 Object static methods rationale document

2008-07-16 Thread Ingvar von Schoultz
Although I agree that brevity isn't very important here, still
here's a shorter variation on the same names:

 Object.getDescriptor (MyObject, MyName);

 Object.setDescriptor (MyObject, MyName, {enumerable: false});

Ingvar



Maciej Stachowiak wrote:
 On Jul 16, 2008, at 2:36 PM, Allen Wirfs-Brock wrote:
 
 Just wait, reify may yet end up as the last name standing...
 
 Methods don't reify things, the language definition does. Property  
 descriptors are reified in ES3.1 whether or not you ever call the  
 method.
 
 I think getPropertyDescriptor is the best name suggested so far, it  
 has no chance of being confused for a method that would get the  
 property value, and it does not use obscure CS jargon in an incorrect  
 way. I don't think brevity is critical for these metaprogramming/ 
 reflection type methods - they are not the kind of thing that will be  
 commonly used by most programmers. Mostly they will be used by  
 frameworks such as Ajax libraries or secure language subsets.
 
 Regards,
 Maciej
 

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 
 ] On Behalf Of Brendan Eich
 Sent: Wednesday, July 16, 2008 2:27 PM
 To: David Flanagan
 Cc: es4-discuss@mozilla.org es4-discuss
 Subject: Re: ES3.1 Object static methods rationale document

 On Jul 16, 2008, at 1:41 PM, David Flanagan wrote:

 Brendan, I think you were correct when you originally wrote:

 lookup : define :: get : put.
 I think that lookupProperty is much nicer than describeProperty,  
 since
 lookup captures the getter nature of the method in a way that
 describe does not.

 Connotations are many, ambiguity without a noun phrase (not just
 overloaded old property) saying what's being got or described
 or looked up is inevitable. This means the stolid, safe name
 getPropertyDescriptor is least likely to confuse.

 I see what you mean about describe in the context of setting a
 description (depict in a graphics context is problematic too) --
 thanks. Thesaurus doesn't include mental concept filtering, dammit.
 I'm sure we'll get this right, but I'm also pretty sure getProperty
 isn't the droid we are seeking.

 /be
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss

 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss
 
 ___
 Es4-discuss mailing list
 Es4-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es4-discuss
 

-- 
Ingvar von Schoultz

--- (My quirky use of capitals in code comes from my opinion that
reserved and predefined words should all start with lowercase, and
user-defined should all start with uppercase, because this will easily
and elegantly prevent a host of name-collision problems when things
like programming languages are upgraded with new labels.)
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss