[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)