1. 59

    This is a great example of how programmers dress up arbitrary opinions to make them look like they were rationally derived. The cognitive dissonance that led to writing that C is not supported, but the near-complete superset C++ is supported, or that rust should not be supported because end developers do not use rust must have been nearly overwhelming.

    1. 18

      The cognitive dissonance that led to writing that C is not supported

      Huh? The doc clearly says that C is approved both for end development and for use in the source tree. It’s not “recommended”, because apparently they’d rather use C++, but that’s not the same as not supporting it.

      1. 10

        None of our current end-developers use Rust.

        … says more about Google than anything else.

        1. 21

          I read it as, “the biggest problem with Rust is that we didn’t make it, so how good could it possibly be?”

          1. 3

            We interviewed a guy the other day who told me that he knows “insider sources” in Google and that they are abandoning Go for all new project starts and moving entirely to Rust.

            EDIT: to be clear, I didn’t believe this guy. I was relating the story because it would be funny that they don’t support Rust for Fuchsia but supposedly are abandoning Go in favor of it…

            1. 8

              This is not true.

              1. 3

                I know. We didn’t hire the guy either.

                1. 1

                  o, sorry :(

                  1. 1

                    What do you hypothesize his motivation was for such a weird fabrication? Was he proseletizing rust in an interview? Were you hiring for rust devs and this just.. came out in the interview as a point of conversational commentary?

                    Just curious. Seems a weird thing for a candidate to raise during an interview!

                    1. 3

                      I think he was trying to sound smart and “in the know.” He brought it up when we mentioned that some of our code is in Go, and mentioned that some of his personal projects were in Rust.

                      Like I said above, we ended up not extending him an offer, for a lot of reasons.

                      1. 1

                        Also very easy to check?

                  2. -1

                    Hopefully not. I don’t want to deal with the influx of twenty-somethings fresh from university who believe starting at Google instantly added 20 points to their (already enlarged) IQ.

                2. 5

                  It makes sense to support C++ and not C. C++ makes it easier to write safer code (RAII) and provides a higher abstraction level (templates).

                  1. 4

                    Those are useful features, but that’s the subset of C++ that isn’t “C functions, compiled with the C++ compiler, and avoiding undecorated casts”. If I’m allowed to use C++ then I’m allowed to use C.

                    My original point remains: “it makes sense” is not “here are our axioms, and here are the conclusions derived from those axioms”. Programming language choice is usually - and rightly - a popularity contest based on what the team finds interesting, and I see no difference here when I look beyond the dressing.

                    I compare this to an experience I had at FB, where the systems developers chose to question their language choice (mostly C++, some Java). Arguments were put forward in favour of and against Rust, D, Go, and maybe some other things that I’ve forgotten. Then the popularity contest was run in the form of a vote, and C++ won, so they decided to double down on C++. Not because [list of bullet points], but because it won the popular vote.

                    1. 5

                      Idiomatic C++ is qualitatively different from C, though the language is technically a superset. That in itself is enough to have a group disallow C but allow C++.

                      You are right that it’s an imprecise process. But, popularity is a feature in itself. A popular language has more developers, more help information online, and more libraries. Why wouldn’t popularity be an important feature?

                1. 2

                  You could remove reject() in favour of without().

                  (I’m familiar with filter, while reject is not something I’ve seen before, and I don’t find the name particularly descriptive. Though I’m not sure it’s any worse than filter.)

                  1. 1

                    I’ve seen reject being used by Smalltalk, so it’s not totally new.

                    1. 1

                      Ruby picked it up from Smalltalk too.

                    2. 1

                      I’m not a Smalltalk or Ruby programmer, so reject reads weird to me, and without is just as reasonable.

                    1. 4

                      Always wondered who it was named after.


                      Hans Thomas Reiser (born December 19, 1963) is an American computer programmer, entrepreneur, and convicted murderer.

                      Cancel my meetings I’ve got some reading to do

                      1. 12

                        Yep. Perfect example of “well that escalated quickly.”

                        I remember when it was in the news. I was sure Hans was innocent, given that one of his victim’s ex-boyfriends had already been in jail for murdering someone. I was genuinely shocked when he was found guilty and took the police to where he buried the body.

                        Wired did a really good write up of it at the time.

                        1. 7

                          I actually had dinner with him a few months before the murder & I remember him ranting about his wife a lot at the time so I wasn’t that surprised.

                          1. 10

                            Also one of the early attempts the “geek defense” by framing himself as Asperger’s, throwing other autists under the bus with it. :/

                            1. 4

                              I was working at a startup that was using ReiserFS at the time, and he was doing contract work for us. I never met the dude, but it was very unsettling to be that close to the story.

                            2. 1

                              Yup! Kinda bizarre. I posted this excerpt several years ago:

                              Reiser4 has a somewhat uncertain future. It has not yet been accepted into the main line Linux kernel, the lead designer is in prison, and the company developing it is not currently in business.


                              1. 1

                                There are a number of crime dramas about this as well.


                                1. 1

                                  Oh you need to catch up to the Reiser4 FS story as well. Good readings.

                                1. 30

                                  This is a constant language problem on HN and I see it here sometimes too… define the word “developer”. Alternatively define the word “professional”.

                                  Is it possible to use FreeBSD for a developer machine? Yes, if your definition lines up with the software available for FreeBSD. Otherwise no. You need to define developer first.

                                  Same argument as “is the 2019 MacBook Pro (or Mac Pro) a real professional machine?” Yes, if you are a professional and your needs line up with the capabilities of that machine. Otherwise no.

                                  But those terms are so broad that there cannot be one single answer. Yet that doesn’t stop people from arguing about it.

                                  1. 6

                                    Precisely this. There are many different ways to be a “developer” and some of them are easy on FreeBSD and some are impossible. Personally, as I spend most of my time in Emacs or Jupyter notebooks, it would work great for me. When I was doing CUDA development, or writing complicated media transformation pipeline using QuickTime, it was a no-go.

                                    1. 3

                                      Headlines are going to be like this. If you want specific definitions of every word in a headline, maybe we should increase the Lobste.rs headline character limit. If the author doesn’t address the headline in the article, I could understand your complaint, but in this case it’s well addressed.

                                      1. 4

                                        The article goes into detail about which development activities work well and which do not. This comment seems like needless nitpicking to me.

                                        I’m pretty disappointed this comment has more upvotes than the thoughtful, interesting, and informative article. What the heck is going on with Lobste.rs?

                                        1. 1

                                          Yes. I guess people online just want to argue about something, and the ambiguous definition of “developer” makes it “fun”.

                                          In all seriousness, the only thing I found that is completely impossible is CUDA on FreeBSD, but I guess this is not part of OP’s “developer” from what he said in replying another comment here. Does it prevent me from using FreeBSD? No. I just sshfs v100: /n/v100 and ssh v100 make run.

                                        1. 11

                                          suckless might or might not be wrong (I suspect both simultaneously, as this seems absolutely like two arguments flying past each other without even the slightest pretence of engagement one with the together), but this article doesn’t really engage with their argumentation.

                                          1. 3

                                            I have a complex backup setup for my Mac; I use Carbon Copy Cloner, Time Machine (locally), and BackBlaze. This is probably overkill, but eh. Most of the data also lives on a big ZFS pool in the basement, as well.

                                            Unlike the OP, I find deletion protection to be 100% worth it; add it to the ease of upgrading machines and I recommend everyone with a Mac grab a cheap USB drive and use it as a default, even if you don’t think you’re going to need it.

                                            1. 3

                                              This makes the oracle cli bearable

                                              1. 2

                                                I was coming in here to post exactly this.

                                              1. 19

                                                As somebody who first learned Python, and then Haskell, and then left both, this review reminds me of many of my own experiences.

                                                I was reading through some of Hillel Wayne’s blog posts, and one of them discussed the Curry-Howard correspondence, which somehow proves a 1:1 association between aspects of a mathematical proof and aspects of a type system. You can convert a proof into a type, if your type system supports it. I think Haskell’s type system respects this. I don’t think Python’s type system does.

                                                Yes, but undefined happens to be a value of every type, in Haskell; this corresponds to being able to prove any statement, including the false ones. So while it is indeed possible to turn proofs into programs, it’s not possible to turn Python or Haskell programs into useful valid proofs.

                                                (Somebody may pedantically note that every Python or Haskell program gives a proof, just not of the fact that we might hope that they prove; they usually have Python-shaped or Haskell-shaped holes in them.)

                                                I don’t think you can do anything like [fmap] with Python or any other practitioner’s language that I’m familiar with.

                                                I think that this is part of the roots of the Haskeller memetic complex. Because Haskell has the lightweight syntax of an ML, and its prelude is rich in algebraic tools, suddenly there is a blindness as to the fact that the tools have been there all along. For example, in Python 3:

                                                >>> plusOne = lambda x: x + 1
                                                >>> lmap = lambda f: lambda xs: [f(x) for x in xs]
                                                >>> nada = object()
                                                >>> mmap = lambda f: lambda x: nada if x is nada else f(x)
                                                >>> dot = lambda f: lambda g: lambda x: f(g(x))
                                                >>> zf = dot(lmap)(mmap)(plusOne)
                                                >>> zf([1, 2, 3])
                                                [2, 3, 4]
                                                >>> zf([1, nada, 3])
                                                [2, <object object at 0x7ff65c5db0d0>, 4]

                                                Even the base error type, bottom or |, is defined as an evaluation that never completes successfully, either because a computation failed, or because there’s an infinite loop. … I don’t think Python’s BaseException has a built-in notion of infinite loops evaluating to an error condition. This appears super powerful to me, because the big error type introduced by going over network connections are network timeouts, which appear to most programs as infinitely long computations.

                                                There are many opinions on this, but I am of the opinion that the sort of incompleteness generated by an unresponsive network peer, known as FLP impossibility or perhaps FLP “incompleteness” of network requests, is not the same as the incompleteness that Turing, Gödel, Tarski, Lawvere, and others showed via diagonalization. They are connected, in that the FLP result implies that a Turing machine which simulates many computers on a network may encounter a Turing-complete subproblem which prevents the simulated network peers from responding.

                                                In Alice-and-Bob framing, suppose Alice is waiting for Bob to reply over the network. The FLP impossibility of Alice having to wait forever for Bob’s reply is connected to the Turing undecidability of whether a simulation of Alice and Bob will hang forever while simulating Bob’s preparation of their reply.

                                                Haskell has Test.QuickCheck, a property-based testing framework that generates values to check a declared property. Python has hypothesis, but having used it a tiny bit for an open-source contribution, I don’t think it’s the same without the Haskell type system.

                                                I think that this is another memetic root; specifically, the root is type-driven dispatch. To compare apples to apples, a better analogue of QuickCheck in Python might be PayCheck, while Hedgehog is closer to Hypothesis in Haskell. As soon as the one-dimensional comparison becomes two-dimensional, the flexibility of Hypothesis, and crucially the ability to select arbitrary strategies for generating test cases, far outweighs the convenience of simple type-checking. This makes sense, in a certain way; if Haskell’s type system were sound in the first place, then QuickCheck would be little more than a totality checker. Hypothesis’ own author recommends Hedgehog over QuickCheck, and in my language, Monte, I implemented both a classic unit-test runner and also a Hypothesis-style property test runner.

                                                Ultimately, I don’t think [indentation] is a big issue. Haskell has code auto-formatters like haskell-formatter, much like Python’s black. Use it and move on. Bikeshed about something else, you know?

                                                Since you didn’t mention it, and none of your code samples seem to use it, and to give an example of something to bikeshed over, it’s worth pointing out that Haskell supports curly-brace-oriented syntax as well as indentation. This is a recurring topic in programming language design: We want code to be readable, and that leads to caring about whitespace.

                                                1. 8

                                                  This makes sense, in a certain way; if Haskell’s type system were sound in the first place, then QuickCheck would be little more than a totality checker.

                                                  I don’t think that follows unless you’re using incredibly specific types. There are many total functions of type Ord a => [a] -> [a], but not all of them would pass the tests of a sorting function.

                                                  1. 3

                                                    This is a fair observation. QuickCheck test selection indeed is driven not just by types, but by typeclasses and associated behaviors, and I was remiss to dismiss it so glibly.

                                                    The main desire is that one might express algebraic laws, and ultimately all of these testing tools are only approximations to actual equational reasoning. That doesn’t preclude a type system from giving useful annotations.

                                                  2. 4

                                                    Wow, amazing comment! I understand about half of this. I wish I had more than one upvote to give you.

                                                    I am really curious as to whether Python’s NoneType would map to Haskell’s bottom in that regards. Would that be the Python-shaped hole you’re talking about?

                                                    I did see a tutorial by David Beazley on implementing a lambda calculus in Python. I didn’t think it was all that practical tbh, and I think he said the same in the video: https://www.youtube.com/watch?v=pkCLMl0e_0k

                                                    Could you give a brief summary of how FLP impossibility and Turing incompleteness are different? I know of “Turing completeness” and that it’s a thing, but my knowledge ends there. I haven’t heard of FLP impossibliity before. Bookmarked that website.

                                                    Huh, the author of hypothesis says QuickCheck doesn’t have integrated shrinking. From his statement on generators rather than type classes, I understand your point on how Hedgehog and Hypothesis are more similar.

                                                    Hmm, there weren’t a whole lot of examples of curly-brace oriented syntax. Most examples used indentation. The Haskell wiki does mention it though: https://en.wikibooks.org/wiki/Haskell/Indentation#Explicit_characters_in_place_of_indentation

                                                    (I do care about whitespace and clean code; I read through “Clean Code” my second year out of college, but in my experience as a practitioner so far I’d rather use a tool and automated process to have a consistent way of doing things with multiple people, in order to spend political capital elsewhere.)

                                                    1. 10

                                                      (Phew this got long, time to turn it into a blog post ;) )

                                                      I am really curious as to whether Python’s NoneType would map to Haskell’s bottom in that regards.

                                                      It’s important to distinguish between the empty type and the unit type. In (type) theory there are no values of the empty type, and there is one value of the unit type. In a language without _|_, like Agda, we might define them something like this:

                                                      data Empty : Type
                                                      data Unit : Type where
                                                          unit : Unit

                                                      This says that Empty is a Type, that Unit is a Type, that unit is a Unit. Since we’ve given no contructors (or “introduction forms”) for Empty, there’s no way to make one. Likewise we can write function types like Int -> Empty which have no values (since there’s no way for any function to return a value of type Empty), we can write tuple types like Pair Int Empty that have no values, etc. We can also write function types like Empty -> Int which do have values (e.g. const 42), but which can never be called (since there are no Empty values to give as an argument). Incidentally, the fact that we can have types with no values is one of the reasons we can’t have a value with type forall a. a (in Haskell) or (a : Type) -> a (in Agda): they claim to return a value of any type, but we might ask for an Empty.

                                                      The unit type is trivial, literally. Since there’s only one value of this type (unit), whenever we know that a value will have type Unit we can infer that the value must be unit, and hence (a) if it’s a return value, we can always optimise the function to simply unit and (b) if it’s an argument, it has no effect on the return value (there’s nothing to branch on). In this sense, the unit type contains 0 bits of information (compared to Bool which contains 1 bit).

                                                      As an aside, Either is called a “sum type” because it contains all the values from its first argument plus those of its second: Either Unit Unit is equivalent to Bool (with values Left unit and Right unit). Pairs are called “product types” since they contain every combination of their first argument and second arguments, which is the number of values in each multiplied together. In this sense Empty acts like zero: the type Either Zero a doesn’t contain any Left values, so it’s equivalent to a, just like 0 + a = a for numbers. Likewise Pair Empty a contains no values, since there’s nothing to put in the first position, just like 0 * a = 0 for numbers. Either Unit a acts like 1 + a, since we have all of the values of a (wrapped in Right) plus the extra value Left unit; note that this is also the same as Maybe a, where Right acts like Just and Left unit acts like Nothing. Pair Unit a is the same as a since each a value can only be paired with one thing, and we know that thing is always unit; this is just like 1 * a = a with numbers.

                                                      Back to your question: things get confusing when we try to apply this to “real” languages, especially since a lot of the terminology is overloaded. In Haskell the type Unit is written () and the value unit is also written ().

                                                      In Haskell the type Empty is called Void, but that is not the same as void in languages like Java! In particular, remember that we cannot have a function which returns Empty, so void being Empty would mean we could not implement methods like public static void putStrLn(String s). Such methods certainly do exist, since they’re all over the place in Java, but what happens if we call them? They will run, and return a value back to us (hence it can’t be Empty). What is the value we get back? We know, without even running the method, that we’ll get back null. That’s just like the Unit type (where we know the value will be unit without having to run the code). Hence Java’s void acts like Unit, and null acts like unit.

                                                      If we follow a similar line of reasoning in Python, we find that None acts like unit (or Java’s null) and hence NoneType is like Unit (or Java’s void). AFAIK Python doesn’t have anything which acts like Empty (Haskell’s Void) since, lacking any values, Empty is only useful for type-level calculations (of the sort which get erased during compilation), which Python doesn’t tend to do.

                                                      That just leaves “bottom”. There are a couple of ways to think about it: we can be “fast and loose” where we ignore bottom as a nuisance, which mostly works since bottom isn’t a “proper” value: in particular, we can’t branch on it; hence any time we do a calculation involving bottoms which results in a “proper” value, we know that the bottoms were irrelevant to the result, and hence can be ignored. Any time a bottom is relevant, we have to abandon our nice, logical purity in any case, since catching them requires IO, so why bother complicating our pure logic by trying to include them?

                                                      Alternatively we can treat bottom as an extra value of every type, in a similar way to null inhabiting every type in Java. From this perspective Haskell’s Void type does contain a value (bottom), and the () type contains two values (() and bottom). In this sense we might think of Java’s void corresponding to Haskell’s Void, but I find this line of thinking difficult to justify. In particular, we can branch on null in Java (in fact we should be doing such “null checks” all the time!), whereas (pure) Haskell doesn’t even let us tell whether we have () or bottom.

                                                      As a final thought, whenever comparing dynamic and static languages, it’s important to not conflate different concepts which just-so-happen to have similar names. In particular I find it useful to think of dynamically typed languages as being “uni-typed”: that is, every value has the same type, which we might write in Haskell as a sum like data DynamicValue = S String | I Int | L List | O Object | E Exception | .... Python is actually even simpler than this, since “everything is an object” (not quite as much as in Smalltalk, but certainly more than e.g. Java), so Python values are more like a pair of a class (which itself is a Python value) and a collection of instance properties.

                                                      This is important because “dynamic types”, like in Python, aren’t directly comparable to “static types” like those of Haskell; they’re more comparable to “tags” (e.g. constructors). In particular, think about a Python function branching based on its argument’s “dynamic type”; this is the same as a Haskell function branching on its argument’s constructor. What does this tell us about “bottom” in Python? From this perspective, there isn’t one (at least not reified; an infinite loop might be comparable, but it’s not something we can e.g. assign to a variable). Python’s None is just a normal value like any other, in the same way that Haskell’s Nothing is a normal value (we might sometimes use it to stand for an error, but that’s not inherent to the system); likewise Python’s exceptions are also normal values (we can assign them to variables, return them from functions, etc.); the idea of “throwing and catching” (or raise/except for Python) is actually a perfectly normal method of control flow (it’s actually a limited form of delimited continuation), and this is orthogonal to error representation and handling.

                                                      This makes raising an exception in Python very different to triggering a bottom in Haskell, since Haskell provides no way to branch on a bottom (or whether we even have one). In Python we can raise a value (with the exception “tag”) as an alternative to using return, and we can catch those values, inspect their tag and value, etc. to determine what our overall return value will be, with none of this being visible by the caller. To do anything like that in Haskell we need some “proper” data to inspect and branch on, hence why I say None, exceptions, etc. are just normal values (even though they’re used to represent errors, and we treat them specially because of that; but the same could be said about Either String values in Haskell, for example). Consider that in Haskell the only way to even check if a bottom exists is to use IO, but the idea behind IO is that it’s like State RealWorld, i.e. every IO a value is a pair of (RealWorld, a), so conceptually we never “actually” see a bottom; it’s more like triggering a bottom changes the RealWorld, and we’re branching on that.

                                                      1. 4

                                                        Thank you for the clarification on None vs bottom! I think it definitely helps me understand how much more different Python is from Haskell.

                                                        I like the idea of saying data DynamicValue = S String | I Int | L List | O Object | E Exception for dynamic languages, and I think from a type theory perspective I finally understand what people say when they say “In {Ruby, Python}, everything is an object”.

                                                        I hate try/catch logic in Python. It works, but I much rather prefer the functorial structure espoused by Haskell.

                                                        I agree on the description on IO! The book does mention IO is technically without effects, since it is merely a description of what IO actions should be taking place instead of imperatively executing IO.

                                                        1. 4

                                                          I like the idea of saying data DynamicValue = S String | I Int | L List | O Object | E Exception for dynamic languages

                                                          That’s a good intuitive starting point, but it’s not the whole story. The “unitype framework” is a way of understanding dynamic types from a static typing perspective, but we can also start from a “dynamic typing perspective” and see where it gets us. A dynamically-typed language is one where you can manipulate type definitions at runtime, and test for type membership at runtime. So saying DynamicValue = S String | I Int ... will always be incomplete, because we might not know something’s type even after creating it!

                                                          An intuition I like here is that dynamic types are boolean predicates: x is of type T iff T(x). This means we can define the type of, say, all functions with format as an optional keyword, or the type of all iterables that aren’t strings, or the type of all types that appear as return values in functions.

                                                          (The downside of this is it gets hellishly confusing very quickly, and allows for a lot of spooky action at a distance. Also, there’s no guarantee that checking type membership is total. That’s one reason even highly dynamic languages shy away from going deep in dynamic types.)

                                                          I think from a type theory perspective I finally understand what people say when they say “In {Ruby, Python}, everything is an object”.

                                                          Everything can also be an object in a static system, too. My rule of thumb for what “everything is an object” means: are object methods also objects? Is the call stack an object? If you are using message passing, are the messages objects? Can you send messages to other messages?

                                                          1. 1

                                                            RE: “Everything is an object”, I usually put it in quotes since the meaning is usually context-dependent. A colleague once said that to me regarding Java, and I replied that Java classes aren’t objects yet Python classes are; and Python’s if branches aren’t objects yet Smalltalk’s are (at least, the closures are); and so on.

                                                            RE: Unitypes, etc. yes the static/dynamic distinction can be built up from the dynamic side too (I tend not to think that way since fixed points and things trip me up). The important thing is that people aren’t talking past each other, e.g. it’s fine to argue about whether “foo can/can’t do bar”, but not so useful when each person is using “foo” and “bar” to mean different things ;)

                                                        2. 3

                                                          The overloaded word “void” across languages is confusing. In Rust and Typescript (and others?) they called it “never”, which I think makes it really clear: values of this type never actually exist. And “this function returns never” is like a pun: “this function never returns” and “this function’s return type is ‘never’”.

                                                          1. 3

                                                            This was wonderfully clear. Thank you.

                                                      1. 1

                                                        I were to have to use a non-Mac Unix for whatever reason, I would be living on NixOS, and using it in this way. Nix is too alien on the Mac for my tastes, but it would be perfect on a less opinionated system.

                                                        1. 1

                                                          You can use home-manager that replaces homebrew. And Nix is still useful for development environments (Mac or Unix).

                                                        1. 2

                                                          I use an iPhone, last year’s big one, which is largely the default, because I do not use Google’s products/services. I’m sure Android is at least as good as iOS, but I trust Apple’s incentives, and, fundamentally, their inability to do anything in services well enough at scale to be creepy. I genuinely derive value from being trapped invested in the Apple ecosystem.

                                                          I badly wish that Microsoft hadn’t tripped all over themselves with mobile; having another vendor of phones that wasn’t Apple might lead to a mobile technology market that isn’t quite so designed to sweep up all of our data in the service of lousy contextual ads.

                                                          1. 3

                                                            It’s going to be snowy, so after shovelling, I hope to take the girls to a local park for some tobogganing. We’re hosting a few friends on Saturday night, so there will also be cleaning and party prep, and then a party, and then cleaning. I have a new Wifi mesh thing to set up at some point; I went with a mesh because we don’t really have the money to wire the house for Ubiquiti gear (yet) and our existing router is, sadly, both dying because toddlers love blinkenlights, and too underpowered to get decent speeds (we have 1.5Gb/s FTTP).

                                                            1. 2

                                                              I have Plex running on a machine in the basement, and I host my website (such as it is) on Linode. But for mail, calendaring, &c., I use Fastmail.

                                                              1. 52

                                                                nine-to-five-with-kids types

                                                                God forbid people have children and actually want to spend time with them.

                                                                As someone with kids, I’m reasonably sure I’m pretty good at what I do.

                                                                1. 40

                                                                  The second statements includes a retraction of sorts:

                                                                  P.S. I have no problem with family people, and want to retract the offhand comment I made about them. I work with many awesome colleagues who happen to have children at home. What I really meant to say is that I don’t like people who see what we do as more of a job than a passion, and it feels like we have a lot of these people these days. Maybe everyone does, though, or maybe I’m just completely wrong.

                                                                  I disagree with them that it’s wrong to see your work as a job rather than a passion; in a system where it’s expected for everyone to have a job, it’s bullshit (though very beneficial for the capitalist class) to expect everyone to be passionate about what they’re forced to do everyday. Nonetheless, the retraction in the second statement is important context.

                                                                  1. 14

                                                                    Owning stock was supposed to fix this, rewarding employees for better work towards company growth. However the employees are somehow not oblivious to the fact that their work does not affect the stock price whatsoever, instead it being dependent mostly on news cycle about the company and their C-level execs (and large defense contracts in the case of Microsoft).

                                                                    1. 7

                                                                      Your appeal to our capitalist overlords here is incorrect. It’s a symptom of capitalism that you have people at work who are just punching in and don’t have a passion for it. If we weren’t bound by a capitalist system, people would work on whatever they’re passionate about instead of worrying about bringing home the bacon to buy more bacon with. Wanting people to be passionate about their work is a decidedly anti-capitalist sentiment, and wanting people to clock in, do their job, clock out and go home to maintain their nuclear family is a pretty capitalist idea.

                                                                      1. 2

                                                                        I agree with you.

                                                                        in a system where it’s expected for everyone to have a job, it’s bullshit (though very beneficial for the capitalist class) to expect everyone to be passionate about what they’re forced to do everyday.

                                                                        That’s true I think, undoubtedly. You can “fix” it by accepting people who aren’t passionate, or by replacing the system where people need a job to survive. I’d definitely prefer to fix it by replacing the system, but in any case, blaming 9-to-5-ers is wrong - they’re victims more than anything, forced to work a job they’re not passionate about instead of going out on whatever unprofitable venture captures their heart.

                                                                        1. 1

                                                                          or by replacing the system where people need a job to survive

                                                                          How do you propose we do that, without literally enslaving people? And without causing necessary but often necessarily low-passion jobs (like sorting freight in a courier company, at 1AM - one of my jobs as teenager) to simply not get done?

                                                                          I mean, what you’re really proposing is that some people get to go on ‘whatever unprofitable venture captures their heart’ while … what? Someone else labours to pay their way?

                                                                          I personally think that it’s entirely reasonable to accept people whose passion isn’t their job, provided they’re professional and productive. There’s nothing here to fix, really, beyond rejecting the (IMO) unrealistic idea that a good employee has to be passionate about their work.

                                                                        2. 1

                                                                          Every time we’ve tried an alternative at scale it’s led to mass murder, or mass starvation, or both.

                                                                          You’re also ignoring the fact that some jobs are just plain unpleasant. I’ve worked some in my youth. It’s reasonable not to be passionate about those; they’re either high paying because they’re unpleasant but skilled, or the lowest paying job because they’re work you do because your labour isn’t valuable in any other way.

                                                                      2. 9

                                                                        As another kind of beef against that line, in my experience, people working crazy long hours on a consistent basis generally aren’t doing it out of some kind of pure passion for the project, implementing a cool amazing design, etc. They’re usually pounding out ordinary boring features and business requirements, and are working long hours because of poor project management - unrealistic promises to customers, insufficient resources, having no idea what the requirements actually are but promising a delivery date anyways, etc. IMO, anyone with any wisdom should get out of that situation, whether or not they have kids.

                                                                        Also IME, those who do have genuine passion to build some cool new thing often don’t work long hours at all, or only do so for a short time period.

                                                                        1. 7

                                                                          Someone I know could easily be working for Google or such, but he works for a smaller, non-tech, local company as a developer, so he can spend his free time building the projects he likes (or the luxury of not having to at all), instead of some absurd scale megacorp thing which will drain all the free time he has. (Or specifically, build the great thing you want to, and not be subject to what say, Facebook wants.) IMHO, it’s pretty smart…

                                                                        2. 7

                                                                          The anonymous author apologizes about this specifically in their follow-up.

                                                                          1. 4

                                                                            The apologies sound like something between a sincere apology for just blindly ranting at it all and an apology for apologies’ sake. It looks to me like the author actually feels (felt) closer to the way he described in the first message then the second. Not all the way, but somewhat.

                                                                            1. 1

                                                                              The apology is also written in an entirely different style. It’s not clear there’s strong reason to assume it’s the same person.

                                                                              edit: reading through the comments, the blog’s owner says: “I won’t reveal how the anonymous poster contacted me, but I am 99.9% sure that unless his communication channel was hacked, he is the same person.” So, ok, it’s the same person.

                                                                          2. 11

                                                                            I know what people the author means though–not all these people have kids though, they’re just the ones who punch a clock from 9-5 and want to remain comfortable and don’t want push themselves to make great things. It’s not that these people want to make bad things, or don’t want to make great things, or aren’t capable of doing great work, they just don’t receive any self-fulfillment from work. I don’t blame these people for acting this way, I’d just rather not work with them.

                                                                            The best dev on my team (by a long shot) is a 9-5 worker who never finished college, but accomplishes more in one day than most devs accomplish in a week or more. He aspires to do incredible work during his time and he exceeds every day.

                                                                            1. 9

                                                                              Once organizations get to a certain threshold of complexity, though, you need to be thinking much more about the incentives that are offered rather than the micro-level of which people want to do excellent things. You have to make it easier to do the excellent thing than not, and that can be difficult, or, in an org the size of Microsoft’s Windows kernel groups, basically, impossible.

                                                                              1. 5

                                                                                The comment was directed at the author’s “9-5 with kids” comment since the author is referring to the contributions of those people. Organizational structure produces different effects on products based on the personalities and abilities of those people within the organization.

                                                                                In general, the bigger the organizational, the less risk-tolerance, but most actions incur some sort of risk. Also, staying with the crowd and doing what you’re told is safest, so inaction or repeating previous actions often becomes the default.

                                                                                1. 2

                                                                                  Good point. It never makes sense to innovate and take risks in a large organization. If your gamble pays off, the pay off will invisibly pump up some vaguely connected numbers that will look good for some manager higher up. If it doesn’t pay off, it’s your fault. So, regardless of how good a gamble it was based on risk-reward ratio, it’s never favorable for you personally. Don’t expect your immediate superior to appreciate it either, even if the gamble pays off, because that person is also facing the same odds.

                                                                              2. 7

                                                                                As an anecdote, the eventually worst workplace I’ve been had a deeply ingrained culture of being passionate about work, and about being part of “a family” through the employer. It’s not entirely a healthy stance.

                                                                                1. 4

                                                                                  I don’t blame these people for acting this way, I’d just rather not work with them.

                                                                                  Why not?

                                                                                  You said they want to make good things, great things, and can do great work. Why does someone else’s opinion of their job matter to you?

                                                                                  1. 5

                                                                                    It’s when people’s opinions affect the work they do. My point is they can do great work, but many don’t. Sometimes it manifests as symptom fixing rather than problem solving because it’s “whatever gets me out today by X, screw consequences later.” Other times it manifests as “I wasn’t told to do this, so I won’t”. When I’ve seen it, it’s often pervasive short term thinking over long term thinking.

                                                                              1. 19

                                                                                Soundness is definitely a thing that can come up, though in handling tens of thousands of lines I don’t feel like I’ve hit it directly.

                                                                                On the other hand, Typescript’s type system is still the most useful typesystem I have ever used. The way unions, “everything is a dictionary”, being able to filter out keys and the like, and everything else work together mean that I can write business logic that handles really dynamic data shapes, and still get guarantees that are basically impossible in other languages without generating loads of wrapper types.

                                                                                For example just being able to inline declare a variable of having “type A and type B” is such a great way of allowing for new APIs.

                                                                                Ultimately Typescript not seeing typing as a mechanism for implementing the language execution semantics, but really as a checker of code validity, opened it up to really practical advantages.

                                                                                1. -2

                                                                                  On the other hand, Typescript’s type system is still the most useful typesystem I have ever used.

                                                                                  I have a canary of sorts which I use to guess whether I will appreciate a type system.

                                                                                  1 == "1"

                                                                                  The correct way to handle this is to issue a type error at compile time (or at least runtime if the language doesn’t have a significant check phase in the compiler). The two ways to fail this are:

                                                                                  • typecheck, return false (python2, python3, ruby, crystal do this)
                                                                                  • typecheck, return true (typescript, javascript, php do this)

                                                                                  I haven’t made final decisions which of these is scarier.

                                                                                  Interestingly, some of the above languages do fine if we use inequality instead:

                                                                                  1 >= "1"

                                                                                  Some languages from the top of my head that do this the way I like it: Haskell (and I assume many of the other strongly typed functional languages as well), Common Lisp (at least sbcl, dunno if it’s standard), Rust, Zig, Nim.

                                                                                  1. 9

                                                                                    To be fair you should always use === in TypeScript, then it works as expected.

                                                                                    1. 6

                                                                                      To be fair you should always use === in TypeScript

                                                                                      To be even fairer, this is not even a Typescript thing, it’s a Javascript thing? A linter on a JS project will complain about the use of ==, without going near Typescript.

                                                                                      1. 3

                                                                                        Throwing my 2-cents in here, PHP is the same. Using === will enforce type checking on the comparison.

                                                                                        1. 3

                                                                                          I don’t think it “type checks” per se in PHP, but rather avoids doing an implicit conversion.

                                                                                          1 == "1" evaluates to true, while 1 === "1" evaluates to false. It won’t error out, like a type checker will typically do for you.

                                                                                        2. 1

                                                                                          To be fairest, Typescript actually does this the way I want. See https://lobste.rs/s/qfpbk9/is_typescript_worth_it#c_hs0olb

                                                                                        3. 2

                                                                                          Does it error, or does it return false like python, ruby, crystal (and js with ===)?

                                                                                          1. 2

                                                                                            It does error at compile time.

                                                                                            1. 1

                                                                                              Yeah, seems like both == and === work as I want in Typescript. See https://lobste.rs/s/qfpbk9/is_typescript_worth_it#c_hs0olb

                                                                                              I’m liking Typescript right now.

                                                                                          2. 1

                                                                                            Ah, forgot about that. Do ts linters warn about ==?

                                                                                            1. 2

                                                                                              Yeah they do.

                                                                                          3. 2

                                                                                            I don’t understand why a typecheck of the integer numeral 1 and a string happening to contain the numeral one returning false is scary.

                                                                                            I know nearly zero about type theory. Could you please explain?

                                                                                            1. 6

                                                                                              Because it’s a category mistake – it’s a nonsensical question.

                                                                                              1. 5

                                                                                                Ah I think I see, so that’s what demands that the response be an exception rather than false.

                                                                                                It’s not just “Is a number equal to a string?” “No.” it’s “That’s not even a sensical question to ask.”

                                                                                                I guess I feel like that’s a bit counter intuitive, since I generally want boolean operators to provide answers in boolean form, but then I don’t know anything about category theory either.

                                                                                                sigh clearly I have a lot to learn :)

                                                                                                1. 9

                                                                                                  Well, it depends. Mathematically there’s nothing “wrong” with it, but it raises some uncomfortable questions. Like “what’s the domain of the == function?” Turns out, equality is not a mathematical function! If it was, everything would be in its domain, aka the forbidden Set Of All Sets. There’s a couple ways around this: the type way is to say that == is actually a collection of functions, one for each type. This ends up working out, and makes comparing different types impossible.

                                                                                                  But there are other formulations! Like there’s nothing wrong with saying int and str always compare false, you just have to be clear what your mathematical axioms are.

                                                                                                  1. 4

                                                                                                    I think it might help to look at the Haskell signature for ==:

                                                                                                    (==) :: a -> a -> Bool

                                                                                                    It makes it clear that you can only compare two values of the same type.

                                                                                                    1. 4

                                                                                                      In Lisps, you typically have = and equal?/equalp. With = you’re asking “are these two things numerically equal”, which is a nonsensical thing to ask about a string and an integer (or a vector and a list, or a character and a boolean, or two other non-number objects). With equal? you’re asking “are these two objects structurally the same thing?”, which makes sense and “false” would be the obvious answer for objects of different types.

                                                                                                      So presumably in many languages, == is the equal? in the above description, but there’s no separate = predicate.

                                                                                                      And then there’s eq?/eqp, which asks “are these things the same object?”, which is a question of identity, not equality. That’s similar to what the is operator does in Python, for example. But yeah, this stuff is confusing if you’ve only been exposed to languages that conflate these different ways of comparing because you’re not used to having to make the choice of which kind of comparison to use in different situations.

                                                                                                      1. 1

                                                                                                        so that’s what demands that the response be an exception rather than false

                                                                                                        I think no one wants it to throw an exception, but to simply not compile.

                                                                                                  2. 2

                                                                                                    1 == "1" is a classic JS gotcha (double equals is not “check for equality” but “check for equality and if it fails check for toString equality”) and 1 === "1" does what you expect.

                                                                                                    I have decently used “fancy type” languages like Haskell, Purescript and Rust. Their type systems still make me somewhat unhappy compared to TS for “enterprise apps” (the one thing that I kinda wish that TS had but would bef impossible given soundness and how stuff works is the return type polymorphism).

                                                                                                    1. 2

                                                                                                      1 == "1" is a classic JS gotcha

                                                                                                      I call it a classic maldesign, but ok :)

                                                                                                      1. 3

                                                                                                        I mean it’s not good, and there’s a reason you don’t see == anywhere in most codebases.

                                                                                                        I guess it’s just not an issue that one hits in practice if you’re an experienced practitioner (compare to…. array bounds errors that even experienced C programmers will hit often). It’s a thing you set your linter to notice, and then never do it.

                                                                                                    2. 1

                                                                                                      Couldn’t edit this any longer, so will make an errata to my comment and mark it incorrect:

                                                                                                      Contrary to what I stated, Typescript does this exactly as I think is best, i.e. signal an error at compile time.

                                                                                                      vegai@Vesas-iMac ~/tmp> cat derp.ts
                                                                                                      let derp1 = 1 == "1";
                                                                                                      let derp2 = 1 === "1";
                                                                                                      vegai@Vesas-iMac ~/tmp> tsc derp.ts
                                                                                                      derp.ts:2:13 - error TS2367: This condition will always return 'false' since the types 'number' and 'string' have no overlap.
                                                                                                      2 let derp1 = 1 == "1";
                                                                                                      derp.ts:3:13 - error TS2367: This condition will always return 'false' since the types 'number' and 'string' have no overlap.
                                                                                                      3 let derp2 = 1 === "1";
                                                                                                      Found 2 errors.

                                                                                                      Don’t even need the strict mode. So apologies to everyone for that bit of bullshitting – I went to check the behaviour in the first typescript playground I found, which for some reason did not behave like this.

                                                                                                  1. 9

                                                                                                    It depends on what you mean by “their copy of git”. As far as I’m aware, this comes in at least 2 different forms, possibly more.

                                                                                                    The backend component of the website, written in rails, most likely uses bindings for libgit2 (especially because GitHub maintains libgit2), probably rugged. Their development of libgit2 and rugged is fairly out in the open. The SSH service may use the actual git binary (or rather git-receive-pack/git-upload-pack).

                                                                                                    When I worked at Bitbucket, we used pygit2 and a small patch applied to git itself which improved NFS performance. There were a number of interesting edge cases which were tested for performance and accuracy which determined whether we’d call out to the binary with a very specific command or use pygit2, though all of that was hidden behind a wrapper library which abstracted out hg and git.

                                                                                                    It is theoretically possible to implement git-receive-pack and git-upload-pack in code rather that calling the binaries, but unless there’s a custom storage backend, this probably isn’t worth it.

                                                                                                    EDIT: the git/libgit2 patches from Bitbucket I’m aware of are listed below.

                                                                                                    1. 2

                                                                                                      unless there’s a custom storage backend

                                                                                                      I would be surprised if there wasn’t in GitHub’s case. Is there anything public about that?

                                                                                                      1. 6

                                                                                                        Not directly, but they talk about how they handle replication with distributed operations at https://github.blog/2016-09-07-building-resilience-in-spokes/. I can’t seem to find anything on routing or how they handle repo accesses though.

                                                                                                        There’s also some pretty low level stuff in https://github.blog/2015-09-22-counting-objects/ where they talk about what they did to optimize git clones for very large repos. They also mention “alternates” in passing which can be very powerful (we used these at Bitbucket for diffs - we generated the diff in a different working directory using alternates, but that’s because they use a very unique diffing algorithm).

                                                                                                        As far as I can tell, GitHub tends to do a pretty good job of upstreaming any changes they make… and these blog post seems to imply that they’re using raw git under the hood for most operations, which makes sense. If you can use the canonical implementation of something, you probably should… especially if it’s the technology on which your whole product is built.

                                                                                                        1. 7

                                                                                                          Thanks! I found it after reading your comment:

                                                                                                          I had a hard time believing they weren’t using a dfs or a specialized storage layer because I’ve worked on storage-at-scale problems before and you run into needing something fancy pretty quickly.

                                                                                                      2. 1

                                                                                                        NFS? Really?

                                                                                                        1. 1

                                                                                                          Yep, it was a Netapp storage cluster which exported NFS volumes.

                                                                                                          1. 3

                                                                                                            I still have flashbacks to that exact setup. Of course this was at Apple so we were eating our own dogfood and using OS X as a client. It was very bad. I used to regularly find bugs in the NFS stack by searching our video sources for 1k runs of 0.

                                                                                                      1. 13

                                                                                                        Even experts don’t know everything. This seems to me like relying on Actor X to talk to you about random subject Y, instead of a subject matter expert on subject Y.

                                                                                                        That said, I don’t blame him for being so cautious about integrating ZFS into the Linux kernel all proper like. Oracle’s past history has shown they are very eager to do everything possible to try and make a buck. But ZFS was released publicly before Oracle bought it, so they would have to do a lot of magic legal loopholes to get around the license Sun released ZFS under, before Oracle bought Sun.

                                                                                                        ZFS is awesome, well maintained and supported, and, from my perspective very much part of the boring technologies one should definitely explore for use in your stack(s). Also except for FAT32, I think it’s the only filesystem that has implementations across all the major OS’s (windows, macOS, linux, BSD, UNIX, etc)

                                                                                                        1. 22

                                                                                                          But ZFS was released publicly before Oracle bought it, so they would have to do a lot of magic legal loopholes to get around the license Sun released ZFS under, before Oracle bought Sun.

                                                                                                          so was the jdk, but that has never stopped oracle as far as I understand it

                                                                                                          1. 4

                                                                                                            Agreed. I totally get not wanting to merge the GPL’d Kernel with ZFS’s unique license, based on Oracle’s past behaviour…

                                                                                                            1. 4

                                                                                                              so was the jdk, but that has never stopped oracle as far as I understand it

                                                                                                              That’s actually a really great non ZFS example: Oracle got all stupid with the JDK, trying to charge for it, so the community forked OpenJDK totally free of Oracle’s ‘stewardship’ and it’s been going gangbusters ever since.

                                                                                                              1. 3

                                                                                                                That’s an oversimplification, OpenJDK still is developed primarily by Oracle employees and existed before Oracle bought Sun. The only thing that changed is that previously it was a bad idea to use the official JDK over OpenJDK and now it’s a disastrously bad idea.

                                                                                                                1. 2

                                                                                                                  Quite right.

                                                                                                                  So the risk now is that Oracle might de-fund OpenJDK development.

                                                                                                                  Given the VAST amount of critical infrastructure built atop the Java ecosystem that still exists, I’ll bet you dollars for donuts that the community would LEAP to the rescue if that happened.

                                                                                                                  Everybody likes to slag Java, but most of those same people would be UTTERLY SHOCKED at how much of what they love is built on that ecosystem.

                                                                                                            2. 6

                                                                                                              I’m reading this as do not use ZFS on Linux both for technical and legal reasons. I totally agree with Linus on that, I’m using XFS which happens to be the CentOS default ;-) Using ZFS might be totally fine on FreeBSD though, don’t know, but hear good stories about it!

                                                                                                              1. 12

                                                                                                                well, zfs on freebsd now uses zfs on linux, so i’m not really sure where the “unmaintained” part comes from. i’m using zfs on linux for quite a while now as data-dump, and it is really solid and easy to use.

                                                                                                                my favourite example: when you have a disk which has problems but isn’t dead yet, you can add a new drive, resilver and then unplug the failing drive. no need to run with a missing drive. this is one command, quoting the manpage:

                                                                                                                zpool replace [-f] pool old_device [new_device]

                                                                                                                Replaces old_device with new_device. This is equivalent to attaching new_device, waiting for it to resilver, and then detaching old_device.

                                                                                                                regarding “buzzword”: there are no equivalent options for linux imho, btrfs isn’t there and won’t be for a long time, if ever. xfs is ok, but has a completely different scope, being “just” a filesystem. zfs replaces the whole lvm+mdraid stack, and wraps it into usable tools without that many footguns.

                                                                                                                the amount of fud spread concerning zfs is really amazing. i’m a bit sad that linus apparently buys into it, i understand the fear about oracle licensing fsckups, though.

                                                                                                                1. 3

                                                                                                                  zfs replaces the whole lvm+mdraid stack

                                                                                                                  Along with cryptsetup.

                                                                                                                  1. 1

                                                                                                                    Yes, forgot that :)

                                                                                                                2. 6

                                                                                                                  I read that is Linus’s perspective, but I(and many others) have a different perspective. I don’t see any technical reason to not use ZFS on Linux, it’s well-maintained, stable and pretty much boring tech these days.

                                                                                                                3. 5

                                                                                                                  I don’t blame him neither - there must have been a (legal) reason for Apple dropping it and coming out with APFS. Nonetheless it’s quite a strong opinion from someone who never used it.

                                                                                                                  1. 8

                                                                                                                    ZFS had a lot of baggage that they didn’t want because they’d never expose it to the users anyway. And it wouldn’t have scaled to work on devices like the Apple Watch because of the ARC.

                                                                                                                    1. 1

                                                                                                                      Apple has implemented ZFS on Mac OS X. I don’t remember exactly whether it made to a public beta, or just it was leaked it exists, but apparently at some point Apple has decided they want ZFS, they just never shipped it to users.

                                                                                                                      1. 2

                                                                                                                        Yes, it was a thing when I was there the first time; but the word on the street was that licensing issues basically killed it, and it was never a good fit for Apple’s primary use case for a file system.

                                                                                                                        1. 1

                                                                                                                          I think the problem was that NetApp sued Sun over alleged violation of their patents by ZFS:

                                                                                                                          In the meantime, Sun and NetApp had been locked in a lawsuit over ZFS and other storage technologies since mid-2007. While Jonathan Schwartz had blogged about protecting Apple and its users (as well as Sun customers, of course), this likely led to further uncertainly. On top of that, filesystem transitions are far from simple. When Apple included DTrace in Mac OS X, a point in favor was that DTrace could be yanked out should any sort of legal issue arise. But once user data hit ZFS, it would take years to fully reverse the decision. While the NetApp lawsuit never seemed to have merit (ZFS uses unique and from-scratch mechanisms for snapshots), it indisputably represented risk for Apple.


                                                                                                                        2. 1

                                                                                                                          Yes I still have a copy of the beta where they included ZFS support.

                                                                                                                          You can still have ZFS on MacOS, just not for your /

                                                                                                                      2. 3

                                                                                                                        Apple dropping it and coming out with APFS

                                                                                                                        AFAIK (and I am no expert) ZFS has little to absolutely no-sense on home devices which Apple is offering. ZFS is meant for servers mostly. In that case APFS makes more sense in this case.

                                                                                                                        1. 2

                                                                                                                          ZFS would make sense on macOS, but agreed, ZFS makes some (but little) sense on ipadOS and zero sense on watchOS. ZFS is most comfortable with ~ 1GB(or more) of ram to itself, which is hard to come by on the smaller devices.

                                                                                                                      3. 3

                                                                                                                        “so they would have to do a lot of magic legal loopholes to get around the license Sun released ZFS under, before Oracle bought Sun.”

                                                                                                                        Them making API’s copywritten was such a magic loophole that I started recommending against depending on anything owned by a company that does patent suits. Those less-popular, foundation-run languages, OS’s, etc suddenly look worth the extra effort.

                                                                                                                        1. 3

                                                                                                                          Agreed on it being a major magic loophole. That’s not quite resolved yet, the supreme court hasn’t ruled. It will be very, very interesting to see what side the supreme court comes down on. Hopefully against Oracle, but who knows.

                                                                                                                          ZFS is an interesting case, because basically everyone that worked on ZFS @ Sun now plays with the OpenZFS version, which is under the Sun license(CDDL), and can’t get back into Oracle’s version(since they closed-source their version) so there are 2 totally different versions of ZFS that are only compatible if you work at it. The ZFS everyone uses, and the ZFS Oracle supports, that nobody uses(again unless they have to for non-technical reasons). The Oracle version doesn’t offer any of the good bits that the OpenZFS version has, like encrypted data, multi-platform support, etc, etc.

                                                                                                                          I also agree on your recommendations. Suddenly the BSD’s are looking better and better every day :)

                                                                                                                          OpenJDK is pretty much the default Java these days isn’t it? I don’t think anyone in server land is actively installing Oracle’s java anymore, unless they have to(for generally non-technical reasons).

                                                                                                                          1. 3

                                                                                                                            Them making API’s copywritten was such a magic loophole that I started recommending against depending on anything owned by a company that does patent suits.

                                                                                                                            IANAL, but I think the problem for Oracle would, in this case, be that they themselves (actually Sun) released ZFS under an open source license, plus that the CDDL includes a patent grant. This is different from the Java case, because Google did not use OpenJDK, but based their implementation on Apache Harmony. If APIs are copyrightable, then you’d think that Sun releasing OpenJDK as GPL would at least license use of the API in that implementation (and in this case ZFS).

                                                                                                                            Of course, they could sue ZoL for infringements of patents in newly-added code. But then they could probably sue developers of other filesystems with those patents as well.

                                                                                                                          2. 2

                                                                                                                            Oh I totally get it. I think his stance makes a lot of sense, but it will be interesting to see how or if things change when Ubuntu makes ZFS mainstream.

                                                                                                                            It’s already available as a checkbox in the 20.04 installer, and I suspect as later releases happen it will become the default.

                                                                                                                          1. 2

                                                                                                                            First trip to IKEA in many years, buying some furniture. Not sure if this is worse than what comes after the buying :P

                                                                                                                            1. 2

                                                                                                                              Every time I go to IKEA I swear never to go to IKEA again. And yet.

                                                                                                                              1. 2

                                                                                                                                2h in there (barely ok), then carrying 100kg of stuff (one cupboard) from car to door, then 4h of building.. visiting wasn’t actually the worst part :P

                                                                                                                            1. 1

                                                                                                                              I mean, USB is a tire fire, that’s not news. But this is not a useful addition to the indictment, really.

                                                                                                                              1. 4

                                                                                                                                Would you prefer to choose over a million custom implementations of a serial port, all proprietary of course, instead?

                                                                                                                                1. 1

                                                                                                                                  I mean, USB is a tire fire, that’s not news.

                                                                                                                                  Yes across the board. My Pixel 3’s USB C port only works right when the cable is inserted “upside down” and there is no such thing for USB C as the intent is for it to be bidirectional.

                                                                                                                                  1. 7

                                                                                                                                    I own a Pixel 3 and it works fine both ways. Either your phone is a dud, or your cable is.

                                                                                                                                1. 2

                                                                                                                                  I just do this with Fastmail; I have my own domains, and I use a separate email address for everything. However, I also use 1Password, and so it’s very little additional administrative burden.

                                                                                                                                  1. 29

                                                                                                                                    I worked at large companies with user-facing products similar to what the author referenced - not Apple, but Skype, Microsoft and Uber. I worked or observed the team closely on OSes like XBox One and Windows 8, similar to the MacOs example. I think the example is overly dramatic.

                                                                                                                                    In software - especially with BigTechCo - the goal is not to ship bug-free software. It’s to ship software that supports the business goal. Typically this means gaining new customers and reducing user churn. Ultimately, the end goal of publicly traded companies is to provide shareholders value. And Apple is dam good at this, generating $50B in profit on $240B in revenues per year.

                                                                                                                                    All the examples in this blog post are ones that won’t result in user churn. The Catalina music app having a buggy section? Big deal, it will be fixed in the next update. The Amazon checkbox issue? Same thing: it will be prioritised and fixed sometime. They are all side-features with low impact. The team might have known about it already. Or - more likely - this team did not spend budget on thorough testing, as what they were building isn’t as critical as some other features.

                                                                                                                                    The Skype app was full of smaller bugs like this: yet it dominated the market for a long time. When it failed, it was not for this. Catalina likely spent resources on making sure booting was under a given treshold and updates worked flawless. Things that - if they go wrong - could lead to loss of customers, gaining fewer new ones. So things that would directly impact revenue.

                                                                                                                                    Finally, a (very incorrect) fact:

                                                                                                                                    Lack of resources? This is Apple, a company that could’ve hired anyone in the world. There are probably more people working on Music player than on the entire Spotify business. Didn’t help.

                                                                                                                                    This is plain false and very naive thinking. Teams are small at Apple and the music player team for Catalina is likely 10-15 people or less, based on my experience. While Apple could hire an army for an app like this, then they would not be the $1T company they are today. They have that valuation because they are very good at consistently generating high profits: for every $10 of revenue, they generate $2 of profit. They hire the number of people needed to make a good enough product and don’t spend money just because they have it.

                                                                                                                                    What did change is Apple used to have a huge budget for manual testers: it was insane, compared to other companies. Due to rationalising - publicly traded company et al - the testing department is likely smaller for non-critical apps. Which puts them in-line or slightly above with the rest of their competitors.

                                                                                                                                    I am not saying that bugs in software are great. But consumer-facing software development is more about iteration, speed and launching something good enough, than it is about perfection. It’s what makes economic sense. For other industries, like air travel or space, correctness is far more important, and it comes at the expense of speed and iteration.

                                                                                                                                    It’s all trade-offs.

                                                                                                                                    1. 12

                                                                                                                                      It’s to ship software that supports the business goal.

                                                                                                                                      This is really the fundamental miss of the author. Author doesn’t understand that (1) crap happens and (2) the level of quality required for a satisficed user is lower than he thinks.

                                                                                                                                      Teams are small at Apple and the music player team for Catalina is likely 10-15 people or less, based on my experience.

                                                                                                                                      Also, I can’t lay my head on a citation, but I think that it’s been studied that smaller teams produce better quality software (up to a point, ofc).

                                                                                                                                      1. 3

                                                                                                                                        All the examples in this blog post are ones that won’t result in user churn. The Catalina music app having a buggy section? Big deal, it will be fixed in the next update. The Amazon checkbox issue? Same thing: it will be prioritised and fixed sometime. They are all side-features with low impact. The team might have known about it already. Or - more likely - this team did not spend budget on thorough testing, as what they were building isn’t as critical as some other features.

                                                                                                                                        The inability to open the iTunes Store might be bad for sales, so they’ll probably want to fix that one. But yes, as long as the basic features are working, these bugs are fine, on some level. This is how it is.

                                                                                                                                        I think he is trying to highlight something on a more fundamental level: it should not be so easy to write these kinds of bugs. The developers should have to go out of their way to write them. But with the tools they have been given, it seems they have to work very hard to avoid writing bugs. It is like they have been given hammers that by their nature have a tendency towards hitting thumbs and sometimes manage to hit both your thumbs at the same time.

                                                                                                                                        Let’s turn it around. Suppose software had a fundamentally good and auspicious nature. Suppose also that your product owner was a tricky fellow who wanted to add some bugs in your program. He comes up with a user story: as a user, sometimes I want to have an item be selected, but not highlighted, so as to further my confusion. I think the result of this would be a commit with some kind of conditional statement, table-driven code or perhaps an extra attribute on the list items that activates the bug path. The point being that you would need to add something to make it buggy. With the tools the Catalina music app team had, they very likely did not have to add anything at all to get those bugs.

                                                                                                                                        The instances of bugs he brings up suggests to me that the tools involved were not used for their intended purpose. They were used to create simulacrum software. The Amazon checkboxes probably get their state from a distributed system where they “forgot” to handle multiple pending state changes. They could instead have used a design where this would never be an issue at all. If it had been designed properly, they would indeed have needed to add code to get it that buggy. And the buggy list items are probably not even in lists, but merely happen to sometimes visually resemble lists. And so on.

                                                                                                                                        It is not good that this sort of thing happens regularly. One example from my own experience: the Swedish Civil Contingencies Agency (MSB) has an app that alerts you to important events. I cannot count how many times it has lost its settings and has defaulted to alerting about everything that happens everywhere. I have uninstalled that app. When the war arrives, I’ll be the last one to know.

                                                                                                                                        1. 4

                                                                                                                                          Teams are small at Apple and the music player team for Catalina is likely 10-15 people or less, based on my experience.

                                                                                                                                          Yes, this accords with my experience. I would be surprised if it were that many people; the number of people who were working on the iTunes client was shockingly small, and they’d never grow the team just for Music.

                                                                                                                                          1. 3

                                                                                                                                            Based on my experience at Apple, I’d be surprised if the Music app was an actual team. Much more likely it was a few folks from another team that was tasked with creating it as a part-time project and wasn’t their primary project. Or, it could’ve been 2 folks who were fairly junior and tasked with writing it with occasional assistance.

                                                                                                                                            In my experience teams and projects were sorely understaffed and underfunded (unless it was wasteful projects like the doomed self-driving car, in which case they were showered with far too much money and people). It was just shocking to work at a company that had so much excess cash and couldn’t “afford” to add people to projects that could really use them.

                                                                                                                                          2. 2

                                                                                                                                            All the examples in this blog post are ones that won’t result in user churn. The Catalina music app having a buggy section? Big deal, it will be fixed in the next update. The Amazon checkbox issue? Same thing: it will be prioritised and fixed sometime. They are all side-features with low impact. The team might have known about it already. Or - more likely - this team did not spend budget on thorough testing, as what they were building isn’t as critical as some other features.

                                                                                                                                            One bug like this would not make me “churn”, but two or three would. I no longer use Chrome, nor iTunes, nor iOS, because of exactly this type of drop in quality. I no longer even bother with new Google products, because I know that they’re more likely than not to be discontinued and dropped without support. I no longer consider Windows because of all the dark patterns.

                                                                                                                                            I am on the bleeding edge relative to less techical users, but I am also a lazy software dev, meaning I hate tinkering just to make something work. I’ll probably go with GNU for my next computer. And a year or two later, I bet so will my neighbor who just uses email and my friend who just needs to edit photos and my other friend who just writes papers.

                                                                                                                                            1. 7

                                                                                                                                              I no longer use Chrome, nor iTunes, nor iOS, because of exactly this type of drop in quality . . . I hate tinkering just to make something work.

                                                                                                                                              I’ll probably go with GNU for my next computer.


                                                                                                                                              1. 1

                                                                                                                                                Not sure if you intended for that to show up as “missing Unicode glyph”, but it works.

                                                                                                                                                You’ve got a point there.

                                                                                                                                                Until now, I have been using macOS for the hardware support, a few niche apps for stuff like playing music, and a GNU VM (Fedora LXDE) for dev which has proven to be a low-maintenance setup all around.

                                                                                                                                                1. 2

                                                                                                                                                  The “missing Unicode glyph” is the Face with one eyebrow raised emoji and shows up for me using Chrome on iOS and Windows.

                                                                                                                                                  1. 2

                                                                                                                                                    And FF on Android