1. 4

    What exactly is a “hosted” operating system?

    1. 2

      A rose by any other name would be known as a runtime platform or environment. See also Erlang/OTP.

      A hosted operating system punts on all the distracting/interesting/useful parts of OS stuff in order to focus on the aesthetic of the programming environment.

      1. 6

        A hosted operating system punts on all the distracting/interesting/useful parts of OS stuff in order to focus on the aesthetic of the programming environment.

        This might an appropriate description of a virtual machine.

        Inferno is a distributed operating system.

        It’s rather different from a mainframe OS, such as Windows or Linux: all services of a network are served to the user with a uniform interface and programs can be distributed over the network transparently, moving data or computations as required.

        The network as a whole is your computing device.

        Now, once you understand this, you might wonder if it’s really so important who write the drivers for a single node.
        Turns out it doesn’t matter that much: as long as the interface is uniform the system works as a whole.

        Now I agree that an OS running on top of an OS is weird. Much more an OS running on top of a browser!

        But sadly, it’s what your cloud vps do. And what any OS that target WASM want to do.

        Guess what? Inferno did both things several years ago!
        And better, with an uniform interface.

        Try this on your mainframe of choice! ;-)

        1. 2

          I’m not sure what you mean by mainframe OS, though it seems like it’s an attempt at derision?

          Virtual machines like those you might rent from a cloud provider are much more a partitioning technology these days. Though there is another operating system running on the same hardware (in the “hypervisor” role), the guest operating system is also interacting directly with quite a lot of CPU management, and increasingly other hardware devices via passthrough mechanisms. Critically, that same software can also run outside the emulation/hypervisor environment: it can take control of an entire computer, providing services to other software, and is thus an operating system.

          In the case of software that isn’t able to (or perhaps even intended to) run on a computer directly without other scaffolding, it’s really not an operating system. If it’s really a network service or programming environment built to run on top of other things (“hosted”, if you will!) it would be less confusing to call it that. There’s obviously no shame in building an amazing new platform for constructing distributed applications – it’d just be best to avoid hijacking existing terminology while doing so.

          1. 2

            I’m not sure what you mean by mainframe OS, though it seems like it’s an attempt at derision?

            Absolutely no!

            I was trying to distingush the OSes that are designed for a single computer (thus in the ancient and noble tradiction of mainframes) from the OSes that are designed for a network of eterogenous computers.

            When we talk about distributed operating systems, the focus is not in the control of the hardware of a single pc, but in the control of a whole network.

            In the case of Inferno, you can run it on bare metal, on Windows, on Linux, on Plan9, on some game platforms and on IE8 (if I remember correctly).

            This covers a variety of architectures that few mainstream OS could compete with.
            Without an hardware emulator.

            it’d just be best to avoid hijacking existing terminology while doing so

            I’m afraid Inferno was defined as a distributed operating system before “existing terminology” was conceived.

            So one might argue that existing terminology was designed by people either ignoring previous art or meaning something different.

            In both cases, I will keep calling Inferno an OS.

            1. 2

              I’m afraid Inferno was defined as a distributed operating system before “existing terminology” was conceived.

              I don’t think that’s true at all. Even the Wikipedia page for Inferno suggests it was released in 1996, and links to at least one paper from the authors from around that time. I think we’d kind of settled on an operating system being a body of software chiefly responsible for controlling an actual machine and providing services to software and users by then.

              By way of contrast, the Amoeba distributed operating system is another attempt (and seemingly prior to Inferno!) that is both distributed (providing network transparency as a core system primitive) and an operating system (Amoeba includes a microkernel base which runs on all of the machines throughout a deployment). Sprite is another similar project, also late 1980s to early 1990s, in which some level of network transparency was achieved in addition to the base job of an operating system: controlling the machine.

              1. 1

                I’m not sure if this count as an objection. :-)

                Fine, Amoeba and Sprite are distributed operating systems.
                Plan 9 is a distributed operating system too. So is Inferno, that can run on bare metal AND hosted by another OS.

          2. 1

            You mean different from a centralized mainframe. The CTOS system looks pretty close to a distributed OS. Customers were loving it, too.

            Far as OS on an OS, IBM invented that (I think…) in VM/370 in the 1970’s. VM could even run itself mainly for debugging. Mainframes also supported multiple users and metered CPU/memory. The cloud reinvents mainframes on cheaper hardware with more flexible software. The core concepts were a mainframe advantage, though.

          3. 2

            Right, it definitely doesn’t feel like an especially appropriate use of the term until it’s also in control of the actual machine. If it’s a runtime environment and library, it seems clearer to just call it that.

            1. 1

              The point at which services are provided to programs by “the operating system” versus other programs present but not considered part of the “operating system” is blurry, and getting blurrier all the time in a distributed world. “Control of the actual machine” sounds like the definition of a kernel, which can certainly be part of an operating system, but isn’t the whole thing.

              tl;dr: what you’re referring to as Linux is actually GNU/Linux,,,

              1. 2

                Not all of the control of the machine is in the hands of the kernel in every operating system. For instance, in illumos we perform some amount of interrupt configuration from a privileged process running in usermode (intrd(1M)) – but it’s still part of the operating system.

                Words have a meaning, and I think eroding the term operating system does us a terrible disservice. There are already loads of other terms that better describe a program that runs on top of an operating system and provides services to other programs, whether over local IPC mechanisms or through some network protocol.

                It’s true that a distribution of Linux may include quite a lot of software that isn’t really “operating system” software per se; e.g., chat clients or drawing software. But if your software doesn’t have the ability to take a computer from cold start up to running some other workload, it’s really not, itself, an operating system.

                1. 2

                  I think eroding the term operating system does us a terrible disservice.

                  I’m totally for a precise and clear technical language!

                  But, why we write hardware emulators like qemu, xen, virtual box and so on… if we cannot run operating systems on them?

                  And if what run on qemu is an operating system when it provides the user all the tools she needs, why a software that does the same but run without the hardware emulator is that different?

          4. 1

            Because they mention Inferno on the description they probably mean that in addition to running on ‘bare metal’ it can also run in an emulator inside another OS. Same as Inferno.

            1. 1

              no, but their approach to not doing so is quite entertaining.

            1. 18

              I no longer believe that daemons should fork into the background. Most Unix systems now have better service control and it makes the code easier to deal with if it doesn’t call fork(). This makes it easier to test (no longer do you have to provide an option not to fork() or an option to fork()) and less code is always better.

              1. 6

                Not forking also allows logging to be an external concern and the process should just write to stdout and stderr as normal.

                1. 1

                  This is not so much about the forking per se, but rather the other behaviour that generally goes with it: closing any file descriptors that might be connected to a controlling terminal.

                2. 4

                  OpenBSD’s rc system seems to expect that processes fork. I don’t see an obvious workaround for processes that don’t fork.

                  1. 3

                    It’s not that hard to write a program to do the daemonization (call umask(), setsid(), chdir(), set up any redirection of stdin, stdout and stderr, then exec() the non-forking daemon.

                    1. 2

                      It’s even simpler when you have daemon(3): http://man7.org/linux/man-pages/man3/daemon.3.html

                      1. 1

                        Which you do on OpenBSD, actually.

                        Note that daemon(3) is a non-standard extension so it should be avoided for portable code. The implementation is simple enough, though.

                    2. 2

                      I’m not sure this is accurate, at least on -current. There are several go “deamons” that as far as I understand don’t support fork(2). These can still be managed by OpenBSD’s rc system:

                      # cd /etc/rc.d
                      # cat grafana                                                                                                                                                                                                  
                      #!/bin/ksh
                      #
                      # $OpenBSD: grafana.rc,v 1.2 2018/01/11 19:27:10 rpe Exp $
                      
                      daemon="/usr/local/bin/grafana-server"
                      daemon_user="_grafana"
                      daemon_flags="-homepath /usr/local/share/grafana -config /etc/grafana/config.ini"
                      
                      . /etc/rc.d/rc.subr
                      
                      rc_bg=YES
                      rc_reload=NO
                      
                      rc_cmd $1
                      

                      I’m not sure if there’s more to it that I don’t understand, I don’t write many deamons!

                      1. 1

                        Well, it turns out, I can’t read! The key to this is rc_bg, see https://man.openbsd.org/rc.subr#ENVIRONMENT

                    3. 1

                      For those that don’t know, daemontools is a nice service system that explicitly wants programs to not try to daemonize themselves. For services I build and run I try to use that.

                    1. 36

                      Then again, I’ve rarely seen anyone use their editor of choice well. I’ve lost count of how many times I’ve watched someone open a file in vim, realise it’s not the one they want, close vim, open another file, close it again… aaarrrgh.

                      I do this a lot, because I prefer browsing files in the shell. I make pretty extensive use of a lot of other vim features though. When did you become the arbiter of how “well” I’m using my computer?

                      1. 3

                        Closing vim seems odd to me. Why wouldn’t one instead open the new file without closing vim? Maybe it’s a cultural thing? I don’t think anyone would do that in Emacs.

                        1. 26

                          “Why would I ever leave my editor” definitely feels like a common refrain from the Emacs crowd.

                          1. 1

                            I do the thing you quoted as well, but that is because vim is often my editor of convenience on a machine rather than my editor of choice, which is true for many usages I see of vim.

                          2. 21

                            Because the shell lets me change directories, list files with globs, run find, has better tab-completion (bash, anyway), etc, etc. I might not remember the exact name of the file, etc. Finding files in the shell is something I do all day, so I’m fast at it. Best tool for the job and all that.

                            (Yes I can do all that with ! in vi/vim/whatever, but there’s a cognitive burden since that’s not how I “normally” run those commands. Rather than do it, mess it up because I forgot ! in front or whatever, do it again, etc, I can just do it how I know it’ll work the first time.)

                            1. 6

                              This is exactly why I struggle with editors like Emacs. My workflow is definitely oriented around the shell. The editor is just another tool among many. I want to use it just like I use all my other tools. I can’t get on with the Emacs workflow, where the editor is some special place that stays open. I open and close my editor many, many times every day. To my mind, keeping your editor open is the strange thing!

                              1. 3

                                It’s rather simple actually: the relationship between the editor and the shell is turned on it’s head – from within the editor you open a shell (eg. eshell, ansi-term, shell, …) and use it for as long as you need it, just like a one would use vi from a shell. Ninja-slices.

                                You can compare this as someone who claims to log out of their x session every time they close a terminal or a shell in a multiplexer. Would seem wierd too.

                                1. 3

                                  I know you can launch a shell from within your editor. I just never really understood why you would want to do that.

                                  Obviously some people do like to do that. My point is just that different ways of using a computer make intuitive sense to different people. I don’t think you can justify calling one way wrong just because it seems odd to you.

                                  1. 6

                                    I know you can launch a shell from within your editor. I just never really understood why you would want to do that.

                                    I do it because it allows me to use my editor’s features to:

                                    a) edit commands b) manipulate the output of commands in another buffer (and/or use shell pipelines to prep the output buffer) c) not have to context switch to a different window, shutdown the editor, suspend the editor, or otherwise change how I interact with the currently focused window.

                                    1. 1

                                      That makes a lot of sense. I guess I have been misleading in using the word “shell” when I should really have said “terminal emulator”. I often fire off shell commands from within my editor, for just the same reasons as you, but I don’t run an interactive shell. I like M-! but I don’t like eshell, does that make sense?

                                      Having pondered this all a bit more, I think it comes down to what you consider to be a place. I’m pretty certain I read about places versus tools here on lobsters but I can’t find it now. These are probably tendencies rather than absolutes, but I think there are at least a couple of different ways of thinking about interaction with a computer. Some people think of applications as places: you start up a number of applications, they persist for the length of your computing session, and you switch between them for different tasks (maybe a text editor, a web browser and an e-mail client, or something). Alternatively, applications are just tools that you pick up and drop as you need them. For me, a terminal, i.e. an interactive shell session, is a place. It is the only long-lived application on my desktop, everything else is ephemeral: I start it to accomplish some task then immediately kill it.

                                2. 3

                                  It’s really simple in emacs. Just Ctrl-z and run fg when you are ready to go back.

                            1. 1

                              Privileged Command Execution History

                              A new command, admhist, was included in Solaris 11.4 to show successful system administration related commands which are likely to have modified the system state, in human readable form. This is similar to the shell builtin “history”.

                              That’s a curious one. It’s a shame the solaris manpages don’t appear to be public. I wonder if they’re logging the use of system() or exec*() in their libc.

                              What’s worse is I immediately started thinking about how this workaround could be useful. Naughty Hales! Fix the shell configs on the servers instead. Stop imagining libc level hacks to see what coworkers have been up to.

                              1. 4

                                I have no idea how it’s implemented, but I would note that Solaris and illumos systems have an auditing system with kernel involvement that can capture, amongst other things, all command execution. Perhaps this is a set of filters for displaying information gathered by the existing auditing mechanism.

                              1. 7

                                Am I crazy? I thought Oracle killed off Solaris? Or did they just lay off a bunch of folks?

                                1. 8

                                  They definitely sacked a lot of people, which presumably did nothing for the morale of the folks left behind either. We picked up some of the people jumping ship at Joyent when it happened.

                                  You can only fire or terrorise so many of the people in an organisation who know how something works before there won’t be a critical mass left to maintain it. Because of the long pipeline of work that was already underway at the time of the event (including the most recent line of SPARC microprocessors) they had a lot of stuff they could release just after the firing – “See, of course we’re not dead!” – but I wouldn’t hold out much hope for anything else.

                                  1. 1

                                    Oracle killed OpenSolaris, not Solaris.

                                  1. 57

                                    tl;dw

                                    • Removing Promises after they were initially added to Node. They should have been left in.

                                    • There’s virtually no security. V8 has a very good sandbox, which could have been maintained for server-side applications

                                    • The build system (GYP): Chrome used to use it, but moved on, now Node is the sole user:

                                      “it’s a very funky interface […] it’s very terrible”

                                      “it’s an awful experience for users”

                                      “the continued use of GYP is probably the largest failure of node core”

                                    • package.json led to NPM being sanctioned, and there being a centralized repo for JS packages (Ryan doesn’t explain why this is a regret).

                                      “It gives rise to this concept of a ‘module’ as a directory of files, which wasn’t a concept before, when we just had Javascript files […] it’s not a strictly necessary abstraction”

                                      “package.json has all this unnecessary noise in it”

                                    • node_modules:

                                      “it massively complicates the module resolution algorithm”

                                      “deviates greatly from browser semantics”

                                      “In practice a $NODE_PATH, like $PYTHON_PATH, would have worked, you can do vendoring that way too.”

                                    • “require” without the extension (eg “.js”)

                                      “Why? It just makes things more complicated”

                                    • “index.js”

                                      “I thought it was cute, because there was index.html”;

                                      “it needlessly complicates the module loading system”;

                                      “One thing I’ve learned as I’m aging is that whenever you’re designing a program there’s things that you think might be cute to add in. You always regret those”.

                                    1. 16

                                      Thanks for typing these up. I saw some of the slides and some hot takes fly past on Twitter at the time Ryan as giving the talk, too.

                                      I definitely get the impression that Ryan holds a particularly fundamentalist view on what he perceives as unnecessary software complexity, when I think in reality one of the rough parts of Node was that for a long time (and on some level, still today) there is insufficient complexity to cover the problem domain.

                                      For instance, the EventEmitter class is extremely simple in its implementation, and as such it can be very difficult to produce correct and robust software with it. The abstraction provides no mechanism to enumerate the set of events a producer might emit, and no way to enforce any rules about the ordering of events (e.g., end and close) or the valid sequences of events (e.g., you should emit at most end or error, but not both). It is also difficult to reason about what happens when you attach more than one listener for the same event. As such, there have been many bugs in core and add-on modules alike, both in event producers and consumers.

                                      I think his comments on node_modules and require() are pretty similar. One of the fantastic things about node_modules the way it works today is that you don’t have to futz with environment variables (e.g., $NODE_PATH). Resolution is performed starting at the location of the source file which the require() call is made, traversing the directory tree in a standard way. This is in stark contrast to some other environments which require either installation of modules into a global directory tree, and/or an environment variable to be correctly set informing the runtime or compiler of the location of modules.

                                      I’ll be the first in line with criticism about NPM, or the quality of many or even most of the modules in the ecosystem, but having built production-grade software for six years using Node, I can say I would absolutely miss the current module resolution behaviour if it was gone.

                                      1. 4

                                        I did watch, but appreciate your notes anyways!

                                      1. 2

                                        On illumos systems we have elfwrap(1), which will create an object file with a symbol for the start and end of a region containing the bytes from the wrapped file that you can then link into C or C-like programs.

                                        1. 9

                                          Why not use forward declarations without public definitions to create opaque types? For example, in the public header file:

                                          typedef struct handle handle_t;
                                          

                                          Then, only in the code which needs to access the concrete type:

                                          struct handle {
                                             ...
                                          };
                                          

                                          Then the compiler can correctly allow a handle_t * only where the function signature wants one.

                                          1. 5

                                            Incomplete types as abstractions has a complete example of doing this.

                                          1. 4

                                            While I enjoyed the post, the comparison at the end is unfair. The author compares ZFS with a 475GB NVMe drive as a cache to XFS without an equivalent cache.

                                            1. 2

                                              The initial comparison with XFS is somewhat unfair as well, though: does XFS provide the same data integrity features that ZFS does? It’s hard, really, to compare file systems with vastly different design centres and feature sets – which feels like the point they’re trying to make, really.

                                              1. 2

                                                Was the comparison looking at data integrity though? I didn’t see any mention of that anywhere – everything I saw was entirely about performance. If you’re doing a performance comparison of two filesystems, comparing them on (very) different hardware doesn’t seem real meaningful.

                                                The author mentions the possiblity of comparing against something like bcache (which would then be a zfs vs. xfs+bcache comparison rather than strictly a filesystem comparison), but then handwaves it away as “exotic” and concludes, essentially, that “zfs plus additional fancy hardware and a bunch of manual tuning outperforms xfs”. Well…big deal.

                                                1. 2

                                                  At what point do you need to assume integrity as a baseline though? This is a database blog we’re talking here.

                                                  Unrelated observation: it’s tragic that most production databases out there aren’t running on ZFS, and says a lot about the priorities (and less charitably the general ability) of our industry.

                                            1. 8

                                              I am sort of wondering whether it wouldn’t be possible to just ship a 32 bit x86 executable instead of amd64, then the 32 bit tricks could potentially be pulled. Since it doesn’t seem to need any libraries it wouldn’t incur any additional dependencies I think.

                                              1. 3

                                                I didn’t think of trying that…

                                                1. 1

                                                  I thought he was using 32-bit already? On my system, __NR_pause is defined to be 29 (his number) in asm/unistd_32.h, and 34 in asm/unistd_64.h. He’s also using eax over rax… Perhaps using int 80h and not syscall uses the 32-bit abi?

                                                  1. 2

                                                    int 0x80 is definitely the 32 bit Linux system call entry point.

                                                    1. 1

                                                      To be honest, my knowledge of assembler is minimal and even that is 20 years out of date…

                                                  1. 3

                                                    On an illumos system, you can use the libproc(3LIB) interfaces to achieve a similar thing without the use of a debugger. It would be reasonably easy to make a kind of custom splicing tool which could replace any open fd with an fd for a different path.

                                                    The rough sequence would be a call to Pgrab(3PROC) followed by a call to pr_open(3PROC) to open the new file descriptor in the target process. Once you have a file descriptor, you can use pr_fcntl(3PROC) to simulate dup(2) using the F_DUP2FD argument (described in fcntl(2)). Finally, use Prelease(3PROC) to let go of the target process and set it running again.

                                                    Our nohup(1) also includes a -p flag which allows the user to apply the semantics of nohup after the fact, rather than needing to do it in advance when starting the process – including redirecting any subsequent output that would have gone to the controlling terminal to the nohup.out file. This is done with a similar sequence of calls to those I briefly described above.

                                                    1. 2

                                                      Working on a tool which is effectively a layer on top of an Amazon service feels like a risky business. If you demonstrate that the need exists, what’s to stop them waking up tomorrow to quickly build an in-house duplicate?

                                                      1. 2

                                                        Nothing. ;) If AWS will build something better, that’s a great thing - way to go!

                                                        It’s not our primary business. We would love to have such facilities in place already. We build that tool in order to ease the pain regarding maintaining a pile of templates - for our convenience.

                                                      1. 22

                                                        Comments really aren’t a “code smell.”

                                                        1. 16

                                                          Nothing stinks quite like uncommented complicated code.

                                                          1. 7

                                                            Exactly! Margaret Hamilton’s code itself, whom the author cites, is full of comments. Possibly more comments than source code. Which, if you’re sending a ship with the processing power of a toothbrush to the Moon, is a great idea.

                                                            1. 10

                                                              This code is not readable on it’s own, if it was possible to use variable and function names most of those comments could be removed. It’s also quite likely that every detail of the program was decided before writing the code. In a modern codebase things are always evolving and comments can get left behind.

                                                              1. 5

                                                                This is my fear with comments. I code in a team of 2, so we don’t really comment stuff. I know it’s bad, but I’m a team of two, we kind of know the whole code anyway.

                                                                We also don’t write tests. We’re bad people.

                                                                1. 4

                                                                  Oh man, save yourself some pain and write unit tests. You don’t need 100% test coverage, even non-zero coverage of basic functionality will save you so much time. If you don’t know how to use test frameworks then you don’t have to bother, just write one big main file with a function per test you want to do, and call them all in main. That’s basically what test frameworks are, so if you need a low barrier to entry then don’t bother learning one yet, just do something. If you program in a language with a REPL you can literally just save the stuff you use to manually test into a file so you don’t have to type it more than once.

                                                                  I personally couldn’t develop without unit tests. You can test the application and do something that hits the code path you just changed, which is time consuming and tedious, especially to do repeatedly, or you can write a little bit of code that calls the code and run it with zero effort every time all the time for the rest of forever. Even a small sanity test of the happy path is better than nothing, you can at least check your code doesn’t blatantly fuck up with normal input and save yourself the round trip through the application.

                                                                  If I had to code without unit tests I’d quit. And I have worked on teams that didn’t want to unit test, so I had out-of-tree tests I wrote for myself. The amount of bugs I fixed a couple hours after someone else committed was mind boggling.

                                                                  1. 4

                                                                    How do you even develop without unit tests?

                                                                    I’d avoid this kind of shaming, especially since the commenter has already noted (in a self-deprecating manner) that they’re aware of the stigma associated with not using tests.

                                                                    If the intent is to encourage the use of tests, I would put your last paragraph first and focus on how it would help GP.

                                                                    1. 3

                                                                      Revised, thank you for the feedback. 😊

                                                                    2. 2

                                                                      Depends on the language and coding style though. I wrote a 25000 line game in C++ without a single test, and I never had a regression. I obviously had occasional bugs in new code, but they’re unavoidable either way. Now my preferred language is Haskell, and I feel the need for tests even less. I generally prefer correct-by-construction to correct-by-our-tests-pass. My purpose isn’t to discredit tests though, just that not every codebase has as much need for them.

                                                                      1. 2

                                                                        I’m just self taught and kind of out of my depth on it. I had a dev friend who did integration tests, and they were really brittle and slowed us down a lot. Are unit tests not as bad at slowing down a small team of two devs who are both self taught? We’re good / mediocre / we build good stuff (I consider ourselves hackers) but we don’t have a ton of time.

                                                                        1. 1

                                                                          Unit tests don’t have to slow things down like integration tests. In your situation, I’d wait until the next bug comes up, then instead of fixing the bug immediately, I’d write a test that reproduces the bug. Usually doing that helps narrow down where the bug is, and after fixing it, the test passes and (here’s the cool part) you will never see that bug again

                                                                          1. 1

                                                                            That’s what i was told about integration tests, but I had to set up all these extra dependencies so that the integration tests continued to work every time we added an external service… we’d have to mock it or shit would break.

                                                                            I’m assuming since Unit tests don’t run like that, they don’t have external dependencies like that? You’d mock on a component by component basis, and wouldn’t have to mock unrelated shit just to keep them running… hmm… maybe i will.

                                                                            Any unit testing video series I could watch as a noob to get started you’d recommend? Or anything like that?

                                                                        2. 1

                                                                          I second saving yourself pain with writing tests! I’ve avoided lots of rakes with a handful of tests

                                                                      2. 2

                                                                        What makes everybody think that the programmers who change code so that it no longer matches the comments they just used to understand it will somehow write code so clear you don’t need comments to understand it?

                                                                        1. 1

                                                                          Often people write code like total = price * 1.10 #This is tax which can be rewritten as total = price * TAX A lot of comments like that can be removed by just putting them in the actual code.

                                                                          1. 2

                                                                            I’m not suggesting it can’t be done I’m suggesting it won’t be done

                                                                      3. 4

                                                                        I’ll also correct the article to say a team did the code and review per the reports I read. She describes it here in “Apollo Beginnings” as a team with a lot of freedom and management backing with unusual requirement to get software right the first time. Unfortunately, a rare environment to work in.

                                                                      4. 5

                                                                        You can’t write test coverage for a comment. You can’t have your compiler warn you that a comment is inaccurate.

                                                                        If you have no tests, and your code is full of dead paths, you can’t even percieve the risk posed by an errant, out of date, or unintentionally misleading comment.

                                                                        Sometimes they’re necessary. But the best default advice to a ‘mediocre’ developer is to write better code, not add more comments.

                                                                        1. 5

                                                                          You can’t write test coverage for a comment. You can’t have your compiler warn you that a comment is inaccurate.

                                                                          https://docs.python.org/3/library/doctest.html

                                                                          If you have no tests, and your code is full of dead paths, you can’t even percieve the risk posed by an errant, out of date, or unintentionally misleading comment.

                                                                          If you have no tests or comments you have no way of knowing whether your code is actually matching your spec, anyway.

                                                                          Sometimes they’re necessary. But the best default advice to a ‘mediocre’ developer is to write better code, not add more comments.

                                                                          That’s like saying that the best default advice to a ‘mediocre’ developer is to write less buggy code, not add unit tests.

                                                                          1. 2

                                                                            doctest is great for testing comments that include code, but nothing else… If a comment says “Framework X is expecting variable foo in JSON format inside the array bar.” I would be inclined to believe it at first and then test the hypothesis that the comment is wrong. That’s the danger of comments.

                                                                            1. 1

                                                                              A couple of times today I caught myself committing deleted or changed lines without deleting or changing the associated comment. Luckily I could go back and fix things so that the comments weren’t complete nonsense. Sometimes though they escape detection.

                                                                          2. 2

                                                                            Once the code is cleaned as much as possible and still is hard to understand, or if something is tricky, comments help a lot!

                                                                            I guess the author talked about comments that could be removed by making the code cleaner.

                                                                            Maybe it depends on what motivates one to add comments, there might be good reasons as well.

                                                                            1. 2

                                                                              True.

                                                                              But Comments that are wrong or out of date stink like dead rats.

                                                                              I view asserts as “executable comments” that are never out of date. Sometimes they are wrong… but testing will tell you that.

                                                                              If a plain comment is wrong… nothing will tell you except a very long, very Bad Day at work.

                                                                              1. 7

                                                                                But Comments that are wrong or out of date stink like dead rats.

                                                                                Valuable comments are something along the lines of “this looks weird, but I did it because of [historical reason that is likely to be forgotten] even though [other implementation] looks like the more obvious solution at first glance; it wouldn’t have worked because [rationale].”

                                                                                The longer I spend working with old codebases, the more I’ve come to treasure such comments. But comments that just explain what the code is doing rather than why are suspect.

                                                                            1. 16

                                                                              Seeing more and more of these “Go rants”, regardless of whether the author hates, loves, uses, avoid, wants to convince you to stop using Go or not, I would like to remind people to consider that Go is not a language that can be neatly sorted into the existing categories, being either imperative, object oriented, functional or whatever. The divide wasn’t clear to begin with, but Go certainly isn’t the stabilising force in the debate. The reason why this is relevant, is that this isn’t necessarily just a different floor – one can’t just program go like Java or C++ – actually one can(!), and that is kind of the problem. The ability exists, which leads to the pitfall being exploited, to the mental harm of the programmer.

                                                                              In my opinion, this is quite an ironic twist, but one that probably couldn’t be avoided, since Go is quite well known for being an opinionated language, where Rob Pike the language designers got to choose more about what good style and good practice is, than you as a developer get to choose (this is also sometimes taken as the basis for a vulgar argument against Go, which I personally very much disagree with, I think stuff like go fmt are some of the best things about the language).

                                                                              Go requires a different kind of thinking, when it comes to conceptualizing and solving program. It’s not just a different form. Again, despite not falling perfectly into pre-existing categories, it doesn’t just create a new one, but I belive, it brings into question the whole relm within which we categorize. And I guess this is part of the reason people are so divided. Those who dislike it, be it corporate pragmatists, or academic purists, both have to adjust and change their patterns and frames of thought, which might disgruntle them for different reasons, but I belive that if people have the right attitudes (the go proverbs do a good job at summarizing these) and want to solve the right problems, one can overcome this frankly silly dispute (use the right tool for the right task still is true), for the better.

                                                                              1. 6

                                                                                Go is quite well known for being an opinionated language, where the language designers got to choose more about what good style and good practice is, than you as a developer get to choose

                                                                                Except that declaration by fiat doesn’t make it so. It may be the official style and the official practice, but that doesn’t make it some absolute good. There were recommendations made about how to write Java by the Java folks as well – not everybody followed them because, not unreasonably, not everybody agrees on these sorts of things.

                                                                                Go requires a different kind of thinking … it brings into question the whole relm within which we categorize. Those who dislike it, be it corporate pragmatists, or academic purists, both have to adjust and change their patterns and frames of thought, which might disgruntle them for different reasons … one can overcome this frankly silly dispute …

                                                                                This highlights one of the most frustrating parts about Go for me personally. It’s not a religious experience; it’s basically C with garbage collection and M:N threading, and nearly a decade of punting on useful management of modules of software.

                                                                                It’s not that I don’t understand; that if I don’t agree I must be some kind of pantomime villain. Go represents a set of design decisions and trade-offs that, in my experience as a software engineer, don’t align with the way I think we should be building software.

                                                                                If you happen to like it, that’s great – but let’s not oversell this as some major breakthrough, some software engineering messiah. It’s just not, or at least, not any more than anything anybody else is doing.

                                                                                1. 2

                                                                                  It may be the official style and the official practice, but that doesn’t make it some absolute good. 

                                                                                  Of course not – my point was that within the Go community, these were set up by the Go team, not as recommendations, but as quasi rules. And for the most part, they were lucky/smart enough to have made reasonable choices. Sure, they might not be perfect, but asking for perfection is the wrong question, which again, I see the Go designers as correctly recognising.

                                                                                  it’s basically C with garbage collection and M:N threading, and nearly a decade of punting on useful management of modules of software.

                                                                                  My point is that if you try to describe go this way, you will end up misinterpreting Go. There are many more subtle features and idoms (since a language is not only it’s syntax, but aso it’s “culture”, ie. the standard library, the available packages, the naming, …) which make Go interesting. Small interfaces, errors as values, nil values with meaning, … The way you phrased it, all these things fall away, while they are important when actually using the language.

                                                                                  If you happen to like it, that’s great – but let’s not oversell this as some major breakthrough, some software engineering messiah.

                                                                                  You’re right, I might have over-phrased it, my bad. Again, what I am trying to say, to put it more subtly, is that Go (at least to me) signifies a shift in languags, which doesn’t fit within the existing coordinates of language theory, which isn’t something that has never happend before, of course, but should remind the developer to actually learn the language in a richer sense, rather than forcefully trying to apply general OOP or FP ideas onto it, not that Go isn’t doing anything wrong, and it must not be criticised.

                                                                                2. [Comment from banned user removed]

                                                                                  1. 1

                                                                                    That’s a neat little “defense” of your favourite programming language - just remove the goalposts altogether!

                                                                                    I never claimed that Go was my “favourite programming language”, I just think that all of this is a silly thing to argue about, so I wanted to offer some points to make more sense of the debate. And there is no reason to be so arogant, as you seem to be, about something like this.

                                                                                    Gosh, since there’s no apples-to-apples way to compare Go to other programming languages, who’s to say whether it’s better or worse than any of them!

                                                                                    Read my other comment if this is how you understood my point. All I’m saying is that if you’re (to use your analogy) you want to make an apple pie out of onions, you’ll have a hard time – use the language in the way it was designed to be used, if you want to get something out of it. Sure, when this is actually done, which from my experane of Go criticism is not so often the case, you can civily debate what language or toolkit would be more adequat for a specific scenario, that’s uncontroversial.

                                                                                    Oh it’s a vulgar argument against Go, huh? That sounds bad. It must be an invalid argument too, then!

                                                                                    What? All I’m saying is that if you complain that Go doesn’t let me place my brackets on the next line, like I want to, so it’s a overall bad language!, that you haven’t really made any point beyond vaguely whining about the fact that you can’t do something meaningless in the way you want to, but the point remains: who cares? Enforcing one style, for example, makes it easier for others to read your code, for VCS to maintain it and it prevents you from trying to be “smart” when you should be clear. One can debate all of this, yes, but it’s all just preferences.

                                                                                    It requires a different way of writing code too, since it lacks many of the facilities other programming languages have!

                                                                                    Yes, no doubt. Go comes from a background and a culture that prefers minimalism and clarity over being a swiss knife. I personally do so to, for example when using AWK as compared to perl. But why should this be necessarily bad? This is exactly one of the things Go wants to do, but if you expect Go to be C++ or Java, you’ll necessarily (I argue) have a bad experiance.

                                                                                1. 2

                                                                                  https://www.pkgsrc.org/#platforms lists 17 platforms. Why the illumos tag? I don’t see anything Solaris-specific on the Con page.

                                                                                  1. 6

                                                                                    while pkgsrc supports many plattforms it is also the default package system on NetBSD and SmartOS, one of the illumos distributions. So it is probably of special interest in those two communities.

                                                                                    pkgsrcCon is a pretty open conference and everyone interested in packaging or portability will be welcome of course!

                                                                                    1. 2

                                                                                      I didn’t know that! Thanks for explaining.

                                                                                      Maybe that should be advertised on the pkgsrc landing page? I think it’s a feather in the cap for pkgsrc and NetBSD that another OS has picked it up as its default.

                                                                                    2. 2

                                                                                      We’re really not Solaris anymore, and haven’t been for almost a decade. I don’t think the talks are up yet but I can find out if the people we employ at Joyent to focus on pkgsrc are going!

                                                                                      1. 1

                                                                                        As I believe Oracle Solaris is dead or in effect dead, isn’t illumos the Solariest OS out there, and maybe the de facto Solaris?

                                                                                        If I want the unique features of Solaris from a decade ago, isn’t illumos the place to go and aren’t they mostly still unique features?

                                                                                        You make it sound like being associated with Solaris would be a bad thing. :-)

                                                                                        pkgsrc platforms page still says Solaris / SmartOS / illumos. :-)

                                                                                        1. 1

                                                                                          If you wanted to run Solaris on your sparc hardware, illumos wouldn’t be my first stop.

                                                                                          1. 1

                                                                                            What would be?

                                                                                            Is that really a unique feature of Solaris, though? NetBSD and Linux both run on Sparc, IIRC.

                                                                                    1. 4

                                                                                      If you can write a stand-alone program with one function until you get it right - great!

                                                                                      I saw a cute pattern in the FreeBSD libc source: they included assert.h and declared a main function to run tests in a library source file, guarded by #ifdef TEST. You need only compile with -DTEST and run the resulting binary to test the code. I thought that was real slick for a file with a few smallish functions. I’ve used the pattern a lot since, and I’ve found it’s pretty nice to have the tests in the same file as the source as example usage.

                                                                                      I totally agree with liberal use of asserts. Since C has such a weak type system, they can kind of act as a substitute. It sucks that basic asserts like “not null” aren’t evaluated statically at compile time, but they do let you assert logical constraints that aren’t easily expressed with types. And they conveniently document the assumptions of all your functions inline with the code.

                                                                                      But best of all: C asserts trigger a core dump! You can fire up a debugger and examine the entire program state at the time of the crash. No other language gives you that much context for an assertion failure. That alone makes C asserts the best asserts I’ve used out of any language.

                                                                                      1. 11

                                                                                        But best of all: C asserts trigger a core dump! You can fire up a debugger and examine the entire program state at the time of the crash. No other language gives you that much context for an assertion failure.

                                                                                        Hey, Lisp assertion failures simply pause the running image and dump you into the debugger, leaving the entire running state available to inspect and even possibly modify/restart. :-) But I agree it’s otherwise a fairly unusual feature. The IBM Java VM supports core dumps and postmortem debugging, but it isn’t on by default, and I don’t think the standard Hotspot VM supports it.

                                                                                        edit: Apparently JDK 9 adds this.

                                                                                        1. 5

                                                                                          We have the assertion behaviour you’re talking about with Node as well. We run production services with --abort-on-uncaught-exception, and use various assert() style libraries that then throw and trigger a core dump on failure. We can also call process.abort() directly if something is whacky.

                                                                                          We look at the resulting core files with MDB (and the mdb_v8 module) and can fish out the JS stack, with arguments, as well as effectively every object in the heap. It’s pretty magical. Of course we can also do this with C, as you note, and I am a huge fan of that too!

                                                                                          1. 2

                                                                                            Ah, of course joyent / illumos has that capability. If only the linux ecosystem cared about debuggability. :(

                                                                                            1. 2

                                                                                              As one of my former colleagues was fond of saying: I can’t fix others, I can only fix myself. Our software is open source and available if you want it!

                                                                                          2. 4

                                                                                            If you do not mind non-standard stuff, you can use __attribute__((nonnull)) (and returns_nonnull) with Clang and GCC, through a macro defined to nothing if not supported. Then you’ll get your compile-time warnings.

                                                                                            1. 2

                                                                                              That’s fantastic, thank you! It’s not as good as a language that standardizes on using option types, but that’ll be damn useful. While we’re talking about attributes, I’m a big fan of warn_unused_result.

                                                                                            2. 4

                                                                                              This is basically how tests work in Rust. It’s pretty great!

                                                                                            1. 1

                                                                                              I wonder if fork(2) was able to return failure back then, or if it just panicked the system.

                                                                                              1. 6

                                                                                                Can’t we at least call it SunOS for us old farts?

                                                                                                1. 9

                                                                                                  I share your sense of nostalgia, but it’s been such an uphill struggle to get people to acknowledge both the name we’ve given ourselves, and that we’re a totally distinct project and body of software from That Other SunOS. I’d like it to just be illumos if we’re going to do this.

                                                                                                  1. 1

                                                                                                    Oh I’m really teasing. I spent a lot of time on SunOS 4.1.1 and 4.1.3 but my later experiences on Solaris were fairly negative.

                                                                                                    1. 2

                                                                                                      Ah! Yes, I am familiar with this sentiment. I gather things were not the best for quite a while after the SunOS to Solaris transition.

                                                                                                      Solaris 10 was brand new when I got started in a Solaris-centric UNIX group, and I feel things were pretty great by then. We had some S8 and S9 systems left for a while, but not much older than that. All I have of the SunOS 4 years are the stories of the elders. ;)

                                                                                                1. 5

                                                                                                  How about solaris, so it covers all possibilities?

                                                                                                  1. 12

                                                                                                    solaris today means oracle solaris. illumos as a project and as a community stand for very different things even if the code history is shared.

                                                                                                    Sometimes terms such as solarish or SunOS (after uname) are used to mean both, the closed version and it’s open source descendants, but I’m not sure how meaningful such a tag would be.

                                                                                                    1. 2

                                                                                                      Isn’t Solaris dead?

                                                                                                      1. 2

                                                                                                        No, Oracle just released a new version like, a week ago. Plus you’d cover any other Solaris forks that exist.

                                                                                                        1. 2

                                                                                                          Wouldn’t OpenIndiana or OpenSolaris be a better name?

                                                                                                          Oracle fired pretty much all Solaris and SPARC engineers in 2017.

                                                                                                          As far as I know any work on Solaris is limited to maintenance, and no new features are planned.

                                                                                                          1. 6

                                                                                                            illumos is the community continuation of OpenSolaris. OpenIndiana is one of the illumos distributions, but there are others like SmartOS, OmniOS and Tribblix.

                                                                                                            1. 4

                                                                                                              I mean, it seems like naming the linux tag ubuntu to me. Cover all branches with the parent.

                                                                                                              1. 9

                                                                                                                There’s been almost 10 years of divergence between Illumos and (Open)Solaris. I think it would be more like having a 4.4BSD tag to cover all of {Net,Free,Open,Dragonfly}BSD.

                                                                                                                1. 2

                                                                                                                  Mhh, I thought that my naming ideas were more inclusive, because Solaris in my mind refers to the proprietary product, while e.g. OpenSolaris covers all the descendants from the open source project.

                                                                                                                  1. 9

                                                                                                                    While we descended from OpenSolaris, that name doesn’t really refer to anything anymore. We (illumos) have been a wholly separate thing for around a decade now.