Live data from Hacker News

Replacing Clever Code with Unremarkable Code in Go

vividcortex.com

61–70 of 140 posts

Re: Replacing Clever Code with Unremarkable Code in Go

#61
post #56

Clever is not smart. Consider this anecdote: I recently put together a DIY 3d printer. I didn't have the right tools to cut steel bar, so I made a clever jig and used a shitty Dremel without enough clearance. Clever? Yes -- it got the job done with limited resources. Smart? No -- dumb, actually. Smart would have been driving 15 minutes to Harbor Freight to buy a $20 cut-off saw.

Smart might be to buy a cut-off saw. Brilliant would be to find a working cut-off saw with blade for $20!

If he has an air-compressor already, he could do it for under $20. Air tools are pretty damn cheap on the low end. ;)

Re: Replacing Clever Code with Unremarkable Code in Go

#63
post #34

Earlier quoted context omitted.

That's only true in a language with type inference and type aliases. In Java, generics make your code completely unreadable, as content is buried in boilerplate. Map ,ReadyState ops; for (Entry ,ReadyState e: ops.entrySet()) { ... In Go, generics would be an unqualified win for the author/reader. No one disputes that. The only dispute is over the compiler and runtime costs.

Generics (outside of C++'s templates which are a pretty odd duck[1]) generate very little compiler costs and little to no runtime costs (depending whether they're erased or reified), unless you decide to (optionally) trade some added compiler costs for some runtime improvements by generating type-specialized collections behind the scenes. [1] and their cost is seriously compounded by the rest of C++, D has C++-style…

Depends what you're comparing against. If it's a poor man's generic implementation in current Go using interface{}, then obviously there would be no extra runtime overhead if the compiler generated that for you in a type safe manner; but compared to manually specialized collections or the built-in generic collections, there is quite a lot of runtime overhead. Whether the compiler costs are manageable or not is up for debate.

Re: Replacing Clever Code with Unremarkable Code in Go

#64
post #22
post #18

Earlier quoted context omitted.

A little off-topic, but could you give some (Perl) code examples of this: > You feel initiated into an inner circle. You feel like you’ve discovered LISP in an alternate dimension (but you haven’t).

It's tough to give examples of this in Perl without a lot of narrative (and sometimes a lot of code), but the technique I'm referring to is currying: programs that write programs, via functions that write functions. This, of course, is what you do all the time in LISP. It takes half the (Higher-Order Perl) book to illustrate the technique and its power. Which is kind of the point: shouldn't it be a commonplace thing…

> shouldn't it be a commonplace thing that doesn't take so much work to get around to explaining and using?

Why? It's a reality of the world that more complex things take more time and more effort to learn. However, often that is because these more complex things allow you to do a lot of very useful things much more efficiently. I would prefer to drive over a bridge built by an engineer who learned all those difficult equations, material properties, and buildings codes as opposed to a high school kid with a few physics courses under his belt.

Programming is similar in some effects. As you get better and better you acquire more and more tools to do what needs to be done. Now granted, if you are working on an interface that needs to be easily accessible to the widest range of people it makes sense to simplify. However, cleverness has it's place in code that is expected to be read by specialists.

In the end, even if you avoid all the clever tricks and shortcuts you know, a large enough project will still be utterly inaccessible to a novice. The real challenge of projects that complex becomes less about the specific detail of how a piece works, but more about how all the pieces work together. If you're skilled enough to follow the design of a project like that, I don't think it's too much to ask that you either know these "clever" techniques, or you should be willing to learn.

Looking at your code you linked in the article, I think part of the problem is the fact that there are entire pages of code without a single inline comment. When you're doing these clever things you really need to document every logical step in order to understand and verify your through process later on. You also have to be ready to accept that sometimes you will mess up in your cleverness. In fact, If you are getting a lot edge cases that's a good signal to go back, re-read your comments/design notes, and find where you could improve your approach.

Ironically, I would argue that go channels are actually an example of doing something "clever" the correct way. These channels are very effective at separating a single concept from a whole pile of abstractions, and doing a lot of clever interactions beneath the hood in order to ensure it's all effectively synchronized. In other words, using go channels is using the same type of "clever" techniques once they've been abstracted away.

Re: Replacing Clever Code with Unremarkable Code in Go

#66
Perhaps I'm reading this wrong, but if I'm not, it seems to be making a great point but missing a far greater one.

This is the more important lesson.

Replace clever code with unremarkable code.

Go has nothing to do with it. PERL has nothing to do with it. Switching languages most certainly has nothing to do with it. Keeping yourself in check and stepping back from your problems to understand their fundamentals, then looking for more appropriate and elegant methods of dealing with them in any language is what does this.

Re: Replacing Clever Code with Unremarkable Code in Go

#67
post #63

Earlier quoted context omitted.

Generics (outside of C++'s templates which are a pretty odd duck[1]) generate very little compiler costs and little to no runtime costs (depending whether they're erased or reified), unless you decide to (optionally) trade some added compiler costs for some runtime improvements by generating type-specialized collections behind the scenes. [1] and their cost is seriously compounded by the rest of C++, D has C++-style…

Depends what you're comparing against. If it's a poor man's generic implementation in current Go using interface{}, then obviously there would be no extra runtime overhead if the compiler generated that for you in a type safe manner; but compared to manually specialized collections or the built-in generic collections, there is quite a lot of runtime overhead. Whether the compiler costs are manageable or not is up for…

The built-in collections can remain built-in if that gets you off. Same deal for manually specialized collections, except those aren't generic, so they remain not generic.

Re: Replacing Clever Code with Unremarkable Code in Go

#68
post #44

http://www.paulgraham.com/avg.html Programmers get very attached to their favorite languages, and I don't want to hurt anyone's feelings, so to explain this point I'm going to use a hypothetical language called Blub. Blub falls right in the middle of the abstractness continuum. It is not the most powerful language, but it is more powerful than Cobol or machine language. And in fact, our hypothetical Blub programmer w…

I think this basically nails the attitude of every single go convert that I have spoken to. I am starting to get tired of hearing lines like "that lisp stuff is too complicated, I am a go programmer" or "why would you do x in y way, it's so much better in go". I don't think I have ever seen such unrelenting fanboyism in a programming language. It very well may be a fantastic language but its not an end all be all, we…

Ruby and Javascript were (are?) pretty similar when it comes to fans. It's rather depressing to see how cultish programming is.

Re: Replacing Clever Code with Unremarkable Code in Go

#69

Earlier quoted context omitted.

Like this, I presume: go func(){ for { select { case

Nice. I still haven't given Go much time, but I really like this form, where you can switch on multiple blocking calls. I've definitely wanted this in other languages where I'm using thread safe queues for communication, and had to do manual multiplexing into a new queue whenever I wanted to do a blocking get on multiple queues. Does anyone know of a convenient way to do this when handling multiple instances of pytho…

I've been implementing go-style channels in Python. Check it out here: https://github.com/stuglaser/pychan

Blocking on multiple channels works (chanselect).

Re: Replacing Clever Code with Unremarkable Code in Go

#70
post #56

Clever is not smart. Consider this anecdote: I recently put together a DIY 3d printer. I didn't have the right tools to cut steel bar, so I made a clever jig and used a shitty Dremel without enough clearance. Clever? Yes -- it got the job done with limited resources. Smart? No -- dumb, actually. Smart would have been driving 15 minutes to Harbor Freight to buy a $20 cut-off saw.

Smart might be to buy a cut-off saw. Brilliant would be to find a working cut-off saw with blade for $20!

I disagree. Brilliant would have been renting one for the day, or borrowing it from a friend.
Post reply on HN