3 ms·
Minimizing key strokes is seen as 'false', but it has actually been proven that one can write (debug, maintain,...) about 10 lines of code per hour. Those 10 li
by toolslive 11y ago
Minimizing key strokes is seen as 'false', but it has actually been proven that one can write (debug, maintain,...) about 10 lines of code per hour. Those 10 lines can be 10 lines of assembly, 10 lines of c++ or 10 lines of haskell.
Of course, you can do much more in 10 lines of haskell than you can do in 10 lines of assembly. It basically means you want to be work on the highest level of abstraction that you can afford. It also means that economy of expression is important.
source: https://vimeo.com/9270320 https://vimeo.com/9270320
- Jtsummers 11y agoProbably more a warning against pre-mature optimization. If you can eliminate all ; in most, or even all, circumstances in otherwise C-like syntax, what do you gain? And most of the savings you see there are from having greater levels of abstraction available. Assembly = arithmetic. You have to explicitly state each step, and on its own there's no understanding of what you're operating on, they're all bits (numbers). C++ (ok, more C) = algebra. You have a bit more understanding of your structure, better names and concepts behind things (types = units, for instance). You're still operating on bits, but now most of those bits have a specifically, language encoded, meaning. Haskell = calculus. Not only are your bits typed, so are your functions (ok, technically also typed in C and kin syntaxes, but not usually as useful) and you can pass them around and modify them. EDIT: I'm more picking on the class of syntax available. When you include semantics OO languages offer a great deal more expressive power than most procedural languages. Probably should've just had C and not C++, but it is what I wrote. More generally what I should have written was towards language classes: assembly (as most primitive procedural language), structured procedural languages (C, Go, Algol, Ada, etc.), OO languages (Java, C++, Smalltalk, etc.) and functional languages (lisps, Haskell, ML-family, etc.). But then you have to break it down further. OO is not inherently more or less expressive than functional languages, it depends on the feature set of the OO and functional languages. Smalltalk is very expressive, easily comparable to the more expressive functional languages. Java, as it used to be, not familiar with developments post adding generics so I'm really rusty on it, was not so expressive. So a comparison between Smalltalk and Common Lisp would put them on a similar level of abstraction. But Common Lisp versus Java (again, with my outdated knowledge), Common Lisp is at a higher level of abstraction (both syntactically and semantically).
- Avshalom 11y agoIt's a 'false god' as in not something you should worship at the feet of. Don't prefer fr to for; feel free to require empty () when calling a function without arguments; lambda instead of \ is fine. It also doesn't mean you can't, just that you shouldn't use it as a/the primary concern.
- josteink 11y ago> Those 10 lines can be 10 lines of assembly, 10 lines of c++ or 10 lines of haskell. I seriously doubt the validity of this. 10 lines of assembly is usually reasonably clear-cut what is about. 10 lines of Haskell can take hours of mindfuck trying to peer through the functor and monad operators, trying to work out which operation does what and which operator takes precedence where. And then you need to start worrying about which data-type are you actually working on. And how does that type implement lift and bind. Etc etc. Basically 10 seems like a BS number taken out of thin air, because it looks good in a base 0x0a number-system.
- Jtsummers 11y agoThe origin of this idea, for my first introduction I guess, was in The Mythical Man Month. I don't have a copy at hand, so I can't read what Fred Brooks wrote specifically. 10 is very precise, but really the writing was about the order of magnitude that people can manage in a day. It's about the level of complexity involved. 10 lines of assembly is very clear about what exactly is happening. It's a sequence of adds, loads, branches, stores, moves, etc. Each step is incredibly clear, but what are they operating on? Now it's not so clear. What is R2 at this point in the program? Am I calling a subroutine? On this architecture is there some way to automatically handle this with storing the PC and everything, or am I going to use a regular branch instruction? Regular branch? Ok, now I'm storing the PC and other information away per our calling convention. C: Oh, I'm calling a function. I'm calculating a formula. I have named variables, so it's clear what I'm operating on (hopefully, this is at least possible here, even if not well done in practice). With typedefs, good naming conventions, structs and enums, you can maintain an order of magnitude greater complexity in the same time as an assembly programmer, in an order of magnitude lower amount of code. Haskell: I have functions, I have types, I operate over these types transforming them from one to another. Collecting objects of a type here, transforming them there, zipping them with those, and back again. And I've written a function that would take dozens of lines of C or grosses of lines of assembly, and it took me an hour. Again, an order of magnitude more complexity can be entertained in another order of magnitude less code. Don't get stuck on the specific number, that's incredibly pedantic and unhelpful. It's about the degree and magnitude.
- codygman 11y ago
- seanmcdirmid 11y agoThen of course APL is king since a 10 line APL program is huge. But that doesn't really bear it given APL's reputation as a write only language. Abstraction also has a cost. You can cram a lot into 10 lines, but if you have to think a long time about the most elegant way to do that, you might not be winning in productivity.
- jerf 11y agoIt may help to know what he's talking about. He's probably [1] not referring to whether you use C-style || vs. Python's "or". He's probably referring to things like this: NB. Initialize a global, but not if it's already been initialized NB. Example: 'name' initifundef 5 initifundef =: (, ('_'&([,],[))@(>@(18!:5)@(0&$)) ) ux_vy ((4 : '(x) =: y')^:(0:>(4!:0)@<@[)) From the bottom of http://code.jsoftware.com/wiki/Phrases/Language_Utilities http://code.jsoftware.com/wiki/Phrases/Language_Utilities . NB. appears to be the comment marker, so the last line is the payload. Yeah, I picked the worst thing I could find, and my guess is that that code is doing something really nasty hacky, because it is too large to be doing only what it is described. On the other hand, the fact that I pretty much have to guess with almost no information is sorta my point. There's creating a computer language to be concise and readable, and then there's just concise. You can also have a look at Perl, which can (and generally should) be programmed as a fairly normal dynamic object-oriented language, but has a subset of functions, operators, and implicit variables that allows you to spit out terribly small, dense lines of few characters that do horrible things, usually not just doing whatever they are putatively doing but also having other mysterious side effects in the process. [1]: I'm reasonably confident I'm on the right track here, but don't want to put words in his mouth, so I'm hedging. Especially since there's a non-zero chance the original author will show up here. As I type this, that has not happened yet.
- bcbrown 11y ago> NB. appears to be the comment marker Likely in reference to https://en.wikipedia.org/wiki/Nota_bene https://en.wikipedia.org/wiki/Nota_bene