We Who Value Simplicity Have Built Incomprehensible Machines
51–60 of 96 posts
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#52Gall's Law is relevant here. http://en.wikipedia.org/wiki/Galls_law A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#53For example, I deal with a lot of network code. I regularly have to make various softwares work with different protocols, sometimes in async systems, sometime in threaded systems, sometimes in simple blocking systems. Further, networking is an inherently layered space - (eg. the JSON app specific protocol sits on http sits on tcp, which sits on ip, which sits on ethernet, id like to bea able to say is encapsulated in rather than sits on, but that breaks at various layers :/). So anyway I get the order to implement support for FooProto in a few systems. Great, I've heard about FooProto and wanted to play a bit.
A bit of research turns up that there are a few major and complete implementations. One is the reference implementation and it is of course big, bloated and slow. It does everything but there is no cohesion to the API or whatever. That one is probably out.
So the others have mixed reviews but a few are very popular and "simple".
Option 1: exposes 4 methods, provides my code with a well designed data structure, and looks fantastic. Problem is, it does blocking I/O and isn't thread-safe. It will work for some situations, but not all the ones I have. Worse, the transport is pretty heavily tied to the socket code and various system calls. But it is very simple.
Option 2: optimized for non-blocking. Has lots of callback hooks. Still tied in with the socket/syscall layers, but not in a way that makes extraction impossible. But it would take a few hundred lines of wrapper to make it look synchronous. And forget thread safety.
Option 3: Really thread safe, decent api, layers split out, but in a weird metaphor that requires some odd wrapper code would really require some rework to translate, or would require reworking of the hosting code to deal with the metaphor.
So which of these is simpler? Arguably each of them. One solution of course would be to use each as needed. Then of course I have to track multiple APIs, there are integration and bug compatability concerns. Not really simple.
Odds are I'll end up choosing the reference implementation or make my own, just because in the small it is more complex, but in the large, it makes my life simpler - one code base to handle multiple situations. Also a simpler choice, albeit on a different access.
So my point is, simplicity is not just hard, but sometime incompatible with itself. Simple on one axis may complicate things on another, and in irreconcilable ways.
Aside: To anyone implementing protocols -- _Please_ keep your parsers, state machines and transports as loosely coupled as possible. I, and many people I know, will love you for it. Transports change, encapsulation is common, and networks seem to be mostly edge-case. Feel free to add a layer tying them all together in a nice common-use api, this is a good thing too, but keep in mind there are always other use cases. Keep in mind that you are always just feeding your parser a stream of bytes, and feeding your state machine a series of tokens. Some protocols have a few layers of this built in. Due to the nature of the beast tho, it always can be modeled that way.
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#54Earlier quoted context omitted.
The failure isn't in that we're adding too much complexity (we have to be able to create complex structures) or that we're not layering it enough (leaky abstractions build up). It's a general, and much more far-reaching, problem: our abstraction mechanisms are failing us. We need to stop complaining and put more effort into research. There are four or five projects working on this and, literally, hundreds of photo-sh…
Any links to such projects?
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#55What insight does the author have to offer with this essay? It's easy to complain about complexity, harder to offer a simpler but equally capable alternative. The author makes it sound like simple is easy. As if it's just a matter of saying no to complexity, like saying no to memcpy() whenever we have a memmove() that's good enough. This is not the case. Simple is not easy. On the contrary, simple is hard . So you th…
Simple by design might be hard, but "simplify in retrospect" is easy. It just needs you to be willing to sacrifice meaningless backwards compatibility and inflict some temporary pain (rewriting stuff dependent on it) for the benefit of tomorrow.
>So you think "ls" has too many command-line flags; how are you going to cut the number in half? Which ones do we keep and which ones get axed? How are you going to provide for all the same use cases that those 35 flags were added for?
You don't. Fuck ALL those use cases. Keep only those that are used a large percentage of the time by the large majority. For those that need the extra juice, let them use the old, convoluted version. You don't have to have "ls" be a be-all-end-all. Have both ls AND a power-version if anyone cares to maintain the second.
And sure as hell, don't keep competing or duplicated flags just for backwards compatibility.
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#56What insight does the author have to offer with this essay? It's easy to complain about complexity, harder to offer a simpler but equally capable alternative. The author makes it sound like simple is easy. As if it's just a matter of saying no to complexity, like saying no to memcpy() whenever we have a memmove() that's good enough. This is not the case. Simple is not easy. On the contrary, simple is hard . So you th…
In my reading I certainly saw insight, I think you're not pulling your 'world view' back enough when reading it and looking too closely at the examples. I think his point is not that "ls" needs less flags, it's that it needs no flags. Or that libpng is low-level versus high-level, it's more that there shouldn't even be a concept of low-level. And the other thing he seems to be saying is that backward compatibility sh…
Then don't use the flags. The default bare 'ls ' is sane 99% of the time for me, and I consider myself a junior power user.
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#57What insight does the author have to offer with this essay? It's easy to complain about complexity, harder to offer a simpler but equally capable alternative. The author makes it sound like simple is easy. As if it's just a matter of saying no to complexity, like saying no to memcpy() whenever we have a memmove() that's good enough. This is not the case. Simple is not easy. On the contrary, simple is hard . So you th…
I don't disagree, but these points needs highlighting: > It's easy to complain about complexity, harder to offer a simpler but equally capable alternative. Want real stuff? Check out VPRI's work: http://vpri.org/html/work/ifnct.htm Right now, they're working on a 20KLOC OS (including desktop publishing, messaging, and the whole compilation chain). That's about 4 orders of magnitude smaller than current systems. Here…
Is it possible to summarize in a paragraph how they are able to achieve this LOC reduction? Is it simply that systems like Linux et. al. have been cobbled together by many hands over many years while VPRI has a single vision? Are there coding techniques I can use today in my own work? The only example I've found was a mention of some networking stack that was able to make use of a parsing engine, rather than implementing a custom networking-specific engine. This sounds like nothing more (not to trivialize this task) than choosing the correct parts to turn into reusable libraries and then reusing them.
> they don't mind small unjustified complexities
This is something I've noticed as well. Complex code of my own creation grates on my nerves until I am able to erode it and smooth it out. I get the impression that not everyone feels this way.
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#58What insight does the author have to offer with this essay? It's easy to complain about complexity, harder to offer a simpler but equally capable alternative. The author makes it sound like simple is easy. As if it's just a matter of saying no to complexity, like saying no to memcpy() whenever we have a memmove() that's good enough. This is not the case. Simple is not easy. On the contrary, simple is hard . So you th…
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#59is BCD really a bad idea? it's 2012 and generally we still have to live with binary-only floats and without a decently fast decimal arithmetic.
Re: We Who Value Simplicity Have Built Incomprehensible Machines
#60Simplicity is such an overloaded concept. It can mean: reducing the complexity of interface, reducing the complexity of operations, reducing the understanding required for use, reducing work to do the unanticipated, keeping common metaphors (as opposed to introducing new ones), and on and on. Ugh. For example, I deal with a lot of network code. I regularly have to make various softwares work with different protocols,…
Ok, I have to curb my excitement here a bit, because what I'm about to tell you is that I'm solving exactly your problem with an obsessive focus on achieving exactly what you desire.
Though in saying so I'll have to disagree with you slightly when you say:
> Simple on one axis may complicate things on another, and in irreconcilable ways.
Basically I'm striving for (and believe I am on the verge of achieving) a design that achieves the best possible simplicity for network parsers and serializers in all dimensions. If you're wondering what the catch is, the catch is that it's taken me 2.5 years and counting to refine the design to the point where it can achieve this.
My library performs no I/O (it's buffers in, buffers out), is completely resumable (so you can suspend the state machine at any point and resume it later), is completely composable (so you can create pipelines that feed the output of one parser to the input of another), loosely coupled, small (And it's open-source. Don't be misled by the fact that it's advertised as a Protocol Buffer library; that's how it started, but I'm working on generalizing it to be capable of arbitrary parsing and serializing. Though Protocol Buffers schemas are used to specify the structure of any structured data that a parser wants to produce or a serializer wants to consume.