From: Joost Diepenmaat on
beegee <bgulian(a)gmail.com> writes:

> Recently, I've noticed that C# has
> added lambdas and a variant (typeless) type to the latest version.
> The syntax is kind of a nightmare compared to Javascript but it means
> that VM is doing the same kind of "interpretation" that the Javascript
> interpreter is doing. So maybe the difference between these languages
> is that one type is oriented toward compilation and the other is
> oriented toward interpretation even though they have evolved towards
> each other.

This is nothing new. Take a look at Common Lisp for a language that has
both extreme expressiveness and compilers that can produce very fast
code. Anyway the border between interpreted and compiled implementations
is very fuzzy (unless you just mean that you can transform the source
code to some pre-processed byte stream or stand-alone executable, which
is really quite easy and doesn't really mean much. Many languages that are
typically viewed as interpreted (perl, for instance) can do that.

This whole discussion is pretty meaningless.

--
Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
From: dhtml on
On Apr 22, 5:39 pm, Richard Cornford <Richard.Cornf...(a)googlemail.com>
wrote:
> On Apr 21, 10:21 pm, dhtml wrote:
>
> > On Apr 19, 9:02 am, Richard Cornford wrote:
> >> One of the arguments paraded in favour of these libraries is
> >> that they are examined, worked on and used by very large
> >> numbers of people, and so they should be of reasonably high
> >> quality because with many eyes looking at the code obvious
> >> mistakes should not go unnoticed. My experience of looking
> >> at code from the various 'popular' libraries suggests that
> >> this is a fallacy, because (with the exception of YUI (for
> >> obvious reasons))
>
> > Not obvious.
>
> > There's plenty of bugs YUI.
>
> Who is talking about bugs? Take this code from the dojo library:-
>
> | if(
> | elem == null ||
> | ((elem == undefined)&&(typeof elem == "undefined"))
> | ){
> | dojo.raise("No element given to dojo.dom.setAttributeNS");
> | }
>
> The rules for javascirpt dictate then whenever the -
> (elem == undefined) - expression is evaluated (that is, whenever
> - elem == null - is false) the result of the expression must be
> false, and so the - (typeof elem == "undefined") - expression just
> cannot ever be evaluated. The bottom line is that if the author of
> that code had understood javascript when writing it the whole thing
> would have been:-
>
> if(elem == null){
> dojo.raise("No element given to dojo.dom.setAttributeNS");
>
> }
>
> - or possibly:-
>
> if(elem){
> dojo.raise("No element given to dojo.dom.setAttributeNS");
>
> }
>
> - as there should be no issues following from pushing other
> primitive values that have falseness through the exception
> throwing path as well null and undefined.
>
> The first is not a bug; it does exactly what it was written to, and
> does it reliably and consistently. But it is a stupid mistake on the
> part of its 'programmer', and survived in the dojo source for long
> enough to be observed because nobody involved with dojo knew enough
> actual javascript to see that it was a stupid mistake and correct it.
>
> YUI may contain bugs but it does not contain this type of stupid
> mistake because at least one person (and it only takes one) knows
> javascript well enough to be able to see this type of thing and
> stop it (presumably at source by ensuring any potential
> transgressors become better informed bout the language they are
> using).

I really didn't want to be goaded into postup a dumb and dumber
competition with other people's code, but you've left me with not very
good choices.


YUI has some pretty bad/obvious bugs in crucial places. augmentObject,
hasOwnProperty. Dom.contains:-

hasOwnProperty: function(o, prop) {
if (Object.prototype.hasOwnProperty) {
return o.hasOwnProperty(prop);
}

return !YAHOO.lang.isUndefined(o[prop]) &&
o.constructor.prototype[prop] !== o[prop];
},

- Which will throw errors in IE when - o - is a host object and
return wrong results in Opera when - o - is window. augmentObject:-

augmentObject: function(r, s) {
if (!s||!r) {
throw new Error("Absorb failed, verify dependencies.");
}
var a=arguments, i, p, override=a[2];
if (override && override!==true) { // only absorb the
specified properties
for (i=2; i<a.length; i=i+1) {
r[a[i]] = s[a[i]];
}
} else { // take everything, overwriting only if the third
parameter is true
for (p in s) {
if (override || !r[p]) {
r[p] = s[p];
}
}

YAHOO.lang._IEEnumFix(r, s);
}
},


It is questionable strategy to do object augmentation on the prototype
chain of the supplier. It would be better to use hasOwnProperty to
filter the stuff in the supplier's prototype chain out. Next, if the
receiver has a property p with a false-ish value, then the ovveride
flag is irrelevant.

Dojo calls object augmentation "extend" which to me seems to be
misleading.

isAncestor: function(haystack, needle) {
haystack = Y.Dom.get(haystack);
needle = Y.Dom.get(needle);

if (!haystack || !needle) {
return false;
}

if (haystack.contains && needle.nodeType && !isSafari)
{ // safari contains is broken
YAHOO.log('isAncestor returning ' +
haystack.contains(needle), 'info', 'Dom');
return haystack.contains(needle);
}
else if ( haystack.compareDocumentPosition &&
needle.nodeType ) {
YAHOO.log('isAncestor returning ' + !!
(haystack.compareDocumentPosition(needle) & 16), 'info', 'Dom');
return !!(haystack.compareDocumentPosition(needle) &
16);
} else if (needle.nodeType) {
// fallback to crawling up (safari)
return !!this.getAncestorBy(needle, function(el) {
return el == haystack;
});
}
YAHOO.log('isAncestor failed; most likely needle is not an
HTMLElement', 'error', 'Dom');
return false;
}

This would return inconsistent results, depending on the browser.
For example:
YAHOO.util.Dom.isAncestor(document.body, document.body);

Though the last is not as obvious a mistake as the others.

There are considerably questionable practices in the Event library.

The connection manager is horribly designed. The fact that it attempts
to do form serialization within iteself, is just a horrible decision.
If the author had been forced to write a test for that, he'd probably
have moved that form serialization code somewhere else, to make it
easier to test (easier coverage verification).

[snip]

> And where those
> authors are part of a collective they don't speak for the
> knowledge of the specific author responsible but instead
> indicate the level of understanding of the _most_
> knowledgeable person involved.
>

This can lead to blocking code reviews and scape goating. With a test
driven approach, the only thing to blame is the process, and that's
fixable (besides the fact that the test never has any hard feelings).

Without tests, you get things like blood commits and code freezes.
Some libraries actually do code freezes. And they have at least one
expert. And they have bugs. Dumb ones.

> <snip>
>
> > A fix for the bug that was demonstrated seems to be by
> > simply putting the &amp; last.
>
> > String.prototype.unescapeHTML = function() {
> > return this.replace(/&lt;/g,'<')
> > .replace(/&gt;/g,'>')
> > .replace(/&amp;/g,'&');
> > };
>
> > That would need to be tested out though.
>
> No it does not need to be test, it is correct. The general
> rule is that the character significant in escaping needs to
> be processed first when escaping and last when unescaping.
>

It addresses the problem that was demonstrated in your example. It
does not, however, take into consideration the possibility that - this
- could contain * any * other entities.

If the need to handle - &quot; - or &#38; (which is also '&') got
added in later, they'd need to be reviewed by the one, sole expert, to
make sure the person who wrote the amending code didn't make a rookie
mistake. A test could clearly prove it worked.

var s = "&quot;".replace(/&quot;/g, '"');

So the fix addresses only one concern.

another consideration is that String.prototype.escapeHTML should be
stable, but if there's a bug, and dependencies on that bug, then the
fixing of the bug becomes complicated. In may very well be the case
that some novice programmer used escapeHTML, found that it didn't work
right, made some adjustments in his implementation to compensate for
that bug. In essence, his implementation is now depending on that bug.
This is where I see adding things to built-in prototypes to be risky.

If the programmer had made a method, then that method could always be
deprecated in a future release, if found to be problematic.

So, to sum it up, my recommentations:
1) write a test
2) don't put the methods on String.prototype because they might change
later.

