Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

!0 versus true

38 views
Skip to first unread message

Andrew Poulos

unread,
May 23, 2013, 9:31:01 AM5/23/13
to
I'm working with some people who write code and minimises it. As ab
afterthought, I unminimise some of it and worked my way through it.

One thing I found was that the minimiser had converted all instances of
true to !0.

When I reported it no one thought it an issue as both true and !0 are
truthy. Should they be concerned?

Andrew Poulos

Scott Sauyet

unread,
May 23, 2013, 10:58:25 AM5/23/13
to
It's not just that both are truthy. !0 is true, by 11.4.9 and 9.2 of
the ECMA-262 5.1 specification.

But there are of course some degenerate cases where this minification
could still bite you. E.g.:

var f=function(){return true;};
("" + f).substring(19, 20); // => "t"

var f=function(){return !0;};
("" + f).substring(19, 20); // => "!", in most implementations

But if you have this sort of technique in your code, then you'd
probably avoid minification in any case. I can't see other reasons
for concern.

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 23, 2013, 11:53:00 AM5/23/13
to
They should reconsider their approach as they are exchanging a minor
increase in loading performance against a probably larger reduction of
runtime performance, adding an operation (“!”) where there does not have to
be one, just for the sake of two octets less per occurrence (“!0” vs.
“true”).

They should ask themselves instead why there were so many occurrences of
”true” in the code in the first place. If I wrote a minimizer, *that* is
where I would look first. For example,

if (x == true)

and

if (true == x)

can be minimized to the equivalent, shorter, more efficient

if (x)

This is easy to find and replace with regular expressions:

/* if (x) if (y) z; */
"if (x == true) if (true == y) z;"
.replace(/([^=])\s*==\s*true\b|\btrue\s*==\s*([^=])/g, "$1$2");

or

/* if (x) if (y) z; */
"if (x == true) if (true == y) z;"
.replace(/([^=])\s*==\s*true\b|\btrue\s*==(?!=)\s*/g, "$1");

or if the minimizer was Perl or PCRE-based, you could use negative
lookbehind. (Exceptions for String and RegExp literals not included.)

Same for type-converting comparisons with “false” and negative type-
converting comparisons with “true” and “false”.

--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Daniel Pitts

unread,
May 24, 2013, 3:17:28 PM5/24/13
to
On 5/23/13 8:53 AM, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
>
>> I'm working with some people who write code and minimises it. As ab
>> afterthought, I unminimise some of it and worked my way through it.
>>
>> One thing I found was that the minimiser had converted all instances of
>> true to !0.
>>
>> When I reported it no one thought it an issue as both true and !0 are
>> truthy. Should they be concerned?
>
> They should reconsider their approach as they are exchanging a minor
> increase in loading performance against a probably larger reduction of
> runtime performance, adding an operation (“!”) where there does not have to
> be one, just for the sake of two octets less per occurrence (“!0” vs.
> “true”).
>
> They should ask themselves instead why there were so many occurrences of
> ”true” in the code in the first place. If I wrote a minimizer, *that* is
> where I would look first. For example,
>
> if (x == true)
>
> and
>
> if (true == x)
>
> can be minimized to the equivalent, shorter, more efficient
>
> if (x)
Yes, but if (x === true) can not be reduced to if (x).

Also, perhaps you're returning true after doing something that succeeded:

if (flibber()) { flub(); return true; }
if (flabber()) { noFlub(); return false; }

In these cases, reducing true and false to !0 and !!0 might make sense.

Thomas 'PointedEars' Lahn

unread,
May 24, 2013, 3:56:22 PM5/24/13
to
Daniel Pitts wrote:

> On 5/23/13 8:53 AM, Thomas 'PointedEars' Lahn wrote:
>> Andrew Poulos wrote:
>>> [true minized to !0]
>>
>> They should reconsider their approach as they are exchanging a minor
>> increase in loading performance against a probably larger reduction of
>> runtime performance, adding an operation (“!”) where there does not have
>> to be one, just for the sake of two octets less per occurrence (“!0” vs.
>> “true”).
>>
>> They should ask themselves instead why there were so many occurrences of
>> ”true” in the code in the first place. If I wrote a minimizer, *that* is
>> where I would look first. For example,
>>
>> if (x == true)
>>
>> and
>>
>> if (true == x)
>>
>> can be minimized to the equivalent, shorter, more efficient
>>
>> if (x)
>
> Yes, but if (x === true) can not be reduced to if (x).

Which is precisely why nobody suggested that.

> Also, perhaps you're returning true after doing something that succeeded:
>
> if (flibber()) { flub(); return true; }
> if (flabber()) { noFlub(); return false; }
>
> In these cases, reducing true and false to !0 and !!0 might make sense.

It does not, for the reasons I have already given. In particular your
latter suggestion is utter nonsense, adding *yet* *another* operation where
does not have to be one (false === !1).

Daniel Pitts

unread,
May 24, 2013, 4:13:57 PM5/24/13
to
Yup, I wasn't thinking, !1 does work better.

In any case, worrying about adding a negation operation is silly on
modern systems. Even lowly smart phones shouldn't have a problem with
that. Unless of course you're running a tight loop around some code
which does that, in which case you might want to hand optimize the
minified output, or avoid minifying that section at all.


Thomas 'PointedEars' Lahn

unread,
May 24, 2013, 4:23:21 PM5/24/13
to
Daniel Pitts wrote:

> On 5/24/13 12:56 PM, Thomas 'PointedEars' Lahn wrote:
>> Daniel Pitts wrote:
>>> Also, perhaps you're returning true after doing something that
>>> succeeded:
>>>
>>> if (flibber()) { flub(); return true; }
>>> if (flabber()) { noFlub(); return false; }
>>>
>>> In these cases, reducing true and false to !0 and !!0 might make sense.
>>
>> It does not, for the reasons I have already given. In particular your
>> latter suggestion is utter nonsense, adding *yet* *another* operation
>> where does not have to be one (false === !1).
>
> Yup, I wasn't thinking, !1 does work better.
>
> In any case, worrying about adding a negation operation is silly on
> modern systems. Even lowly smart phones shouldn't have a problem with
> that.

Wishful thinking, as expected.

> Unless of course you're running a tight loop around some code

A minimizer cannot know how oftena certain line of code is executed. Adding
unnecessary complexity to a program when it should have removed it, is a
*failure*.

> which does that, in which case you might want to hand optimize the
> minified output, or avoid minifying that section at all.

Just because junk code can run faster on occasion does not make it proper
code. Check your assumptions.

And trim your quotes.

Denis McMahon

unread,
May 24, 2013, 6:08:03 PM5/24/13
to
On Fri, 24 May 2013 12:17:28 -0700, Daniel Pitts wrote:

> Yes, but if (x === true) can not be reduced to if (x).

How about if(x===!0)

if "!0" is identical to "true" then the test "x===true" is identical to
the test "x===!0"

Where I use "is identical to" in the sense of "===", whereas I would use
"is equivalent to" in the sense of "=="

--
Denis McMahon, denismf...@gmail.com

Thomas 'PointedEars' Lahn

unread,
May 25, 2013, 1:00:33 AM5/25/13
to
Denis McMahon wrote:

> On Fri, 24 May 2013 12:17:28 -0700, Daniel Pitts wrote:
>> Yes, but if (x === true) can not be reduced to if (x).
>
> How about if(x===!0)

I think that was the point of the comment. However, it is not a good idea.
This is not just an equivalent expression. Since we must not assume
optimization, it includes an *additional operation* *each* time this
statement is executed. For what? Two octets less loaded the *one* time it
is loaded – a time savings of 0.3 ms in the *worst* case (56k dial-up
modem)?

<http://samizdat.mines.edu/howto/HowToBeAProgrammer.html#id2789469>

> if "!0" is identical to "true" then the test "x===true" is identical to
> the test "x===!0"

And +!1 is equivalent to 0. We still write only 0; not because it is
shorter, but because it is *less complex*, i.e. *faster*.

> Where I use "is identical to" in the sense of "===", whereas I would use
> "is equivalent to" in the sense of "=="

Making up your private terminology is not helpful. An *expression* is
/equivalent/ to another *expression* if both expressions are evaluated to
the same value under the same conditions; one expression can be exchanged
with the other without affecting the outcome of expressions in which they
are used. A *value* is /identical/ to another *value* if both values are
the same.

Scott Sauyet

unread,
May 25, 2013, 11:04:43 PM5/25/13
to
Thomas 'PointedEars' Lahn wrote:
> Denis McMahon wrote:

>> if "!0" is identical to "true" then the test "x===true" is identical to
>> the test "x===!0"
>
> And +!1 is equivalent to 0.  We still write only 0; not because it is
> shorter, but because it is *less complex*, i.e. *faster*.
>
>> Where I use "is identical to" in the sense of "===", whereas I would use
>> "is equivalent to" in the sense of "=="
>
> Making up your private terminology is not helpful.

ACK

> An *expression* is
> /equivalent/ to another *expression* if both expressions are evaluated to
> the same value under the same conditions; one expression can be exchanged
> with the other without affecting the outcome of expressions in which they
> are used. [ ... ]

But this is less clear to me, at least as to its practical
implications. Because of the ability to retrieve (at least an
approximation of) the source of a function as a string from within
running code, expressions that are not character-for-character
identical can cause different behaviors in a program, even though
meeting your definition above. This makes me suspect that your
definition doesn't really capture what one would want it to capture:

var f=function(){return 0;};
alert(("" + f).substring(19, 20));

versus:

var f=function(){return +!1;};
alert(("" + f).substring(19, 20));

Although the expressions `0` and `+!1` should be considered equivalent
by such a definition, these two short programs have different
behaviors in many modern ES implementation, the first alerting "0",
the second alerting "+".

-- Scott

Evertjan.

unread,
May 26, 2013, 5:07:29 AM5/26/13
to
Scott Sauyet wrote on 26 mei 2013 in comp.lang.javascript:

> var f=function(){return 0;};
> alert(("" + f).substring(19, 20));
>
> versus:
>
> var f=function(){return +!1;};
> alert(("" + f).substring(19, 20));
>
> Although the expressions `0` and `+!1` should be considered equivalent
> by such a definition, these two short programs have different
> behaviors in many modern ES implementation, the first alerting "0",
> the second alerting "+".
>

Your grave programming error shows here, Scott:

<script type='text/javascript'>

function f2(){return +0007;};
document.write( f2 );

document.write('<br><br>');

function f2(){return +0007;};
document.write( f2() );

</script>


--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Thomas 'PointedEars' Lahn

unread,
May 26, 2013, 7:11:03 AM5/26/13
to
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> An *expression* is
>> /equivalent/ to another *expression* if both expressions are evaluated to
>> the same value under the same conditions; one expression can be exchanged
>> with the other without affecting the outcome of expressions in which they
>> are used. [ ... ]
>
> But this is less clear to me, at least as to its practical
> implications. Because of the ability to retrieve (at least an
> approximation of) the source of a function as a string from within
> running code, expressions that are not character-for-character
> identical can cause different behaviors in a program, even though
> meeting your definition above. This makes me suspect that your
> definition doesn't really capture what one would want it to capture:
>
> var f=function(){return 0;};
> alert(("" + f).substring(19, 20));
>
> versus:
>
> var f=function(){return +!1;};
> alert(("" + f).substring(19, 20));
>
> Although the expressions `0` and `+!1` should be considered equivalent
> by such a definition, these two short programs have different
> behaviors in many modern ES implementation, the first alerting "0",
> the second alerting "+".

If that. The string representation of functions, that is, the return value
of Function.prototype.toString() for a Function instance as its “this”
value, is *implementation-dependent* (ES 5.1, §15.3.4.2).

Your confusion stems from the fact that you are proceeding from a false
assumption. It is _not_ the function that is used in your example, but a
string representation of the function.

If you were to consider the function instead, you would find that

f() === 0

in both cases. That is, the expressions “0” and “+!1” *are* *equivalent*
because they are evaluated to the same (*identical*) value, (+)0 under the
same (here: all) conditions. As a result, the functions returning that
value are equivalent, i.e. one can be replaced with the other in the same
expression without affecting the outcome (“true”) of evaluating the
expression in which it is used. (It is that equivalence why refactoring and
minimizers work.)

HTH

Scott Sauyet

unread,
May 26, 2013, 4:28:53 PM5/26/13
to
Correct, although it's scheduled to become more standardized in ES 6:

<http://wiki.ecmascript.org/doku.php?
id=harmony:function_to_string>

> Your confusion stems from the fact that you are proceeding from a false
> assumption.  It is _not_ the function that is used in your example, but a
> string representation of the function.

I believe I said as much.

