Live data from Hacker News

Writing New System Software

borud.no

121–130 of 158 posts

Re: Writing New System Software

#121
post #105

Earlier quoted context omitted.

(Opinions are my own) > Also, their "no exceptions" rule only applied to work involving their legacy code. The reasons for not using exceptions are outlined in this post: https://abseil.io/tips/76 absl::Status is basically exceptions without language sugar. Or, another way of looking at it, golang err in C++. Basically, non-local control flow is dangerous as it can't be evident to the programmer when something deep i…

> Basically, non-local control flow is dangerous (...) This is the crux of the error you're making. Exceptions are not about control flow. Exceptions are a transparent and clean way to handle exceptional events. Exceptions are not intended to, say, handle the status code of a HTTP requests. Exceptions are intended to handle exceptional and potentially unrecoverable errors in a safe and controlled manner, such as fail…

> Exceptions are a transparent and clean way to handle exceptional events.

I'd sum up this argument as: Exceptions are syntax sugar that allow callers of a function to ignore the error cases of something they are calling and depend on something that calls into them to handle the error case.

An example:

    void HandleRequest(const Request &request, KV &kv) {
        ...
        kv.set("a", 10);
        ...
    }
In this example KV.set will raise an exception. The programmer implementing HandleRequest isn't directly exposed to this fact and so to them, and the reviewer, and future onlookers this code looks correct. Now lets say kv.set() throws an exception in production under a specific case. Maybe there were two people attempting to set the same value at the same time or a networking issue. Doing this in the context of a webserver might make sense as the webserver might handle exceptions as error codes but that's not the end-all-be-all. Suppose we refactored to something like this

    Something CreateSomething(....);
How do you know if this function will throw an exception? How do you find all of the possible exceptions that can be thrown? Statically you can't really. If instead you see

    absl::StatusOr CreateSomething(...);

You can tell for sure that the result has some error that needs to be handled. Your original code:

    kv.set("a", 10);
This code no longer compiles in an absl::Status world. Instead you'd need to do something like:

    CHECK_OK(kv.set("a", 10)) // this will panic
    RETURN_IF_ERROR(kv.set("a", 10)) // Bubble up

From this we get:

1. a stack trace since RETURN_IF_ERROR adds metadata about the call site.

2. Guarantee that code will not compile if errors are not handled.

3. Guarantee that future readers know that some very high level function could probably call into code that can produce an error you need to handle.

This matters much more if things like this are happening:

    kv.beginTransaction();
    kv.set(...);
    kv.endTransaction();

This could be handled by destructors in this case but in other cases:

    otherService.startingWork();
    kv.set(...);
    otherService.doNextStep();
There are cases where destructors do not make sense. You do not always want to call `doNextStep()` as it would be 100% wrong in the case where we cannot set our value in our kv store. Contrived but I've run into these in real life services. If a developer sends me the above code snippet I might LGTM. If the developer instead sends me:

    otherService.startingWork();
    if (!kv.set(...).ok()) { log("something went wrong"); }
    otherService.doNextStep();
I'll be able to point to the exact problem with this code much more easily. Also if there's an outage and I need to read this code I can clearly see why this `something went wrong` in the logs correlates to incorrectly called doNextStep().

I'm not saying that Status is perfect (I'm not 100% sold) but exceptions are a type of control flow in an abstract sense. The problem some people have with it is it's control flow you can't audit.

Re: Writing New System Software

#122
post #99

I am a professional software developer for over 16 years, and learned C in the last 3 or so years for interests sake. I would most likely fall into the category of C developers that think they know enough tricks to get by, but probably write terrible code without realizing it. > Yes, you can write things in C and C++ that are very fast, but statistically, it is unlikely that you have the skill and discipline to do so…

It is particularly foolish to pick up C at this late date. There were reasons 40, even 30 years ago.

Now, unless you are coding for the Linux kernel or Postgres, it is a boat anchor. C++ will remain a sensible choice for at least two decades. Others are a crap shoot.

Re: Writing New System Software

#123
post #104

Earlier quoted context omitted.

> It's got to be any package maintainer's worst nightmare. Is this really a problem in most modern package management systems and build systems? I think Nix is a great example of handling this gracefully by just tracking the inputs and outputs of each compilation and sandboxing the compilation so we can guarantee the build definition includes all specified deps. This is something debian can build on top of apt.