> > Right?
>
> Absolutely. It is a simple bug, and a mistake that in my
> experience is made by nearly every programmer who comes to
> the issues of encoding/escaping for the web for the first
> time (pretty much no matter what their previous level of
> experience in other areas). It is something that I have
> learnt to double check, habitually, and that is the reason
> that I spotted it so quickly.
>
That was my first time writing an unescape function in Javascript. I
think I might have written one in Java several years ago in a response
filter exercise, though.

If I had to write something more comprehensive to account for more
entities, I'd probably consider looking into inverting control to the
browser's parser using a combination of newDiv.innerHTML and
newDiv.textContent|innerText

document.body.textContent = "&";
document.body.innerHTML; // &amp;

document.body.innerHTML = "&quot;"
document.body.textContent; // "

Obviously not using document.body, but a newly created node. I would
probably write some tests for that, including the cases you posted,
make sure they all fail, then write out some code (the code could be
changed in the future, since there are tests).

Garrett

> Richard.

From: Peter Michaux on
On May 5, 4:26 pm, "Richard Cornford" <Rich...(a)litotes.demon.co.uk>
wrote:

> But anyone then asserting that, for example, the best way forward with
> Prototype.js would be to delete it and start again from scratch will be
> disregarded even if they think that advice is constructive (and it is
> virtually the only way that it would be possible to correct the mistake
> of violating the language's specification's injunction against using the
> '$' symbol as the initial character in Identifiers except when they were
> machine generated).