I was not expressing confusion. I was noting that your definition of
equivalence sounds as though it would imply that two programs that
differed only by a difference of two expressions that were equivalent
would in fact have identical behavior, but that this is not actually
true. I realize you didn't claim this. But the fact that it's not
true means that the definition has less utility than it seems.


> If you were to consider the function instead, you would find that
>
>   f() === 0
>
> in both cases.  That is, the expressions “0” and “+!1” *are* *equivalent*
> because they are evaluated to the same (*identical*) value, (+)0 under the
> same (here: all) conditions.  As a result, the functions returning that
> value are equivalent, i.e. one can be replaced with the other in the same
> expression without affecting the outcome (“true”) of evaluating the
> expression in which it is used.  (It is that equivalence why refactoring and
> minimizers work.)

And my example shows one limitations of minimizers (and in fact in all
refactorings) in languages that allow programs access to their own
source code.

Here you simply restate your definition. It's a reasonable-seeming
one. But it has a serious flaw, which might be stated like this: two
programs which differ only in that a single expression in one has been
replaced by an equivalent expression in the other do not necessarily
exhibit the same behavior under the same conditions.

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 27, 2013, 6:07:31 AM5/27/13
to
This is interesting, but does not justify the statement “is scheduled to
become more standardized”.

>> Your confusion stems from the fact that you are proceeding from a false
>> assumption. It is _not_ the function that is used in your example, but a
>> string representation of the function.
>
> I believe I said as much.

No, you did not.

> I was not expressing confusion.

But evidently you *are* confused.

> I was noting that your definition of equivalence sounds as though it would
> imply that two programs that differed only by a difference of two
> expressions that were equivalent would in fact have identical behavior,
> but that this is not actually true. I realize you didn't claim this.
> But the fact that it's not true means that the definition has less utility
> than it seems.

No, it means that you are trying (and failing) to use a strawman argument.

>> If you were to consider the function instead, you would find that
>>
>> f() === 0
>>
>> in both cases. That is, the expressions “0” and “+!1” *are* *equivalent*
>> because they are evaluated to the same (*identical*) value, (+)0 under
>> the same (here: all) conditions. As a result, the functions returning
>> that value are equivalent, i.e. one can be replaced with the other in the
>> same expression without affecting the outcome (“true”) of evaluating the
>> expression in which it is used. (It is that equivalence why refactoring
>> and minimizers work.)
>
> And my example shows one limitations of minimizers (and in fact in all
> refactorings) in languages that allow programs access to their own
> source code.

No, it does not. Minimizing and all refactoring are operations on the
original *source code*. You are confusing the expressions with the values
created from them.

> Here you simply restate your definition.

I have used your example to show that “my” definition is correct.

> It's a reasonable-seeming one.

It is a/the correct one.

> But it has a serious flaw, which might be stated like this: two programs
> which differ only in that a single expression in one has been replaced by
> an equivalent expression in the other do not necessarily exhibit the same
> behavior under the same conditions.

No, you have just learned the difference between an expression and its
string representation, and the difference between functional equivalence and
value-equivalence.

BTW, this is beyond the scope of this newsgroup.

Scott Sauyet

unread,
May 27, 2013, 2:27:42 PM5/27/13
to
>>   <http://wiki.ecmascript.org/doku.php?id=harmony:function_to_string>
>
> This is interesting, but does not justify the statement “is scheduled to
> become more standardized”.

You're right. I was under the impression that this was included in
the latest (2013-05-14) Draft Specification for ES.next (Ecma-262
Edition 6). But §15.3.3.2 still contains the old "implementation-
dependent" language.


>>> Your confusion stems from the fact that you are proceeding from a false
>>> assumption.  It is _not_ the function that is used in your example, but a
>>> string representation of the function.
>
>> I believe I said as much.
>
> No, you did not.

Yes, I did too.

I said:

| Because of the ability to retrieve (at least an approximation of)
the source
| of a function as a string from within running code...

and you quoted it twice so far in this thread.


>> I was not expressing confusion.
>
> But evidently you *are* confused.

Have you never, even once, considered the possibility that someone who
disagrees might understand the subject in as much depth as you do and
still have reached a different conclusion?

I am not confused.


>> I was noting that your definition of equivalence sounds as though it would
>> imply that two programs that differed only by a difference of two
>> expressions that were equivalent would in fact have identical behavior,
>> but that this is not actually true.  I realize you didn't claim this.
>> But the fact that it's not true means that the definition has less utility
>> than it seems.
>
> No, it means that you are trying (and failing) to use a strawman argument.

No, I am making a fairly simple point: Even though two expressions
are equivalent under your definition, one cannot count on being able
to substitute one for the other in all programs without changing
behavior. This to me means that the definition is less useful than it
first sounds.


>>> If you were to consider the function instead, you would find that
>
>>>   f() === 0
>
>>> in both cases.  That is, the expressions “0” and “+!1” *are* *equivalent*
>>> because they are evaluated to the same (*identical*) value, (+)0 under
>>> the same (here: all) conditions.  As a result, the functions returning
>>> that value are equivalent, i.e. one can be replaced with the other in the
>>> same expression without affecting the outcome (“true”) of evaluating the
>>> expression in which it is used.  (It is that equivalence why refactoring
>>> and minimizers work.)
>
>> And my example shows one limitations of minimizers (and in fact in all
>> refactorings) in languages that allow programs access to their own
>> source code.
>
> No, it does not.  Minimizing and all refactoring are operations on the
> original *source code*.  You are confusing the expressions with the values
> created from them.

No, I am noting that in some implementations (in fact in most modern
browsers) a program has access to portions of that original source
code, or at least to approximations thereof. I think perhaps you've
been missing the point that my example included the `alert` statement
as part of the same program being minified.

If a minimizer ran against the following two-line program:

var f=function(){return +!1;};
alert(("" + f).substring(19, 20));

by your definition, it should be allowed to create this one:

var f=function(){return 0;};
alert(("" + f).substring(19, 20));

But the second program has observably different behavior than the
first.


>> Here you simply restate your definition.
>
> I have used your example to show that “my” definition is correct.

Correct according to what standards? I'm a mathematician by training;
I'm used to terms being defined for convenience. But there is a
question of the utility of a definition. I'm not sure there is any
better definition of "equivalent expression", but I'm suggesting that
in the context of Javascript (or ECMAScript implementation, if you
prefer) the notion of "equivalent expression" is not nearly as useful
as it might be in other languages. If equivalent expressions cannot
be freely substituted without possibly changing the behavior of a
program, then what practical use is there of knowing that the
expressions are equivalent?



>> It's a reasonable-seeming one.
>
> It is a/the correct one.

References, please?


>> But it has a serious flaw, which might be stated like this: two programs
>> which differ only in that a single expression in one has been replaced by
>> an equivalent expression in the other do not necessarily exhibit the same
>> behavior under the same conditions.
>
> No, you have just learned the difference between an expression and its
> string representation, and the difference between functional equivalence and
> value-equivalence.

No, I quite understood that difference. I was trying to point out
that the string representations of some expressions are, for better or
for worse, accessible from within code.

The question is whether you've learned anything from this. Do you
claim that the two programs above will have the same behavior? Or can
you agree that by your definition, equivalent expressions cannot be
freely substituted in programs without risking a change in that
program's behavior?


> BTW, this is beyond the scope of this newsgroup.

For heaven's sake, why?

We are discussing a feature of ES languages, and how that might differ
from certain other languages. Why in the world would that be out-of-
bounds?

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 27, 2013, 5:30:57 PM5/27/13
to
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> Scott Sauyet wrote:
>>>>> Although the expressions `0` and `+!1` should be considered equivalent
>>>>> by such a definition, these two short programs have different
>>>>> behaviors in many modern ES implementation, the first alerting "0",
>>>>> the second alerting "+".
>>>> If that. The string representation of functions, that is, the return
>>>> value of Function.prototype.toString() for a Function instance as its
>>>> “this” value, is *implementation-dependent* (ES 5.1, §15.3.4.2).
>>> Correct, although it's scheduled to become more standardized in ES 6:
>>> <http://wiki.ecmascript.org/doku.php?id=harmony:function_to_string>
>> This is interesting, but does not justify the statement “is scheduled to
>> become more standardized”.
>
> You're right. I was under the impression that this was included in
> the latest (2013-05-14) Draft Specification for ES.next (Ecma-262
> Edition 6). But §15.3.3.2 still contains the old "implementation-
> dependent" language.

It would still only be a Draft Specification even if it were in there.

>>>> Your confusion stems from the fact that you are proceeding from a false
>>>> assumption. It is _not_ the function that is used in your example, but
>>>> a string representation of the function.
>>
>>> I believe I said as much.
>>
>> No, you did not.
>
> Yes, I did too.
>
> I said:
>
> | Because of the ability to retrieve (at least an approximation of)
> | the source of a function as a string from within running code...
>
> and you quoted it twice so far in this thread.

But this is a different context. You are using the functions as a value (in
particular, their string representations), not the return value of the
functions. Therefore, your examples do not show that the expression that is
evaluated to the return value of the one function is not equivalent to the
expression that is evaluated to the return value of the other function.
Which was what I had referred to in “my” definition (I put that in quotes
deliberately).

IOW, you have only showed that the functions thus created are not value-
equivalent with regard to their string representations (and nobody had
claimed they were). That is, if the implementation-dependent string
representations could have showed that. For example, it would be standards
compliant if the content of the function body were not contained in the
representation at all because there is no Specification requirement for
that. The string representations would not be distinguishable then, and the
two functions would not only be functional equivalent, but also value-
equivalent with regard to their string representations.

>>> I was not expressing confusion.
>>
>> But evidently you *are* confused.
>
> Have you never, even once, considered the possibility that someone who
> disagrees might understand the subject in as much depth as you do and
> still have reached a different conclusion?

I have. But evidently you have not understood this subject (in as much
depth as I have).

> I am not confused.

Well, you have been confusing different contexts and concepts. So it is
fair to say that you are at least a bit confused.

>>> I was noting that your definition of equivalence sounds as though it
>>> would imply that two programs that differed only by a difference of two
>>> expressions that were equivalent would in fact have identical behavior,
>>> but that this is not actually true. I realize you didn't claim this.
>>> But the fact that it's not true means that the definition has less
>>> utility than it seems.
>>
>> No, it means that you are trying (and failing) to use a strawman
>> argument.
>
> No, I am making a fairly simple point: Even though two expressions
> are equivalent under your definition, one cannot count on being able
> to substitute one for the other in all programs without changing
> behavior. This to me means that the definition is less useful than it
> first sounds. [fallacy]

But nobody except you has claimed that your interpretation applies there.
That is why yours *is* a strawman argument.

>> BTW, this is beyond the scope of this newsgroup.
>
> For heaven's sake, why?

Because equivalence as it is discussed here is not specific to ECMAScript;
it is a subject of mathematics, computer science, and linguistics within the
domain of formal languages. It can be understood as an equivalent
translation where we would exchange one word (e.g., “+!1”) with another word
(e.g., “0”) without the phrase changing its meaning, because the first word
is defined to be a compound word that has the same meaning as the second
(non-compound) word.

Obviously there is an intrinsic difference between using the original phrase
(i.e., using the string representation of a function) and using the
translated phrase (i.e., calling that function and using its return value).

> We are discussing a feature of ES languages, […]

No, actually we are not. We just happen to discuss this general concept in
the context of ECMAScript and its implementations.

Scott Sauyet

unread,
May 27, 2013, 8:12:59 PM5/27/13
to
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Scott Sauyet wrote:
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>> Scott Sauyet wrote:

>>>>> If that.  The string representation of functions, that is, the return
>>>>> value of Function.prototype.toString() for a Function instance as its
>>>>> “this” value, is *implementation-dependent* (ES 5.1, §15.3.4.2).
>>>> Correct, although it's scheduled to become more standardized in ES 6:
>>>> <http://wiki.ecmascript.org/doku.php?id=harmony:function_to_string>
>>> This is interesting, but does not justify the statement “is scheduled to
>>> become more standardized”.
>> You're right.  I was under the impression that this was included in
>> the latest (2013-05-14) Draft Specification for ES.next (Ecma-262
>> Edition 6).  But §15.3.3.2 still contains the old "implementation-
>> dependent" language.
> It would still only be a Draft Specification even if it were in there.

And with that, I'll abandon this to the "Scroll position detection"
thread.

:-)


>>>>> Your confusion stems from the fact that you are proceeding from a false
>>>>> assumption.  It is _not_ the function that is used in your example, but
>>>>> a string representation of the function.

>>>> I believe I said as much.

>>> No, you did not.

>> Yes, I did too.

>> I said:

>> | Because of the ability to retrieve (at least an approximation of)
>> | the source of a function as a string from within running code...

>> and you quoted it twice so far in this thread.

> But this is a different context.  You are using the functions as a value (in
> particular, their string representations), not the return value of the
> functions.

