eval. rinse. reload. and repeat
June 23, 2012 12:18 PM   Subscribe

Having trouble with Javascript? An automated solution, the descendant of a long line of DWIM aids to programming, is at hand. (library name NSFW)

FuckItJS: Javascript Error Steamroller. The aim of FuckItJS? "To make sure your javascript code runs whether your compiler likes it or not"
posted by zippy (44 comments total) 15 users marked this as a favorite


 
I like how the library pretty much the same thing a mediocre programmer would do. I wouldn't be surprised if it significantly reduced IT costs in web design shops.
posted by idiopath at 12:24 PM on June 23, 2012 [1 favorite]


Stupid name aside, I'm not seeing how "whether your compiler likes it or not" is a laudable design goal.
posted by fatbird at 12:24 PM on June 23, 2012


It's a optimization of cut and paste coding, eliminating the paste step.
posted by zippy at 12:25 PM on June 23, 2012 [5 favorites]


"Whether the compiler likes it or not" is a bit glib. It just deletes lines where errors happened, until it works. Even if that is because your program is now empty.

This is useful because with javascript your code is expected to run on a variety of incompatible interpreters, and this saves the trouble of explicitly ifdefing or whatever.
posted by idiopath at 12:26 PM on June 23, 2012 [1 favorite]


Hah. Idiopath, we both need to read the readme.
posted by fatbird at 12:34 PM on June 23, 2012 [4 favorites]


FAQ

1) Is this a good idea?

Of course not. This is quite possibly the worst javascript plugin ever written.

2) Isn't "eval" evil?

See Question #1.
posted by Obscure Reference at 12:36 PM on June 23, 2012 [5 favorites]


Technically javascript isn't compiled, it's interpreted. Of course modern browsers probably do generate machine code from JS to speed it up (And you can use something like the closure compiler as well)
posted by delmoi at 12:37 PM on June 23, 2012 [1 favorite]


This is the best thing since the cat face detector.
posted by ph00dz at 12:44 PM on June 23, 2012 [2 favorites]


I'd prefer if it split-test mutated the code, genetic algorithm style, until your site got an optimal level of traffic, or whatever goal you define. Maybe someday.
posted by iotic at 12:46 PM on June 23, 2012 [3 favorites]


I love this
posted by Philosopher Dirtbike at 12:48 PM on June 23, 2012


Isn't this not going far enough? I'd want a browser plugin that detects and kills scripts that slows down page loads for any reason.

AdBlock and Ghostery are nice for keeping away the stupid. JavaScript Blacklist is nice for keeping away the worst of the worst.

JavaScript Blocker takes this further by requiring that users manually enable every offsite script :   Does your site embed google maps or hit verified by visa, fine I'll enable that for your site. Does your news site hit Google's jQuery.js, yeah that's dumb, no you may not use jQuery.
posted by jeffburdges at 1:02 PM on June 23, 2012


I wonder what it says about the language in question that this seemed like an appropriate to joke to someone...
posted by tempythethird at 1:16 PM on June 23, 2012


Technically javascript isn't compiled, it's interpreted. Of course modern browsers probably do generate machine code from JS to speed it up (And you can use something like the closure compiler as well)

Modern interpreters are so far from the original definition of the term that this distinction is almost meaningless. Python emits pre-compiled byte code for its VM as an optimization, while Perl has a distinct compilation phase that generates an in-memory representation of the code before it starts executing. On the other side, Java byte code is compiled on-the-fly into native machine code by so-called "hotspot" VMs. We should really just ditch this distinction at this point, since it's not even that useful. (Why does it matter if something has a distinct compilation to a separate file on disk?)
posted by spitefulcrow at 1:17 PM on June 23, 2012 [3 favorites]


Never mind that processors run microcode that interprets the 'bare metal' machine code they receive.
posted by zippy at 1:19 PM on June 23, 2012


I didn't know "program by torture" was a paradigm now.
posted by RobotVoodooPower at 1:31 PM on June 23, 2012