ES3 spec:

"The dollar sign is intended for use only in mechanically generated
code."

Both "intended" and "mechanically generated" make the sentence
ambiguous. It is only a recommendation at best.

Since ES is a spec that is based on existing implementations and
language use, I think the safe bet is that such a reservation about $
in identifiers will be removed when ES4 is published.

Peter
From: Richard Cornford on
dhtml wrote:
> On Apr 22, 5:39 pm, Richard Cornford wrote:
>> On Apr 21, 10:21 pm, dhtml wrote:
>>> On Apr 19, 9:02 am, Richard Cornford wrote:
>>>> One of the arguments paraded in favour of these libraries is
>>>> that they are examined, worked on and used by very large
>>>> numbers of people, and so they should be of reasonably high
>>>> quality because with many eyes looking at the code obvious
>>>> mistakes should not go unnoticed. My experience of looking
>>>> at code from the various 'popular' libraries suggests that
>>>> this is a fallacy, because (with the exception of YUI (for
>>>> obvious reasons))
>>
>>> Not obvious.
>>
>>> There's plenty of bugs YUI.
>>
>> Who is talking about bugs? Take this code from the dojo
>> library:-
<snip>
>> The rules for javascirpt dictate then whenever the -
>> (elem == undefined) - expression is evaluated (that is,
>> whenever - elem == null - is false) the result of the
>> expression must be false, and so the -
>> (typeof elem == "undefined") - expression just cannot
>> ever be evaluated. The bottom line is that if the author
>> of that code had understood javascript when writing it
>> the whole thing would have been:-
>>
>> if(elem == null){
>> dojo.raise("No element given to dojo.dom.setAttributeNS");
>>
>> }
>>
>> - or possibly:-
>>
>> if(elem){
>> dojo.raise("No element given to dojo.dom.setAttributeNS");
>>
>> }
>>
>> - as there should be no issues following from pushing other
>> primitive values that have falseness through the exception
>> throwing path as well null and undefined.
>>
>> The first is not a bug; it does exactly what it was written
>> to, and does it reliably and consistently. But it is a
>> stupid mistake on the part of its 'programmer', and
>> survived in the dojo source for long enough to be observed
>> because nobody involved with dojo knew enough actual
>> javascript to see that it was a stupid mistake and correct
>> it.
>>
>> YUI may contain bugs but it does not contain this type of
>> stupid mistake because at least one person (and it only
>> takes one) knows javascript well enough to be able to see
>> this type of thing and stop it (presumably at source by
>> ensuring any potential transgressors become better informed
>> bout the language they are using).
>
> I really didn't want to be goaded into postup a dumb and
> dumber competition with other people's code, but you've left
> me with not very good choices.

You had a choice.

> YUI has some pretty bad/obvious bugs in crucial places.
> augmentObject, hasOwnProperty. Dom.contains:-
>
> hasOwnProperty: function(o, prop) {
> if (Object.prototype.hasOwnProperty) {
> return o.hasOwnProperty(prop);
> }
>
> return !YAHOO.lang.isUndefined(o[prop]) &&
> o.constructor.prototype[prop] !== o[prop];
> },
>
> - Which will throw errors in IE when - o - is a host
> object and return wrong results in Opera when - o - is
> window. augmentObject:-

So? Does the documentation propose that this method is objects other
than native ECMAScript objects?

