

Why ++[[]][+[]]+[+[]] = 10 in JavaScript - smharris65
http://stackoverflow.com/questions/7202157/can-you-explain-why-10

======
wonnage
Seems like "this is why Javascript sucks!" is a common reaction here, which I
find strange on a "hacker" community. It's a fun little brainteaser, not
production code. Use your head a little?

~~~
romaniv
It demonstrates language issues that can (and often do) lead to problems in
production. So the response is completely appropriate.

~~~
wonnage
About the only problem I can think of here is that it makes it harder to
filter/sanitize for XSS. But I don't think the problem here is Javascript.
Look at SQL injection - trying to escape user input is just an endless game of
whack-a-mole. The proper way to deal with it is parameterized queries. HTML
doesn't have anything similar AFAIK.

------
thought_alarm
My question is, _when_ did that start working in Javascript?

Does this trick work in Brendan Eich's first JS implementaion in Netscape 2.0?
Which came first, the spec or the implementation?

~~~
statictype
Funny thing, that.

The implementation came first. From what I understood, Microsoft looked at
Netscape's implementation, wrote a spec from that and implemented it - so when
time came to standardize it, Microsoft had a readily available spec (having
written one after reverse engineering Netscape's implementation). Since
Javascript has lots of little quirks, Microsoft didn't quite get everything
right and so when the final spec was published, Netscape's implementation was
actually in violation of it in a couple of places.

I guess that's funny depending on who you are.

------
gmcabrita
((__=!($=[]))+$)[$++]+(_={}+$)[$]+_[$++]+_[$]+(__+_)[--$]+(!__+_)[$]

returns "foobar"

------
billpg
This sort of thing really bothers me with Javascript. Using the unary +
operator on an array should be an error. Hiding errors by having implicit type
convertions doesn't help me fix those errors.

You may say that users don't need to see to see strange error messages they
don't understand. Quite right, what we need instead is to have a way for
browsers to transmit uncaught exceptions in JS to the server.

~~~
esrauch
What should the unary + operator do except for type coercion into a number? Or
are you saying it should only work on strings?

It just doesn't seem like something that would happen accidentally, there's no
reason to put + on something unless you are explicitly trying to coerce it
into a number. It's not like unary minus where -x; could have some other
semantic meaning for something that is already a number and you make a mistake
and give it an array (which javascript has, and I think is a much more likely
source of error than the unary plus).

~~~
billpg
Using an array (or a string for that matter) where only a number should be is
an error. I'd like to see an exception thrown and the current JS uncaught-
exception-handler would be invoked, assuming something else catches it.

If I want an array to be a number, I'll call .Count on the array or whatever
the applicable property I want is.

~~~
esrauch
I don't think you understand what I am trying to say.

The unary '+' operator is completely pointless if something is already a
number, it is a no-op. Literally the only time anyone would ever type +x is if
x is _not_ a number, if someone chose to write +x and x turned out to
unexpectedly be an array, pretty much the only thing that you know they were
thinking of when they wrote the + was that they thought x isn't a number;
maybe a string if they were using +x instead of parseFloat(x), but definitely
not a number.

It just isn't a reasonable example of a situation where an array is being used
where a number should be, +x where you know that x is a number would make no
sense. If you talk about -x then that is completely different, people who
write -x almost certainly expect it to be a number, and -[] === 0. Unary plus
is just not the right example for awful type coercion here.

------
raganwald
From wtfjs.com:

    
    
      ",,," == Array((null,'cool',false,NaN,4)); // true

~~~
blurbytree
Clever, but not as surprising...

(null,'cool',false,NaN,4) evaluates to the last expression - 4

Array(4) creates an array with 4 elements.

Array(4).toString() = ",,,"

~~~
bretthoerner
You describe that as "not surprising"? Yikes.

~~~
blurbytree
It's surprising if you haven't used javascript before I guess.

~~~
pawn
You can use javascript for years and never come across a situation where you'd
do or see several of the things found in that small statement.

~~~
blurbytree
There are only 3 things, which aren't surprising to anyone who has done much
js.

    
    
      1). a list of expressions eg (foo,bar,baz) evaluates to the last one.
      2). Array(4) creates an empty array of 4 elements
      2). Array(4).toString() = ",,,"

~~~
bonobo
I don't think the comma operator wouldn't be surprising to an experienced js
programmer. I can't remember a single piece of serious code where I could see
it in use.

The same applies to the void operator, I can think of one or two cases at most
where it would be useful, but I don't see anyone using it.

------
zackzackzack
Thought some and came up with an way to convert whichever natural number you
want into this form.

<https://gist.github.com/1531201>

It depends on underscore.js for the functional bits.

~~~
pavel_lishin
Wow, those are _really_ unfortunate variable names.

I've never seen the term "gook" outside of a racial slur context.

~~~
zackzackzack
Changed. Figured that the time it would have taken to write up something about
people being able to look past racial slurs blah blah blah was more than just
"fixing" it.

~~~
zackzackzack
Also, I meant to say thank you as well. I would like to avoid offending anyone
with variable name choices. So, thank you for pointing that out.

------
SanjayUttam
Reminds me of: <http://adamcecc.blogspot.com/2011/01/javascript.html>

------
gosub
I can't find a link to a page, from some time ago, in which every letter and
number was obtained combining only parentheses and punctuation.

~~~
blurbytree
It's linked directly in the original question?

