
A Javascript journey with only six characters - Jazcash
http://jazcash.com/a-javascript-journey-with-only-six-characters/
======
qwertyuiop924
I'm a fan of Javascript. It has proper lambdas, true lexical scope, will soon
have TCO, and is a really flexable language.

But it's not without its warts, and this is one of the worst. Although it's
sometimes fun to mess with, nonetheless.

To see this taken to one of its logical extremes, check out If Hemmingway
Wrote Javascript's entry for Douglas Adams:

    
    
      // Here I am, brain the size of a planet, and they ask me to write JavaScript...
      function kevinTheNumberMentioner(_){
        l=[]
        /* mostly harmless --> */ with(l) {
     
          // sorry about all this, my babel fish has a headache today...
          for (ll=!+[]+!![];ll<_+(+!![]);ll++) {
            lll=+!![];
            while(ll%++lll);
            // I've got this terrible pain in all the semicolons down my right hand side
            (ll==lll)&&push(ll);
          }
          forEach(alert);
        }
     
        // you're really not going to like this...
        return [!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]];
      }

~~~
djsumdog
For those of you too lazy to open up a Javascript console, it's a function
that returns "42".

~~~
qwertyuiop924
It also alerts all the primes between 0 and its arg.

------
madflame991
The title is incorrect; you need "!" and the only reason why I clicked on the
article was that doing it without "!" would be a BIG deal. The title of the
original article is "A Javascript journey with only six characters" and the
topic has been posted/reposted and explained more times than I can count on HN

~~~
Jazcash
Oh sorry, how could I miss that :( Fixed it now

------
kukx
Wat
[https://www.destroyallsoftware.com/talks/wat](https://www.destroyallsoftware.com/talks/wat)

~~~
thehesiod
I created an account just to thank you for that post, so funny :)

------
tempodox
This is an extreme demonstration of the validity of a delightfully snarky blog
post by Robert Harper on how dynamic typing is actually static typing using a
unitype:

[https://existentialtype.wordpress.com/2011/03/19/dynamic-
lan...](https://existentialtype.wordpress.com/2011/03/19/dynamic-languages-
are-static-languages/)

A string is a Boolean is a number is a function, and braindead conversions can
happen without anyone noticing. How does one keep their sanity using a
language like that?

~~~
jorams
What the OP takes to the extreme is a property of _weak_ typing, not dynamic
typing.

These properties are separate issues. A language is either statically typed or
dynamically typed, and it is also either strongly typed or weakly typed.

In a statically typed language, types are attached to variables. In a
dynamically typed language, types are attached to values. Do note that many
languages don't fit 100% into either category. (Note that the blog post you
linked to calls types attached to values _classes_ , but that distinction
often isn't made so clearly.)

A weakly typed language performs implicit type conversions as it deems
necessary, while a strongly typed language does no implicit type conversions.
Most languages don't fit 100% into either category. Usually languages that are
considered to be strongly typed still allow you to add integers to floating
point numbers, for example.

It is possible for a dynamically typed language to be so strongly typed that
it won't do any implicit type conversion, ever. Such a language would not
allow you to, say, add an integer and a floating point number without
explicitly converting one to the other.

It is also possible for a statically typed language to be so weakly typed that
it implicitly converts types everywhere. Such a language might do the exact
same things the OP uses, like converting a function to a string of its source
code when adding it to a string.

~~~
catnaroek
> In a statically typed language, types are attached to variables.

More precisely, _expressions_ may be typed. Of course, free variables are one
particular of expression.

> In a dynamically typed language, types are attached to values.

More precisely, _tags_ are attached to _objects_. An object is a “physical”
entity that exists in space (computer memory) and time (from its construction
to its destruction or garbage collection). A value is an abstract and
atemporal entity that only exists in the language's semantics.

> Such a language would not allow you to, say, add an integer and a floating
> point number without explicitly converting one to the other.

But it _does_ allow you to add integers and floating points! The result just
_happens_ to be an exception, which is a very well defined operation in the
semantics of most high-level languages.

If it weren't allowed, it simply wouldn't happen.

~~~
tempodox
In a dynamic language, you have to wait until runtime to decide whether an
operation is valid or not. Only then can you check an object's tag to see if
it proclaims the right type. If it doesn't, non-local exit (of which the
exception is the most popular form), is still the best you can do. So, cum
grano salis, throwing an exception is a dynamic language's way of disallowing
invalid operations.

~~~
catnaroek
This isn't true. Throwing an exception is a perfectly valid operation. Of
course, it is not the operation you want, but that's a-whole-nother matter.

~~~
tempodox
I didn't say throwing an exception is an invalid operation.

How does your dynamic language tell its user an operation is invalid, based on
argument type?

~~~
catnaroek
> How does your dynamic language tell its user an operation is invalid, based
> on argument type?

It doesn't! That's exactly the point. If something is invalid, then it can't
happen. At all.

~~~
tempodox
If only. What language are you talking about, exactly? This unicorn I have to
see.

~~~
catnaroek
Any memory-safe language? Say, Python. `[] / []` is a perfectly valid
operation: its result is a raised exception misleadingly called `TypeError`.
OTOH, in most typed languages, this is a genuinely invalid operation, and it
can't happen at all.

------
shp0ngle
Why do I feel like I have read this article a few years ago? I remember it,
but it has 2016...

~~~
colejohnson66
Because this technique was used to bypass EBay's JS blocker a while back.

~~~
alxndr
Interesting, any chance you have a link to a writeup of that?

~~~
colejohnson66
[http://blog.checkpoint.com/2016/02/02/ebay-platform-
exposed-...](http://blog.checkpoint.com/2016/02/02/ebay-platform-exposed-to-
severe-vulnerability/)

