HackerTrans
TopNewTrendsCommentsPastAskShowJobs

dexterlemmer

no profile record

comments

dexterlemmer
·vor 4 Jahren·discuss
Type hints and static typing are completely orthogonal. It is merely more common for the designers of dynamically typed languages to make the mistake of not allowing type hints pretty much every where and requiring them in a library's API (or at least linting for them being missing in the API) than making the same mistake is for the designers of staically typed languages.
dexterlemmer
·vor 4 Jahren·discuss
> While typing is dynamic, I rarely see this being used, perhaps with the exception of identifying empty variables with None. Most identifiers are born and die the same type. It would be interesting to see how much effect dynamic typing has on the rate of programming errors.

Dynamic typing and changing the type of a variable are orthogonal.

You can change a type with casting, coercion, transmutation, dynamic dispatch, downcasting, reflection, monkeypatching (i.e. simultaneosly using dynamic dispatch and downcasting and reflection). All of these methods are available in Rust, which is a statically typed language.

Some things that some people think are changing the type of a variable in Python is not what it seems, for example:

    # Python
    a = 1
    a = ['h','i'] # `a: int` is unchanged but gets implicitly shadowed by `a: list[str]`
    a[1] = "a"    # We're combining shadowing with weird and inconsistent scoping
translates to the following in Rust:

    // Rust
    #[allow(unused_mut, unused_variables)]
    {
        let mut a = 1;
        let mut a = ["h", "i"]; // Explicit shadowing
        a[1] = "a"; // We're simply calling a mutating operator
    }
Furthermore:

    # Python
    lst: Array[Any] = [1, "2", 3.0] # A heterogeneous list
    for elem in lst:
        print(elem);
translates to the following in Rust:

    // Rust
    // Below `dyn` has nothing whatsoever to do with dynamic typing.
    // ... it is just fluff having to do with the requirements of systems programming.
    // ... (Technically it means we're using vtables to do dynamic dispatch.)
    // ... The `Box` nonsense is more systems dev fluff having to do with memory allocation.
    // ... Of course in Rust, App devs often don't need to worry about such fluff because
    // ... lib devs should provide ergonomic API's, but I'm doing as close as
    // ... possible to a direct translation of the Pyhon code.
    #[allow(unused_mut)]
    let mut lst: Vec<Box<dyn Display>> = vec![
        Box::new(1),
        Box::new("1"),
        Box::new(1.0),
    ];
    for elem in lst {
        println!("{elem}");
    }
The one major difference between the Python code and Rust code above is that `Display` in Rust is a Rust trait (i.e. a typeclass) and typeclasses don't exist in Python.
dexterlemmer
·vor 4 Jahren·discuss
I don't see the connection between white space in PLs and parenthesis in math.

On the other hand: Let's consider what the Python-like version of math actually look like:

    f(x) = :
        x, if x > 0
        -x/2, if x < 0 and x is even
        0, otherwise
In stead of:

              __
             /
             | x,  if x > 0
    f(x) =  <  -x/2, if x < 0 and x is even
             | 0, otherwise
             \__