Yeah, the actual native code that modern x86 processors run is unknown -- they actually translate x86 code to even smaller operations on the fly, and then execute the smaller ops. (I think they're called micro uops, but I'm not certain, and I'm too lazy to go look.)

So most interpreters aren't really interpreters, since they frequently generate "native code" on the fly. But compilers aren't really compilers either, because the 'native code' isn't what actually runs on the hardware.

Basically, nobody really knows what the fuck is actually happening when you run a program.
posted by Malor at 2:11 PM on June 23, 2012 [8 favorites]


Isn't this not going far enough? I'd want a browser plugin that detects and kills scripts that slows down page loads for any reason.

You want NoScript.
posted by urbanwhaleshark at 2:16 PM on June 23, 2012 [3 favorites]


Metafilter: Basically, nobody really knows what the fuck is actually happening when you run a program.
posted by localroger at 2:27 PM on June 23, 2012 [2 favorites]


I think they're called micro uops

uops = µops = micro-ops

posted by Mars Saxman at 3:40 PM on June 23, 2012 [1 favorite]


We need something like this for YouTube comments.
posted by TwelveTwo at 3:55 PM on June 23, 2012 [1 favorite]


From the source code:
//@TODO: give a shit
Simply brilliant.
posted by smcdow at 5:24 PM on June 23, 2012 [7 favorites]


Modern interpreters are so far from the original definition of the term that this distinction is almost meaningless

I wanted to argue this but then I realized this is a useful and insightful observation. Perhaps it is more accurate to say that the qualities traditionally associated with interpreted languages and environments (relatively slow, solution focused, loose) now apply to most of the languages and environments people work with. Whether that environment is "interpreted" or not becomes a moot point.

Why does it matter if something has a distinct compilation to a separate file on disk?

Traditionally compiled software had few or no external dependencies. A compiled piece of software would run on any hardware that could run it, and since hardware didn't vary very much, this was the preferred means of distribution. "Interpreted" code, on the other hand, required significant maintenance and support costs due to version and library skew. But nowadays "compiled" software also has many dependencies, and so this distinction too has been eroded.
posted by deo rei at 5:56 PM on June 23, 2012


It just deletes lines where errors happened, until it works. Even if that is because your program is now empty.

This is how my boss would write code.

He's an electrical engineer.
posted by DU at 5:57 PM on June 23, 2012 [6 favorites]


Traditionally compiled software had few or no external dependencies. A compiled piece of software would run on any hardware that could run it, and since hardware didn't vary very much, this was the preferred means of distribution. "Interpreted" code, on the other hand, required significant maintenance and support costs due to version and library skew. But nowadays "compiled" software also has many dependencies, and so this distinction too has been eroded.

I disagree with this characterization. A Win32 binary won't and can't run on Linux, and vice versa, even though both could be running on identical hardware. This has been true since the very early days: a 386BSD executable could not run under MS-DOS, even if the hardware was identical. Compiled binaries have always been specific not just to hardware but to the execution environment, putting them firmly at the bottom of the portability ladder. On the other hand, a traditional interpreted language like Bourne shell or Perl or Python could run on all of those systems without any modification or hassle, which puts them at the top of the portability ladder.
posted by Rhomboid at 6:08 PM on June 23, 2012 [1 favorite]


(And obviously there are things like Wine, but that's very much a special case exception.)
posted by Rhomboid at 6:09 PM on June 23, 2012


I feel like the JavaScript community writes more satirical code than other programming communities. But it's probably more to do with the rise of GitHub.

A couple months back, when we were all losing our shit over semicolons, Isaac Schlueter wrote a Node module as a rebuke to the (arguably strawman) position that a semicolon on the end of every line magically wards off syntax-error bogeymen. And then he threw a bunch of sarcastic semicolons into the source code.
posted by savetheclocktower at 6:47 PM on June 23, 2012


If you really need help, you might consider the Javascript Hotline..
posted by jkolko at 7:28 PM on June 23, 2012 [1 favorite]


I spent many years working in Interlisp and it's successors, and I can tell you this is not how DWIM worked.
posted by Runes at 7:38 PM on June 23, 2012 [1 favorite]


A Win32 binary won't and can't run on Linux, and vice versa, even though both could be running on identical hardware

that has more to do with the on disk format of "executables" than code in and of itself no?

If everyone adoped, ELF for instance, a sufficiently simple program, that did not use any OS specific libraries would run anywhere no?

I agree with you that they are not at all portable from a practical standpoint but X86 machine language is X86 machine language is X86 machine language.
posted by Ad hominem at 8:50 PM on June 23, 2012


I spent many years working in Interlisp and it's successors, and I can tell you this is not how DWIM worked.

If only because one rarely loses track of close-parens in Javascript.

)))))) ; for good measure
posted by zippy at 9:25 PM on June 23, 2012


It just deletes lines where errors happened, until it works. Even if that is because your program is now empty.

This is how my boss would write code.

He's an electrical engineer.
That's interesting. I had an electrical engineer boss who wrote code, as well. His approach was the opposite though.

