@graydon@types.pl cover

semi-serious slightly-more-public / professional account, mostly computer stuff with a dash of leftist political advocacy

dislike attention and deeply loathe getting into arguments with strangers on the internet, but am easily drawn into them regardless. therefore likely to block if debated. it's nothing personal, just my own self-preservation; there's no option to disable replies, and my next-best option is simply not to be here at all. sorry.

This profile is from a federated server and may be incomplete. View on remote instance

@whitequark@treehouse.systems avatar whitequark , to random

target triple
look inside
four parts

graydon ,
@graydon@types.pl avatar

@whitequark there are three hard things in computer science, and between two and five of them are known to appear in a target triple.

@graydon@types.pl avatar graydon , to random

the idea that I'd be somehow opposed to tools that make C/C++ safer because I guess they make rust marginally less attractive by comparison in some contexts is like .. insultingly silly.

language pluralist. also I live on planet earth where there are eleventy trillion lines of legacy C/C++ that even TRACTOR++9000 will never manage to rewrite. also the next two day jobs after rust were (surprise!) C++ and I've only very recently got to use in rust professionally at all. also it's just not always the best tool for lots of jobs. also lots of people dislike it and they are allowed to. like come on! people!

graydon OP ,
@graydon@types.pl avatar

@matt yeah, I mean, I can understand both of those aspects to a moderate extent but .. I guess to me it seems like universal adoption of any language just isn't plausible, and also isn't necessary to get you over the hump of good-enough network effects and the local zero-sum-ness of making per-project PL choices (after all rust is at 2% now and plenty of projects choose it!)

the question is: should the 98% of people who don't choose it, or the 20%ish of all new code that's C/C++, or the 99.99%-of-all-code that's existing already-written codebases, have some other options to help their computers not get taken over? or should they just be punished until they make the right choice? to me this has a fairly obvious answer.

graydon OP ,
@graydon@types.pl avatar

@matt yeah I mean the fundamental issue to me is just that on even the most aggressive RIIR timeline I can imagine (which is not exactly forthcoming!) we've got decades ahead of us of unix, windows and macos/ios userspaces that are otherwise going to be deployed and vulnerable. plus vast, vast amounts of in-house and embedded code. and a lot of legacy code is of the form "nobody alive knows exactly what it does or how it works" so even rewriting is deep archaeology and behaviour-regression.

graydon OP ,
@graydon@types.pl avatar

@matt and also like .. gosh .. I really wish we could all at least agree collectively that a little perf overhead is worth it for meaningful safety. I wish rust had shipped more (eg. checked arithmetic by default).

sadly people keep shipping new PLs that trade the other way. zig, hare, odin, jai -- fine languages! -- but whoops we're back to pervasive memory errors. I guess it'll depend if anyone is actually willing to pay the dynamic checking cost or if it just turns into a rhetorical thing ("our code can be safe! but ugh so slow so we will turn it off in prod")

like I really truly want the speed limit on my town's streets limited to 30km/h you know? and I would 100% buy a cell phone that said "this can't be taken over via memory bugs" even if it's noticeably slower. I bet a lot of people would. safety features are good!

graydon OP ,
@graydon@types.pl avatar

@josh @matt well, "numeric" libraries are usually floating point.

there are libraries with hot integer loops (crypto, codecs, hashing, parsing, serialization) but these are libraries that already do lots of micro-optimization and benchmarking and pay attention to their bit-twiddling -- they'll have no problem just picking the wrapping ops when checked ones show up in profiles.

the rest of the time, in non-inner-loop code, IME integer math is mostly like either harmless user-config-value stuff or else "a few numbers multiplied together and then passed to an allocator or bulk-copy unsafe function" and that latter one is the problem. attacker can make one of the terms a little bigger than you expected => uh oh.

@graydon@types.pl avatar graydon , to random

pointing out that rust does not fix all classes of errors is just not the epic dunk people seem to think it is