The latter is, of course how math actually looks.
dexterlemmer
·vor 4 Jahren·discuss
> A couple of newlines to create a new paragraph is semantic whitespace, as one newline or a space would not do so. Markdown (although not HN's Markdownesque syntax) even has significant trailing whitespace, which I would object to in a programming language.

A code block is *not* the same as a paragraph. It is the same as a part/chapter/section/subsection/subsubsection. (Think about it.) In formal writing, these are practically always clearly indicated by not just semantic whitespace but also by semantic headers with particular semantic styling as well as semantic numbering. In addition, if you you write these programatically in for example Markdown or LaTeX, you might have semantic whitespace in the markup language but you definitely will have semantic non-whitespace symbols in the markup language.

Next Quote:

    for (i = 1; i < 11; ++i)
        printf("%d ", i);
        printf("%d ", i);
This has nothing to do with the lack of significant white space and everything to do with terrible language design. Here is the *only* valid way to write the above in Rust:

    for i in 1..11 {
        println!("{}", i);
    }
    println!("{}", i);
If you tried:

    for in in 1..11
        println!("{}", i);
        println!("{}", i);
you would get a compiler error because the braces are required around the bodies of all control- and loop structures. Also note that a common class of bugs is avoided in Rust because in Rust the loop condition is not in parenthesis. (Nor are the conditions in `if`s, etc.)

> Also, with Python appealing to new programmers, there'd probably otherwise be plenty of beginner code with no indentation at all.

Which is to say teaching methodology for coding sucks. While you shouldn't overwhelm a beginner with linting errors from a very pedantic linter (to put it mildly), not automatically linting all beginner code for some basic issues like incorrect white space and wEirD_caPS_in_OVERLY_LOOOOOOOONG_idENTIFIERS or `l` `o` `t` `s` `o2` `f` `s2` `h` `o3` `r` `t` `i` `d` `s3` (lots of short identifiers) is, IMHO, a really bad idea.

Furthermore, actually (at least in my experience tutoring C++/Java/C#), bad white space is actually not that common for beginners after the first few lessons. I guess that most humans are used to just automatically write and type semantic white space. Therefore if they see their teacher writing code with white space they'll not only use white space themselves but use it similarly.

On the other hand the identifier issues I've mentioned above are all more common, especially too short and obscure identifiers.
dexterlemmer
·vor 5 Jahren·discuss
Looking at the examples you've provided, I'm pretty sure the Linux kernel's codebase dwarfs their combined codebases into insignificance. Since it is very hard to not have NP-hard asymptotic complexity when formally verifying a codebase as large and as demanding (in terms of performance, etc) as the Linux kernel, I would expect that if you tried to rewrite Linux in the languages you've mentioned and formally verify the rewrite, you will be able to keep the entire AWS cloud (globally) very busy for a very, very long time. On the other hand, if you were to do the rewrite in Rust and use some hypothetical formally verified Rust compiler to type check it (which is mathematically equivalent to such a formal verification in, say, F* limited to only verifying certain properties), it'll probably type check in minutes or even seconds on the laptop I'm currently writing this reply on.

For a less hypothetical example. RedoxOS has a codebase that dwarfs Sel4 (but it is still much smaller than Linux in turn), yet it type checks with much less compute cost than it takes to formally verify Sel4. Or heck, Redleaf actually formally verifies in a tiny fraction of the time it takes to formally verify Sel4, because the Rust type checker not only significantly reduces the amount of requirements that still needs to be formally verified but also reduces the complexity to verify those requirements to linear to the codebase size due to the restrictions that the Rust type system and module system puts on valid Rust programs (with a little bit of care when writing the code). Of course, until you have a certified Rust compiler there might still be miscompiles of Redleaf and until all the features of Rust used in the Linux kernel is formally specified, we cannot do the same with the Linux kernel as for Redleaf even if somehow all of Linux got rewritten in Rust. But in Rust at least it is conceivably possible given sufficient resources and sufficient time. I very much doubt it will ever be possible without help from a sufficiently expressive and practical type system.

Oh yea. Then there's another problem. Most (all?) of the examples you've mentioned have requirements that are well specified and pretty much set in stone. The requirements fro the Linux kernel... aren't quite as obliging.
dexterlemmer
·vor 5 Jahren·discuss
Rust was considered for Zircon. The only reason it wasn't chosen was that at the time Rust wasn't yet sufficiently mature for embedded. And it really wasn't.

In the meantime, Google makes extensive use of Rust in new components of both Fuchsia and Android and even rewrites some legacy components where it makes sense.
dexterlemmer
·vor 5 Jahren·discuss
> Regarding Linus ...

I wouldn't trust Big tech as far as I can throw one of their server farms. That said, I doubt that Linus's spirit is broken and he's simply surrendering to them. Assuming you aren't just ~~trolling~~ tin foil hat farming, I'll answer what I think:

I remember Linus said some years ago (probably ~2019 or 2018) that Rust or something like it in the Linux kernel is inevitable. His reasoning was that the Linux kernel is unlikely to remain maintainable in the long run. Due to the C code in the kernel being very non-standard and due to there being a lot of code in the kernel that got written the way it was for a specific reason and most of it being just unwritten implicit knowledge of the old hands. This makes it very hard to onboard new maintainers and PR's often require significant fixes and significant internal expertise to recognize the need for those fixes and be able to make them. As the old hands grow older, they may not be replaceable.

Furthermore, new bugs are now being discovered in the kernel faster than they can be fixed [1].

If I were to guess, Linus is just hoping that Rust or some other modern safe systems language suitable for kernel development (of which Rust is by far the most mature) could help sustain the kernel's maintainability.

As for why Big tech wants Rust in the kernel. I guess that's because they want total world domination. Which will probably be hard to achieve if any idiot can easily zero-day the kernel their infra all depends on and steal all their secret big data which is "the oil of the age of AI" or rootkit a phone making it harder to surveil it's ~~owner~~ addict. ;-)

> Regarding technical merit ...

Rust is very fundamentally different from "C++ with switches toggled in different ways and a borrow checker on top". I could call Java "Cobol with switches toggled in different ways and inheritance on top" but that wouldn't make them quite that similar as I've made them sound. If you think that Rust isn't fundamentally something drastically different from C++, you either don't have a clue about C++ or don't have a clue about Rust. Rust is holistically designed to be safe, which is the only possible way to actually make a safe language. C++, however modern and with whatever programming best practices and tools, is still fundamentally completely unsafe. It helps reduce security vulnerabilities from very very very unacceptably high to merely very very unacceptably high but in this case better is nowhere near good enough. Rust actually eliminates entire classes of security vulnerabilities (with some manageable caveats).

Another difference is that by the time you've addressed all the reasons typical C++ code is unacceptable in a kernel, you are back at simply C. But you can have high level abstractions and safety and, etc. in Rust inside the Linux kernel. For just one difference, Rust's zero-cost abstractions are actually, you know, zero cost. Unlike C++'s supposedly zero-cost abstractions which have unacceptable (in the Linux kernel) overhead. (For example a move in C++ is potentially very expensive, but at worst it is a memcpy in Rust.) But there are plenty of other reasons mentioned in this thread.

[1]https://lore.kernel.org/dri-devel/20200710103910.GD1203263@k...
dexterlemmer
·vor 5 Jahren·discuss
1. Yea, a road that was used for target practice during a large-scale NATO training exercise is the same as a road that could do with a bit of maintenance with painted potholes to warn people. After all, they both have potholes.

2. You are cherry picking. He also said "These are hard to locate for most languages; I wouldn't know where to look in case of C." Rust has some advantages from for example Clippy and from a very newcomer-welcoming and helpful community.

3. Rust in kernel would indeed have kernel-specific idioms. But it'll probably be very similar to other embedded Rust and relatively easy for a newcomer to pick up. (Ee'll have to wait and see, but there is good reason to expect this.) C in kernel is known to be very hard for other C developers to pick up.

4. Thanks for the info.

5. But some things are special about Rust that makes testing easy.

6. The kernel doesn't deal much with text and even when it does, it generally doesn't need to deal with encodings (let alone modern encodings). That said, text is really a nightmare in C. Even just ASCII is needlessly complex due to null-terination, badly designed functions and the regular C UB pitfalls. At least you did acknowledge it may indeed be a problem for C compared to Rust.
dexterlemmer
·vor 5 Jahren·discuss
I could never figure out Githut2.0. Githut1.0 had a much nicer interface and although Rust looked bad on first impression, just moving it left a set period of time (or vice versa moving Go right a set period) showed that Rust actually grew at a very similar rate as Go... until Rust started accelerating by around 2018. I suspect something similar may be the case on Githut2.0 but just too hard to tell. Linear graphs comparing exponential growths can be very deceiving.

In my experience TIOBE is very noisy and bad at predicting long-term trends for languages outside the top-ten or so. And it seems even worse recently due to Covid. Heck Julia recently jumped into the top-20 for a single motnh earlier this year before falling back to the mid 30's. And that isn't even all that uncommon for TIOBE. I think I see a trend of Rust slowly climbing, but it is hard to tell through the noise.

PYPL says Rust has respectable growth and that its growth is remarkably consistent (i.e. it is growing at a near constant expeonential rate until 2018, then slowing down a bit in 2018 and then continuing at a very constant and this time faster exponential growth rate.

Redmonk calls Rust the tortoise language (from the hare and the tortoise story). It's growth is never impressive, but its steadiness in growing is very impressive.

You actually do mention some success stories. Also, Amazon is using Rust for a lot more than Firecracker. A lot of their critical infra is in Rust. Also, rustls is pretty big, IMO. Finally an actually secure implementation of SSH. ;-) (And fast to boot.) The Ferrocene project project is fully open source, paid for in full by donations despite the considerable expense because some of the (very big) high integrity industry really want to use Rust The Linux kernel is seriously considering including Rust and Linus said something like Rust in the kernel is inevitable. The Linux kernel team (and Linus specifically) are notorious for their previously adamant hostility towards any language other than C in the kernel. They are starting carefully with just drivers but that's already way more than for example C++ ever managed. On the CNCF, we have TiKV and Linkerd2 in Rust. These aren't small or unimportant projects although, no, they don't quite match k8s.

