[HN Gopher] Rust: A Unique Perspective (2019)
       ___________________________________________________________________
        
       Rust: A Unique Perspective (2019)
        
       Author : wilsonzlin
       Score  : 88 points
       Date   : 2023-02-10 06:48 UTC (16 hours ago)
        
 (HTM) web link (limpet.net)
 (TXT) w3m dump (limpet.net)
        
       | ynik wrote:
       | I think part of what makes programming languages hard to learn is
       | that two authors rarely can agree on the same terminology.
       | Reading a mixture of sources can lead to confusion about what's
       | going on.
       | 
       | This article explains the uniqueness/mutability relation well,
       | but it uses the terms "variable" and "value" with different
       | meanings than most programmers would use. What the article calls
       | "value" I would call "memory location" (maybe one could even call
       | it "variable"); and what it calls "variable" isn't 100% accurate
       | but I guess it works to keep the explanation simple.
        
         | kjaa wrote:
         | I agree! "Resource" instead of "value" and "reference" instead
         | of "variable" would bring this in line with the program logic
         | community, from which many of these ideas spring or draw
         | inspiration from.
        
           | kzrdude wrote:
           | Reference can't be used for this article since it has a
           | specific meaning in Rust, i.e the most basic safe pointers,
           | those with the & syntax, are references.
        
         | kzrdude wrote:
         | memory location is maybe not a great replacement for value in
         | this article. values are preserved when moving them, but the
         | memory location changes. The location doesn't matter for the
         | purpose discussed in the blog post.
         | 
         | Models where the value `1` in `let x = 1` gets a memory
         | location - they unnecessarily mix in details about where the
         | value is stored. In most cases, the value is not stored
         | anywhere, neither stack nor heap etc, that is just a value and
         | the compiler and compiler settings determine what happens next.
         | A common case is that it's constant folded into some operation,
         | so the `1` then doesn't have any relationship to memory at all.
         | 
         | I think the terms used are typical for Rust. Doesn't each
         | language have its own terms? The C standard's object is not the
         | same as Python's object and so on.
        
           | dureuill wrote:
           | "variable" seems untypical for rust. We have "bindings",
           | which are not 100% the same as "variables" (hence maybe GP's
           | feeling of something odd).
           | 
           | Value is OK.
        
             | kzrdude wrote:
             | Do you have a quick example for a situation where binding
             | is better than variable in Rust?
        
               | alpaca128 wrote:
               | The usage of the `@` operator is usually called a
               | binding:                   match value {             n @
               | 0..8 => println!("{n}"),             _ => {},         }
               | 
               | It lets you bind and use the specific value within a
               | matched range. I don't think I ever used it though, I
               | tend to write something like `n if n<8 => {...}` instead
        
               | kzrdude wrote:
               | I'm sure you have used it in things like `if let Some(x)
               | = foo` where x is the binding, then.
               | 
               | I recognize the name binding being used there all the
               | time, but maybe variable would work well in this
               | particular context too?
        
               | cormacrelf wrote:
               | The reason people say binding is because the words
               | "immutable variable" are an oxymoron. It never makes
               | sense to use variable for immutable bindings; they are
               | not able to be varied. Binding is just the meaning of the
               | word "variable" but without the implied mutability.
               | 
               | This aligns with the fact that the mutability is
               | (syntactically and conceptually) a property attached to
               | the binding, and hence there is a need to talk about
               | bindings generally without implying anything about the
               | mutability. Lots of languages don't have immutable
               | bindings, all bindings are mutable, so you may as well
               | call them variables in C, Go, etc.
        
               | orbital223 wrote:
               | > The reason people say binding is because the words
               | "immutable variable" are an oxymoron.
               | 
               | Mathematics has had immutable variables since long before
               | computers.
        
               | tuukkah wrote:
               | "Immutable variable" is not an oxymoron, because the
               | value of a variable can and typically will vary via other
               | means than mutation. The value of a variable is
               | potentially different every time it comes to scope, e.g.
               | whenever a function is called.
        
             | alpaca128 wrote:
             | The compiler calls it "variable" so I wouldn't say it's
             | untypical, "variable binding" seems to be synonymous. I
             | think I've seen "binding" used alone within
             | destructuring/matching patterns, but in the end that
             | fulfills the same purpose.
             | 
             | I don't see what's wrong with variable, it's not like Rust
             | does anything special that warrants a different term.
        
         | DougBTX wrote:
         | > it uses the terms "variable" and "value" with different
         | meanings than most programmers would use
         | 
         | Have to disagree on this, these are very common words with
         | normal meanings, from the Assignment page on Wikipedia:
         | 
         | > Assignments typically allow a *variable* to hold different
         | *values* at different times during its life-span and scope
         | 
         | https://en.wikipedia.org/wiki/Assignment_(computer_science)
         | 
         | Unless there's something I'm missing, this is exactly how Matt
         | is using those words.
        
         | the_gipsy wrote:
         | I have recently seen "exclusive" for &mut, instead of "unique"
         | here.
         | 
         | The "value" and "variable" naming is unambiguous though.
         | "Variable" might be problematic for someone that conflates the
         | concepts of reference and value - but that's an issue that
         | should be solved far earlier than ownership.
        
           | hgomersall wrote:
           | Exclusive is an interesting description in this context
           | because it describes the semantics of the mut as regards the
           | borrow checker. "mut" in Rust means much more than just
           | "mutable".
        
       | ki_ wrote:
       | as a language designer.. im still stuck wether ownership is a
       | good or bad idea. I like ownership because that's how we handle
       | things in the real world. Eg. 2 people grabbing potato chips out
       | of a bag at the same time is a bad idea. We pass the bag along.
       | wait turns. But for some reason, we dont do this with computer
       | programs. So.. should we do this with computers or not? Feel free
       | to reply.
       | 
       | My instinct says 'yes'. But i also have a feeling that im going
       | to run into problems that current languages dont have. Such as
       | being forced to copy data or have complex systems like in rust to
       | make the compiler happy.
        
         | duped wrote:
         | > But for some reason, we dont do this with computer programs
         | 
         | I'm unsure what you mean here. It's pretty foundational to the
         | structuring of programs hierarchically (eg, trees own their
         | children, functions own their variables, closures own their
         | environments, and so on).
         | 
         | The classic argument against ownership as a language semantic
         | is that it doesn't play well with graphs and circularly linked
         | lists, where there isn't a meaningful hierarchy and therefore
         | no one ancestor is the "owner" of any descendant. The
         | counterargument is that these datastructures are both rare and
         | better represented with a single owner of the data and the
         | relationships represented through indirection even if your
         | implementation language doesn't enforce ownership (for example,
         | adjacency lists/matrices for graphs, vectors for lists, etc).
        
           | ki_ wrote:
           | I just meant that 99% of software was written without the
           | idea of ownership. Sure, we had objects containing other
           | objects, but i dont see that as "ownership".
           | 
           | Interesting arguments. Thanks.
        
             | duped wrote:
             | The term might be a bit new now that we have some work that
             | seeks to establish a formalism for it, but the concepts are
             | very old.
             | 
             | A modern definition could be that ownership semantics
             | define how aliases to data are created and shared. This
             | includes things like variable binding and class members,
             | but also encapsulates pointers and references - which have
             | formal semantics in every language that uses them (and
             | therefore, bake in ownership, even if it is implicit).
             | 
             | In systems programming languages like C and C++ the word
             | "owner" and "ownership" are often used to describe which
             | data structures and calling contexts are responsible for
             | managing data lifetimes, since aliases to that data are
             | used to control memory allocation and deallocation. The
             | semantics are not baked into the language, but most
             | software in these ecosystems _has_ to be written with
             | ownership in mind to be sound - and indeed, has been for
             | many years, with that verbiage ( "lifetime", "owner", etc).
        
         | ihatepython wrote:
         | > I like ownership because that's how we handle things in the
         | real world.
         | 
         | Not if you live in a communist society.
         | 
         | I think it would be better if there was no ownership, because
         | everybody would be happy.
        
           | shakow wrote:
           | Communism does not mean "no ownership" - Marx never said he
           | was going for your toothbrush.
           | 
           | It means no private ownership of the means of production,
           | which another can of worms.
        
           | ki_ wrote:
           | That's distributed ownership. Basically you get ownership of
           | certain objects for no reason. And if you question the
           | Goverment Class about this behaviour, you get freed from
           | memory. Not a good strategy in my opinion.
        
         | mtlmtlmtlmtl wrote:
         | I think ownership is necessary to understand as a programmer
         | when designing systems, regardless of whether or not the
         | language has explicit enforcement of it. Having a clear idea of
         | ownership and accommodating it in your data structures is the
         | best way to know when to free an object in C.
         | 
         | Similarly, having a clear idea of ownership can help in writing
         | GC friendly code.
        
           | ki_ wrote:
           | True. But doing this yourself can result in bugs. It would be
           | nice if we didnt have to think about it.
        
         | kaba0 wrote:
         | I think some variant of it is a must in low-level languages
         | like Rust, even if as vague as "this given arena owns this and
         | will free these objects".
         | 
         | For a higher level hobby language I'm designing, I'm thinking
         | of doing a similar concept, but with runtime overhead -
         | basically every object would be "synchronized" in Java's
         | parlance, but to make it efficient most lockings would be
         | elided at compile time via move semantics. So data races
         | couldn't happen (also, could possibly do a better job at escape
         | analysis).
         | 
         | The primary reason I'm thinking about that is that we really
         | shouldn't be using non-thread safe primitives anymore --
         | Clojure did get this right. That should be left as a compiler
         | optimization if it can prove that that given code runs inside a
         | "alone".
        
       | [deleted]
        
       | sliken wrote:
       | Maybe add a (2019) to the title?
        
       | anonymousDan wrote:
       | Does Rust provide support for low level synchronisation related
       | operations such as memory fences? If so is there any way relying
       | on these can break data race freedom (which as I understand Rust
       | guarantees)?
        
         | masklinn wrote:
         | > If so is there any way relying on these can break data race
         | freedom (which as I understand Rust guarantees)?
         | 
         | It's not clear what your question is.
         | 
         | You can use unsafe to write unsound code which suffers from
         | data races.
         | 
         | If you use safe Rust, then you should not suffer from data
         | races (and fences only add constraints, so they can't add data
         | races, they're tools to avoid those), although bugs are always
         | possible and sometimes purportedly safe stdlib APIs are found
         | to be unsound (that's one of the few things for which the rust
         | project allows breaking backwards compatibility, though even
         | that depends on the blast radius e.g. std::mem::uninitialized
         | is still there, just deprecated, even though there's almost no
         | way to use it soundly).
        
         | kaba0 wrote:
         | Besides other's answers, while data races are not possible in
         | safe rust, other race conditions can happen (and not even the
         | actor model is immune to these).
        
         | shinazueli wrote:
         | It has Atomics that use the same memory constraint model
         | (Relaxed, SeqCst, etc), if that's what you meant.
         | 
         | You can indeed create data races with them, but only in
         | combination with unsafe code.
         | 
         | https://doc.rust-lang.org/nomicon/races.html
        
           | anonymousDan wrote:
           | I meant inserting barriers (read fence/write fence etc)
           | explicitly. Thanks for the link, very interesting.
        
             | jamesmunns wrote:
             | Yep, we have `fence` for runtime+compile time barriers, and
             | `compiler_fence` for compile time barriers. They take the
             | same Ordering enum as atomics.
        
       | pornel wrote:
       | UnsafeCell (a wrapper for all the hacky unsafe memory access) is
       | such a great idea. This allows rest of the program to be easier
       | to statically analyze. For everything _not_ in it, the compiler
       | can assume it respects strict aliasing and immutability without
       | any gotchas. If UnsafeCell didn 't exist it, it would be unclear
       | where the programmer really meant to allow data races or poke
       | holes in immutability, etc.
        
       ___________________________________________________________________
       (page generated 2023-02-10 23:02 UTC)