Live data from Hacker News

Kill hashtables, get shorter code.

herdrick.tumblr.com

21–30 of 46 posts

Re: Kill hashtables, get shorter code.

#21

"That sort of sucks. Further, it makes some functions, like euclidean, hopelessly non-general, since euclidean now has to know what function to call to get a frequency [3]." No. You can just pass in the appropriate, memoized frequency function to call. In the new code, that just means that "freq" would be an additional argument to euclidean, instead of a globally defined function.

Right. That's what I said in the footnote, [3].

Re: Kill hashtables, get shorter code.

#22
post #6

When he talks about performance, he mentions that memoization allows performance to not suffer very much, but what he doesn't mention that almost the entire performance gain comes from memoizing frequencies ... which stores the hashtables anyway; it just does it behind the scenes. This is fine for CPU usage, but it does have a significant storage penalty depending on the characteristics of the input. There's some low…

Without profiling it I'd guess it's memoizing the function that does the disk i/o that makes the biggest difference.

Right, I realized after writing that that I was forgetting about that one. Still, memoizing frequencies takes it from O(n^2) to O(n) right now, so it's easily the second largest increase.

Re: Kill hashtables, get shorter code.

#23
post #9
post #2

In summary: instead of getting a hash back from a function and pulling out the (single!) desired key, pass the key to the function and get the value back directly. A limited-use but handy technique, and they're not arguing for dogmatic adherence to the rule. Something to keep in mind, but don't go re-wiring old code unless you're bored. You could also code the function so if you pass no key-args, you get the whole ha…

I hate it when I see code like that. It's so much harder to maintain. You've saved two lines of code but made the intent at least 10x harder to infer. I've been wading through the Rails codebase lately and this kind of thing gets to be annoying fast, particularly when you're trying to debug a function that's littered with these kinds of expressions, often nested. Honestly it's this kind of thing that makes me wonder…

That's just excessive "cleverness." I don't think you should equate that with concise coding. I could write an equally "clever" snippet that takes 12 lines to do the same thing. Really, you're only saving one line of code over a perfectly readable version:

  x = aFunction(arg)
  value1, value2 = x[:key1], x[:key2]
And you can still write a one-liner much better than the original:

  value1, value2 = aFunction(args).values_at(:key1, :key2)
In essence: That style of coding is not really clever, and I would argue it's not idiomatic. It's doing more work to compensate for a missing tool (in this case, not knowing about the values_at method).

Re: Kill hashtables, get shorter code.

#24
post #23
post #9

Earlier quoted context omitted.

I hate it when I see code like that. It's so much harder to maintain. You've saved two lines of code but made the intent at least 10x harder to infer. I've been wading through the Rails codebase lately and this kind of thing gets to be annoying fast, particularly when you're trying to debug a function that's littered with these kinds of expressions, often nested. Honestly it's this kind of thing that makes me wonder…

That's just excessive "cleverness." I don't think you should equate that with concise coding. I could write an equally "clever" snippet that takes 12 lines to do the same thing. Really, you're only saving one line of code over a perfectly readable version: x = aFunction(arg) value1, value2 = x[:key1], x[:key2] And you can still write a one-liner much better than the original: value1, value2 = aFunction(args).values_a…

Aside from the use of a temporary variable (which can be used for self-documentation anyway), people aren't saving any operations with the one-liner. They are just cramming more operations into a single line.

If LOC was so important for readability, we could just write in C without using any newlines.

Re: Kill hashtables, get shorter code.

#25
post #4

"But it’s hard to argue with brevity." No, it's really not. Brevity != clarity. Clarity is hard to argue with, brevity is not. By his own admission this new code is harder to write and harder to debug. It's interesting to me that in the article the author dismisses any performance impact of his changes because "we can profile and deal with it latter", but fails to realize that by attempting to reduce the length of hi…

That's a pretty old debate. I think brevity does a lot for clarity, and the more you work at making your code brief the better you'll be at reading brief code. Of course if other people are reading your code then you should consider what current programming practice is. But the current practice in Clojure is, for cultural reasons, to make things really succinct. So you can assume those reading your code are ok with t…

> That's a pretty old debate. I think brevity does a lot for clarity

Up to a point, that's true, but if you start shortening words by removing letters, you've gone too far.

Re: Kill hashtables, get shorter code.

#26
post #24
post #23

Earlier quoted context omitted.

That's just excessive "cleverness." I don't think you should equate that with concise coding. I could write an equally "clever" snippet that takes 12 lines to do the same thing. Really, you're only saving one line of code over a perfectly readable version: x = aFunction(arg) value1, value2 = x[:key1], x[:key2] And you can still write a one-liner much better than the original: value1, value2 = aFunction(args).values_a…

