Hacker News new | past | comments | ask | show | jobs | submit login

I love magic!

Every level of abstraction above binary code, from assembly, to C, to Ruby, to Rails DSL's--each works by creating magic incantations that let you run larger functionality with a new shorter series of magic words.

Are you really against magic, or is it that you are against black magic (which I would classify as leaky abstractions)?


Sometimes the new magic incantation is longer than the old incantations it was based on, though. And slower. And harder to understand. And buggier. And doesn't expose important functionality, so you invent roundabout ways to access it. And when you put several abstractions on top of each other, you will eventually get all these problems combined.

For example, try to draw a single black pixel on the screen... using JavaScript, or better yet, some language that compiles to JavaScript. How long would that take you? How many lines of code? How fast does it run? How much memory used by all subsystems combined? How many system calls involved? In assembly language that would be one instruction. And don't tell me that drawing single pixels is unimportant. I can show you any number of hackers who would create extremely cool webapps if drawing a pixel took one assembly instruction.

I don't know what it's like for other Javascript-based environments, but in mine it looks like this:


    var app = new Mars.UIApplication().init(1280, 720);

    var scene = new Mars.UIScene().init(app);

    var surface = new Mars.UISurface().init(app);
    surface.setSize(300, 200);

    var texture = surface.getTexture();
    texture.setPixel(150, 100, 0x000000FF);

Do not confuse the language with the environment in which it runs. The difficulty with pixel-poking isn't with JavaScript, it's with the environment. Give it another environment that allows the language direct access to the window (rather than to a DOM node nestled deep withing the bowels a parse tree which then needs to be rendered by a completely separate engine) then the difficulty would vanish. JavaScript may most typically run in a browser context, but the browser context is not JavaScript.

On the other hand, there are things that you want to make difficult, like stealing credit card information.

It's hard to disagree with you when you use that definition of 'magic'. This is an example of my definition...

Yesterday I was looking at a Chartbeat gem that accesses the Chartbeat REST API [1]. The entire class is 40 lines of code, however it's coded so weirdly that you'd have to read the source in order to use it. Every API call was a method_missing call, so instead of doing (in irb)

    puts Chartbeat.new(:apikey => 'a', :host => 'b').public_methods
you'd have to do

    puts Chartbeat::METHODS
    puts Chartbeat::DASHAPI_METHODS
But I only know that because I had to look at the source code. In addition, there's no way to specify custom exceptions to the user, you have to rely on the rest_client gem's exceptions.

The code does look magical, and kudos to the developer that wrote it for the ingenius use of method_missing, but IMHO it's a bit to magical for my tastes. I like to look at a library's documentation and instantly know what methods I'm allowed to call and what exceptions/results I'm going to get back.

[1] https://github.com/ashaw/chartbeat/blob/master/lib/chartbeat...

Honestly, this is why I cringe whenever I hear code described as "clever." I bring up "clever" here because "magic" seems to be used in this discussion in a manner synonymous with "clever." [1] Developers tend to be intelligent people who like to stretch their intelligence, but in terms of code robustness, the boring, normal solution is almost always a better choice than the clever approach. Clever, to me, has almost become synonymous with unusable, fragile, and over-complicated.

[1] Edit: Added explanation since, on a second read, it seems like I'm digressing from the topic.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact