Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think this article is a mix of fair criticisms but at points lapses into a lot of hand waving. At points it devolves into "This is confusing/non-intuitive if you don't know CS" and "This is not the way I like to do things".

I find the proposition that porting a library (no matter the size) gives you "as much experience as anyone" pretty dubious. It's clear the author has some experience with CS, and I wouldn't discard out of hand the input of someone who had only used it for 5 minutes...but I found that particular statement a bit dismissive of people who have been using CS for a long time on a lot of different projects. Too often people confuse the "getting comfortable, I basically know whats going on here" phase of learning a language with "knowing" that language...which is really more "I understand this on an intuitive level".

I found the "We Process Images and Symbols Faster than Words" section extremely dubious and strikes me as very hand-wavy. I see what the author is going for, but it's a completely false analogy and their point is flawed to begin with.

They're trying to compare the acquisition and understanding of new concepts vs the recognition of an already known pattern, entirely different things.

Also, the author is essentially cheating, because they are talking about conveying inherently visual information using pictures. Showing someone a picture of a circle and saying "this is a circle" does not convey what a circle is, it conveys what a circle looks like (or perhaps, it does explain what a circle is, but only visually) which is to be sure useful for some purposes. However, it gives them no inherent understanding of how to properly construct a circle, or what it's relation is to other shapes (such as a line) geometrically (say compared to a triangle which could be called any three non-collinear points).

With the baby picture, again...I see what they are going for but I think it just doesn't actually support what they are trying to assert. Evoking an emotional response is not the same as passing knowledge, and it doesn't strike me as a good objective to have when writing code. Sure, show someone a picture of a baby and they will have an emotional response. However, they will have no idea who the baby is or why you are showing them the picture which would probably be more useful.

All of this does very little to support their assertion that "&&" is somehow more of a symbol and is more visually rich than "and", something I find dubious even disregarding the poor examples. Letters are symbols themselves and "&&" is just as much a "word" as any other, though admittedly more visually distinctive. With syntax highlighting, I would say that there is no objective difference between "&&" and "and".

"That is verbally readable code, but it’s not very comprehensible"

I'd say that less the fault of CS, and more the fault of the fact that the algorithm they are expressing in it doesn't make any sense:

    wash plate, brush, sink for plate of dishes when plate.dirty if meal.status is 'done'