Aside from the use of a temporary variable (which can be used for self-documentation anyway), people aren't saving any operations with the one-liner. They are just cramming more operations into a single line. If LOC was so important for readability, we could just write in C without using any newlines.

The point isn't to save operations or lines of code — it's to reduce semantic load and make code more readable. In most languages, calling a function actually results in more operations than just doing copy-and-paste with the same code, but I don't think you'd dismiss well-factored code on those grounds.

A rough gauge for better code might be how much a skilled coder can grok by glancing at N lines of code. This means that reducing LOC can be helpful, but it's not a 1:1 correspondence — your example of C with no newlines would make it harder to read. On the other hand, putting what is essentially a hash destructuring on one line actually does tighten up the semantics.

Re: Kill hashtables, get shorter code.

#27

Earlier quoted context omitted.

That's a pretty old debate. I think brevity does a lot for clarity, and the more you work at making your code brief the better you'll be at reading brief code. Of course if other people are reading your code then you should consider what current programming practice is. But the current practice in Clojure is, for cultural reasons, to make things really succinct. So you can assume those reading your code are ok with t…

> That's a pretty old debate. I think brevity does a lot for clarity Up to a point, that's true, but if you start shortening words by removing letters, you've gone too far.

I disagree in two senses. First, it's a poor measurement of brevity that depends on identifier length. Even LOC (surely the gold standard of bad metrics) doesn't depend that much on that. Second and more interestingly, as code gets more concise, long explicit identifiers begin to detract from readability. Well-written concise code discloses valuable information just by the shape it takes. With experience reading such code, you start to grok it at a whole-expression level. Lengthy identifiers interfere with this gestalt: they provide an initial boost when reading the code, but at the long-term cost of overwhelming the code with lexical noise.

Concise programs often appear laughably unreadable to people who are used to a definition of "clarity" that derives from more verbose languages. At one time they appeared that way to me too. But with time spent working in less verbose languages, to my surprise I found myself wanting to use shorter and shorter names, not to interfere with clarity but to enhance it.

Re: Kill hashtables, get shorter code.

#28
post #16

Earlier quoted context omitted.

Coffeescript is certainly cool, but Clojure has sophisticated destructuring assignment as well.

The point was not "Coffeescript is better than Clojure", it was "destructuring assignment (like in Coffeescript, for instance) is a better solution than the one proposed in the post". If Clojure has sophisticated destructuring assignment, awesome. Use that instead.

I suppose I failed to see how destructuring assignment on hash-maps accomplishes anything interesting at all related to the post. The post eliminates hash-maps altogether.

Re: Kill hashtables, get shorter code.

#29
post #23
post #9

Earlier quoted context omitted.

I hate it when I see code like that. It's so much harder to maintain. You've saved two lines of code but made the intent at least 10x harder to infer. I've been wading through the Rails codebase lately and this kind of thing gets to be annoying fast, particularly when you're trying to debug a function that's littered with these kinds of expressions, often nested. Honestly it's this kind of thing that makes me wonder…

That's just excessive "cleverness." I don't think you should equate that with concise coding. I could write an equally "clever" snippet that takes 12 lines to do the same thing. Really, you're only saving one line of code over a perfectly readable version: x = aFunction(arg) value1, value2 = x[:key1], x[:key2] And you can still write a one-liner much better than the original: value1, value2 = aFunction(args).values_a…

Ooh, yeah, had forgotten about that one. Thanks!

Re: Kill hashtables, get shorter code.

#30
post #27

Earlier quoted context omitted.

> That's a pretty old debate. I think brevity does a lot for clarity Up to a point, that's true, but if you start shortening words by removing letters, you've gone too far.

I disagree in two senses. First, it's a poor measurement of brevity that depends on identifier length. Even LOC (surely the gold standard of bad metrics) doesn't depend that much on that. Second and more interestingly, as code gets more concise, long explicit identifiers begin to detract from readability. Well-written concise code discloses valuable information just by the shape it takes. With experience reading such…

Then length of an identifier name should be proportional to it's scope. But specifically I'm talking about non descriptive function names shortened for brevity: map, filter, join, split are better names than mp,flt,jn,sp no matter how often you use them.

It takes less effort to read a word than to trip over an unfamiliar abbreviation, so while the code may be more concise, it is less clear. If your code relies upon the reader to know a bunch of specific idioms, then it might be concise, but it isn't clear; it's jargon.

Post reply on HN