<http://sla.ckers.org/forum/read.php?24,33349,33405>

------
tingletech
related: <http://news.ycombinator.com/item?id=1154338>

------
ajankovic
I wonder how people come up with this kind of code to begin with?

~~~
flpmor
This comes from an attempt to write valid JavaScript without using any letters
or numbers. It's partly for the sake of demonstrating it's possible and part
for security testing reasons, to show that poorly written input validation
filters can be bypassed.

~~~
vineetdhanawat
True! you wont use it. I guess it'll end up being just an Interview Question.

~~~
raganwald
The correct interview question is, “Write a filter that blocks executable
JavaScript but allows text.” And the correct answer is “Kobayashi Maru."

~~~
kls
_The correct interview question is, “Write a filter that blocks executable
JavaScript but allows text._

I would hire you on the spot, my post history is littered with how irrelevant
these type of questions are to gauging ones ability to develop real world
solutions. You pretty much summed up the irony nicely.

------
recoiledsnake
This is the reason I prefer strongly typed languages. Allowing developers to
play fast and loose with data types only leads to less maintainability down
the road and makes code difficult to read.

~~~
raganwald
I am not a PL expert, but is this a strong vs. weak type problem or an
implicit conversion problem? My layman’s (simplistic) model is that “weakly
typed” languages allow entities to change their type at runtime, strongly
typed languages do not.

But what we have here is an expression where entities are being implicitly
converted into intermediate values, along with operators that do different
things based on the values they are given. For example, the behaviour of the
“+” infix operator in JavaScript could be replicated in any strongly typed
language that has pattern matching:

    
    
      x:string + y:string -> concat(x,y)
      x:stringable + y:string -> concat(toString(x), y)
      x:string + y:stringable -> concat(x, toString(y))
      x:numeric + y:numeric -> sum(x,y)
      ...
    

I recall implicit conversion being one of the gotchas in C++. While its casts
break strictly strong typing, a program with lots of implicit conversions can
behave just about as mysteriously as the example JavaScript.

Back in the day when I wrote C++ (by gaslight, after I rode my penny farthing
to the office), any one-argument constructor was presumed to be an implicit
conversion unless you provided the “explicit” keyword.

UPDATE (and thanks to the hacker who pointed me in this direction):

<http://en.wikipedia.org/wiki/Strong_typing>

It seems that the expression “Strong typing” subsumes both the concept of
static typing (variables and/or values do not change their types) and of
coercion. (Along with other issues such as whether programmers can
deliberately evade restrictions).

If I were to rewrite my question, I would ask if this is a strong typing
problem overall or just the subset of strong typing issues concerning
coercion?

So part of the issue with this code is implicit coercion, which is not “strong
typing,” but the other is polymorphic operators like “+”, which are
independent of strong vs. weak typing.

~~~
extension
Wikipedia has a good page on this subject. In a nutshell, "strong/weak" typing
is not formally defined. Usually languages are called weakly typed when they
allow a lot of implicit type coercion or just don't strictly enforce types.
It's not at all unique to dynamically typed languages. C is pretty weakly
typed, for example. And a static language could just as easily have a quirk
like this JavaScript thing.

<http://en.wikipedia.org/wiki/Weak_typing>

Update to your update:

Strong typing does not subsume static typing. Ruby, for example, is dynamic
and quite strongly typed. You can't bypass the type system at all, and the
only real coercion is to boolean, which follows a very simple rule.

~~~
raganwald
While the phrases don’t seem to have strict definitions, by the Wikipedia
description of Strong Typing ,there is an overlap with Static Typing:

 _The mandatory requirement, by a language definition, of compile-time checks
for type constraint violations. That is, the compiler ensures that operations
only occur on operand types that are valid for the operation. However, that is
also the definition of static typing, leading some experts to state: "Static
typing is often confused with StrongTyping”..._

 _Fixed and invariable typing of data objects. The type of a given data object
does not vary over that object's lifetime. For example, class instances may
not have their class altered._

<http://en.wikipedia.org/wiki/Strong_typing>

I guess this is one of those things where the correct response to any claim
about “Strong,” “Static,” “Weak,” or “Dynamic” typing is to ask the speaker
what, specifically, he is thinking of.

In this case, you and I are exploring the subject in some depth, but the
person who originally used the phrase “Strongly Typed” is silent, so neither
of us has any idea what he had in mind.

~~~
justincormack
The thing is in a weakly typed language you can implement functions that do
coercion, while a strongly typed language will not let you as generally there
is a fixed type (or type class) to each parameter. That does not mean the
standard built in or library functions have to do javascript levels of
coercion though, I think there are better balances.

------
ultimatewarrior
Reminds me of the J programming language

~~~
saryant
Hold up, I think I just stumbled on to a fellow alum.

(Surely no other university teaches that language besides mine, right?)

~~~
irrumator
Which university are you talking about?

(I'm learning J and other APL derivatives right now by myself by experimenting
with the J docs and pinging the amazing people at the J software forums).

~~~
saryant
Trinity University in San Antonio. One of our profs has been working on J for
decades.

------
billpg
If you rely on that sort of thing in production code, you're doing it wrong.

~~~
billpg
Wow, -1 points! Are the two of you saying that this is a good thing for
production code?

------
kickingvegas
Putting this in the category of "not going to think hard about this, because
it's only going to make me upset and angry."