> augmentObject: function(r, s) {
> if (!s||!r) {
> throw new Error("Absorb failed, verify dependencies.");
> }
> var a=arguments, i, p, override=a[2];
> if (override && override!==true) { // only absorb the
> specified properties

Why do you find it so difficult to cope with posting code that is not
mangled by line wrapping?

> for (i=2; i<a.length; i=i+1) {
> r[a[i]] = s[a[i]];
> }
> } else { // take everything, overwriting only if the
> third parameter is true
> for (p in s) {
> if (override || !r[p]) {
> r[p] = s[p];
> }
> }
>
> YAHOO.lang._IEEnumFix(r, s);
> }
> },
>
>
> It is questionable strategy to do object augmentation
> on the prototype chain of the supplier.

So a "questionable strategy" not a bug?

> It would be better to use hasOwnProperty to
> filter the stuff in the supplier's prototype chain out.

No, it would not. It may, under some circumstances, be better, but it
also may not be; it depends on what outcome you are after.

> Next, if the receiver has a property p with a false-ish
> value, then the ovveride flag is irrelevant.

That may be how the code was programmed, but what makes it a bug?

> Dojo calls object augmentation "extend" which to me seems
> to be misleading.

Misleading code may not be great, much as obscure code may not be great,
but where are the bugs you spoke of?

> isAncestor: function(haystack, needle) {
> haystack = Y.Dom.get(haystack);
> needle = Y.Dom.get(needle);
>
> if (!haystack || !needle) {
> return false;
> }
>
> if (haystack.contains && needle.nodeType && !isSafari)
> { // safari contains is broken
> YAHOO.log('isAncestor returning ' +
> haystack.contains(needle), 'info', 'Dom');
> return haystack.contains(needle);
> }
> else if ( haystack.compareDocumentPosition &&
> needle.nodeType ) {
> YAHOO.log('isAncestor returning ' + !!
> (haystack.compareDocumentPosition(needle) & 16), 'info', 'Dom');
> return !!(haystack.compareDocumentPosition(needle)
> & 16);
> } else if (needle.nodeType) {
> // fallback to crawling up (safari)
> return !!this.getAncestorBy(needle, function(el) {
> return el == haystack;
> });
> }
> YAHOO.log('isAncestor failed; most likely needle is
> not an HTMLElement', 'error', 'Dom');
> return false;
> }
>
> This would return inconsistent results, depending on the browser.
> For example:
> YAHOO.util.Dom.isAncestor(document.body, document.body);

What does the documentation have to say about the expected arguments?

> Though the last is not as obvious a mistake as the others.

So there was no evidence of any bugs in the others and this one is less
obvious than they were?

> There are considerably questionable practices in the Event
> library.

What have "questionable practices" got to do with your suggestion that
you may be presenting "pretty bad/obvious bugs in crucial places"?

> The connection manager is horribly designed. The fact that
> it attempts to do form serialization within iteself, is
> just a horrible decision. If the author had been forced
> to write a test for that, he'd probably have moved that
> form serialization code somewhere else, to make it easier
> to test (easier coverage verification).

So you don't see the difference between writing code that logically
cannot be executed and your opinions about how things should be
designed? Unfortunately your not perceiving that distinction goes quite
some way towards bring into question your opinions on how code should be
designed.

> [snip]
>
>> And where those
>> authors are part of a collective they don't speak for the
>> knowledge of the specific author responsible but instead
>> indicate the level of understanding of the _most_
>> knowledgeable person involved.
>>
>
> This can lead to blocking code reviews and scape goating.

What "can lead to ..."?

> With a test driven approach, the only thing to blame is the
> process, and that's fixable (besides the fact that the test
> never has any hard feelings).

A test driven approach helps nothing when the people designing those
tests are not capable of stressing their code to the point of showing
how were and why it falls over.

> Without tests, you get things like blood commits and code
> freezes. Some libraries actually do code freezes. And they
> have at least one expert. And they have bugs. Dumb ones.