Of course I am. That's the whole point. You can't be blind enough
not to recognize this after all the different ways I've phrased it so
far. Various implementations allow us to use functions this way. The
fact that you can do so means that two programs differing only by a
single expression can have different behavior even though the two
expressions are equivalent.

Do you agree with that or not? If not, can you explain why?


> Therefore, your examples do not show that the expression that is
> evaluated to the return value of the one function is not equivalent to the
> expression that is evaluated to the return value of the other function.

Please read more carefully. I never claimed that.


> Which was what I had referred to in “my” definition (I put that in quotes
> deliberately).

And, if you haven't heard it yet, I'm explaining that this definition
is not as useful in a language which allows programmatic access to the
source code of certain expressions.


> IOW, you have only showed that the functions thus created are not value-
> equivalent with regard to their string representations (and nobody had
> claimed they were).

You seem to have things in the wrong order. I'm not trying to
demonstrate any exception to your definition. I'm trying to show that
the definition you presented offers little of use when discussing ES
implementations.


>  That is, if the implementation-dependent string
> representations could have showed that.  For example, it would be standards
> compliant if the content of the function body were not contained in the
> representation at all because there is no Specification requirement for
> that.  The string representations would not be distinguishable then, and the
> two functions would not only be functional equivalent, but also value-
> equivalent with regard to their string representations.

Yes they would. But in many modern implementations, this is not how
it works. The problem is not that it always happens. The problem is
that it could happen. I've tested the following two links in five
relatively modern browsers:

<http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
<http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>

In all browsers I tested, the programs displayed different behavior,
even though the two programs are identical except that one expression
has been replaced by an equivalent one in the second. I understand
that the specification does not insist on precisely this behavior.
But the specification *allows* it.


>>>> I was not expressing confusion.

>>> But evidently you *are* confused.

>> Have you never, even once, considered the possibility that someone who
>> disagrees might understand the subject in as much depth as you do and
>> still have reached a different conclusion?

> I have.  But evidently you have not understood this subject (in as much
> depth as I have).

I'm afraid you have that backwards. Or do you assert that all
specification-conforming browsers *should* yield identical behavior
for the two programs mentioned above?



>> I am not confused.
>
> Well, you have been confusing different contexts and concepts.  So it is
> fair to say that you are at least a bit confused.

No, I'm afraid you haven't been reading very carefully.


>>>> I was noting that your definition of equivalence sounds as though it
>>>> would imply that two programs that differed only by a difference of two
>>>> expressions that were equivalent would in fact have identical behavior,
>>>> but that this is not actually true.  I realize you didn't claim this.
>>>> But the fact that it's not true means that the definition has less
>>>> utility than it seems.
>
>>> No, it means that you are trying (and failing) to use a strawman
>>> argument.
>
>> No, I am making a fairly simple point:  Even though two expressions
>> are equivalent under your definition, one cannot count on being able
>> to substitute one for the other in all programs without changing
>> behavior.  This to me means that the definition is less useful than it
>> first sounds.  [fallacy]
>
> But nobody except you has claimed that your interpretation applies there.
> That is why yours *is* a strawman argument.

Do you even know how to read?

This is what I said upon joining this thread:

| This makes me suspect that your definition doesn't really
| capture what one would want it to capture

I have been arguing that your definition lacks utility.



>>> BTW, this is beyond the scope of this newsgroup.
>
>> For heaven's sake, why?
>
> Because equivalence as it is discussed here is not specific to ECMAScript;
> it is a subject of mathematics, computer science, and linguistics within the
> domain of formal languages.  It can be understood as an equivalent
> translation where we would exchange one word (e.g., “+!1”) with another word
> (e.g., “0”) without the phrase changing its meaning, because the first word
> is defined to be a compound word that has the same meaning as the second
> (non-compound) word.

If that were all we were discussing, it would still be relevant to
this group, as it has a bearing on how the language(s) under
discussion behave(s). But I've brought in other points beyond formal
equivalence that have little to do with mathematics, computer science,
or linguistics. It is certainly relevant.


> Obviously there is an intrinsic difference between using the original phrase
> (i.e., using the string representation of a function) and using the
> translated phrase (i.e., calling that function and using its return value).

And this latter point is irrelevant to this ng?


>> We are discussing a feature of ES languages, […]
>
> No, actually we are not.  We just happen to discuss this general concept in
> the context of ECMAScript and its implementations.

You seem to be determined to discard what I'm discussing, but I am
talking about a feature of languages such as JavaScript, JScript, and
the like, not usually available in most languages I've used. How many
programming languages allow direct programmatic access to the source
code of their functions?

This is quite relevant to this group.

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 27, 2013, 8:40:54 PM5/27/13
to
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> Scott Sauyet wrote:
>>>>> Thomas 'PointedEars' Lahn wrote:
>>>>>> Your confusion stems from the fact that you are proceeding from a
>>>>>> false assumption. It is _not_ the function that is used in your
>>>>>> example, but a string representation of the function.
>>>>>
>>>>> I believe I said as much.
>>>>
>>>> No, you did not.
>>>
>>> Yes, I did too.
>>>
>>> I said:
>>>
>>> | Because of the ability to retrieve (at least an approximation of)
>>> | the source of a function as a string from within running code...
>>>
>>> and you quoted it twice so far in this thread.
>>
>> But this is a different context. You are using the functions as a value
>> (in particular, their string representations), not the return value of
>> the functions.
>
> Of course I am. That's the whole point.

You do not have a point. You are misinterpreting “my” definition of
(value-)equivalence of an expression to include “string representations of
functions in which this expression occurs”, so that you can claim that the
definition would not universally apply although it never was claimed that it
applied universally. This is the strawman argument that I am talking about.

In addition, you are ignoring that string representations of functions are
implementation-dependent in the first place, thus not suited to support your
point if you had one.

> You can't be blind enough not to recognize this after all the different
> ways I've phrased it so far.

“When did you stop beating your wife?”

> Various implementations allow us to use functions this way.

Such as?

> The fact that you can do so means that two programs differing only by a
> single expression can have different behavior even though the two
> expressions are equivalent.

No, it means that ECMAScript programs which rely on function serialization
are deeply flawed, which really is old news.

> Do you agree with that or not?

I do not agree with your knee-jerk interpretation of what I wrote, …

> If not, can you explain why?

… because you are ignoring the context in which I wrote it.

>> Therefore, your examples do not show that the expression that
>> is evaluated to the return value of the one function is not
>> equivalent to the expression that is evaluated to the return
>> value of the other function.
>
> Please read more carefully. I never claimed that.

You claimed, while ignoring the difference, that therefore “my” definition
was not useful. As for reading carefully, you should have read the
following paragraph more carefully.

>> Which was what I had referred to in “my” definition (I put that in quotes
>> deliberately).
>
> And, if you haven't heard it yet, I'm explaining that this definition
> is not as useful in a language which allows programmatic access to the
> source code of certain expressions.

Which is wrong, caused by your proceeding from a false premise. Ex falso
quodlibet.

>> IOW, you have only showed that the functions thus created are not value-
>> equivalent with regard to their string representations (and nobody had
>> claimed they were).
>
> You seem to have things in the wrong order.

Apparently you are unable to read statements in context, and I am getting
tired pointing that out to you.

> I'm not trying to demonstrate any exception to your definition.

Yes, you are. You have (mis)used function serialization to demonstrate an
exception to it where actually none exists. The function itself is a
context that *you* have added.

> I'm trying to show that the definition you presented offers little of use
> when discussing ES implementations.

Which is still wrong.

> [tl;dr]

Scott Sauyet

unread,
May 27, 2013, 11:29:20 PM5/27/13
to
Again, you are twisting things. I did not in any way suggest that
your definition included string representations of the functions. I
said simply that as a definition the one you presented means little in
the languages most discussed here. Since that definition cannot be
reliably used to transform arbitrary programs into other ones with the
same behavior, the definition adds nothing of value to the discourse.


>> You can't be blind enough not to recognize this after all the different
>> ways I've phrased it so far.
>
> “When did you stop beating your wife?”

Or perhaps you can. "I stopped long before I started."


>> Various implementations allow us to use functions this way.
>
> Such as?

Recent versions of SpiderMonkey, V8, and Chakra, to name a few.


>> The fact that you can do so means that two programs differing only by a
>> single expression can have different behavior even though the two
>> expressions are equivalent.
>
> No, it means that ECMAScript programs which rely on function serialization
> are deeply flawed, which really is old news.

So is the definition you've been defending only worthwhile when
programmers eschew function serialization?



>> Do you agree with that or not?
>
> I do not agree with your knee-jerk interpretation of what I wrote, …

It was a simple question. I said that "two programs differing only by
a
single expression can have different behavior even though the two
expressions are equivalent." Again, do you agree with that?


>> If not, can you explain why?
>
> … because you are ignoring the context in which I wrote it.

No, I'm asking if you agree with a statement I made. Nothing you
wrote has any bearing on it. Can you give (and defend) a yes or no
answer to that question?


>>> Therefore, your examples do not show that the expression that
>>> is evaluated to the return value of the one function is not
>>> equivalent to the expression that is evaluated to the return
>>> value of the other function.
>
>> Please read more carefully.  I never claimed that.
>
> You claimed, while ignoring the difference, that therefore “my” definition
> was not useful.

And I still claim it. I'm glad you finally understand. Do you
understand the basis for my argument? Do you have an actual
counterargument?


> As for reading carefully, you should have read the
> following paragraph more carefully.
>
>>> Which was what I had referred to in “my” definition (I put that in quotes
>>> deliberately).

I did ask earlier for references. Until shown otherwise, I have no
problem attributing this definition to you. Is that what you're
complaining about?


>> And, if you haven't heard it yet, I'm explaining that this definition
>> is not as useful in a language which allows programmatic access to the
>> source code of certain expressions.
>
> Which is wrong, caused by your proceeding from a false premise.  Ex falso
> quodlibet.

Except that I should have said "in an implementation which allows...",
what false premise do you see?


>>> IOW, you have only showed that the functions thus created are not value-
>>> equivalent with regard to their string representations (and nobody had
>>> claimed they were).
>
>> You seem to have things in the wrong order.
>
> Apparently you are unable to read statements in context, and I am getting
> tired pointing that out to you.

Funny, I thought I was the one pointing that out to you. Ad nauseum.


>> I'm not trying to demonstrate any exception to your definition.
>
> Yes, you are.  You have (mis)used function serialization to demonstrate an
> exception to it where actually none exists.  The function itself is a
> context that *you* have added.

No. What does it take to make you realize that I'm accepting entirely
your definition of equivalent expressions, and proceeding to show that
it cannot be reliably used to alter a program by substituting one
expression for an equivalent one without risking a change in the
behavior of the program?

I did not try to demonstrate an exception to the equivalence of
expressions. The different behavior I presented was in an entirely
different statement of the program than the one where the expression
substitution occurred. It is no exception to your definition.

If you're willing to say that the definition of equivalent expressions
you presented is consistent and coherent but still risky for any
automated program manipulation in many modern ES implementations, then
we'd be in agreement. But it sounds as though you disagree.




>> I'm trying to show that the definition you presented offers little of use
>> when discussing ES implementations.
>
> Which is still wrong.

So how do you propose it gets used?


>> [tl;dr]

Yeah, I'm getting pretty tired of this too.

-- Scott

John Harris

unread,
May 28, 2013, 10:38:54 AM5/28/13
to
On Mon, 27 May 2013 17:12:59 -0700 (PDT), Scott Sauyet
<scott....@gmail.com> wrote:

<snip>
> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
> <http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>
>In all browsers I tested, the programs displayed different behavior,
>even though the two programs are identical except that one expression
>has been replaced by an equivalent one in the second.
<snip>

Name the functions in the two examples f and g to lessen the
confusion.

You are saying that when f() and g() are 'equivalent' expressions
then f.toString() should be 'equivalent' to g.toString() for
equivalence to be a useful concept.

Why? After all, you wouldn't expect the expressions f and g to be
the same : they evaluate to references to different function objects.
These objects can be given different properties by the program without
changing the values returned by f() and g().

The equivalence of expressions is not the same as the equivalence of
objects.

John

Scott Sauyet

unread,
May 28, 2013, 11:32:39 AM5/28/13
to
John Harris wrote:
> Scott Sauyet wrote:
>   <snip>
>>    <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>    <http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>>
>> In all browsers I tested, the programs displayed different behavior,
>> even though the two programs are identical except that one expression
>> has been replaced by an equivalent one in the second.
>   <snip>
>
> Name the functions in the two examples f and g to lessen the
> confusion.

That would only confuse the point. The point is that the only
difference between the two programs is the substitution of `0` in the
second for the equivalent `+!1` in the first. Nonetheless the two
programs have different behavior. Making an additional change by
changing the name of the function would muddy the waters.


