A Parable by Dijkstra (1973)
cs.utexas.edu
cs.utexas.edu
Also, those helpful arrows would be guiding the passenger the wrong direction for two of those car lengths.
So we have comments that go out of sync with the running program, a spec that lies about reality, and an implementation that doesn't match the spec. Yep, that sounds like programmers to me.
Legit parable.
Edit: just realized the least lucky passenger would have to walk six car lengths. If the passenger is already at the wrong end of the "symmetrical" two-car unit with a broken toilet, the arrow will point them in the direction of the broken toilet. If the broken toilet is the last car, then they must walk back two car lengths to get where they started. Now if the next two-car unit is turned the wrong direction they must walk two more car lengths.
So add to this a spec that's difficult to reason about.
Again, legit programmer parable.
I just want to elaborate on this to show which assumptions you are making. There are two ways to make a paired unit: --+ and -+-.
In your scenario I think you assume the first. The end of the train is thus ...+----+, since you mention the second last car's orientation being reversed. The +'s represent toilets. Then, what you are saying is to consider a passenger located at the ^ symbol: ...+--^--+. In this configuration, your observation makes sense.
I do think that a more practical solution is to work only with (-+,-) pairs. The symmetry that Dijkstra talks of is then that (-+,-) and (-,+-) are equivalent for the purposes of the problem. Then an end of a train would be: ...-+-+-. This is then the "extra few feet" that he talks of.
"When each car with a toilet was coupled, from now until eternity, at its toileted end with a car without a toilet, from then onwards the shunting yard, instead of dealing with N directed cars of two types, could deal with N/2 identical units that, to all intents and purposes, could be regarded as symmetrical."
On the physical "train" side of the analogy, we've got a believable scheme to save money by only having a toilet in every other car. Given the constraints, it is indeed clever to make these two-car atomic units and reimagine them as symmetrical. All the fixes in the story taken together could pale in comparison to the cost of putting a toilets all the cars.
But when we cross the digital divide we get a completely different set of constraints. Even if dealing with 100 million train cars it may be cheaper to just fork the entire train yard and add a toilet object to each car.
Why are there three characters to represent a pair?
Do you mean something like this:
car with toilet: [+-]
car without toilet: [--]
my pair: [+-][--]
your pair: [-+][--]
?
> This is then the "extra few feet" that he talks of.
Using my notation (sorry to flip it):
[-+][--][-+][--]
That's four cars. If someone is sitting at the right end of car #2, they have an arrow pointing them to car #1 for the toilet. If that toilet is broken, then they must walk back through car #2 all the way to the end of car #3.
But I may be misunderstanding your initial notation.
Sorry about the error earlier: "...-+-+-" was a typo that I couldn't edit anymore.
1) basic (great for kids, math novices, whatever): https://www.amazon.com/gp/product/0470684534/ref=dbs_a_def_r... (ignore the two star review, this book would get 5 stars from me)
2) advanced (free, complete with videos): http://www.cs.toronto.edu/~hehner/aPToP/
3) advanced: https://www.amazon.com/gp/product/0470848820/ref=dbs_a_def_r...
4) advanced, theoretical, from the man himself: https://www.springer.com/gp/book/9781461279242
https://www.amazon.co.uk/Algorithmic-Problem-Solving-Roland-...
A Discipline of Programming
https://www.amazon.com/Discipline-Programming-Edsger-W-Dijks...
For more practical fun, consider Frama-C, SPARK, and Dafny.
Sounds like software engineering to me!
That, plus a manager inventing and enforcing specific requirements for dubious reasons, causing trouble in the company, and - as 'jancsika points out in their comment - quite likely introducing many new problems into the product.
And the one guy who would have thought of this, they passed on three months before because he wanted 10% more in salary.
/cynicism
Rather a 'true mathematician' (who by definition ignores all practical considerations) would find it unsatisfactory because the problem of finding a way of allowing toilet-less carriages is solved by not allowing toilet-less carriages.
Frankly I think they should have just put the toilet in the middle of the toilet-carrying carriages, but maybe I'm weird.
Of course, outsourcing, interdepartmental or interpersonal politics can create commercial misincentives to remove such time and money saving features...
In that respect programming is often as much an art as it is a practice.
A lot of times when we try to build for speed, the real bottlenecks are no where we think they'd logically be.
Go further.
"Mountaineering is often called Alpinism, especially in European languages"
Haskell is not that hard to get into: there are hard parts but they are totally optional and avoidable.
Also for newcomer who want to get in fp but find Haskell intimidating, you can try Elm, it's tailored to cater to beginners.
I say yes, for a two reasons. 1) Enforced purity means you can't just fall back to your old imperative style as coding and use it as a crutch, and 2) it's the "most different" functional language, it will expose you to more than just functional programming and thus teach you more.
Learning Haskell will teach you: pure functional programming, algebraic datatypes, laziness, and ML-style types. All of which are worthwhile imo.
ML-style typing and algebraic datatypes you could also learn in F#/Ocaml/SML, but pure FP and laziness are two things that are very much worth learning and only apply to a handful of languages. And of that handful Haskell is really the only one with an ecosystem and community that makes it practical to write actual projects in.
If the non-toilet cars were made mutable, specifically if they were made so the arrows could be reversed, then the shunting yard could compose the cars without regard for the orientation of the non-toilet cars, and someone later could go through and set the arrow directions. I'd guess there is some sort of preload inspection done by the crew, which might be a good place to handle setting the arrows.
I see the point. In fact I'd go so far as to call myself "delighted". But I thought I was a true mathematician.
'Scuse me while I go have a little existential crisis.
That algorithms can be simplified by slightly lifting the constraints?
I think it was Robert Tarjan that wrote a book on that topic, but I can't find it.
- Car 1 and 10 are engines, and include some second class seats. - Cars 2 and 3 are first class. - Car 4 is the bar-restaurant. - Car 5 is first class. - Cars 6, 7, 8 and 9 are second class.
All the infrastructure is designed to treat the train as a single unit, during all operations at the shunting yard, in repair workshops, and son on.
And the position of toilets (including special toilets for nappy changes) is fixed.
Rolling stock needs maintenance, and if you keep units permanently paired you can easily run out of units.
In fact there is no easy solution given realistic business constraints. You can either put toilets in every car, which has a cost because it reduces available seating. In the best case you’ll lose money because of the lost seats. In the worst case overcrowding will make the toilets ineffective.
Or you can buy enough spare units to allow for maintenance, which has a larger up front cost, and continuing costs in terms of stabling, and possible issues with shunting yard size.
Working out the most efficient answer given real trains, real passenger loads, likely future passenger loads, and shunting yard constraints, is not a trivial problem.
Unlike Dijkstra, some of the managers in his audiences will have understood this. It’s no wonder they found his glib hand-waving annoying.
The actual lesson of the parable is the opposite of the one Dijkstra is making: the real world is hard, and if you think a solution fits neatly into a trivial software construct, you’re almost certainly wrong.
($ * toilet each car) < shunting{($ * action * yard) + ($ * training * employee)} + ($ * accident cleanup) + ($ * customer bad will)
What "software crisis"? Since its inception in the 50s or so, software has only gone from strength to strength.
Projects running over-time
Software was very inefficient
Software was of low quality
Software often did not meet requirements
Projects were unmanageable and code difficult to maintain
Software was never delivered
Yeah, that one.
1) we don't get increasingly bigger and more powerful systems
2) we're behind some previously existing "no crisis" state
Both (1) and (2) are factually wrong.
Projects running over-budge, over-time, often not meet requirements etc, are not a crisis in the actual meaning of the world.
It's just a normal state of affairs.
And despite that we have got from the laughingly primitive software in the 50s and 60s, to the software "eating the world" today, and have systems with 10 to 100 or 1000 more lines of code, and way more functionality -- even in our pockets.
If only "crisis" looked that way in other domains too.
It's not a crisis, it's just unrealistic expectations.
Even if we could do 100x better in the _future_, it wouldn't justify the term crisis for the state we're in, and have been for decades.
You are factually wrong because you know only the status quo that emerged from that crisis.
> Projects running over-budge, over-time, often not meet requirements etc, are not a crisis in the actual meaning of the world.
> It's just a normal state of affairs.
To you it is.
To the people in the 1960s, it wasn't.
Because they had previously experienced a state where the hardware imposed such drastical limits on the possible size and complexity of software that each programmer working on a project could intimately know and understand every piece of code in it and the requirements that influenced it.
The change from that to one where programmers understand only part of a project is absolutely fundamental and completely changes the way you have to work to achieve your goals. Now your project will fail if you cannot manage and divide-and-conquer its complexity in some way.
https://chrisdone.com/posts/dijkstra-haskell-java
https://www.cs.utexas.edu/users/EWD/OtherDocs/To%20the%20Bud...
Hint: Of your graduates, probably 95% will work as software engineers, and only 5% will be computer scientists. But CS departments think they're computer science departments, even though they mostly are located in the college of engineering. (I accidentally typed "enginerring", which I thought was amusing...)
> But CS departments think they're computer science departments, even though they mostly are located in the college of engineering.
I used to think this is true in the form you presented, but now I feel it's really a more relaxed form that's true - CS departments in universities think they're still in universities, not in glorified vocational schools. They try to teach you more than the immediate needs of your likely job, so that you understand the context of what you're working with, and are exposed to more powerful ways of thinking.
(I mean, 99% of the time, your typical JavaScript-slinger doesn't need to know what an "algorithm" is and what can be solved with one. These days, a popular language, StackOverflow and open-source libraries are enough to do acceptable levels of work. However, some extra theoretical knowledge will help tackle more complicated problems, solve them better, and will enable one to do something more challenging if they want to leave the web/CRUDsphere.)
Related: we now have "vocational schools" for programming too. They're called "bootcamps", for some reason.
Tangential: there's a feedback loop between workers, universities and employees in every industry. Progress of the "industry standard" must come from somewhere. If all the new people are being exposed to is Java(Script), the industry will forever keep being stuck on Java(Script). So I feel it's good that at least some people in some universities try to teach above the level required by the industry.
Bootcamps are a joke. Germany has had proper vocational schools for programmers for decades. After high school, you can spend three years to become a Fachinformatiker (it's difficult to translate, but basically means "applied computer specialist"). There are two subflavors, Anwendungsentwicklung (application developer) and Systemintegration (systems integrator, this curriculum combines sysadmin and development tasks).
All that is entirely separate from CS courses at university, which is an alternate path that one can take (and one that has a higher entry barrier since you need to have at least 8 years in secondary education, i.e. until 12th or 13th grade). In the vocational training, you alternate between weeks at school and weeks at your employer where you work on actual projects under supervision of a qualified mentor.
Then there's "vocational" or "applied science" colleges you can enrol in after either vocational or academic secondary school. They offer four-year bachelor-level degree programs in various fields from healthcare to engineering. The education attempts to mix theory and practice (with varying success).
Finally there's the "real" universities, offering primarily five-to-seven-year BSc+MSc programs (before the Bologna Process you used to go straight to master's; these days the steps are somewhat more discrete), and of course PhD programs for those wishing to pursue an even higher level of education.
I would actually take that even one step further - they specifically teach you the things that you're probably not going to encounter in your likely job. I've lost count of how many people I see complain that they never encountered SQL, version control or build management while in school and my response is - that's a good thing! You're going to learn all you need to know about those things when you need them, and they're veryamenable to learning on the job, a little bit at a time. Calculus, statistics, push-down automata, context-free grammars, and all the other "esoteric" stuff you encounter in a CS degree are not.
Either one. But certainly not "Java Programming".
Good thing, too -- I doubt many of the UT Austin students Dijkstra was teaching back in the day ended their careers still pounding out punch cards...
So, does a software engineer need to know some computer science? Absolutely, but they need to know more than that. They need to know how to efficiently produce working software at scale.
And, to return to my previous post, starting with Haskell could still get you to a software engineering education, as opposed to a computer science education. But it feels to me like the initial direction is aiming at a CS education, not at a software engineering education.
While later on, he does gripe about language quality, I think this is the most salient point of that letter. It touches upon IMO one of the most misunderstood things about Computer Science- it's a science curriculum, not a vocational school. The best (only?) way to build practical skills is doing practical things and learning through experience. Computer Science is more about rigorous reasoning about programs and their mathematical properties.
While learning about practical things like building web apps is fine and well, universities are not well equipped for this sort of vocational curriculum. They are primarily institutions optimized for performing scientific research.
I griped about this to my CS/SE professors until my senior year of college, when I finally understood why they were teaching us all these weird languages and styles instead of the C/C++ that I assumed everybody used at the time: Programming languages come and go - hell, entire platforms come and go - but the underlying concepts (and the ability to teach oneself) are forever. I haven't written a single line of C/C++ professionally, but thank goodness I have the mental tools necessary to pick up all the different programming languages, libraries, protocols, etc. I did end up using.
I don't know how many decades ago you were in school, but imagine all those people who were "rigorous" with learning punch cards in 80s in depth, at the expense of getting a wider education...
Also, while software engineering changes frequently, I'm not convinced that computer science is changing rapidly. It's expanding, but it's not as if fundamental computer science concepts are being rendered obsolete.
It definitely makes more sense if you look at the idea of the "sheepskin effect" where the degree is not a signifier of material mastered, but a signifier that you are a good worker. In that case, what you learn is generally far less important than whether you work well on a team. And a high GPA means you are orderly, methodical and conscientious.