11 ms·
Programming Modern Systems Like It Was 1984
- mklencke 12y agoIn some cases, 2x or 4x is worth the risk. Imagine having a warehouse-scale computer where you can use 50,000 CPUs instead of 200,000.
- lostcolony 12y ago'In some cases' is the key bit. In the 80s, it was much closer to 'all cases'. Nowadays, by all means, turn on the optimizing stuff if you need it, but you are adding risk (especially since you are probably using something like C if you're that concerned about performance, and with so many undefined behaviors)...but unlike the 80s, there's a decent chance you may not need it to achieve the performance goals you need.
- fegu 12y agoLearn to trust virtual memory. This is the real reason not to use temp files. Virtual memory handling is mature in all modern operating systems.
- pjmlp 12y agoStarted coding in 1986. So no cryogenic sleep, rather living through the whole thing. Agree with all those points. Actually C was already primitive in 1984 and only mattered for those coding in an UNIX system. Meanwhile, some of us had the chance to Modula-2, Ada and the myriad of Pascal dialects that were available back then. Always with an healthy set of Assembly code, given the quality of generated code, even in C's compilers case, which were everything but fast back then.
- greenyoda 12y ago"Actually C was already primitive in 1984 and only mattered for those coding in an UNIX system." There was lots of code getting written in C on IBM PCs (running DOS) back then. This article in Byte Magazine from 1983 reviewed nine different PC C compilers: https://archive.org/stream/byte-magazine-1983-08/1983_08_BYTE_08-08_The_C_Language#page/n135/mode/2up https://archive.org/stream/byte-magazine-1983-08/1983_08_BYT...
- pjmlp 12y agoC on MS-DOS was an option among a myriad of languages. MS-DOS was written in Assembly. All major compiler vendors had C, Modula-2, Pascal dialects, BASIC dialects, Assemblers to choose from. I only looked at C for the first time in 1993 and was dysmaid what it offered vs the alternatives. C on UNIX was The Official System Programming language.
- cturner 12y agoI'm setting up a DX4 for messaround with Norton books and asm at the moment, so quite interested in this. The general purpose environments I know of from then would have been C, Turbo Pascal, Basic, ASM, and then probably some databasey things like Clipper, Foxpro. What do you feel was stronger for general purpose dev in that era than Turbo C? Even on OS/2 2.0/1, I can't think of a general purpose tool that would have been more effective than Visual C (but I wasn't actively developing myself then).
- pjmlp 12y agoTurbo Pascal, of course.
- cturner 12y agoOK, given, that's pretty cool. Although Pascal/Ada would be nicer if they had shorter tokens.
- pjmlp 12y agoI always favored readability over hieroglyphs. Code is read more times than written. Specially important when you need to act as fireman in foreign code, a common situation in consulting. Check Turbo Pascal 6.0 or 7.0 with Turbo Vision.
- cturner 12y agoHieroglyphs are not necessarily less readable than words. It's good to be able to build mental state, and the more verbose a language is, the more you need to dance between parsing mode and building mental state. Context shifting is expensive. Paging around is particularly exhausting. I spoke to one of the guys working on the K-language OS at a conference last week. He made the case that - once learnt - the grammar for K it is objectively simple to build mental state from compared to alternatives. I'm open to this being true. I didn't know about Turbo Vision - that's great. And cross-platform too. Thanks!
- VLM 12y agoI go back to '81, and the bigger pix missed is the staggering homogeneity and low cost. "What? The compiler is free, not $299.95 mail order? And the same compiler runs on your desktop as on your server? What manner of sorcery is this?" "The worlds best programming editor is free?" "Wait, you mean the same kernel and similar OS is on my phone and my settop box and my desktop and my server?" The lack of "NIH" and pounding square pegs into round holes is spectacular. There is a bit more attention to security now that everything is interconnected. When the default is never to be connected to anything, you only need security slightly better than physical security which usually isn't much. Subjectively, error messages are staggeringly more verbose yet contain less content than ever. I'd like to see an AI system for error messages that provides more useful error messages. AFAIK this has never been implemented. Another subjective annoyance is believe it or not in the 80s we knew all about no silver bullet and all that, and we were dumb enough to think the industry would implement the lessons and workarounds instead of making the same old mistakes over and over. In the 80s, Brooks had published his MMM a decade ago about experiences two decades earlier and sure, software projects in the modern mid 80s sometimes did dumb things right out of the pages of MMM, but surely in the 90s, 00s, 10s, and 20s no one would be that stupid. Another interesting 80s point of view is recent CS research topics like sorting was more or less applicable to line of business programmers. The red black tree data structure was only a decade old. People were researching performance bounds on slightly older stuff like the quicksort right up to the 80s. In the 10's its very unusual for any fundamental CS discoveries from the last 30 years to cross the desk of your average IT drone other than cryptography (which is usually misapplied such that the average IT drone doesn't do crypto correctly anyway), which was not the case at all in the 80s. We may have been working out of couple year old books instead of minutes old web pages, but we were working within a decade of the cutting edge, not redoing stuff from decades ago but now on a webpage instead of CICS.
- Alupis 12y agoSeveral issues with this post: > It's time to be using all of those high-level languages that are so fun and expressive But then soon says: > Something is wrong if most programs don't run instantaneously Well, most higher level languages are getting interpreted, which require some cpu time to startup. Even with something not-so-high-level-but-sorta-high-level like Java or C#, you still have an abstraction level (JVM/CLR) that must first boot, then interpret, then execute. > Highly optimizing compilers aren't worth the risk Today's optimizing compilers are truly works of genius, and can perform optimizations on code un-thinkable by most programers. Even if they were thinkable, the source code required to produce the same machine code without compile-time optimizations would be hairy to say the least, and mostly unmaintainable (unrolling loops, bit-shifts instead of multiplication, etc). Not to mention 2-4x performance improvements is nothing to shake a stick at. > Design applications as small executables that communicate I don't have any particular qualms with this statement in principle, however with some enterprise apps this simply isn't feasible. Sure I may use a great many separate apps, all working together in orchestration (my database, authentication server, some 3rd party libs, etc), however for some apps, a great deal of the codebase will end up being a monolithic piece, and that is just fine so long as it's maintainable and extensible. > Don't write temporary files to disk, ever This depends on what the temporary file is (and how "temporary", temporary really means in context). If I'm writing a program that will generate some XML document then ultimately send that off to some remote server, I might want a local copy kept in the working directory so that in the event something goes wrong, I can look at the file and see what the last produced content was (or wasn't). > Everything is so complex that you need to isolate yourself from as many libraries and APIs as possible This seems to be in the context of writing system-level code. Even in that context, if a library has done something already that will be useful to you, use it. Taken to the extreme, this could imply one should re-write portions of libc into their app to avoid any external API calls in a vein attempt to guard against external dependencies and a potentially changing API surface. In my projects, I typically have a loose rule that if something is relatively maintained and recent, and it helps me get my job done quicker, I'll use it. That is a very loose definition, but typically prevents me from including some lib that hasn't been updated since 2002 just to parse some XML document. > C still doesn't have a module system Any why should it? It's a low-level language usually (but not always) reserved for low-level (ie. system) programming. This is not the typical language of choice to write your pluggable enterprise app in.
- vim-guru 12y ago> C still doesn't have a module system There's package manager-ish: https://github.com/clibs/clib https://github.com/clibs/clib
- pjmlp 12y agoHow does it solve naming clashes?
- informatimago 12y ago1984: MacOS GUI programming in (Lisa)Pascal, Lightspeed Pascal came the following year, and the MPW with Object Pascal a couple of years later. OOP wasn't very common yet, but when you look at the Mac Toolbox, you can see that it is definitely an OO design (eg. Window is a subclass of GrafPort and Dialog is a subclass of Window, see also the various Control and "subclasses"). Therefore I would say that 1984 with the Macintosh starts modern programming age, marked with high level programming languages (the Mac Toolbox was written in Pascal! (only the Mac OS was written in Assembler, and of course Quickdraw was first debugged in Pascal, and then hand-optimized in assembler), and with object oriented programming. Of course, when people started to write Mac applications in C, it was a set-back, but then NeXTSTEP made a big advance with Objective-C and OpenStep (now Cocoa, ie. MacOSX and iOS), which allowed the creation of the web (and therefore Javascript). But really, OpenStep (Cocoa) is just a cleaned up version of the Mac Toolbox (which was itself a dumbed down version of Smalltalk developped in the 70's at the PARC). So I would say that not much new since then. We've heard of some experiment where some program was run on the Amazon cloud to debug programs on a cost of $8/bug (which assumedly is cheaper than a programmer debugging), but we don't have those kind of AI aids integrated in our tool boxes. We've heard of some automatic proof systems (Coq, ACL, etc), but management wouldn't let us invest in their use (perhaps rightly so, they seem to be as much time sinks as programming itself). We ARE still programming like it wask 1984!!! (unfortunately). Well, not exactly, ok. Now compilations are instantaneous instead of taking hours, and just try to write your next program on a 512x342 pixel screen (or just a 80x25 terminal) with no Internet access for the documentation (all the documentation printed in thick bibles on your knees! (Imagine Android documentation printed!)). Ok, there's some progress still: nowadays I use Common Lisp and emacs all the time (for a pale rendition of the 80's Lisp Machines), and people often use Ruby or python, or even Java, which are run with garbage collectors. So this invention from 1959 finally takes ground, helping us concentrate on solving users' problem instead of managing computing resources.
- lmm 12y agoGah. An interesting thing to think about, but you do have to actually think. > Highly optimizing compilers aren't worth the risk. If they were buggy, sure. But, probably through the weight of every single developer using them for absolutely everything, the bugs have been ironed out. > Something is wrong if most programs don't run instantaneously. Why? Do a straight-up cost/benefit analysis. How much extra would you pay for a program that ran twice as fast? If anything I'd expect people pay more for bigger programs that take longer to run, since they feel like they're doing something important. > Design applications as small executables that communicate. The microservices people are sort of doing this. It's a great way to turn all your problems into distributed problems. And what's not set up is any sensible way to send even basic data structures around. "pipes and sockets" send streams of bytes. In 2014, if I want to send an object, a function even - heck, if I want to send an inert struct - from one process to another, I'm basically stuck. The least-bad option is probably to write out the object definition in Thrift IDL, generate a bunch of code and then write a bunch more code to map back and forth with my actual program datatypes. It's hard to express quite how much it sucks, but many people have tried and failed to come up with something better. > Don't write temporary files to disk, ever. If you're building new executables for everything you're either doing something wrong, or you don't care about the space you're wasting. The right way to do these tiny tweaks is in an interactive, workbooky environment like ipython. If you like that style of programming. > Everything is so complex that you need to isolate yourself from as many libraries and APIs as possible. Absolutely backwards. Everything is so complex - and using libraries so easy - that you should use libraries for everything. A good library provides a simpler interface than the things it's built on top of, so you can just call e.g. encrypt(data) rather than doing thousands of lines of bit-twiddling.
- tonyonodi 12y ago> but many people have tried and failed to come up with something better Can you give any examples? I'd be interested.
- lmm 12y agoCORBA. Java RMI. EJB. To a certain extent Erlang (which may yet succeed), or the various Lisp S-expression serializations. (My view is that turing-complete code is the wrong abstraction and we need to draw an explicit distinction between serializable code and non-serializable code, but that would require a programming-language-level solution and a rewrite of approximately everything. Sooner or later I'll get around to writing a language based on this notion)
- brians 12y agoSo that's where Bernstein comes from. This advice has a lot in common with his (& others) advice on how to write safe programs with a small trusted base---and the other elements seem a matter of shared taste.
- bsaunder 12y agoGreat write-up. I like the perspective of a 30 year jump. In retrospect it feels like we are lobsters slowly boiling. When looked at from a distance, these observations become much clearer. > It's time to be using all of those high-level languages that are so fun and expressive I think for most of us, programmer efficiency is more important than program efficiency. IMHO, in these cases, there's much to be gained from the scripting languages. For many programmers though, these seem to push some comfort zones too much. There are obviously some domains were performance is still king and the high-level languages won't cut it. > Highly optimizing compilers aren't worth the risk. For some they sure are. Probably would have been better stated with "not worth the cost" rather than risk. I don't see much risk here, more so cost (in the terms of effort and opportunity cost). I'd rather not worry about the details of bit twiddling on things if my current problem is plenty efficient on the small n's I'm dealing with. Compilation time can be a real cost as well. I have much faster code-test cycles in scripting environments. > Something is wrong if most programs don't run instantaneously. I think many people don't comprehend how true this is. Its truly mind boggling to consider how many instructions a second are run these days. What could your program possibly be doing with all of them in one second? Again, for some folks there are very good answers. For most of us, its loading and initializing layers upon layers of classes. I routinely see some stack traces dozens of lines deep. I'm sure each one is providing some useful abstraction of something, but.. really? We have a Java based application that was written without any external libraries, just straight up Java. It compiles down to a 120KB jar and provides significant real-time functionality with phone systems. Meanwhile some of our Java based web apps provide a 50MB war, but probably use every relevant Java library out there to help. > Design applications as small executables that communicate. Yes! I've gotten a lot of mileage out of this. Many would to well to read Eric Raymond's book: "The Art of Unix Programming". The only thing I'd like a better solution for is a nice mechanism to set-up and configure the deployment of said "small executables that communicate". I'd like programming to be as easy as building chain of commands in a Unix command line. Yet setting up a production environments with chains of commands seems a bit.. ugly. > Don't write temporary files to disk, ever. Once upon a time, those in the know would set-up RAM disks. These days with SSDs, it seems that's effectively what we are doing. Probably a negligible gain to use RAM over SSD. Only slight advantage of RAM over SSD I see is that things get cleaned up on a reboot (does anyone still reboot regularly?). > Everything is so complex that you need to isolate yourself from as many libraries and APIs as possible. I think this is behind the recent backlash against frameworks. Unfortunately, many raw languages still lack some basic utilities that make it just a bit painful to use without any libraries. Seems many people will be migrating towards unobtrusive libraries that add value in the places needed without requiring a cascading set of components and tight coupling with the application being coded. This is a good thing. > C still doesn't have a module system? I've got nothing here. In general, I've been migrating towards a more data driven approach rather than native code. I wish we'd start loading code modules the same way we would load a piece of data from a file or database. At the end of the day it's all the same. Obviously you need to be sure of the sources you are loading code from, but you should be protecting your data the same way. UPDATE: Minor editing for clarity. UPDATE2: And math.
- sehugg 12y agoIn some ways it's still 1984, especially for mobile dev: > Highly optimizing compilers aren't worth the risk. Rewrite slightly to "non-mainstream toolchains aren't worth the risk". Should you write your next game in pure Java, or use JNI/C++, or use Unity, or something more obscure? No matter which you pick, you'll be running to StackOverflow (if you're lucky) to fix the periodic show-stopper. Using the most popular tool gives you the highest likelihood of success without delving into library source code. > Something is wrong if most programs don't run instantaneously. Forget startup time -- Make a 1980s developer deal with iOS code-signing issues and watch them switch their occupation to animal husbandry. > Everything is so complex that you need to isolate yourself Back then documentation was delivered in thick paper volumes which often contained more bits of information than the software being documented. Now we just Google StackOverflow and cross our fingers.
- gbuk2013 12y ago> why isn't it possible to create and execute a script without saving to a file first It is certainly possible in Bash, at least: CODE='echo Hello; echo World' RESULT=$(bash -c "$CODE") echo "$RESULT" Very good article though! :-)
- npsimons 12y agoOther more "obscure" options also come to mind: Emacs Lisp, Smalltalk, etc. Wasn't there also something in Plan 9's GUI like this? The whole saving to a file first thing is just a convention, and one that got me thinking: it's a convention for a reason (reproducibility), and this argument ("why can't I just run it without saving first?"), seems kind of contrary to the whole point of the post. Disks are fast! Saving a file first is ridiculously fast in this day and age. Just bind a keystroke to save and run in one button press. It speaks more to lousy development environments than anything else if you can't make this a one button press operation.
- 101914 12y agoIt used to be that the major limitation in computing was hardware. Look at the creativity that it spawned. We are still living off of ideas three decades old. Now what is the limitation? Is it programmer stupidity? Or maybe there is no limitation? Maybe that is the problem. History shows hardware kept getting faster, but there has been no decrease in the amount of ever larger, slow, unreliable software. Where is all the lean, "instantaneous" software running in RAM, extracting every last bit of computing power, instead of mindlessly consuming it? What exactly is the point of "programmmer productivity" and whatever problems some programmers think that this justifies? Is the point to advance computing? The state of the art? Or is the goal is to peddle their junk to those with very low expectations, not to mention those with zero expectations. (The later were not old enough, or even alive, to see how computing was done in the 80's and hence have nothing with which to compare.) It is unfortunate that giving programmers what they wanted -- faster hardware -- has not resulted in software that is any more creative or powerful, and truly it is less so, than the software of the past. Only hardware has improved. Given the history so far, I would argue that the only proven path to true creativity in computing is through limitation. Perhaps present day computing's limitation is programmer stupidity, or to be more gentle, programmer ignorance. Agree 100% with all points in the blog post, except perhaps the last one. Well done.
- userbinator 12y agoIt used to be that the major limitation in computing was hardware. Look at the creativity that it spawned. This can be summed up in one word: demoscene. In fact I thought the article would be about the demoscene, just from its title. History shows hardware kept getting faster, but there has been no decrease in the amount of ever larger, slow, unreliable software. That's what I think someone who took this 30-year-leap would perceive if they switched from a computer of the 80s to a new system today: "This app is how many bytes!? It's pretty and all, but it can only do this? Why does it take so long to boot up?" Interesting comparison here: http://hallicino.hubpages.com/hub/_86_Mac_Plus_Vs_07_AMD_DualCore_You_Wont_Believe_Who_Wins http://hallicino.hubpages.com/hub/_86_Mac_Plus_Vs_07_AMD_Dua... What exactly is the point of "programmmer productivity" and whatever problems some programmers think that this justifies? I think it's more like a combination of laziness and selfishness: programmers want to be more "productive" by doing the least work possible, and at the same time are uncaring about or underestimate the impact of this on the users of their software. Trends in educating programmers that encourage this sort of attitude certainly don't help... There's also this related item a few days ago: https://news.ycombinator.com/item?id=8679471 https://news.ycombinator.com/item?id=8679471
- npsimons 12y agoI don't have to imagine what a programmer doing this jump would do, I can look to my father, who started out writing programs on punch cards in high school to be sent to the university, and maybe a week later he'd get results back (if his program worked at all). He retired from his day job writing Java a few years back, and is still hacking on websites using Tomcat, etc, and he's never looked back.
- sehugg 12y agoHow it might go: "That web programming thing sounds pretty fun!" (glances across bookshelf) "So if you'll give me a copy of the spec, I can get started."
- Roboprog 12y agoI started working part time while going to school in '85 (off by one year, here). I did use a reasonably high level language, dBASE, rather than C/Pascal (most of the time). Writing a CRUD app in dBASE/xBASE (Clipper, Fox) back then, vs using a low level language, felt like using Ruby on Rails does now (vs "Enterprise" make-work). Of course, in both cases, you sometimes run into performance/capacity issues that make you rethink what you did with the higher level platform :-) So, I guess I disagree that everything was done at or near the assembly language level back then.
- Roboprog 12y agoTemp files are great - you can inspect your output. And, while they might suck on Windows, on Unix, they are pretty much an in-memory data structure anyway.
- xolve 12y ago> Why does this little command line program take two seconds to load and print the version number? > Don't write temporary files to disk, ever. > Why does a minor update to a simple app require re-downloading all 50MB of it? Gets me!
- shoover 12y agoHigh level, instant startup, message passing, isolation from complex APIs (interfaces), and a good module system. Sounds like he's advocating for Go.