> You are saying that when  f()  and  g()  are 'equivalent' expressions
> then  f.toString()  should be 'equivalent' to  g.toString()  for
> equivalence to be a useful concept.

Not at all.

The real point is that the equivalence of expressions is less useful
in Javascript than in many other languages. Automatic minification
based upon it can break programs that take advantage of this weird
quirk of the language. Perhaps the only answer is Thomas' assertion
that, "ECMAScript programs which rely on function serialization are
deeply flawed." But this does mean that automated minification can
possibly wreak havoc with certain code.


> Why? After all, you wouldn't expect the expressions  f  and  g  to be
> the same : they evaluate to references to different function objects.
> These objects can be given different properties by the program without
> changing the values returned by f() and g().

I'm of the opinion that there is no clear safe way to automatically
refactor arbitrary Javascript code. I believe that for any automated
mechanism, some clever coder could write a program that would be
broken by it. The ability to reach within the source code makes me
thing nasty things about Kurt Gödel. :-)


> The equivalence of expressions is not the same as the equivalence of
> objects.

Shame on you; I think you've been listening to Thomas. :-) I am
certainly not disputing that. I'm talking about the usefulness of the
concept of expression equivalence in Javascript. I think it's pretty
low.

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 28, 2013, 3:14:39 PM5/28/13
to
Scott Sauyet wrote:

> John Harris wrote:
>> Scott Sauyet wrote:
>> <snip>
>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>>>
>>> In all browsers I tested, the programs displayed different behavior,
>>> even though the two programs are identical except that one expression
>>> has been replaced by an equivalent one in the second.
>> <snip>
>>
>> Name the functions in the two examples f and g to lessen the
>> confusion.
>
> That would only confuse the point. The point is that the only
> difference between the two programs is the substitution of `0` in the
> second for the equivalent `+!1` in the first. Nonetheless the two
> programs have different behavior. Making an additional change by
> changing the name of the function would muddy the waters.

You are the one who is muddying the waters here.

The point is that you continue to fail to differentiate between

A) an expression

and

B) the string representation of the function that contains it.

The expression is evaluated to the return value of the function by the
*compiler/interpreter* not before the function is *called*; its equivalence
to another expression in that context means that the evaluation of the
expression for the return value results in the same (identical) value.

In short, the return values of the functions are the same, therefore the
expressions leading to the return values are (value-)equivalent and the
functions are functional equivalent. The functions themselves are obviously
not value-equivalent per se (as indicated by the possibility of different
string representations), but then again nobody but you claimed they should.

It is that difference, and that change of context involved, that you fail to
comprehend, and that you ignore so that you can make the knee-jerk statement
of a “reduced usefulness” of the textbook definition of (expression)
equivalence.

>> You are saying that when f() and g() are 'equivalent' expressions
>> then f.toString() should be 'equivalent' to g.toString() for
>> equivalence to be a useful concept.
>
> Not at all.

Yes, you are.

> The real point is that the equivalence of expressions is less useful
> in Javascript than in many other languages.
^^^^^^^^^^
Utter nonsense, twofold. Assuming “Javascript” as a misnomer for
“ECMAScript implementations”, you of all people should know that those
languages are not the only languages in which functions are first-class
objects. It is negatively surprising to me how little you understand both
ECMAScript implementations and pure functional programming languages, yet
you are attempting to implement – unnecessarily – “functional programming”
in ECMAScript.

> Automatic minification based upon it can break programs that take
> advantage of this weird quirk of the language. Perhaps the only answer is
> Thomas' assertion that, "ECMAScript programs which rely on function
> serialization are deeply flawed." But this does mean that automated
> minification can possibly wreak havoc with certain code.

Yes, and it means that you have still not understood the not-that-difficult
concept of equivalence (of expressions in a computer program).

> > The equivalence of expressions is not the same as the equivalence of
> > objects.
>
> Shame on you; I think you've been listening to Thomas. :-) […]

How many people explaining to you that you are wrong does it take before you
can see that you are wrong?

| Have you never, even once, considered the possibility that someone who
| disagrees might understand the subject in as much depth as you do and
| still have reached a different conclusion?
– Scott Sauyet in
<news:ed180bb2-f6be-48dc...@h5g2000vbg.googlegroups.com>

Probably you are either not smart enough for this, or you are trolling.

Scott Sauyet

unread,
May 28, 2013, 6:38:55 PM5/28/13
to
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> John Harris wrote:
>>> Scott Sauyet wrote:
>>> <snip>
>>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>
>>>> In all browsers I tested, the programs displayed different behavior,
>>>> even though the two programs are identical except that one expression
>>>> has been replaced by an equivalent one in the second.
>>> <snip>
>
>>> Name the functions in the two examples f and g to lessen the
>>> confusion.
>
>> That would only confuse the point. The point is that the only
>> difference between the two programs is the substitution of `0` in the
>> second for the equivalent `+!1` in the first. Nonetheless the two
>> programs have different behavior. Making an additional change by
>> changing the name of the function would muddy the waters.
>
> You are the one who is muddying the waters here.
>
> The point is that you continue to fail to differentiate between
>
> A) an expression
>
> and
>
> B) the string representation of the function that contains it.

No, as I've demonstrated repeatedly, I understand the difference.

However, even though the two programs I supplied differ only in one
equivalent expression, they have different behavior.

Stipulating the definition of equivalent expressions as you've
presented it, if we define Document A as the one residing at

<http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>

and Document B as the one residing at

http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>

The argument, in excruciating detail, proceeds as follows:

1. Document A and Document B differ only on line 9.
2. The difference on line 9 starts at column 29.
3. That difference falls inside a client-side program spanning lines
7 - 18. These two distinct programs we will label Program A
and Program B, respectively.
4. The difference from Program A to Program B can be described as
the deletion of the characters "+!1" and the insertion of the
character "0".
5. At character 29 of line 9, an expression is allowable.
6. "+!1" is a legal expression.
7. "0" is a legal expression.
8. "+!1" and "0" are equivalent expressions.
9. Hence Program A and Program B differ only in the substitution of
equivalent expressions.
10. Loading Document A and Document B into Chrome 27.0.1453.94 (*)
yield differing output.
11. That differing output is the result of the differences between
Program A and Program B.
12. Therefore, two programs that differ only in the substitution of
equivalent expressions can yield differing output.

(*) Feel free to substitute another modern browser.

Can you accept this argument? If not, which is the first step you
reject? And why do you reject it?

From here, it's my *interpretation* that the definition supplied is
not particularly useful, especially in the context specified by the OP
of minifiers. Of course you're free to disagree with this
interpretation. But you're not free to twist my words to make it
sound as though I argued something I didn't and something I disagree
with, not without challenge.


> The expression is evaluated to the return value of the function by the
> *compiler/interpreter* not before the function is *called*; its equivalence
> to another expression in that context means that the evaluation of the
> expression for the return value results in the same (identical) value.
>
> In short, the return values of the functions are the same, therefore the
> expressions leading to the return values are (value-)equivalent and the
> functions are functional equivalent. The functions themselves are obviously
> not value-equivalent per se (as indicated by the possibility of different
> string representations),

None of this is in contention. I don't know how to make it clearer
that I agree about this.


> but then again nobody but you claimed they should.

I have not tried to suggest an alternative definition, if you notice.
I did not claim that value-equivalence (or any approximation thereof
related to serialization) is essential. I have simply stated that the
definition as presented, one which can be used fairly
straightforwardly for automated refactorings in many languages, is not
as useful for that task in ES languages. I have provided an example,
which you seem determined to ignore. Do you accept Statement 12 in
the list above? If so, we're down to a question of interpretation.
You can be very sanguine about what I see as a significant problem by
insisting that those who rely on function serialization are simply out
of luck. Or you can take my view, which is that the weak
specification for function serialization together with the actual
implementation of it in modern ES engines is a serious blow to anyone
trying to write a bulletproof minifier. But if you don't agree with
Statement 12, I'd really like to know why.


> It is that difference, and that change of context involved, that you fail to
> comprehend, and that you ignore so that you can make the knee-jerk statement
> of a “reduced usefulness” of the textbook definition of (expression)
> equivalence.

Which textbook?

And why are you characterizing it as a knee-jerk reaction? This is
the only time I've ever discussed this topic in this ng. It's not as
though I've been harping on it over the years.


>>> You are saying that when f() and g() are 'equivalent' expressions
>>> then f.toString() should be 'equivalent' to g.toString() for
>>> equivalence to be a useful concept.
>
>> Not at all.
>
> Yes, you are.

Please provide a quote to back that up. I believe I remember quite
well what I've argued. And it was never that. I don't think
expression equivalence, by any definition, is likely to useful in
light of the problems I've described. (This is something of a
rhetorical flourish. I think it can be useful up to a point. But I
think that the type of exceptions displayed by my example demonstrates
that there is a large hole in any Javascript minification technique
that depends upon expression equivalence.)


>> The real point is that the equivalence of expressions is less useful
>> in Javascript than in many other languages.
> ^^^^^^^^^^
> Utter nonsense, twofold. Assuming “Javascript” as a misnomer for
> “ECMAScript implementations”,

(In order to reduce the noise, I'm willing to cater to your
idiosyncrasy on this when our posts are mostly a dialog between you
and me, but this was a response to John's post, and I reverted to my
usual language. No apologies.)

> you of all people should know that those
> languages are not the only languages in which functions are first-class
> objects. It is negatively surprising to me how little you understand both
> ECMAScript implementations and pure functional programming languages, yet
> you are attempting to implement – unnecessarily – “functional programming”
> in ECMAScript.

Of course I understand that there are many languages with first-class
functions. I've worked with a number of them, and have been studying
several others. I find no relevance except for those that allow
programs direct access to (at least some reasonable approximation) of
the source code of their functions. I'm sure there are other
languages that do so, but I've not observed this in other languages
I've used. Do you know of other examples?


>> Automatic minification based upon it can break programs that take
>> advantage of this weird quirk of the language. Perhaps the only answer is
>> Thomas' assertion that, "ECMAScript programs which rely on function
>> serialization are deeply flawed." But this does mean that automated
>> minification can possibly wreak havoc with certain code.
>
> Yes, and it means that you have still not understood the not-that-difficult
> concept of equivalence (of expressions in a computer program).

How does that follow?


>>> The equivalence of expressions is not the same as the equivalence of
>>> objects.
>
>> Shame on you; I think you've been listening to Thomas. :-) […]
>
> How many people explaining to you that you are wrong does it take before you
> can see that you are wrong?

Argumentum ad populum, now? From the man who's ever standing alone
arguing with everyone about the use of the term "Javascript"? What
could this world be coming to?

It would certainly take more than the "arguments" you've been
presenting, mainly trying to claim I'm saying something I'm not and
that I don't understand something I do.


>| Have you never, even once, considered the possibility that someone who
>| disagrees might understand the subject in as much depth as you do and
>| still have reached a different conclusion?
> – Scott Sauyet in
> <news:ed180bb2-f6be-48dc...@h5g2000vbg.googlegroups.com>
>
> Probably you are either not smart enough for this, or you are trolling.


Actually I'm just waiting for you to come to even a modicum of
understanding about something very basic. Maybe it's a forlorn hope.
One of my first dialogs with you in this ng had the same quality. You
insisted over many posts that Rice's Theorem implied something that
Lasse Nielsen and I and the OP all disagreed with. It took many
posts, it seemed, before you stopped simply arguing and actually
listened, at which point you said:

| Apparently there has been a gross misunderstanding here. Of course
| what you describe is possible. I had no intention of denying
that.
- Thomas Lahn in <news:1566943.A...@PointedEars.de>

I'm still waiting for the comparable moment in this thread. I really
think you've got it in your head that I'm arguing something I'm not,
and you haven't been able to read what I actually wrote to see that it
is quite different.

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 29, 2013, 7:16:37 AM5/29/13
to
How typical of you that you would make this a personal issue.

> The argument, in excruciating detail, proceeds as follows:
>
> 1. Document A and Document B differ only on line 9.
> 2. The difference on line 9 starts at column 29.
> 3. That difference falls inside a client-side program spanning lines
> 7 - 18. These two distinct programs we will label Program A
> and Program B, respectively.
> 4. The difference from Program A to Program B can be described as
> the deletion of the characters "+!1" and the insertion of the
> character "0".
> 5. At character 29 of line 9, an expression is allowable.
> 6. "+!1" is a legal expression.
> 7. "0" is a legal expression.
> 8. "+!1" and "0" are equivalent expressions.
> 9. Hence Program A and Program B differ only in the substitution of
> equivalent expressions.
> 10. Loading Document A and Document B into Chrome 27.0.1453.94 (*)
> yield differing output.
> 11. That differing output is the result of the differences between
> Program A and Program B.
> 12. Therefore, two programs that differ only in the substitution of
> equivalent expressions can yield differing output.
>
> (*) Feel free to substitute another modern browser.
>
> Can you accept this argument

