Live data from Hacker News

Rust--: Rust without the borrow checker

github.com

221–230 of 269 posts

Re: Rust--: Rust without the borrow checker

#221
post #215

Earlier quoted context omitted.

Except, as you say, all those factors always exist, so we can compare things against each other. No language to date has grown its market share by a factor of ten at such an advanced age [1]. Despite all the hurdles, successful languages have succeeded faster. Of course, it's possible that Rust will somehow manage to grow a lot, yet significantly slower than all other languages, but there's no reason to expect that a…

This sounds like you're just repeating the same claim again. It reminds me a little bit of https://xkcd.com/1122/ We get it, if you squint hard at the numbers you can imagine you're seeing a pattern, and if you're wrong well, just squint harder and a new pattern emerges, it's fool proof.

Observing a pattern with a causal explanation - in an environment with selective pressure things spread at a rate proportional to their relative competitive advantage (or relative "fitness") - is nothing at all like retroactively finding arbitrary and unexplained correlations. It's more along the lines of "no candidate has won the US presidential election with an approval of under 30% a month before the election". Of course, even that could still happen, but the causal relationship is clear enough so even though a candidate with 30% in the polls a month before the election could win, you'd hardly say that's the safer bet.

Re: Rust--: Rust without the borrow checker

#222

This can't possibly be guaranteed to work just by disabling the checker, can it? If Rust optimizes based on borrow-checker assumptions (which I understand it can and does) then wouldn't violating them be UB, unless you also mess with the compiler to disable those optimizations?

I guess this is like putting an unsafe { } around all your code...

Not really. Unsafe blocks don't change the semantics of Rust code or disable Rust's normal checks, so if you have something that doesn't compile due to a borrow checker error adding an unsafe block around that code will do precisely nothing to get around that error.

Re: Rust--: Rust without the borrow checker

#223

I'm the author of this repo. I see some really angry comments, some of them even personal. Obviously I didn't think that just by tinkering with a compiler, I'd get personally attacked, but anyway, fair enough. For those of you confused: yes, this started as a satirical project with the corroded lib. Then I thought "why not just remove the borrow checker?" without any real motivation. Then I just went ahead and did it…

This is incredible! I honestly think Rust is an awesome language because it has a lot of high-level niceties like HOF, powerful libraries but can simultaneously let you manage memory manually or put assembly next to your regular code - the borrow checker is an annoyance in a lot of cases like prototyping as you said. I would loove if this was an official mode that Rust supported, Rust could really work in any niche with that capability.

Re: Rust--: Rust without the borrow checker

#224
post #60

Earlier quoted context omitted.

What if you don't know ahead of time how big that monitor is that you are displaying stuff on? In any case, what you are describing sounds like an ad-hoc re-implementation of virtual memory?

> What if you don't know ahead of time how big that monitor is that you are displaying stuff on? Use a reasonable upper estimate? > ad-hoc re-implementation of virtual memory? If you rely on actual virtual memory instead of specially designed file format, saving large files will become prohibitively slow. On each save you have to stream the entire document from page file to actual memory, serialize the document, prod…

> If you rely on actual virtual memory instead of specially designed file format, saving large files will become prohibitively slow. On each save you have to stream the entire document from page file to actual memory, serialize the document, produce the entire file, then replace. And then when resuming editing after the save, you probably have to load the visible portion back from disk.

How large is large? Loading and saving a few GiB from my SSD is pretty fast, and few files ever get so large.

In any case, you are mixing things up here.

You can have a special file format and use virtual memory. You could mmap your specially formatted file and rely on the operating system to keep what you do in memory in sync with what's happening on disk. That's a prime use of virtual memory.

> Use a reasonable upper estimate?

Saddling some guy on an underpowered Chromebook with a crazy large static allocation, just because you want your programme to also support some crazy large screen that might come out in 2035, seems a bit silly?

Re: Rust--: Rust without the borrow checker

#225
post #60

Earlier quoted context omitted.

What if you don't know ahead of time how big that monitor is that you are displaying stuff on? In any case, what you are describing sounds like an ad-hoc re-implementation of virtual memory?

Either take the biggest one or render in chunks.

Saddling some guy on an underpowered Chromebook with a crazy large static allocation, just because you want your programme to also support some crazy large screen that might come out in 2035, seems a bit silly?

Re: Rust--: Rust without the borrow checker

#226
post #102
post #54