This is not a valid construct. By using "of" you are iterating through the keys of dishes, which will inevitable be strings. You later check the dirty property of the key (string) which will surely not exist. You need to either use in or less likely, access them as dishes[plate]. (I'd assume dishes in an array, in which case a loop is more idiomatic and safe than for-in)

Fine, probably an honest mistake. Sure, I just felt the need to point it out, though I think it does potentially suggest that the author is not yet at the "intuitive" level of knowing CS. You are going to have problems like this in any language where you do not yet fully know it, JavaScript included.

Even excepting that, the algorithm doesn't makes sense. You're cleaning your sink and brush after washing each plate? Doesn't make much sense. I suggest a more realistic version:

    if meal.status is done
        wash plate for plate in dishes when plate.dirty
        wash brush, sink
The author makes a couple points about their original comprehension; how it's densely packed, and I think this largely untangles them. It puts the most important predicate first.

You don't need to know immediately that you are dealing with the dishes array... The code is composed of discrete "pieces" and each depends on the others. I think it's arbitrary to say "oh I need to know I'm iterating through dishes first thing". It's just as useful to say "ok, I'm going to be washing something, a plate...". That provides a context for everything else. The fact that it's a comprehension is pretty obvious immediately so it's just a case of deconstructing it.

So overall I find this a bit of a straw man. It doesn't make sense to begin with, it doesn't need to be so packed, and it's taken out of context which dramatically cuts back readability. If you were writing an app about doing things in the kitchen, the comprehension (even the dense version) would make quite a bit of sense because the context would make certain things more obvious. In my code, this section would probably be prefaced with a comment like:

    # cleanup
    wash dishes
    wipe counter
    stow utensils

So the fact that we just spent X number of lines getting dishes dirty, and knowing precisely what a dish object is in the context of the overall program i.e. that they need to be cleaned, it would be obvious that I need to now wash them each in turn...amongst other things.

Now really, I see what the author is going for. List comprehensions get messy fast. Sure, I just don't see this as a criticism of CS per se and I find the example poor.

Remember, just because CS offers extreme conciseness doesn't necessarily mean you have to use it. I'll admit CS users often make a big deal about conciseness, and that can send mixed messages...but I would say in most cases it's about demonstrating that power is there if you need it than saying this is always best practice. The author clearly understand this as they go on to provide more readable examples, but it bears repeating.

I could similarly break down the "one liner", but I'm running pretty long already and don't have forever. Again, what is probably a misuse of "of", and sticking more than is needed in the comprehension. I get the idea that the point is you can do this, but every language has powerful features with which to shoot yourself in your foot.

If the author actually found that in their company's code, I most respectfully suggest perhaps they don't know CS well enough or it may not be their style. At any rate, it would explain their distaste for CS.

"It’s hard to recognize instantly that I’m actually calling $.ajax"

I suppose, but CS uses juxtaposition to call functions, if you see identifier\wvalue or identifier\widentifier...it's a function call. I would say, remember CS's golden rule: when in doubt disambiguate. Feel free to add () to function calls.

I think the next point the author makes it better. I would say that it's just an unfortunate fact that in many languages some constructs will be ambiguous. I think CS does a good job of pushing ambiguity to edge/rare cases.

In the author's particular example I would note the point is a bit moot because CS has implicit return:

    getUser = (id) ->
        url = "users/#{id}"
        dfd = $.ajax
            url: url
            format: 'json'
            method: 'post'

        # return
        url: url
        promise: dfd.promise()
In other cases I would refer you to the Golden Rule.

"Now with the fat-arrow, people are encouraged to fat-arrow their way to oblivion"

I find this a dubious assertion. Stupid people maybe, but I doubt very much giving stupid people JavaScript will give you overall less problems...just different ones. At any rate, I don't see any problem with saying a tool should be reserved for experienced users.

"Therefore it will never really be supported natively, and will always be a compile-to-JS language, and will therefore always have a terrible debugging experience."

I disagree. The browsers are working on features to make such debugging much easier. Further, I know a few people working on CS in CS interpreters, so that if you need a richer debugging experience you could run your scripts through the interpreter rather than as JS. Granted it will probably never be as rich as the Developer tools in the browser, but between the two I would say it's enough.

The author noted they feel the need to throw in a lot of logging in to debug. I would say this is a style a lot of CS developers I know use, myself included. I am quite adept with the developer tools, having debugged JS since the Venkman and Visual Studio days, but I just don't feel the need for that sort of debugging very often. For me, it's either a syntax error or a problem with the flow of data through my program. The only time I really break out the debugger is debugging other people's code.

Editor macros make inserting logs dead simple. A good build process removes them except when needed. I can appreciate that some people will find this workflow annoying and a pain, which is fair. I just want to note I find it works superior for me.

So this is getting long. Despite my objections, I like this article. CS is not perfect by any stretch, and it's still relatively new. It needs work. It needs criticism from the trenches. I think most of the stuff in this article is mostly fair.

However, I find that CS suits a particular group of developers...and for them it is a very useful tool. I think that a lot of people criticize it without realizing that really they don't fit into that group.



> "I find the proposition that porting a library (no matter the size) gives you "as much experience as anyone" pretty dubious"

My intro comes off as though I'm claiming to be some sort of authority, which wasn't my intention at all. So good call on your part. I just meant "It's not like I've only spent 5 mins with the language". Lots of folks out there are dismissing it w/o giving it a shot.

However, I do know the language well at this point since it has a lot of rubyisms (and I'm alright with ruby) and at the end of the day is just JavaScript™.

Concerning images/symbols v. words. Like I said in the article, I _feel_ the relationship when I see `!==`, I don't feel it when I read `isnt`. However, I went from design -> code, so maybe imagery is a bigger deal to me.

> but I doubt very much giving stupid people JavaScript will give you overall less problems...just different ones

Yeah, one of which is not a less-than-optimal debugging experience.

> The only time I really break out the debugger is debugging other people's code.

Welcome to my article.

> Editor macros make inserting logs dead simple

I use vim, and I agree. But that's an extra few steps from my JS debugging. When something unexpected happens, I go straight the console, start adding break points, watch expressions, mutating data, etc. etc. to find the problem before I ever get back to vim. People who have always console.log'd will probably not get as frustrated as me. I feel like I'm limping.

Thanks for the criticisms. For me, the imagery is a big deal, it's not hand-waving, it's my true experience, and that of others I've talked to. We all have different minds.


Sure, likewise it's not my intention to write you off, you clearly have some good points based on real usage... I'm just trying to contrast your experience with people who have used it even longer still.

> Like I said in the article, I _feel_ the relationship when I see `!==`, I don't feel it when I read `isnt`.

Sure, I think that's fair. The point that I'm trying to make is that I think this is subjective based on your own personal background/brain/whatever other nebulous factors.

In your article it could be taken to sound like you are making a case that there is some neurological reason that "!==" is more readable, and I'm not prepared to accept that without some more substantial evidence.

I think I get where you're going, you're just trying to draw comparisons...I just want to add that those comparisons are somewhat nebulous and should not be taken absolutely.

> Welcome to my article.

I didn't get a chance to expand on that point because of space limits. What I mostly mean there is once you're in someone elses code, as far as I'm concerned it's basically all bets are off anyway. At this point when debugging other-code it's often JS, so the point is moot anyway. However, even when it's CS I don't find debugging the JS directly very difficult because it's clear enough for that purpose. Usually it's some issue like a value is not being coerced properly, or arguments being passed in the wrong order, and those are pretty easy for me to nail down with a debugger even if the source is a mess of compiled JavScript...then it's easy to fix it.

Re: debugging, I think we are on the same page. We have different styles. Yours is somewhat crippled by CoffeeScript. It may get better in the future, it may not. I just wanted to say I feel no such impediment.

> it's not hand-waving

My main objection is your examples. Like I said they could be construed as making a more scientific-objective case, rather than a more philosophical subjective one.


Woah, missed a whole section:

> This is not a valid construct. By using "of" you are iterating through the keys of dishes, which will inevitable be strings.

No, they are objects with properties like "dirty", not strings. Dishes is an object of key value pairs. I've been very active in MooTools, contributed to its source, and have written plenty of my own stuff to know the importance of iterating arrays v. objects properly, (and have since repented of extending built-ins).

While I'm on the topic, I love `for own key, val of obj`, own is so, so awesome right there.


Ok, just to be clear because this comment is ambiguous as to if you understand what I'm saying.

The comprehension in your article is not valid, you need to change one thing or the other for it to work.

> Dishes is an object of key value pairs

Yes, and you are getting the KEYS, not the VALUES. I doubt I need to say this, but per the spec KEYS are ipso facto strings.

At the point you do

    plate.dirty
"plate" is a STRING, one of the key names in the dishes object.

See, here is the compiled code fresh from the compiler (with added comments):

    var plate;

    if (meal.status === 'done') {
        for (plate in dishes) {
            // plate is a STRING, plate.dirty will not exist
           // you want dishes[plate].dirty
            if (plate.dirty) wash(plate, brush, sink);
        }
    }
You're making the mistake of thinking CS will do the plate = dishes[ key ] part for you, but it won't...do it yourself or us "in" on an array.

You'll also note there are no sanity checks, so use with caution.

This is precisely what I mean when I talk about not knowing CS well enough. I mean this with all due respect and do not intend to dismiss you. You are clearly very bright and a good coder. Anyone will get tripped up in any language at first.

The point is I've used CS so much I breathe this stuff...I knew instantly that it was an invalid construct.... I'm simply saying (like any language) once you learn it well enough a lot of these sorts of issues fade into the background.

Maybe you don't think it's worth the effort to get to this point, and that would be fair enough. I just think it needs saying that some of the points you raise are related to being relatively new to CS.


Dishes is an object, a dish is an object. I know what I'm doing :)

    dishes = {
      ryansPlate: { dirty: true },
      yourPlate: { dirty: false },
      hisPlate: { dirty: false }
    }
Now go into the debugger, find the _ref, and then add a break point, inspect it, and you'll see.

Or if it was just JS, you wouldn't have to mess with _ref, you'd just put in a break point right where you were last looking at the code wondering "what kind of object is dishes?"

Edit: Oh snapz you got me!

    for key, plate of dishes
Missed the `key`, post updated. Go ahead an chalk that up to "Ryan doesn't know CS", if you believe it's any more incriminating than missing any ol' arg in a function signature.


Sure, and here's the issue:

At the point you do

    plate.dirty

plate === "ryansPlate"

In CoffeeScript the construct for foo of bar

Iterates through the KEYS of bar in turn, assigning them to foo...NOT the values

To be more specific, it iterates through PROPERTY NAMES.

Per the JS spec, property names are always strings (you can't use objects...but you know this I'm just being thorough.)

In your example, you do

   plate.dirty
At this point, plate is equal to "ryansPlate" on the first iteration, "yourPlate" on the second, etc. (well technically the order is undefined, but you get my point)

You want dishes[plate].dirty

To be absolutely clear, I'm don't want to make this out to be anything other than the sort of stupid error all of us make all the time. I'm simply pointing out that I recognize it much quicker because I have a very intuitive understanding of CS at this point. Where you, who are very good at (and used to) JS have a harder time seeing the error.

Likewise, I'm sure that you're aware of the dangers of for-in, I'm simply pointing out that it does no sanity checks so watch out.

Also to be clear, I'm talking about your example as written in the article. Maybe you have some other version that works. Go back to my other comment, I compiled your CS code with the CS compiler. You'll see the error there. If you like I'll make a JSFiddle that demonstrates the problem.

I think you've getting stuck on the fact that in my original criticism I didn't know if dishes was an Array or an Object because it wasn't clear from your code...to be clear it is wrong both ways...so I simply said "it's wrong, something must be changed" apologies if this was ambiguous. Now that you've clarified, it's still wrong...just a particular kind.


I do find it interesting that you didn't go "Oh, if he's got an object, he just missed `key`" so I could argue you likewise not as proficient as you could be :P


We replied simultaneously, view my response above, and yes, I'd also do `for own key, plate` in real code (which I think its really awesome).


> Go ahead an chalk that up to "Ryan doesn't know CS", if you believe it's any more incriminating than missing any ol' arg in a function signature.

Precisely what I intend to do. Everyone makes little logic errors and whatnot, I was just trying to use this as an opportunity to show that people who are, while not necessarily new, but not super experienced...will have a harder time spotting stuff like this in the language.

This is understandably frustrating, so sometimes it colors some of their opinion.


Again I say, you should have caught that I missed the `key` every bit as much as I forgot it ;)


"At points it devolves into 'This is confusing/non-intuitive if you don't know CS' and 'This is not the way I like to do things'."

Sure. Most of the arguments for CoffeeScript itself pretty much boil down to "JS is confusing/non-intuitive if you don't know JS" and "This is not the way I like to do things."




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

Search: