1. 3

    This is quite timely. I am going through the process for switching doctors, and I needed to get my records from my previous office transferred. For $reasons, I had to do this myself instead of the typical thing, which I think, is where the offices communicate with each other and sort things out. Going through the process myself was horrifying, on a couple levels:

    1. The only two options available to me were postal mail or fax (just as this talk points out). I could not ask someone. I could not come in person and request it. Snail mail or fax.
    2. The only information I needed to provide was a name, a student ID number (this office was at my alma mater), date of birth, the place to send the docs (another fax number) and a signature.

    Other than the fact that such antiquated technology is still being used, I cannot believe that anyone can access my medical records so long as they have my name, student ID number and date of birth. My student ID number isn’t exactly a secret. Not only was it on my ID card, but I searched my email for the ID number, and it’s plastered across all sorts of different types of communication with my school. So… tons of people have it.

    I guess this is probably a similar situation as with one’s SSN, but man, it sure feels like anyone could have just requested my medical records with relative ease. The medical record request form felt more like CYA than an actual guard against someone snooping.


    With my tangential rant out of the way, I did watch the entire talk, and it was worth it. The demo at the end was way cool.

    1. 4

      On a similarly tangentially-related note, the title reminds me of an anecdote (I think) was in one of David Crystal’s linguistics textbooks:

      On a Monday morning the judge said in court “I’m afraid we’ll have to adjourn this case, I have written my judgement out, but I left it in my cottage in Devon and I can’t get it sent here until tomorrow.” “Fax it up my Lord,” the helpful barrister suggested, to which his Lordship replied, “Yes, it does rather.”

    1. 17

      Suggesting that people “get involved” more with the FOSS they use is great, but this blog post comes across really immature, in my opinion. It may do more harm than good, making FOSS types seem childish.

      1. 8

        Exactly. I appreciate that the author is trying to bring attention to the problem. Best route is to present it in a mature, respectable way that average consumer and business person will share with their friends. Most won’t share this. A number will even have filters blocking them from seeing it at work.

        An alternative style that did get a lot of traction was Nadia Eghbal’s article. I suggest chaica do one more like that if aiming to maximize sharing and contributions.

        1. 7

          There is a particular brand of FOSS developer who thinks that because they are donating their free time in support of some project or another, that anyone who uses their software but contributes back nothing is some kind of freeloader. I didn’t even read the whole thing because of all the holier-than-thou and meme gifs but that’s how the author of this article comes across to me. I’m sorry, but just because you put something some code on the internet doesn’t mean the users of the code owe you anything. (Or at least, anything that isn’t already spelled out clearly in the license.)

          1. 1

            I’m sorry, but just because you put something some code on the internet doesn’t mean the users of the code owe you anything

            Legally? No. Morally? Yes. Then you can convince yourself otherwise to cope with the inevitable guilt you will have by being a freeloader, but FOSS is a community and communities are built on exchange and sharing. If you want to get the fruits of their work without participating in the community you’re allowed to, because using code doesn’t cost anything, but you’re still morally in debt to a certain degree.

            1. 8

              I guess we disagree then. Personally, I expect zero return for anything I put on the Internet. Not because I think my efforts are valueless but because the value was derived from the making of the thing in the first place and, perhaps secondarily, sharing it with others. If someone wants to contribute back in some way, that’s absolutely great, but the blatant expectation that they should is just too close to unjustified entitlement for my taste.

              And then there’s just the sheer logistical problem of such an idea as well. If you took all of the different open source projects that I used to get my work done today alone, they would number in the thousands, easily. It would take me at least a lifetime to make a meaningful contribution to every single one of those just to repay my one day of work.

              1. 1

                But you don’t have to contribute to each one of them. The nature of contribution is not transactional in nature. Since it’s a community, in theory, giving back to a single FOSS project is like contributing to each one of them. You participate as an individual but the effort is collective and you shouldn’t think about this matter as a material transaction between you and the maintainer of each one of the projects you use: “I give you 20 mins of my time and 5 dollars in donations in exchange for 5000 lines of your good code” I mean, you can, but the spirit of most of the people involved in this thing is different.

                Also the way you speak about your own code shows that probably you don’t feel part of the community and so you can’t understand the behavior of others and you call entitlement. Just because you publish stuff on the internet with this attitude doesn’t mean that others do the same. You participate in this as an individual, others don’t.

                1. 3

                  I am part of an open source community and my feelings are far closer to @bityard’s than what’s described in the OP. Entitlement comes in many shapes and sizes, and some form of it is definitely on display in the OP.

                  1. 1

                    Then what’s your idea of community? I mean, in general, not in Open Source.

                    1. 2

                      My idea of what a community is is irrelevant. You just got done telling someone else they “didn’t understand” because they weren’t part of one. What I’m telling you is a fact: I am part of one and I see things very similarly to @bityard, so your model of what kinds of things people do or don’t understand needs revision.

                      I am mostly trying to dodge your question, mostly because I don’t think it’s a productive use of my time and also because both the question and its answer will inevitably be incredibly vague, nuanced and difficult to express in a Lobsters comment.

                      1. 0

                        If you don’t want to have a discussion is fine, even though Lobste.rs comments are supposed to support a discussion.

                        because both the question and its answer will inevitably be incredibly vague, nuanced and difficult to express

                        There are things that cannot be dealt with in an analytical and dry approach. Vagueness (as intended by STEM people), subjectivity and communication issues are a necessary tradeoff to investigate matters that are complicated.

                        1. 1

                          Your condescension is enough of a reason not to want to talk to you. Just because I don’t want to have a very vague discussion doesn’t mean I think vagaries are themselves unnecessary.

                          1. 0

                            Then don’t use it as an accusation next time.

                            1. 1

                              I didn’t.

          2. 3

            I don’t think so. The message is simple and straight. It resonates with those people that can understand life beyond consumption and maybe suggest a non-consumeristic, non-capitalistic mode of interaction to some others that are inclined to receive the message. Why is it childish? Because it tells you you shouldn’t be a consumer? That’s not childish at all. It requires a lot of effort to escape consumerist-logic, since it’s what you have learnt in school, from your parents, from media and it’s considered the standard way of living.

            1. 1

              making FOSS types seem childish.

              Could you elaborate on this one?

              1. 0

                Maybe he’s talking about being overly idealistic? The Stallman-esque era of open source in the late 90s/early 2000s had us believe that one day Gimp would surpass Photoshop, and that we’d go into coffee shops and casually observe Linux netbooks.

                For a number of reasons that never happened. I wrote a post about it a while back:

                https://penguindreams.org/blog/the-philosophy-of-open-source-in-community-and-enterprise-software/

                1. 4

                  I note that we go into coffee shops and do observe Android phones.

              2. 1

                Agreed. The large majority of volunteering work is thankless work. Sadly, a lot of people are more likely to thank you when they are paying for your work. Yet, throwing a tantrum is counterproductive indeed.

              1. 19

                I write about one post per year, because it’s a lot of work. I tend to write about specific projects or problems I’m working on.

                https://blog.burntsushi.net

                1. 3

                  Everytime I see a post for Nim I am hoping for a Golang competitor that can actually bring something new to the table. But then I look at the library support and community and walk back disappointed. I am still hoping for nim to take off and attract Python enthusiasts like me to a really fast compiled language.

                  1. 11

                    But then I look at the library support and community and walk back disappointed.

                    It’s very hard to get the same momentum that Go achieved, just by the sheer fact that it is supported and marketed by Google. All I can say is: please consider helping Nim grow its community and library support, if everyone sees a language like Nim and gives up because the community is small then all new mainstream languages will be owned by large corporations like Google and Apple. Do you really want to live in a world like that? :)

                    1. 3
                      1. 1

                        Have tried it; GC is way to optimistic so under high loads you would see memory being wasted. I love the syntax and power of language but it still stands shy when you can’t compile single binary (like golang) and end up with weird cross compile issues. Nim is way more efficient in terms of memory and GC overhead.

                        1. 1

                          Cannot compile single binary? What do you mean by that?

                          1. 1

                            Let me rephrase; binary is not standalone with everything static linked (LibSSL and some dependencies). I had to recompile my binaries on server to satisfy the dynamic linked libraries with particular version.

                            1. 5

                              I think that’s more a result of Go having the manpower to develop and maintain an SSL library written in Go. As far as I understand, if you were to write an SSL library in 100% Crystal you wouldn’t have this problem.

                              By the way, Nim goes a step further. Because it compiles to C you can actually statically embed C libraries in your binary. Neither Go nor Crystal can do this as far as I know and it’s an awesome feature.

                              1. 3

                                Is there a distinction between “statically embed C libraries in your binary” and “statically link with C libraries”? Go absolutely can statically link with C libraries. IIRC, Go will still want to link with libc on Linux if you’re using cgo, but it’s possible to coerce Go into producing a full static executable—while statically linking with C code—using something like go install -ldflags "-linkmode external -extldflags -static".

                                1. 2

                                  There is a difference. Statically linking with C libraries requires a specially built version of that library: usually in the form of a .a or .lib file.

                                  In my experience, there are many libraries out there which are incredibly difficult to statically link with, this is especially the case on Windows. In most cases it’s difficult to find a version of the library that is statically linkable.

                                  What I mean by “statically embed C libraries in your binary” is: you simply compile your program’s C sources together with the C sources of all the libraries you depend on.

                                  As far as Go is concerned, I was under the impression that when you’re creating a wrapper for a C library in Go, you are effectively dynamically linking with that library. It seems to me that what you propose as a workaround for this is pretty much how you would statically compile a C program, i.e. just a case of specifying the right flags and making sure all the static libs are installed and configured properly.

                              2. 2

                                I suppose you built with --static?

                                1. 2

                                  You have to jump through quite a few hoops to get dynamic linking in go.

                                  By default it statically links everything, doesn’t have a libc, etc.

                                2. 1

                                  It’s not uncommon or difficult in go to compile a webapp binary that bakes all assets (templates, images, etc) into the binary along with a webserver, HTTPS implementation (including provisioning its own certs via ACME / letsencrypt), etc.

                                  1. 1

                                    only have a passing familiarity with go’s tooling, how do you bake in assets?

                                    1. 1

                                      There are different approaches, https://github.com/GeertJohan/go.rice for example supports 3 of them (see “tool usage”)

                                3. 1

                                  I think he mentions the ability to statically build [1] binaries in Golang. I’d note that this is a feature that is not so common and hard to achieve. You can do this with C/C++ (maybe Rust), but it has some limits, and it’s hard to achieve with big libraries. Not having statically built binaries often means that you need a strong sense of what you need and to what point or using good packaging/distribution workflows (fpm/docker/…).

                                  It’s a super nice feature when distributing software (for example tooling) to the public, so it feels like “here you are your binary, you just have to use it”.

                                  [1] https://en.wikipedia.org/wiki/Static_build

                            2. 1

                              The “programming by duct taping 30 pip packages together” method of development is pretty new, and it isn’t the only way to program. Instead, you grow the dependencies you need as you build your app, and contribute them back once they’re mature enough.

                              More time consuming, but you have total control.

                            1. 22

                              After writing Go for 5 years, I’d recommend Rust for C developers. It’s more complicated than Go for sure, but also has more to offer. The lack of garbage collection and support of generics are definitely a plus compared to Go.

                              Go is a better language for junior devs, but I wouldn’t call C programmers junior. They should be able to digest Rust’s complexity.

                              1. 9

                                They should be able to digest Rust’s complexity.

                                Non trivial amount of C programmers are still doing C to avoid additional complexity. Not everyone wants a kitchen & sink programming language.

                                1. 6

                                  Rust can definitely get overly complex if the developers show no constraint (i.e. type golf), but the control afforded by manual memory management makes up for it, IMHO. Unless it’s a one-run project, performance will eventually matter, and fixing bad allocation practices after the fact is a lot harder than doing it right from the beginning.

                                  1. 1

                                    Couldn’t they just start with a C-like subset of Rust adding from there to their arsenal what extra features they like? It’s what I was going to recommend to those trying it for safety-critical use since they likely know C.

                                    1. 9

                                      I think it’s rather difficult to write rust in a C like manner. This contrasts with go, where you can basically write C code and move the type declarations around and end up with somewhat unidiomatic but working go.

                                      1. 3

                                        I think C++ as a better C works because you still have libc besides the STL, etc. The Rust standard library uses generics, traits, etc. quite heavily and type parameters and lifetime parameters tend to percolate to downstream users.

                                        Though I think a lot of value in Rust is in concepts that may initially add some complexity, such the borrow checker rules.

                                        1. 3

                                          The problem with C++ is its complexity at the language level. I have little hope of teams of people porting various tools for static analysis, verification, and refactoring to it that C and Java already have. Certifying compilers either. C itself is a rough language but smaller. The massive bandwagon behind it caused lots of tooling to be built, esp FOSS. So, I now push for low-level stuff either safer C or something that ties into C’s ecosystem.

                                        2. 4

                                          You could argue the same for C++ (start with C and add extra features). Complexity comes with the whole ecosystem from platform support (OS, arch), compiler complexity (and hence subtle difference in feature implementations) to the language itself (C++ templates, rust macros). It’s challenging to limit oneself to a very specific subset on a single person project, it’s exponentially harder for larger teams to agree on a subset and adhere to it. I guess I just want a safer C not a new C++ replacement which seems to be the target for newer languages (like D & Rust).

                                          1. 4

                                            It’s challenging to limit oneself to a very specific subset on a single person project, it’s exponentially harder for larger teams to agree on a subset and adhere to it.

                                            I see your overall point. It could be tricky. It would probably stay niche. I will note that, in the C and Java worlds, there’s tools that check source code for compliance with coding standards. That could work for a Rust subset as well.

                                            “I guess I just want a safer C not a new C++ replacement which seems to be the target for newer languages (like D & Rust).”

                                            I can’t remember if I asked you what you thought about Cyclone. So, I’m curious about that plus what you or other C programmers would change about such a proposal.

                                            I was thinking something like it with Rust’s affine types and/or reference counting when borrow-checking sucks too much with performance acceptable. Also, unsafe stuff if necessary with the module prefixed with that like Wirth would do. Some kind of module system or linking types to avoid linker errors, too. Seemless use of existing C libraries. Then, an interpreter or REPL for the productivity boost. Extracts to C to use its optimizing and certifying compilers. I’m unsure of what I’d default with on error handling and concurrency. First round at error handling might be error codes since I saw a design for statically checking their correct usage.

                                            1. 3

                                              I can’t remember if I asked you what you thought about Cyclone. So, I’m curious about that plus what you or other C programmers would change about such a proposal.

                                              I looked at it in the past and it felt like a language built on top of C similar to what a checker tool with annotations would do. It felt geared too much towards research versus use and the site itself states:

                                              Cyclone is no longer supported; the core research project has finished and the developers have moved on to other things. (Several of Cyclone’s ideas have made their way into Rust.) Cyclone’s code can be made to work with some effort, but it will not build out of the box on modern (64 bit) platforms).

                                              However if I had to change Cyclone I would at least drop exceptions from it.

                                              I am keeping an eye on zig and that’s closest to how I imagine a potentially successful C replacement - assuming it takes up enough community drive and gets some people developing interesting software with it.

                                              That’s something Go had nailed down really well. The whole standard library (especially their crypto and http libs) being implemented from scratch in Go instead of being bindings were a strong value signal.

                                              1. 2

                                                re dropping exceptions. Dropping exceptions makes sense. Is there another way of error handling that’s safer or better than C’s that you think might be adoptable in a new, C-like language?

                                                re Zig. It’s an interesting language. I’m watching it at a distance for ideas.

                                                re standard library of X in X. Yeah, I agree. I’ve been noticing that pattern with Myrddin, too. They’ve been doing a lot within the language despite how new it is.

                                                1. 4

                                                  Dropping exceptions makes sense. Is there another way of error handling that’s safer or better than C’s that you think might be adoptable in a new, C-like language?

                                                  Yes, I think Zig actually does that pretty well: https://andrewkelley.me/post/intro-to-zig.html#error-type

                                                  edit: snippet from the zig homepage:

                                                  A fresh take on error handling that resembles what well-written C error handling looks like, minus the boilerplate and verbosity.

                                                  1. 2

                                                    Thanks for the link and tips!

                                      2. 7

                                        Short build/edit/run cycles are appreciated by junior and senior developers alike. Go currently has superior compilation times.

                                        1. 10

                                          Junior and senior developers also enjoy language features such as map, reduce, filter, and generics. Not to mention deterministic memory allocation, soft realtime, forced error checking, zero-cost abstractions, and (of course) memory safety.

                                          1. 3

                                            Junior and senior developers also enjoy language features such as map, reduce, filter, and generics.

                                            Those are great!

                                            deterministic memory allocation, soft realtime, forced error checking, zero-cost abstractions, and (of course) memory safety.

                                            Where are you finding juniors who care about this stuff? (no, really - I would like to know what kind of education got them there).

                                            1. 8

                                              I cared about those things, as a junior. I am not sure why juniors wouldn’t care, although I suppose it depends on what kind of software they’re interested in writing. It’s hard to get away with not caring, for a lot of things. Regarding education, I am self-taught, FWIW.

                                            2. 1

                                              Map, reduce and filter are easily implemented in Go. Managing memory manually, while keeping the GC running, is fully possible. Turning off the GC is also possible. Soft realtime is achievable, depending on your definition of soft realtime.

                                              1. 1

                                                Map, reduce and filter are easily implemented in Go

                                                How? Type safe versions of these, that is, without interface{} and hacky codegen solutions?

                                                1. 1

                                                  Here are typesafe examples for Map, Filter etc: https://gobyexample.com/collection-functions

                                                  Implementing one Map function per type is often good enough. There is some duplication of code, but the required functionality is present. There are many theoretical needs that don’t always show up in practice.

                                                  Also, using go generate (which comes with the compiler), generic versions are achievable too. For example like this: https://github.com/kulshekhar/fungen

                                                  1. 9

                                                    When people say “type safe map/filter/reduce/fold” or “map, reduce, filter, and generics” they are generally referring to the ability to define those functions in a way that is polymorphic, type safe, transparently handled by the compiler and doesn’t sacrifice runtime overhead compared to their monomorphic analogs.

                                                    Whether you believe such facilities are useful or not is a completely different and orthogonal question. But no, they are certainly not achievable in Go and this is not a controversial claim. It is by design.

                                                    1. 1

                                                      Yes, I agree, Go does not have the combination of type safety and generics, unless you consider code generation.

                                                      The implementation of generics in C++ also works by generating the code per required type.

                                                      1. 5

                                                        The implementation of generics in C++ also works by generating the code per required type.

                                                        But they are not really comparable. In C++, when a library defines a generic type or function, it will work with any conforming data type. Since the Go compiler does not know about generics, with go generate one can only generate ‘monomorphized’ types for a set of predefined data types that are defined an upstream package. If you want different monomorphized types, you have to import the generic definitions and run go generate for your specific types.

                                                        unless you consider code generation

                                                        By that definition, any language is a generic language, there’s always Bourne shell/make/sed for code generation ;).

                                                        1. 1

                                                          That is true, and I agree that go does not have support for proper generics and that this can be a problem when creating libraries.

                                                        2. 3

                                                          That’s why I said “transparently handled by the compiler.” ;-)

                                                          1. 0

                                                            I see your point, but “go generate” is provided by the go compiler, by default. I guess it doesn’t qualify as transparent since you have to type “go generate” or place that command in a build file of some sort?

                                                            1. 1

                                                              Yes. And for the reasons mentioned by @iswrong.

                                                              My larger point here really isn’t a technicality. My point is that communication is hard and not everyone spells out every point is precise detail, but it’s usually possible to infer the meaning based on context.

                                                              1. -1

                                                                I think the even larger point is that for a wide range of applications, “proper” and “transparent” generics might not even be needed in the first place. It would help, yes, but the Go community currently thrives without it, with no lack of results to show for.

                                                                1. 1

                                                                  I mean, I’ve written Go code nearly daily since before it was 1.0. I don’t need to argue with you about whether generics are “needed,” which is a pretty slimy way to phrase this.

                                                                  Seems to me like you’re trying to pick a fight. I already said upthread that the description of generics is different from the desire for them.

                                                                  1. -2

                                                                    You were the first to change the subject to you and me instead of sticking to the topic at hand. Downvoting as troll.

                                              2. 1

                                                By superior, I guess you meant shorter?

                                                1. 2

                                                  Compiling a very large go project with a cold cache might take a minute (sub-second once the cache is warm).

                                                  Compiling a fairly small rust app with a warm cache has taken me over a minute (I think it’s a little better than that now).

                                                  1. 1

                                                    Yes, and superior to Rust in that regard. Also the strict requirement to not have unused dependencies contributes to counteract dependency rot, for larger projects.

                                              1. 3

                                                Rust itself runs tests in CI on every pull request that are required to pass. For example, https://travis-ci.org/rust-lang/rust/builds/410084149

                                                I can see why in a project as young as Rust maintaining different distributions’ forked build and test scripts for the compiler could be prioritized lower than e.g. language-level improvements.

                                                1. 6

                                                  Yes, Rust CI runs tests on x86_64. Hence lots of breakages on other Debian architectures.

                                                  I agree with you on the priority, but I am of the opinion that you can’t have it both ways. Either Rust should address test failures on other architectures, or Rust should stop claiming C level portability. Rust portability is “almost” there, but not there yet because other architectures are not maintained well.

                                                  1. 12

                                                    Can you please point out where Rust “claims C level portability”?

                                                    1. -3

                                                      This is one of those things where it doesn’t matter what the “official” stance but what the popular interpretation of that stance is. Certainly a number of people are writing Rust replacements for old C bastions, like grep or the coreutils. This along with the RIIR meme spreads the idea that Rust is a viable replacement for C in all situations, including portability.

                                                      If the RESF wants to be clearer about how Rust isn’t ready to replace C yet, they need to be clearer that it’s not ready instead of being silent on the point about portability claims and saying they never said that.

                                                      1. 7

                                                        This is one of those things where it doesn’t matter what the “official” stance but what the popular interpretation of that stance is. Certainly a number of people are writing Rust replacements for old C bastions, like grep or the coreutils. This along with the RIIR meme spreads the idea that Rust is a viable replacement for C in all situations, including portability.

                                                        If the RESF wants to be clearer about how Rust isn’t ready to replace C yet, they need to be clearer that it’s not ready instead of being silent on the point about portability claims and saying they never said that.

                                                        I realize you’re probably just going to go bitch about me on IRC again, but your comment smells like a load of bullshit to me. Rust’s supported platform list looks like a pretty good indicator to me of what the platform support looks like. In fact, it looks like the exact opposite of “silence.”

                                                        saying they never said that.

                                                        I actually didn’t say that. I asked where we claimed C level portability. If we were doing such a thing, I’d want to know about it so we can correct it. Which is exactly the thing you’re blabbering on about. But no. Instead, I get RESF thrown in my face.

                                                        Lose, lose. Thanks for playing.

                                                        1. -1

                                                          Aha, I also see this:

                                                          We do not demand that Rust run on “every possible platform”. It must eventually work without unnecessary compromises on widely-used hardware and software platforms.

                                                          So I guess the current situation with failing tests is entirely intentional but not well-known. Well, it should be better known.

                                                    2. 1

                                                      I agree that Rust needs a better multi-architecture story - as someone who does embedded development, I’ll play with Rust but I’d be very wary of using it “for real” - but lack of serious support for non-x86 [EDIT: non-Windows/-Linux/-Mac] is pretty well-documented.

                                                      [EDITed in response to sanxiyn’s clarification, thanks!]

                                                      1. 1

                                                        Rust Platform Support page is pretty clear. x86 is Tier-1, anything else is not.

                                                  1. 30

                                                    I enjoyed the author’s previous series of articles on C++, but I found this one pretty vacuous. I think my only advice to readers of this article would be to make up your own mind about which languages to learn and use, or find some other source to help you make up your mind. You very well might wind up agreeing with the OP:

                                                    Programmers spend a lot of time fighting the borrow checker and other language rules in order to placate the compiler that their code really is safe.

                                                    But it is not true for a lot of people writing Rust, myself included. Don’t take the above as a fact that must be true. Cognitive overheads come in many shapes and sizes, and not all of them are equal for all people.

                                                    A better version of this article might have went out and collected evidence, such as examples of actual work done or experience reports or a real comparison of something. It would have been a lot more work, but it wouldn’t have been vacuous and might have actually helped someone answer the question posed by the OP.

                                                    Both Go and Rust decided to special case their map implementations.

                                                    Rust did not special case its “map implementation.” Rust, the language, doesn’t have a map.

                                                    1. 16

                                                      Hi burntsushi - sorry you did not like it. I spent months before this article asking Rust developers about their experiences where I concentrated on people actually shipping code. I found a lot of frustration among the production programmers, less so among the people who enjoy challenging puzzles. They mostly like the constraints and in fact find it rewarding to fit their code within them. I did not write this sentence without making sure it at least reflected the experience of a lot of people.

                                                      1. 20

                                                        I would expect an article on the experience reports of production users to have quite a bit of nuance, but your article is mostly written in a binary style without much room for nuance at all. This does not reflect my understanding of reality at all—not just with Rust but with anything. So it’s kind of hard for me to trust that your characterizations are actually useful.

                                                        I realize we’re probably at an impasse here and there’s nothing to be done. Personally, I think the style of article you were trying to write is incredibly hard to do so successfully. But there are some pretty glaring errors here, of which lack of nuance and actual evidence are the biggest ones. There’s a lot of certainty expressed in this article on your behalf, which makes me extremely skeptical by nature.

                                                        (FWIW, I like Rust. I ship Rust code in production, at both my job and in open source. And I am not a huge fan of puzzles, much to the frustration of my wife, who loves them.)

                                                        1. 4

                                                          I just wanted to say I thought your article was excellent and well reasoned. A lot of people here seem to find your points controversial but as someone who programs C++ for food, Go for fun and Rust out of interest I thought your assessment was fair.

                                                          Lobsters (and Hacker News) seem to be very favourable to Rust at the moment and that’s fine. Rust has a lot to offer. However my experience has been similar to yours: the Rust community can sometimes be tiresome and Rust itself can involve a lot of “wrestling with the compiler” as Jonathan Turner himself said. Rust also provides some amazing memory safety features which I think are a great contribution so there are pluses and minuses.

                                                          Language design is all about trade-offs and I think it’s up to us all to decide what we value in a language. The “one language fits all” evangelists seem to be ignoring that every language has strong points and weak points. There’s no one true language and there never can be since each of the hundreds of language design decisions involved in designing a language sacrifices one benefit in favour of another. It’s all about the trade-offs, and that’s why each language has its place in the world.

                                                          1. 10

                                                            I found the article unreasonable because I disagree on two facts: that you can write safe C (and C++), and that you can’t write Rust with fun. Interpreted reasonably (so for example, excluding formally verified C in seL4, etc.), it seems to me people are demonstrably incapable of writing safe C (and C++), and people are demonstrably capable of writing Rust with fun. I am curious about your opinion of these two statements.

                                                            1. 7

                                                              I think you’re making a straw man argument here: he never said you can’t have fun with Rust. By changing his statement into an absolute you’ve changed the meaning. What he said was “Rust is not a particularly fun language to use (unless you like puzzles).” That’s obviously a subjective statement of his personal experience so it’s not something you can falsify. And he did say up front “I am very biased towards C++” so it’s not like he was pretending to be impartial or express anything other than his opinion here.

                                                              Your other point “people are demonstrably incapable writing safe C” is similarly plagued by absolute phrasing. People have demonstrably used unsafe constructs in Rust and created memory safety bugs so if we’re living in a world of such absolute statements then you’d have to admit that the exact same statement applies to Rust.

                                                              A much more moderate reality is that Rust helps somewhat with one particular class of bugs - which is great. It doesn’t entirely fix the problem because unsafe access is still needed for some things. C++ from C++11 onwards also solves quite a lot (but not all) of the same memory safety issues as long as you choose to avoid the unsafe constructs, just like in Rust.

                                                              An alternative statement of “people can choose to write safe Rust by avoiding unsafe constructs” is probably matched these days with “people can choose to write safe C++17 by avoiding unsafe constructs”… And that’s pretty much what any decent C++ shop is doing these days.

                                                              1. 5

                                                                somewhat with one particular class of bugs

                                                                It helps with several types of bugs that often lead to crashes or code injections in C. We call the collective result of addressing them “memory safety.” The extra ability to prevent classes of temporal errors… easy-to-create, hard-to-find errors in other languages… without a GC was major development. Saying “one class” makes it seem like Rust is knocking out one type of bug instead of piles of them that regularly hit C programs written by experienced coders.

                                                                An alternative statement of “people can choose to write safe Rust by avoiding unsafe constructs” is probably matched these days with “people can choose to write safe C++17 by avoiding unsafe constructs”

                                                                Maybe. I’m not familiar with C++17 enough to know. I know C++ was built on top of unsafe language with Rust designed ground-up to be safe-as-possible by default. I caution people to look very carefully for ways to do C++17 unsafely before thinking it’s equivalent to what safe Rust is doing.

                                                        2. 13

                                                          I agree wholeheartedly. Not sure who the target survey group was for Rust but I’d be interested to better understand the questions posed.

                                                          Having written a pretty large amount of Rust that now runs in production on some pretty big systems, I don’t find I’m “fighting” the compiler. You might fight it a bit at the beginning in the sense that you’re learning a new language and a new way of thinking. This is much like learning to use Haskell. It isn’t a good or bad thing, it’s simply a different thing.

                                                          For context for the author - I’ve got 10 years of professional C++ experience at a large software engineering company. Unless you have a considerable amount of legacy C++ to integrate with or an esoteric platform to support, I really don’t see a reason to start a new project in C++. The number of times Rust has saved my bacon in catching a subtle cross-thread variable sharing issue or enforcing some strong requirements around the borrow checker have saved me many hours of debugging.

                                                          1. 0

                                                            I really don’t see a reason to start a new project in C++.

                                                            Here’s one: there’s simply not enough lines of Rust code running in production to convince me to write a big project in it right now. v1.0 was released 3 or 4 years ago; C++ in 1983 or something. I believe you when you tell me Rust solves most memory-safety issues, but there’s a lot more to a language than that. Rust has a lot to prove (and I truly hope that it will, one day).

                                                            1. 2

                                                              I got convinced when Rust in Firefox shipped. My use case is Windows GUI application, and if Firefox is okay with Rust, so is my use case. I agree I too would be uncertain if I am doing, say, embedded development.

                                                              1. 2

                                                                That’s fair. To flip that, there’s more than enough lines of C++ running in production and plenty I’ve had to debug that convinces me to never write another line again.

                                                                People have different levels of comfort for sure. I’m just done with C++.

                                                          1. 10

                                                            I’ve used Aho-Corasick a lot. Not just on its own, but also as a tool to optimize special cases in a regex engine. Here are some various tidbits:

                                                            • Aho-Corasick can work fairly nicely in my experience up to ~low millions of entries. Somewhere around this point, constructing the automaton can get quite slow.
                                                            • Aho-Corasick is very nice when you want solid predictable performance.
                                                            • Aho-Corasick won’t beat specialized algorithms for searching a smaller number of patterns, especially some of the new packed substring algorithms that use vector instructions.
                                                            • If you can prove that every match of an AC automaton starts with at most a few different distinct bytes (e.g., Inspector Lestrade|Sherlock Holmes|Irene Adler has two distinct bytes), then you can use optimized routines in a skip loop to search for one of those bytes when your automaton is in a start state. For example, if there is only one beginning byte, you can use memchr. (You can extrapolate the implementation of memchr to memchr2 and memchr3 variants.) One must be judicious with such optimizations; feeding a very common byte to a skip loop can destroy performance. This negates the “predictable” performance aspect that you typically get with Aho-Corasick.
                                                            • Aho-Corasick can be used to find overlapping or non-overlapping matches.
                                                            • Aho-Corasick is fairly easy to adapt to report matches over streams such that your haystack needn’t be resident in memory at once. (“easy” in this context means “you don’t need to hand roll a special buffer that deals with edge cases.”)
                                                            • Commentz-Walter is an interesting concoction that combines the ideas of Aho-Corasick and Boyer-Moore. Namely, it constructs a backwards automaton that matches patterns in reverse while using the same type of skipping logic that Boyer-Moore does. Unfortunately, Commentz-Walter doesn’t scale as well as Aho-Corasick as you add patterns, because the more patterns you have, the less likely the skipping logic is going to buy you anything. However, for a smallish number of patterns, Commentz-Walter can beat Aho-Corasick. This may be why GNU grep used to use Commentz-Walter.
                                                            • In the literature, there is a variant of Aho-Corasick called “Advanced” Aho-Corasick. This variant compiles away all of the “failure” transitions found in the original algorithm down to a table based DFA. This makes the number of operations performed during search per byte constant instead of proportional to patterns themselves. This can result in a nice boost in performance, but of course, will cost quite a bit more memory. (There are tricks to reduce memory size—typically generic to any table based DFA—but they also come with costs.)
                                                            1. 3

                                                              If the 2 sides spent time talk past one another, it should have been made clear to provide a proposal by X date. It seems like the process was unclear or failed on that point (deliverables, before moving onto step Y).

                                                              1. 7

                                                                “The single biggest problem in communication is the illusion that it has taken place.”

                                                                (attributed to various folks in one form or another)

                                                                EDIT: Just to be super clear: this wasn’t intended as a dig. I myself suffer from this problem continuously. It’s a constant struggle to communicate effectively.

                                                              1. 1

                                                                The section on compatibility seems unfair. In the maximal (Cargo) approach, it is posited that since CI runs on everything, you have strong evidence that they work together. But in the minimal (modules) approach, no such consideration is given. The same argument applies there, but better: in the maximal approach, you have to rerun CI for every library that transitively depends on you when you release a new version, invalidating all previous runs. But, in the minimal approach, every CI run stays valid until someone explicitly updates to the new version AND pushes a new tagged version of their own library. Even then, only that new tagged version requires a CI run. No other libraries are affected. I think it’s reasonable to assume people won’t publish new tagged versions of their libraries with broken dependencies, and so you’re much more likely to get a compatible set.

                                                                In other words, assuming authors test their releases, the only way to get an untested configuration in the minimal world is if you combine multiple libraries together that share a transitive dependency. Even then, you know that at least one subset of libraries is a tested combination. The maximal world contains this failure mode and more: every time a package is published, every transitive dependency may get a broken combination, and you aren’t guaranteed that any of your libraries have been tested in combination.

                                                                1. 2

                                                                  Sharing transitive dependencies is pretty common, at least in Rust world. As you pointed out, this cancels most of “you get configuration tested by author” advantage.

                                                                  There is a tradeoff between getting configuration tested by author and getting configuration tested by ecosystem. Another tradeoff is between silently getting new bugs and silently getting new bugfixes.

                                                                  1. 1

                                                                    I don’t believe it cancels out most of the advantage. The versions in the transitive dependencies also have to be different, which I believe will be rare due to how upgrades work. As for testing by the author vs testing by the ecosystem, all it takes is one library in the ecosystem depending on the same two libraries as you, and you get just as much ecosystem testing.

                                                                    I agree with the bug tradeoff. Personally, I prefer stability, but I can understand that others may have a different preference. I think in the minimal world, people who want updates can explicitly ask for that, and in the maximal world, it seems people are starting to add flags to allow the other direction (–minimal-versions).

                                                                    1. 1

                                                                      Sharing transitive dependencies with different versions is also common in Rust. Instead of making assertions, I probably should whip up a script to count and publish statistics, but exa/Cargo.lock should illustrate my point. exa is rather popular Rust command line application.

                                                                      How to read Cargo.lock: top section is serialization of graph so hard to read. Bottom section is checksum, sorted by package name and version. exa transitively depends on both num_traits 0.1 and 0.2, and winapi 0.2 and 0.3. This is typical.

                                                                      1. 1

                                                                        num-traits 0.1 actually depends on 0.2. None of the transitive dependencies there actually require 0.1 in a way that excludes 0.2 (only datetime requires ^0.1.35) as far as I can tell, so I see no reason it needs to be included in the build. Perhaps it’s included in the checksum for some other reason?

                                                                        edit: I have since learned that ^ on v0 dependencies only allows patch level updates. So ^0.1.35 means >=0.1.35, <0.2.

                                                                        Winapi 0.2 and 0.3 do appear to both be required in the build. This is due to the term_size crate using a ~0.2 constraint. While I do not have a windows machine to test right now, this commit bumped the version to 0.3. It was only a reorganization of imports, and I believe that all of the pub use entries in 0.3 would cover all of the old imports. I will test this out on a windows machine later tonight.

                                                                        None of the dependencies on v1 or greater require multiple versions. People tend to attempt to respect semver, so this is expected. Also note that out of 55 transitive dependencies, only those two libraries had multiple versions, and only one would possibly require any changes, and it was a v0 dependency. I believe this is also typical, and I have surveyed a large corpus of Go packages that use dep and had the same findings. Even if the tools allow stricter constraints, typically they weren’t needed.

                                                                        edit: Here’s a link to my analysis of these types of issues in the Go community: https://github.com/zeebo/dep-analysis

                                                                        edit edit: To be clear, currently in the Go community there is no easy or supported way to include multiple versions of the same package into your library or binary. The Rust community can, and so perhaps some norms around what types of code transformations are possible differ, causing it to happen more often. I think the fact that Go has been getting along fine without multiple versions is evidence that Go doesn’t need that feature as much, but does not imply that for Rust. I don’t mean to argue that minimal selection would be a fit for Rust, but I don’t think it has the problems that the post describes in the context of Go.

                                                                        1. 1

                                                                          Oops, you are right. num-traits is using so-called semver trick, which explains it better than I ever can. For crates using semver trick, it is indeed normal for num-traits 0.1 to depend on num-traits 0.2. A good way to think about it is that post-0.2 release 0.1.x deletes 0.1 implementation and provides 0.1 interface compatible shim around 0.2 implementation instead.

                                                                          lalrpop/Cargo.lock is probably a better example. LALRPOP is a parser generator and transitively depends on regex-syntax 0.4, 0.5, and 0.6, without semver trick. I admit this is not typical, but it is also not rare. Multiple versions support has been in Cargo since forever.

                                                                          Your dep analysis is fascinating. Thanks a lot for letting us know.

                                                                          1. 1

                                                                            Thanks for another example. In this case, the Cargo.lock is shared for a number of workspaces, so many of the duplications are not actually present in the same artifact. Additionally, many of the different versions are present only in build-dependencies for some artifact. I analyzed the dependencies and reduced the set of real duplications down to these:

                                                                            | workspace      | dependency   | duplicated    |
                                                                            |----------------|--------------|---------------|
                                                                            | lalrpop        | regex        | v0.8 and v1   |
                                                                            | lalrpop        | regex-syntax | v0.5 and v0.6 |
                                                                            | lalrpop        | unreachable  | v0.1 and v1   |
                                                                            | lalrpop-snap   | regex-syntax | v0.4 and v0.6 |
                                                                            | lalrpop-snap   | unreachable  | v0.1 and v1   |
                                                                            

                                                                            The first two duplications were fixed by upgrading docopt from 0.8 to 1.0. No code changes required, the tests passed, and would happen automatically with MVS. The third was fixed by upgrading string_cache from 0.7.1 to 0.7.3. Again, no code changes were required, the tests passed, and this would happen automatically. This also fixed the fifth duplication. The fourth duplication is the only one that caused any problems, as there were significant changes to regex-syntax between 0.4 and 0.5, and it directly depends on 0.4.

                                                                            So in this case, there was only one dependency issue that would not have been solved by just picking the higher version out of about 70 dependencies, and the one failure was in a v0 dependency. So, while I agree they exist, I just don’t think they will be frequent, nor a significant source of pain.

                                                                            In fact, the only times duplications happened were when “breaking” changes happened. The way the default version selector in Cargo exacerbates this by considering any minor version change in a v0 crate to be “breaking”. In only one example was it actually breaking, and in every other example, just using the largest version worked. In the MVS world, breaking changes require updating the major version, which will allow both copies to exist in the same artifact. So while sharing transitive dependencies is frequent, sharing transitive dependencies that do not respect semver is infrequent, and sharing transitive dependencies with incompatibilities within compatible semver versions is also infrequent, causing this to not be a problem in practice.

                                                                            1. 1

                                                                              and sharing transitive dependencies with incompatibilities within compatible semver versions is also infrequent, causing this to not be a problem in practice.

                                                                              I don’t think you can reach this conclusion. If someone were to do this analysis, time is a critical dimension that must be accounted for. I also think you aren’t doing a correct treatment of semver. Namely, if I were in the Go world, regex-syntax would be at v6 rather than v0.6, to communicate its breaking changes. Each one of those minor version bumps had breaking changes. It simply may be the case that some breaking changes are bigger than others, and therefore, some dependents may not be affected.

                                                                              With respect to time, there is often a period of time after which a core crate has a new semver release where large parts of ecosystem depend on both the new version (because some folks are eager to upgrade) and also the older version. For example, there was a period of time a ~year ago where some projects were building both regex 0.1 and regex 0.2, even when there were significant breaking changes in the 0.2 release. You wouldn’t observe this now because people have moved on and upgraded. So the collection of evidence to support your viewpoint is quite a bit more subtle than just analyzing a particular snapshot in time.

                                                                              (To comment on the larger issue, my personal inclination is that I’d probably like a world with minimal version selection better just because it suits my sensibilities, but that I’m also quite happy with Cargo’s approach, and really haven’t experienced much if any pain with Cargo that could be attributed to maximal version selection.)

                                                                              1. 1

                                                                                Thanks for explaining the v6 vs v0.6 distinction better than I was able to. I was trying to get at that with the “breaking” paragraph. Cargo implicitly treats all minor version changes in the v0 major range as “breaking” by making the valid limit only in the minor range, in the same way it treats major versions in the v1 and above range as “breaking”. I think this is a great idea, but muddies the waters a bit on comparing ecosystems with respect to multiple versions of transitive dependencies. Like you said, in a Go world, it would be regex-syntax at v4 and v6, which would both be allowed in the binary at the same time.

                                                                                About your point on talking about time, in a Go world, those would be regex v1 and regex v2, again, not causing any issues. I am claiming that it is rare that multiple versions of some package need to exist in the same artifact when they are within the same compatible semver range. For example, if both v1.2 and v1.3 are required in the binary at the same time. I agree an analysis through time is valuable, but rarity also depends on time, so sampling any snapshot will help estimate how often it happens.

                                                                                In order to get an estimate for how often multiple semver compatible dependencies occur, I went through the git history of the above projects and their Cargo.locks, but only counting duplicates if they are of the form v0.X.Y and v0.X.Z or vX.Y.Z and vX.S.T. Again, v0 gets this special consideration because of the way that Cargo applies the default constraint. In order to make sure that the authors of these libraries weren’t pinning to some possibly older but semver compatible range, I checked their Cargo.tomls for any constraints that were not of the default form.

                                                                                • LALRPOP had no such conflicts in 15 revisions back to 2015. Every constraint was of the default form.
                                                                                • exa had no such conflicts in 115 revisions back to 2014. Every constraint was either default or "*".

                                                                                There is no evidence in either of these repositories that at any time Cargo had to do anything other than pick the highest compatible semver version for any shared transitive dependencies.

                                                                                This discussion has helped me understand better that the v0 range is going to be problematic for the Go modules system if people treat is as I expect and is encouraged: as a spot for breaking changes and experimentation. Cargo handles this gracefully by allowing breakage to be signaled in the minor version, but Go has no such design consideration. I hope that either a change is made to make this easier, or guidance is made in the community to avoid the problems.

                                                                                1. 2

                                                                                  I am claiming that it is rare that multiple versions of some package need to exist in the same artifact when they are within the same compatible semver range.

                                                                                  Oh interesting, OK. I think I missed this! I think I would indeed say that this is consistent with my experience in the ecosystem. While I can definitely remember many instances at which two semver incompatible releases are compiled into the same binary, I can’t remember any scenario in which two semver compatible releases were compiled into the same binary. I imagine Cargo probably tries pretty hard to avoid that from ever happening, although truthfully, I can’t say that I know whether that’s a hard constraint or not!

                                                                                  This discussion has helped me understand better that the v0 range is going to be problematic for the Go modules system if people treat is as I expect and is encouraged: as a spot for breaking changes and experimentation. Cargo handles this gracefully by allowing breakage to be signaled in the minor version, but Go has no such design consideration. I hope that either a change is made to make this easier, or guidance is made in the community to avoid the problems.

                                                                                  Yeah that’s a good point. I can’t think of any libraries I’ve ever published (aside from maybe a few niche ones that nobody uses) that haven’t had to go through some kind of breaking changes before I was ready to declare an API as “stable.” Usually they only happen because other people start to actually use it. The Go ecosystem could technically just reform their conventions around what v1 means. IIRC, the npm ecosystem kind of pushes toward this by starting folks at 1.0.0 by default I think? But that may be tricky to pull off!

                                                                1. 9

                                                                  This is a great article. I loved it. I generally agree with all of it, and actually practice most of it as well. I do have two pieces of critical feedback though. :-)

                                                                  Firstly, this doesn’t talk about error handling. For the most part, there isn’t much to it, but there are definitely interesting pits that one can fall into. e.g., If you need to perform batch operations that can partially succeed or the correct translation of errors into corresponding HTTP errors. It’s easy to let errors nest, so simple type switching can be problematic, although the github.com/pkg/errors can help with that via its causal chains.

                                                                  Secondly, I think this article gives the standard party line on interfaces, but it is incomplete IMO. And not in a pedantic way, but importantly incomplete. I wrote about this more here: https://lobste.rs/s/9ots3k/advanced_testing_techniques_go#c_1ueuxw

                                                                  1. 8

                                                                    Thanks for the feedback. I chose talking points based on my experience of what tends to trip folks up, and in my experience, error handling hasn’t really been an issue. Tell people about pkg/errors.Wrap and they’re pretty much good to go.

                                                                    Also, we’ve spoken about this aspect of interfaces before; I still believe we work in sufficiently different codebases. That is:

                                                                    The only real issue here is that you want everyone else that uses this storage system to be able to also use the in-memory implementation as well. The most natural way to do that is to define an interface.

                                                                    In the line-of-business code I’m most often exposed to, packages rarely have more than one consumer; often, it’s just package main, plus relevant tests. In that case, where the interface definition lives is essentially a coin-flip, and (IMO) keeping the consumer contract with the consumer is the best default way to encode the abstraction boundary.

                                                                    Or, if the package does have multiple consumers, most often each consumer is using a different subset of functionality. For example, a shared repository type might be a dependency to two components, but one writes, and the other reads. In this case, it still makes the most sense to define downscoped consumer interfaces.

                                                                    If I did have multiple packages using the complete methodset of a shared type, I would absolutely define the interface with the implementations. I just can’t think of many (any?) times in my industrial programming experience where that’s been the case.

                                                                    1. 3

                                                                      Interesting. I forgot we talked about this before. :-) We have many packages that make use of said storage layers. e.g., There are lots of different things that want to communicate with out Elasticsearch cluster for a variety of different reasons, but we can manage to button up all of the Elasticsearch specific stuff for a particular data model behind a layer of encapsulation. The interface for it is quite large, as you might imagine. :-)

                                                                      RE error handling: it hasn’t been a major source of frustration, but it definitely hasn’t been zero either. It is very easy for a type switch to not do what you think it’s doing when needing to perform error conversion or when needing to “cleanse” errors such that you aren’t showing, say, transient Elasticsearch errors in your HTTP 500 payload. We’re probably approaching it in the wrong way, honestly.

                                                                      1. 2

                                                                        We’re probably approaching it in the wrong way, honestly.

                                                                        In the Go kit view of the world, there is a strict separation between business domain and transport (e.g. HTTP). One common operation is translating business domain errors to and from transport semantics. The pattern that seems to work best is to do it explicitly, via some kind of mapping. That is,

                                                                        func httpError(biz error) (code int, err error) {
                                                                            if biz == service.ErrBadCredentials {
                                                                                return http.StatusNotAuthorized, biz
                                                                            }
                                                                            if biz == service.ErrInvalidRecord {
                                                                                return http.StatusNotFound, biz
                                                                            }
                                                                            switch e := biz.(type); e {
                                                                            case service.DependencyError:
                                                                                return http.StatusBadGateway, e.Error
                                                                            case service.RegionError:
                                                                                return 451, errors.New(e.Description)
                                                                            }
                                                                            return http.StatusInternalServerError, biz
                                                                        }
                                                                        

                                                                        This behavior can be implemented as a free function defined in the transport package, as above, which is what I generally recommend. Or, if the service only really speaks one transport, it may make sense to “splat” the logic out into a common interface, which all business errors can implement:

                                                                        type HTTPError interface {
                                                                            Code() int
                                                                            Err() error
                                                                        }
                                                                        

                                                                        This approach technically violates separation of concerns and the inward-facing dependency rule, but it can be a useful hack in some circumstances.

                                                                        Maybe this gives you some ideas for how to handle crossing the Elasticsearch/business domain boundary.

                                                                        1. 2

                                                                          Thanks! I’ll ponder that. :-)

                                                                  1. 16

                                                                    Having spent the last 6 months working Rust, I’d disagree with his conclusion around Rust being prideful about pushing the borrow checker.

                                                                    The language is explicit in how you should use it - the rules are different than someone coming from C++ or C# might expect. It is to be expected that you fight the compiler - it’s a different way of thinking. That doesn’t mean Rust is right but it also doesn’t mean it’s wrong. It’s an opinion.

                                                                    This is similar to new users of Haskell fighting purity. Just because Haskell is pure doesn’t mean it’s right or wrong - it’s a design choice that you have to learn to work with.

                                                                    1. 1

                                                                      I think we have to admit that, for most people, the just get it to compile->runtime error->printf debugging loop is preferable. Even if only because it feels more productive.

                                                                      1. 8

                                                                        There is quite a large class of bugs that Rust purports to fix in which you only get a runtime error if you’re lucky. At least, when compared to C or C++.

                                                                        1. 0

                                                                          You’re right. It’s closer to a (wait for the world to explode->printf debugging->wait again) loop. This goes along with the metaphor of building software as construction. There’s a whole group of people who just want to duct tape that leak under the sink. They aren’t building a house or even a shed, as much as they are temporary tenants. You know you won’t be living in the house forever, so it’s not worth it to actually fix the problem.

                                                                          1. 2

                                                                            I do think most source codes live too short to care, but shouldn’t systems be built to last? I think Rust is a better systems programming language than C or C++ in that sense.

                                                                            1. 3

                                                                              I do think most source codes live too short to care

                                                                              Even then, Wirth’s languages showed you could get fast compiles, be safe by default, have clean module system, and support concurrency built-in. C the language is still worse if one aims to quickly throw together code that doesn’t crash or get hacked as often.

                                                                            2. 1

                                                                              I’d contend that maybe those folks shouldn’t be building systems :). Until you have to deal with servicing a huge number of client machines, the guarantees don’t really set in as to how much they help.

                                                                          2. 2

                                                                            I’d disagree. That feels considerably less productive for systems programming. In fact, it’s infuriating. I mostly work in client-side software developed on a large-to-huge scale. Runtime failures are the last thing I want to deal with - it means I have to update upwards of 500k clients.

                                                                            While it might be acceptable to deal with compile->runtime error->printf debug on the server side. It’s hardly a good solution on client side – even if it was how we dealt with it for many years.

                                                                            1. 1

                                                                              Yes, I agree that certain tasks require different tools. I was trying to specifically point out that generalization is for most people. E.g. quick data analysis jobs, internal web UI, etc. Obviously dynamic or interpreted languages are better for such tasks, than something like C. Personally I see the future of C being for microcontroller projects or toy ISAs, where you care about ease of implementation, and support for better defined languages take over primary systems. That may take another half-century at this rate, though.

                                                                            2. 1

                                                                              Well, there are those who feel that compile/type errors hold back their unbounded creativity, but that doesn’t mean those analyses are bad.

                                                                          1. 12

                                                                            As someone who uses arch on all my developer machines, arch is a horrible developer OS, and I only use it because I know it better than other distros.

                                                                            It was good 5-10 years ago (or I was just less sensitive back then), but now pacman Syu is almost guaranteed to break or change something for the worse, so I never update, which means I can never install any new software because everything is dynamically linked against the newest library versions. And since the arch way is to be bleeding edge all the time, asking things like “is there an easy way to roll back an update because it broke a bunch of stuff and brought no improvements” gets you laughed out the door.

                                                                            I’m actually finding myself using windows more now, because I can easily update individual pieces of software without risking anything else breaking.

                                                                            @Nix people: does NixOS solve this? I believe it does but I haven’t had a good look at it yet.

                                                                            1. 14

                                                                              Yes, Nix solves the “rollback” problem, and it does it for your entire OS not just packages installed (config files and all).

                                                                              With Nix you can also have different versions of tools installed at the same time without the standard python3.6 python2.7 binary name thing most place do: just drop into an new nix-shell and install the one you want and in that shell that’s what you have. There is so much more. I use FreeBSD now because I just like it more in total, but I really miss Nix.

                                                                              EDIT: Note, FreeBSD solves the rollback problem as well, just differently. In FreeBSD if you’re using ZFS, just create a boot environment before the upgrade and if the upgrade fails, rollback to the pre-upgrade boot environment.

                                                                              1. 9

                                                                                Being a biased Arch Developer, I rarely have Arch break when updating. Sometimes I have to recompile our own C++ stack due to soname bumps but for the rest it’s stable for me.

                                                                                For Arch there is indeed no rollback mechanism, although we do provide an archive repository with old versions of packages. Another option would be BTRFS/ZFS snapshots. I believe the general Arch opinion is instead of rolling back fixing the actual issue at hand is more important.

                                                                                1. 8

                                                                                  I believe the general Arch opinion is instead of rolling back fixing the actual issue at hand is more important.

                                                                                  I can see some people might value that perspective. For me, I like the ability to plan when I will solve a problem. For example I upgraded to the latest CURRENT in FreeBSD the other day and it broke. But I was about to start my work day so I just rolled back and I’ll figure out when I have time to address it. As all things, depends on one’s personality what they prefer to do.

                                                                                  1. 2

                                                                                    For me, I like the ability to plan when I will solve a problem.

                                                                                    But on stable distros you don’t even have that choice. Ubuntu 16.04, (and 18.04 as well I believe) ships an ncurses version that only supports up to 3 mouse buttons for ABI stability or something. So now if I want to use the scroll wheel up, I have to rebuild everything myself and maintain some makeshift local software repository.

                                                                                    And that’s not an isolated case, from a quick glance at my $dayjob workstation, I’ve had to build locally the following: cquery, gdb, ncurses, kakoune, ninja, git, clang and other various utilities. Just because the packaged versions are ancient and missing useful features.

                                                                                    On the other hand, I’ve never had to do any of this on my arch box because the packaged software is much closer to upstream. And if an update break things, I can also roll back from that update until I have time to fix things.

                                                                                    1. 2

                                                                                      I don’t use Ubuntu and I try to avoid Linux, in general. I’m certainly not saying one should use Ubuntu.

                                                                                      And if an update break things, I can also roll back from that update until I have time to fix things.

                                                                                      Several people here said that Arch doesn’t really support rollback which is what I was responding to. If it supports rollback, great. That means you can choose when to solve a problem.

                                                                                      1. 1

                                                                                        I don’t use Ubuntu and I try to avoid Linux, in general. I’m certainly not saying one should use Ubuntu.

                                                                                        Ok, but that’s a problem inherent to stable distros, and it gets worse the more stable they are.

                                                                                        Several people here said that Arch doesn’t really support rollback

                                                                                        It does, pacman keeps local copies of previous versions for each package installed. If things break, you can look at the log and just let pacman install the local package.

                                                                                        1. 1

                                                                                          It does, pacman keeps local copies of previous versions for each package installed. If things break, you can look at the log and just let pacman install the local package.

                                                                                          Your description makes it sound like pacman doesn’t support roll backs, but you can get that behaviour if you have to and are clever enough. Those seem like very different things to me.

                                                                                          Also, what you said about stable distros doesn’t seem to match my experience in FreeBSD. FreeBSD is ‘stable’ however ports packages tend to be fairly up to date (or at least I rarely run into it except for a few).

                                                                                          1. 1

                                                                                            I’m almost certain any kind of “rollback” functionality in pacman is going to be less powerful than what’s in Nix, but it is very simple to rollback packages. An example transcript:

                                                                                            $ sudo pacman -Syu
                                                                                            ... some time passes, after a reboot perhaps, and PostgreSQL doesn't start
                                                                                            ... oops, I didn't notice that PostgreSQL got a major version bump, I don't want to deal with that right now.
                                                                                            $ ls /var/cache/pacman/pkg | rg postgres
                                                                                            ... ah, postgresql-x.(y-1) is sitting right there
                                                                                            $ sudo pacman -U /var/cache/pacman/pkg/postgres-x.(y-1)-x86_64.pkg.tar.xz
                                                                                            $ sudo systemctl start postgres
                                                                                            ... it's alive!
                                                                                            

                                                                                            This is all super standard, and it’s something you learn pretty quickly, and it’s documented in the wiki: https://wiki.archlinux.org/index.php/Downgrading_packages

                                                                                            My guess is that this is “just downgrading packages” where as “rollback” probably implies something more powerful. e.g., “rollback my system to exactly how it was before I ran the last pacman -Syu.” AFAIK, pacman does not support that, and it would be pretty tedious to actually do it if one wanted to, but it seems scriptable in limited circumstances. I’ve never wanted/needed to do that though.

                                                                                            (Take my claims with a grain of salt. I am a mere pacman user, not an expert.)

                                                                                            EDIT: Hah. That wiki page describes exactly how to do rollbacks based on date. Doesn’t seem too bad to me at all, but I didn’t know about it: https://wiki.archlinux.org/index.php/Arch_Linux_Archive#How_to_restore_all_packages_to_a_specific_date

                                                                              2. 12

                                                                                now pacman Syu is almost guaranteed to break or change something for the worse

                                                                                I have the opposite experience. Arch user since 2006, and updates were a bit more tricky back then, they broke stuff from time to time. Now nothing ever breaks (I run Arch on three different desktop machines and two servers, plus a bunch of VMs).

                                                                                I like the idea of NixOS and I have used Nix for specific software, but I have never made the jump because, well, Arch works. Also with Linux, package management has never been the worst problem, hardware support is, and the Arch guys have become pretty good at it.

                                                                                1. 3

                                                                                  I have the opposite experience

                                                                                  I wonder if the difference in experience is some behaviour you’ve picked up that others haven’t. For example, I’ve found that friend’s children end up breaking things in ways that I would never do just because I know enough about computers to never even try it.

                                                                                  1. 2

                                                                                    I think it’s a matter of performing Syu update often (every few days or even daily) instead of once per month. Rare updates indeed sometimes break things but when done often, it’s pretty much update and that’s it.

                                                                                    I’m an Arch user since 6 years and there were maybe 3 times during those 6 years where something broke badly (I was unable to boot). Once it was my fault; second & third one is related to nvidia driver and Xorg incompatibility.

                                                                                    1. 3

                                                                                      Rare updates indeed sometimes break things but when done often, it’s pretty much update and that’s it.

                                                                                      It’s sometimes also a matter of bad timing. Now every time before doing a pacman -Syu I check /r/archlinux and the forums to see if someone is complaining. If so then I tend to wait for a day or two before the devs push out updates to broken packages.

                                                                                    2. 1

                                                                                      That’s entirely possible.

                                                                                  2. 4

                                                                                    I have quite a contrary experience, I have pacman run automated in the background every 60 minutes and all breakage I suffer is from human-induced configuration errors (such as misconfigured boot loader or fstab)

                                                                                    1. 1

                                                                                      Things like Nix even allow rolling back from almost all user configuration errors.

                                                                                      1. 3

                                                                                        Would be nice, yeah, though I never understood or got Nix really. It’s a bit complicated and daunting to get started and I found the documentation to be lacking.

                                                                                    2. 3

                                                                                      How often were you updating? Arch tends to work best when it’s updated often. I update daily and can’t remember the last time I had something break. If you’re using Windows, and coming back to Arch very occasionally and trying to do a huge update you may run into conflicts, but that’s just because Arch is meant to be kept rolling along.

                                                                                      I find Arch to be a fantastic developer system. It lets me have access to all the tools I need, and allows me to keep up the latest technology. It also has the bonus of helping me understand what my system is doing, since I have configured everything.

                                                                                      As for rollbacks, I use ZFS boot environments. I create one prior to every significant change such as a kernel upgrade, and that way if something did happen go wrong, and it wasn’t convenient to fix the problem right away, I know that I can always move back into the last environment and everything will be working.

                                                                                      1. 2

                                                                                        How do you configure ZFS boot environments with Arch? Or do you just mean snapshots?

                                                                                        1. 3

                                                                                          I wrote a boot environment manager zedenv. It functions similarly to beadm. You can install it from the AUR as zedenv or zedenv-git.

                                                                                          It integrates with a bootloader if it has a “plugin” to create boot entries, and keep multiple kernels at the same time. Right now there’s a plugin for systemdboot, and one is in the works for grub, it just needs some testing.

                                                                                          1. 2

                                                                                            Looks really useful. Might contribute a plugin for rEFInd at some point :-)

                                                                                            1. 1

                                                                                              Awesome! If you do, let me know if you need any help getting started, or if you have any feedback.

                                                                                              It can be used as is with any bootloader, it just means you’ll have to write the boot config by hand.

                                                                                    1. 18

                                                                                      I’ll add to the chorus of folks with good experiences using Archlinux. I’ve been using it for almost 10 years now, and it’s been extremely solid. I use it at home, at work, on my laptop and on my various media PCs. My wife uses it now too. There is nothing in particular that has really made me want to switch to something else. NixOS has piqued my curiosity since I read their paper many years ago, but I’ve never given it a fair shake because Arch has been so good to me, and because I tend to be a “worse is better” kind of a guy, but only when necessary. ;-) I love me some PKGBUILD!

                                                                                      I’m not sure I’d sing praises for the Archlinux community. I do like their trial by fire approach to things. But my personal interactions with them haven’t been a shining beacon of friendliness, I can tell you that. I never really fit in with the Archlinux community, so I tend to avoid it. But I think that’s OK.

                                                                                      1. 3

                                                                                        Arch Linux is (mostly) friendly towards experienced users that also strives towards keeping things simple. How can a distro communicate that it’s not for beginners, nor for maximalists (excluding large groups of users, on purpose) while also communicating that it is friendly?

                                                                                        1. 6

                                                                                          I don’t know how to answer your question, but I will clarify my statement. I said that my personal interactions with people in the Archlinux community have not been what I’d call “friendly.” I’m talking about conversing with people, not the official documentation materials, which I’ve found do a great job of being friendly while simultaneously being a great example of the trial-by-fire approach to learning that really works.

                                                                                          To be fair, I think it is very hard to mix trial-by-fire learning (which I think is one of many great ways to learn) with friendliness in an online community. It’s too easy to slip. But that’s just my belief based on what I think I understand about humans.

                                                                                          Like I said, I just don’t fit in with that style of communication. But there are a lot of places that I don’t fit into. And I really do think that’s OK.

                                                                                          EDIT: Also to add a positive note, not all of my interactions with Archlinux community members have been bad. There have been (very) good ones too. I guess it’s just much easier to focus/remember the bad. :-/

                                                                                          1. 3

                                                                                            I guess it’s just much easier to focus/remember the bad

                                                                                            This is a known psychological effect called Negativity Bias. In theory it protects you to from forgetting things that could harm you, and helps you notice potentially dangerous situations.

                                                                                            1. 2

                                                                                              Yeah, this happens. Mainly because too many people forget how rolling works, and the forums are tired of answering the same questions :/

                                                                                        1. 15

                                                                                          I love how varied university education can be. We definitely had very different experiences. I’ll just ramble some hand wavy thoughts, don’t take them too seriously.

                                                                                          • School in the US doesn’t have to be expensive, depending on circumstances. I went to UMass Amherst for a year (living on campus) before transferring to Worcester State (living at home). UMass was too expensive for my taste, and it was still quite a bit cheaper (in state) than private schools in the area you probably haven’t heard of (WPI, Clark, Assumption, Becker, Mount Holyoke, Amherst). State schools like Worcester State are much much cheaper by comparison, especially if you can finagle a way to live at home. I worked my way through school and had pretty small student loans at the end, about an order of magnitude less than others in my circle of friends. Order of magnitude is not an exaggeration. Living at home was a convenient option that I was fortunate to have, but everyone in my circle had that opportunity as well. But they prioritized other things. :-)
                                                                                          • The most important thing I ever did was learn how to learn. This made most courses stupidly easy, in the sense that I still learned some things but I spent very little time on it. I don’t consider myself particularly bright, but figuring out how to do active reading in high school felt like a cheat code.
                                                                                          • I very rarely tried anything new because I knew what I liked, and that’s OK. The only real friends that I stay in contact with from college are my wife, my boss and my mentor (where my mentor was from graduate school). (Sorry @jfredett, fellow woo stater, but we haven’t seen each other in a loooong time. :-))
                                                                                          • I enjoyed my time in school overall. In part because I liked taking classes and expanding my exposure to topics I wanted to know more about in a structured way. But really, I liked school because I had so much god damn time. I always tried to arrange my schedule on a Tues/Thurs or Mon/Wed/Fri rhythm. Sure, I ended up with 12 hour (or more) days, but then I had alternating days off. Homework and exam prep always happened in spirts, so I’d almost always have huge huge chunks of time where I could just do whatever I wanted to. I look back on those days with longing. These days (with a full time job), I need to be much more efficient and ruthless with how I spend my time.
                                                                                          • I almost never went to office hours, and disliked working in groups. I think I was too stubborn for office hours, because I would just do my best to work it out on my own. I disliked working in groups because the incentive structure was always completely off. Occasionally I worked with other motivated students, and those were great.
                                                                                          • I enjoyed study groups in large part because I got to teach others. This reinforced the material even more for me. Win-win. But I didn’t do this often.
                                                                                          • At every school I went to, I always found my little corners of quiet. I loved those so much, especially when nobody else was around. They really helped me a lot. In my three years at Worcester State, almost nobody went to the second floor of the library during the day. It was bliss.
                                                                                          • Find a way to be engaged with what you’re spending your time on. You’ll be happier and so will the people around you. (Easier said than done, but it has always come naturally to me. More than that, I’ve found that I tend to be surrounded by people that do the same. I don’t know how that happened, but it’s happened several times now, so I’m pretty sure it isn’t coincidence.)
                                                                                          1. 6

                                                                                            Eh, I run into you on the internet often enough. :) We should get a beer sometime though.

                                                                                            I can definitely echo a lot of these statements, but especially these two:

                                                                                            The most important thing I ever did was learn how to learn. This made most courses stupidly easy, in the sense that I still learned some things but I spent very little time on it. I don’t consider myself particularly bright, but figuring out how to do active reading in high school felt like a cheat code.

                                                                                            This is critical, but ‘learning how to learn’ has never been my favorite phrasing. The latter, “active reading” is closer, but I think I like “active learning” the most – the idea of not just learning something, but learning how you learn it, and critically examining and engineering better ways to learn. I was not a particularly great high school student, but college taught me pretty quickly how to treat learning as an engineering problem, and that was super valuable.

                                                                                            I almost never went to office hours, and disliked working in groups. I think I was too stubborn for office hours, because I would just do my best to work it out on my own. I disliked working in groups because the incentive structure was always completely off. Occasionally I worked with other motivated students, and those were great.

                                                                                            I was similar. I much preferred leading discussion in a peer group – in that way I ended up being forced to teach the material / defend my position (even when I wasn’t particularly confident I was right!). @burntsushi was a pretty common foil for my ramblings in the Math lab.

                                                                                            Having a good set of friends to talk math at was super valuable; I suspect that is the core thing to try to acquire in any situation that involves a lot of learning. I’ve developed a similar method of working now, my team consists of a lot of really smart people who know their fields well and have enough overlap that we can all bounce ideas off each other while still having areas we can feel expert in. It’s the best of both worlds, I think.

                                                                                            I suppose this is number three, but quiet parts of libraries are the best. The bottom floor of WPI’s library is where I got most of my work done.

                                                                                            1. 6

                                                                                              Tangential comment:

                                                                                              Wow, I had no idea there were woo state alums here. I, too, went to Worcester State. I can’t compare it to any other undergraduate experience but I had a great time and I came out with almost no debt (my 4 years there were less than 1 semester of friends who went to more prestigious schools in the are). While the cost savings wasn’t an active decision at the time, it turned out to be a great one. I have found, for software engineering at least, the amount of negative impact going to a small school has on one’s career is minimal to zero. And since those loans are in my name, I’m much better off financially than those going to more expensive schools and having to pay for it (although I know many who had parents willing to foot the bill). Google might not have been waiting outside during my graduation but I see little different in my career relative to most friends who went to much more prestigious schools for undergrad.

                                                                                              1. 4

                                                                                                Neat! What years were you there? I was there 2007-2010.

                                                                                                1. 3

                                                                                                  I was there 2001 - 2006 (I think, I’m terrible with dates). My claim to fame is I was the first person to graduate with the Bioinformatics concentration. I don’t know if that still existed when you were there. I can’t wait to retire though, I miss college and want to go back full time!

                                                                                                  1. 3

                                                                                                    Hah, nice. I also graduated with a bioinformatics concentration (and a Math degree). The biology and chemistry courses were awesome. Judging by the number of other people I was aware of that were pursuing a CS w/ bioinformatics concentration, I wouldn’t be surprised if I was the second one. :P

                                                                                                    1. 2

                                                                                                      Wow! Small world!

                                                                                                      I was actually just reflecting on how much I enjoyed the bio and chem as well! I feel it really grounded me in the real world. In CS we just have control over so much since we’re defining so much of it but bio and chem are messy and fun and so many unknowns.

                                                                                            1. 4

                                                                                              Seems like an over-reaction to me. It’s quite plausible that Uncle Bob is misguided in his politics but still right about a lot of things in programming. Speaking from personal experience, I used to be an evangelical Christian and a conservative Republican. I’ve now renounced those positions, but I still think I did some of my best programming work back then.

                                                                                              1. 2

                                                                                                I was blissfully unaware of Uncle Bob’s politics until this post, but have never liked any of the advice I’ve read of his on programming specifically. (My dislike stretches across multiple dimensions too; everything from the expression of certainty to the technical ideas themselves. When you’re that certain about something, my bullshit detectors go off because I am just certain that something is being omitted. ;-))

                                                                                                With that said, I agree with your point. History is absolutely littered with individuals who have done or believed crazy things despite doing other things that clearly require strong talents and gifted intellectual abilities (which may have been used for great good or great evil).

                                                                                                1. 1

                                                                                                  I don’t think the two are related in any meaningful way, but I don’t like his politics and I don’t really like his programming. People can lack epistemological responsibility in any political context, lacking the basic questioning that keeps us effective. I’ve seen it on both sides of the political spectrum. Sometimes even people who lack that questioning luck into a good solution or good politics.

                                                                                                  Being correct on any issue doesn’t mean you understood why that thing is right. Before someone lambasts me for saying there is such a thing as bad politics consider the worst possible political position imaginable such as the eradication of all humans. Surely someone here will disagree with me on that but I reserve the right to consider it bad.

                                                                                                1. 19

                                                                                                  As with most of Gary Bernhardt’s writing, I loved this piece. I read it several times over, as I find his writing often deeply interesting. To me, this is a great case study in judgement through attempting to apply Americanized principles to speech between two non-Americans (a Pole and a Finn) communicating in a second language.

                                                                                                  There are several facets at play here as I see it:

                                                                                                  1. There’s a generational difference between older hackers and newer ones. For older hackers, the code is all that matters, niceties be damned. Newer hackers care about politeness and being treated well. Some of this is a product of money coming in since the 90s, and people who never would’ve been hackers in the past are hackers now.

                                                                                                  2. Linux is Linus’ own project. He’s not going to change. He’s not going to go away. If you don’t like the way he behaves, fork it. Run your own Linux fork the way you want, and you’ll see whether or not the niceties matters. Con Kolivas did this for years.

                                                                                                  3. There are definitely cultural issues at play. While Linus has a lot of exposure to American culture, he’s Finnish. Finnish people are not like Americans. I find the American obsession with not upsetting people often infuriatingly two-faced, and I’m British. I have various friends in other countries who find the much more minor but still present British obsession with not upsetting people two-faced, and they’re right.

                                                                                                  Go to Poland, fuck up and people will tell you. Go to Germany, do something wrong and people will correct you. Go to Finland, do something stupid getting in the way of a person’s job and probably they’ll swear at you in Finnish. I’m not saying this is right, or wrong, it’s just the rest of the world works differently to you, and while you can scream at the sea about perceived injustices, the sea will not change it’s tides for you.

                                                                                                  Yes Linus is being a jerk, but it’s not like this is an unknown quantity. Linus doesn’t owe you kindness. You don’t owe Linus respect either. If his behaviour is that important to you, don’t use Linux.

                                                                                                  1. 16

                                                                                                    Finnish people are not like Americans. I find the American obsession with not upsetting people often infuriatingly two-faced […]

                                                                                                    • I think this is a false comparison of some sort. Americans worrying doesn’t say anything useful about Finns.
                                                                                                    • I emphatically disagree that Linus is representative of the social culture around me in Finland.
                                                                                                    • Nonviolent, clear communication is not the same thing as avoiding difficult subjects. It’s the opposite!
                                                                                                    1. 5

                                                                                                      I think this is a false comparison of some sort. Americans worrying doesn’t say anything useful about Finns.

                                                                                                      In my experience of dealing with Finns, they don’t sugar coat things. When something is needed to be said, the Finns I’ve interacted with are extremely direct and to the point, compared to some other cultures. Would you say that’s fair?

                                                                                                      I emphatically disagree that Linus is representative of the social culture around me in Finland.

                                                                                                      I didn’t say that he’s representative of Finnish culture. He’s a product of it. He wasn’t raised American. He didn’t grow up immersed in American culture and values. It would be unrealistic to expect him to hold or conform to American values.

                                                                                                      Nonviolent, clear communication is not the same thing as avoiding difficult subjects. It’s the opposite!

                                                                                                      Definitely! Out of interest, what are your thoughts on this in terms of applicability to his communication style? I’m fairly certain there’s a general asshole element to his style, but I wonder how much (if any) is influenced by this.

                                                                                                      1. 1

                                                                                                        He didn’t grow up immersed in American culture and values. It would be unrealistic to expect him to hold or conform to American values.

                                                                                                        As an Italian, I can say that after the WWII, US did a great job to spread their culture in Europe.
                                                                                                        Initially to counter the “Bolsheviks” influx, later as a carrier for their products.

                                                                                                        They have been largely successful.
                                                                                                        Indeed, I love Joplin just like I love Vivaldi, Mozart and Beethoven! :-)
                                                                                                        But we have thousands years of variegate history, so we are not going to completely conform anyway. After all, we are proud of our deep differences, as they enrich us.

                                                                                                        1. 2

                                                                                                          At the risk of getting into semantics, Finland was much more neutral post WWII than other European nations due to realpolitik.

                                                                                                          Also, there is something to say for Italian insults, by far some of the finest and most perverse, blasphemous poetry I’ve ever had the pleasure of experiencing. It’s the sort of level of filth that takes thousands of years to age well :)

                                                                                                          1. 3

                                                                                                            Actually the Invettiva is a literary gender on its own, that date back to ancient Greek.

                                                                                                            In Italian, there are several passages of Dante’s Divina Commedia that belong to the genre and are spectacular examples of the art you describe.

                                                                                                            But since we are talking about jerk, I will quote Marziale, from memory: 2000 years later we still memorize his lines at school

                                                                                                            Os et labras tibi lingit, Menneia, catellus.
                                                                                                            Non miror, merdas si libet esse cani.

                                                                                                            Nothing Linus can say will ever compete! ;-)

                                                                                                            1. 1

                                                                                                              Os et labras tibi lingit, Menneia, catellus. Non miror, merdas si libet esse cani.

                                                                                                              Google translates this as

                                                                                                              Your mouth and lip licking, Menneas, catelle. I am not surprised, merda, if you like to be for the dog.

                                                                                                              Which I assume is horribly wrong. Is it possible to translate for us non-worldly folks who only know English? :-)

                                                                                                              1. 2

                                                                                                                The translation from Latin is roughly

                                                                                                                The little dog licks your mouth and lips.
                                                                                                                Not a surprise: dogs like to eat shits.

                                                                                                                It’s one of Martial’s Epygrams.
                                                                                                                Not even one of the worse!

                                                                                                                It’s worth noticing how nothing else remains of Menneia. And the same can be said of several people targeted by his insults.

                                                                                                                1. 1

                                                                                                                  Hah, that’s great. Thank you!

                                                                                                    2. 9

                                                                                                      speech between two non-Americans (a Pole and a Finn) communicating in a second language.

                                                                                                      How is that relevant? On my current team, we have developers from Argentina, Bosnia, Brazil, China, India, Korea, and Poland, as well as several Americans (myself included). Yet as far as I can recall from the year that I’ve been on this team so far, all of our written communication has been civil. And even in spoken communication, as far as I can recall, nobody uses profanity to berate one another. To be fair, this is in a US-based corporate environment. Still, I don’t believe English being a second language is a reason to not be civil in written communication.

                                                                                                      1. 7

                                                                                                        You’re comparing Linux, a Finnish-invented, international, volunteer-based non-corporate project to a US-based corporate environment, and judging Linus’ communications against your perception of a US-based corporate environment. You’re doing the same thing as the author, projecting your own values onto something that doesn’t share those values.

                                                                                                        Additionally, by putting the words I’ve said, and following that up with a reference to a US-based corporate environment, you’ve judged the words of a non-American who wasn’t speaking to you by your own US-based corporate standards.

                                                                                                        I hope that helps you understand my point more clearly. My point isn’t that Linus does or doesn’t act an asshole (he does), but that expecting non-Americans to adhere to American values, standards or norms is unrealistic at best, and cultural colonialism at worst.

                                                                                                      2. 8

                                                                                                        For older hackers, the code is all that matters, niceties be damned. [..]
                                                                                                        Some of this is a product of money coming in since the 90s, and people who never would’ve been hackers in the past are hackers now.

                                                                                                        No, people who would’ve never been hackers in the past, are not hackers now either.
                                                                                                        And hackers have always cared about more than code. Hacking has always been a political act.

                                                                                                        Linus is not a jerk, his behaviour is pretty deliberate. He does not want to conform.
                                                                                                        He is not much different from Dijkstra, Stallman or Assange.

                                                                                                        Today, cool kids who do not understand what hacking is, insult hackers while calling themselves hackers.

                                                                                                        Guess what? Hackers do care about your polite corporate image as much as they do care about dress code.

                                                                                                        There are definitely cultural issues at play.

                                                                                                        Not an issue. It’s a feature! Hackers around the world are different.

                                                                                                        And we are proud of the differences, because they help us to break mainstream groupthink.

                                                                                                        1. 2

                                                                                                          Hacking has always been a political act.

                                                                                                          This is a really interesting idea! I’m seeing this kind of idea more and more these days and I haven’t been able to work out what it means. I guess you don’t mean something as specific as “Hacking has always been in favour of a particular political ideology” nor something as general as “Hacking has always had an effect on reality”. So could you say something more precise about what you mean by that?

                                                                                                          1. 3

                                                                                                            This is a good question that is worth of a deep answer. I’ll rush a fast one here, but I might write something more in the near future.

                                                                                                            All hacks are political, but some are more evidently so. An example is Stallman’s GNU GPL. Actually the whole GNU project is very political. Almost as political as BSDs. Another evidently political hack was done by Cambridge Analytica with Facebook’s user data.

                                                                                                            The core value of hackers activity is curiosity: hackers want to learn. We value freedom and sharing as a mean to get more knowledge for the humanity.

                                                                                                            As such, hacking is always political: its goal is always to affect (theoretically, to improve) the community in one way or another.

                                                                                                            Challenging laws or authorities is something that follows naturally from such value, but it’s not done to get power or profit, just to learn (and show) something new. This shows how misleading is who distinguish hats’ colours: if you are an hacker you won’t have problems to violate stupid laws to learn and/or share some knowledge, be it a secret military cablage, how to break a DRM system or how to modify a game console: it’s not the economical benefit you are looking for, but the knowledge. The very simple fact that some knowledge is restricted, forbidden or simply unexplored, is a strong incentive for an hacker to try to gain it, using her knowledge and creativity.

                                                                                                            But even the most apparently innocent hack is political!
                                                                                                            See Rust, Go, Haskell or Oberon: each with its own vision of how and who should program and of what one should expect from a software.
                                                                                                            See HTTP browsers: very political tools that let strangers from a different state run code (soon assembly-like) on your pc (ironically with your consent!).
                                                                                                            See Windows, Debian GNU/Linux or OpenBSD: each powerful operating systems which their own values and strong political vision (yes, even OpenBSD).
                                                                                                            See ESR appropriation of the jergon file (not much curiosity here actually, just a pursuit for power)!

                                                                                                            Curiosity is not the only value of an hacker, but all hackers share such value.

                                                                                                            Now, this is also a value each hacker express in a different way: I want everyone to become an hacker, because I think this would benefit the whole humanity. Others don’t want to talk about the political responsibility of hacking because they align with the regime they live in (be it Silicon Valley, Raqqa, Moscow or whatever), and politically aware hackers might subvert it.

                                                                                                            But even if you don’t want to acknowledge such responsibility, if you hack, you are politically active, for better or worse.

                                                                                                            That’s also the main difference between free software and open source software, for example: free software fully acknowledge such ethical (and thus political) responsibility, open source negate it.

                                                                                                            1. 1

                                                                                                              Hacking has always been a political act.

                                                                                                              So if I understand you correctly you are saying something much closer to “Hacking has always attempted to change the world” than “Hacking has always been in support of a political party”.

                                                                                                              1. 1

                                                                                                                Politics is to political parties, what economy is to bankers.

                                                                                                                If you read “Hacking has always been a political act” as something related to political parties, you should really delve deeper in the history of politics from ancient Athens onwards.

                                                                                                                “Hacking has always attempted to change the world”

                                                                                                                No.
                                                                                                                This is a neutral statement that could be the perfect motto/tagline for a startup or a war.

                                                                                                                Hacking and politics are not neutral. They are both strongly oriented.

                                                                                                                Politics is oriented to benefit the polis.
                                                                                                                Indeed, lobbying for particular interests is not politics at all.

                                                                                                                Hacking is not neutral either.
                                                                                                                Hacking is rooted in the international scientific research that was born (at least) in Middle Age.

                                                                                                                Hackers solve human problems. For all humans. Through our Curiosity.

                                                                                                                1. 2

                                                                                                                  IMO, you’re defining “Hacking is political” to the point of uselessness. Basically, nothing is apolitical in your world. Walking down the street is a political statement on the freedom to walk. Maybe that’s useful in a warzone but in the country I live in it’s a basic right to the point of being part of the environment. I don’t see this really being a meaningful or valuable way to talk about things. I think, instead, it’s probably more useful for people to say “I want to be political and the way I will accomplish this is through hacking”.

                                                                                                                  1. 2

                                                                                                                    Basically, nothing is apolitical in your world.

                                                                                                                    Read more carefully.
                                                                                                                    Every human action can serve the polis, but several human actions are not political.

                                                                                                                    Hacking, instead, is political in its very essence. Just like Science. And Math.

                                                                                                                    Maybe it’s the nature of knowledge: an evolutive advantage for the humanity as a whole.
                                                                                                                    Or maybe it is just an intuitive optimization that serves hackers’ curiosity: the more I share my discoveries, the more brains can build upon them, the more interesting things I can learn from others, the more problem solved, the more time for more challenging problems…

                                                                                                                    For sure, everyone can negate or refuse the political responsibility that comes from hacking, but such behaviour is political anyway, even if short-sight.

                                                                                                                    1. 2

                                                                                                                      I just don’t see it. I think you’re claiming real estate on terminology in order to own a perspective. In my opinion, intent is usually the dominating factor, for example murder vs manslaughter (hey, I’m watching crime drama right now). Or a hate crime vs just beating someone up.

                                                                                                                      You say:

                                                                                                                      As such, hacking is always political: its goal is always to affect (theoretically, to improve) the community in one way or another.

                                                                                                                      But I know plenty of people who do what would generally be described as hacking with no such intent. It may be a consequence that the community is affected but often times it’s pretty unlikely and definitely not what they were trying to do.

                                                                                                                      1. 1

                                                                                                                        Saying that “intent is usually the dominating factor” is a political act. :-)

                                                                                                                        It’s like talking about FLOSS or FOSS, like if free software and open source were the same thing. It’s not just false, it does not work.

                                                                                                                        Indeed it creates a whole serie of misunderstanding and contraddictions that are easily dismissed if you simply recognise the difference between the two world.

                                                                                                                        Now, I agree that Hacking and Engineering overlap.
                                                                                                                        But they differ more than Murders and Manslaughters.

                                                                                                                        Because hackers use engineering.

                                                                                                                        And despite the fact that people abuse all technical terms, we still need proper terms and definitions.
                                                                                                                        So despite the fact that everyone apparently want to leverage terms like “hacking” and “freedom” in their own marketing, we still need to distinguish hackers from engineers and free software from open source.

                                                                                                                        And honestly I think it’s easy to take them apart, in both cases.

                                                                                                                  2. 1

                                                                                                                    Could you help me understand better then your usage of the word “politics” because I don’t think it’s one that I am familiar with.

                                                                                                                    1. 1

                                                                                                                      Good question! You caught me completely off-guard!
                                                                                                                      Which is crazy, given my faculty at University was called “Political Science”!

                                                                                                                      I use the term “Politics” according to the original meaning.

                                                                                                                      Politics is the human activity that creates, manages and preserves the polis.

                                                                                                                      Polis was the word ancient Greeks used for the “city”, but by extension we use it for any “community”. In our global, interconnected world, the polis is the whole mankind.

                                                                                                                      So Politics is the set of activities people do to participate to our collective life.

                                                                                                                      One of my professors used to define it as “the art of living together”.
                                                                                                                      Another one, roughly as “the science of managing power for/over a community”.

                                                                                                                      Anyway, the value of a political act depends on how it make the community stronger or weaker. Thus politics is rarely neutral. And so is hacking.

                                                                                                                      1. 2

                                                                                                                        Thanks a lot. That does make things clearer. However I am still confused why under the definition of “Politics is the human activity that creates, manages and preserves the polis.” I admit that I don’t understand what ‘Saying that “intent is usually the dominating factor” is a political act’ but at least I now have a framework in which to think about it more.

                                                                                                          2. 4

                                                                                                            That’s very good explanation. I might add:

                                                                                                            • The author has the luxury of not having to worry about people dying because they didn’t get the message.
                                                                                                            • The author has the luxury of only caring about the message being understood by his own cultural sub-group.

                                                                                                            Linus has none of these luxuries. He cannot err on the side of being too subtle.

                                                                                                            This blog post is just another instance of an American that believes that the rest of the world has to revolve around his cultural norms.

                                                                                                            1. 7

                                                                                                              I think the author did a pretty good job of editing the message in such a way that it was more clear, more direct, and equally forceful, while ensuring that all of that force was directed in a way relevant to the topic at hand.

                                                                                                              (Linus has strong & interesting ideas about standardization & particular features. I would love to read an essay about them. The response to a tangentially-related PR is not a convenient place to put those positions: they distract from the topic of the PR, and also make it difficult to find those positions for people who are more interested in them than in the topic of the PR.)

                                                                                                              The resulting message contains all of the on-topic information, without extraneous crap. It uses strong language and emphasis, but limits it to Linus’s complaints about the actually-submitted code – in other words, the material that should be emphasized. It removes repetition.

                                                                                                              There is nothing subtle about the resulting message. Unlike the original message, it’s very hard to misread as an unrelated tangent about standardization practices that doesn’t address the reasons for rejecting the PR at all.

                                                                                                              The core policy being implemented here is not “be nice in order to avoid hurting feelings”, but “remove irrelevant rants in order to focus anger effectively”. This is something I can get behind.

                                                                                                            2. 2

                                                                                                              I find the American obsession with not upsetting people often infuriatingly two-faced, and I’m British.

                                                                                                              […]

                                                                                                              Go to Poland, fuck up and people will tell you. Go to Germany, do something wrong and people will correct you. Go to Finland, do something stupid getting in the way of a person’s job and probably they’ll swear at you in Finnish.

                                                                                                              Just wanted to point out that America is a huge country and its population is not homogenous. For example, you could have replaced Poland, Germany, and Finland with “Boston” and still have been correct (though, they’d just swear at you in English 🙂).

                                                                                                              I think because most American tech comes out of San Francisco/Silicon Valley that it skews what is presented as “Americanized principals” to the international tech community.

                                                                                                              1. 2

                                                                                                                Just wanted to point out that America is a huge country and its population is not homogenous.

                                                                                                                Down here in the South, they have an interesting mix of trying to look/sound more civil or being blunt in a way that lets someone know they don’t like them or think they’re stupid. Varies by group, town, and context. There’s plenty of trash talking depending on that. Linus’s style would fit in pretty well with some of them.

                                                                                                              2. 1

                                                                                                                If his behaviour is that important to you, don’t use Linux.

                                                                                                                Rather don’t develop the kernel. One can use Linux without having ever heard the nettle Torvalds (the majority I guess)

                                                                                                              1. 7

                                                                                                                This is the best write up on this topic that I’ve ever seen. It’s worth the read.

                                                                                                                1. 6

                                                                                                                  Rust was eliminated for lack of nested functions, which is entirely fair. Although I understand why it was not included in Rust (because of safety problems), I sometimes miss it.

                                                                                                                  Clueless people on HN are arguing why closures are not sufficient. Well, because it’s a different feature.

                                                                                                                  1. 6

                                                                                                                    How is it different? Other than the lack of mutual exclusion enforcement in D, Rust closures seem the same to me. What am missing?

                                                                                                                    1. -1

                                                                                                                      A nested function can modify a variable in the enclosing scope. I don’t think Rust can do that.

                                                                                                                      https://dlang.org/spec/function.html#nested

                                                                                                                      Edit: Whoa, whoa, RESF, just one of you was enough.

                                                                                                                      1. 2

                                                                                                                        A closure can. A fn can’t.

                                                                                                                        1. 2

                                                                                                                          Rust can do that: http://play.rust-lang.org/?gist=cbedf929dc6ee3a45b8e5fa5787460a4&version=stable&mode=debug

                                                                                                                          I wrote it a little differently than D’s example because of the borrow checker. It’s just an example after all, so I don’t feel that bad about it, but if you want to be a stickler to match D’s example more precisely, I’d probably just use interior mutability: http://play.rust-lang.org/?gist=16d817b9a819518d2c51436730b48e75&version=stable&mode=debug

                                                                                                                          Go can also do this as well.

                                                                                                                          1. 2

                                                                                                                            Man, I really have a hard time reading Rust. Why did they have to pick such a weird syntax that looks like nothing else?

                                                                                                                            1. 4

                                                                                                                              Looks fine to me. I was never bothered by it, even when I first started, when the syntax was considerably noisier (before 1.0).

                                                                                                                              But then again, I can’t remember the last time I ever bothered to complain about the syntax of anything. I realize people disagree with me, but as long as it’s reasonableish, I don’t think it matters very much.

                                                                                                                              I also think discussions about syntax are mildly annoying, primarily because most of it probably isn’t going to change. Either you’re willing to live with it or you’re not.

                                                                                                                              edited to soften my language

                                                                                                                              1. 2

                                                                                                                                So it turns out that OCaml is a strong inspiration for Rust and that’s why it looks foreign to me. I didn’t know that.

                                                                                                                                1. 2

                                                                                                                                  I don’t know OCaml either, but I have done a fair amount of work in Standard ML. That got me used to the tick marks used as lifetime parameters (type parameters in SML).

                                                                                                                                  Types after names I think is in Go, which I’ve also done a fair amount of work in. I don’t know if Go originated that though. I’d guess not.

                                                                                                                                  Most of the rest of the syntax is pretty standard IMO. Some things are too abbreviated for some folks’ taste, but I don’t really mind, because once you start writing code, those sorts of things just disappear. They are really only weird to virgin eyes. Some other oddities include using ! in macros and perhaps the different syntaxes for builtin pointer types, e.g., &mut T. (Probably defining macros themselves looks really strange too, but there are a relatively small amount of rules.)

                                                                                                                                  Maybe the closure syntax is weird too, I don’t know. I think it’s similar to Ruby’s syntax? I definitely appreciate the terseness, as found in SML, Haskell and heck, even Javascript’s arrow functions, particularly when compared to Python’s or Lua’s longer syntax. Go’s is also mildly annoying because there’s no type inference, and you need to write out the return keyword. But, you don’t use closures as much in Go as you do in Rust as parameters to higher order functions (in my experience) because of the lack of generics. It’s for loops all the way down.

                                                                                                                                  As long as it’s within a broad realm of reasonableness, syntax mostly just bleeds into the background for me.

                                                                                                                                  It’s also worth mentioning that the use of interior mutability can lead to more noise in the code, especially in an example as terse as the one up-thread.

                                                                                                                          2. 2

                                                                                                                            You can if the closure borrows a reference to the value (which is necessarily how it works in D). Sharing a mutable reference requires an explicit Cell/RefCell/UnsafeCell, though. UnsafeCell would presumably have the same semantics as in D.

                                                                                                                            1. 2

                                                                                                                              Edit: Whoa, whoa, RESF, just one of you was enough.

                                                                                                                              Instead of being a troll about it, you might consider that we all started responding around the same time and didn’t know others had already done so. (e.g., When I clicked post, Steve’s comment wasn’t on my page.)

                                                                                                                              1. 1

                                                                                                                                Well, the RESF is pretty strong. I make one off-hand wrong comment and three of you, whether intentionally or not, jump on it. I practically never get that many comments in quick succession in Lobsters. I obviously struck a nerve by speaking a falsehood that must be corrected immediately.

                                                                                                                                I’m also slightly unhappy that we can’t ever talk about D without “I would like to interject for a moment, what you are referring to as D is in fact Rust or as I’ve taken to calling it, CRATE+Rust”.

                                                                                                                                1. 3

                                                                                                                                  I called out the RESF effect here. Hit Twitter immediately haha. Ive been keeping an eye out since. Ive seen no evidence of an active RESF here or on HN. Just looks like a mainstream language with a lot of fans, areas of usefulness, and therefore lot of comments. I see more comments about Go than Rust.

                                                                                                                                  And then there’s Pony. Now, that one comes across as having an evangelism team present. ;)

                                                                                                                                  1. 1

                                                                                                                                    that one comes across as having an evangelism team present

                                                                                                                                    Where? :) I’d like to read more actual articles about Pony, but all I’ve seen so far are links to minor release announcements…

                                                                                                                                    1. 3

                                                                                                                                      It was an inside joke about the Pony fan club we have here on Lobsters. Sometimes I see more Pony articles than those for mainstream languages. They usually have plenty of detail to be interesting enough for the site. Only exceptions are release submissions. I’m against release submissions in general being on this site since people that care about that stuff will likely find the release anyway. Might as well use that slot for something that can teach us something or otherwise enjoyable.

                                                                                                                                  2. 3

                                                                                                                                    The OP mentions Rust, and you were talking about it too. Scanning the posts tagged with D, I see exactly one substantive discussion involving Rust other than this thread. So I’m going to have to call shenanigans.

                                                                                                                                    Well, the RESF is pretty strong.

                                                                                                                                    Just stop. If you have an issue, then address it head on instead passive aggressively trolling.

                                                                                                                                    D and Rust are used to solve similar sets of problems. This invites comparisons, not just on the Rust side but on the D side too. A lot of people who haven’t used Rust get their claims mixed up or are just outright wrong. I see nothing bad about politely correcting them. That’s what I did for your comment. What do I get in exchange? Whining about syntax and some bullshit about being attacked by the RESF. Please. Give me a break.

                                                                                                                                    Do you want to know why you don’t see me talking about D? Because I don’t know the language. I try not to talk about things that I don’t know about. And if I did, and I got something wrong, I’d hope someone would correct me, not just for me, but for anyone else who read what I said and got the wrong idea.

                                                                                                                          1. 7

                                                                                                                            Meanwhile, a friend of mine just got a response on a PR. Written in nice polite professional prose: “Sure, we can merge that, thanks for this improvement, but would you first please …” and that’s where it spun off into senselessness. It was all politely written, no swearing, but made no sense.

                                                                                                                            Linus will swear. And read the code. And understand both the code and what you tried to do, and have a decent idea of what’s achievable.

                                                                                                                            It seems to me that some people really mind the swearing, and do not realise that everyone has faults. Complaining about swearing isn’t a step towards faultless people, it’s effectively pushing us towards other faults, the ones that get no complaints.

                                                                                                                            1. 18

                                                                                                                              Why is there a dichotomy? Why would reducing rudeness be “pushing us towards other faults”?

                                                                                                                              1. 0

                                                                                                                                Suppose you are to choose a team leader. You can choose a team leader, but you have to choose from among the people who are there, none of whom are saints. One will swear like a sailor, another doesn’t care about documentation, a third suffers from Rambling Meeting Syndrome. Disallowing one of them for one fault doesn’t happen in a vacuum, because “none of the three” is not an option.

                                                                                                                              2. 21

                                                                                                                                Removing or reducing one fault doesn’t necessarily imply the rise of another. Someone can both say nonsense and be a jerk at the same time, but I’d rather they just say nonsense.

                                                                                                                                I’ve certainly responded to PRs with nonsense occasionally. It happens, because I didn’t read closely enough or just missed something. But I at least try not to be jerk.

                                                                                                                                Should people be jerks? I’d rather not. At least try not to.

                                                                                                                                Should people say nonsense? Again, I’d rather not.

                                                                                                                                The world doesn’t have to be seen as black or white. People can ask others to not be a jerk without simultaneously endorsing the rise of nonsense.

                                                                                                                                1. 17

                                                                                                                                  It seems to me that some people really mind the swearing

                                                                                                                                  I’m from New England. I swear a lot.

                                                                                                                                  That said, Torvald’s candor is unacceptable. There’s no reason to devolve into namecalling (“moron”, “brain damaged”) that’s clear intent is to hurt feelings.

                                                                                                                                  So no, I don’t mind the word “fuck.” However, I really fucking mind it when people insult other’s intelligence with the intentionality of hurting their feelings. Who would want to work on a project like that? I know that I wouldn’t.

                                                                                                                                  1. 9

                                                                                                                                    Pretty sure being crude and being nonsensical both garner complaints, for example, you’re complaining about your friend’s nonsensical PR response, and the author here is complaining about Linus’s crude and belittling language.

                                                                                                                                    While understanding the issues is much appreciated, so is not being a jerk. Technical skills have brought us this far, but soft skills will help bring us to a future where more and more people are willing to get involved with open-source (and other) projects.

                                                                                                                                    1. 13

                                                                                                                                      I don’t think the article is about swearing. It’s about verbal abuse and how to convey the same information without attacking the recipient.

                                                                                                                                      1. 5

                                                                                                                                        You hit the nail on the head. I feel like we’re moving rapidly towards a culture of, “Let’s all celebrate diversity and embrace inclusion, except for those who we disagree with who are just going to have to change their barbaric ways.”

                                                                                                                                        For every person who is offended by swear words (I mean, words of all things) there’s someone else who reads a phrase like, “this is pure and utter bullshit,” who thinks, man, this person is really passionate about what they’re talking about, maybe they have something interesting to say.