I guess one can work around the lack of dynamic linking in a language like Go on the package manager and/or distro level (though some established distros and package management ecosystems, which I very much hope will not go away, will have it harder to adapt than others), but I really would like to make everyone think about whether we should... Imagine a Debian archive (that is, a few tens of thousands of packages wi…

> I guess one can work around the lack of dynamic linking in a language like Go on the package manager and/or distro level (though some established distros and package management ecosystems, which I very much hope will not go away, will have it harder to adapt than others)

Package managers already have ways to do this since no programs are 100% dynamicly or statically linked. Even Golang has dynamic linking (glibc recently).

> but I really would like to make everyone think about whether we should...

Why not? This has the major benefits of making distributed rebuilds, caching of builds, etc much easier. Nix and Bazel have been very successful with this.

> Imagine a Debian archive (that is, a few tens of thousands of packages with source, build recipies and binaries for multiple architectures available) with only static linking on the table. You got a few hundreds to thousands of those packages installed on typical, real-world Debian machines. Then, a central component like zlib or OpenSSL gets an important patch. This triggers hundreds, if not tens of thousands (transitive library .so dependencies are a thing after all, and you want to have all your supported arches covered) of rebuilds across the archive. All users will have to re-download and re-install all resulting upgraded packages they have installed.

The story isn't as bad as you might think. I'd wager that most programs do not dynamically link anything other than glibc: https://drewdevault.com/dynlib

> With increased sharing of source code ... and only static linking on the table, this kind of problems gets really, really bad really quickly for large-ish software archives. Kinda like with log4j in the Java ecosystem, where each app is used and event expected to dragging all its runtime dependencies along on its own.

With LTOs it's possible to remove the 99% of the code that isn't used from these libraries. It's not as bad as one might think and, if you define your libraries in smaller scopes, you can include only a few .so files.

> In the dylib world we are living in right now however, users get a single updated package, and upon the next restart of an application linking against it, they're immunized against the bug

This is the positive case but the unfortunate negative is that a majority of the time the program breaks. To save 30MB to 100MB of network traffic we introduce the possibility of an breaking all bins. An overwhelming majority of my binaries use less than 10% of the symbols of their dynamic libraries. Also, if things are statically linked, we can run automated testing on binaries to catch errors before deploying package updates. Maybe a security fix breaks your favorite app? Useful info to know.

> of a monorepo world with each dependency fully vendored in, and an "intelligent" build and deployment system atop it all that will take care of gracefully upgrading everything

That's sort of the description of what OS distros do IMO.

> For the significant portion that makes up the rest of the world, they generally don't have such luxuries, and will be a lot worse off. Especially established and wonderful Free Software communities like Debian or Fedora. I think that would be a huge sacrifice to make.

IMO having a system like what Nix has to do hermetic builds would improve debian and other OSs as they could build, test, and reproduce builds more easily. This is important for security.

Re: Writing New System Software

#125
post #124
post #114

Earlier quoted context omitted.

AOSP is an ancient collection of Android apps Google published.

Well however good / bad their code is is not my problem. I see no reason for me looking at it.

Except as an object lesson. But we all have read more than our share of bad code already.

Re: Writing New System Software

#126
post #122
post #99

I am a professional software developer for over 16 years, and learned C in the last 3 or so years for interests sake. I would most likely fall into the category of C developers that think they know enough tricks to get by, but probably write terrible code without realizing it. > Yes, you can write things in C and C++ that are very fast, but statistically, it is unlikely that you have the skill and discipline to do so…

It is particularly foolish to pick up C at this late date. There were reasons 40, even 30 years ago. Now, unless you are coding for the Linux kernel or Postgres, it is a boat anchor. C++ will remain a sensible choice for at least two decades. Others are a crap shoot.

I use C++ to write backend servers. Firmware for less powerful microcontrollers - I use C.

Re: Writing New System Software

#127
post #126
post #122

Earlier quoted context omitted.

It is particularly foolish to pick up C at this late date. There were reasons 40, even 30 years ago. Now, unless you are coding for the Linux kernel or Postgres, it is a boat anchor. C++ will remain a sensible choice for at least two decades. Others are a crap shoot.

I use C++ to write backend servers. Firmware for less powerful microcontrollers - I use C.

Old habits die hard.

Re: Writing New System Software

#129
post #125
post #124

Earlier quoted context omitted.

Well however good / bad their code is is not my problem. I see no reason for me looking at it.

Except as an object lesson. But we all have read more than our share of bad code already.

As a lesson that ISO C++ contributions are themselves not an example of the kind of code shown at CppCon talks.
Post reply on HN