Earlier quoted context omitted.

Straightjackets can be very useful. Haskell (and OCaml etc) give you both straightjackets and a garbage collector. Straightjackets and GC are very compatible. Compared to C, which has neither straightjackets nor a GC (at least not by default).

>Haskell (and OCaml etc) give you both straightjackets.. Haskell's thing with purity and IO does not feel like that. In fact Haskell does it right (IO type is reflected in type). And rust messed it up ("safety" does not show up in types). You want a global mutable thing in Haskell? just use something like an `IORef` and that is it. It does not involve any complicated type magic. But mutations to it will only happen i…

> You want a global mutable thing in Haskell? just use something like an `IORef` and that is it. It does not involve any complicated type magic. But mutations to it will only happen in IO, and thus will be reflected in types. That is how you do it. That is how it does not feel like a straight jacket.

Haskell supports linear types now. They are pretty close in spirit to Rust's borrowing rules.

> Haskell as a language is tiny.

Not at all. Though much of what Haskell does can be hand-waved as sugar on top of a smaller core.

Re: Rust--: Rust without the borrow checker

#227

Earlier quoted context omitted.

In Rust, it's a lot easier to refactor half the codebase than it would be in another language. Once you're done fighting the compiler, you're usually done! instead of NEVER being sure if you did enough testing.

I can’t tell if you missed the whole point of “exploratory”…

I don't know either. Personally I can spend days or more on exploratory efforts that end up scrapped. My source code is usually version controlled, so I never have to worry about messing things up. But I suppose not everyone has this kind of time for stuff that isn't guaranteed to pan out.

Sometimes I will prototype an exploration in another crate or module so I can see if there are performance gains in a more limited application. Sometimes these explorations will grow into a full rewrite that ends up better than if I had refactored.

Re: Rust--: Rust without the borrow checker

#228
I don't want a Rust language without a borrow checker. I want a C language with a Borrow Checker. Rust's complexity is already approaching C++, and removing the Borrow Checker would turn it into a similar disaster. Austral looks like a good option to me, but it's not mature enough yet, and the Pascal-like syntax is also difficult to get used to.

Re: Rust--: Rust without the borrow checker

#229

Earlier quoted context omitted.

> It will even work fine as long as you don't write code which invokes UB (which does include code which would not pass the borrow checker, as the borrow checker necessarily rejects valid programs in order to forbid all invalid programs). To be clear, by "this" I meant "[allowing] code that would normally violate Rust's borrowing rules to compile and run successfully," which both of us seem to believe to be UB.

Not quite, there is code which fails borrow checking but is safe and sound. That is part of why a number of people have been waiting for Polonius and / or the tree borrows model, most classic are relatively trivial cases of "check then update" which fail to borrow check but are obviously non-problematic e.g. pub fn get_or_insert ( map: &'_ mut HashMap , ) -> &'_ String { if let Some(v) = map.get(&22) { return v; } ma…

Imo if you run into the halting problem it's because you are trying to do too much. In particular I think what you actually want is to check soundness based on the "shape" of the code rather than the reason about which variables can have which values and what that means for soundness.

  flag=false;
  if flag {
    use_after_free();
  }
can be rejected with a clear conscience.

Re: Rust--: Rust without the borrow checker

#230

This can't possibly be guaranteed to work just by disabling the checker, can it? If Rust optimizes based on borrow-checker assumptions (which I understand it can and does) then wouldn't violating them be UB, unless you also mess with the compiler to disable those optimizations?

Yes. An analog would be uninitialized memory. The compiler is free to make optimizations that assume that uninitialized memory holds every value and no value simultaneously (because it is undefined behavior to ever read it). In the following example, z is dereferenced one time and assigned to both x and y, but if z and x are aliased, then this is an invalid optimization. fn increment_by(x: &mut i32, y: &mut i32, z: &…

> Yes. An analog would be uninitialized memory. The compiler is free to make optimizations that assume that uninitialized memory holds every value and no value simultaneously (because it is undefined behavior to ever read it).

Even casting a MaybeUninit::uninit() to i32 is UB, even though every bit pattern in that memory space is a valid i32.

What's interesting is your code example is solved in Rust. By preventing a reference and a mutable reference all of the sudden the code becomes easier to reason about. No need for special attributes: https://www.lysator.liu.se/c/restrict.html#comparison-with-n...

Post reply on HN