No (but that is not the reason why I also reject your later interpretation).

> If not, which is the first step you reject?

10.

> And why do you reject it?

There is no guarantee for that. AISB:

| An implementation-dependent representation of the function is returned.
^^^^^^^^^^^^^^^^^^^^^^^^
Several other browsers than Chrome (27.0.1453.94) do support a different
ECMAScript implementation than Google V8 JavaScript.

The ECMAScript Language Specification allows that the return value does not
contain the contents of the original /FunctionBody/, and it allows that it
contains other expressions not found in the original. The only requirement
is:

| This representation has the syntax of a /FunctionDeclaration/.

As I indicated before, a conforming ECMAScript implementation is allowed to
return

"function () {}"

both for

(function a (b) { return !+1; }).toString()

and for

(function c (d, e) { return 0; }).toString()

because

| 13 Function Definition
|
| Syntax
|
| […]
| FunctionExpression :
| function Identifier_opt ( FormalParameterList_opt ) { FunctionBody }
|
| […]
| FunctionBody :
| SourceElements_opt

or, in reduced ABNF:

FunctionExpression = "function" [Identifier] "(" [FormalParameterList] ")"
"{" [SourceElements] "}"

This means that as for their string representation those two functions would
not be value-equivalent. But they would still be (weakly) functional
equivalent, because the expressions leading to their return values are
(value-)equivalent. (In this case there would also be strong functional
equivalence because the function calls cannot have side-effects.)

> From here, it's my *interpretation* that the definition supplied is
> not particularly useful, especially in the context specified by the OP
> of minifiers. […]

And precisely *that* is your fallacy. To break it down for you:

You are falsely assuming that equivalence must be transitive, even
universal. That is, you are assuming that if two expressions in a program
are equivalent, all functions and all programs containing those expressions
must be equivalent as well.

You find a corner case (string representation of functions in ECMAScript
implementations) in which this assumption of yours *might not* be fulfilled,
and therefore you doubt the usefulness of the *original* definition of
expression/value-equivalence, in the context of ECMAScript implementations.

Can you see your mistake now?

> [tl;dr]

Thomas 'PointedEars' Lahn

unread,
May 29, 2013, 7:20:48 AM5/29/13
to
[Cancel & Supersedes]
How typical of you that you would make this a personal issue.

> The argument, in excruciating detail, proceeds as follows:
>
> 1. Document A and Document B differ only on line 9.
> 2. The difference on line 9 starts at column 29.
> 3. That difference falls inside a client-side program spanning lines
> 7 - 18. These two distinct programs we will label Program A
> and Program B, respectively.
> 4. The difference from Program A to Program B can be described as
> the deletion of the characters "+!1" and the insertion of the
> character "0".
> 5. At character 29 of line 9, an expression is allowable.
> 6. "+!1" is a legal expression.
> 7. "0" is a legal expression.
> 8. "+!1" and "0" are equivalent expressions.
> 9. Hence Program A and Program B differ only in the substitution of
> equivalent expressions.
> 10. Loading Document A and Document B into Chrome 27.0.1453.94 (*)
> yield differing output.
> 11. That differing output is the result of the differences between
> Program A and Program B.
> 12. Therefore, two programs that differ only in the substitution of
> equivalent expressions can yield differing output.
>
> (*) Feel free to substitute another modern browser.
>
> Can you accept this argument

No (but that is not the reason why I also reject your later interpretation).

> If not, which is the first step you reject?

10.

> And why do you reject it?

This means that as for their string representation those two functions might
or might not be value-equivalent. But they would still be (weakly)
functional equivalent, because the expressions leading to their return
values are (value-)equivalent. (In this case there would also be strong
functional equivalence because the function calls cannot have side-effects.)

> From here, it's my *interpretation* that the definition supplied is
> not particularly useful, especially in the context specified by the OP
> of minifiers. […]

And precisely *that* is your fallacy. To break it down for you:

You are falsely assuming that equivalence must be transitive, even
universal. That is, you are assuming that if two expressions in a program
are equivalent, all functions and all programs containing those expressions
must be equivalent as well.

You find a corner case (string representation of functions in ECMAScript
implementations) in which this assumption of yours *might not* be fulfilled,
and therefore you doubt the usefulness of the *original* definition of
expression/value-equivalence, in the context of ECMAScript implementations.

Can you see your mistake now?

> [tl;dr]

Scott Sauyet

unread,
May 29, 2013, 9:37:19 AM5/29/13
to
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:

>>> The point is that you continue to fail to differentiate between
>>>
>>>   A) an expression
>>>
>>> and
>>>
>>>   B) the string representation of the function that contains it.
>>
>> No, as I've demonstrated repeatedly, I understand the difference.
>
>> However, even though the two programs I supplied differ only in one
>> equivalent expression, they have different behavior.
>>
>> Stipulating the definition of equivalent expressions as you've
>> presented it, if we define Document A as the one residing at
>>
>>     <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>
>> and Document B as the one residing at
>
>>    http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>
> [libel]
In other words, you deny that "Loading Document A and Document B into
Chrome 27.0.1453.94 yield differing output."


>> And why do you reject it?

> There is no guarantee for that.  AISB:
>
> | An implementation-dependent representation of the function is returned.
>      ^^^^^^^^^^^^^^^^^^^^^^^^

Quite irrelevant as to that specific environment. I'm providing a
proof of existence. If conforming implementations can have the
behavior I've noted, then expression equivalence is not enough of a
guarantee of identical program behavior. That version of Chrome,
running its version of the V8 engine is such an example.


> Several other browsers than Chrome (27.0.1453.94) do support a different
> ECMAScript implementation than Google V8 JavaScript.
>
> [... unnecessary lecture on what's allowed by the specification ...]
>
> This means that as for their string representation those two functions might
> or might not be value-equivalent.  But they would still be (weakly)
> functional equivalent, because the expressions leading to their return
> values are (value-)equivalent.  (In this case there would also be strong
> functional equivalence because the function calls cannot have side-effects.)

If you think I've said anything that contradicts this, you need to re-
read the thread.


>> From here, it's my *interpretation* that the definition supplied is
>> not particularly useful, especially in the context specified by the OP
>> of minifiers. […]
>
> And precisely *that* is your fallacy.  To break it down for you:
>
> You are falsely assuming that equivalence must be transitive, even
> universal.  That is, you are assuming that if two expressions in a program
> are equivalent, all functions and all programs containing those expressions
> must be equivalent as well.

Again, you are misreading. But you're getting closer. I'm
specifically demonstrating that because of the possibility of
programatic access to the source code of a program's own functions,
expression equivalence is *not* transitive. (I will continute to use
"transitivity" here as it is a fair approximation of what we're
discussing, although it's not entirely appropriate, since we're
talking about generalizing from expressions to entire programs.)


> You find a corner case (string representation of functions in ECMAScript
> implementations) in which this assumption of yours *might not* be fulfilled,
> and therefore you doubt the usefulness of the *original* definition of
> expression/value-equivalence, in the context of ECMAScript implementations.

Pretty close.

But I do not make the assumption of transitivity. The assumption I'm
making is that such trasitivity is is important in automated
refactoring, particularly minification. Demonstrating an exception to
that transitivity shows a potential weakness in such automated
refactoring tools in ES environments.

But more generally, do you really object to using corner cases to cast
doubt on techniques or definitions? ISTM that a great deal of the
history of client scripting techniques has revolved around noting such
corner cases and modifying what were once thought to be useful
techniques to cover these cases.


> Can you see your mistake now?

No. I'm pretty sure I haven't made one. I don't really believe you
deny step 10 above; I think you're quibbling. In fact, I'm pretty
sure that you are bright enough to realize that my conclusion, "Two
programs that differ only in the substitution of equivalent
expressions can yield differing output", is true. I'm also pretty
certain that our only disagreement in this thread beyond various
misinterpretation of what one another has said, is in the
interpretation of that fact. And while you're free to try to convince
me that my interpretation is faulty, I have no compunction about
promoting that interpretation.

Or am I wrong? Do you insist that by specification two programs that
differ only in the substitution of equivalent expressions must by
specification yield the same output?

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 29, 2013, 10:28:48 AM5/29/13
to
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> The point is that you continue to fail to differentiate between
>>>>
>>>> A) an expression
>>>>
>>>> and
>>>>
>>>> B) the string representation of the function that contains it.
>>>
>>> No, as I've demonstrated repeatedly, I understand the difference.
>>
>>> However, even though the two programs I supplied differ only in one
>>> equivalent expression, they have different behavior.
>>>
>>> Stipulating the definition of equivalent expressions as you've
>>> presented it, if we define Document A as the one residing at
>>>
>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>>
>>> and Document B as the one residing at
>>
>>> http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>>
>> [libel]

This was not libel. *The record shows* that it *is* typical for you to fail
to differentiate between the argument and the person making it. One could
consider your using my name in this context libel, but I do not intend to
descend to your niveau of argumentation and let you beat me with experience
there.

>>> The argument, in excruciating detail, proceeds as follows:
>>
>>> 1. Document A and Document B differ only on line 9.
>>> 2. The difference on line 9 starts at column 29.
>>> 3. That difference falls inside a client-side program spanning lines
>>> 7 - 18. These two distinct programs we will label Program A
>>> and Program B, respectively.
>>> 4. The difference from Program A to Program B can be described as
>>> the deletion of the characters "+!1" and the insertion of the
>>> character "0".
>>> 5. At character 29 of line 9, an expression is allowable.
>>> 6. "+!1" is a legal expression.
>>> 7. "0" is a legal expression.
>>> 8. "+!1" and "0" are equivalent expressions.
>>> 9. Hence Program A and Program B differ only in the substitution of
>>> equivalent expressions.
>>> 10. Loading Document A and Document B into Chrome 27.0.1453.94 (*)
>>> yield differing output.
>>> 11. That differing output is the result of the differences between
>>> Program A and Program B.
>>> 12. Therefore, two programs that differ only in the substitution of
>>> equivalent expressions can yield differing output.
>>
>>> (*) Feel free to substitute another modern browser.
>>
>>> Can you accept this argument
>>
>> No (but that is not the reason why I also reject your later
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> interpretation).
^^^^^^^^^^^^^^
>>> If not, which is the first step you reject?
>>
>> 10.
>
> In other words, you deny that "Loading Document A and Document B into
> Chrome 27.0.1453.94 yield differing output."

No. And as long as you cannot see that even though I made it perfectly
clear, there really is nothing else to discuss. Apparently you are
challenged by even the slightest deviation from the answer that you expect −
calling those responses “irrelevant” even though they are not.

So the only chance to resolve this in a civilized manner (and save me
precious free time no less) that I can see at this point is to take it step
by step:

No, I do not deny that "Loading Document A and Document B into Chrome
27.0.1453.94 yield differing output."

John Harris

unread,
May 29, 2013, 12:33:55 PM5/29/13
to
On Tue, 28 May 2013 08:32:39 -0700 (PDT), Scott Sauyet
<scott....@gmail.com> wrote:

>John Harris wrote:
>> Scott Sauyet wrote:
>>   <snip>
>>>    <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>>    <http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>>>
>>> In all browsers I tested, the programs displayed different behavior,
>>> even though the two programs are identical except that one expression
>>> has been replaced by an equivalent one in the second.
>>   <snip>
>>
>> Name the functions in the two examples f and g to lessen the
>> confusion.
>
>That would only confuse the point. The point is that the only
>difference between the two programs is the substitution of `0` in the
>second for the equivalent `+!1` in the first. Nonetheless the two
>programs have different behavior. Making an additional change by
>changing the name of the function would muddy the waters.

I'm surprised that you, "a mathematician by training", didn't realise
that g is used as an alias for the purpose of this discussion.

Alternatively, I'm surprised that you, as someone who knows something
about javascript, hadn't assumed that
var g = f;
has been added in one of the examples.


>> You are saying that when  f()  and  g()  are 'equivalent' expressions
>> then  f.toString()  should be 'equivalent' to  g.toString()  for
>> equivalence to be a useful concept.
>
>Not at all.
>
>The real point is that the equivalence of expressions is less useful
>in Javascript than in many other languages. Automatic minification
>based upon it can break programs that take advantage of this weird
>quirk of the language. Perhaps the only answer is Thomas' assertion
>that, "ECMAScript programs which rely on function serialization are
>deeply flawed." But this does mean that automated minification can
>possibly wreak havoc with certain code.

Your argument applies to any language that can allow read access to
the executing code : the .exe file or whatever. E.g programs that do a
sumcheck of themselves at startup. Also, programs that have access to
a stack trace. And for function calls, it applies to any functions
that have externally visible side effects.

