7 ms·
I took his post as a fairly standard "worse is better" argument. Many newer or more fashionable languages enable some very elegant programming styles, but this
by rjknight 13y ago
I took his post as a fairly standard "worse is better" argument. Many newer or more fashionable languages enable some very elegant programming styles, but this comes with a concern about the elegance of one's code, which can easily result in the programmer spending more time thinking about elegance than about functionality. For example... should I use map or reduce here, or maybe an iterator, or... oh fuck it, I'll use a for loop. It turns out that the old-school for loop works just as well despite earning you precisely zero style points.
There's actually something quite liberating about languages that deny you any clever solutions. Just write code that works and don't worry about whether you could have used <fashionable programming concept X> instead. I found Go to be quite refreshing for the same reason - the standard library is pretty small and the language lacks anything particularly magical, even some stuff that Java has like generics. The end result, however, is code that is very easy to read and write for anyone who learned imperative programming in the last 30 years.
- bad_user 13y agoThe "worse is better" argument is in the context of Unix and C and cannot be separated from that context, otherwise it is meaningless. And a lot of thought went into Unix, as evidenced by its longetivity and long lasting tradition of its phylosophy. To date it's the oldest family of operating systems and at the same time, the most popular. Anybody that thinks the "worse" in the "worse is better" argument is about not carrying, is in for a surprise: http://en.wikipedia.org/wiki/Unix_philosophy http://en.wikipedia.org/wiki/Unix_philosophy Even in the original comparisson to CLOS/Lisp Machines outlined by Richard Gabriel, he mentions this important difference (versus the MIT/Stanford style): It is slightly better to be simple than correct. But again, simplicity is not about not carrying about design or the implementation and in fact the "worse is better" approach strongly emphasises on readable/understandable implementations. And simplicity is actually freaking hard to achieve, because simplicity doesn't refer to "easy", being the opposite of entanglement/interwiving: http://www.infoq.com/presentations/Simple-Made-Easy http://www.infoq.com/presentations/Simple-Made-Easy
- rjknight 13y ago"Worse is better" can easily be separated from that context, though I would admit that most people do it incorrectly. "Worse is better" is, ultimately, an argument against perfectionism. Many of the features of Unix could have been implemented in a "better" way, and these ways were known to people working at the time. But it turns out that those "better" options are much more difficult to implement, harder to get right and are ultimately counter-productive to the goal of delivering software that works. We can set up clear, logical arguments as to why doing things the Unix way is worse than doing things another way (e.g. how Lisp Machines would do it), but it turns out that the Unix approach is just more effective. Basically, although we can invent aesthetic or philosophical standards of correctness for programs, actually trying to follow these in the real world is dangerous (beyond a certain point, anyway). I think that's pretty similar to the OP's argument that, whilst Haskell is clearly a superior language to Java in many respects, writing code properly in Haskell is much harder than doing so in Java because, probably for entirely cultural reasons, a programmer working with Haskell feels a greater need to write the "correct" program rather than the one that just works. Java gives the programmer an excuse to abandon perfectionism, producing code that is "worse" but an outcome that is "better". I think I know what you're getting at, which is that a comparison between Unix and the monstrous IDE-generated Java bloatware described in the OP is insulting to Unix. On this you are correct. But for "worse is better" to be meaningful, there still has to be some recognition that, yes, Unix really is worse than the ideal. Unix isn't the best thing that could ever possibly exist, it's just the best thing that the people at the time could build, and nobody has ever come up with a better alternative.
- bad_user 13y agoI do not agree. "Worse is better" emphasizes on simplicity - and as example, the emphasis on separation of concerns by building components that do one thing and do it well. It's actually easier to design monolithic systems, than it is to build independent components that are interconnected. Unix itself suffered because at places it made compromises to its philosophy - it's a good thing that Plan9 exists, with some of the concepts ending in Unix anyway (e.g. the procfs comes from Plan9). And again, simplicity is not the same thing as easiness. > Haskell is clearly a superior language to Java in many respects, writing code properly in Haskell is much harder than doing so in Java I do not agree on your assessment. Haskell is harder to write because ALL the concepts involved are extremely unfamiliar to everybody. Java is learned in school. Java is everywhere. Developers are exposed to Java or Java-like languages. OOP and class-based design, including all the design patterns in the gang of four, seem easy to you or to most people, because we've been exposed to them ever since we started to learn programming. Haskell is also great, but it is not clearly superior to Java. That's another point I disagree on, the jury is still out on that one - as language choice is important, but it's less important than everything else combined (libraries, tools, ecosystem and so on).
- Dewie 13y ago> For example... should I use map or reduce here, or maybe an iterator, or... oh fuck it, I'll use a for loop. Use the least powerful tool that solves the problem. A map is less powerful than a fold (reduce), so use that if you can. A fold is probably less powerful than a for-loop, so use that if you can. An iterator is probably less powerful than a for-loop, so use that if you need the more streamlined accessing of elements rather than a fine-grained, indexed loop.
- rjknight 13y agoBut I know how to write a for loop in 15 different languages, and all of those other solutions work differently! If I have a problem that I can solve with a for loop, I should probably just use a for loop and move on to bigger problems, rather than remind myself exactly how iterators work in $LANGUAGE.
- deleted 13y ago[deleted]
- chriswarbo 13y agoBut I know how to write a GOTO in 15 different machine code dialects, all of those other solutions work differently! If I can solve with a GOTO, I should probably just use a GOTO and move on to bigger problems, rather than remind myself exactly how loops work in $LANGUAGE.
- marcosdumay 13y agoAnd the point is? Goto has a problem, it breaks the structure of the code. For does not have this problem. Thus, you should avoid goto, and there is no reason to avoid for. The fact that you knows how to write both changes what?
- chriswarbo 13y agoThe point is that different languages have different features and even those with similar features may place different emphasis on which to use. By writing code for the 'lowest common denominator' like this, you're missing the advantages of whichever language you're using. The most obvious symptom would be with libraries; even though GOTOs, loops, recursion and morphisms are equivalent, if most libraries expose APIs in a different style than your code, you'll have to sprinkle translation code all over the place. It also makes a difference for static analysis, eg. in IDEs and linters. For example, Iterators might give you more precise type hints or unhandled-exception warnings, which makes that style safer (all else being equal). Of course, the other point is that there are no such 'lowest common denominators'. GOTO certainly isn't, since Python, Java, etc. don't support them. For loops aren't, since languages like Prolog, Haskell, Erlang and Maude don't support them. Recursion isn't supported in COBOL or OpenCL, and took several decades to appear in FORTRAN. Morphisms require first-order functions, which rules out FORTRAN and C, and until very recently C++ and Java. It may or may not be possible to build such features from the other ones, but even so that's clearly working against the language and causing massive incompatibility with everyone else. Clinging to particular features like this will only blinker us to the possibilities which are out there. In this case, clinging to for loops implies avoidance of at least Erlang, Haskell and Prolog. These languages have a lot to offer, and are/look-to-become the go-to solutions* in the domains of concurrent, high-confidence and logical/deductive code respectively. Clinging to inappropriate concepts dooms us to 'reinventing the square wheel'. * No pun intended ;) PS: I actually think recursion and morphisms are safer, more structured and conceptually simpler than for-loops. See http://lambda-the-ultimate.org/node/4683#comment-74319 http://lambda-the-ultimate.org/node/4683#comment-74319
- Curmudgel 13y ago> Many newer or more fashionable languages enable some very elegant programming styles, but this comes with a concern about the elegance of one's code, which can easily result in the programmer spending more time thinking about elegance than about functionality. That's a common anti-intellectual fallacy about why people code in higher level languages. High level languages are attractive because they let you write code faster and make your code easier to maintain, and not because they're "fashionable". >There's actually something quite liberating about languages that deny you any clever solutions To me, "deny[ing] clever solutions" translates to "this code is going to be a pain in the ass to write because I'm going to waste time fighting the language to get what I want." Programmers learn to avoid unnecessarily complicated code as they gain more experience. Mature programmers should have the freedom to exercise their judgement about what kind of code is appropriate.
- bad_user 13y ago> That's a common anti-intellectual fallacy about why people code in higher level languages. High level languages are attractive because they let you write code faster and make your code easier to maintain, and not because they're "fashionable". Writing code faster is not my problem. The problem is building systems (that work) faster and this need sometimes requires using higher-level abstractions that maybe allow for more modularity, that maybe are more composable, or maybe are safer to use (and I'm specifically thinking here of concurrency, parallelism, asynchronous I/O, etc...). Higher-level abstractions is my goal when learning a new language (this or gaining access to another platform). "clever solutions" is indeed an unwarranted euphemism that people use. But we are ending up having such discussions, precisely because we aren't defining well what we are talking about. Writing less code is a subjective problem. Not being able to build and/or work with a certain abstraction is an objective problem.
- macspoofing 13y ago>High level languages are attractive because they let you write code faster and make your code easier to maintain, and not because they're "fashionable". Maybe, maybe not. But at least 2 of the 3 points that you made are not true of JavaScript. Also, the whole "write code faster" has always been perplexing to me. The speed at which you write code is never significantly different between any two mainstream languages to really matter in the end, especially since the lifetime of a piece of software is dominated by maintenance. And I don't know what you mean by "High level language". Java is a high level language. >To me, "deny[ing] clever solutions" translates to "this code is going to be a pain in the ass to write because I'm going to waste time fighting the language to get what I want." There's clever and then there's too clever.
- einhverfr 13y ago> Many newer or more fashionable languages enable some very elegant programming styles, but this comes with a concern about the elegance of one's code, which can easily result in the programmer spending more time thinking about elegance than about functionality. This isn't a bad tradeoff though. Elegance means generally gains in maintainability, possibly with lesser costs in the actual development. And thinking about elegance in code is the first step to writing better, more maintainable code. > For example... should I use map or reduce here, or maybe an iterator, or... oh fuck it, I'll use a for loop. It turns out that the old-school for loop works just as well despite earning you precisely zero style points. I usually stick with for loops because they are clear. Remember: elegance is about simplicity and clarity. If you sacrifice either of these, you are reducing the elegance of your code.