Hacker Newsnew | past | comments | ask | show | jobs | submit | more TwentyPosts's commentslogin

Honestly struggling to comprehend how this one isn't neutral.

As far as we know this was a supply-chain attack specifically on military pagers actively used by Hezbollah, and (right now) it looks like most injured are in fact Hezbollah members (which makes sense, since no one else has any reason to carry such a pager). (With some sad and unfortunate exceptions.)


After I posted my comment the title was updated to be a little bit more neutral.

The previous headline was emphasizing a little too strongly the assumption that this attack was against Hezbollah only, and as you mention there are "exceptions", meaning, civilians and non-militants (including children) were killed and injured.

EDIT: in other words, the headline is/was written with the assumption that whoever was attacked was a member of Hezbollah, but this isn't true.


When half the official death toll are children and medical staff, calling this an attack on "Hezbollah" is a clear form of IDF-leaning bias: https://x.com/AssalRad/status/1836428722381164935


This is semantically not the same as a sum type (as understood in the sense of Rust, which is afaik the academically accepted way)!

Python's `A | B` is a union operation, but in Rust a sum type is always a disjoint union. In Python, if `A = B = None`, then `A | B` has one possible instance.

In Rust, this sum type has two possible instances. This might not sound like a big deal, but the semantics are quite different.


Sorry, I could not grok the difference, even after reading a few Rust examples.

def foo(int | None = None) ...

... just means the variable's default value is None in a function definition. But it could be either in an actual function call.


There's no difference there because the types are already disjoint.

Say you wanted to define some function taking `YYMMDD | MMDDYY`. If both YYMMDD and MMDDYY are just aliases to `str`, then you gain no information, you cannot discriminate on which one it is, since the union `str | str` just reduces to `str`.

Sum types are disjointed unions, you can't just say `str | str`, the terms are wrapped in unique nominal data constructors, like:

enum Date { MMDDYY(String), YYMMDD(String) }

Then when accepting a `Date` you can discriminate which format it's in. You could do the same in Python by defining two unique types and using `MMDDYY | YYMMDD`.


The original rust compiler was written in OCaml. That's not evidence it "had an influence", but it's highly striking considering how many other languages Greydon could've used.


Yes: if a person knows nothing else about Rust and the languages that might have influenced it, then the fact that the original Rust compiler was written in OCaml should make that person conclude tentatively that OCaml was the language that influenced the design of Rust the most.

I'm not one to hold that one shouldn't form tentative conclusions until one "has all the fact". Also, I'm not one to hold that readers should trust the opinion of an internet comment writer they know nothing about. I could write a long explanation to support my opinion, but I'm probably not going to.


It's like trying to say Elixir wasn't influenced the most by Erlang


Was any Elixir interpreter or compiler every written in Erlang?

If not, what is the relevance of your comment?


Elixir’s implementation still has significant parts written in Erlang. I don’t know if it’s a majority but it’s a lot. e.g.: https://github.com/elixir-lang/elixir/blob/aef7e4eab521dfba9...


HOTA?


Community mod, that re-balances game mechanics, fixes bugs, adds features like advanced keyboard shortcuts, fullscreen hd, two new factions, online multiplayer lobby.

This game still has very active pro-scene


Horn of the Abyss unofficial mod


You sound like you'd enjoy giving the Helix editor a try. It replaced neovim completely for me.


Helix is really great. It’s so nice to not require screenfuls of configuration. And Emacs Lisp fans will feel right at home when the Scheme plugin system lands


How will emacs fans feel at home, in an editor that has mandatory modal editing?


It sounds like the parent is proposing Helix as an alternative to nvim for modal use cases. I’ll have to check it out.


It's a good editor, if modal is your thing. Requests in the past to add immediate-style editing capabilities have basically stated it won't/can't happen.


I keep coming back to Helix ... but... modal editing.

Nope.


So now you're writing two compilers.

What did you actually gain from this, outside of more work?


Writing a small compiler in C and a big compiler in Rust is simpler than writing a big compiler in C.


But writing a Rust compiler in Rust is already done.


Sure, but the small compiler that you write in C can't compile rustc. So you write a new Rust compiler that uses much simpler Rust that the small compiler in C can compile. Then that new Rust compiler can compile rustc.

And since that new Rust compiler might not have much of an optimizer (if it even has one at all), then you recompile rustc with your just-compiled rustc.