This doesn't make "equivalent expressions" useless, merely that care
is needed in using equivalence. E.g in ECMAScript you can't replace 1
by 0 + 1 in some circumstances, even if you can replace it by (0 + 1).


>> Why? After all, you wouldn't expect the expressions  f  and  g  to be
>> the same : they evaluate to references to different function objects.
>> These objects can be given different properties by the program without
>> changing the values returned by f() and g().
>
>I'm of the opinion that there is no clear safe way to automatically
>refactor arbitrary Javascript code. I believe that for any automated
>mechanism, some clever coder could write a program that would be
>broken by it.

Yet people do modify functions to clean them up and expect there to be
no change in the program's behaviour. Even people who know enough to
be careful.

I agree that automatic minifying/refactoring mustn't be done if the
programmer(s) have written certain kinds of pathological code.

But this is true in practically any programming language.


>The ability to reach within the source code makes me
>thing nasty things about Kurt Gödel. :-)
<snip>

Unfair to Kurt!

John

Scott Sauyet

unread,
May 29, 2013, 2:34:35 PM5/29/13
to
John Harris wrote:
> Scott Sauyet wrote:
>> John Harris wrote:
>>> Scott Sauyet wrote:
>>> <snip>
>>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>
>>>> In all browsers I tested, the programs displayed different behavior,
>>>> even though the two programs are identical except that one expression
>>>> has been replaced by an equivalent one in the second.
>>> <snip>
>>>
>>> Name the functions in the two examples f and g to lessen the
>>> confusion.
>>
>> That would only confuse the point.  The point is that the only
>> difference between the two programs is the substitution of `0` in the
>> second for the equivalent `+!1` in the first.  Nonetheless the two
>> programs have different behavior.  Making an additional change by
>> changing the name of the function would muddy the waters.
>
> I'm surprised that you, "a mathematician by training", didn't realise
> that g is used as an alias for the purpose of this discussion.
>
> Alternatively, I'm surprised that you, as someone who knows something
> about javascript, hadn't assumed that
>   var g = f;
> has been added in one of the examples.

I think perhaps I misunderstood your suggestion. I thought you were
suggesting taking the function that's named `f` in the first document
and naming it `g` in the second. That's what I thought would muddy
the waters, because at that point we have more than the single change
between the documents.

If you're suggesting something else, I'm not quite sure what it is.
The program in each document defines only a single function, so it
doesn't matter if I call it `f` or `g`, as long as it's consistent
between the two documents.

I could have written the programs differently and tried to directly
compare these serialization of these two functions:

var f=function(){return +!1;}
var g=function(){return 0;}

and then done a test like this {

if (("" + f) == ("" + g)) { /*...*/ }

for the same sort of demonstration. I considered it, but thought that
the version I created was more explicit.


>>> You are saying that when f() and g() are 'equivalent' expressions
>>> then f.toString() should be 'equivalent' to g.toString() for
>>> equivalence to be a useful concept.
>>
>> Not at all.
>
>> The real point is that the equivalence of expressions is less useful
>> in Javascript than in many other languages.  Automatic minification
>> based upon it can break programs that take advantage of this weird
>> quirk of the language.  Perhaps the only answer is Thomas' assertion
>> that, "ECMAScript programs which rely on function serialization are
>> deeply flawed."  But this does mean that automated minification can
>> possibly wreak havoc with certain code.
>
> Your argument applies to any language that can allow read access to
> the executing code : the .exe file or whatever. E.g programs that do a
> sumcheck of themselves at startup. Also, programs that have access to
> a stack trace.

Yes, the same argument can be made in those environments. And in each
case, I would evaluate whether the risks are serious enough to
automated refactoring. I was mainly arguing that this is serious
enough for Javascript. I've seen a fair bit of usage of Javascript
function serialization in the wild. I have seen programs that
calculate their own checksums, although rarely. Obviously you
couldn't combine that in any simple manner with a tool that changes
the source code after the expected checksum has been calculated, for
the same reasons I've been describing here. I can (just barely)
imagine scenarios where stack traces could work the same way; it seems
unlikely enough to be a factor that I'm much more comfortable to
answer the, "Doctor it hurts when I do this," with, "Then don't do
that!"


> And for function calls, it applies to any functions
> that have externally visible side effects.

In general, or only when the program has access to the function's
source code? If the former, can you explain?


> This doesn't make "equivalent expressions" useless, merely that care
> is needed in using equivalence. E.g in ECMAScript you can't replace 1
> by 0 + 1 in some circumstances, even if you can replace it by (0 + 1).

I don't really think it's useless. I just think that it is less
useful for automated refactoring in Javascript than it would be in
many languages. (This did start as a thread on minification!)

I'm sure I'm going to give myself a dope slap when you present one,
but I can't come up with an example of the "0 + 1" issue. Can you
supply one?


>>> Why? After all, you wouldn't expect the expressions f and g to be
>>> the same : they evaluate to references to different function objects.
>>> These objects can be given different properties by the program without
>>> changing the values returned by f() and g().
>>
>> I'm of the opinion that there is no clear safe way to automatically
>> refactor arbitrary Javascript code.  I believe that for any automated
>> mechanism, some clever coder could write a program that would be
>> broken by it.
>>
> Yet people do modify functions to clean them up and expect there to be
> no change in the program's behaviour. Even people who know enough to
> be careful.

Of course. But it's much easier to do this for code you know than to
write a tool to do this in an automated fashion that should work
across all programs.


> I agree that automatic minifying/refactoring mustn't be done if the
> programmer(s) have written certain kinds of pathological code.
>
> But this is true in practically any programming language.

I agree. The question then is whether depending upon function
serialization is a type of pathological code. It sounds like Thomas
would say so. I'm less willing to, although I was disappointed that
the specification discussed didn't end up getting included in the
latest draft. I've seen some very clever things done with function
serialization that didn't have obvious solutions without it. This is
of course risky as it's dealing with underspecified behavior. But web
developers have to be fairly well used to that.


>> The ability to reach within the source code makes me
>> thing nasty things about Kurt Gödel.  :-)
>
>   <snip>
>
> Unfair to Kurt!

I know. He was just the bearer of bad tidings.

-- Scott

Scott Sauyet

unread,
May 29, 2013, 4:32:34 PM5/29/13
to
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Scott Sauyet wrote:

>>>> However, even though the two programs I supplied differ only in one
>>>> equivalent expression, they have different behavior.
>>>>
>>>> Stipulating the definition of equivalent expressions as you've
>>>> presented it, if we define Document A as the one residing at
>>>>
>>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>>>
>>>> and Document B as the one residing at
>>>>
>>>> http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>>>
>>> [libel]
>
> This was not libel. *The record shows* that it *is* typical for you to fail
> to differentiate between the argument and the person making it.

I'd be very interested to see any evidence whatsoever of this
assertion. What record are you considering?


> One could
> consider your using my name in this context libel [ ... ]

Is that what you were blithering about, the fact that I used your name
in the damn documents? If that offended you, I apologize. I've
removed your name from them.

>>>> The argument, in excruciating detail, proceeds as follows:
>>>> [... elided ...]
>>>>
>>>> Can you accept this argument
>>>>
>>> No (but that is not the reason why I also reject your later
>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> interpretation).
> ^^^^^^^^^^^^^^


Yes, I read it the first time. I've been making a factual claim and
an interpretation of that claim. As far as I can tell, you're arguing
vigorously against that factual claim. I know quite well that you
don't agree with my interpretation. I've stated my point there; I'm
not trying to convince you. But if you have a legitimate argument
against the factual claim, then I would quite like to hear it.

I'm not holding my breath.


>>>> If not, which is the first step you reject?
>>>
>>> 10.
>>
>> In other words, you deny that "Loading Document A and Document B into
>> Chrome 27.0.1453.94 yield differing output."
>
> No. And as long as you cannot see that even though I made it perfectly
> clear, there really is nothing else to discuss. Apparently you are
> challenged by even the slightest deviation from the answer that you expect -
> calling those responses "irrelevant" even though they are not.
>
> So the only chance to resolve this in a civilized manner (and save me
> precious free time no less) that I can see at this point is to take it step
> by step:
>
> No, I do not deny that "Loading Document A and Document B into Chrome
> 27.0.1453.94 yield differing output."

Sorry, I'm not willing to play that game. You know the rest of the
argument. If you choose not to respond, that's your right. But
unless you do, I'm going to have to go with "there really is nothing
else to discuss."

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 29, 2013, 5:27:05 PM5/29/13
to
Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> Scott Sauyet wrote:
>>>>> However, even though the two programs I supplied differ only in one
>>>>> equivalent expression, they have different behavior.
>>>>>
>>>>> Stipulating the definition of equivalent expressions as you've
>>>>> presented it, if we define Document A as the one residing at
>>>>>
>>>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>>>>
>>>>> and Document B as the one residing at
>>>>>
>>>>> http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>>>>
>>>> [libel]
>>
>> This was not libel. *The record shows* that it *is* typical for you to
>> fail to differentiate between the argument and the person making it.
>
> I'd be very interested to see any evidence whatsoever of this
> assertion. What record are you considering?

Do you really want the ugliness of your character revealed here? So be it,
fool:

<news:ddd1ea21-b947-4614...@hq4g2000vbb.googlegroups.com>
<news:c27f1e07-80dd-48ad...@he10g2000vbb.googlegroups.com>
<news:95f8d3fa-cbf6-4b68...@y14g2000vbk.googlegroups.com>
<news:1fdd1b94-723f-4f42...@r4g2000vbf.googlegroups.com>
<news:c6cce191-f2f8-487a...@r3g2000yqe.googlegroups.com>
<news:b4cc9394-21bf-45ca...@d6g2000yqi.googlegroups.com>
<news:923176ef-2dd8-49db...@o2g2000yqb.googlegroups.com>

I could live with – and killfile forever – such a troll. However, the most
disgusting aspect of your false character is that you actually think you can
make up for that extreme hostility with subsequent extreme reverence, (and
I, believing in the good core in people, continuously fall for it):

<news:95f8d3fa-cbf6-4b68...@y14g2000vbk.googlegroups.com>
<news:1fdd1b94-723f-4f42...@r4g2000vbf.googlegroups.com>
<news:bd93fc08-185a-4614...@n11g2000yqe.googlegroups.com>
<news:c6cce191-f2f8-487a...@r3g2000yqe.googlegroups.com>

That is only what is still online, and from it what I cared to find for this
occasion. I was only halfway those the articles matching your name.

Now I know I might not be considered the nicest person around because of the
facts that I state, but at least I am *honest*: When I say something, I say
what I think, and I do what I say. If I sometimes target the person instead
of the behavior or the argument in question, it is only accidentally, under
rather extreme circumstances, when forced to react, like now. For example,
you have seldom, if ever, seen me talking bad about people behind their back
like you do, seemingly out of habit.

>> One could
>> consider your using my name in this context libel [ ... ]
>
> Is that what you were blithering about, the fact that I used your name
^^^^^^^^^^^^^^^^^^^^^^^^^
> in the damn documents? If that offended you, I apologize. I've
> removed your name from them.

q.e.d.

>>>>> The argument, in excruciating detail, proceeds as follows:
>>>>> [... elided ...]
>>>>>
>>>>> Can you accept this argument
>>>>>
>>>> No (but that is not the reason why I also reject your later
>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> interpretation).
>> ^^^^^^^^^^^^^^
>
> Yes, I read it the first time. I've been making a factual claim and
> an interpretation of that claim. As far as I can tell, you're arguing
> vigorously against that factual claim.

No, I am still arguing against your interpretation. Because I know what I
wrote and how I meant it, and it was not what you misconstrue it to be.

> I know quite well that you don't agree with my interpretation.

So, there really is nothing else to discuss if all you can base your
argument on is your interpretation, and if you would not accept the
possibility that your interpretation could be (and in this case is) wrong.

> I've stated my point there; I'm not trying to convince you.

But you are trying to convince everyone else that your interpretation is
correct when it has been showed by at least two people that it is not. Now
where is the logic in that?

> But if you have a legitimate argument against the factual claim, then I
> would quite like to hear it.

I have made *several* legitimate arguments against your interpretation,
which is the primary point in question here. The secondary point that I
debated is your are preceeding from *another* false assumption: the single
possibility for the return value of Function.prototype.toString() for a
given function, regardless of the implementation.

You have chosen to ignore all of them and label them “irrelevant”. I am not
going to repeat them for you because quite frankly I have better things to
do than to teach you how to read properly.

> I'm not holding my breath.

Me too. He cannot be convinced who thinks he cannot be wrong.

