Kill hashtables, get shorter code.
herdrick.tumblr.com
Kill hashtables, get shorter code.
1–10 of 46 posts
Re: Kill hashtables, get shorter code.
#2A 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 hash back.
I'm personally a fan (sometimes) of code like this when I really want to one-line something but need multiple values:
# ruby
value1, value2 = [(x=aFunction(arg))[:key1],x[:key2]]
:)Re: Kill hashtables, get shorter code.
#3Re: Kill hashtables, get shorter code.
#4No, 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 his code he is at risk of creating exactly the same type of needlessly hard to read, hard to debug, code that premature optimization does.
Re: Kill hashtables, get shorter code.
#5Good stuff. My only comment is to make a macro like defmemo. That way instead of writing something like: (def set-m (memoize set)) you could write (defmemo set-m set).
Re: Kill hashtables, get shorter code.
#6There's some low-hanging fruit to cut down on the required storage, namely wrapping to-words and frequencies together, and memoizing that. This doesn't reduce the number of hashtables, but at least there's no need to store the entire word lists. As it stands, this will simply fail if your corpus is too large to fit in your RAM all at once.
Re: Kill hashtables, get shorter code.
#7There're other languages that do this two, eg. JavaScript written by functional programmers often ends up looking like this. In Arc, the distinction is completely meaningless, because you "call" a hashtable to index an object anyway.
The problem with it, I've found, is the lack of debugability. You can enumerate a hashtable, and you can inspect it in the debugger. You generally can't enumerate a function. I've found that with complex systems, the biggest correlation to programming productivity is the amount of debug information available, not the size of the code. Trading off debugability to get short code is usually a poor trade-off, once you get past a certain code size.
Re: Kill hashtables, get shorter code.
#8This is actually a pretty common technique in Haskell. If you look at the Alex lexical analyzer generator's source code, it represents CharSets as functions from Char -> Bool: they return true if the character is in the charset or false if it is not. Internally, they work just like the article describes: the union of two CharSets doesn't actually enumerate every possible character in the set, it just calls the two Ch…
I don't think this point is made often enough. Brevity is a virtue certainly, but ultimately what counts is not LOC, bug counts, iterations/sec etc but features delivered to users. Worse is better reigns supreme here which is why you so often see engineering and design disasters like php, craigslist, myspace, and windows brushing aside far more elegant but less engaging alternatives. For most of us the pride we take in our craft makes this a very hard pill to swallow but swallow it we must.
Re: Kill hashtables, get shorter code.
#9In 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…
Honestly it's this kind of thing that makes me wonder if the Pythonistas don't have a point about clarity vs cleverness.
Re: Kill hashtables, get shorter code.
#10In 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…
edit: my most-epic-single-line is a range definition, and I actually use this one as-is with a description of how it works:
[((left=prefix*10*scale-1)==-1 ? (scale==0 ? prefix-1 : prefix) : left)..((right=prefix*10*scale+(10*scale-1))==-1 ? prefix-1 : (scale > 0 ? right-1 : right))]
If passed a prefix, this iterates over all array entries where the index matches /^prefix/ (one-based, I have a zero-based too), entirely skipping non-matching ones. Just need to increase scale appropriately, and loop until it finds nothing. It was fun to come up with.