It absolutely is, and I think it's what separates good from bad and junior from senior devs.
Most devs can produce an artifact that more or less works. But one that has an internal consistency others can understand and extend, one which accurately captures the problem as it exists and ways it will likely change, is much more of an art form.
A big part of that is knowing which situations are worth making a stand. Every you write code or leave feedback, your doing it for your team current and future.
Nothing that you talked about pertains to art. Writing good code does not mean you're making art.
You shouldn't strive for internal consistency with yourself, you should strive for external consistency with the other developers in your team. If someone reads your code and immediately knows it was you, you probably aren't doing a good job.
And that's the difference. If you are doing a good job as a software engineer, no one should notice you. If you're making good art, everyone should see you. And that is the difference between devs who think they're good, and devs who are truly good.
Code can be art but not all code should or even could be art. Like there is just zero utility or elegance in formatting your bash script with pretty comments and some elegant data model if it’s just something you run to manually pull metrics from a staging environment or whatever.
I see code more like rocks, nails, planks, tape, shards of broken glass, and a pile of signs that say things like RADIOACTIVE - DO NOT ENTER. If you need to do something cool with that stuff you probably do need to create something that looks pretty interesting and elegant in spite of your choice in building materials. But sometimes you just need to take a NO TRESPASSING sign and tape it to a plank that you jam into a pile of rocks. Don’t need to find a hammer if you don’t use nails, only need it up for a day, just one of a hundred things on your plate to do something of bigger scope and impact - just make sure the rocks are big enough to keep the plank standing, leave and forget about it.
I think a distinction can be made between bad taste and different tastes.
One of the greatest developers I've worked with, who I learned a lot from and respect immensely, has extremely different tastes in software from me. To the point where I wouldn't say I think he has good taste.
But, his work still has a distinct style and intention. I can tell anytime I come across libraries he had a hand in. I understand what the code is doing and why is is correct, even when I disagree with it.
And I think that is what is important. When working with more junior people, I'll ask them why they did things a certain way and will generally me be with a "well, idk" of some variant of path dependence.
I think developing that intentionality as a developer is important. Which does come with some amount of aesthetic, and I think taste is a defensible metaphor.
The predominant wind is from the east, and the air cools aid forms rainclouds as it tries to rise over the mountains in the center of the island. Then warms again as it descends down the eastern slopes.
So the eastern (Hilo) side is pretty lush jungle, and the west(Kona) is desert.
With snowy mountains in between.
It's interesting to see the transition. Lush green grass and vegetation on your left, and as you turn your head right, it goes more yellow and then completely dry desert on your right.
It's almost like you can see the line across the terrain.
Going from downtown Los Angeles to Santa Monica is $30s for a Waymo and runs up to $50s for Uber/Lyft (sometimes). Otherwise, they tend to be within a few dollars.
I figured it was a combination of Google subsidizing rides and a lack of a "traffic tax".
They're a significantly better experience for 45+ minute rides.
We have common carrier laws to cover cases like Comcast. Which Section 230 explicitly says social media platforms are not.
And the problem with Comcast is not necessarily that they will make speech decisions we don't like (an inherent part of free speech). The problem is that they're a monopoly and people don't have other options. So we should fix that problem instead of further limiting 1A rights.
> Why would treating a social media site's moderation as protected speech automatically make the social media site a common carrier?
First of all, you're asking the question backwards. If corporate moderation is protected speech then why wouldn't it be protected speech for common carriers?
The only plausible answer is that they have a dominant market position, but then so do the large social media platforms, which are the only things these laws apply to.
The dominant market position of someone who has last/mile cables to every household in an area is much stickier and more absolute than the dominant position of any social networking site.
Even if it’s hard to stop using e.g. Facebook, it’s easy to access 1000000 other sites too, and publish your own. That’s not the case with ISPs - for the most part you can have only one.
> Even if it’s hard to stop using e.g. Facebook, it’s easy to access 1000000 other sites too, and publish your own.
There aren't 1000000 major social media sites. Sites with fifty users in total are irrelevant and can't be used for the same purpose, and for the same reason most people can't feasibly start their own.
> That’s not the case with ISPs - for the most part you can have only one.
This is also not true. You can generally choose between the "cable company" and the "phone company" in addition to satellite providers like Starlink and various cellular networks. You have about as much choice in ISPs as you have in social media sites, and in both cases it's not much.
> The only plausible answer is that they have a dominant market position
Not necessarily. If the internet were as essential to average daily life today in the US as electricity (which I am not declaring true or false in this particular sentence), then it would be reasonable to treat ISPs but not websites as common carriers no matter how competitive the internet access market is.
Another answer that doesn't rely on the previous one would be that it is not reasonable to expect a social media site to deliver a user's speech as reliably as one would expect an ISP to deliver the speech. I got this idea from an excerpt on Wikipedia [1]:
> Cases have also established limitations to the common carrier designation. In a case concerning a hot air balloon, Grotheer v. Escape Adventures, Inc., the court affirmed a hot air balloon was not a common carrier, holding the key inquiry in determining whether or not a transporter can be classified as a common carrier is whether passengers expect the transportation to be safe because the operator is reasonably capable of controlling the risk of injury.
If you're referring to common carriers offering transport of physical goods or people (as cargo railroads and passenger railroads do) then a different answer could be that users can sometimes have priority over physical property owned by someone else, while treating websites as common carriers would mean giving users priority over physical property owned by someone else which the owner also uses (e.g. puts terms of service on and moderates) to express what kind of website the website is. In other words, outweighing property rights alone is easier than outweighing property rights and speech rights combined.
Moreover, I'm guessing that whether the public associates an ISP with third-party speech depends on whether the speech is protected. Suppose that a social media site is notorious for users who speak in favor of copyright infringement (copyright infringement being unprotected speech). The public might associate the ISPs those users use with copyright infringement (anecdote: Reddit, Frontier, and copyright infringement [2]). But what about protected speech? A social media site is notorious for users who speak in favor of hate crimes. Will the public be comparably likely to associate the ISPs those users use with hate speech?
But nothing I wrote above is not really an answer, since I've been speculating for the most part. I'm not very knowledgeable about the legal theory behind a common carrier designation, so here is something closer to an answer from Mike Masnick [3]:
> As you look over time, you’ll notice a few important common traits in all historical common carriers:
> 1. Delivering something (people, cargo, data) from point A to point B
> 2. Offering a commoditized service (often involving a natural monopoly provider)
> In some ways, point (2) is a function of point (1). The delivery from point A to point B is the key point here. Railroads, telegraphs, telephone systems are all in that simple business — taking people, cargo, data (voice) from point A to point B — and then having no further ongoing relationship with you.
> That’s just not the case for social media. Social media, from the very beginning, was about hosting content that you put up. It’s not transient, it’s perpetual. That, alone, makes a huge difference, especially with regards to the 1st Amendment’s freedom of association. It’s one thing to say you have to transmit someone’s speech from here to there and then have no more to do with it, but it’s something else entirely to say “you must host this person’s speech forever.”
> Second, social media is, in no way, a commodified service. Facebook is a very different service from Twitter, as it is from YouTube, as it is from TikTok, as it is from Reddit. They’re not interchangeable, nor are they natural monopolies, in which massive capital outlays are required upfront to build redundant architecture. New social networks can be set up without having to install massive infrastructure, and they can be extremely differentiated from every other social network. That’s not true of traditional common carriers. Getting from New York to Boston by train is getting from New York to Boston by train.
He's grasping at straws trying to distinguish them:
> It’s one thing to say you have to transmit someone’s speech from here to there and then have no more to do with it, but it’s something else entirely to say “you must host this person’s speech forever.”
This is exactly what we ask of phone companies. As long as the customer has an account, the phone company routes their calls, forever, or until they cease to be a phone company.
Also notice how disingenuous this is. What it's meant to evoke is the unreasonable notion that they're required to keep operating their service for your benefit for free forever, when what we're really talking about is a non-discrimination rule. If they're continuing to host everybody else's 15 year old posts, they can continue to host yours. If they want to shut down their site, or delete everything more than 10 years old from everybody, they can do that too. The issue is when they want to delete you and not somebody else, solely because they don't like your opinions, or because their algorithm screws over innocent people and they don't care to fix it or have any responsibility for it.
> Facebook is a very different service from Twitter, as it is from YouTube, as it is from TikTok, as it is from Reddit.
Air travel is a very different service from trains, as it is from cars, as it is from ships, as it is from spacecraft. What does that have to do with whether planes or trains or taxis are common carriers?
If anything this is the problem. If they were all completely fungible services and you actually could just start your own with no loss of utility then it wouldn't matter what they do because you would have so many viable alternatives. The reason it matters is that you can't feasibly reach your Facebook audience via Tiktok, nor can you stand up your own Facebook instance if you have a dispute with Meta and use that to communicate with Meta's users.
Make it into that kind of fungible commodity market and then there is no problem with anyone moderating however they like -- because if you don't like someone's moderation you could swap them out without losing access to the people in the same network.
>> It’s one thing to say you have to transmit someone’s speech from here to there and then have no more to do with it, but it’s something else entirely to say “you must host this person’s speech forever.”
> This is exactly what we ask of phone companies. As long as the customer has an account, the phone company routes their calls, forever, or until they cease to be a phone company.
The phone company hosts a phone call for you and someone else. After you hang up, the phone call is over. Unless the contract promised as much, you have no expectation of later being able to ask the phone company to give you a recording of the call. The person on the other end has no expectation of later being able to ask the phone company to tell them what you said. The call is one and done. A social media post? Not so. You post, and as long as no automation removes it and no person manually removes it, the post stays and continues getting served.
As long as a customer has an active contract with the phone company, the phone company must continue to provide calls unless someone triggers an exit condition in the contract, in which case the phone company would be able to remove the account. But your average phone contract will not guarantee you a service for hosting an individual phone call forever.
Currently, any TOS you'll find from the big social media sites will allow the sites to remove any post or user for any reason or no reason at all. That's an exit condition that's always active. Everyone gets the same contract. Currently, the contract lasts 0 seconds, and possibly longer if the social media site decides to keep your posts up, doesn't decide to take them down, or forgets to take them down. If you turn certain social media companies into common carriers, then where would you draw the line relative to Facebook and a Mastodon instance? Twitter and a social media site for game discussions? Truth Social and Bluesky? Where does Hacker News fit into this? Would you turn all social media sites into common carriers, and how would you define a social media site? Keep in mind, a phone company doesn't stop being a common carrier if the phone company loses market share.
Mike Masnick's "fungibility" argument is unclear at best, but his point that transportation service is transient still stands [1]:
> Social media, from the very beginning, was about hosting content that you put up. It’s not transient, it’s perpetual. That, alone, makes a huge difference, especially with regards to the 1st Amendment’s freedom of association. It’s one thing to say you have to transmit someone’s speech from here to there and then have no more to do with it, but it’s something else entirely to say “you must host this person’s speech forever.”
...
> It is hosting content perpetually, not merely transporting data from one point to another in a transient fashion.
The average train company is a common carrier. You book a trip from station A to station B. You take the trip, and that's it. You don't get to take another trip with the same booking unless the contract said so.
Assume that ISPs are common carriers (which is not true because the FCC under Ajit Pai decided that ISPs are not common carriers; however, making ISPs common carriers is easier to justify than making social media websites common carriers). An ISP transmitting a website to you is not obligated to host the website, because transmitting bits doesn't functionally require storing them beforehand and because a large chunk of the responsibility of making sure that the website data to be transmitted exists right at this moment falls on the website owner.
Now assume that a particular social media website is a common carrier. You haven't made the case that social media sites must store posts. The social media site must allow anyone to sign up. The social media site must transmit any posts whose contents and audience have been specified, but it would be your responsibility to make sure that the social media site receives the contents to put in the posts every time someone wants to receive those posts. For example, you set a post to followers-only and send it. The post will be sent SMS-style to everyone who is currently following you. If you want followers to continually request a post, you are responsible for setting up an automated system to give the social media website the right post content i.e. you would have to host the posts to be transmitted. If the website offers to automatically read a passive folder of posts you want to repeatedly transmit, then the website has to offer that capability to everyone. However, the website can discriminate in deciding whose posts to host. The website might offer to host your posts, but doesn't have to do so for some amount of time unless the contract specifically says so, and doesn't have to make an identical offer to other users.
The issues with the Darling 58 project had some good discussion here two weeks ago[0].
Tangentially: A distillery in Los Angeles, The Obscure, is making a rye whisky aged in American Chestnut barrels, with some of the proceeds going to the American Chestnut Foundation. It's quite good.
I try to avoid nits totally unrelated to the changes at hand, since on a subconscious level they may discourage people from even wanting to touch older/less loved files at all.
The critical exception being avoiding issues due to path dependence.
E.g while a change is "correct" is doing X poorly because of surrounding issue Y. So we should fix Y now instead of building atop it.
I think it's just a very confusing, hard to use correctly behavior. And according to the article, very bug prone in implementations.
In the example given, the result is that both writes happened before both reads, which directly contradicts the source. There's a valid explanation for why it happens, but it's still paradoxical.
I remember at work a C++ standards committee member was giving examples of atomic and how to use them safely with different memory models, when someone pointed out his toy example for relaxed order was wrong. It took 5 people debating for a week to figure out what a safe/correct behavior would be. For a 10 line sample class.
As times your second question, the article recommends Hans Boehm's proposal to add a no-op conditional branch after the read. I guess it forces the load to be resolved and enforces a sequenced-before behavior on the individual threads. So at least one read must resolve before one write in the example.
Yes, relaxed memory semantics are exceedingly difficult to reason about. Hard to believe this is news to the C++ standards committee.
I find the premise of this article confusing, and assume it must be because I’m missing something crucial—obviously Hans Boehm knows what he’s talking about. Why do (opt in!) relaxed semantics need to be fixed?
> relaxed memory semantics are exceedingly difficult to reason about
People say this but I don't understand how? They're basically just like ordinary variables. Except even better, because you can use them from multiple threads. And it's guaranteed that a given thread will only ever see values that were actually written by the program (like it's guaranteed the compiler won't introduce spurious writes during optimization). There's no ordering guarantee, just like there's no ordering guarantee across threads for ordinary variables. If relaxed atomics are too hard then aren't ordinary variables too hard?
You can certainly use them in a way that's confusing, but that's not because they're themselves complicated - it's because you're writing confusing code. You can do that in a single thread too, with ordinary variables. It's not specific to relaxed atomics.
In fact, in my experience, the most confusing atomics are the sequentially consistent ones! I never know when I need to use them in practice vs. acquire/release.
There's no ordering guarantee, just like there's no ordering guarantee across threads for ordinary variables.
This is what makes them hard to reason about. C++ makes “as if” ordering guarantees within a single thread trivial: If you can observe things happening out of the order in which your defined-behavior code sequenced them, you have a bug in your compiler or your CPU.
Relaxed ordering (on purpose) throws out all implicit sequencing guarantees when threads observe each other.
My confusion is that I believed this was all well-understood by implementers and programmers decades ago. That relaxed is harder than sequential to get right was as true on the Alpha as it is on modern ARMs. But this article seems to suggest what should be obvious consequences of relaxed semantics are unexpected & undesirable for C++!
> This is what makes them hard to reason about. [...]
I think we're speaking past each other.
You're implicitly assuming there is some piece of code using atomics, and you're saying it's harder to reason about its behavior when the atomics are made to be relaxed (versus, say, sequentially consistent). That's true enough, but it misses my point.
I'm coming at this from the opposite direction: I have certain kinds of atomics available, and then I'm using them to write the code. In such a scenario, it's quite easy to distinguish between "I might care about ordering" vs. "I don't care about ordering". In the first case, you probably shouldn't use relaxed atomics - good luck figuring out what to use, it may very well be tricky. If you insist on using relaxed atomics for those, it will definitely be tricky to get it right if it's at all possible, but that's when you should avoid relaxed atomics if at all possible. In the latter case, you should use relaxed atomics, and it's not tricky because you already know ordering doesn't matter.
Example: relaxed atomics are trivial to reason about in single-writer situations that aren't signaling any kind of event. Like when a worker is just trying to report progress to the foreground UI with minimal overhead. In this example, the writer (which is on a background thread) simply loads its progress indicator, adds 1, then stores back the variable. There isn't even a need for an atomic RMW, let alone any ordering. The worst case is the user will see "100% done" a few milliseconds too early, which is a non-issue (and already bound to happen due to rounding etc. anyway). Using relaxed atomics doesn't introduce any complexity in such a situation; it's basically exactly what you'd expect from ordinary variables without write-tearing.
You run into problems if you try to depend on the "100% progress" indicator to mean "everything is finished" (so you can, say, clean up data structures), but at that point you clearly need ordering and shouldn't use a relaxed atomic to begin with; you'd want release semantics (or stronger), and those are trickier.
> My confusion is that I believed this was all well-understood by implementers and programmers decades ago.
I definitely agree with this part. I didn't think in 2023 I would read that programmers are shocked that relaxed atomics can be reordered. That's... their entire point. It's like being shocked that compilers propagate constants during optimization.
> I didn't think in 2023 I would read that programmers are shocked that relaxed atomics can be reordered.
At my current and prior jobs, I've had to do the "C++ cleanup" job while porting some x86_64 code to ARM. The TSO model from x86 is just something I think a lot of people have assumed and haven't been hurt by (again because it's TSO). Most of the work I had to do is basically using all the SA and sanitizers I could, staring hard at the code to convince myself there wasn't some secret data dependency on some relaxed atomic.
"It's just a simple flag, so I'll use a relaxed atomic, nbd", meanwhile the same person is assuming another structure they've "published" (e.g. to a shared queue) will be visible is alarming.
Isn't the problem elsewhere here? The fact that people are using an API whose entire purpose they don't understand? "I passed a flag without understanding at all what it's supposed to do" doesn't seem specific to atomics at all.
This feels exactly like crossing an intersection without looking around despite noticing a sign saying "blind intersection", then being surprised when you get hit, then blaming it on the sign being "tricky" to reason about. There was nothing tricky about the logic... you just ignored it.
Just to be clear, I'm agreeing with you. It's people using an API they don't understand but happens to work because of TSO. When you take away TSO (e.g. on ARM), those assumptions come back to haunt the code in very tricky race conditions.
Context matters. In the context of a single thread, ordinary variable reads and writes happen as if they were in program order. So in that context, they are extremely natural. When shared across threads, reading and writing ordinary variables happens under a lock, so everything still appears as if in program order.
Atomics are used in a context of being shared across threads without locks. In that context, reasoning about them makes you actually think about memory ordering in a way that wasn't there with ordinary variables.
Sequentially consistent atomics are the easiest to reason about because all seq_cst atomic operations within a thread happen in program order (and are visible to other threads in that order). Relaxing that to acquire/release/relaxed loosens that, so it requires more thinking about what needs to be visible and in what order. It's only complicated because seq_cst has a performance cost, so you typically want to think about whether it's necessary or not for the particular use case. But reasoning about what is happening with an algorithm when using seq_cst atomics is always at least as easy as when using looser ordering.
Under certain assumptions. This method relies on making its assumptions expensive to violate. Which is good enough in practice...
...unless you're dealing with an attacker with vastly more resources than you, and a will to spend it. It's always worth keeping in mind that the way magic tricks work is usually because the performer invested much more time and effort in preparation and practice than anyone in the audience would consider reasonable.
But you can do almost all that while working at Google. And imo, the stability makes it even easier to do so.
It's been my experience that Google is a super chill place to work, especially when you take advantage of the fact that you're just one cog among many.
You get 5 weeks pto plus 4 weeks work from anywhere. This year alone I'm going to the Arctic, Antarctica, and the Carribean.
Including a 40 day stretch without internet. I couldn't imagine doing the latter in a startup.
And all the while getting paid and having the comfort to make plans knowing that I'll (probably) continue to do so in the future.
It absolutely is, and I think it's what separates good from bad and junior from senior devs.
Most devs can produce an artifact that more or less works. But one that has an internal consistency others can understand and extend, one which accurately captures the problem as it exists and ways it will likely change, is much more of an art form.
A big part of that is knowing which situations are worth making a stand. Every you write code or leave feedback, your doing it for your team current and future.