No that makes no sense to me. Or are we pretending cross-compilation doesn't exist?


Sometimes people like to do things just do do them, because the idea is cool. Sometimes an idea is cool because it has real world ramifications just for existing (trusting trust, supply chain attacks), though many people like to argue about whether or not this particular idea is Just Cool TM or Actually Useful TM. I don’t think the article made any false pretenses either way- it seemed evident to me that at least some of the motivation was “because how? I want to do the how!” And that’s cool! Also, I think the article pretty clearly redirects your question. Duh he could just cross compile rust. But the whole article, literally the entirety of it, is dedicated to exploring the chicken/egg problem of “if rustc is written in rust, what compiles rustc?”, and the rabbithole of similar questions that arise for other languages. The answer to that question being both “rustc of course”, and also “another compiler written in some other language.” The author wants to explore the process of making the compiler in [the/an] ‘other language’ because it’s Cool.

Just because something has already been done, does not mean there’s no worth in doing it- nor that there is only worth in doing it for educational and/or experiential purposes :)


Cross-compilation is orthogonal to bootstrapping, which is the major motivating factor for having something like what is described earlier in this thread: a small compiler written in C which can compile a subset of Rust, used to compile a larger, feature complete Rust compiler in that Rust subset -- versus what we have right now, which is a Rust compiler written in Rust which requires an existing Rust compiler binary, which means we have an unmitigated supply chain attack vector.

If you change your question to "why does anyone care about bootstrapping?", the answer would revolve around that aforementioned supply chain attack vector.

For details, you could check out:

- Reading the 1984 paper "Reflections on Trusting Trust", for which Ken Thompson was given the ACM Turing award: https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_Ref...

- Or watching this short Computerphile video on the above: https://www.youtube.com/watch?v=SJ7lOus1FzQ

- You can read about the GNU Guix endeavor to achieve a 100% bootstrapped Linux development environment (using zero pre-compiled binaries), starting from a 357-byte HEX file: https://guix.gnu.org/en/blog/2023/the-full-source-bootstrap-...

Perhaps you're comfortable with the lack of assurances that non-boostrapable builds entails (everyone has a different appetite for risk); some others aren't though, and so they have an interest in efforts to mitigate the security risks inherent in trusting a supply chain of opaque binaries.


The post is about solving a specific same-architecture bootstrapping problem. Cross-compilation is irrelevant to this discussion.


Yes, they are because they want to target systems which explicitely disallow cross-compilation like Debian.

Yes, I think it's silly too but other people disagree and they are free to work on whatever they want. Do I think it's a mostly pointless waste of time? Obviously, I do. Still, I guess there are worst ones.

Note that the Rust project does use cross-compilation for the ports it supports itself and considering the amount of time they use features only available in the current version of rustc in rustc, I guess it's safe to assume they share my opinion on the usefulness of keeping Rust bootstrappable.


There are two kinds of bootstrapping:

* Bootstrapping a language on a new architecture using an existing architecture. With modern compilers this is usually done using cross compilation * Bootstrapping a language on an architecture _without_ using another architecture

The latter is mostly done for theoretical purposes like reproducibility like reflections on trusting trust


Paring down a rust compiler in rust to only use a subset of rust features might not be a big lift. Then you only need to build a rust compiler (in C) that implements the features used by the pared-down rust compiler rather than the full language.

Pypy, for instance, implements RPython, which is a valid subset of Python. The compiler is written in RPython. The compiler code is limited on features, but it only needs to implement what RPython includes.


How do you compile that on a new platform?


Cross-compilation. There is no requirement of being able to run the compiler on the platform to compile for that platform.

It is much easier to add support for a platform to the compiler backend than to write a new, full compiler with its own, new bootstrapping method.


One way would be to have an intermediate target that is easily recompiled or run on any hardware.

https://ziglang.org/news/goodbye-cpp/


But that doesn't conform to the "Descent Principle" described in the article.

I haven't really been following Zig, but I still felt slightly disappointed when I learnt that they were just replacing a source-based bootstrapping compiler with a binary blob that someone generated and added to the source tree.

The thing that makes me uncomfortable with that approach is that if a certain kind of bug (or virus! [0]) is found in the compiler, it's possible that you have to fix the bug in multiple versions to rebootstrap, in case the bug (or virus!) manages to persist itself into the compilation output. The Dozer article talks about the eventual goal of removing all generated files from the rustc source tree, ie undoing what Zig recently decided to do.