Where you or I, when encountering a bug, would slow down a sec, plan, think, and problem solve, he would just throw more and more code at it.
posted by !Jim at 9:30 PM on June 23, 2012 [1 favorite]


but X86 machine language is X86 machine language is X86 machine language.

No, it is absolutely, positively not. This is not a simple matter of file formats. Different platforms implement things differently:
  • How syscalls are made (i.e. what instruction, sysenter or int, and if int then what interrupt number?), their numbering, their arguments, and their semantics
  • Exception handling:
    • how is the stack unwound
    • how are handlers registered
    • is it table-based or setjmp/longjump based
  • Alignment requirements
  • Calling conventions, a blanket term that includes:
    • what registers are call-clobbered and which must be saved
    • what register is the PIC register, if any
    • what order arguments are passed
    • who's responsible for clearing the stack
    • whether arguments are passed in registers or the stack
    • how structures larger than a word are returned
    • must the stack pointer be aligned, and if so to what alignment, and who's responsible for it
    • how and where x87, XMM/YMM/AVX registers are saved
    • must space be reserved on the stack? (red zone)
  • How does dynamic loading work?
    • How are symbols resolved at runtime? What are the semantics?
    • Can any symbol be interposed or must the be specially annotated in the source?
    • Is it lazy binding or does everything happen at initialization?
    • What happens if two modules define the same name?
    • Can a library override/interpose a symbol in the main .text segment of the executable?
    • What bout COMDAT symbols, weak symbols, linkonce symbols? What about symbol visibility?
    • Must shared libraries be compiled as PIC? Does PIC even exist?
  • How about symbol mangling -- and I'm not just talking about C++ here. Do symbols have a leading underscore? What about for various calling conventions, do they have different decorations, such as adding @nn for stdcall?
  • How does static TLS work? dynamic TLS?
  • what are the segment registers set up to point to? What are the commonly used thread-local data structures, such as the TIB at FS:[0x00] and the TEB at FS:[0x18]?
In virtually all of the above items, the answer is different on Windows and Linux. All of the above affect code generation, and if you look at the assembly generated by a C compiler for one platform it will be significantly different than code generated by the same compiler targeted at a different platform, but on the same hardware. All of these things matter. There is no such thing as "generic x86 assembly code". You are not operating in a void, you are in the context of an operating system and there are many system level conventions and rules that you must follow.
posted by Rhomboid at 10:03 PM on June 23, 2012 [6 favorites]


If only because one rarely loses track of close-parens in Javascript.

The same was true of Interlisp, as it used syntax-aware editors. It was impossible to have unbalanced parens.
posted by Runes at 10:09 PM on June 23, 2012


If only because one rarely loses track of close-parens in Javascript.

Right, in Javascript it's more a matter of "})})})});" than it is of ")))))))".
posted by kenko at 10:22 PM on June 23, 2012 [4 favorites]


deo rei: Perhaps it is more accurate to say that the qualities traditionally associated with interpreted languages and environments (relatively slow, solution focused, loose) now apply to most of the languages and environments people work with.

I can't really speak to the other two claimed qualities, but 'slow' often doesn't apply anymore, either. Java and C# are extremely fast, not quite as quick as C, but startlingly close much of the time. Sun/Oracle Java in particular runs like a scalded cat.

The CPython interpreter and Perl are a lot slower, but it's also important to realize that, in modern desktops, the processor is massively overpowered compared to everything else in the computer. Most programs will spend a great deal of time waiting for data, either from the disk, the network, or even the keyboard in some cases. (humans are slooooooow). In cases like this, faster code just idles more quickly.
posted by Malor at 11:51 PM on June 23, 2012


he would just throw more and more code at it.

Oh yeah, he doesn't that too.

I was actually thinking of another practice of his. If a vital parameter is missing from the database, just have the code create it and move on. Why was this should-never-be-missing thing missing? Who cares, I have work to do!
posted by DU at 2:09 AM on June 24, 2012


>>Does your site embed google maps or hit verified by visa, fine I'll enable that for your site. Does your news site hit Google's jQuery.js, yeah that's dumb, no you may not use jQuery.

>What the hell are you talking about?


Precisely my question. Using the Google CDN for your jquery or whathaveyou is the opposite of dumb.
posted by stavrosthewonderchicken at 3:46 AM on June 24, 2012


So... this is basically JSLint with an axe?

> Right, in Javascript it's more a matter of "})})})});" than it is of ")))))))".

"});});});});" dammit.

