From: VK on
On Jun 26, 10:22 pm, VK <schools_r...(a)yahoo.com> wrote:
> Upcasting and downcasting in JavaScript never were throughoutly
> documented anywhere, it is a historical inheritance thing in the most
> of its parts. A good sample is the implicit upcasting/downcasting of
> string primitives like
>  var s = 'abc';
>  var l = s.length // here
> and the "helper" for number primitives like
>  var n = 2;
>  window.alert( (n).toString(2) ); // here - no parenthesis for n =
> error
>
> One need to go to Netscape developers archives via wayback machine,
> somewhere there I presume. Don't want to spend the week-end on that
> really. Yet I didn't say "no".

OK, at the first glance the situation is rather funny: for 14 years
the original Netscape note for NN 2.0b pre-release was reproduced by
anyone:

<g>
All unary operators, such as the ! operator, evaluate expressions as
follows:
* If applied to undefined or null expressions, a run-time error is
raised.
* Objects are converted to strings.
* Strings are converted to numbers if possible. If not, a run-time
error is raised.
* Boolean values are treated as numbers (0 if false, 1 if true).
</g>

No one seem ever bothered to check that 95% of it is a complete bs. I
guess it was earlier thoughts for LiveScript, but it for the release
the potential amount of run-time errors was realized and all that
silliness replaced by introducing Boolean object and the implicit
upcasting/downcasting.

So the question is not to find some docs as they never were written
but to write for the first time ever upcasting/downcasting algorithm
for logical operations as it is.



From: Stefan Weiss on
On 26/06/10 20:46, VK wrote:
> On Jun 26, 10:22 pm, VK <schools_r...(a)yahoo.com> wrote:
>> Upcasting and downcasting in JavaScript never were throughoutly
>> documented anywhere, it is a historical inheritance thing in the most
>> of its parts. A good sample is the implicit upcasting/downcasting of
>> string primitives like
>> var s = 'abc';
>> var l = s.length // here
>> and the "helper" for number primitives like
>> var n = 2;
>> window.alert( (n).toString(2) ); // here - no parenthesis for n =
>> error

There's no error if you omit the parentheses around n. You may be
confusing that with something like (2).toString().

Anyway, that's not what I was talking about. In your example, there's a
reason why an object should be created: you want to access one of its
methods or properties. Even so, the object could potentially be
optimized away by a script engine, but at least the behavior is
described in terms of objects (yes, in the "mysterious" ECMAScript
specs), and the code looks as if there was an object. The same is not
true for the logical NOT operator. There's no mention of objects in the
specs, and the syntax doesn't suggest objects, either. You insist that
there's an Boolean object hidden in there somewhere, and that this
"correlates with the experimental results down to NN 2.02". How can you
experimentally test and confirm something which is never directly
accessible to you?
(unless you plan on building a Large Object Collider in Switzerland)

>> One need to go to Netscape developers archives via wayback machine,
>> somewhere there I presume. Don't want to spend the week-end on that
>> really. Yet I didn't say "no".
>
> OK, at the first glance the situation is rather funny: for 14 years
> the original Netscape note for NN 2.0b pre-release was reproduced by
> anyone:

I admire your archeological talent, but I'm not sure why you're digging
around in pre-release documents for Navigator 2. The language has
evolved quite a bit since then, and so have the script engines. Even if
NN 2 did create Boolean objects to evaluate an expression like !x (which
I still don't believe), is that really relevant today?

> <g>
> All unary operators, such as the ! operator, evaluate expressions as
> follows:
> * If applied to undefined or null expressions, a run-time error is
> raised.
> * Objects are converted to strings.
> * Strings are converted to numbers if possible. If not, a run-time
> error is raised.
> * Boolean values are treated as numbers (0 if false, 1 if true).
> </g>

That appears to be a quote from Microsoft's JScript documentation, not a
Netscape document.

> So the question is not to find some docs as they never were written
> but to write for the first time ever upcasting/downcasting algorithm
> for logical operations as it is.

Not for me. What I'm saying is that in order to evaluate a logical NOT,
there's no need to create a Boolean object, get its value, and destroy
it immediately afterwards. You claim that this is exactly what happens
in JavaScript. The SpiderMonkey source is open; show me the code.
Oh, alright - if you can dig it up in the NN2 sources, I'll accept that
as proof, too. Deal?


--
stefan
From: Lasse Reichstein Nielsen on
VK <schools_ring(a)yahoo.com> writes:

> Right.
> window.alert( "foo".length ); // 3
> window.alert( 2.toString(2) ); // run-time error

Not runtime. Syntax error. The tokenization of this is
"window" "." "alert" "(" "2." "toString" "(" "2" ")" ")" ";"
The literal "2." (matched by the rule
DecimalLiteral ::
DecimalIntegerLiteral . DecimalDigits_opt ExponentPart_opt
) might not be what you intended, but it is what you wrote.

A number, "2.", followed by an identifier, "toString" doesn't match
any rule in the grammar, so you get a syntax error.

> window.alert( (2).toString(2) ); // 10
> var n = 2; window.alert( n.toString(2) ); // 10

> So different implicit up/down-casting for string literal, number
> literal, number returning expression, identifier for number value.

No, it's all handled during parsing. There is no more or less
"up/down-casting" whether you use a variable hondling a number or a
literal number.

See
alert(2..toString(2));
(which tokenizes as
"alert" "(" "2." "." "toString" "(" "2" ")" ")" ";"
)

> All this still waits to be decently described for 14 years as
> well. Some day maybe...

And it's all documented in the ECMAScript specification of the grammar,
well enough that all the implementors can figure it out.

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

From: Stefan Weiss on
On 26/06/10 23:23, VK wrote:
> On Jun 26, 11:30 pm, Stefan Weiss <krewech...(a)gmail.com> wrote:
>> There's no error if you omit the parentheses around n. You may be
>> confusing that with something like (2).toString().
>
> Right.
> window.alert( "foo".length ); // 3
> window.alert( 2.toString(2) ); // run-time error
> window.alert( (2).toString(2) ); // 10
> var n = 2; window.alert( n.toString(2) ); // 10
> So different implicit up/down-casting for string literal, number
> literal, number returning expression, identifier for number value. All
> this still waits to be decently described for 14 years as well. Some
> day maybe...

....unless you want to venture into the mysterious realm of ECMAScript,
where this is, in fact, described. I know, I know, I'll stop now.

>> You insist that
>> there's an Boolean object hidden in there somewhere, and that this
>> "correlates with the experimental results down to NN 2.02". How can you
>> experimentally test and confirm something which is never directly
>> accessible to you?
>> (unless you plan on building a Large Object Collider in Switzerland)
>
> OK, I cannot "see" that temporary object wrapper just like I cannot
> "see" that wrapper for "foo".length. Let's us say I do postulate its
> existence - just like for the Higgs boson - as the only fully non-
> contradictory explanation of the observed results. An LHC equivalent
> could be to write yet another C++ program using say IActiveScript and
> relevant interfaces. It is a ridiculous yet alas very common situation
> to treat JavaScript implementation producers as some natural force of
> the Universe unwillingly disclosing its secrets over time, efforts and
> money consuming experiments... :-) :-|

