1. 5

    I might think the process is just overwrought and not rife with useless steps / conflating things in a non-malevolent way until I got the the 8 written questions “essay exam” part. Then I would probably drop out of the process and just work somewhere else.

    1. 3

      Being able to write and communicate well is such a crucial part of software engineering, especially on a long-lived product maintained by a group of engineers with the inevitable membership churn that happens over many years. Strong writing skills also help with the kind of asynchronous communication that often works best with remote teams who might have members in far flung time zones, and when collaborating with members of open source communities.

      At least, those are things I believe are important. The written questions are not meant to take a long time to answer, though because we don’t ask you to answer them in front of us you can really take as long as you want. For folks that get nervous under exam or interview conditions, hopefully the chance to polish their thoughts in writing at their own pace also affords a chance to demonstrate clarity of thought and breadth of experience in a lower stress setting.

      At the end of the day, it’s true that no process (or job!) will fit everybody. Though the RFD is certainly detailed, it represents a level of transparency with applicants that I’m not sure is that common in our industry. It also helps us in our attempt to give each candidate a consistent treatment.

      1. 1

        Of course writing skill is important. It’s important in nearly every industry, yet no other industry that I have ever heard of assigns essay question homework. Only in the software industry does this “dancing bear” mentality predominate, where most employers are wholly unwilling to look at any existing work product the candidate may have, instead demanding that the candidate produce new work (for free) especially for evaluation. It’s abusive and should be illegal.

        1. 1

          If you take a closer look at the RFD, you’ll see that the written answers we’d like are not dissimilar to regular interview questions, except that we’re asking you to write instead of asking you in person. They’re not some exercise which is suspiciously close to asking for free labour relevant to our shipping product.

          In addition, for the other artefacts we ask for such as a code sample, we’re perfectly happy to accept any code you’ve written already which meets the criteria.

          These interviews are for professional positions with an agreeable salary, where much of the work you do will be extremely collaborative – with other engineers and with customers. I don’t think it’s exploitative to ask for you to write a little about yourself when you’re applying for a job like that.

          1.  

            Again, no other industry requires this hoop-jumping, even for much more senior positions than that of an individual-contributor engineer. I’ve observed my partner go through the interview process a couple times, for positions with dozens of people in the reporting chain and millions of dollars in budget. She is often asked to provide writing samples from work product she’s created at previous jobs, but I don’t recall a single instance where she was asked to do the kind of homework that is routine for even the most junior software job. I have not seen any evidence that the software hiring process yields better results than the process used in every other field.

            Homework excludes people with childcare and other responsibilities, and it also makes it very difficult to interview with more than one or two companies at a time, which puts the candidate at a disadvantage as far as finding the best available offer.

            1.  

              Again, no other industry requires this hoop-jumping, even for much more senior positions than that of an individual-contributor engineer.

              I think that’s a very broad generalisation and though I appreciate you’re relaying your personal experience, I’m not convinced it’s universally true.

              She is often asked to provide writing samples from work product she’s created at previous jobs

              Which, if you’ll look at the RFD, describes most of the artefacts we request. A writing, code, and analysis sample, each of which can absolutely be from previous jobs or from open source work or from a portfolio you already have. We’re willing to look at anything you’re allowed to show us, even if it’s not something you can or wish to post in public.

              Of course, if you have none of these things at all, we do ask you to produce something specifically for your application. We try to make it clear that you shouldn’t spend an undue amount of time on it.

              Homework excludes people with childcare and other responsibilities

              I have a son, and certainly raising him takes a lot of time and energy. One of the reasons I love working for Joyent is that everybody is very understanding of this, and I have no trouble making flexible arrangements to attend important events or to stay home when he’s sick.

              Assuming you have existing samples, the only pre-interview thing we’re asking you to do is answer a few questions about yourself in an e-mail. We’ve tried to keep the list of questions long enough to give us some insight into you and your ability to write, while short enough not to be burdensome – even for those with family and other responsibilities.

              Hiring is complicated, as is finding the right job for you personally. We aim to be a workplace where people feel like they can (and want to!) build a career, hopefully on the time scale of at least years. I’ve been with Joyent for six years, myself. With that in mind, an hour or less spent answering some questions is hopefully not too much to ask, especially if you would like to work with us on the products we build!

              1.  

                I do appreciate that Joyent allows you to provide existing work. My complaint is really about the majority of software hiring managers who are not willing to do that and want you to do their specific coding exercise.

                I think that’s a very broad generalisation and though I appreciate you’re relaying your personal experience, I’m not convinced it’s universally true.

                I’d certainly be interested to hear about examples of other fields which require similar things of job candidates. Offhand, the performing arts are the only examples that come to mind.

    1. 9

      Somewhat darkly, the best part about this (otherwise clearly well-thought-out process) is in a couple years when the employee burns out, is summarily sacked, or leaves because there’s no salary growth or incentive structure or because they know they can’t build a career at their company.

      Software hiring hand-wringing is a meme to distract us from the garbage retention and compensation practices.

      1. 3

        I wonder if “garbage retention & compensation practices” are actually the norm is most industries and for most fields but only cause hiring problems in the few where there are better alternatives to prospective employees.

        1. 1

          I wouldn’t be surprised at all if those issues are the increasingly the norm in other industries–I can only speak to what I know.

          1. 1

            I think they’ve actually been the norm for a while (at least a couple of decades).

        2. 1

          I work with Bryan at Joyent (and have done since 2012!) and though I agree there are a lot of dire patterns in the industry, I like to think that the hiring RFD reflects our attempts to avoid some of the pitfalls we see – and indeed have ourselves experienced in the past. Over the years we’ve certainly had staff come and go, but I’ve definitely enjoyed my time at the company thus far!

        1. 6

          What a nice and inspiratory write-up! I really like this kind of quality content, even though it’s a topic only a small small minority would even want to reason about in this world.

          I really see the computer as an extension to my mind, and I must say that I’ve managed to create an environment for myself which suits this purpose. Using other computers with common operating systems or window managers, or even tablets or smartphones, really makes you realize how disconnected people are from their technology despite most of them using it every day, some even almost every minute.

          I would argue that this is a stress factor in itself, where people feel the need to check their phone regularly and literally experiencing stress when they don’t. I’m looking forward to what the future will bring; I’m almost sure the next big step after the smartphone will be direct brain-computer-interfaces (Let’s hope it’s open source, folks! I wouldn’t want to catch a virus that way).

          1. 7

            I’m really very happy not attaching the computer to my brain at all. I appreciate that it’s a physical artefact that I have some hope of being able to turn off, push out a window, etc – that Amazon isn’t putting advertising material into my subconscious in a way I can’t observe.

            1. 5

              I’m really very happy not attaching the computer to my brain at all. I appreciate that it’s a physical artefact that I have some hope of being able to turn off, push out a window, etc – that Amazon isn’t putting advertising material into my subconscious in a way I can’t observe.

              The real problem here is that we still cannot trust computers to obey us and only us. There’s also a secondary (or perhaps even, primary) master, which is whomever created the software. Tying back to the article, I doubt Engelbart would approve of a “mind augmentation” that bugged its user with advertisements.

              In my mind, free software is the only solution out of this mess, but society seems to be pretty clearly and universally uncaring about any of this at all. Sure, there’s the occasional griping about ads, but by and large people accept it and seek out the free as in beer ad-driven software.

              1. 2

                Yes, I totally agree with you! This software matter is sadly not the only topic where this applies. We can also stretch this to politics, economics, consumerism and so forth. When people don’t reflect on topics and ignore them, they end up falling into traps, maybe even being fine for years beforehand.

                There was a time 1-2 years ago where a big PR-agenda by the advertising agency “convinced” lots of people to argue for ads that they were the lifeblood of many papers and so forth, completely ignoring the issue at hand regarding tracking and other things. I, and many others, are open for microtransactions for these kinds of services. The Ad-based revenue bubble will probably burst in a few years (when everyone sees that the king wears no clothes), and Alphabet knows that (which is why they are so aggressively expanding into so many different fields).

                Back to topic: We are just doomed to wait for a big catalytic event to happen.

              2. 1

                It’s important to note that when Sutherland, Licklider, and Engelbart talked about man-machine symbiosis, they didn’t mean physical connection (as in brain-computer interfaces). (The idea had already been seriously floated – the paper that coined the term ‘cyborg’ was published around the same time as the MOAD, & physical human-machine hybrids had been around for longer – notably in E.V. Odle’s Clockwork Man in the teens.)

                Instead, they were talking about what Deluze and Guatari referred to as a ‘dyad’ and what Burroughs called ‘the third mind’: the tendency for facility of communication to increase in certain kinds of close collaboration to the point where two people become effectively a single functioning organism (despite being joined by normal communications mechanisms) more effective than either alone. I think most of us on lobste.rs have felt this way at a REPL on occasion.

                1. 1

                  These analogies are not without challenges, though. For starters, a REPL doesn’t do much of anything by itself – it’s just a tool that I can use, not substantially different from a pocket calculator. I think some of the historic research is interesting, and some of it appears too forced an attempt to project thinking from fields like psychology onto the computer – especially from a time when computers were just not that powerful, so a lot of it is in a fairly future-imaginative tense.

                  1. 1

                    It doesn’t take a lot of computing power to create a usable, responsive system that people can develop a connection & personal cant with. I mention the REPL because REPLs are lightweight enough to have been this responsive in the early 70s (if not earlier).

                    Actual symbiosis does not necessarily involve a direct biological connection, so I would not call it a mere metaphor to consider a REPL symbiotic with its user (or a BCI inherently more symbiotic than a REPL). For instance, the clownfish / anemone symbiosis doesn’t involve bits of anemone in the clownfish & vice versa.

                    We’ve got a lot of wiggle room to make interfaces better before resorting to wet wiring. (And, current wet wiring tech requires substantial training, for reasons that are unlikely to go away without substantial advances in mapping the peripheral nervous system. Basically, people are too varied in terms of what parts of the brain correspond to even straightforward motor stuff, and it’s a lot easier to have the person remap their brain regions to match the prosthesis than to have the prosthesis identify the current mapping, even though having the person do that remapping means months or years of intense physical therapy.)

                    1. 1

                      Sure, my Commodore 64 could have a conversational or at least responsive textual interface. It even had a few GUI environments, though those consumed so much of the available resources that they were unable to do much else beyond very basic word processing or bitmapped painting.

                      But the C64 couldn’t index large quantities of online information in a way that’s relatively easy to search. Just like the MOAD system was fully unable to perform the video conferencing part of the demo, a feat not realised until decades later.

                      Lots of people wrote toy programs for the C64, and lots of people have imagined what the future might hold. Others still have actually built the tools we – and millions of others – use every day. The tools could always improve, and often they do, but I think it’s unfortunate to cling to specific unrealised research ideas to the extent that you can’t see the wonder right in front of our eyes.

                      I remember in the nineties I watched space shuttle launches in a postage stamp sized window via a dialup modem, probably 5fps at best. It was objectively terrible by today’s standards but it was, at the time, marvellous. Now, in 2018, I can hold my phone in the air when a piece of music is playing and it can find me the recording. I can video conference with my parents on the other side of the world as if they were right across the room. I can send real time messages, attach pictures sound and documents, to anywhere in the world instantly. I can read that conversation history on multiple devices at once, and everything is backed up automatically. I can watch thousands of movies on my TV without having to go to Blockbuster.

                      In short, though it’s true that my phone isn’t a Smalltalk or a LISP machine, I’m not sure that really matters. There are opportunities for composing interfaces certainly, and you find pieces of that in tools that millions use like Excel, or some of the newer Notebook systems. But the fact that specific research ideas haven’t taken off isn’t necessarily a tragedy, or even that surprising. There are so many forces at work in software, beyond a particular aesthetic preference or set of expectations of functionality, that not everyone will be completely happy with everything.

                      If these truly are things we cannot do without, then one expects they might almost sell themselves – and I wish you well in building that future!

                      1. 1

                        I think it’s unfortunate to cling to specific unrealised research ideas to the extent that you can’t see the wonder right in front of our eyes.

                        People keep trying to tell me that I lack sufficient appreciation for the status quo. I’m very suspicious of any system that gets defended from sensible criticism by telling people to be grateful that they have anything at all.

                        Just like the MOAD system was fully unable to perform the video conferencing part of the demo, a feat not realised until decades later.

                        Should note that this isn’t so accurate – Bell already had a commercial videophone service before the MOAD. (I could look up the exact year, by my memory is that it was launched in the mid-1960s, debuted at a world’s fair, & became available a couple years later. It drove some of the early digitalization of switching equipment. Ultimately, the service was cancelled, because – priced to pay for the upgrade of the whole Bell network to digital exchanges – it was too expensive, and people who did pay for it quickly realized that they didn’t actually want video conferences anyway.)

                        If these truly are things we cannot do without

                        We clearly can do without them, because we have been. You can do without housing, too, but few people do it by choice. I personally don’t want to do without powerful tools until someone deigns to sell them to me (which is why I write them).

                        , then one expects they might almost sell themselves

                        I don’t think stuff like this will ever be profitable. That’s a good reason to make it: to make sure it exists, because no corporation will.

                2. 1

                  Believe me, me too! I actually didn’t really say it, but I would think 6 times before even considering such a brain-computer-interface. It would have to fulfill high standards, e.g. being open source and based on a mature codebase. And even then, the question is how well the scientific “model” is. You wouldn’t want to fry your hearing nerve just because there’s a misconception of perception of something.

              1. 15

                Polemics like this always seem to leave out the part where, though things might not be exactly to the author’s preference, they are nonetheless actually pretty impressive. We’ve built a lot of systems that are truly amazing in the positive impact they have, just as we have built tools that are used for distasteful purposes. In addition, a lot of the idealism vanishes out the window once you actually try to build a real thing which works for thousands or millions of people, rather than a lab experiment or research project.

                I’m sure we’re not at a global maximum of whatever it is we should be optimising, but the idea that everything is terrible and we’re all just lying to ourselves is such a tired one.

                1. 5

                  Well, the article wasn’t about that (it’s about how history is misrepresented to present a world dominated by technological determinism), but I’m always up for discussing the subject.

                  ‘Polemics like this’ are generally not making the argument that everything is terrible, but that relatively straightforward & obvious improvements are not being made (or once made are being ignored). In the case of the work of folks mentioned in this article, commercial products today are strictly worse along the axes these people care about than commercially-available systems in the late 1970s and early 1980s. In the case of both Alan Kay & Ted Nelson, they themselves released open source software that gets closer to their goals.

                  I don’t think it’s unfair to get mad about a lack of progress that can’t be excused by technical difficulties. It’s absurd that popularly available software doesn’t support useful features common forty years ago. However, the tech industry is uniquely willing to reject labor-saving technology in favor of familiar techniques – it does so to a degree far greater than other industries – so while absurd, it’s not surprising: software engineering is an industry of amateurs, and one largely ignorant of its own history.

                  1. 6

                    I think you’re deliberately understating the current state of computing, programming, and networking.

                    It’s absurd that popularly available software doesn’t support useful features common forty years ago.

                    Like clipboards! And spellcheckers! And pivot tables! And multimedia embedding! And filesharing! And full-text searching! And emailing!

                    Except…wait a second, those weren’t really common useful features at all. Wait a second….

                    However, the tech industry is uniquely willing to reject labor-saving technology in favor of familiar techniques – it does so to a degree far greater than other industries – so while absurd, it’s not surprising

                    What do you mean by this? Have you compared it to industries like, say, paper printing? Healthcare? Cooking?

                    Would you consider the constant churn of, say, web frameworks promising ever-easier development to be favoring familiar techniques? What about the explosion functional and ML languages which will magically save us from the well-documented pitfalls and solutions of procedural and OOP languages, for the mere cost of complete retraining of our developers and reinvention of the entire software stack?

                    Please put some more effort into these bromides–facile dismissals of tech without digging into the real problems and factors at play is at least as shortsighted as anything you complain of in your article.

                    one largely ignorant of its own history.

                    Here I would have to agree with you. :)

                    1. 3

                      Like clipboards!

                      That’s actually a decent example. Companies operating under the philosophy to interoperate with maximum number of techs for benefits enkiv2 is going for would want everyone to have clipboards that could interoperate with each other, too. Instead we get walled garden implementations. Additionally, Microsoft patented it instead of leaving it open in case they want to use it offensively to block its adoption and/or monetize it.

                      On a technical angle, clipboards were much weaker than data-sharing and usage models that came before them. Some of the older systems could’ve easily been modified to do that with more uses than clipboards currently offer. There’s entire product lines on Windows and Linux dedicated to letting people manipulate their data in specific ways that might have just been a tie-in (like clipboards) on top of a fundamental mechanism using the extensible designs enkiv2’s and his sources prefer. Instead, we get patented, weak one-off’s like clipboards added on many years after. Other things like search and hyperlinks came even later with Microsoft’s implementation in Windows once again trying to use IE to lock everyone in vs real vision of WWW.

                      I could probably write something similar about filesharing adoption in mainstream OS’s vs distributed OS’s. languages, and filesystems from decades earlier.

                      1. 3

                        The clipboard mechanism in X Windows allows for more than just text. I just highlighted some text in Firefox on Linux. When I query the selection [1], I see I have the following targets:

                        • Timestamp
                        • targets (this returns the very list I’m presenting)
                        • text/html
                        • text/_moz_htmlcontext
                        • text/_moz_htmlinfo
                        • UTF8_STRING
                        • COMPOUND_TEXT
                        • TEXT
                        • STRING
                        • text/x-moz-url-priv

                        If I select text/html I get the actual HTML code I selected in the web page. When I select text/x-moz-url-priv I get the URL of the page that I selected the text on. TEXT just returns the text (and the alt text from the image that’s part of the selection). I use that feature (if I”m on Linux) when blogging—this allows me to cut a selection of a webpage to paste into an entry which grabs the URL along with the HTML.

                        Of course, it helps to know it’s available.

                        [1] When first playing around with this in X Windows, I wrote a tool that allowed me to query the X selection from the command line.

                        1. 1

                          Didnt know about those tricks. Thanks for the tip.

                          1. 2

                            There’s a reason I used it as an example. ;)

                            Ditto spellcheckers–they used to be a real bear to implement and ship as a feature, if they got shipped at all, because of the memory and speed constraints in implementing them.

                          2. 1

                            That’s table stakes for clipboard implementations. Microsoft Windows also allows multiple objects to be attached to the clipboard, with the expectation that they provide different representations of the same data. Android’s clipboard is built on the same Content Provider API that all of their application data interoperability uses. The WHATWG clipboard API allows the data to be keyed by mimetype, using the same formats as the drag-and-drop API. I assume macOS provides similar functionality, but I don’t know where to look for info on that.

                            It’s not used for anything that fancy because (a) the clipboard can only ever hold one piece of data at a time (b) you have to get the applications to support the same data format, just like if you’d used a file

                        2. 2

                          I think you’re deliberately understating the current state of computing, programming, and networking.

                          Never do I say that the tech we have is worthless. But, at every opportunity, I like to bring up the fact that with not much effort we could do substantially better.

                          those weren’t really common useful features at all.

                          It shouldn’t take fifty years for a useful feature to migrate from working well across a wide variety of experimental systems to working poorly in a handful of personal systems – particularly since we have a lot of developers, and every system owned by a developer is a de-facto experimental system.

                          There weren’t impossible scaling problems with these technologies. We just didn’t put the effort in.

                          Have you compared it to industries like, say, paper printing? Healthcare? Cooking?

                          I was thinking in particular of fields of engineering. CAD got adopted in mechanical engineering basically as soon as it was available.

                          But, sure: in the domain of cooking, sous vide systems got adopted in industrial contexts shortly after they became available, and are now becoming increasingly common among home cooks. Molecular gastronomy is a thing.

                          Healthcare is a bit of a special case. All sorts of problems, at least in the US, and since the stakes are substantially higher for failures, some conservativism is justified.

                          Printing as an industry has a tendency to adopt new technology quickly when it’ll increase yield or lower costs – even when it’s dangerous (as with the linotype). There are some seriously impressive large-scale color laser printers around. (And, there was a nice article going around about a year ago about the basic research being done on the dynamics of paper in order to design higher-speed non-jamming printers.) My familiarity with printing is limited, but I’m not surprised that Xerox ran PARC, because printing tech has been cutting edge since the invention of xerography.

                          Would you consider the constant churn of, say, web frameworks promising ever-easier development to be favoring familiar techniques?

                          Promising but never actually delivering hardly counts.

                          What about the explosion functional and ML languages which will magically save us from the well-documented pitfalls and solutions of procedural and OOP languages, for the mere cost of complete retraining of our developers and reinvention of the entire software stack?

                          Functional programming is 70s tech, and the delay in adoption is exactly what I’m complaining about. We could have all been doing it thirty years ago.

                          (The other big 70s tech we could benefit a great deal from as developers but aren’t is planners. We don’t write prolog, we don’t use constraint-based code construction, and we don’t use provers. SQL is the rare exception where we rely upon a planner-based system at all in production code. Instead, we go the opposite route: write java, where engineer time and engineer effort is maximized because everything is explicit.)

                          1. 1

                            We could have all been doing it thirty years ago.

                            I’m pretty sure the computers of the time weren’t really up to the task. How much RAM does GHC take up?

                            Can you write a useful functional language and interpreter that works in the hardware available at the time, and will it be faster/smaller than the equivalent, say, C compiler?

                            1. 2

                              The variety of lisps and schemes available for early-90s commodity hardware indicates that a functional style has been viable on that hardware for thirty years. We can be very conservative and call it twenty-five too: if Perl scripts running CGI are viable, so is all of the necessary features of functional programming (provided the developer of the language has been sensible & implemented the usual optimizations). Haskell is probably not the best representative of functional programming as a whole in this context: it really is heavy, in ways that other functional languages are not, and has a lot of theoretical baggage that is at best functional-adjacent. Folks can and did (but mostly didn’t) run lisp on PCs in ’95.

                              By the late 90s, we are already mostly not competing with C. We can compare performance to perl, python, and java.

                              The question is not “why didn’t people use haskell on their sinclair spectrums”. The question is “why didn’t developers start taking advantage of the stuff their peers on beefier machines had been using for decades as soon as it became viable on cheap hardware?”

                              1. 3

                                You’re playing fast and loose with your dates. You said 30 years ago, which would’ve been 1988–before the Intel 486. Even so, let’s set that aside.

                                The variety of lisps and schemes available for early-90s commodity hardware indicates that a functional style has been viable on that hardware for thirty years.

                                The most you could say was that the languages were supported–actual application development relies on having code that can run well on the hardware that existed. I think you’re taking a shortcut in your reasoning that history just doesn’t bear out.

                                if Perl scripts running CGI are viable, so is all of the necessary features of functional programming (provided the developer of the language has been sensible & implemented the usual optimizations).

                                I’m not sure what you mean by viable here. The Web in the 90s kinda sucked. You’re also overlooking that actual requirements for both desktops and servers at the time for web stuff were pretty low–bandwidth was small, clients were slow, and content was comparatively tiny in size when compared with what we use today (or even ten years ago).

                                The second bit about “assuming the developer of the language” is handwaving that doesn’t even hold up to today’s languages–people make really dumb language implementation decisions all the time. Ruby will never be fast or small in memory for most cases. Javascript is taking a long time to get TCO squared away properly. Erlang is crippled for numeric computation compared to the hardware it runs on.

                                By the late 90s, we are already mostly not competing with C. We can compare performance to perl, python, and java.

                                I don’t believe that to be the case, especially in the dominant desktop environment of the time, Windows. Desktop software was at the time very much written in C/C++. with Visual Basic and Delphi probably near leaders.

                                ~

                                I think the problem is that you’re basing your critiques on a present based on a past that didn’t happen.

                                1. 4

                                  You’re also overlooking that actual requirements for both desktops and servers at the time for web stuff were pretty low–bandwidth was small, clients were slow, and content was comparatively tiny in size when compared with what we use today (or even ten years ago).

                                  That’s not a bad thing. :)

                                  1. 3

                                    actual application development relies on having code that can run well on the hardware that existed

                                    Professional (i.e., mass-production) development is more concerned with performance than hobby, research, and semi-professional development – all of which is primarily concerned with ease of exploration.

                                    Sure, big computing is important and useful. I’m focusing on small computing contexts (like home computers, non-technical users, and technical users working outside of a business environment, and technical users working on prototypes rather than production software) because small computing gets no love (while big computing has big money behind it). Big computing doesn’t need me to protect it, but small computing does, because small computing is almost dead.

                                    So, I think your criticisms here are based on an incorrect understanding of where I’m coming from.

                                    Professional development is totally out of scope for this – of course professionals should be held to high standards (substantially higher than they are now), and of course the initial learning curve of tooling doesn’t matter as much to professionals, and of course performance matters a lot more when you multiply every inefficiency by number of units shipped. I don’t need to say much of anything about professional computing, because there are people smarter than me whose full time job is to have opinions about how to make your software engineering more reliable & efficient.

                                    Powerful dynamic languages (and other features like functional programming & planners) have been viable on commodity hardware for experimental & prototype purposes for a long time, and continue to become progressively more viable. (At some point, these dynamic languages got fast enough that they started being used in production & user-facing services, which in many cases was a bad idea.)

                                    For 30 years, fairly unambiguously, fewer people have been using these facilities than is justified by their viability.

                                    Folks have been prototyping in their target languages (and thus making awkward end products shaped more by what is easy in their target language than what the user needs), or sticking to a single language for all development (and thus being unable to imagine solutions that are easy or even idiomatic in a language they don’t know).

                                    For a concrete example, consider the differences between Wolfenstein 3d and Doom. Then, consider that just prior to writing Doom, id switched to developing on NeXT machines & started writing internal tooling in objective c. Even though Doom itself ran on DOS & could be built on DOS, the access to better tooling in early stages of development made a substantially more innovative engine easier to imagine. It’s a cut and dried example of impact of tools on the exploration side of the explore/exploit divide, wherein for technical reasons the same tools are not used on the production (exploit) side.

                                    people make really dumb language implementation decisions all the time

                                    Sure. And, we consider them dumb, and criticize them for it. But, while today’s hardware will run clojure, a c64 lisp that doesn’t have tail recursion optimization will have a very low upper limit on complexity. The difference between ‘viable for experimentation’, ‘viable for production’, and ‘cannot run a hello world program’ is huge, and the weaker the machine the bigger those differences are (and the smaller a mistake needs to be to force something into a lower category of usability).

                                    The lower the power of the target machine, the higher the amount of sensible planning necessary to make something complex work at all. So, we can expect early 90s lisp implementations for early 90s commodity hardware to have avoided all seriously dumb mistakes (even ones that we today would not notice) & performed all the usual optimization tricks, so as to be capable of running their own bootstrap.

                                    There are things that can barely run their own bootstrap, and we generally know what they are. I don’t really care about them. There are other things that were functional enough to develop in. Why were they not as widely used?

                                    Desktop software was at the time very much written in C/C++. with Visual Basic and Delphi probably near leaders.

                                    Sure, but software was being written in scripting languages, and so writing your software in a scripting language was not a guarantee that it would be the slowest thing on the box (or even unusably slow). That makes it viable for writing things in that will never be sold – which is what I’m concerned with.

                                    I think the problem is that you’re basing your critiques on a present based on a past that didn’t happen.

                                    I think I just have a different sense of appropriate engineer time to cpu time tradeoffs, and don’t consider the mass production aspect of software to be as important.

                                    1. 1

                                      I certainly ran Emacs Lisp on a 386 SX-16, and it ran fine. I didn’t happen to run Common Lisp on it, mainly because I wasn’t into it, or maybe there were only commercial implementations of it back then. But I would be pretty surprised if reasonable applications in CL weren’t viable on a 386 or 68020 in 1990. Above-average amounts of RAM were helpful (4 or 8 MB instead of 1 or 2).

                        1. 12

                          It’s really no more clear. I much prefer putting the constants to the right, as a general rule.

                          I expected it to be about using a single comparator in sort algorithms, ect.

                          1. 14

                            Yeah, I think this is definitely in the realm of one person’s aesthetic sense. I think that, e.g.,

                            if (x < MIN_VALUE || x > MAX_VALUE) {
                                    return (EINVAL);
                            }
                            

                            … makes a lot of sense, especially when you consider a verbal version: less than the minimum or greater than the maximum allowed value.

                            1. 2

                              It does. Except that you should get rid of those parens around EINVAL. There is no need for those. :-)

                              1. 2

                                While that’s technically true in this example, I’ve read and written so much SunOS cstyle code that it looks weird without the parens at this stage.

                          1. 5

                            Using the assignment operator = will instead override CC and LDD values from the environment; it means that we choose the default compiler and it cannot be changed without editing the Makefile.

                            This is true, but really, if you want to ensure variables are set in a Makefile, pass them as overrides (make ... CC=blah ...), don’t set them in the environment. The environment is a notoriously fragile and confusing way to specify all these things. (They certainly don’t work with the GCC and binutils stuff I work with on a regular basis!)

                            My advice for Makefile is be explicit. It’s tedious and boring, but so much easier to debug.

                            1. 4

                              The reason that setting things in the environment is fragile is because people follow advice to ignore the environment. It’s very useful for cross compilation to simply set the appropriate environment and go.

                              1. 1

                                There’s also no easy way to pass arguments and options to a makefile except through environmental variables. You can also play games with the target, but there’s only so much you can do with that.

                                1. 2

                                  I don’t believe that’s true. You can also pass macro definitions as arguments to make; e.g., make install PREFIX=/opt/tools

                                  1. 1

                                    Yes, overrides passed on the command line can be arbitrary expansions.

                                    % cat Makefile
                                    STUFF = 1 2 3 4
                                    
                                    all:
                                            @echo $(FOO)
                                    % make 'FOO=$(firstword $(STUFF))'
                                    1
                                    
                                    1. 0

                                      Yeah, but environmental variables are turned into make variables in the same way as variables after the make command. The only difference is that they also get placed in the environment of subcommands.

                                      1. 2

                                        I’m reasonably sure that is not true either. From my reading of the manual, an explicit assignment of a macro within the Makefile will override a value obtained from the environment unless you pass the -e flag to make. The manual suggests the use of this flag is not recommended. In contrast, a macro assignment passed on the command line as an argument will override a regular assignment within the Makefile.

                                        Additionally, some macros receive special handling; e.g., $(SHELL), which it seems is never read from the environment as it would conflict with the common usage of that environment variable by user shells.

                                        1. 2

                                          As far as I can tell, they both get placed in the environment of subcommands. The manual is (as per many GNU manuals) unclear on the matter: “When make runs a recipe, variables defined in the makefile are placed into the environment of each shell.” My reading is that anything set in Make should be passed through, but this does not appear to be the case.

                                          % cat Makefile
                                          FOO = set-from-make
                                          
                                          all:
                                                  @sh ./t.sh
                                          % cat t.sh
                                          echo "FOO is '${FOO}'"
                                          % make
                                          FOO is ''
                                          % FOO=from-env make
                                          FOO is 'set-from-make'
                                          % make FOO=from-override
                                          FOO is 'from-override'
                                          
                                          1. 1

                                            IMO the GNU make manual is pretty clear on this.

                                            https://www.gnu.org/software/make/manual/html_node/Values.html

                                            Variables can get values in several different ways:

                                            • You can specify an overriding value when you run make. See Overriding Variables.
                                            • You can specify a value in the makefile, either with an assignment (see Setting Variables) or with a verbatim definition (see Defining Multi-Line Variables).
                                            • Variables in the environment become make variables. See Variables from the Environment.
                                            • Several automatic variables are given new values for each rule. Each of these has a single conventional use. See Automatic Variables.
                                            • Several variables have constant initial values. See Variables Used by Implicit Rules.

                                            https://www.gnu.org/software/make/manual/html_node/Overriding.html

                                            An argument that contains ‘=’ specifies the value of a variable: ‘v=x’ sets the value of the variable v to x. If you specify a value in this way, all ordinary assignments of the same variable in the makefile are ignored; we say they have been overridden by the command line argument.

                                            https://www.gnu.org/software/make/manual/html_node/Environment.html

                                            Variables in make can come from the environment in which make is run. Every environment variable that make sees when it starts up is transformed into a make variable with the same name and value. However, an explicit assignment in the makefile, or with a command argument, overrides the environment. (If the ‘-e’ flag is specified, then values from the environment override assignments in the makefile. See Summary of Options. But this is not recommended practice.)

                                            1. 1

                                              Yes, I don’t disagree with any of this and it’s consistent with usage. My point was about variables getting into the environment of shell commands in recipes. The wording suggests all variables are put into the environment, but based on the first result in the example that’s clearly not the case.

                                              1. 1

                                                Oh I see. The manual is less clear on that point:

                                                By default, only variables that came from the environment or the command line are passed to recursive invocations. You can use the export directive to pass other variables.

                                                It should probably say “passed to child processes through the environment” or something similar.

                                                $ cat Makefile
                                                VAR1='hi'
                                                export VAR2='hi'
                                                test:
                                                        echo $$VAR1
                                                        echo $$VAR2
                                                $ make
                                                echo $VAR1
                                                
                                                echo $VAR2
                                                'hi'
                                                
                                                
                                1. 1

                                  I’d have trouble trusting Python for something like this, just due to the chance of someone changing an important line subtly to steal secrets. Am I crazy?

                                  1. 8

                                    What language doesn’t allow people changing important lines?

                                    1. 1

                                      A reasonable question which might betray my insanity for preferring compiled languages for handling private authentication materials.

                                      1. 3

                                        Surely it’s harder to see the suspicious modification in a compiled form. If you’re going to rely on hash checks, say, instead of inspection, I would think that would apply equally well to any executable.

                                  1. 11

                                    Is the author not aware that you can use zfs on linux with both lxc and docker? Article doesn’t really go into any of the details of what goodies that I’m missing out on.

                                    1. 7

                                      Newer features like encryption and raw sends (likely crucial to some end-to-end encryption features Datto is planning on offering; Tom Caputi, one of their engineers, authored that feature) might take a while to land in FreeBSD and IllumOS.

                                      At the same time, FreeBSD ZFS has had TRIM for a while, but it’s still being developed on Linux and appears to be in some sort of development hell (c.f. https://github.com/zfsonlinux/zfs/issues/598 https://github.com/zfsonlinux/zfs/issues/5925).

                                      See http://open-zfs.org/wiki/Features for more details - it seems to be a bit out of date, especially regarding things like encryption which made their way to 0.8.0-pre in Linux.

                                      So, the result is that a lot of newer pool feature flags are Linux-only for now, and pools created with -pre releases of ZFS can’t be imported on other platforms. Not a problem if you’re only using Linux, but something to keep in mind.

                                      1. 5

                                        We’re working on importing the encryption changes, but we’re not going to finish that process until we’re sure they’re ready. There have been some panics and other issues that we’ve been chasing down. It’s the file system, so it’s extremely important to get this stuff right, even when it takes a while.

                                        1. 2

                                          Absolutely, and the encryption changes are rather extensive.

                                          Related: what do you think of channel programs? Running Lua in the kernel scares me a little.

                                          1. 2

                                            I’m not sure that I’m scared. I think the Lua interpreter we have is almost certainly a high quality piece of code that has seen a lot of testing and (I believe?) fuzzing in the upstream codebase. I definitely had (and, really, still have) reservations about it – you can read about some of them in comments I made on the pull request.

                                            That said, because the implementation is still (as far as I know) constrained to use by the super-user – and even then, only in the global zone – I don’t think it’s been the cause of much if any havoc on general purpose or multi-tenant systems. I do appreciate that if you’re building a sealed appliance that happens to sit on top of illumos, it probably does help with certain internal ZFS administration functions that you might want to build.

                                        2. 3

                                          Sure, I can accept that there will be version/feature skew, however that’s a long way from the claims the author is making about “doing it wrong”.

                                      1. 3

                                        I particularly liked 4. Be sure that authors annotate source code before the review begins. The section heading is perhaps a little misleading: while the apparent effect is notes to reviewers, the most concrete benefit is reviewing your own change as a separate step to writing it.

                                        Self-review is something that I feel is perhaps not that common, but I think it’s very important. If you take a critical eye to your own change, especially in a different setting and mood to when you were writing it, you’ll almost certainly find things that you could improve before you ask others to look.

                                        1. 4

                                          Take a branch with only 3 small changes and it will get a whole lot of comments and suggestions. Take one with +100 changed files and it will get none.

                                          That’s a great example of bikeshedding.

                                          1. 2

                                            But it’s a real problem. Nobody reads long diffs. You want your code reviewed, don’t you? Then make it shorter. If it must be longer, then turn it into a lot of small diffs, each requiring no further or minimal context.

                                            1. 3

                                              Thankfully some people don’t buy into this self-defeating rhetoric and can and do read longer diffs when the changes required are longer. Constraining the length of a change works for some problems and under some conditions, but it’s not a fundamental good or even universally achievable.

                                              1. 5

                                                It’s not a self-defeating rhetoric. It’s just hard to pay attention when your work is longer. It’s not because people are lazy or stupid or some other wrong thing. It’s because we’re humans and we are just not good at reading long and rambling bits of code that someone else wrote all at once. When every line of a giant hairball diff involves a context switch, nobody is going to read that, not even the original author.

                                                I’m not saying you can’t make long changes. I am saying that you should split up your long changes. Split them as much as possible so each change has the least context possible to be understood. Books have sentences, paragraphs, chapters. Code has functions, modules, source files, repositories. Code review should use commits as the demarcation.

                                                Move the effort of making the diff understandable to the writer, not the reader.

                                                1. 1

                                                  Obviously if a change is rambling, it could probably stand to be improved – but something can be long without being rambling.

                                                  When every line of a giant hairball diff involves a context switch, nobody is going to read that, not even the original author.

                                                  I think you may be projecting a little. To stack my anecdote alongside yours, I have both read and written longer changes that required a lot of context to understand. I agree that it takes longer, which perhaps means I won’t get to do it all in one sitting – but I can take notes about my thoughts, as I would encourage all engineers to do, and I can pick up where I left off.

                                                  Split them as much as possible so each change has the least context possible to be understood.

                                                  I agree this can be beneficial when it’s possible, I just don’t think it always is. I’ve definitely seen people err too far on the side of microscopic changes. While the tiny change at issue may seem correct in isolation, the broader context is often actually very important and by avoiding understanding it you’re not going to give or get a very thorough review.

                                                  Code review, like designing and writing the code in the first place, and like testing it, takes time and energy. There’s just no magic bullet when the goal is thoughtful, consistent, and rigorous change to the software.

                                                  1. 2

                                                    The data is on the side of shorter reviews.

                                                    Our results suggest that review effectiveness decreases with the number of files in the change set. Therefore, we recommend that developers submit smaller and incremental changes whenever possible, in contrast to waiting for a large feature to be completed.

                                                    https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/bosu2015useful.pdf

                                                    Reviews should be of changes that are small, independent, and complete.

                                                    http://users.encs.concordia.ca/~pcr/paper/Rigby2012IEEE.pdf (based on data from https://users.encs.concordia.ca/~pcr/paper/Rigby2011Dissertation.pdf )

                                                    There is no large code change that cannot be split up into incremental, meaningful changes. It takes training to recognise those atomic boundaries, but they exist, and using them is helpful for reviewers.

                                                2. 1

                                                  This is one of the things I really like about Go: the language designers explicitly design features to enable easier incremental changes.

                                            1. 42

                                              This is what running a VM in Microsoft Azure means. Microsoft controls the underlying datacenter hardware, host OS, hypervisors etc.

                                              There is no defense against sustained physical access.

                                              1. 10

                                                I think the difference raymii is making is between online and offline access - yes, they can unrack the servers and look at your disks with a magnifying glass, but online access where they can log in live to your running instance is a different threat model. If you rack hardware somewhere, sure, they have your hardware, but they most likely don’t have (an equivalent of) the root password. This story surprised me.

                                                1. 18

                                                  But we’re talking about virtual machines here, right? So you don’t need to unrack anything; your magnifying glass is just /proc/$(pgrep qemu)/mem (or whatever the hyper-v equivalent is), to peruse at your leisure, online, from the host.

                                                  (And even in the case of rented physical servers, there are still probably BMCs and such in scope that could achieve analogous things.)

                                                  1. 2

                                                    But that is still more work than just executing commands via an agent that’s already running. You still have to do something to get root access to a specific machine, instead of being able to script against some agent and accessing all machines.

                                                    Leaving your door unlocked is one thing; setting it wide open with a sign “Enter here” is another.

                                                    1. 2

                                                      On the plus side, though it is “easy” it also appears to be logged and observable within the VM, which is the part most obviously unlike actual backdoors.

                                                  2. 13

                                                    There is absolutely nothing to be done from within a VM to prevent the host flipping a bit and backdooring it arbitrarily, or snapshotting it without shutting it down and doing the same. I’d be very surprised all the big names don’t have this functionality available internally – at least Google support live migration, which is the same tech.

                                                    There are open toolkits for doing arbitrarily nasty poking and introspection to a running VM, e.g. volatility framework

                                                    Hard to point fingers at Microsoft here

                                                    1. 3

                                                      Moreover, Live Migration of VM’s is a functionality available in widely deployed VMware ESXi software since 90’s. I suppose even longer than that on Big Iron.

                                                    2. 2

                                                      They can access the memory. That is equivalent to a root password. IMHO CPU supported memory encryption like Intel SGX is snake-oil at most, if you are targeted by the phisycal host of your VM.

                                                      Hosting in the cloud is a matter of trust and threat analysis.

                                                    3. 5

                                                      I’m really suprised, it seems that everybody thinks it’s common knowledge and they seem to think it’s normal. I don’t like my hosting provider having this level of access to my data and machines. We are smart enough to find a solution to this, hosting infrastructure without giving up on all security…

                                                      1. 26

                                                        With managed virtualized infrastructure, “this level of access” is completely unavoidable. They run the virtualized hardware your “server” is running on; they have complete memory and CPU state access, and they can change anything they want.

                                                        I guess it makes backdooring things marginally simpler to write a guest-side agent, but their actual capabilities are totally unchanged.

                                                        This is something that ought to be common knowledge, but unfortunately doesn’t seem to be.

                                                        1. 1

                                                          The risk of your provider taking a snapshot of your disk and ram is always there with virtualization. But, you could encrypt the disk, which would make it harder for them (they have to scan ram for the key, then decrypt). But just an agent with root privileges… what bothers me the most I guess is that it is not made clear. A note in /etc/issue or motd with “we have full root acces in your vm, read http://kb.ms.com/kb77777 for more info” would make it clear right from the get-go.

                                                          1. 10

                                                            (they have to scan ram for the key, then decrypt)

                                                            Not even that, just put a backdoor in the BIOS, boot loader, initramfs, or whatever code is used to unlock the encrypted disk to intercept key entry.

                                                            1. 3

                                                              Do you know of any isolated / trusted vm like solution? Where provider access is mitigated?

                                                              1. 12

                                                                No. Even the various “gov clouds” are mainly about isolation from other customers and data center location.

                                                                The cloud providers are executing the cpu instructions that the VM image provided by you (or picked from the store) contains. There isn’t any escaping that access level.

                                                                The only option is to actually run your own physical hardware that you trust in an environment you consider good enough.

                                                                1. 4

                                                                  In my comment about host and TLA resistance, I had a requirement for setups resistant to domestic TLA’s that might give orders for secrets to be turned over or use advanced attacks (which are getting cheaper/popular). It can be repurposed for an untrusted, host setup.

                                                                  “If it has to be U.S. and it’s serious, use foreign operated anti-tamper setup. The idea is all sensitive computations are run on a computer stored in a tamper detecting container that can detect radiation, temperature changes, power surges, excessive microwaves, etc. Tamper detection = data wipe or thermite. The container will be an EMSEC safe and the sensors/PC’s will always be located in a different spot in it. The system is foreign built and operated with the user having no control of its operation except what software runs in deprivileged VM’s in it. Status is monitored remotely. It helps to modify code so that most sensitive stuff like keys are stored in certain spot in memory that will be erased almost instantly.”

                                                                  The clouds aren’t built anything like this. They have total control like those in physical possession of hardware and software almost always have total control. They can do what they want. You won’t be able to see them do it most of the time without some clever detection mechanisms for security-relevant parts of the stack. That’s before we get to hardware risks.

                                                                  Bottom line: external providers of computing services should always considered trusted with full access to your data and services. By default. Every time. It’s why I encourage self-hosting of secrets. I also encourage pen, paper, and people for most confidential stuff. Computers aren’t as trustworthy.

                                                                  1. 3

                                                                    What is your threat model?

                                                                    There is something based on selinux for Xen https://wiki.xen.org/wiki/Xen_Security_Modules_:_XSM-FLASK which can by design prevent the privileged “dom0” from reading the memory of nonprivileged guest domains. But that assumes you trust your provider to actually implement this when they say they do.

                                                                2. 7

                                                                  A note in /etc/issue or motd with “we have full root acces in your vm, read http://kb.ms.com/kb77777 for more info” would make it clear right from the get-go.

                                                                  I think this is a combination of “common knowledge, so not worth mentioning specially” for users who already know this and “let sleeping dogs lie” for people who don’t already know. I mean, why press people with their noses on a fact that the competitor is equally mum about? Seems like a bad PR move; you’d get clueless people all alarmed and leaving your platform for reasons that are totally bogus, as any competitor has the same kind of access.

                                                          1. 13

                                                            I usually expose -x via a flags like --trace/--debug. You can also invoke it manually with bash -x ze_script. I wouldn’t turn it on by default.

                                                            1. 2

                                                              I definitely agree. I think it’s tempting to think trace output like this means you don’t have to work on log messages and error messages for human beings, and the result is a giant wall of pretty inscrutable output to sift through to sort out what went wrong.

                                                              1. 2

                                                                -x is really useful when writing Dockerfiles, so you can do:

                                                                RUN set -x \
                                                                    && my-command \
                                                                    && my-2nd-command
                                                                

                                                                This way you get clear picture of what’s happening while doing image builds.

                                                                EDIT: formatting

                                                              1. 16

                                                                Reads like a collection of own goals underlining the need for open source.

                                                                1. 17

                                                                  Every exposure I’ve ever had to FPGA design and synthesis tools and IP sets has left me deliriously happy to be working not in that space. A truly deeply proprietary space with tools that serve to make Lotus Notes seem fun to deal with.

                                                                  1. 2

                                                                    I guess it’s because of how capital intensive developing hardware can be. Anyone with a computer can start writing and distributing code with negligible marginal cost, but to develop hardware you need money.

                                                                    One of the big incentives for Open Source software is interoperability/adoption (the open source solution should theoretically spread the fastest), but it’s more profitable to keep it closed source if people will adopt it anyway (no good alternatives).

                                                                    1. 2

                                                                      We’re already using GHDL and as soon as any FPGA vendor opens up their bitstream…. we will push to jump to that one.

                                                                    2. 2

                                                                      And ASIC EDA tools aren’t any better. At $dayjob we’ve recently starting working with one of the major vendors in the space (/^S.+s$/) and the general quality of the software & support thereof has been…profoundly underwhelming, especially considering the convoy of trucks loaded with cash we had to send them in exchange for the privilege of using it.

                                                                      Open source is by no means a silver bullet (there’s plenty of examples of terrible pieces of it), but man…I guess I’m spoiled by the sorts of things I usually deal with – when I suddenly have to use some proprietary something for some reason, probably 80+% of the time the drop in general quality is pretty astonishing.

                                                                      1. 2

                                                                        I think one of the main points about open source is the ability to scratch itches and ease pain points.

                                                                        But if you have a vast monolith of proprietary crap… you’re stuck in a land of pain and digital eczema.

                                                                        1. 2

                                                                          I think one of the main points about open source is the ability to scratch itches and ease pain points.

                                                                          Oh, certainly. I have on occasion though had situations where I’ve noticed such an itch, pulled back the curtain to scratch it, and been too horrified by what was going on beneath the UI surface to follow through and do so. (Like “I don’t want my name publicly associated with this codebase”.)

                                                                          But such instances have been rare, and having at least the ability to do so is massive advantage.

                                                                          1. 1

                                                                            I have in quite a few instances in the Open Source world I have done no more than give a good bug report and well defined small test case and had the issue resolved the next day.

                                                                            In other instances I had to walk about in the debugger until I reach a “Huh? Wtf!” moment and then posted a query to the appropriate mailing list… and received a prompt “Yeah, that looks a bit odd… I think it should be…” reply which fixed it.

                                                                            In the closed source world my experience has been universally, ahhh, buy the next version, it might be fixed in that.

                                                                  1. 0

                                                                    This is why I simply love programming with golang. Everything is setup for you to handle errors somewhat properly, without much hassle.

                                                                    1. 3

                                                                      But when you look at actual real-world code in Golang, what you often see is:

                                                                      err := fn()
                                                                      if err != nil {
                                                                          return err
                                                                      }
                                                                      

                                                                      Even a sane system can be used in silly way.

                                                                      1. 2

                                                                        At least the snippet checks for an err value!

                                                                        1. 2

                                                                          That’s ok, if you don’t want to handle it there.

                                                                          Worst is:

                                                                          output, _ := fun()

                                                                        2. 3

                                                                          That’s a joke, right?

                                                                          Error handling is one of the few things I think go has comprehensively messed up. In no particular order, the builtin errors lack:

                                                                          • Internationalization of error messages
                                                                          • Derived errors (high-level-failure caused by low-level-failure)
                                                                          • Syntactic support for error propagation
                                                                          • Distinction between programmer errors and runtime errors (eg Printf returns an error for a bad format string or stdout being closed)
                                                                          1. 1

                                                                            Different opinions, man. It’s not perfect but I think it’s pretty good, compared to all the languages I worked with.

                                                                            Btw, internationalisation of error messages is dead simple to implement, even if it is not straight out of the box.

                                                                        1. 3

                                                                          Slightly related, I really like the HaskellWiki page on errors vs exceptions: https://wiki.haskell.org/Error_vs._Exception

                                                                          At least for me, discussing “errors” has always been confusing due to the ways we recycle terminology. I like to use “failure mode” to describe a way in which a system can fail, “exception” to refer to uncommon - but not expected - behavior, and “error” to mean to un-handled exceptional behavior; an instance of a failure.

                                                                          Not everyone uses these terms this way, and there could be a better vocabulary for this stuff, but I think it’s worth trying to tease apart fine distinctions in this area.

                                                                          1. 5

                                                                            For what it’s worth, I think we’ve drawn a similar distinction in the Joyent guide to Error Handling. Note that while this document was part of our effort to describe the way we build software using Node, the taxonomy really applies everywhere.

                                                                            We split things into two broad categories: Operational Errors and Programmer Errors. The former appears akin to your notion of “Exceptions”; i.e., something that could reasonably happen and should be handled. The latter is effectively a logic error in the program itself: the program is not correct as written and the only completely safe course of action is to terminate without doing further damage (e.g., scribbling into a data file). In this taxonomy, the failure to account for and handle an operational error (e.g., malloc() returning NULL) is, itself, a programmer error (probably a SIGSEGV in the malloc() case).

                                                                          1. 30

                                                                            Props for risking high-paying jobs to stand up for your principles. I’m a pro-gun, pro-Constitution, pro-privacy American whose fine with justifiable, measured actions by U.S. military where actually needed with minimal blowback expected. I’ve opposed most of what U.S. military has done over past two decades. So, I’ll add my reaction to two quotes:

                                                                            ““If big tech companies are going to turn their back on the US Department of Defense, this country is going to be in trouble,” he said. “

                                                                            ““a defeat for US national security [and] patriotism”.

                                                                            That’s un-American bullshit supported by a large segment of right-leaning voters. The very design of U.S. government is to limit trust to any one branch. Relevant example is Executive branch directing military-industrial complex daily theoretically kept in check by suspicious Congress and courts. If there’s argument, ask right-leaning voters if they want liberals or Hillary Clinton to decide who to kill or not kill for 4 years straight. I bet they won’t be unconditionally supportive.

                                                                            Further, historical, heavy hitters that led the military like George Washington and Dwight Eisenhower cautioned us to keep it in check citing prior and likely outcomes of bad behavior that would hurt America. Most of those happened, too. The biggest critique coming from General Smedley Butler: a two-time awardee of Medal of Honor who confessed most wars he led were specifically for capitalist exploitation, not freedom or democracy. Or as George Carlin says: “War is rich old men protecting their wealth by sending lower and middle-class young men off to die.”

                                                                            I’ll listen to Washington, Eisenhower, and Butler about managing a military over a Bezos or Bloomberg any day. Hell, have they even shown they understand the concept of putting their lives on the line and giving up business opportunities to protect the average American? I don’t know if they have service records or what they did if they did. Hell, I’ll even count peaceful organizations or nonprofits that require full-time work at lower-than-tech pay. Although I lack that data, I do know Bezos was willing to risk killing Americans just to make himself a bit more money and personal satisfaction. Dude isn’t much better than terrorists in my book. If it was legal, such an amoral leader would probably be killing his opponents like his ilk used to.

                                                                            1. 13

                                                                              Eisenhower literally coined the term military-industrial complex in his farewell address to the nation. In an earlier speech he decried the buildup of defense spending, not only in terms of economic drain but also of mental and creative output:

                                                                              Every gun that is made, every warship launched, every rocket fired signifies, in the final sense, a theft from those who hunger and are not fed, those who are cold and are not clothed. This world in arms is not spending money alone. It is spending the sweat of its laborers, the genius of its scientists, the hopes of its children. The cost of one modern heavy bomber is this: a modern brick school in more than 30 cities. It is two electric power plants, each serving a town of 60,000 population. It is two fine, fully equipped hospitals. It is some fifty miles of concrete pavement. We pay for a single fighter with a half-million bushels of wheat. We pay for a single destroyer with new homes that could have housed more than 8,000 people. . . . This is not a way of life at all, in any true sense. Under the cloud of threatening war, it is humanity hanging from a cross of iron.

                                                                              Quite a departure from the turn of phrase on Ginsberg: “The best minds of my generation are thinking about how to make people click ads.”

                                                                              1. 1

                                                                                Oh yeah. Thanks for posting it. He brilliantly put defense spending into perspective by showing what we sacrifice to waste that money. The hospital comparisons show we might be wasting lives, too. I’ve used paraphrased versions of his arguments in debates with die-hard military supporters for years. It doesn’t get as far as I’d like but it always works to get them to back off a bit. Gotta force them to choose between investing in America, esp American lives, versus wasting money on useless toys.

                                                                              2. 15

                                                                                History has made it plainly clear that the constitution has failed to keep military power at bay. Our complete loss of privacy is another failure. It turns out a bunch of rich slave owners make a flawed system.

                                                                                One success of the constitution is no internal wars for 150 years, which is nice.

                                                                                1. 16

                                                                                  Not descending into civil war periodically isn’t really unique to the US though, so it’s hard to say whether anything about that is really because of the constitution.

                                                                                  1. 1

                                                                                    It might be worth looking into how many democracies avoid a civil war with and without a constitution. For a case study, did Australia have more civil war and/or less protection for individuals before its constitution or afterward?

                                                                                    1. 5

                                                                                      Australia is a bit of an odd one, since prior to the constitution it was a military-occupied colony of a country that did have a constitution.

                                                                                      1. 1

                                                                                        Didn’t the different constituent parts of Australia have their own mini-versions of the “constitution” of the UK?

                                                                                        The constitution of the Confederate States of America was essentially a carbon-copy of the US one, with the right to own slaves explicitly added. In all other respects both states considered themselves as heirs to the original US constitution.

                                                                                    2. 1

                                                                                      Which nations are you thinking of?

                                                                                      1. 3

                                                                                        I mean, Australia hasn’t really descended into civil war. We’ve only been a federated country in our current form for a little under 120 years but still.

                                                                                1. 1

                                                                                  This was a fun watch. Rob Pike is sometimes criticized for having strong opinions (he’s anti- syntax highlighting!), but it’s nice to hear the experiences that helped developed them and the thought processes behind them.

                                                                                  1. 1

                                                                                    I’ve learnt to edit Go without syntax highlighting and honestly I don’t miss it at all.

                                                                                    1. 1

                                                                                      Syntax highlighting is definitely one of those areas where we should just let people do whatever makes them happy. If you’ve decided to give it up, that’s fine. I enjoy it, so I won’t.

                                                                                      Rob has said some pretty grating things about both syntax highlighting as well as the people who use syntax highlighting – I think the criticism is usually more of the inflicting of the opinion than the strength with which it is held.

                                                                                  1. 2

                                                                                    Wow:

                                                                                    Generally, a driver can be written in one of two ways: as a kernel module or as a user space driver. Both have distinct advantages and disadvantages though ultimately user space drivers are faster, which is the most important requirement in modern use cases.

                                                                                    ixy shows that it is possible to implement a basic user space network driver in just below 1000 lines of code

                                                                                    1. 1

                                                                                      though ultimately user space drivers are faster

                                                                                      I hear this rhetoric a lot, but I don’t think it’s a universal truth so much as an admission that the people making the claim aren’t interested in working on the kernel. It’s probably true that traditional POSIX I/O functions (send, recv, etc) aren’t going to get you there – but the kernel could arrange for a new API for the modern era, with rings and polling and steering.

                                                                                      1. 1

                                                                                        Yep. Can’t say one is faster than the other unless you build both apples to apples with benchmarks. Who knows what would result. The monoliths are too complex to know ahead of time for sure.

                                                                                    1. 8

                                                                                      The C programming language defines a string as char*.

                                                                                      No it doesn’t. char* is a type. String is not a type in C.

                                                                                      Here is how the definition reads: A string is a contiguous sequence of characters terminated by and including the first null character.

                                                                                      The only advantage of this representation is space efficency.

                                                                                      There are other advantages, such as its simplicity. Or the fact that you can split a blob of bytes into strings without having to first count the number of strings and allocate a bunch of length-capacity-pointer tuples for each. It works great with fixed size buffers and static storage. (I’ve heard static analysis tools like fixed sizes and static storage.)

                                                                                      If you’re going to shit on C strings, try not to start the post with a completely incorrect statement. It’ll look a little more credible.

                                                                                      I’m not yet quite convinced that replacing simple NUL-terminated strings with reference counting, chunks, lengths and capacities and the arithmetic that goes with it plus allocated storage is all inherently safer.

                                                                                      I’d say most of these supposed safety benefits can only be realized when there’s a complete, carefully vetted API & implementation that wraps it all in a way that doesn’t allow the user to shoot themselves in the foot. I’m afraid it’d have to be opaque. Because if people start doing arithmetic and tricks with the bare pointers, they will fuck it up. And I’d probably have to take out features like slices, because they’ll either surprise somebody (when some string suddenly got immutable) or immutability isn’t enforced by the API and someone shoots their foot off.

                                                                                      Without these restrictions, it’s probably no more safe than plain C strings. Heck, I’d say the number of things you can get wrong is just greater. It’s a more complicated alternative to C strings.

                                                                                      1. 12

                                                                                        I’d say most of these supposed safety benefits can only be realized when there’s a complete, carefully vetted API & implementation that wraps it all in a way that doesn’t allow the user to shoot themselves in the foot.

                                                                                        I think that’s the whole point. C’s problem – and yes, it is a problem – is that it purports to have a string API but it basically doesn’t. Having programmed in C for a while and having used Lisp, Python and vast array of other languages, there’s no question that C’s “string” API is the least friendly and most difficult to use. As you say, string is not a type in C.

                                                                                        Without these restrictions, it’s probably no more safe than plain C strings.

                                                                                        This is true if you expose these to the user. Most (all?) APIs don’t so this. This is precisely why C “strings” are unpleasant to work with when you’re doing actual string manipulations.

                                                                                        If you’re going to shit on C strings, try not to start the post with a completely incorrect statement.

                                                                                        I think it’s universally accepted that a “C string” is a char * even though the standard may not say it directly. Besides, you have a whole section of the standard (7.21 in my copy) entitled “String handling” where most functions take a const char * as the “string”.

                                                                                        1. 2

                                                                                          I totally agree on the (lack of a good) API being a big problem. Then again, if you had a good, opaque string API, the user-perspective discussions about nul-terminated-vs-pascal-strings should just die because it’s an implementation detail at that point. Internally, different implementations could have however few or many different possible representations to support optimal space & efficiency characteristics strings of different lengths and access patterns. (Do I want something that complicated in C however?). The whole complaint about C “strings” being unpleasant to work with becomes moot because you’ll be working through an API instead of the internal representation.

                                                                                          I think it’s universally accepted that a “C string” is a char * even though the standard may not say it directly.

                                                                                          A pointer-to-char can be a NULL pointer, or it can point to zero, one, or more C strings. The storage for a string definitely doesn’t reside inside a pointer-to-char.

                                                                                          It might sound like pedantry but way too many people are confused over arrays, pointers, and strings in C that it is impossible to tell whether someone’s just casually using sloppy terminology or really not thinking straight. A pointer-to-char is not at all a string, and I prefer not to call it one so as to avoid contributing to this confusion.

                                                                                          And yes, I’ve seen people hating on C strings because they are afraid that they are not NUL-terminated. Such a thing is by definition not a C string, but people get confused because they think char* is a string. If you have to worry about that kind of thing, it’s no surprise the already somewhat lackluster API can feel like a complete minefield! It doesn’t help that there are broken functions that can take a pointer to string and produce something that is sometimes not a string. Avoid these.

                                                                                          If you only people would use the APIs that guarantee the output is a string if the input is a string, life suddenly gets a lot easier. But you also need to recognize whether you’re working with strings or just pointers to an arbitrary blob of chars.

                                                                                          1. 2

                                                                                            Then again, if you had a good, opaque string API, the user-perspective discussions about nul-terminated-vs-pascal-strings should just die because it’s an implementation detail at that point.

                                                                                            You are probably looking for vstr if you don’t know about it already. It’s the best “good, opaque string API” I’ve found. Its biggest problem is probably being so comprehensive (large) but the author has a good solution in the form of a second, smaller (smaller) “opaque string API”.

                                                                                            However these are not the best string API. Opacity has a cost, and if it’s not clear, consider doing operations on many strings – where is vstr_srch_manyvstr_any()? Who has good support for building DFA or a bloom filter? Why is parsing so hard? Details sometimes matter.

                                                                                            The best string API is an array API that treats a string as an array of characters. If you have good tools for arrays, you’ll have no problems with strings. Even in C. Hiding inside of q/kdb+ (for example) are bindings for C that create and manipulate performant arrays, but because they’re arrays you can mmap them, or use a vm_remap/memfd, or use any other library that already works with arrays. Or implement your fancy special search or whatever – you’ve got a very solid foundation for anything string related: A fast webserver, a algol/C-like programming language parser.

                                                                                            1. 2

                                                                                              Once you’re in Unicode territory, it’s difficult to even think of arrays of characters. Not all of the code points represent a standalone character, and there are often several different code point sequences that end up mapping to the same visible or even semantic construction.

                                                                                              Basically: strings are exhausting, even with good facilities!

                                                                                              1. 1

                                                                                                Once you’re in Unicode territory, it’s difficult to even think of arrays of characters.

                                                                                                So many people had the exact-same idea, so I shouldn’t think it that difficult: C’s early efforts into Unicode were of a wide character; Erlang implements a “string” as a (linked-) list of integers. Java thought they were so clever for making a “character” 16-bits. And so on. Maybe 16-bits isn’t enough, maybe we need 32-bits. Or the full-numeric tower. Or nested lists (for combining ints!).

                                                                                                Without passing judgement: This actually works very well if you have enough memory (you probably do), and if you’re going to be doing a lot of glyph or code-point level manipulation.

                                                                                                However there’s a reason most people kept the byte-array and just used utf8: It was good enough, and people don’t actually index or manipulate the arrays of characters that much anyway. I certainly never need to know the number of characters or codepoints or surrogate pairs, runes or glyphs. And on one hand I can count the number of times I’ve needed to write a routine that needed to compute the number of pixels wide a string would be rendered. My advice: Keep them packed. Save the bits.

                                                                                        2. 5

                                                                                          My intention was not to “shit on C strings” but give an overview over the alternatives.

                                                                                          You are right that Pascal strings cannot be split without reallocations while I can insert NUL into C strings. I did not think of that use case. Where does it usually occur?

                                                                                          1. 4

                                                                                            My intention was not to “shit on C strings” but give an overview over the alternatives.

                                                                                            Then I apologize for using such an expression. I guess it’s just too fashionable to hate on anything and everything to do with C these days, and it’s getting to me. “C strings are only good for one thing, here’s how to do it better” just sounded like it..

                                                                                            You are right that Pascal strings cannot be split without reallocations while I can insert NUL into C strings. I did not think of that use case. Where does it usually occur?

                                                                                            Tokenizers & parsers (or just field splitters, see anything that uses strtok or strtok_r) for simpler formats where parts are always separated by a character that you can replace with a NUL.

                                                                                            1. 3

                                                                                              I can insert NUL into C strings. I did not think of that use case. Where does it usually occur?

                                                                                              So I’m reading a file. I read() or mmap() the beast.

                                                                                              Now I want to break it into lines.

                                                                                              One way is to copy each line into a new buffer. Another would be to treat the entire file as a chunk and create a list of rc_string.

                                                                                              And yet another would be to scan for a newline, replace it with 0, use the string, then resume from the new offset. this is extremely space-efficient and very simple code:

                                                                                              for(x=p=buffer;p<endp;++p)
                                                                                                if(*p=='\n'){*p=0;doit(x);x=p+1;}
                                                                                              
                                                                                          1. 9

                                                                                            So, uh, what’s better?

                                                                                            1. 15
                                                                                              • composable GUIs (like the alto & modern smalltalk environments)
                                                                                              • notebook interfaces (like jupyter & mathematica)
                                                                                              • literate programming interfaces (like swyft / the canon cat)
                                                                                              • plan9
                                                                                              • menuet
                                                                                              • NeWS
                                                                                              • language-based systems like interim
                                                                                              • modern unix shells like zsh
                                                                                              • borderline-obscure stuff like zigzag, sometimes

                                                                                              And, of course, I’ve been working on a prototype of the system I pitched last year.

                                                                                              The thing about interfaces is, if you put what you’re already accustomed to out of your mind, you start to think of alternatives pretty quickly – and many of them are better for certain tasks than what you already use.

                                                                                              For my next book I’m planning to write a survey of alternatives to the WIMP paradigm that can be easily run or emulated by readers. Unfortunately, I’m going to need to do plenty of research if I’m to seriously discuss the internals of these systems, since a lot of them are language-based systems built around languages I don’t know very well (like lisp or forth) or at all (like holy c or oberon).

                                                                                              1. 5

                                                                                                I’m interested in your research. is there any place where I can keep on track with it?

                                                                                                1. 4

                                                                                                  I’ve barely started researching for the book in question, so I’m not sure to what extent chapters & other content will be made available before it’s finished.

                                                                                                  The last book was mostly compiled from stuff I had already published on Medium. If you follow me there, you’ll probably get at least some of the material intended for the next one – maybe even rough drafts for chapters. Also, a lot of the chapters from the last book were inspired by or adapted from discussions I’ve had on mastodon or SSB, & this will probably be true of the next one: if you follow me on mastodon, no doubt you’ll get a preview of some of the ideas I’m playing with.

                                                                                                  If there’s enough interest, I might make a point of posting about the systems I’m researching on a more regular basis. Those posts will probably end up on Medium too.

                                                                                                  1. 2

                                                                                                    Also, I’m going to be posting resources here as I find them during my research.

                                                                                                    1. 2

                                                                                                      Thank you for this. I’m going to follow your work on it.

                                                                                                2. 7

                                                                                                  I’d assume the biggest problem is overlapping windows. I’ve been using tiling window managers since 2012 and I would not go back. If you look at all the newer mobile operating systems (iOS, Android, that failed Windows 8/10 UI thing), they’re all either single app at a time or, at most, split screen.

                                                                                                  I guess a second thing is steering people away from mouse dependence. Hotkeys should be easily discoverable and easily encouraged. A higher learning curve at first can mean faster operation later on. Great example: Autozone. Watch staff look up a part today. They do a lot of clicking and switching back and fourth. The old setup was all terminal based and had the same searching/information. I think the new GUI still has a lot of keyboard shortcuts, but very few people I’ve watched use them.

                                                                                                  1. 5

                                                                                                    Overlapping windows are pretty pointless when they can’t be made to work together in interesting ways. Drag & drop between unrelated applications is the minimum interoperability to justify even supporting overlapping windows in my eyes (and support for that is pretty rare), but I’d be all about overlapping windows if freeform composition with gestures was a standard part of the toolkit. Even then, tiling is preferable on large displays once we’ve settled on an arrangement & interconnections.

                                                                                                    Support for tiling and pseudo-tiling (and quick-switching mechanisms) is something I don’t have a problem with in modern desktops, though. Even Microsoft and Apple have been pretty quick to jump on that bandwagon.

                                                                                                    1. 5

                                                                                                      Tiling windows seems like a funny point since we’re complaining about UIs treating users as stupid. The first version of Windows was tiling only because users were too stupid to handle overlap and might lose track of a hidden window, but eventually it was decided that users could be trusted with the responsibility of arranging things in their own. Round the circle we go.

                                                                                                      1. 1

                                                                                                        The first version of Windows was tiling not because of contempt of users, but to avoid a lawsuit from Apple (who did get overlapping windows working because they thought the Alto had it when it didn’t really). Also, a tiling window system is easier to write than overlapping.

                                                                                                        1. 1

                                                                                                          Alas, I’m not sure of the reference, but they apparently had the feature, tested it, users were confused, and it was pulled.

                                                                                                      2. 4

                                                                                                        I think we’re slowly moving away from mouse-oriented approach, for better or worse. I’d personally wish for keyboard-oriented desktop UI, but judging by how much Microsoft and Apple are striving to unite all their systems software-wise (eg Windows Phone and Xbox One both running Windows variants, or audioOS etc being iOS-based), we might expect a move towards touchscreen-oriented UI on desktops instead. (Although I guess that goes as far back as GNOME 3 instead.) On the other hand, there exist a minority of mouse-oriented UI advocates, such as Rob Pike and his followers. He argues that mouse is more intuitive and faster, and the problem lies in bad UI design instead.

                                                                                                        1. 6

                                                                                                          On the other hand, there exist a minority of mouse-oriented UI advocates, such as Rob Pike and his followers. He argues that mouse is more intuitive and faster, and the problem lies in bad UI design instead.

                                                                                                          i still think that acmes mouse interface for common editing operations is better than keyboard shortcuts (see http://acme.cat-v.org/mouse). the way the mouse is used in most other systems is bad though. the windows way is nearly unusable with the popup-menu thing, and X11 is only saved by the primary selection insert with the middle mouse button ;)

                                                                                                      3. 4

                                                                                                        Presumably some form of programming-is-first-class system like the Alto, where everything you can click is also explorable (“view source” is built in) and extendable via SmallTalk. On the one hand I’m a bit sceptical and think not many users will really make use of this, on the other hand if you see how far some regular (i.e. non-programmer) users take, say, Excel and VBA scripting, having this programmability available pervasively by default in every application would definitely empower users much more than “closed” systems like the original Mac do.

                                                                                                        I have no idea how many people use AppleScript, which ostensibly brings pervasive programmability to the Mac. It wasn’t part of the original Mac OS and is about programming scripts “on the outside” onto or “against” existing applications rather than full-fledged inspection and modification of internals “inside” those same applications.

                                                                                                        1. 3

                                                                                                          The only “modern” OS I know that makes use of hypertext self-documentation is… TempleOS. It also blurs the line between “using” and “programming”, like Alto and LispMs It’s not entirely user-friendly, but I guess it fits the bill.

                                                                                                        2. 8

                                                                                                          Ask not the polemic for what is better; it is merely the shallow well in which the author steeps their discontent.