[http://thedailywtf.com/articles/bidding-on-
security](http://thedailywtf.com/articles/bidding-on-security)

~~~
alxndr
Thanks!

------
Centime
Without parenthesis (requires 8 characters though):

[http://centime.org/jsfsck/](http://centime.org/jsfsck/)

------
JelteF
The article does not explain how it gets the {}, which is used to get the
Object constructor string. Other than that it's very clear.

~~~
kukx
It does, see the "fill" step: «So now we have acquired the following extra
characters: c,o,v,(,),{,[,],}, .».

~~~
JelteF
Those characters are only inside a string, not as executable code.

~~~
softawre
But you can execute strings...as it says in the article.

~~~
JelteF
Yes, but not at that point in the article yet...

------
fibo
Wow, JavaScript is also an esoteric Language.

I remember similar strange and interesting stuff in Perl, like the spaceship
operator.

------
lell
Reminds me a bit of the quest for alphanumeric shell code.

------
novaleaf
Does anyone know a good sandboxing technology to execute user written
javascript in a safe way? (like, on other user machines or on the server)? I
have some ideas like "learn programming" that would benefit from this
immensely.

~~~
dougk16
[https://developers.google.com/caja/](https://developers.google.com/caja/)

Used it a few years ago. It was a little finnicky to get working right but I
was impressed at the time. No idea where the project is at nowadays.

~~~
AgentME
Note that caja doesn't protect against local denial-of-service attacks: user-
written javascript executed with it could allocate tons of memory or run
forever (`while(true){}`). This may or may not be a problem depending on your
use-case. (If you're using caja for code written by mostly-trusted 3rd
parties, or for one user's code only on their own machine, then it's not much
of an issue. If you're serving code written by one user to another, then it
could be a problem.)

~~~
dougk16
Ha, here's an old thread where I asked the caja developers about that exact
scenario: [https://groups.google.com/forum/#!topic/google-caja-
discuss/...](https://groups.google.com/forum/#!topic/google-caja-discuss/RAi-
hHiClRA)

Some possible mitigations but I don't know if they ever implemented them.

------
sjclemmy
This is quite timely. I was looking at a library the other day which had IIFEs
preceded by '+'. I wondered what the purpose was. Now I know!

------
joshschreuder
I saw a similar video recently called Code Without Keywords which was quite
interesting.

[https://www.youtube.com/watch?v=LG-
ozmTnhdI](https://www.youtube.com/watch?v=LG-ozmTnhdI)

------
keyle
I knew about these languages but I've never understood how they were made.
This is a fun, fantastic article! These articles make me excited about
technology. Even bad ones.

------
pvdebbe
I sighed with relief that the characters were not emoji.

------
CiPHPerCoder
> Javascript is a weird and wondeful language that lets us write some crazy
> code

Wondeful! A typo six words in.

~~~
omnimus
Why do you care?

~~~
CiPHPerCoder
I thought it was an amusing parallel to the title.

------
amelius
I'm getting a browser security warning on the url on Android.

------
a_c
I don't see the point of a programming language allowing itself braining
fucking its users(developer) for serious use

~~~
arundelo
If you don't like JavaScript's type coercion rules, fair enough. But if you're
criticizing the fact that you can write JavaScript programs with nothing but
punctuation characters, remember that no-one ever does so except as a joke,
and that you can do ridiculous stuff in most languages. (Try Googling
"obfuscated $YOUR_FAVORITE_LANGUAGE".)

------
mooveprince
One more reason for the world to hate JavaScript ? :(

------
kyriakos
this is insane. someone should create a js obfuscator that converts human
readable code to this.

~~~
Normal_gaussian
It is linked at the end of the article:

[http://www.jsfuck.com/](http://www.jsfuck.com/)

~~~
mxfh
some how the link to
[http://aem1k.com/aurebesh.js/](http://aem1k.com/aurebesh.js/) is missing,
where he takes this one step further.

------
eweise
So glad I don't write in a "weird and wondeful language that lets us write
some crazy code that's still valid"

------
catscratch
This doesn't make me want to use JS. The power of JS is in two things, it's in
every major browser and it doesn't completely suck. JS syntax kind of sucks.
The power in JS is that it's dynamic and lets you send functions around, but
defining functions is much uglier than defining a lambda in Ruby:

-> {anything goes here}

or

->(a,b,c) {anything goes here}

The problem with Ruby is that you then have to .() the lambda vs. (), so that
is more verbose than just calling the function.

If browsers were to embrace a language that was more Ruby-like and less clunky
than JS, I'm sure I'd use it more.

~~~
zuck9
ES6 lets you define functions like a => a * 2

Or (a, b, c) => a * b ^ c

~~~
catscratch
That's succinct, but less clear than the Ruby version, imo, as you don't have
any scope indicators required for the function body.

JS:

    
    
      let f = (a,b,c) => a * b ^ c;
      f(2,3,4);
    

vs. Ruby:

    
    
      f = ->(a,b,c) { a * b ^ c }
      f.(2,3,4)
    

Ruby's shorter and clearer. But, when you use the Ruby lambda more than once
in the code, you lose the brevity advantage, because of the "extra" dot. But,
in Ruby I use methods more than lambdas, which would be:

    
    
      def f(a,b,c) { a * b ^ c }
      f(2,3,4)

~~~
qaq
None is preventing you from writing let f = (a,b,c) => {a * b ^ c}; in JS

~~~
1000hz
when you include curly braces in arrow functions you lose the implicit return,
so this function would return undefined

~~~
johnhenry
You can get the implicit return if you use parentheses instead:

f = (a,b,c) => (a * b ^ c)