So if YUI is not the library with these bugs (just "questionable
practices", in your opinion) why aren't you naming it here?

>> <snip>
>>
>>> A fix for the bug that was demonstrated seems to be by
>>> simply putting the &amp; last.
>>
>>> String.prototype.unescapeHTML = function() {
>>> return this.replace(/&lt;/g,'<')
>>> .replace(/&gt;/g,'>')
>>> .replace(/&amp;/g,'&');
>>> };
>>
>> > That would need to be tested out though.
>>
>> No it does not need to be test, it is correct. The general
>> rule is that the character significant in escaping needs to
>> be processed first when escaping and last when unescaping.
>>
>
> It addresses the problem that was demonstrated in your
> example. It does not, however, take into consideration
> the possibility that - this - could contain * any * other
> entities.

No, but it was not coded to do that.

> If the need to handle - &quot; - or &#38; (which is also
> '&') got added in later, they'd need to be reviewed by the
> one, sole expert, to make sure the person who wrote the
> amending code didn't make a rookie mistake. A test could
> clearly prove it worked.

Obviously.

> var s = "&quot;".replace(/&quot;/g, '"');
>
> So the fix addresses only one concern.

Yes, it addresses the thing that stops the pair of encoding/decoding
methods being symmetrical.

> another consideration is that String.prototype.escapeHTML
> should be stable, but if there's a bug, and dependencies on
> that bug, then the fixing of the bug becomes complicated.
> In may very well be the case that some novice programmer used
> escapeHTML, found that it didn't work right, made some
> adjustments in his implementation to compensate for that bug.
> In essence, his implementation is now depending on that bug.
> This is where I see adding things to built-in prototypes to
> be risky.

That is a truly lousy argument for not augmenting built-in prototypes,
as it is just as true for any aspect of any public API in any
general-purpose library.

> If the programmer had made a method, then that method
> could always be deprecated in a future release, if found
> to be problematic.

What is to stop a library that augments the built-in prototypes from
deprecating the methods it adds to the prototype?

> So, to sum it up, my recommentations:
> 1) write a test

A reasonable suggestion, but a little superficial. The assertion is that
there was a test for these methods, but that in itself did not expose
the issue.

> 2) don't put the methods on String.prototype because they
> might change later.

You might as well say 'don't put methods anywhere as they might change
later'.

>>> Right?
>>
>> Absolutely. It is a simple bug, and a mistake that in my
>> experience is made by nearly every programmer who comes to
>> the issues of encoding/escaping for the web for the first
>> time (pretty much no matter what their previous level of
>> experience in other areas). It is something that I have
>> learnt to double check, habitually, and that is the reason
>> that I spotted it so quickly.
>>
> That was my first time writing an unescape function in
> Javascript.

But you did have the advantage of knowing that there was something up
with the code as it had been written, which usually makes finding and
fixing an error easier.

> I think I might have written one in Java several years ago
> in a response filter exercise, though.
>
> If I had to write something more comprehensive to account
> for more entities, I'd probably consider looking into
> inverting control to the browser's parser using a combination
> of newDiv.innerHTML and newDiv.textContent|innerText

That is what Prototype.js's other versions of this method do (hence the
cross-browser inconsistencies as it means that those methods will
handle other entities where these version will not).

> document.body.textContent = "&";
> document.body.innerHTML; // &amp;
>
> document.body.innerHTML = "&quot;"
> document.body.textContent; // "
>
> Obviously not using document.body, but a newly created node.
> I would probably write some tests for that, including the
> cases you posted, make sure they all fail, then write out
> some code (the code could be changed in the future, since
> there are tests).

A general entity encoding/decoding method is probably either over the
top or totally unnecessary for most real-world contexts.

Richard.

From: VK on
On May 6, 3:26 am, "Richard Cornford" <Rich...(a)litotes.demon.co.uk>
wrote:
> But anyone then asserting that, for example, the best way forward with
> Prototype.js would be to delete it and start again from scratch will be
> disregarded even if they think that advice is constructive (and it is
> virtually the only way that it would be possible to correct the mistake
> of violating the language's specification's injunction against using the
> '$' symbol as the initial character in Identifiers except when they were
> machine generated).

So are you proposing to trash out a whole library because one of used
identifiers is _not suggested_ yet fully valid? IMO it is an act of
lunatism. Prototype.js has a number of its defaults - but making $
usage as the main reason to drop it makes the poster look ridiculous.
And the least I want to see in c.l.j. is _Richard Cornford_ looking
ridiculous or funny. Upset, sarcastic, nasty - any time, just please
don't make fun of yourself. Can you switch on some _substantional_
library criticism instead?