Over all. Rust is trying to replace C/C++. That is a very tall order. No previous language have ever come close to where Rust currently is already in that task. But it is not going to happen over night. It is a huuuuuuge task that will take a lot of time and a lot of resources and a lot of mindshifts.

Regarding improvements in the other languages. Sure, but C++20_0000_000 will not come close to some of the advantages Rust already had by 1.0 unless they are willing to break backward compatibility to the point where you can just as well rewrite in Rust. All those languages are fundamentally broken or limited in ways that cannot be fixed or worked around. Rust also have historical baggage already. But it starts from a much better starting point with a lot of lessons learned.

How have unsafety been addressed in C/C++? C++20 is exactly as unsafe as C. It has much better what I call "safeness", but that's like saying by going from 1 to 10 I made progress towards infinity. It reduces some classes of errors, if you know what you are doing and apply considerable discipline. It doesn't eliminate any errors. C++20 is sill based on the C abstract machine, which is to say a DEC11. It is still very hard to do some optimizations that are easy or even trivial in Rust and some that would've been trivial if LLVM didn't miscompile perfectly correct code. C++20 still doesn't have a borrow checker and will never have one remotely as capable as Rust's. C++/Java/C#/Python/... are still OOP with inheritance which is fundamentally at odds with really capable composition which is fundamentally superior in expressive power and fits a lot of domains a lot better. Yes. Those languages can close the gap. They can never catch up. Can they get close enough to reduce the value proposition of the newer languages to the point where the newer languages (or some others even newer than these) won't take and hold a considerable fraction of their market share? I doubt that. But taking the market share of the incumbents will take very long. The network effect is brutal. But sometimes a disruptive technology is too good to stop it from -- eventually -- overcoming that effect. Of course, again exponential growth means what starts slow can quite suddenly explode. Also, when sufficient barriers are overcome or a language gets the rigth killer app it can again explode. May be for Rust that'll be high integrity or the Linux kernel. Consider that Redleaf is already vastly superior (better security, better performance, more features, more portable) and vastly cheaper to develop and verify than sel4 for one impressive achievement. Of course, until we can actually compile Redleaf on a certified rust compiler (probably by next year), Redleaf will remain an academic curiosity. But once we can? I'm no high integrity developer, but it seems the sky's the limit.