If everything is reliably built from source, you can just fix any bugs by editing the current source files.

[0] https://wiki.c2.com/?TheKenThompsonHack


I think there is too much mysticism here in believing that the bootstrapping phases will offer any particular guarantees. Without essentially a formal proof that the output of the compiler is what you expect, you will have to manually inspect every aspect of every output phase of any bootstrapping process.

OK, so you decide to use Compcert C. You now have a proof that your object code is what your C code asked for. Do you have a formal proof of your C code? Have you proved that you have not allowed any surprises? If not, what is your Rust compiler? Junk piled on top of junk, from this standpoint.

On the other hand, you could have a verified WASM (or other VM) runner. That verified runner could run the output of a formally verified compiler (which Rustc is not). The trusted base is actually quite small if you had a fully specified language with a verified compiler. But you have to start with that trusted base, and something like a compiler written in C is not really enough to get you there.

Oh, and why do we trust QBE?


> Without essentially a formal proof that the output of the compiler is what you expect, you will have to manually inspect every aspect of every output phase of any bootstrapping process.

And why would it be easier to manually inspect (prove correct) the output of every phase than to manually inspect (prove correct) the source code? The compiled code will often lose important information about code structure, how abstractions are used, include optimisations, etc.

I usually trust my ability to understand source code better than my ability to understand the compiled code.


But you cannot trust the compiler, you said.


That's not what I said. I've implied that it's hard to trust the output of some unknown compiler (eg, the "zig1.wasm" blob) and that it's easier to trust source code.

The Dozer article explains, under "The Descent Principle", how rustc will eventually be buildable using only source code [0] (other than a "512-byte binary seed" which implements a trivial hex interpreter). You still need to trust a computer to run everything on, though in theory it should be possible to gain trust by running it on multiple computers and checking that the result is the same (this is why any useful system bootstrapping project should also be reproducible [1]).

[0] https://github.com/fosslinux/live-bootstrap

[1] https://bootstrappable.org/best-practices.html


The even more immediate objection is that a binary blob is the opposite of portable?!


In this case it is portable, because the Zig compiler source tree includes an interpreter for the blob (WASM) in portable C.

It's not objectionable to have non-portable source code anyway. I think it's fine having architecture-specific assembly code, just as long as it's hand-written.

The problems arise when you're storing generated content in the source repository, because it becomes unclear how you're meant to understand and fix the generated content. In this case it seems like the way to fix it is by rerunning the compiler, but if running the compiler involves running this incorrect blob, it's not clear that running the compiler again will produce a correct blob.

I wonder if anyone is monitoring these commits in Zig to ensure that the blobs are actually generated genuinely, since if not it seems like an easy way for someone to inject a KTH (Ken Thompson Hack): https://github.com/ziglang/zig/commits/master/stage1/zig1.wa...


Cross compilation.


Writing programs in Rust is not simpler then writing programs in C.


For compilers specifically, I think plenty of people would disagree.

It's not that it's exceedingly hard in C, but programming languages have evolved in the last millenium, and there are indeed language features that make writing compilers easier than it used to be

I have the most fun when I write x86 MASM assembly. It's a pretty simple language all in all, even with the macro system. Much simpler than C.

But a simple language doesn't always make it simple to write complex programs like compilers.


It is really remarkably sucky to process trees without algebraic datatypes and full pattern matching. Most of your options for that are ML progeny, and the rest are mostly Lisps with a pattern-matching macro. While it’s definitely possible to implement, say, unification in C, I wouldn’t want to—and I happen to actually like C.

Given the task is to bootstrap Rust, a Rust subset is a reasonable and pragmatic choice if not literally the only one (Mes, a Lisp, could also work and is already part of the bootstrappable ecosystem).


Sure, for you it isn't. It is for me. Especially if we're talking "working roughly as intended" programs.


Rust feels impossible to use until you "get" it. It eventually changes from fighting the borrow checker to a disbelief how you used to write programs without the assurances it gives.

And once you get past fighting the borrow checker it's a very productive language, with the standard containers and iterators you can get a lot done with high level code that looks more like Python than C.


I agree but it's not different than C with a decent library of data structures. And even when you become more borrow checker aware and able to anticipate most of the issues, still there are cases where the solution is either non obvious or requires doing things in indirect ways compared to C or C++.