>>>>> If not, which is the first step you reject?
>>>>
>>>> 10.
>>>
>>> In other words, you deny that "Loading Document A and Document B into
>>> Chrome 27.0.1453.94 yield differing output."
>>
>> […]
>> No, I do not deny that "Loading Document A and Document B into Chrome
>> 27.0.1453.94 yield differing output."
>
> Sorry, I'm not willing to play that game. You know the rest of the
> argument.

Yes, I know the rest of your fallacious argument all too well.

> If you choose not to respond, that's your right. But unless you do, I'm
> going to have to go with "there really is nothing else to discuss."

I *have* responded to your false statement which says that I would “deny”
your previous factual statement. It is *your* turn now.

--
PointedEars

Thomas 'PointedEars' Lahn

unread,
May 29, 2013, 5:34:35 PM5/29/13
to
[Supersedes & Cancel due to Copy & Paste error]

Scott Sauyet wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> Scott Sauyet wrote:
>>>>> However, even though the two programs I supplied differ only in one
>>>>> equivalent expression, they have different behavior.
>>>>>
>>>>> Stipulating the definition of equivalent expressions as you've
>>>>> presented it, if we define Document A as the one residing at
>>>>>
>>>>> <http://scott.sauyet.com/Javascript/Demo/2013-05-27a/>
>>>>>
>>>>> and Document B as the one residing at
>>>>>
>>>>> http://scott.sauyet.com/Javascript/Demo/2013-05-27b/>
>>>>
>>>> [libel]
>>
>> This was not libel. *The record shows* that it *is* typical for you to
>> fail to differentiate between the argument and the person making it.
>
> I'd be very interested to see any evidence whatsoever of this
> assertion. What record are you considering?

<news:b4cc9394-21bf-45ca...@d6g2000yqi.googlegroups.com>
<news:923176ef-2dd8-49db...@o2g2000yqb.googlegroups.com>

I could live with – and killfile forever – such a troll. However, the most
disgusting aspect of your false character is that you actually think you can
make up for that extreme hostility with subsequent extreme reverence, (and
I, believing in the good core in people, continuously fall for it):

<news:bd93fc08-185a-4614...@n11g2000yqe.googlegroups.com>
<news:c6cce191-f2f8-487a...@r3g2000yqe.googlegroups.com>

That is only what is still online, and from it what I cared to find for this
occasion. I was only halfway those the articles matching your name.

Now I know I might not be considered the nicest person around because of the
facts that I state, but at least I am *honest*: When I say something, I say
what I think, and I do what I say. If I sometimes target the person instead
of the behavior or the argument in question, it is only accidentally, under
rather extreme circumstances, when forced to react, like now. For example,
you have seldom, if ever, seen me talking bad about people behind their back
like you do, seemingly out of habit.

>> One could
>> consider your using my name in this context libel [ ... ]
>
> Is that what you were blithering about, the fact that I used your name
^^^^^^^^^^^^^^^^^^^^^^^^^
> in the damn documents? If that offended you, I apologize. I've
> removed your name from them.

q.e.d.

>>>>> The argument, in excruciating detail, proceeds as follows:
>>>>> [... elided ...]
>>>>>
>>>>> Can you accept this argument
>>>>>
>>>> No (but that is not the reason why I also reject your later
>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> interpretation).
>> ^^^^^^^^^^^^^^
>
> Yes, I read it the first time. I've been making a factual claim and
> an interpretation of that claim. As far as I can tell, you're arguing
> vigorously against that factual claim.

No, I am still arguing against your interpretation. Because I know what I
wrote and how I meant it, and it was not what you misconstrue it to be.

> I know quite well that you don't agree with my interpretation.

So, there really is nothing else to discuss if all you can base your
argument on is your interpretation, and if you would not accept the
possibility that your interpretation could be (and in this case is) wrong.

> I've stated my point there; I'm not trying to convince you.

But you are trying to convince everyone else that your interpretation is
correct when it has been showed by at least two people that it is not. Now
where is the logic in that?

> But if you have a legitimate argument against the factual claim, then I
> would quite like to hear it.

I have made *several* legitimate arguments against your interpretation,
which is the primary point in question here. The secondary point that I
debated is your are preceeding from *another* false assumption: the single
possibility for the return value of Function.prototype.toString() for a
given function, regardless of the implementation.

You have chosen to ignore all of them and label them “irrelevant”. I am not
going to repeat them for you because quite frankly I have better things to
do than to teach you how to read properly.

> I'm not holding my breath.

Me too. He cannot be convinced who thinks he cannot be wrong.

>>>>> If not, which is the first step you reject?
>>>>
>>>> 10.
>>>
>>> In other words, you deny that "Loading Document A and Document B into
>>> Chrome 27.0.1453.94 yield differing output."
>>
>> […]
>> No, I do not deny that "Loading Document A and Document B into Chrome
>> 27.0.1453.94 yield differing output."
>
> Sorry, I'm not willing to play that game. You know the rest of the
> argument.

Yes, I know the rest of your fallacious argument all too well.

> If you choose not to respond, that's your right. But unless you do, I'm
> going to have to go with "there really is nothing else to discuss."

Scott Sauyet

unread,
May 30, 2013, 9:30:55 AM5/30/13
to
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> Scott Sauyet wrote:
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>> [libel]
>>> This was not libel.  *The record shows* that it *is* typical for you to
>>> fail to differentiate between the argument and the person making it.
>> I'd be very interested to see any evidence whatsoever of this
>> assertion.  What record are you considering?
>
> Do you really want the ugliness of your character revealed here?  So be it,
> fool:
^^^^

Insults, is it? I'm quite used to that when involved with you online.
You're right. I did insult you once among those otherwise perfectly
reasonable posts:

|>> So you aren't willing to give a yes-or-no answer to my questions?
[…]
|
|> That is correct. I will not fall for your *fallacies*.
|
| That's what I thought.
| Pathetic.
-- from <news:ddd1ea21-
b947-4614-89b...@hq4g2000vbb.googlegroups.com>
(| = Scott Sauyet, |> = Thomas 'PointedEars' Lahn, |>> = Scott
Sauyet)

I can live with the fact that eventually I end up resorting to
insults, when the provocation is great enough. The other posts seem
quite harmless and much less insulting than yours often are.


> I could live with – and killfile forever – such a troll.  However, the most
> disgusting aspect of your false character is that you actually think you can
> make up for that extreme hostility with subsequent extreme reverence, (and
> I, believing in the good core in people, continuously fall for it):

Reverence? Do you really think so? What you're seeing is respect.
When you post something that I find interesting or well-done, I say
so. I don't let the fact that your overall effect on the group is
mostly one of supercillious pedantic bullying stop me from noting when
you add something useful to the dialog.

But I fairly recently decided that I would no longer refrain from
calling you out on the nonsense too. I feel no reason to apologize.
The few insults I've directed at you are so many fewer than you've
directed my way, so many fewer than I've seen you direct at all sorts
of participants.

I also believe that you can read the entire history of posts from my
three-and-a-half years of involvement with this group and find that
there's only one other person I've insulted. Him I have stopped
responding to. I feel interacting with him is simply a waste of
time. So far I haven't gotten to that point with you, probably for
much the same reasons you haven't kill-filed me. I hope it remains
that way because I do believe you have a lot to contribute to the
group.


> Now I know I might not be considered the nicest person around because of the
> facts that I state, but at least I am *honest*: When I say something, I say
> what I think, and I do what I say.  If I sometimes target the person instead
> of the behavior or the argument in question, it is only accidentally, under
> rather extreme circumstances, when forced to react, like now.  For example,
> you have seldom, if ever, seen me talking bad about people behind their back
> like you do, seemingly out of habit.

If you're suggesting that by comparison I'm dishonest, I'm afraid I
disagree. What I state is always what I think. But perhaps I am more
willing to accept the social mores that suggest one not insult others
without dire provocation. So I do not always state what I think. If
I did, we probably would have been having this sort of conversation
three years ago.

But mentioning someone in a thread in which he/she has been
participating is not discussing him/her behind his/her back. Do you
think I've done it in some other way?



>>>                                                                 One could
>>> consider your using my name in this context libel [ ... ]
>
>> Is that what you were blithering about, the fact that I used your name
>               ^^^^^^^^^^^^^^^^^^^^^^^^^
>> in the damn documents?  If that offended you, I apologize.  I've
>> removed your name from them.
>
> q.e.d.

"Senselessly talkative, babbling". Precisely.
"Used chiefly as an intensive to express annoyance or contempt."
Unfortunately, also true.


Evidently, you can't comfortably take the same sort of insults you
dish out regularly. There's a number of words for someone like that.
But I don't want to use them and risk hurting your feelings.

> [tl;dr]

-- Scott

John Harris

unread,
May 31, 2013, 5:22:56 AM5/31/13
to
On Wed, 29 May 2013 11:34:35 -0700 (PDT), Scott Sauyet
<scott....@gmail.com> wrote:


<snip>
>> This doesn't make "equivalent expressions" useless, merely that care
>> is needed in using equivalence. E.g in ECMAScript you can't replace 1
>> by 0 + 1 in some circumstances, even if you can replace it by (0 + 1).
>
>I don't really think it's useless. I just think that it is less
>useful for automated refactoring in Javascript than it would be in
>many languages. (This did start as a thread on minification!)

There's an aspect that hasn't been mentioned so far.

If the function's specification says that its source code must contain
the substring "!0" then any modification or refactoring of the
function must obey this requirement. Other parts of the program can
then rely on the function's code containing "!0". (Whether all
browsers can be relied on to preserve it is a seperate discussion).

On the other hand, if the function's specification does not mention
the source code then any programmer who relies on the code containing
a certain substring should be sacked on the grounds that he has
endangered the project, and possibly the company.

Presumably it's a rare minifying/refactoring tool that has heard of
function specification, alias pre- and post-conditions, alias design
by contract.

I really don't think javascript is all that weaker than other
languages in this respect. Obviously, your opinion leans the other
way, but we both agree that the magic word is BEWARE!


>I'm sure I'm going to give myself a dope slap when you present one,
>but I can't come up with an example of the "0 + 1" issue. Can you
>supply one?
<snip>

You'll kick yourself :
"" + 0 + 1 is "01",
"" + (0 + 1) is "1".
Do minifiers know this ?

John

Christoph Becker

unread,
May 31, 2013, 7:04:10 AM5/31/13
to
Or even without type conversion:

2 * 0 + 1 !== 2 * (0 + 1)

--
Christoph M. Becker

Scott Sauyet

unread,
May 31, 2013, 10:25:12 AM5/31/13
to
John Harris wrote:
> Scott Sauyet wrote:

>>> This doesn't make "equivalent expressions" useless, merely that care
>>> is needed in using equivalence. E.g in ECMAScript you can't replace 1
>>> by 0 + 1 in some circumstances, even if you can replace it by (0 + 1).
>
>> I don't really think it's useless.  I just think that it is less
>> useful for automated refactoring in Javascript than it would be in
>> many languages.  (This did start as a thread on minification!)
>
> There's an aspect that hasn't been mentioned so far.
>
> If the function's specification says that its source code must contain
> the substring "!0" then any modification or refactoring of the
> function must obey this requirement. Other parts of the program can
> then rely on the function's code containing "!0". (Whether all
> browsers can be relied on to preserve it is a seperate discussion).
>
> On the other hand, if the function's specification does not mention
> the source code then any programmer who relies on the code containing
> a certain substring should be sacked on the grounds that he has
> endangered the project, and possibly the company.

I haven't seen any cases as scary as this. The main usage I've seen
of the function serialization was to do something with parameter
names. And I have never coded anything myself that depended on it.
But I've seen several tools that disallowed minification because
minifiers changed function parameter names and the infrastructure was
using these names. I never saw how they used those names, but I'm
guessing it must have been some form of function serialization; it's
the only tool I can imagine that would work.



> Presumably it's a rare minifying/refactoring tool that has heard of
> function specification, alias pre- and post-conditions, alias design
> by contract.

Even if the tool authors have heard of them, it's hard to imagine how
to easily integrate DbC into the minification workflow, which doesn't
usually involve actually *testing* the functions in question, never
mind the entire programs.


> I really don't think javascript is all that weaker than other
> languages in this respect. Obviously, your opinion leans the other
> way, but we both agree that the magic word is BEWARE!

I wish I could remember which web framework it was that had this
issue. It wasn't that long ago. It's not so much that I had some
general concern about this, but I saw a live case of this, either in a
presentation or in documentation, not in something I was using. It
was enough to make my more wary than I might have otherwise been.

Minification is a different type of refactoring than most automated
ones I've seen. The restructuring involved often ends up much more
radical. It's pretty much essential for large web applications, and I
can't see any alternative. But I do think one needs to be more
careful in JS than in other languages which don't often try this
degree of automated refactoring, certainly not in a single step!