Yikes! That was a lot of words! Sorry, but I'm too tired to edit.
dexterlemmer
·vor 5 Jahren·discuss
Agreed. But it can also mean not actually achieving at all what you set out to do. I don't know if that is the case for Loom specifically, but that seems to be what was implied by the parent comment.
dexterlemmer
·vor 5 Jahren·discuss
I don't see any such note and it's 8 days later. May be you should check your comment again? Also, while games aren't exactly regular applications performance-wise, I think they fall more under that than embedded or utmost control and while a 1ms delay won't be the end of the world, it'll likely hurt.
dexterlemmer
·vor 5 Jahren·discuss
I'm getting a bit off topic here, but if you haven't heard about it yet, you might be interested in https://ferrous-systems.com/ferrocene/.

Some quotes from the linked page:

> Ferrocene is a sustainable effort led by Critical Section GmbH, a newly formed Ferrous Systems subsidiary, tasked with making Rust a first-class language for mission and safety-critical systems. Ferrocene produces a qualified Rust compiler toolchain. General availability is expected by the end of 2022.

And also:

> Ferrocene is a vehicle for a versioned Rust and MIR specification, paired with automated verification of Rust semantics. These "runnable specs" give developers in mission-critical and high-security environments a sound, proven, and addressable foundation for building critical libraries, analysis tools, and further system assurances.

And also:

> Critical Section will maintain designated legacy versions of the Rust toolchain and supporting utilities. This support includes backporting fixes of critical language and standard library issues (performance bugs, unsoundness, security) and maintaining key rustc targets, including test cases and platform-specific testing.

And finally:

> Ferrocene is a principled project with much work ahead, requiring cross-industry collaboration and continuous feedback. It has support from crucial industry partners and subject experts, and we're building a thoughtful community.

> Right now, Ferrous Systems and Critical Section are calling for additional partners to join this effort. We're currently looking for partners from diverse industries
dexterlemmer
·vor 5 Jahren·discuss
If the borrow checker of 1.52.1 "screeches" on every LOC but it compiles on 1.0 then very likely either there's some bug in 1.52.1 that you should report or you code was never correct and should never have compiled in 1.0 in the first place but did due to a compiler bug that since got fixed.

Of course, without more info nobody can tell which of these or even whether it is one of these two or something else.
dexterlemmer
·vor 5 Jahren·discuss
It's not just the GC, Go's Interfaces are very heavy weight (including in TinyGo). Its green threads are very heavy weight (including in TinyGo)... Oh. And a GC is really unacceptable in a kernel (though not necessarily in the rest of an OS) for all sorts of reasons, not just throughput but also latency and severe issues with FFI and concurrency and frankly how the heck are you even supposed to run a GC without a runtime in the first place? And speaking of which: TinyGo has a massive runtime that requires a sophisticated OS like FreeRTOS already installed on the system, not just for GC but for greenthreads, and, well, everything.

Just because nowadays even MCU's are so powerful that you can just waste an insane amount of resources on TamaGo and just because TamaGo seems to run on custom hardware/firmware that specifically provides it what it needs to directly run on the hardware without help from C/C++/Rust, doesn't mean Go is particularly viable for Android today.

Even more importantly. Google actually wants to use a safe language for Android. Go isn't safe the moment you go parallel/concurrent/async. Go also isn't memory safe for important OS tasks like direct memory access. Go also isn't null safe. Go also isn't typestate safe... Rust have all of the above mentioned safety in all of the above mentioned situations.
dexterlemmer
·vor 5 Jahren·discuss
I'm no expert in this domain but it seems to me that RedLeaf (implemented in Rust and formally verified) is vastly superior to seL4. AFAIU RedLeaf is orders of magnitude cheaper to formally verify to a much higher standard[1] while also being significantly more performant[2] and that Rust's properties are key to both of those advantages[1,2]. (Note: I only skimmed [2].)