posted by ardgedee at 7:12 AM on June 24, 2012 [2 favorites]


Java and C# are extremely fast, not quite as quick as C, but startlingly close much of the time. Sun/Oracle Java in particular runs like a scalded cat.

Not to get into language wars - I like C# and Java - but the relative slowness of those versus, say, C, really can't be argued if you include performance aspects such as start-up time and responsiveness. The much larger memory pressure imposed by these environments also impacts real-world performance in various ways, as do the size and scope of their respective class libraries. You get a lot and the trade-off is almost always worth it, but it is not free, and - more importantly - the cost is almost impossible to avoid.
posted by deo rei at 7:58 AM on June 24, 2012


And as a matter of fact, modern apps written in C/C++ also have many or all of the issues I attribute to C# and Java above, because they also have to provide features such as networking, scriptability, reflection, internationalization, interesting UI, security, advanced memory management etc. All this functionality comes at a cost. The distinction is that with C/C++ there is the option of avoiding this added cost, for those cases where it makes sense to do so.
posted by deo rei at 8:22 AM on June 24, 2012


I disagree with this characterization. A Win32 binary won't and can't run on Linux, and vice versa, even though both could be running on identical hardware

That's a fair point, it's better to speak of hardware + OS as the target rather than just the hardware. But then the question becomes, what is part of the OS? Is it the kernel, or kernel + libc, or kernel + libc + userspace tools? What about drivers, in particular drivers which are complex systems in themselves, like DirectX or OpenGL?

On the other hand, a traditional interpreted language like Bourne shell or Perl or Python could run on all of those systems without any modification or hassle, which puts them at the top of the portability ladder.

I think its important to distinguish between ease of distribution and portability in an abstract sense. If I create a bash script that does something useful and send it to you, chances are you will need to modify it to reflect your tool conventions, filesystem conventions, environment, and shell version before you will be able to reproduce those results. On the other hand if I send you a statically linked binary that is suitable for your OS (let's say, kernel + libc), then chances are it will run without further ado, not least because binary compatibility is a consideration in hardware and OS development.
posted by deo rei at 8:44 AM on June 24, 2012


What I'm trying to get at here is that while there is an abstract sense in which dependency on a particular hardware + OS makes something less portable, this obscures the fact that portability can also mean something like: "will it run on my system?". Since there are strong economic and social forces which make certain hardware + OS combinations much more likely than others, this means that if you want your software to have the highest chance of running in any random environment (i.e. increase its portability in the latter sense), then you are best off distributing it in a format suited to that environment. This is what we're doing when we're pushing for adoption of e.g. web development standards - we're trying to increase portability not by making our code more portable, but by standardizing the platform.
posted by deo rei at 9:05 AM on June 24, 2012


!Jim:
It just deletes lines where errors happened, until it works. Even if that is because your program is now empty.

This is how my boss would write code.

He's an electrical engineer.
That's interesting. I had an electrical engineer boss who wrote code, as well. His approach was the opposite though.

Where you or I, when encountering a bug, would slow down a sec, plan, think, and problem solve, he would just throw more and more code at it.
Yep. For the record, EE here, but when I read engineering code, I expect to see this-situation-only fixes, not a comprehensive plane to handle the problem throughout the code. As you step through a stereotypical engineer's code, you meet fix after fix, and shortcut after shortcut; functions used innovatively, but without regard to whether this is a time-optimal solution (the answer may be a side effect of the function's more common output) or even an intended output (could be changed in language version Now.0.1).
posted by IAmBroom at 5:03 AM on June 25, 2012 [1 favorite]


The moreConflict method is a thing of beauty, especially since it overwrites everything in the window object, except for the location, leaving you with a nice, useless web browser.
  FuckIt.moreConflict = function(){
    for (var prop in window){
      if (prop === "location"){
        //you're not getting away that easy.
        continue;
      }
      window[prop] = FuckIt;
    }
  }
The EULA is equally hilarious:
If the Author of the Software (the "Author") needs a place to crash and you have a sofa available, you should maybe give the Author a break and let him sleep on your couch.

If you are caught in a dire situation wherein you only have enough time to save one person out of a group, and the Author is a member of that group, you must save the Author
especially since somebody at Hacker News noted that widespread adoption of this EULA could lead to a race condition, should multiple developers ever be put into a life-threatening situation together.
posted by schmod at 10:02 AM on July 3, 2012 [2 favorites]


« Older Computer says No   |   Every Hollywood Movie Is A Children's Film Newer »


This thread has been archived and is closed to new comments