1. 45

    RustTL;DR: It’s a very impressive language with a clear vision and priorities, but the user interface needs a lot of work. Also, the collection library is much better than Scala’s.

    • Generics with <>. It’s 2017 by now, we know it’s a bad idea. One of the reasons why the language suffers from abominations like the “turbofish” operator ::<>.

    • Strings don’t offer indexing, because it doesn’t make sense for UTF-8. Correct! But Strings offer slicing … WAT?

    • Misuse of [] for indexed access. Having both () and [] doing roughly the same thing, especially since [] can be used to do arbitrary things, doesn’t make sense. Pick one, use the other for generics.

    • Inconsistent naming. str and String, Path and PathBuf etc.

    • :: vs. . is kind of unnecessary.

    • Mandatory semicola, but with some exceptions in arbitrary places: struct Foo; vs. struct Foo {}

    • Arbitrary abbreviations all over the place. It’s 2017, your computer won’t run out of memory just because your compiler’s symbol table stores Buffer instead of Buf.

    • Can someone decide on a casing rule for types, please, instead of mixing lowercase and uppercase names? Some types being “primitive” is an incredibly poor excuse.

    • Also, having both CamelCase and methods_with_underscores?

    • Library stutter: std::option::Option, std::result::Result, std::default::Default

    • iter(), iter_mut(), into_iter() … decide prefix or postfix style and stick with it.

    • Coercions do too many things. For instance, they are the default way to convert i32 to i64, instead of just using methods.

    • Also, converting numbers is still broken. For instance, f32 to i32 might result in either an undefined value or undefined behavior. (Forgotten which one it is.)

    • Bitcasting integers to floats is unsafe, because the bits could be a signaling NaN, causing the CPU to raise an FP exception if not disabled.

    • Forward and backward annotations: #[foo] struct Foo {} vs struct Foo { #![foo] }. Also /// for normal documentation, //! for module level documentation. Documentation already uses Markdown, so maybe just let people drop a markdown file in the module dir? That would make documentation much more accessible when browsing through GitHub repositories.

    • Also, documentation can cause compiler errors … that’s especially fun if you just commented a piece of code for testing/prototyping.

    • Type alias misuse: In e.g. io crate: type Result<T> = Result<T, io::Error> … just call it IoResult.

    • Macros are not very good. They are over-used due to the fact that Rust lacks varargs and abused due to the fact that they require special syntax at call-site (some_macro!()).

    • Pattern matching in macros is also weird. x binds some match to a name in “normal” pattern matching, but matches on a literal “x” in “macro pattern matching”.

    • println! and format! are very disappointing given that they use macros.

    • Compiler errors … ugh. So many things. Pet peeve: “Compilation failed due to 2 errors” … 87 compiler errors printed before that.

    1. 7
      • Library stutter: std::option::Option, std::result::Result, std::default::Default
      • Type alias misuse: In e.g. io crate: type Result<T> = Result<T, io::Error> … just call it IoResult.

      How ya gonna square that circle?

      1. 2

        I think std::io::IoResult would be fine – it would solve the issue of having vastly different Results flying around, while not having single-use namespaces that are only used by one type.

        1. 1

          The general pattern is to import Io instead. When doing this, IoResult would be jarring.

          use std::io;
          
          fn my_fun() -> io::Result<T> {
          
          }
          
      2. 13

        It’s 2017,

        I have some news for you, @soc.

        1. 3

          Haha, good catch. Now you see how old this list is. :-)

          The only thing I got to delete since then was “get rid of extern crate”.

        2. 3

          What’s your preferred alternative to generics with <>?

          1. 6

            [], as it was in Rust before it was changed for “familiarity”.

            Unlike <>, [] has a track of not being horribly broken in every language that tried to use it.

            1. 5

              How is <> broken?

              1. 16

                It complicates parsing due to shift and comparison operators.

                1. 2

                  Ah, yeah, that makes sense.

                2. 19

                  Pretty much no language has ever managed to parse <> without making the language worse. The flaws are inherent in its design, as a compiler author you can only pick where you place the badness; either:

                  • Add additional syntax to disambiguate (like ::<> vs. <> in Rust).
                  • Have weird syntax to disambiguate (like instance.<Foo>method(arg1, arg2) in Java).
                  • Read a potentially unlimited amount of tokens during parsing, then go back and fix the parse tree (like in C#).
                  • etc.

                  In comparison, here are the issues with using [] for generics:

                  • None.

                  For newly created languages (unlike C++, which had to shoehorn templates/generics into the existing C syntax) it’s a completely unnecessary, self-inflicted wound to use <> for generics.

                  More words here: Why is [] better than <> for generic types?

                  1. 2

                    Those are good reasons to not use <>, but as a Haskeller I personally find either style somewhat noisy. I’d rather just write something like Option Int. Parentheses can be used for grouping if needed, just like with ordinary expressions.

                    1. 2

                      Haskell feels like it is in the same category as D, they both just kicked the can a tiny bit further down the road:

                      Both need (), except for a limited special-case.

                      1. -1

                        I don’t see how Haskell kicked the can down the road. The unit type is useful in any language. Rust has a unit type () just like Haskell. Scala has it too.

                        I’m not sure what “special case” you are referring to.

                        1. 2

                          The fact that you still need () for grouping types in generics as soon as you leave the realm of toy examples – just as it is in D.

                          (Not sure what’s the comment on the unit type is about…)

                          1. 4

                            Ah, I understand what you’re saying now. But that’s already true for expressions at the value level in most programming languages, so personally I find it cleaner to use the same grouping mechanism for types (which are also a form of expressions). This is especially applicable in dependently typed languages where terms and types are actually part of the same language and can be freely mixed.

                            However, I can also appreciate your argument for languages with a clear syntactic distinction between value expressions and type expressions.

              2. 1

                D’s use of !() works pretty well. It emphasizes that compile-time parameters aren’t all that crazy different than ordinary runtime parameters.

                1. 1

                  I prefer my type arguments to be cleanly separated from value arguments (languages that fuse them excepted).

                  I find D’s approach slightly ugly, especially the special-cases added to it.

                  1. 1

                    I prefer my type arguments to be cleanly separated from value arguments

                    Well, in D they aren’t type vs value arguments, since you can pass values (and symbol aliases) as compile-time arguments as well. That’s part of why I like it using such similar syntax, since it isn’t as restricted as typical type generics.

                    I find D’s approach slightly ugly, especially the special-cases added to it.

                    The one special case is you can exclude the parenthesis for a single-token CT argument list and actually I thought I’d hate it when it was first proposed and I voted against it… but now that it is there and I used it, I actually like it a lot.

                    Sure does lead to a lot first timer questions on the help forums though… it certainly isn’t like any other language I know of.

              3. 2

                Also, converting numbers is still broken. For instance, f32 to i32 might result in either an undefined value or undefined behavior. (Forgotten which one it is.)

                Yeah, I kind of feel the same way. Even with try_from() dealing with number conversions is a pain in Rust.

                1. 1

                  You saved me a lot of typing. 100% agree.

                  1. 1

                    Thanks! I’d love to know the reason why someone else voted it down as “troll” – not because I’m salty, but because I’m genuinely interested.

                  2. 1

                    2 pains I have with Rust right now:

                    • I would like to be able to connect to a database (Teradata specifically)
                    • I want to launch a subprocess with other than the default 3 stdio descriptors (e.g. exec $CMD $FD<>$PIPE in sh)
                    1. 2

                      I know it’s technically unsafe and that might preclude it from your use, but does CommandExt::pre_exec not fit your bill?

                      1. 1

                        That could work. I’m still new to Rust so I haven’t fully explored the stdlib.

                    2. 1

                      Ahahaha, this is a great list. I’m curious about a couple things though, since you’ve obviously put a lot of thought into it…

                      Bitcasting integers to floats is unsafe, because the bits could be a signaling NaN, causing the CPU to raise an FP exception if not disabled.

                      The docs for f32::from_bits() and such talk about precisely this, but I considering the misdesign of signaling NaN’s really don’t see how it could possibly be made better. Any ideas?

                      …They are over-used due to the fact that Rust lacks varargs…

                      What little experience I have with programming language design makes me feel like varargs are a hard problem to deal with in a type-safe language, at least if you want to allow different types for the args (instead of, say, forcing them all to be what Rust would call &dyn Display or something). Do you know of any language which does it Right?

                      1. 1

                        The docs for f32::from_bits() and such talk about precisely this, but I considering the misdesign of signaling NaN’s really don’t see how it could possibly be made better. Any ideas?

                        Rust could have disabled the trapping of signaling NaN’s on start up, but I think Rust fell into the same design mistake of C:

                        Scared of making the use-case of the 0.01% (people who want signaling NaN’s to trap) harder to achieve, they made life worse for the 99.99%.

                        varargs are a hard problem to deal …

                        Agreed, it’s safe to say that language designers hate them. :-)

                        … at least if you want to allow different types for the args

                        I think this is only partially the reason. You can still have only same-typed varargs at runtime, but allow recovering the individual types of the arguments in macro calls – which is exactly the case for format! and friends.

                        Do you know of any language which does it Right?

                        I think in the case of format strings, focusing on varargs is the wrong approach. If you imagine how you want an ideal API to look like, you probably want to interpolate things directly inside the string, never having to go through the indirection of some vararg method.

                        Instead of having the formatting parameters in one place, and the to-be-interpolated values in a different one, like in …

                        let carl = "Carl"
                        let num = 1.234567;
                        format!("{}'s number is {:.*}, rounded a bit", carl, 2, num)
                        // -> "Carl's num is 1.23, rounded a bit"
                        

                        … wouldn’t it be much nicer to write (this is Scala):

                        val carl = "Carl"
                        val num = 1.234567
                        f"$carl's num is $num%.2f, rounded a bit"
                        // -> "Carl's num is 1.23, rounded a bit"
                        
                        1. 1

                          Julia has nice string interpolation too. I honestly don’t understand why more programming languages don’t have it. Does everyone just forget how useful it is in bash when they come to design their language?

                    1. 1

                      Has anyone managed to get on the “general” mailing list for this project?

                      1. 1

                        Fixed :) Sorry for the noise.

                      1. 12

                        I’ve been evaluating sourcehut recently and I was involved in the Neovim/OpenBSD CI integration.

                        The testing infrastructure is really good and it’s really simple to fire up VMs running different BSDs and Linuxes. I much prefer it to travis, which is just a pain to set up.

                        The git side of things is very minimal, and you won’t see things like pull requests (they recommend using the email workflow). If you want PRs, then you can integrate sr.ht with GitHub. Personally I prefer the PR workflow and my guess is that the majority of others would too. Nonetheless, I moved one personal project (for which I don’t expect collaboration) to sr.ht and it all seems to work fine. Perhaps a little slow to push, but that’s geography for you.

                        I’ve not played with the mailing lists or todos much yet.

                        I’d say I’m likely to donate, as I’d like to see a BSD-friendly github alternative succeed.

                        1. 15

                          I am really pleased with sourcehut. Neovim project needed CI for OpenBSD and FreeBSD. I was dreading the yak-shaving, but spent ~20 minutes and now we are set up: https://builds.sr.ht/~jmk/neovim

                          1. 2

                            Agreed. It was very simple :)

                          1. 6

                            The number of times I’d wished I had this feature on Travis.

                            Instead you just end up blindly pushing changes to the branch in the hope that it works :P

                            1. 4
                              1. 3

                                Only on Travis-ci.com (the paid version), and not Travis-ci.org (the free version).

                                1. 4

                                  sr.ht is also a paid service, right?

                                  1. 4

                                    It’s up to you whether to pay or run the exact same free software on your own infra.

                                    1. 2

                                      Is it easy to run on your own? That’s kind of cool. I may pay them anyway but still run it myself.

                                      1. 9

                                        https://man.sr.ht/installation.md

                                        Reach out to the mailing list if you run into trouble :)

                                        1. 1

                                          Wow, cool! Thanks :)

                                      2. 1

                                        You can also run travis-ci.org on your own infra (I currently do this) but there isn’t a lot of info about it.

                                    2. 3

                                      The trick is that for public repos, you have to email support: https://docs.travis-ci.com/user/running-build-in-debug-mode/#enabling-debug-mode

                                      1. 1

                                        Weird… I guess that they’re trying to prevent wasted containers by adding manual process in the middle?

                                        1. 2

                                          It’s a security risk, especially for public repos.

                                          1. 2

                                            Eeeek, that’s rough. builds.sr.ht’s SSH access uses the SSH keys we already have on your account for git authentication et al.

                                            1. 1

                                              You get that from Github, too. But I also think it doesn’t help, because GH projects are liberal with adding people to orgs/repos and while they cam be grouped, there’s no way to assign structures roles. GH as an identity provider is mediocre at best.

                                            2. 1

                                              Like, in terms of things which they may do in the shells, DDoSing by creating too many, etc? They use your SSH key from GitHub to prevent others from SSHing in, right?

                                              1. 4

                                                They use your SSH key from GitHub to prevent others from SSHing in, right?

                                                Not AFAIR. It gives a temporary login/password in the build log (which is public). And anyone who logs in can see the unencrypted secrets (e.g. API keys used for pushing to GitHub).

                                                1. 1

                                                  oooooooh… yipes. Super dangerous. CircleCI uses SSH keys to improve on this.

                                        2. 1

                                          Aren’t they doing some funky reorganization to eliminate the split? I haven’t looked closely so I might be wrong.

                                        3. 2

                                          I guess I’ve just been too cheap to pay then ;)

                                        4. 1

                                          This feature is on Travis, but their new configuration API is so excruciatingly painful and lacking of reasonable documentation that it fails to help when it’s really needed.

                                          1. 1

                                            With Gitlab you can debug CI stages on your machine by starting a local Gitlab Runner.

                                          1. 1

                                            One of those weird git hosting sites that don’t put code first. And that file browser’s is really bad. Who sorts files and directories alphabetically? Usually you put directories first.

                                            1. 2

                                              And that file browser’s is really bad. Who sorts files and directories alphabetically?

                                              I feel this isn’t totally fair. There’s a big red box on the front page that makes it quite clear that it’s early days for development:

                                              Achtung! Sourcehut is still under heavy development, and while many of the services are usable, expect to find lots of missing polish, broken links, incomplete docs, and so on. Here be dragons!

                                              Why don’t you submit an issue?

                                              1. 1

                                                I feel this isn’t totally fair. There’s a big red box on the front page that makes it quite clear that it’s early days for development

                                                Fair to who? Its just obvious flaws.

                                                Why don’t you submit an issue?

                                                I don’t really care.

                                            1. 3

                                              Privacy:

                                              When you host your own mailserver, you truly own your email without having to rely on any third-party.

                                              Yeah, not really.

                                              • If you send email to someone with a Gmail address, then Google reads the email.
                                              • If someone send you an email from a Gmail address, Google reads the email.

                                              Only in a scenario where both parties own their infrastructure do you get the privacy gain the author assumes. Even then, you have to trust that the third party has good intentions and sound security practices.

                                              I think the best approach to (unencrypted) email is to assume that anyone can read it.

                                              1. 1

                                                I still relay outgoing mail through Google (most of which is to public mailing lists or GMail accounts anyway), but I set up a receive‐only mail server last month, and now Google no longer has access to my sales receipts, my utility bills, my flight itineraries, nor knows all the mailing lists I subscribe to. That’s a big win in my book, even if email is ultimately unsecurable.

                                              1. 1

                                                On the left side of the laptop are two Thunderbolt 3-enabled USB-C ports, a port for the ethernet dongle (which annoyingly blocks the second USB-C port when it’s plugged in), a USB-A port… On the right side are another USB-A port

                                                I have the 5th generation model, which has the same USB configuration as the 7th, and my only real complaint is that I have to carry a USB hub to have more ports.

                                                1. 5

                                                  It’s been on this site before, but it wasn’t caught by the duplicate link checker because the domain changed: https://lobste.rs/s/u4imgn/sr_ht_is_now_sourcehut

                                                  1. 5

                                                    It’s been long enough a repost is OK. The hard limit is a week.

                                                    1. 1

                                                      The hard limit is a week.

                                                      Gosh, do you really want to allow slightly-older-than-1-week material to be reposted here?

                                                      1. 6

                                                        When I said “hard limit” I was thinking of what the code enforces, and I remembered wrong, it’s 30 days. Whoops. I’ve used a week as the time period for merging duped stories/hot takes so big news doesn’t take over the homepage.

                                                        1. 1

                                                          Wow, that list of articles. That is certainly a powerful case for why the feature needs to exist.

                                                          1. 1

                                                            Thanks for the clarification! I’m usually not that quick to flag submissions as “already posted” but now I know there’s an informal limit I can make more informed choices.

                                                      2. 1

                                                        Oops! Thanks for letting us know!

                                                      1. 2

                                                        I stumbled across this recently. Claims to support testing on BSDs, which may make it a suitable travis-a-like substitute for BSD folk.

                                                        1. 3

                                                          Yes, it’s really cool, Drew DeVault here made it~!

                                                          1. 2

                                                            I have been using SourceHut for git and NixOS CI, and it is really awesome. Consider subscribing!

                                                          1. 3

                                                            This isn’t any fundamentally different than issuing su or similar from an Xterm and sending keystrokes to it. (Interestingly, Windows does mitigate that particular case - if there’s a privileged application’s window, you can’t send messages to it from a lower privileged window.)

                                                            1. 1

                                                              I was unable to get the xterm trick to work: https://lobste.rs/s/2fqraj/tmux_privilege_escalation#c_2ixk3w

                                                            1. 4

                                                              This is super-misleading.

                                                              Of course, if you su to root in a tmux, then you can send keys from another of your unprivileged panes.

                                                              Even if tmux didn’t have the keystroke sending functionality, you could just attach to the session containing the root shell and send keys that way!

                                                              TL;DR: If you log in as root, you can run commands as root! Shocker!

                                                              1. 2

                                                                I don’t understand. How can you send keys [from a script or program] without send-keys, and without typing on the [victim’s] keyboard?

                                                                1. 2

                                                                  If the user ‘jack’ starts a tmux session called S1:

                                                                  tmux new -sS1
                                                                  

                                                                  Then he uses sudo and the tmux session now contains a root shell.

                                                                  The linked article now points out that if someone with access to jack’s account opens another tmux session S2, they can send keys to the session S1 and have root commands executed.

                                                                  This of course assumes that the “attacker” has access to jacks account in the first place in order to create S2. Both sessions must be owned by the same user so that the sessions use the same tmux socket for communication (and I’m assuming the socket permissions have not been fiddled).

                                                                  But if you have access to jack’s account to create S2, then you can also just do:

                                                                  tmux a -tS1
                                                                  

                                                                  and see the root shell in S1 anyway. So, what’s the big deal?

                                                                  All we really learn is that you shouldn’t leave root shells hanging around, but that’s standard practice.

                                                                  1. 2

                                                                    I think what the author was trying to point out is that you could send keys to the root shell without having enough access to jack’s account that you could type (in real time) arbitrary shell commands to the root shell. I think the/a scenario would be the malicious actor getting the victim to run a script or program (which the actor created).

                                                                    1. 1

                                                                      I think what the author was trying to point out is that you could send keys to the root shell without having enough access to jack’s account that you could type (in real time) arbitrary shell commands to the root shell

                                                                      That’s not what I take away from the article:

                                                                      su # login as root
                                                                      Now go back to the other tmux pane (where you are logged in as user). Now run the following script…

                                                                      So there’s the explicit assumption that you already have used su (or similar) to get root access, and you already have an unprivileged shell.

                                                                      I think the/a scenario would be the malicious actor getting the victim to run a script or program (which the actor created).

                                                                      Well yes, tmux cannot protect users from themselves. By the same logic, all shells are arbitrary code execution vulnerabilities ;)

                                                                      1. 1

                                                                        By the same logic, all shells are arbitrary code execution vulnerabilities

                                                                        But can you run from a non-root shell commands as root without knowing the root password?

                                                                        1. 1

                                                                          I take your point, but isn’t this also not unique to tmux? I think you could pull the same trick using /dev/tty* device nodes if you logged in as jack and used su?

                                                                          1. 1

                                                                            I think so. Others have pointed out similar already-existing concerns with TTYs.

                                                                            1. 3

                                                                              Having thought about your point some more, I think you are on to something.

                                                                              Here’s a more compelling scenario:

                                                                              Suppose some rogue code entered a software package, which subsequently was imported into an OS package manager, or a programming language package manager (pip, npm, …). The untrusted code could be scanning for tmux sessions or ttys which were initiated by unprivileged users, but which have escalated privileges through sudo/su/doas/…

                                                                              In another scenario, perhaps untrusted Javascript code from the Internet could have broken its browser sandbox and employed the same kind of scanning.

                                                                              So actually, @Pistos, you’ve changed my mind! Hat off to you sir!

                                                                              My next question: how do you mitigate it? Only ever log in as root from the system console? Then the tty device node is presumably owned by root? Make ttys and tmux “root aware” (ugh)?

                                                                              1. 2

                                                                                Well, what I do is start tmux directly as root for root operations. I don’t use sudo for one-off root command execution. I’m thinking this should keep me safe from this particular vulnerability.

                                                                                1. 2

                                                                                  Yeah @Pistos may be changing my mind here also. If you were the tmux maintainer, what would you do about this? I use tmux daily (can’t imagine living without it) and genuinely am not sure what a reasonable solution to this would be. Check privilege/user levels between panes? But what if you use tmux to ssh to multiple nodes, and send-keys to issue simultaneous identical commands across nodes?

                                                                                  1. 3

                                                                                    I’m still not convinced this is a tmux-only issue by the way. See my comment above about tty device nodes possibly having the same problem (not had a chance to test it yet).

                                                                                    1. 1

                                                                                      I tried doing the same thing using device nodes on my OpenBSD box: $ echo “ls\n” > /dev/ttyp4

                                                                                      This will print the string to the other terminal (an xterm in this case), but not execute it. So either I used the wrong line ending (also tried \r and \r\n), or ttys are not vulnerable in the same way.

                                                                1. 9

                                                                  Statically-typed functional languages are amazing. They have a property that exists almost nowhere else: if your program compiles, it works.

                                                                  Ahem…

                                                                  1. 4

                                                                    It’s true if the author has very distorted notion of what “it works” means.

                                                                    Lets say you wanted a program that sorts a list. What’s the type signature? It needs some sorting function, and list to sort as the input. The result would be a sorted list.

                                                                    Now if we do Haskell we can’t represent sorted lists (probably some dude comes to say it’s got an extension for this), but hey it’s okay. We can accept that it works if it compiles.

                                                                    sort :: (a -> a -> bool) -> [a] -> [a]
                                                                    sort lt list = []
                                                                    

                                                                    Since it compiles, it works. But you didn’t get the list sorted? Well that’s because you were unable to tell the type system that the list must be sorted. But it works since it compiles. The program perfectly matches the definition in the type after all.

                                                                    If the user complains too much, you can supply the second program:

                                                                    sort lt list = sort lt list
                                                                    

                                                                    Since it compiles, it works. Perfectly. It’s perfectly correct program because we say so.

                                                                    1. 0

                                                                      Now if we do Haskell we can’t represent sorted lists

                                                                      Are you sure?

                                                                      1. 7

                                                                        Yes. We’ll consider Haskell 2010. In this example, your referenced type is defined as:

                                                                        newtype SortedList a = SortedList [a] deriving (Eq, Ord)
                                                                        

                                                                        This clearly does not encode any sorted requirement in the type. Only smart constructors and programmer discipline can keep that list sorted.

                                                                        Here are some list functions. They all have the same signature, but different behaviors:

                                                                        id :: [a] -> [a]
                                                                        return . head :: [a] -> [a]
                                                                        reverse :: [a] -> [a]
                                                                        const [] :: [a] -> [a]
                                                                        init :: [a] -> [a]
                                                                        (++ []) :: [a] -> [a]
                                                                        

                                                                        Nothing in the type system can issue salvation here. Nothing surrounding the type system, either; the relevant theorem for free concerns map, which doesn’t appear here. Haskell’s type system doesn’t cover:

                                                                        • Partial functions, like head
                                                                        • Shape-preserving element-agnostic permutations, like reversing a list without looking inside it
                                                                        • Linearity and naturality, ensuring that arguments are used
                                                                        • Shape-preserving non-linear transformations, like init
                                                                        • Operations which normalize to id but predictably and reliably incur runtime costs, like appending an empty list to the end of a singly-linked list
                                                                        1. 0

                                                                          Of course you are totally correct, but I’d like to make the argument in practical terms. If you want to encode a sorted list in the type signature, you can, at least in practice.

                                                                          This is like the inverse of the argument that you can do FP in JavaScript. Theoretically you can, but in practical terms it just doesn’t work.

                                                                    2. 2

                                                                      This is effectively true for pure functional code if you unit-test it. Once you add side-effects, it’s harder to be sure.

                                                                      1. 3

                                                                        Unit testing helps, yes, but that’s not what the author is implying.

                                                                        1. 2

                                                                          This isn’t true either. Consider a complex simulation encoded as a pure function. A unit test just shows it gives the expected output for a given input, not that it correctly solves the problem for all inputs.

                                                                          This is also true for PBT. Just pick more complex pure functions.

                                                                          1. 3

                                                                            Indeed. That’s why I said it “helps”: you are still up against test coverage.

                                                                            You can unit test and statically analyse all day, but you can always insert bugs that won’t be caught.

                                                                        2. 1

                                                                          Author here. Good point. What I was referring to was the observation that many people make when using Haskell/OCaml/Elm, that once they’ve got it compiling it usually (or maybe just often?) works. I definitely overstated that.

                                                                          1. 1

                                                                            Well, you won’t get any type errors ;)

                                                                        1. 3

                                                                          such a person would remove the surrounding $(..) to find out what a victim would have been fooled into executing

                                                                          I very nearly did exactly this, but thought “nah, better not”.

                                                                          1. 1

                                                                            Cool!

                                                                            I’ve never used VMS. What would it be good for in 2019 on an x86_64 machine?

                                                                            1. 3

                                                                              @trn’s description is great. I”ll add two things:

                                                                              1. Security is probably behind BSD’s and Linux’s now if you’re using all the state of the art sandboxes, compiler tools, and so on. What any given company or distro does varies considerably. VMS’s default capabilities (circa 1999) were better than UNIX’s defaults, though. It had finer-grain permissioning of processes, CPU/memory metering like in clouds, and most services off-by-default like in OpenBSD. Since it was expensive and unfamiliar to hackers, it also had only about twenty something CVE’s versus hundreds for Linux and Windows. Better security design plus obfuscation equaled less attacks in practice. Note that higher-security extensions like SEVMS and VAX Secure VMM (pdf) existed. Just nobody buying higher security stuff at the time. VMM was cancelled. Idk if SEVMS still available.

                                                                              2. I don’t have any market data about banking use. I do have a banking example (pdf) that, on 9/11, perfectly illustrated why many companies run critical stuff on VMS clusters. It also shows off the AlphaServer hardware that kept running as all the Wintel machines crashed. Just mentally compare that to all the outages you see on these online services running on Linux. That kind of thing isn’t tolerated in OpenVMS shops. Cost a lot to get the reliability, though.

                                                                              HP had a guide on using OpenVMS for disaster tolerance. It goes into a lot of detail about the topic in general that can aid efforts outside of OpenVMS. It also shows how thoroughly the OpenVMS ecosystem had this covered.

                                                                              1. 2
                                                                                1. Security is probably behind BSD’s and Linux’s now if you’re using all the state of the art sandboxes, compiler tools, and so on.

                                                                                That’s the problem with a proprietary monolithic operating system that is designed and not “grown” organically - it stagnates once the stewards begin to neglect it.

                                                                                OpenVMS did not get the attention it deserved after passing through so many hands after DEC (at Compaq and HP/HPe).

                                                                                VMSI’s team consists of numerous ex-DEC employees and many original core VMS developers. Their senior engineer who lead the x86-64 effort is the man who oversaw the VAX to Alpha transition at Digital.

                                                                                I really hope they can succeed with VMS.

                                                                                1. 2

                                                                                  I agree. There might have been extra motivation for letting it stagnate when they had two, competing products with NonStop being more profitable. I like that the new team has the necessary experience. What they’ll do for security… who knows.

                                                                              2. 2

                                                                                VMS excels where you need fine grained security, tight clustering, functional yet relatively simple management of a large cluster, unified and simple networking and communication between users and processes, most importantly, extremely high reliability and stability, and the ability to support a very large number of interactive users or terminals on modest hardware.

                                                                                Historically, VMS was also rather unique because it was a single software system and management platform which scaled from very modest pizzabox form-factor desktop systems to extremely large mainframe-class clustered systems that spanned entire raised-floor datacenters. That may be taken for granted now with large UNIX and NT systems, but remember that VMS was a mature product when UNIX was still in it’s (commercial) infancy, and the UNIX market and UNIX implementations were very fragmented, with the datacenter-ready UNIX systems all being very different independent developments.

                                                                                VMS systems were, and still are, used in safety and life-critical applications in industries like defense, oil and natural gas, power generation, nuclear, shipping and transportation, rail, factory and process automation, etc.

                                                                                (While some big finance/banking users existed, as far as I know, VMS never really took off in that market, which was, and still is, dominated by IBM, Stratus, and NonStop.)

                                                                                There used to be a very large community of scientific and research users (both in academia and industry) who used VMS, mainly in high-energy particle physics and astronomy. Most of those users used the computers not because they were “computer people”, but because they just needed computers in the course of their work and wanted systems that would “just work” and otherwise stay out of the way.

                                                                                1. 2

                                                                                  Somewhat straying from the original question, but, remember, was also a time not so long ago, that UNIX vendors - especially supercomputer manufacturers - were aggressively marketing VMS compatible and interoperable systems.

                                                                                  Convex was big player with CoVue - The Convex-to-VMS User Environment which offered system (DAP, DECnet), user (DCL, EDT), and developer (VMS RTL) compatibility with VMS.

                                                                                  UNIX was a tough sell in traditionally VMS-heavy markets, and an impossible without getting the users to buy in. There were very real management concerns about retraining staff and lower productivity — even if the replacement hardware was more powerful, it’s useless without users.

                                                                                2. 0

                                                                                  V9.0 will be for a selected set of customers and partners to get a head start on porting their applications

                                                                                  Good thing they are keeping it isolated and far from wide spread introduction. It’ll be amusing how many kilo dollars per core its going to be to have the honour of this dead end zombie

                                                                                1. 4

                                                                                  I have yet to see a GC’d language written in rust that doesn’t cop out and use Rc .

                                                                                  1. 3

                                                                                    What’s wrong with using Rust’s Rc standard library feature to implement garbage collection? You gotta write the garbage collector in some non-garbage-collected language after all, and while I’m not an expert in GC implementation, I would think that any GC is going to need some kind of reference counting semantics. So why not use the one that’s built into the Rust standard library?

                                                                                    1. 2

                                                                                      What’s wrong with using Rust’s Rc standard library feature to implement garbage collection?

                                                                                      Most reference counting implementations are slower than a moving, tracing GC alternative for a couple of reasons: they have to increment/decrement the count on every allocation/deallocation; and, with Rc in particular, they require two extra machine words (for the strong and weak count), which results in much poorer cache behaviour.

                                                                                      The other traditional problem with reference counting is that it can’t deal with cycles without the user annotating weak pointers. It’s easy to get this wrong, so memory leaks can happen if you’re not careful.

                                                                                      I would think that any GC is going to need some kind of reference counting semantics

                                                                                      A tracing GC (like mark-sweep; or stop-and-copy) doesn’t need a reference count. They trace from a root-set (usually on the stack or in registers) during collection looking for live objects. Unreachable objects can then be considered dead and thus their memory is freed. (See https://en.wikipedia.org/wiki/Tracing_garbage_collection)

                                                                                    2. 1

                                                                                      To be fair, CPython uses reference counting (with a tracing GC just to collect cycles).

                                                                                      1. 2

                                                                                        I think the point is, that it’s really hard to write proper GC in Rust.

                                                                                        1. 2

                                                                                          No harder than in C, if your willing to use raw pointers. There are a couple of Rust GCs that you could probably use off the shelf, though.

                                                                                          1. 1

                                                                                            Why is that?

                                                                                            1. 2

                                                                                              Existing approaches to GC in Rust which don’t have language support suffer from at least one of two problems: i) their API makes them too impractical to use; ii) their performance is worse than Rc. In some cases, it’s a bit of both :).

                                                                                              At this stage, I think fully tracing GC in Rust with acceptable performance for writing language interpreters would require some form of Rust language support. This has its own interesting challenges. You’ll encounter fairly non-language-specific problems when trying to retro-fit GC support: how to identify roots and interior pointers; whether to use a separate heap for GC objects; how the API will look; etc.

                                                                                              But what makes Rust difficult in particular are its additional borrow rules and safety guarantees. How safe should the GC be? I’m guessing the answer is “well if I use safe Rust code, I don’t expect to segfault”. Then the GC needs to be deal with things like this:

                                                                                              let s = S{}; // Assume S is some GC object
                                                                                              let s_obfuscated_ptr = &s as *const S as *const usize;
                                                                                              

                                                                                              Casting a raw pointer (to a potential GC item) to some other type can be written in safe Rust code. Dereferencing it cannot. There’s a problem here though, we’ve potentially hidden a GC root from our collector, and this could introduce unsoundness.

                                                                                              Another problem is the borrow rules. Multiple mutable references in Rust is UB. No exceptions. So you would still need something like RefCell inside your GC managed container to enforce those rules at runtime. This does some ref counting under the hood so you’d still, in some sense, have to deal with the reference count penalty. It’s important that this invariant in Rust isn’t broken - at present, I’m not aware of any optimisations rustc performs based on the mutability of references - but in the future, who knows? Breaking this invariant could lead to unsound behaviour based on assumptions made by the optimiser later on down the line.

                                                                                              The Deref trait also adds complexity because a GC needs to maintain the frozen reference property: any active reference &'a T to an object, must have a constant address for the whole of its lifetime a. If a collection takes place while an object is being dereferenced, the collector can’t move the object without breaking the FRP. From what I can remember, a lot of rustc’s safety relies on this invariant, and a GC would need to ensure that it pins objects across a deref to ensure soundness.

                                                                                              There are lots of other creases that would need ironing out for a sound Rust GC API. There’s a few resources on this from back when some of the core team were actively working on it but I think the work has now stagnated. This blog is a good start if you wanted to find out more: https://manishearth.github.io/blog/2016/08/18/gc-support-in-rust-api-design/

                                                                                          2. 1

                                                                                            Sure, that is fair, but from what I have seen is that rust ownership semantics make implementing mutability + sweeping part very hard. I have seen a rust GC ref type before, just never seen it used in a rust interpreter.

                                                                                            edit: jake hughes comment above is an excellent summary.

                                                                                        1. 53

                                                                                          You might even say they’re “borrowing” the model

                                                                                          1. 23

                                                                                            Too bad rust won’t be able to use it anymore.

                                                                                            1. 16

                                                                                              They can still use it, they just won’t be able to make any more changes.

                                                                                              1. 2

                                                                                                Digital piracy did it first, Rust is just an imposter

                                                                                                1. 1

                                                                                                  Well played ;)

                                                                                              1. 5

                                                                                                Maybe I’m a pessimist, but I can’t see Rust catching on as ubiquitous web-dev language on account of it being hard to learn and use compared to “managed” languages.

                                                                                                But who knows. Maybe time will prove me wrong.

                                                                                                1. 2

                                                                                                  It’s extremely handy to have a ssh auth key in your pocket. I use a similar setup that amazingly works on Mac, Windows, Linux and OpenBSD (using GPG and a combo of pcscd / opensc).

                                                                                                  As an alternative to Yubikey, checkout Nigrokey. The form factor isn’t as convenient, but they get the job done!

                                                                                                  1. 4

                                                                                                    oh man.. colemak noob typo - NitroKey

                                                                                                    1. 2

                                                                                                      Nigrokey

                                                                                                      That typo sounds racist. I’m glad it’s not the real product’s name.

                                                                                                      1. 2

                                                                                                        Somewhat beside the point but I think that’s literally Italian for “black” (also Nigro seems to be an actual surname).

                                                                                                      2. 1

                                                                                                        Can you use the built-in openssh auth key stuff alongside gpg-agent for the other key types?

                                                                                                        1. 1

                                                                                                          Not sure. I don’t use them outside of gpg.

                                                                                                        2. 1

                                                                                                          The Nitrokey is really nice (I have two). They run the open source gnuk firmware, which can also run on many STM32 F103 boards. E.g., some people run gnuk on $2 Blue Pill boards.

                                                                                                          http://www.fsij.org/doc-gnuk/

                                                                                                        1. 2

                                                                                                          I hope they release a digital download version.

                                                                                                          1. 1

                                                                                                            Pretty soon:

                                                                                                            The free megawad will be released in mid- February 2019

                                                                                                            1. 2

                                                                                                              yay!