Edit: It seems RedLeaf is immune to meltdown due to its design while seL4 has meltdown mitigations[2]. I would assume the same goes for spectre, but that would be an assumption on my part. (Note again, I've only skimmed [2] so I can easily be wrong here.)

[1]: https://www.ics.uci.edu/~aburtsev/doc/redleaf-hotos19.pdf

[2]: https://www.usenix.org/system/files/osdi20-narayanan_vikram....
dexterlemmer
·vor 5 Jahren·discuss
It seems like he did. (Or may be someone else's. I didn't check the repo.) Common Lisp is the second slowest on his results table.
dexterlemmer
·vor 5 Jahren·discuss
Huh? Plenty of CVEs found in C/C++ codebases were introduced decades before they were discovered. In fact, it seems to me that the older a C/C++ codebase is (especially C++), the more bugs is has, simply because improved coding practices and "modern C++" features have a far greater impact than amount of user feedback and experience. But best practices and modern C++ features are just a poor man's (semi-effective) borrow checker. ;-)

More seriously. I agree that you can't call rust-coreutils mature yet. But over time maintenance on it will probably be considerably easier and if it ever gets popular enough to be thoroughly battle-tested, it almost certainly will be more reliable and secure. In addition, odds are that even if still immature, it already has fewer serious bugs. Especially memory safety, but also in things like string-handling since C++ -- and especially C -- string handling is notoriously difficult to get right. Then again, maybe not, since coreutils and presumably also rust-coreutils take the stupid approach that strings are just streams of bytes and there's relatively little the Rust std and compiler can do to fix that mess. Oh, wait! Actually it can help a bit by allowing you to be "flexible" in your interface but also parse and validate at the interface, then use better abstractions internally.

Case in point: OpenSSH vs rustls: OpenSSH is a lot older than rustls, has been extensively battle-tested by a very expert community, has been audited, fuzzed, etc to a significant degree, and we're still now starting to see security experts advising using rustls in stead of openssh, or projects deciding to switch to rustls because rustls is likely (and according to a growing body of real-world experience and evidence) less buggy and more secure than openssh. (And as a bonus it's also faster.) Not all of openssh's issues are due to the language, and neither is rustls's choice of language the only reason for its reliability. But in both cases the implementation language does play a crucial role in their security and reliability.
dexterlemmer
·vor 5 Jahren·discuss
> Having standard serialization is just gonna be boilerplate and unneccessary for many programs.

And for a lot of programs having to keep generating and parsing strings is just a bunch of unnecessary boilerplate.

> Stream of bytes is the only sane thing to do. Nothing keeps you from not having a flag in your cli programs to choose the input/output format. In fact many programs already has this and json seems pretty popular.

Having an API like this is a great idea... as a thin wrapper on top of a tool with a standardized serde protocol or binary file format. The different API's can be exposed as separate tools or as separate parts of the API of a single tool from a user's POV.

Furthermore: JSON is not just a stream of bytes nor text, neither is CSV, nor any other text format. Handling text as properly typed objects makes a lot of sense.

I have little experience with shells that can work with objects like Powershell. But I'e seen screenshots of new objects-based shell developed in Rust some time ago and it was early days still so I didn't actually even try it out, but looked downright great compared to the current stream of text-based shells of today in terms of ergonomics and capabilities.
dexterlemmer
·vor 5 Jahren·discuss
Yes and more:

1. Lack of "manual memory management" can be taken as GC (though Rust is neither GC'd nor manual memory managed, it's declaratively memory managed) and a GC is unacceptably expensive for systems programming. Furthermore, until recently GC was also unacceptably bad for FFI. However stable Rust and Haskell with experimental features can nowadays GC across FFI without issue, but I'm still unaware of any other language that can.

2. Lack of "manual memory management" also means lacking direct memory access, etc. This is a problem in systems programming, though you do not need it for all systems programming.

3. Then there's green threads. Early on Rust had them, but they were removed when it was discovered it's theoretically impossible to implement them with acceptably low overhead for a C or even a serious C++ competitor. What's worse, you have to pay the overhead even if you don't use the feature. Nowadays, you can opt in by importing an ecosystem library that provides green threads but mostly people just use futures rather than green threads.

4. Interfaces: Even tinygo's documentation advises avoiding interfaces and tinygo isn't even a C/C++/Rust competitor, it's a micropython competitor.

5. ...
dexterlemmer
·vor 5 Jahren·discuss
I agree. But this particular example ironically has nothing to do with dynamic typing.