more like a reheated PL-world version of the "thanks, obama" meme or something? like ok I guess if you really need to get that out of your system

graydon OP ,
@graydon@types.pl avatar

(this seems to be getting fresher by the day, I guess the more people use rust in production the more that'll be clear? there are lots of ways to make most programs in most languages -- memory safe languages! -- halt with a fatal error. we know this right? we do not write in total languages with functional correctness proofs. like basically anyone at all. it'd be great if we did but the set of people who get paid to do that is extremely small and they produce code at a rate that would make your manager fall out of their chair laughing. because it is extremely super duper hard. that was 100% not the target niche rust was aiming for.)

graydon OP ,
@graydon@types.pl avatar

(like y'all remember java has NPE right? null pointer exception? java is memory safe. it's great. java or C# with null split out into its own type like option so you can mostly statically exclude it is even better. we're just trying to get systems programmers to that point. the crash is the good case. the bad case is "someone takes over your computer". that's why Fil-C was describing itself correctly as a memory-safety system last week. because it turns all the bad cases into crashes. the crash is the good case.)

graydon OP ,
@graydon@types.pl avatar

@zwarich @uep oh yeah the bug's particulars seem odd in their own right. I just mean like .. people write bugs, y'know? in languages. "this can't happen" is an easy thing to be wrong about somewhere.

@graydon@types.pl avatar graydon , to random

for years I've ground my teeth every time I read someone getting excited about a new operating system in terms of whether its GUI has a fresh coat of paint. a little bit of me wants to shout "the GUI is the smallest and least relevant part!"

but deeper down I know of course it actually does take up a lot of code -- GUIs are a huge investment of programming effort -- and more importantly users see and care about them a lot, and don't tend to see and care about a lot of the plumbing I snobbishly wish got more attention.

all this is to say: it is at least somewhat .. refreshing? enjoyable? .. to see the opposite mode: people getting upset about an operating system update when all they're really upset about is "the GUI has an ugly and buggy new coat of paint".

@zwarich@hachyderm.io avatar zwarich , to random

@graydon Someone linked your "things Rust shipped 1.0 without" post and I noticed it included "a compilation model that relies on the order of declarations". What about the traditional ML style of ordered declarations did you dislike?

graydon ,
@graydon@types.pl avatar

@zwarich I think it's nice to be able to move declarations around in a file or among files without changing meaning. and I think it's broadly annoying to force people to topo-sort their declarations and/or definitions (especially if they're mutually recursive). I guess if you have forward declaration for everything, and (more importantly) if you can only ever define a decl once, I suppose it's not so bad. but a lot of PLs fall down on one or another of those.

@graydon@types.pl avatar graydon , to random

re last boost: imagine living inside of a brain that thinks "making a tiny harmless symbolic gesture of solidarity" is an "exploit" that you were "fooled by" once but you "won't repeat that mistake".

like what can that possibly mean? what exploitation is befalling you?

@graydon@types.pl avatar graydon , to random

Honest opinions please. People still taking precautions about covid (masking or limiting social contact) are:

@graydon@types.pl avatar graydon , to random
graydon OP ,
@graydon@types.pl avatar

@joe uh .. I guess .. when we switch to indirect references like maybe a helpful aspect of that hypothetical arena-oriented systems language? or an ECS? just spitballing.

@joe@f.duriansoftware.com avatar joe , to random

C and C++ should let you use another enum as an enum's underlying type

ALT
graydon ,
@graydon@types.pl avatar

@zwarich @joe yeah every napkin-sketch design for "another damn systems language" I have in my drawer starts with "arenas for everything" and works backwards from there.

graydon ,
@graydon@types.pl avatar

@joe @zwarich a fair observation. I always try to emphasize the multiple goals served by the ownership structure, not just memory safety. but there are a lot of really obnoxious design edge cases that just go away if you have coarse intra-program boundaries you can safely and cheaply roll back to (not least: how you handle errors -- cf. rust's panic-handling muddle)

@chrisamaphone@hci.social avatar chrisamaphone , to random

trying to understand a chicken and egg thing. are most gyms “weightlifting gyms” because weightlifting is the main sport people want to do when they decide to try to get fit? or the other way around? and in either case, why?

graydon ,
@graydon@types.pl avatar

@chrisamaphone yes lots of people view it as a chore and don't find any of the alternatives fun either -- they are just boring and painful scheduled blocks of suffering, done for health or beauty (hence all the listening to podcasts / watching TV while exercising).

most other supposedly-more-fun forms are also (variously): expensive, outdoors (so weather dependent), dangerous, embarrassing, require coordinating with a buddy or a team, take a long time, require training, require special equipment, or require large specialized spaces set up so are rare.

the modern semi-standardized gym also isn't just weights: it's cardio machines (rowing/cycling/ellipticals/treadmills), bodyweight and calisthenics mats/bars/anchor points, free weights and weight machines. it's a 24/7 DIY salad bar of cheap, simple/no-instruction, compact devices to get your annoying chore done as quickly as possible (like ~30min). often just like in an otherwise-unrented office space (so ubiquitous).

@graydon@types.pl avatar graydon , to random

on the off chance anyone else wants to relive the moment of bootstrapping rust 14 years ago:
https://graydon2.dreamwidth.org/317484.html

@mcc@mastodon.social avatar mcc , to random

So like
Rust has the ownership model

The ownership model says that you can have EITHER one writer XOR many readers

The ownership model has two benefits:

  • Allows safe, exact memory management (concrete)
  • Decreases bugs (claimed by Rust fans)

Say I wished to remove the XOR from the ownership model— I write a linear typed language, and my rule is only "at most one writer". Is there any reason this would be impossible? (Say I don't care about the claimed bug reduction, only memory management.)

graydon ,
@graydon@types.pl avatar

@mcc the bug that is tricky to prevent is this:

enum U {
Int(i64),
Ptr(Box<i64>)
}

let mut x = U::Ptr(Box::new(10));
match x {
U::Ptr(ref b) {
x = U::Int(1234); // clobber ptr
println!("{}", b); // derefs 1234
}
}

because rust is a non-uniform-representation language, and one that lets you take pointers into the middle of things, and even lets you change the size of things you're pointing into the middle of, you have to prevent mutation while such references are outstanding if you want to ensure type safety and thereby memory safety.

you can construct something similar / less-contrived-seeming with iterator invalidation though it's easier to do workarounds like copy-on-write since the resized vec is already on the heap:

let mut x = vec![1,2,3,4];
for i in x {
x.push(1); // might resize x
println!("{}", i); // use after free
}

if you read through early design notes on rust and the borrow checking rules, you'll see reference to "dan's bug" which is the former change-the-variant-of-a-referenced-enum-thereby-breaking-type-safety bug, and is directly what led to the current rules.

graydon ,
@graydon@types.pl avatar

@mcc (put differently: if you're in a PL where all fields / variables that store pointers point to the first word of a well behaved heap cell -- a uniform representation language -- you can do much, much easier stuff! but you leave a lot of performance on the table if you are always chasing pointers and exploding nested structures into separate allocations. there is a little bit of design room between -- eg. treat unions as special containers or whatever -- but we didn't land there. we did try a lot! rust was originally a copy-on-write language, like newsqueak .. or I guess early swift! people forget a lot :)

@graydon@types.pl avatar graydon , to random
@graydon@types.pl avatar graydon , to random

Re last boost: this is something people often don't get about Rust.

Preventing mutable-aliasing bugs is substantially orthogonal to temporal or spatial memory safety. Rust does both! Having GC only addresses one of these. And mutable aliasing bugs are super pervasive and terrible.

(Yes yes FP people: GC + purity addresses both -- and purity also means your GC can be really simple! -- but .. now you have a different problem)

I wrote about this a while back but it was a longer post connected with formal verification implications so was probably TL;DR
https://graydon2.dreamwidth.org/312681.html

@graydon@types.pl avatar graydon , to random

Re last boost: my spicy take is PLs should probably not ship with both of (a) subtyping and (b) first class function types or user-defined generic container types. You can have second class and built in versions of the latter, or omit the former, but otherwise you are probably past the limits of comprehensibility if you are trying to surface parameter variance in the user visible type sublanguage.

(Though if you try anyway, I do like Kotlin’s approach!)

@graydon@types.pl avatar graydon , to random

Dear PL nerds: please send me your best recommendations on papers to read and projects to examine around type systems and/or other PL features related to prevention of dimensionality and cardinality mismatches, ideally in array or collection-oriented languages. Thanks!

@graydon@types.pl avatar graydon , to random

pet peeve: people suggesting or inferring rust "never cared or thought about" compile time. it was 100% part of the early-days language design to compile very fast: not type-specialize, present stable-ABI libraries, not propagate types beyond single-crate, not inline across crate boundaries, not LTO, not do turing-complete type substitutions or const-eval, etc. etc.

users and later contributors repeatedly and successfully argued for language changes that sacrificed compile time for runtime perf, because for big systems programs the program runs a lot more than it gets compiled.

lots of the issues involved are in direct tradeoff, and despite the habitual cultural drive in the rust community to reject tradeoffs and try to have it both ways, that .. actually doesn't often work. many tradeoffs are quite robust.

@dsp@nullptr.rehab avatar dsp , to random

Woke up to a very nice email from the very own @graydon about source control. Learned a bunch. Now I just need to find time to write the other parts to my initial blog post :).

That said, I so much enjoy having people like Graydon and Marc reach out to me and tell a piece of their part of the story. Graydon told me his take on the fascinating story of how the idea of DAG's came to be in source control systems, originating in Monotone and thought up by a member of the community at the time.

graydon ,
@graydon@types.pl avatar

@durin42 @dsp Well, you can draw a DAG on the structure of lots of distributed systems, I wasn't saying Monotone shipped the first or only system you can draw a DAG on (or did any sort of DAG-based reasoning)!

Merely that the narrow, specific DAG-construction technique of naming each node in a history graph via a cryptographic hash function combining the current content and the node's immediate ancestors showed up first in Version Control in Monotone (due to Jerome Fisher's insight).

The two inputs had some prior art! Nothing happens in a vacuum. Recursive hashing of "trees in general" goes back to Ralph Merkle in 1979 and was present and known-to-us as a production technique to apply to filesystems such as the Venti filesystem, as a way of getting automatic deduplicating-CoW semantics. And recursive hashing of a history of states was present in R&D papers at least in the cryptography community under the name "Linked Timestamping" (usuaully just as a linear time sequence to prove a point-in-time).

But Monotone was the point where the two techniques were hybridized and this sort of "instantly and obviously very useful" hash-the-node-and-its-parents technique got started. And it's fairly clear if you look at the history of systems! All previous systems didn't use it, and most later ones did.

Including tons of systems outside VC. It's a very general distributed-system-building construction technique, that gets you a guaranteed global partial order on all events at O(1) storage and compute cost, requires no synchronized clocks or other coordination, and throws in strong immutable-history and integrity checking as a bonus.

@graydon@types.pl avatar graydon , to random

I did a little blogging about Rust and formal methods and local reasoning and stuff. Let's see how fast a link posted to the fediverse propagates!

https://graydon2.dreamwidth.org/312681.html

graydon OP ,
@graydon@types.pl avatar

@pervognsen I am also an ignoramus and am not able to answer that question confidently, but my impression is that Ralf is interested in the holistic view of Rust in the sense of including the unsafe sublanguage, and therefore needs to use more potent tools.

graydon OP ,
@graydon@types.pl avatar

@pervognsen hmm in that example I think x and y must both be &mut and since x remains live across the assignment through y I think they are exclusive. but I really am just a baby at this stuff.