The quality difference between generics and proc macros vs the hoops C jumps through instead is pretty significant. The way you solve this in C is also unobvious, but doesn't seem like it when you have a lot of C experience.

I've been programming in C for 20 years, and didn't realize how much of using it productively wasn't a skilful craft, but busywork that doesn't need to exist.

This may sound harsh, but sensitivity to order definition, and the fragility of headers combined with a global namespace is just a waste of time. These aren't problems worth caring about.

Every function having its own idea of error handling is also nuts. Having to be diligent about error checking and cleanup is not a point of pride, but a compiler deficiency.

Maintenance of build scripts is not only an unnecessary effort, but it makes everything downstream of them worse. I can literally not have build scripts at all, and be able to work on projects bigger than ever. I can open a large project, with an outrageous number of dependencies, and have it build on the first try, integrate with IDEs, generate API docs, run unit tests out of the box. Usually works on Windows too, because the POSIX vs Windows schism can be fixed with a good standard library and cross-platform dependency management.

Multi-threading can be the default standard for every function (automatically verified through the entire call graph including 3rd party code), and not an adventurous novelty.


Writing non-trivial programs is easier in Rust than in C, for people that are equally proficient in C as in Rust. Especially if you're allowed to use Cargo and the Rust crates ecosystem.

C isn't even in the same league as Rust when it comes to productivity – again, if you're equally proficient in Rust as in C.


I have 40 years of C muscle memory and it took me many tries and a real investment to get into Rust, but I don’t do any C anymore (even for maintenance- I’d rather rewrite it in Rust first).

Rust isn’t in a difference class from C, it’s a different universe!


This does not match my experience.


Try putting everything in Arc<Mutex<>> or allow mutable_transmutes and things get rather comfy.


Doesn't this defeat the point of using Rust a bit?


You have to consider that those who write the Rust compiler are experts in Rust, but not necessarily experts in C. So even if writing programs in C may be simpler than in writing programs in Rust for some developers, the opposite is more likely in this case, even before we compare the merits of the respective languages.


This is 100% the case. All of the honest-to-god Rust experts I know work on the compiler in some way. Same goes for Lean, which bootstraps from C as well.


Writing programs that compile is much easier in C. It lets me accidentally do all sorts of ill-advised things that the Rust compiler will correctly yell at me about.

I don't remember it being any easier to write C that passes through a static analyzer like Coverity etc. than it is to write Rust. Think of rustc like a built-in static analyzer that won't let you ignore it. Sometimes that means it's harder to sneak bad ideas past the compiler.


This is probably true if you assume it doesn't matter whether the program is correct.


Yes it is, why would anyone use it otherwise?


You can now have trustworthy Rust compiler binaries, through the work of the Bootstrappable Builds community, which found a way to build a C compiler without having C compiler binaries yet.

https://bootstrappable.org/ https://github.com/fosslinux/live-bootstrap/


Two simpler pieces of work as opposed to one complex one. Even if the two parts might be more volume, they're both easier to write and debug.


You often write two compilers when trying to bootstrap a C compiler, as GCC used to do. Often, it's a very simple version of the language implemented in the architecture's assembly.


Even if it is a bit more work:

- you can write the bulk of your code in a language you prefer over C

- you end up with a self-hosting rust compiler


Have you read the article?

> As async is already used as an identifier in C#, the team decided to use async2 as a codename for the experiment. If that thing ever makes it into the runtime, it will be called async - so it will be a replacement for the current async implementation.


How much of a background do your have in abstract algebra? I don't think category theory makes much sense or is very satisfying unless you can already list a bunch of categories you interact with regularly, and have results which can be expressed in terms of categories.


I'm fairly well-versed in AA, linear alg, topology, a few others. I got zero satisfaction from CT.

What would be the first interesting (if even mildly insightful) result in CT? I'll pull out my books and take a look...


If you’re looking for ‘something you can only prove using category theory’, you’ll probably not be able to find much. If you’re looking for ‘something commonly proven using category theory, whose proof without invoking such theory is much less elegant and general’, you’ll find plenty in any area of mathematics that uses category theory.

There’s a whole section of Emily Riehl’s book Category Theory In Context on ‘theorems in category theory’ (since it’s famously said that there are none — you’re certainly not the first to level such an accusation!).


See my other reply. It makes some things way easier in real-world programs (and libraries).


The first time I looked at the syntax, it honestly looked like gibberish to me.

It's probably simple, but the control flow just felt convoluted.


Thank you


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: