Leancrew
leancrew.com · Personal blog · on HN since 2009
Dr. Drang, a retired engineer, writes about Unix tools, Python, Apple gear, charts, and programming, in a long-running personal blog.
What HN saysHN cites it for the Knuth versus McIlroy shell comparison on composable pipes, and praises its readable design and posts on RSS.
160HN people shared it
68linked it in comments
269stories submitted
4.4Kstory points
2 months agolast shared
2009people per year2026
Most-shared posts
- 1Knuth and the Unix Way41 people · 436 points · first shared 2011 · 62 comments on HN
- 2Where modules go to die11 people · first shared 2012
- 3On Hyperloop7 people · 168 points · first shared 2013 · 203 comments on HN
- 4iPhone 15 Pro facts and estimates6 people · 47 points · first shared 2023 · 31 comments on HN
- 5Apple gold5 people · 362 points · first shared 2015 · 95 comments on HN
- 6Old Icons – All This4 people · 4 points · first shared 2026 · discussion on HN
- 7I hate stacked area charts (2011)3 people · 370 points · first shared 2013 · 64 comments on HN
- 8Wordle and grep3 people · 88 points · first shared 2022 · 52 comments on HN
- 9Timers, reminders, alarms – oh, my3 people · 57 points · first shared 2018 · 9 comments on HN
- 10Why I Like DST3 people · 2 points · first shared 2013 · 1 comments on HN
- 11Aluminum and strength2 people · 56 points · first shared 2015 · 29 comments on HN
- 12Why I Left Perl2 people · 52 points · first shared 2012 · 40 comments on HN
- 13Filtering RSS with XSLT2 people · 7 points · first shared 2022 · discussion on HN
- 14Discontinuous Ranges in Python2 people · 5 points · first shared 2019 · 1 comments on HN
- 15Font Memories of Old Macs2 people · 4 points · first shared 2025 · discussion on HN
What HN people wrote when they linked it
orf · 2024-05-26
Terminals are not obsolete, it’s just that we try and fit too much into them.
For better or for worse, composable commands composed together with pipes is really effective. See [1] as a good example.
It’s not clear that a new “real” language would be able to have the same effectiveness if it didn’t make some of the same choices and trade-offs. Nushell (and powershell) definitely falls into the “real language without bash” category.
By this I mean: what parts of a “real” language would help with the problem linked in [1]? A imperative language would hinder this greatly, and a fully declarative one is too constraining. So you end up with a mix of both.
1. http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
wwweston · 2020-10-17
It isn't just students. The classic Knuth vs McElroy comparison shows that the right abstractions can matter quite a bit:
http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
ogre_codes · 2020-09-23
Worth following to the original story on Dr Drang's site: https://leancrew.com/all-this/2020/08/rss-and-the-pleasure-of-not-thin…
Related. Such a pleasure to read a site designed to be read with a link that works the way web links work. So many articles are on sites filled with utter garbage, flashing adverts, notifications, and annoying newsletter requests that hitting simple links is just relaxing.
This whole topic made me realize perhaps I should set up an RSS feed with sites like Dr Drang's and this one just so I can have regular access to good non nonsense content.
BenoitEssiambre · 2020-08-12
Carmack weights in: https://twitter.com/ID_AA_Carmack/status/1293311943995002881
"This HN discussion https://news.ycombinator.com/item?id=24123878 is topical for me: at this very moment, I am implementing C++ MFCC code myself, because my attempt to integrate Kaldi (on windows) was unpleasant. It already took more than an afternoon, but I learned good things! \
I'm more sympathetic to the Use-All-The-Dependencies crowd than some might suppose. It definitely isn't my way, but I see them as a fellow subclass of programmer, evolved for other environments. It is amazing what can be cobbled together in a weekend now. \
The old Knuth vs McIlroy story is relevant: http://leancrew.com/all-this/2011/12/more-shell-less-egg/
Generally, use-the-tools is correct, but sometimes you really do want a Knuth (or maybe a Carmack)."
"
sedachv · 2019-10-29
> XML schemas give you a ready-to-use format to describe, restrict and document available configuration settings.
As someone that likes and uses s-expressions, I never thought I would find myself defending XML, but here we are in 2019, no one understands basic parsing theory anymore, and file formats have "evolved" to hot garbage like YAML and TOML.
XML has some great tools in comparison:
http://xmlsoft.org/xmllint.html
https://relaxng.org/
> But for markup... we may be better off to just use markdown inside CDATA blocks
SGML can still make a comeback: https://leancrew.com/all-this/2014/09/sgml-nostalgia/
vram22 · 2019-02-14
>is "Why would I want to write a complicated mess like that?" Just use ${FAVORITE_PROG_LANG:-Perl, Ruby, or whatever}".
Some discussion on the pros and cons of those two approaches, here:
More shell, less egg:
http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
I had written quick solutions to that problem in both Python and Unix shell (bash), here:
The Bentley-Knuth problem and solutions:
https://jugad2.blogspot.com/2012/07/the-bentley-knuth-problem-and-solu…
mschaef · 2018-12-17
There's another interesting story about Knuth that's worth repeating here.
http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
The tl;dr is that Knuth wrote an elaborate implementation of a program to solve a particular problem, and Doug McIlroy replaced it entirely with a six step shell pipeline. (Knuth's program was written using his literate programming tools, could be typeset in TeX, and involved some precise work with data structures and algorithms.)
I love this story as an example both of Knuth's genius and perspective, but also as a way to show what his level of dedication can achieve. It's an amazing intellectual accomplishment.
I also love this story as a demonstration what those of us without that skill and dedication can achieve using the advancements built on the work of Knuth and others.
minikites · 2016-03-13
My favorite counterargument:
http://www.leancrew.com/all-this/2013/03/why-i-like-dst/
>If we stayed on Standard Time throughout the year, sunrise here in the Chicago area would be between 4:15 and 4:30 am from the middle of May through the middle of July. And if you check the times for civil twilight, which is when it’s bright enough to see without artificial light, you’ll find that that starts half an hour earlier. This is insane and a complete waste of sunlight.
>If, by the way, you think the solution is to stay on DST throughout the year, I can only tell you that we tried that back in the 70s and it didn’t turn out well. Sunrise here in Chicago was after 8:00 am, which put school children out on the street at bus stops before dawn in the dead of winter.
DST is the only sensible option in my opinion.
zdw · 2016-01-03
Another, similar post:
http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
The point of both of these posts is more that Unix style tools are extremely powerful and expressive, to the point that writing more involved code for most simple tasks (especially one-off tasks) frequently isn't worth the effort.
Complexity doesn't improve things, especially when it doesn't add value.
ninjakeyboard · 2015-08-30
Probably an uninformed response, but this looks a lot like menlo to me. Edit: People compare to DejaVu sans serif - which is almost identical to menlo as well: http://www.leancrew.com/all-this/2009/10/the-compleat-menlovera-sans-c…
ky3 · 2014-09-17
utterly amazed how they invented such a powerful concept of functional programming for the shell
You might be interested in the classic McIlroy-Knuth dialogue:
http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
The Unix "Software Tools" philosophy -- small kits composable into something big -- is deeply shared by functional programming.
I don't think one begot the other. It was just obviously the natural thing to do during that era.
catenate · 2013-08-09
People like to put down scripting, especially shell scripting, as "not a real language." I prefer shell scripting, since it lets me tie together programs written in many languages, each doing something that language does very well. The opposite of this would be to try to do everything in one language, which seems inefficient to me. Difficult applications of one language are often handled efficiently in some other--why not take advantage of that? Of course, I've made my peace with living in a polyglot computing world, and having to at least superficially know many programming languages and little-language tools.
The best difference I've seen between "programming" and "scripting" is Knuth v McIlroy, summarized here.
http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
ComputerGuru · 2009-10-31
Great article, and awesome fonts.
But for the record, OS X now ships with a new default monospace font called Menlo which is quite nice... but it's really just Deja Vu Sans Mono with modified punctuation (most importantly though is the slash through the zero).
View it here: http://www.leancrew.com/all-this/2009/06/snow-leopards-new-monospaced-…
SkiFire13 · 2024-09-26
> > Bundling dependencies in the stdlib "solves" the problem by making new major versions impossible. > > Yes, which is a feature. For example Go is very annoying about this not only on the stdlib. https://go.dev/doc/go1compat a lot of 3rd party libs follow this principle as well.
But there's no reason such a "feature" requires bundling dependencies in the stdlib. As you mention 3rd party Go libs manage to do this perfectly fine.
> but I tend to think that the stdlib should be fairly big and tackle most common problems.
I tend to disagree with this, because the way to tackle those common problems with likely change in the future, but the stdlib will be stuck with it for eternity. I would rather have some community-standard 3rd party crate that you can replace in the future when it will grow old. See also "Where modules go to die" https://leancrew.com/all-this/2012/04/where-modules-go-to-die/
necubi · 2023-09-15
As someone building my startup [0] on Rust (and a fan of the language since ~2014) I don't think this is a very compelling list of points.
> Rust is overhyped
People are excited about Rust! Not sure why this is a reason you _shouldn't_ use the language.
> Rust projects decay
The text doesn't match the headline here; Rust takes backwards compatibility very seriously, and rust code I wrote in 2016 against Rust 1.10 still compiles with Rust 1.72 in 2023.
> Rust is still in beta
Mentions missing async traits, which is legitimately annoying, but the workaround with the async_trait crate works in practice
> The standard library is anemic
This is a tradeoff; big standard libraries become graveyards over time (the classic article on this: https://leancrew.com/all-this/2012/04/where-modules-go-to-die/). How long was Python stuck with a terrible HTTP client because that was the one in the standard library? In Rust we have an incredible, state of the art regex library because it's a separate crate and is allowed to evolve.
> async is hard
Rust's async is hard to get started with; it's a barrier to get over like learning the borrow checker and lifetime system. But once you do I've found it productive and incredibly performant.
--
Overall, I don't think that Rust is the right solution to all problems. Rust makes you think about everything you're doing, the ways in which your programs use resources, and every possible class of errors. This is incredibly useful for writing fast…
gilch · 2022-09-24
The article starts with some reasonable premises, but the conclusion does not follow.
I think most APL programmers would disagree with this take. Dense code has real advantages, and naming everything has real costs that are hard to see. There's nothing magic about a "line" that suddenly allows for chunking. You have to build a parse tree in your head in any case.
I'm reminded of Doug McIlroy's challenge to Knuth.[1] It's worth a read.
Would you rather have 6 lines of dense shell, or 10 pages of Fabergé egg? I'll take the shell, thanks.
Look at the source code for J (an APL derivative)[2]. It's written in C, but that C was written in APL style by APL programmers. Lines leverage macros and 1–2 character names, making them extremely dense. Some files have a comment on nearly every line. For an average C programmer, this code looks absolutely insane. But it's not. The J devs find this perfectly readable and maintainable. It's clean code! If written with the typical C idioms, it could easily be 10x as long, and therefore harder to maintain. Your first impression is a snap judgement due to a difference of culture. You can learn to read this style with practice. Whatever your current style, that took practice too.
[1]: http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
[2]: https://github.com/jsoftware/jsource
MontyCarloHall · 2022-05-07
>From that perspective, it was entirely reasonable to believe that if a command was so complex that it needed options than it was likely more appropriate for one of the other user interfaces
What would the non-shell interface to commands for text processing pipelining (e.g. sort, cut, grep, etc., all of which absolutely need options to function) have looked like? Some people to this day believe that any text processing more complicated than a simple grep or cut should be done in a stand-alone script written in a domain-specific language (e.g. Perl or awk), rather than piping shell commands to each other.
Personally, I’m glad we got the best of both worlds—having command line tools with a dizzying array of options doesn’t preclude being able to accomplish the same tasks with a more verbose stand-alone script. It is often far faster to write shell pipelines to accomplish fairly involved tasks than to write a stand-alone script. The classic example is the (in)famous McIlroy vs. Knuth: six lines of McIlroy’s shell pipeline accomplished the same thing as dozens of lines of Knuth’s “literate program,” while being equally as understandable [0].
>It’s a shame because McIlroy had a lot of interesting ideas around pipelining audio and graphics that, as far as I know, never materialized.
I would love to hear more about this. The UNIX shell is amazing for pipelining (most) things that are easily represented as text but really falls flat for pipelining everything else.
[0]…
JohnHaugeland · 2022-03-09
> This assumes that experience is more important than skills.
No, it doesn't.
It just means that the word "senior" measures experience, not skills, and is frequently misused.
It's fine to prefer a super skilled junior, and smart companies do that all the time. But that doesn't somehow make them senior, and failing to understand the distinction is a significant problem for hiring.
.
> An extremely smart and motivated programmer with 3 years of experience is going to be far above a programmer with average intelligence who phones it in.
My experience in industry and my personal viewpoint is that actually lazy programmers tend to be the best. They don't over-engineer things, and they write their tests, because they know it's better to spend an hour now than five hours next month.
My experience is that smart and motivated people tend to fall on the Knuth side, and not the McIlroy side, of More Shell Less Egg, and this is not what I personally want.
https://leancrew.com/all-this/2011/12/more-shell-less-egg/
Anyway, this is all irrelevant in my opinion. We can hem and haw until the cows come home about who's going to be a good programmer, what styles we prefer, what candidates we prefer, and who knows, maybe one of us will get lucky and say something correct one day. Most people never do. :)
In the meantime, these words formally refer to years of experience, and if you want to focus on their skillset, then read their list of skills, instead. The standard resume has…
FabHK · 2020-06-25
I find your certainty about something you appear to know nothing about mind boggling. Every crash is a deficiency of sorts, so let’s just tell Airbus to build planes that don’t crash! Easy! Let’s just have peace instead of war! Obvious!
It is not sufficient to point out “obvious deficiencies”, one must also point out possible improvements. As other posters (with more patience than I can muster) have pointed out, it is not obvious how to improve this. Putting a lock in place to prevent movement of the lever adds another level of complexity that can itself fail. This is well known and has been extensively studied (a classic paper is No good deed goes unpunished: Case studies of incidents and potential incidents caused by protective systems [0]).
Listen, for example, to this episode of “Undercover Economist” Tim Hartford’s Cautionary Tales [1] (though the example given might itself be problematic [2]).
Airplanes are extraordinarily safe already (look at the amazingly low accident rate, given those fallible, sometimes even negligent and incompetent people that fly them).
Contrary to your facile assertion “There is lots of room for improvement”, there are very few obvious improvements. Change something and you might prevent one accident but enable another one.
As an example: terrorists enter the cockpit. Easy, obvious: lock the door! Ok. Suicidal pilot locks out the other pilot and flies into a mountain. Easy, obvious: unlock the door. GOTO 10. It’s not obvious. These are…
bsder · 2019-08-24
> However, its interesting to see so many dependencies that are required to build it (73 crates last time I checked)
The problem is that Rust has two issues:
1) In Rust, you don't pay for what you don't use. This means that a lot of stuff tends to be an external library since not using something means you can exclude it COMPLETELY. The issue is that things tend to get atomized more finely than most languages would do.
2) Rust is trying to not bake things into a standard library too early. This is a good comment about standard libraries from Python:
"The standard libraries constitute one of Python’s great features, but they tend to suck up all the oxygen. Programmers are reluctant to write libraries that duplicate their functions, so poor libraries in the standard set persist. Only a few people, like Reitz, are willing to write modules that compete with the standards."
https://leancrew.com/all-this/2012/04/where-modules-go-to-die/
coder543 · 2018-11-23
> even just getting a camera feed on Flutter isn't a built-in
Why should it be built-in? That's such a C++ (or C) mindset: that using dependencies is bad, which stems from the difficulty of adding and updating dependencies in the C++ world.
In a language with a rock solid package manager, it's better to have a small core and then pull in what you need. Each of these out-of-core dependencies can have separate lifecycles, which makes it a lot easier for them to be developed and updated, making them higher quality. If breaking changes need to be made, that can easily be done in out-of-core libraries, since existing projects can continue depending on their SemVer-defined compatible version of the dependency ad infinitum, and the project maintainers can continue releasing updates to any SemVer series of the package if they need to backport changes to older versions. When something is in the core, it's very hard to update it while maintaining complete compatibility, and people can only depend on one version of your core library at a time, so there's no room to be flexible. This constricts growth, since the core needs to meet everyone's needs, but it doesn't have the flexibility to do that as the world changes, so it often meets no one's needs.
I don't know how good Dart's package manager is, since I haven't really touched Dart since the very earliest days of the language after it became public, but Rust's package manager is excellent, and having most things out-of-std has been…
allover · 2018-01-07
> We should always try to strive to lower dependencies when it makes sense.
Maybe, but I think 'when it makes sense', might be 'rarely'. There a 2 ways to avoid dependencies: 1. lean on a batteries-included standard lib as this gist does or 2. write it yourself.
Problem with 1. is standard lib libraries aren't always great, see 'where modules go to die' [1],
(examples: httplib/urllib in Python, or the string libraries in PHP). This can stifle innovation and alternatives, unless an alternative with a strong marketing push can arise ('requests' for Python). Sadly, often because the situation isn't 'that bad' (as in the case of PHP) people continue to use poor APIs.
Problem with 2. is you're probably getting an order-of-magnitude fewer brain cycles on code you wrote yourself -- unless you can spend the extra effort to open-source it, and get lucky with popularity/contributors, it's likely to be inferior than a well-maintained 3rd party alternative.
[1] http://www.leancrew.com/all-this/2012/04/where-modules-go-to-die/
lmm · 2016-01-20
> I don't really get the complains about a kitchen sink of predefined functions, or the functional syntax. You can always fall back on defining a function yourself. (And with the amazing documentation and Google, it's quite easy to find most functions anyways.) Likewise, you can always use C++-style syntax for defining functions, for loops, etc.
http://www.leancrew.com/all-this/2012/04/where-modules-go-to-die/
In the short term a kitchen sink of predefined functions are great, but in the long term they become baggage that holds a platform back (and there's no way to improve them without breaking backwards-compatibility). They're usually a sign that the platform has its priorities wrong: you need a good dependency management solution, and once you have that there's not much value putting things in the standard library. (Look at Scala, which is going to a lot of effort to carve things out of the standard library so that they can be maintained separately with their own release lifecycle).
tjl · 2015-06-03
Most of the Coursera and EdX lectures are actually college lectures, just put online.
I know as a TA, it can be hard to answer some questions via e-mail, so I'm assuming it would be difficult to do in a web forum as well. I once spent several e-mails trying to explain something to a student and after failing, asked them to come to my office and explained it in five minutes in a way they understood. So, while there might not be the difference for a lecture, it's the things around the course that can make the experience better.
I know Khan Academy has some problems (at least in the past) with some of its material. One example is discussed in,
http://www.leancrew.com/all-this/2012/12/khan/
I can verify what he's saying is correct as I used to be involved in teaching the same material.
I first learnt C++ in an in-person corporate training session and it was excellent. I think it all depends.
stonewhite · 2025-01-31
Good points. 3rd one reminds me of the Knuth vs McIllroy story about 10+ page pascal vs 6 bash pipes[1]
[1]: https://leancrew.com/all-this/2011/12/more-shell-less-egg/
jks · 2023-07-31
This reminds me of the story in which Don Knuth wrote a literate program in WEB (reportedly over 10 pages) to do some text processing and Doug McIlroy did the same thing in a six-line shell script:
http://www.leancrew.com/all-this/2011/12/more-shell-less-egg/
entropicdrifter · 2021-12-03
The other problem with literate programming having been pointed out by McIlroy:
https://leancrew.com/all-this/2011/12/more-shell-less-egg/
mrec · 2021-09-05
There's a downside to Python's batteries-included approach though:
https://leancrew.com/all-this/2012/04/where-modules-go-to-die/
HN discussion: https://news.ycombinator.com/item?id=3913182
The obvious compromise would be to let libraries bake as third-party projects for a good long while until there's a fair amount of consensus that they're the Right Thing To Do, then pull them into the standard library. Java's Joda-Time would be one example.
smnrchrds · 2021-08-10
So Hyperloop should be very likely to occur?
https://leancrew.com/all-this/2013/08/hyperloop/
kilodeca · 2021-07-26
From Doug McIlroy's explanation of a shell pipe line tr stands for transliterate.
https://leancrew.com/all-this/2011/12/more-shell-less-egg/