>> I'm sure I'm going to give myself a dope slap when you present one,
>> but I can't come up with an example of the "0 + 1" issue.  Can you
>> supply one?
>
>   <snip>
>
> You'll kick yourself :
>   "" + 0 + 1    is  "01",
>   "" + (0 + 1)  is  "1".
> Do minifiers know this ?


Dope slap administered! Because we were talking about expressions, I
wasn't considering places where `0 + 1` was a subexpression. D'Oh.

-- Scott

Thomas 'PointedEars' Lahn

unread,
May 31, 2013, 12:01:04 PM5/31/13
to
Christoph Becker wrote:

> John Harris wrote:
>> Scott Sauyet wrote:
>>> I'm sure I'm going to give myself a dope slap when you present one,
>>> but I can't come up with an example of the "0 + 1" issue. Can you
>>> supply one?
>> <snip>
>>
>> You'll kick yourself :
>> "" + 0 + 1 is "01",
>> "" + (0 + 1) is "1".
>
> Or even without type conversion:
>
> 2 * 0 + 1 !== 2 * (0 + 1)

The question not quoted here was

>> Do minifiers know this ?

I think – I do *hope* – all minifiers preserve precedence. Otherwise they
would really be useless. Those are obviously _not_ equivalent expressions.

One might think that this is a case special to ECMAScript implementations
because of the overloaded “+” operator. There is a sort of implicit
precedence here:

"" + 0 + 1 ≡ ("" + 0) + 1 ≡ "0" + 1 ≡ "01"
1 + 0 + "" ≡ 1 + (0 + "") ≡ 1 + "0" ≡ "10"

However, for example in Python 3:

----------------------------
#!/usr/bin/env python3

class MyString (str):
def __add__ (self, rhs):
# AIUI, "%s%s" % (self, rhs) is simpler but deprecated in Py3k
return MyString("{0}{1}".format(self, rhs))

s = MyString()

# 01\n
print(s + 0 + 1 + "\n")
----------------------------

Or in C++ (compiled with g++ on GNU/Linux):

----------------------------
#include <string>
#include <iostream>
#include <sstream>
using namespace std;

string operator+ (const string& lhs, const int& rhs) {
ostringstream converter;
converter << lhs << rhs;
return converter.str();
}

int main () {
string s = "";

/* 01\n */
cout << s + 0 + 1 << endl;
}
----------------------------

All it takes is a programming language that overloads the “+” operator or
allows overloading of the “+” operator :)

[I would be interested to know if and how the second case can be done in
Python, C++ or any other non-ECMAScript language. Apparently in C++

----------------------------
string operator+ (const int& lhs, const string& rhs) {
ostringstream converter;
converter << lhs << rhs;
return converter.str();
}
----------------------------

results in

"1"

for

1 + 0 + s

because 1 + 0 takes precedence. But the “+” operator for the “int” type
cannot know about the third operand “s”, can it?

And in Python apparently it always takes an explicit typecast –

----------------------------
class MyInt (int):
def __add__ (self, rhs):
# AIUI, "%s%s" % (self, rhs) is simpler but deprecated in Py3k
return "{0}{1}".format(self, rhs)

i = MyInt(1)

# "10"\n
print(i + 0 + "" + "\n")
----------------------------

– which is not what I am looking for.]

--
PointedEars

Thomas 'PointedEars' Lahn

unread,
May 31, 2013, 12:13:24 PM5/31/13
to
[Supersedes; 1 + 0 + "" === "1"]

Christoph Becker wrote:

> John Harris wrote:
>> Scott Sauyet wrote:
>>> I'm sure I'm going to give myself a dope slap when you present one,
>>> but I can't come up with an example of the "0 + 1" issue. Can you
>>> supply one?
>> <snip>
>>
>> You'll kick yourself :
>> "" + 0 + 1 is "01",
>> "" + (0 + 1) is "1".
>
> Or even without type conversion:
>
> 2 * 0 + 1 !== 2 * (0 + 1)

The question not quoted here was

>> Do minifiers know this ?

I think – I do *hope* – all minifiers preserve precedence. Otherwise they
would really be useless. Those are obviously _not_ equivalent expressions.

One might think that this is a case special to ECMAScript implementations
because of the overloaded “+” operator. There is a sort of implicit
precedence here:

"" + 0 + 1 ≡ ("" + 0) + 1 ≡ "0" + 1 ≡ "01"
1 + 0 + "" ≡ (1 + 0) + "" ≡ "1" + 1 ≡ "1"

However, for example in Python 3:

----------------------------
#!/usr/bin/env python3

class MyString (str):
def __add__ (self, rhs):
# AIUI, "%s%s" % (self, rhs) is simpler but deprecated in Py3k
return MyString("{0}{1}".format(self, rhs))

s = MyString()

# 01\n
print(s + 0 + 1 + "\n")
----------------------------

Or in C++ (compiled with g++ on GNU/Linux):

----------------------------
#include <string>
#include <iostream>
#include <sstream>
using namespace std;

string operator+ (const string& lhs, const int& rhs) {
ostringstream converter;
converter << lhs << rhs;
return converter.str();
}

string operator+ (const int& lhs, const string& rhs) {
ostringstream converter;
converter << lhs << rhs;
return converter.str();
}

int main () {
string s = "";

/* 01\n */
cout << s + 0 + 1 << endl;

/* 1\n */
cout << 1 + 0 + s << endl;
}
----------------------------

All it takes is a programming language that overloads the “+” operator or
allows overloading of the “+” operator :)

[I would be interested to know if and how the second case can be done in
Python or any other non-ECMAScript language.

----------------------------
class MyInt (int):
def __add__ (self, rhs):
return "{0}{1}".format(self, rhs)

# "1"\n
print(MyInt(1 + 0) + "" + "\n")
----------------------------

Thomas 'PointedEars' Lahn

unread,
May 31, 2013, 12:16:48 PM5/31/13
to
Thomas 'Ingrid' Lahn wrote:

> One might think that this is a case special to ECMAScript implementations
> because of the overloaded “+” operator. There is a sort of implicit
> precedence here:
>
> "" + 0 + 1 ≡ ("" + 0) + 1 ≡ "0" + 1 ≡ "01"
> 1 + 0 + "" ≡ (1 + 0) + "" ≡ "1" + 1 ≡ "1"

Correction:

1 + 0 + "" ≡ (1 + 0) + "" ≡ 1 + "" ≡ "1"

> [but …]

--
PointedEars

imma harper

unread,
May 31, 2013, 12:46:23 PM5/31/13
to
I feel it worth noting here that code that processes the source of other functions is not relevant to minification as it can be constructed to break under any and all code changes. Arguing about it's relevance does not help the initial post.

On topic: !0 vs true is a size-vs-speed issue, as they resolve to exactly the same
If the code is executed millions of times, it's likely not worth the download speed change (although it could be worth testing, if it's that major an issue) but it could still be worth the bandwidth costs
If the code is almost never executed (under average use - ie it covers an unusual edge case) then clearly saving the download speed and bandwidth would be worth it assuming you don't need to debug client-side ;-)

Thomas 'PointedEars' Lahn

unread,
May 31, 2013, 3:38:57 PM5/31/13
to
imma harper wrote:

> I feel it worth noting here that code that processes the source of other
> functions is not relevant to minification as it can be constructed to
> break under any and all code changes. Arguing about it's relevance does
> not help the initial post.

ACK. That is what I thought of Scott's argument, along the lines of “red
herring” or even “strawman argument”.

> On topic: !0 vs true is a size-vs-speed issue, as they resolve to exactly
> the same If the code is executed millions of times, it's likely not worth
> the download speed change (although it could be worth testing, if it's
> that major an issue)

Yes, I think we have already agreed on that.

> but it could still be worth the bandwidth costs If the code is almost
> never executed (under average use - ie it covers an unusual edge case)
> then clearly saving the download speed and bandwidth would be worth it
> assuming you don't need to debug client-side ;-)

I do not follow. If the code is almost never executed, and it covers an
unusual edge case, then there would be few occurrences of it and the amount
of space saved to replace few “true” with “!0” would be negligibly small.
Also, I am puzzled by your reference to unnecessary “client-side
debugging” – where else would you debug code that runs in a browser? Are
you just joking after all?

You have posted out of thread, without quoting, and with lines that are 241
characters long. Please do not use Google Groups for posting if you cannot
work around its bugs. TIA.

<http://jibbering.com/faq/#posting>
<http://PointedEars.de/faq#posting>

<FAQENTRY> Perhaps a subsection about the problems caused by posting via
Google Groups should be added? </FAQENTRY>

John Harris

unread,
Jun 1, 2013, 12:37:29 PM6/1/13
to
But as SS has pointed out, the minified program will die horribly if
some other part of the program relies on the substring "true"
occurring in the source code.

John

Dr J R Stockton

unread,
Jun 2, 2013, 4:03:00 PM6/2/13
to
In comp.lang.javascript message <gMWdnU1mmO68hwPMnZ2dnUVZ_sqdnZ2d@westne
t.com.au>, Thu, 23 May 2013 23:31:01, Andrew Poulos
<ap_...@hotmail.com> posted:

>I'm working with some people who write code and minimises it. As ab
>afterthought, I unminimise some of it and worked my way through it.
>
>One thing I found was that the minimiser had converted all instances of
>true to !0.
>
>When I reported it no one thought it an issue as both true and !0 are
>truthy. Should they be concerned?


That depends on the purpose of the minimisation.

If it is a pure intellectual challenge, to minimise given code without
affecting the result, then they should not be at all concerned, unless
the code reads its own source in which case special care is needed.

In days of yore, AIUI & IIRC, it generally took a fortnight's work to
reduce the size of DEC's RT-11 OS by a single 16-bit word - and that was
considered worth-while if enough space was freed to accommodate a real
improvement to the product.

My own site has examples of minimised code for Easter Sunday, in
addition to examples of comprehensible code derived from the original
formal authorities.


Where script is intended and expected to be executed very many times
without ever being intended to be read as text, it is appropriate to do
at least some programmed minimisation on the public-facing version -
removal of leading and trailing white-space and blank lines, and of some
or all comment, for example.

--
(c) John Stockton, nr London, UK. E-mail, see Home Page. Turnpike v6.05.
Website <http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc. : <http://www.merlyn.demon.co.uk/programs/> - see in 00index.htm
Dates - miscdate.htm estrdate.htm js-dates.htm pas-time.htm critdate.htm etc.

Scott Sauyet

unread,
Jun 3, 2013, 7:45:02 AM6/3/13
to
Dr J R Stockton wrote:
> Andrew Poulos posted:
>> [ ... ]
>> One thing I found was that the minimiser had converted all instances of
>> true to !0.
>
>> When I reported it no one thought it an issue as both true and !0 are
>> truthy. Should they be concerned?
>
> That depends on the purpose of the minimisation.
> [ ... ]
>
> Where script is intended and expected to be executed very many times
> without ever being intended to be read as text, it is appropriate to do
> at least some programmed minimisation on the public-facing version -
> removal of leading and trailing white-space and blank lines, and of some
> or all comment, for example.

One note on the removing of comments, though. A technique I've seen
in a number of places, and linked to again in the most recent
JavaScript Weekly [1], is the technique described at

<http://tomasz.janczuk.org/2013/05/multi-line-strings-in-
javascript-and.html>

of creating multi-line strings in Javascript as the commented bodies
of functions. The author was specifically talking about using this in
Node.js, and hence taking advantage of the known feature of V8. The
example is this one:

var html = (function () {/*
<!DOCTYPE html>
<html>
<body>
<h1>Hello, world!</h1>
</body>
</html>
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];

Because several minifiers have a mechanism to exempt certain comments
from minification, this is at least feasible in certain browser-based
environments, even after minification. But it fails in recent
SpiderMonkey versions and is certainly not to be recommended for the
browser. Nonetheless, it's another interesting data point in the use
of function serialization.

-- Scott
_____
[1] http://javascriptweekly.com/archive/132.html

Dr J R Stockton

unread,
Jun 4, 2013, 12:23:28 PM6/4/13
to
In comp.lang.javascript message <de4181c7-fcd1-490f-87b7-21fcf3d042ce@m8
g2000yqf.googlegroups.com>, Mon, 3 Jun 2013 04:45:02, Scott Sauyet
<scott....@gmail.com> posted:

>Dr J R Stockton wrote:

>> Where script is intended and expected to be executed very many times
>> without ever being intended to be read as text, it is appropriate to do
>> at least some programmed minimisation on the public-facing version -
>> removal of leading and trailing white-space and blank lines, and of some
>> or all comment, for example.
>
>One note on the removing of comments, though. A technique I've seen
>in a number of places, and linked to again in the most recent
>JavaScript Weekly [1], is the technique described at
> ...

I wrote "some or all comment" because
(a) I could not immediately think of any non-removable comment,
(b) [a few] cunning people like you exist.

A valuable response.
0 new messages