There is another way. Nature's implementation of particle physics is
proprietary, so we're reduced to reverse engineering, but browsers are
(in some cases) open for inspection. See below.

>> > <g>
>> > All unary operators, such as the ! operator, evaluate expressions as
>> > follows:
>> > * If applied to undefined or null expressions, a run-time error is
>> > raised.
>> > * Objects are converted to strings.
>> > * Strings are converted to numbers if possible. If not, a run-time
>> > error is raised.
>> > * Boolean values are treated as numbers (0 if false, 1 if true).
>> > </g>
>>
>> That appears to be a quote from Microsoft's JScript documentation, not a
>> Netscape document.
>
> It is a Netscape stuff, I am 99% sure.

I searched Google for some of the phrases in that quote, and all I came
up with were JScript documents. For example:
http://msdn.microsoft.com/en-us/library/zz722703(VS.85).aspx

> MSDN documentation may be not a
> perfect source. It may be a terrible source by some criteria. But I do
> not recall a case where a written "you'll get this" would be 95% wrong
> to the actual JScript results on a span of 5 paragraphs in the row.

Yeah, it does read like somebody simply invented it, but browser history
isn't really my area. Maybe it used to work like that at some point.

>> Not for me. What I'm saying is that in order to evaluate a logical NOT,
>> there's no need to create a Boolean object, get its value, and destroy
>> it immediately afterwards. You claim that this is exactly what happens
>> in JavaScript. The SpiderMonkey source is open; show me the code.

I retract that. Do _not_ look at the SpiderMonkey parser/interpreter
code unless you're drunk or a wizard (or both). I found an older version
lying around in my ~/build directory and got curious. Now I've got a
headache.

To make it short: after peeling away the onion-like layers of macros and
arcane typedefs that make up the JavaScript interpreter, and wrapping my
head around stuff like the difference between JS_ValueToBoolean and
js_ValueToBoolean, what it comes down to is this:

src/jsinterp.c
...
BEGIN_CASE(JSOP_NOT)
POP_BOOLEAN(cx, rval, cond);
PUSH_OPND(BOOLEAN_TO_JSVAL(!cond));
END_CASE(JSOP_NOT)
...
#define POP_BOOLEAN(cx, v, b)
...
ok = js_ValueToBoolean(cx, v, &b); // [ed] branch for strings

src/jsbool.c
...
js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
{
...
} else if (JSVAL_IS_STRING(v)) {
b = JSSTRING_LENGTH(JSVAL_TO_STRING(v)) ? JS_TRUE : JS_FALSE;
...
}
*bp = b;

The length of a string operand for JSOP_NOT (a.k.a. "!") is used to
decide whether the expression evaluates to true or false. There's no
creation of new Boolean objects anywhere. BOOLEAN_TO_JSVAL doesn't
create any, and JS_TRUE and JS_FALSE are (indirectly) defined as 1 and
0, respectively.
As I said, it's an older version (Oct 2008), but hey, at least it's more
recent than NN2 ;-)


I hope this unintended exposure to C didn't brain my damage...


--
stefan
From: Stefan Weiss on
On 26/06/10 19:01, Stefan Weiss wrote:
> Perl also handles the string "0 but false" specially, but that's getting
> a little off-topic.

Still off-topic, but I don't want to let it stand uncorrected: that
should have been "0 but true", of course. It evaluates to 0 in a numeric
context, and as true in a boolean/logical context. The special property
of this exact string is that no type conversion warning will be issued
when it is used in a numeric context.
Not one of the Good Parts [tm] of Perl, I'm afraid.
</ot>


--
stefan