[HN Gopher] Dave Herman's contributions to Rust
___________________________________________________________________
Dave Herman's contributions to Rust
Author : signa11
Score : 601 points
Date : 2021-05-03 06:10 UTC (16 hours ago)
(HTM) web link (brson.github.io)
(TXT) w3m dump (brson.github.io)
| nindalf wrote:
| I've heard a lot of engineers complain about engineering managers
| over the years. I've also heard great managers self-deprecatingly
| say they "don't do any work". I've seen managers feeling bad they
| weren't productive so they resorted to writing code to feel that
| they were having impact.
|
| This post is an example of the incredible impact an engineering
| manager can have without writing a line of code.
| worik wrote:
| Very nice story
|
| I love the designed by committee aspect of Rust. I have great
| respect for good committees. I have served on a few (and some bad
| ones, shiver). One of the things that makes a committee work is a
| good facilitator
|
| As the saying goes: A camel is a horse designed by a committee:
| Goes twice as far on half as much carrying twice the load....
| ndesaulniers wrote:
| I swear I recall being a fly on the wall and just being in awe;
| early on in my career just listening to Dave Herman, Luke Wagner,
| and Alon Zakai discussing asm.js which would one day lead to
| webassembly. It was very early days even for asm.js, but from how
| they spoke of it and it's potential you could tell it would have
| huge impact on the industry.
| willtim wrote:
| Rust maybe a little adhoc in places (e.g. the misappropriated
| Haskell/ML function syntax, enum/struct asymmetry), but overall
| it is a fantastic effort. It is not an easy task to combine an
| advanced static type-system with mainstream ergonomics, but they
| seemed to have pulled it off. The fact that it is also not owned
| and controlled by a single big tech entity is icing on the cake.
| I really hope it achieves even greater success.
| darksaints wrote:
| Building an ecosystem on top of a advanced strictly typed
| language also has an initial hurdle that requires a lot of
| effort to overcome. Potential tool developers must go through
| the effort of becoming familiar with the language and seeing
| the potential for, as well as the path to major improvements.
|
| But once they're there, the result is extremely advanced
| tooling that other language ecosystems have taken years to
| develop. Things like IDEs, debuggers, static analyzers,
| superoptimizers, fuzzers, verification tools, build systems,
| language interop adapters, and code generators, are all
| examples of things that can take advantage of advanced type
| systems to develop strong capabilities extremely easily.
|
| I think Rust is starting to show signs of such benefits, and I
| think in 10 years we'll all be looking back at it with surprise
| that anyone ever doubted it.
| daoxid wrote:
| > misappropriated Haskell/ML function syntax, enum/struct
| asymmetry
|
| I'm curious, could you elaborate?
| willtim wrote:
| In Rust, a function definition left-hand-side looks like an
| annotated pattern, e.g.
|
| foo(x : int)
|
| Therefore, one would expect to annotate the return type as,
|
| foo(x : int) : string
|
| Since the pattern is showing foo applied to x. The Rust
| syntax is actually confusing for both Haskell/ML programmers
| (where the arrow comes from) and mainstream programmers. It's
| too small an issue to change now though.
|
| Rust's support for proper "algebraic data types" is very good
| and gives it an advantage over languages like C++. However
| there are some small surprises, such as forcing all enum
| constructors/fields to be public (one must therefore wrap it
| to make an abstract data type).
|
| Every language has its warts and these are particularly minor
| ones.
| devit wrote:
| That would imply that "foo(x: int)" is a string rather than
| a function.
|
| Haskell doesn't use that notation either, it uses -> both
| for the parameter list and for the return type, and
| separates argument names (arguably, these are poor choices,
| since currying is not an efficient CPU-native operation and
| not intuitive so distinguishing between multiple arguments
| and returning closures is useful, and argument names are
| useful for documentation).
| kaba0 wrote:
| Just a nitpick, but currying is a language detail, one
| can potentially create an efficient implementation with
| or without them.
| willtim wrote:
| Yes and of course Haskell is quite capable of supporting
| uncurried functions too, e.g.
|
| foo :: (Int, Int) -> Int
|
| foo (x, y) = ...
| valenterry wrote:
| I don't think that would be the implication, because we
| are in the context of a function. Otherwise, we should
| also not write foo(x: int) but foo: int -> ?
| willtim wrote:
| > That would imply that "foo(x: int)" is a string rather
| than a function
|
| But foo(x : int) _is_ a string! It literally reads "foo
| applied to x". In the function definition, it appears to
| be used as a left-hand-side pattern which is "matched".
| The definition is written as if to say, whenever the term
| foo(x) is encountered, use this definition here. At
| least, that was my expectation.
|
| > Haskell doesn't use that notation either
|
| OCaml does and Haskell once had a proposal to add it.
| Haskell type signatures are normally written separately,
| but it does support annotating patterns with the right
| extensions.
| gpm wrote:
| No, foo(x: int) is not a string, it's not even an
| expression, it's not even an AST node. It's a fragment of
| the larger ast node fn foo(x: int) ->
| ReturnType { body }
|
| The ast here splits into Function {
| name: foo signature: (x: int) -> ReturnType
| body: body }
|
| I.e. the arrow binary op binds more tightly than the
| adjacency between foo and x: int. And the type of foo is
| a function, not a string.
|
| A "better" way to write this (in that it breaks down the
| syntax into the order it is best understood) might be
| static foo: (Int -> ReturnType) = { let x =
| arg0; body }
|
| Or to put it another way. Reading foo(x: int) as "foo
| applied to x" in this case is a mistake, because that's
| now how things bind. You should read that "foo is a
| (function that takes Int to String)". It's a syntactic
| coincidence that foo and x are beside eachother, nothing
| more.
| willtim wrote:
| That's a nice explanation of what's going on. My point
| remains that I found the syntax confusing though.
| gpm wrote:
| Ya, I'm not really going to defend the current syntax
| past "function syntax is hard".
|
| It's mixing up assigning a global variable, specifying
| that variables type, and destructuring an argument list
| into individual arguments, in one line. I've played at
| making my own language, and this is one part that I've
| never been satisfied with.
|
| Personally I'd probably at least go with a `foo =
| <anonymous function>` syntax to split out the assigning
| part. But that's spending "strangeness budget" because
| that's not how C/Python/Java do it, and I can understand
| the decision to not spend that budget here...
| ZoomZoomZoom wrote:
| > But foo(x : int) is a string!
|
| Can you say so decisively for a language with first-class
| functions?
| willtim wrote:
| You are quoting me out of context. In many languages, the
| term and/or pattern foo(x : int) is a string, if foo :
| int -> string.
| ModernMech wrote:
| I wouldn't say this is a wart or confusing (to me at
| least). As someone who uses Haskell, C++, and Rust
| regularly, I just accept that each language has its own
| syntax. It's true that Rust borrows ideas from many
| languages, but I view Rust's syntax as its own thing, and
| the meaning of the symbols are what they are. It doesn't
| have to do things the C++ way or the Haskell way. It does
| things the Rust way, and that's not a wart.
| willtim wrote:
| It did confuse me when I first saw it, but yes, it is not
| really a significant issue.
| jeltz wrote:
| Having used both Haskell and main stream programming
| languages I did not at all think that was confusing. The
| type of "fn foo(x: int) -> string" is quite obviously
| "fn(x: int) -> string" for people coming from languages
| like C. I do not see how a colon would make anything more
| clear. Imagine the function "fn bar(x: fn(x: int) ->
| string)", would that be more clear with a colon?
|
| On the other hand the enum thing is certainly surprising.
| willtim wrote:
| > Imagine the function "fn bar(x: fn(x: int) -> string)",
| would that be more clear with a colon?
|
| In your example, why bother naming the inner "x" variable
| for the function param? It cannot be used on the right-
| hand-side (definition of "bar"). For that reason, the
| notation is not exactly "clear". In OCaml the annotation
| would be:
|
| bar( x : int -> string )
| east2west wrote:
| In Rust you can write ```f: fn(i32) -> i32```.
|
| Ocaml's syntax is more consistent, I agree, but its colon
| operator has different precedence than in Rust, so I am
| not sure its rational applies to Rust.
| uryga wrote:
| _> one would expect to annotate the return type as
|
| > foo(x : int) : string
|
| > since the pattern is showing foo applied to x._
|
| kind of like the C/C++ "declaration mirrors use" thing,
| i.e. int *foo;
|
| which means
|
| "the result of dereferencing `foo` is of type `int`"
|
| which is _not the same_ as saying foo :
| Ptr<int>;
|
| because in the former, you're kind of describing what `foo`
| is a without actually saying it, if that makes sense.
|
| i find that way of specifying types counterintuitive in
| both C/C++ and MLs.
| the__alchemist wrote:
| FYSA, The Rust approach is the same way it's done in
| Python.
| willtim wrote:
| Well the Python community is hardly an authoritative
| figure on static typing :)
| acdha wrote:
| This is true but Python has a user community which is
| several orders of magnitude broader, which confuses the
| issue a bit. These days if I was designing a language I'd
| probably ask "How would I explain this to someone who
| learned JavaScript/Python?" since even if you have great
| reasons for doing things differently it's a pretty
| reasonable way to predict sources of confusion for
| newcomers.
| ape4 wrote:
| I typed `foo(x : int) : string` when I was starting and
| there was an error message telling me to use `-> string` so
| many people expect this syntax.
| cletus wrote:
| First let me say: I like Rust. I'm a fan. But... it did make
| some early decisions that are going to be hard to shake off,
| most notably around build times. This [1] is well worth a read.
|
| [1]: https://pingcap.com/blog/rust-compilation-model-calamity
| capableweb wrote:
| Yeah, the build times. How does a normal Rust developers
| development environment look like? Do you have to rebuild
| after each change if you want to try out the change itself,
| after you've written tests and so on? How is the REPL
| experience if there is one?
|
| My only experience with Rust so far has been trying to learn
| it by writing applications in it and also use 3rd party CLIs,
| but quickly loosing interest because the "change <> try out
| change" cycle has been too slow and cumbersome, and
| installing/compiling dependencies take fucking forever, even
| on a i9-9900K.
| brabel wrote:
| > How does a normal Rust developers development environment
| look like?
|
| In my experience, you write some code, the rust analyzer
| (which is easily embedded in an IDE like VSCode or IntelliJ
| - which has its own "analyzer" I think) gives you immediate
| feedback, so you know immediately if things compile or not
| (there are a few edge cases the analyzer might miss, so
| when you actually run "rustc" something doesn't compile,
| but it's pretty rare)... you then write a little test , and
| Rust has many ways of letting you do that (unit tests right
| into the same file as the code being tested, integration
| tests which let you use the code as if from another crate,
| and even doctests, which are like unit tests but embedded
| in the documentation of your code)... running the tests is
| a matter of pressing a button and waiting a few seconds
| (compilation + test runtime) normally, unless you change
| dependencies between runs as that requires
| downloading/compiling your code AND the dependencies, which
| can be very slow (dozens of seconds)... which is the same
| problem as with a fresh build, which will almost certainly
| run in the minutes because of the necessary local
| compilation of all dependencies... but the experience is
| not very different from something like Java or Kotlin IMO
| (but definitely a slower cycle than Go, for example).
| hctaw wrote:
| > How is the REPL experience if there is one?
|
| About on par with C/C++ and Go. In that you don't have one
| and don't want for one. REPL driven development is
| difficult with languages like Rust, both to implement and
| use.
|
| I think there are some projects floating around out there,
| but I personally don't see a purpose for one. It's not
| python or matlab.
| capableweb wrote:
| > I think there are some projects floating around out
| there, but I personally don't see a purpose for one. It's
| not python or matlab
|
| I was thinking of a REPL in the sense of common Clojure
| usage (https://vvvvalvalval.github.io/posts/what-makes-a-
| good-repl....) not the basic "write lines into a separate
| program and then copy-paste it into your source code"
| that Python offers.
| zozbot234 wrote:
| The latest TWIR development summary mentions evcxr, a
| notebook-based environment for Rust that's currently
| being worked on, link https://blog.abor.dev/p/evcxr
|
| Notebooks work better than raw REPL's for a language
| that's so heavily based on static typing, but they're
| idiomatically quite similar.
| nessex wrote:
| When I use rust, I find compile times faster and more
| manageable than other languages due to the speed of
| iterative compiles. Compiling from scratch is very slow,
| but iterative compiles are faster than most of my golang
| compiles and faster than running a JS builder in most
| projects. To make it extra fast, I follow the instructions
| from the bevy game engine[1]. With that setup, the feedback
| loop is quick.
|
| [1] https://bevyengine.org/learn/book/getting-
| started/setup/#ena...
| coder543 wrote:
| > iterative compiles are faster than most of my golang
| compiles
|
| Maybe you're comparing apples to oranges here. I've
| worked professionally with both Rust and Go for years now
| on a variety of real world projects, and I've never seen
| a similarly-sized Go codebase that compiles slower than a
| Rust one. If you're comparing incremental Rust
| compilation to first-time Go compilation, _maybe_ they
| could be competitive, but... Rust is incredibly slow at
| compilation, even incremental compilation.
|
| Yes, using lld can speed up Rust compilation because a
| lot of the time is often spent in the linker stage,
| but... that's not enough to make it as fast as Go.
|
| YMMV, of course, but... my anecdotal experience would
| consider it disingenuous to say that Rust compile times
| are an _advantage_ compared to Go, and I 'm skeptical
| that Rust compile times are even an advantage compared to
| the notoriously slow webpack environments.
|
| Rust is good at many things, but compilation speed is not
| one of them. Not even close, sadly. "cargo check" is
| tolerable most of the time, but since you can't run your
| tests that way, that's not actually compilation.
| brundolf wrote:
| It caches things between builds (dependencies in particular
| only have to be built once), and if you use dev builds (the
| default) it doesn't take as long as production. For
| ergonomics you can also install cargo-watch
| (https://crates.io/crates/cargo-watch), which helps a bit.
|
| An important thing though, if you aren't doing this
| already, is to not wait for a full build to know if your
| _types_ check out. You can use cargo-check if you prefer
| (https://doc.rust-lang.org/cargo/commands/cargo-
| check.html), but really I recommend using an editor with
| immediate feedback if at all possible. rust-analyzer (an
| LSP) is one of the best, and should be available even if
| you're on Vim or something.
|
| Using Rust without snappy editor hints is fairly miserable
| because of how interactive the error feedback loop tends to
| be. If you don't rely on a full build for errors - just for
| actual testing - I find the build times to be perfectly
| livable (at least in the smallish projects I've done).
| staticassertion wrote:
| I'm surprise to hear that it was so slow on a powerful
| machine. In my experience throwing more compute at a
| codebase can make compile times very, very fast, though of
| course only after the first run. It parallelizes pretty
| damn well.
| bfrog wrote:
| Clean compiles do take a moment. Comparable to heavily
| templated C++ in my experience.
|
| On the other hand iterative development with rust analyzer
| going and all the dependencies already built is pretty
| painless. By the time you run your tests or program, it's
| likely to take only a few seconds to build.
|
| That said you _can_ write terribly long to compile rust.
| Usually there 's some trades you can make to weigh compile
| time as more important than flexibility or static code
| paths.
|
| I've written a sizeable ad server in rust with maybe
| 25kloc. Where I was the sole developer and sys ops person,
| it cost me a little upfront time but saved me many more
| hours in operations work.
| capableweb wrote:
| I guess by in general a "dynamic programming languages"
| fan, "only a few seconds to build" already sounds like a
| lot. Different tradeoffs I guess, but hard to justify
| when you're used to ms compile time.
| qznc wrote:
| I'm so torn about macros.
|
| They are awesome but they make compile-time arbitrarily bad.
| The D compiler is roughly as fast as the Go one. However, D
| has macros though and that makes it very slow to compile
| sometimes.
|
| The alternative to macros are code generators. Works fine for
| bigger stuff like a parser generator but not for smaller
| stuff like a regex.
| willtim wrote:
| It's better to evaluate at compile time, if possible,
| rather than runtime. The biggest issue with macros is code
| bloat, but every serious general purpose language should
| have them.
| chubot wrote:
| I think a problem is that programmers have little
| intuition about about the evaluation time of macros.
|
| It's possible that Zig's approach helps here -- since the
| metalanguage is just the language, you can take some of
| your intuition about performance along to compile time.
| And the macro language is not weirdly restricted, so you
| can write something you're more used to, with similar
| idioms.
|
| In the limit this is clear: I'm using several Python code
| generators C++ in https://www.oilshell.org, and it's easy
| to reason about the performance of Python. Doing the same
| in C++ metaprogramming would almost certainly be a lot
| slower. It would also give me less indication of code
| bloat; right now I simply count the lines of output to
| test whether my code generator is "reasonable".
|
| e.g. I generate ~90K lines of code now, which is
| reasonable, but if I had 1M or 10M lines of code, that
| wouldn't be. But there's not that much of a sanity check
| on macros (except binary size).
| pcwalton wrote:
| Macros and compile-time function evaluation are different
| and fill different roles. Macros define new syntax, while
| compile-time function evaluation evaluates expressions
| written using the existing syntax. The corresponding Rust
| feature for the latter is not macros, but rather "const
| fn".
| qznc wrote:
| The question is not runtime vs compile time.
|
| The question is whether you do the meta programming/code
| generation within the language or as external tool. Code
| bloat is an issue in both cases.
|
| Macros make it easy to write code which generates code
| which generates code which... This enables some wonderful
| use cases, often around generating type declarations. If
| done with an isomorphic language, you can also reuse the
| same code for compile time and runtime implementations
| with just thin wrappers.
|
| External code generators however will build faster
| because the build system takes care of reusing the
| intermediate code.
| brabel wrote:
| > The D compiler is roughly as fast as the Go one...
|
| Not according to this benchmark:
|
| https://github.com/nordlow/compiler-benchmark
|
| dmd performed around 1.5x to 4x faster than go.
| stared wrote:
| Personally, I find Rust syntax to be well-designed. At least,
| compared to any practical programming language I know.
|
| Quite a few times I was surprised that Rust breaks with some
| old patterns that were copied over and over in the last 50
| years or so. For example: "match" instead of "switch", or the
| same if/else regardless if it is a statement or a value. These
| are small touches, but they show attention to detail.
| linkdd wrote:
| Rust syntax is weird. Weirdly good and sometimes bad.
|
| I'm currently designing my own toy language and writing the
| compiler (to LLVM IR) in Rust.
|
| Representing the AST with Rust's sum types is so simple.
| Visiting that AST through pattern matching is great. But the
| "enum" keyword still bugs me.
|
| The way you define product types (tuples, records, empty
| types) and then their implementation, just awesome. But the
| "struct" keyword still bugs me too.
|
| It feels "high level" with some quirks.
|
| Then you have references, Box, Rc, Arc, Cell, lifetimes
| etc... It feels (rightfully) "low level".
|
| Then you have traits, the relative difficulty (mostly for
| Rust newbies like me) of composing Result types with distinct
| error types, etc...
|
| It feels "somewhat high level but still low level".
|
| Sometimes you can think only about your algorithm, some other
| times you have to know how the compiler works. It seems
| logical for such a language, but still bugs me.
|
| The one thing I hate though, is the defensive programming
| pattern. I just validated that JSON structure with a JSON
| schema, so I KNOW that the data is valid. Why do I need to
| `.unwrap().as_string().unwrap()` everywhere I use this
| immutable data?
| coolreader18 wrote:
| Because ideally your JSON schema validator would turn it
| into a type that mirrors the structure of the data. "Parse,
| don't validate"[0]
|
| [0]: https://lexi-lambda.github.io/blog/2019/11/05/parse-
| don-t-va...
| linkdd wrote:
| But the Rust type system cannot fully express a JSON
| Schema: { "type": "object",
| "oneOf": [{ "required": ["kind", "foobar"],
| "properties": { "kind": {"enum": ["foo"]},
| "foobar": {"type": "string"} } }, {
| "required": ["kind", "barbaz"], "properties": {
| "kind": {"enum": ["bar"]}, "foobar": {"type":
| "number"}, "barbaz": {"type": "string"}
| } }] }
|
| Or am I wrong?
| remexre wrote:
| In general, JSON Schemas are (wrongly, in my view...)
| validation-oriented rather than type-oriented (for
| notions of types that would be familiar to Haskell, Rust,
| or Common Lisp programmers).
|
| I think that schema in particular could be represented,
| though, as: enum Thing {
| foo { foobar: String }, bar { foobar:
| Option<f32>, barbaz: String }, }
| linkdd wrote:
| What about user-supplied JSON schemas? You can't add
| types at runtime.
|
| Also, JSON schemas allows you to encode semantics about
| the value not only their types: {"type":
| "string", "format": "url"}
|
| That's something I like about Typescript's type system
| btw: type Role = 'admin' | 'moderator' |
| 'member' | 'anonymous'
|
| It's still a string, in Rust you would need an enum and a
| deserializer from the string to the enum.
| remexre wrote:
| > What about user-supplied JSON schemas? You can't add
| types at runtime.
|
| Right, well, since they're validators anyway, might as
| well represent them as a defunctionalized validation
| function or something. Agreed that this is more-or-less
| past the point where the type system helps model the
| values you're validating, though a strong type system
| helps a lot implementing the validators!
|
| > It's still a string, in Rust you would need an enum and
| a deserializer from the string to the enum.
|
| Yep, though if you really wanted it to be a string at
| runtime, you could use smart constructors to make it so.
| The downsides would be, unless you normalized the string
| (at which point, just use an enum TBH), you're doing O(n)
| comparison, and you're keeping memory alive, whether by
| owning it, leaking it, reference counting, [...].
|
| Thankfully due to Rust's #[derive] feature, the
| programmer wouldn't need to write the
| serializer/deserializer though; crates like strum can
| generate it for you, such that you can simply write:
| use strum::{AsRefStr, EnumString};
| #[derive(AsRefStr, EnumString, PartialEq)] enum
| Role { Admin, Moderator,
| Member, Anonymous, }
| fn main() {
| assert_eq!(Role::from_str("Admin").unwrap(),
| Role::Admin);
| assert_eq!(Role::Member.as_ref(), "Member"); }
|
| (strum also has also a derive for the standard library
| Display trait, which provides a .to_string() method, but
| this has the disadvantage of heap allocating; EnumString
| (which provides .as_ref()) compiles in the strings, so no
| allocation is needed, and .as_ref() is a simple table
| lookup.)
|
| [0]: https://docs.rs/strum/0.20.0/strum/index.html
| masklinn wrote:
| > Yep, though if you really wanted it to be a string at
| runtime, you could use smart constructors to make it so.
| The downsides would be, unless you normalized the string
| (at which point, just use an enum TBH), you're doing O(n)
| comparison, and you're keeping memory alive, whether by
| owning it, leaking it, reference counting, [...].
|
| Nit: it's more constraining but serde can deserialize to
| an &str, though that assumes the value has no escapes.
|
| Ideally `Cow<str>` would be the solution, but while it
| kind-of is, that doesn't actually work out of the box:
| https://github.com/serde-rs/serde/issues/1852
| linkdd wrote:
| Thanks for the insight! Didn't know strum.
|
| But yeah, I tend to do more work at runtime than compile-
| time, which is not really the way to go in Rust.
| steveklabnik wrote:
| As the input gets more dynamic, so does the type system
| representation. If you want to handle user-supplied JSON
| schemas, in my understanding of JSON Schema, you'd have
| to use the serde_json::Value way:
| https://docs.serde.rs/serde_json/#operating-on-untyped-
| json-...
| masklinn wrote:
| > What about user-supplied JSON schemas? You can't add
| types at runtime.
|
| That kinda sounds like you just launched the goalposts
| into the ocean right here.
|
| > Also, JSON schemas allows you to encode semantics about
| the value not only their types:
|
| JSON schemas encode types as constraints, because "type"
| is just the "trival" JSON type. "URL" has no reason not
| to be a type.
|
| > in Rust you would need an enum
|
| Yes? Enumerations get encoded as enums, that sounds
| logical.
|
| > a deserializer from the string to the enum.
|
| Here's how complex the deserializer is:
| #[derive(Deserialize)] #[serde(rename_all =
| "lowercase")] enum Role { Admin, Moderator,
| Member, Anonymous }
|
| And the second line is only there because we want the
| internal Rust code to look like Rust.
| linkdd wrote:
| Yep, I'm still new to serde and the Deserialize workflow
| :)
|
| I come from highly dynamic languages, and even when I was
| doing C/C++ 10 years ago, I would do more at runtime that
| what could be considered "best practice".
| masklinn wrote:
| I'm sure you can design schemas screwy enough that Rust
| can not even express them[0] but that one seems
| straightforward enough:
| #[derive(Serialize, Deserialize)] #[serde(tag =
| "kind", rename_all = "lowercase")] enum X {
| Foo { foobar: String }, Bar {
| #[serde(skip_serializing_if = "Option::is_none")]
| foobar: Option<f64>, barbaz: String
| } }
|
| [0] an enum of numbers would be an issue for instance,
| though I guess you could always use a `repr(C)` enum it
| might look a bit odd and naming would be difficult.
| willtim wrote:
| Unfortunately Rust is currently lacking structural
| records/structs and enums. I think they removed them
| early on in the design. So you'd have to name the all the
| types. I hope they do add them back one day.
| sireat wrote:
| Syntax wise Rust seems heavily inspired by the "good parts"
| of Scala.
|
| - Pattern matching via "match"
|
| - if being an expression (among most things)
|
| Those are both found in Scala.
| lgessler wrote:
| Didn't Scala get both of those things from ML?
| Jtsummers wrote:
| Yes, and Rust has more direct lineage to OCaml than Scala
| (initial version was written in OCaml, and the language
| had a more ML-ish syntax early on).
| sireat wrote:
| I guess then it would be more correct to say that Scala
| and Rust share a common inspiration in ML languages.
| yoneda wrote:
| > Quite a few times I was surprised that Rust breaks with
| some old patterns that were copied over and over in the last
| 50 years or so. For example: "match" instead of "switch", or
| the same if/else regardless if it is a statement or a value.
| These are small touches, but they show attention to detail.
|
| These are good ideas for sure, but they are bread and butter
| to anyone who is familiar with functional programming. The
| Lisp and ML families of languages have had them for many
| decades.
|
| The fact that more languages _aren't_ like this is what's
| surprising to me, given how effective they are. I love that
| Rust is bringing them to the masses, but what on earth took
| the industry so long to accept them?
|
| I guess the answer is that algebraic data types (inductively
| defined data) tend to be pitted against object-oriented
| programming (coinductively defined data), and object-oriented
| programming has dominated the industry for the past 3
| decades. Some languages like Kotlin have tried to combine
| them, but personally I'd rather just embrace the former and
| relegate the latter to a seldomly-used design pattern, not a
| programming paradigm hardcoded into the language.
| dahfizz wrote:
| Rust reminds me a lot of Scala in that respect. Not really
| a functional language, but with functional goodies
| sprinkled throughout.
| da39a3ee wrote:
| I think that there's still time for Rust to reverse the
| .expect(...) naming mistake. It should be deprecated, either
| introducing something with an appropriate name like
| .unwrap_or_panic(...) or just leave it to be replaced by
| .unwrap_or_else(|| panic!(...)) which IMO one ought to use
| today instead of .expect(...).
|
| Everything else is named so well and designed so well that
| this really sticks out.
| fithisux wrote:
| The impression left by this article is that Bjarne Stroustrup is
| doing a big mistake by continuing his work on C++. Nim / Zig / D
| are UFOlogists and who needs Racket / CL / Haskell anyway. Java
| could be found in ancient Egypt being served to mummies.
| galgalesh wrote:
| Even if rust becomes a full replacement, it might take half a
| century before the last C++ project stops being maintained. In
| the meantime.
|
| Investing your time in improving C++ is a safe bet for a long-
| lasting meaningful impact on software [development]. C++ will
| outlive Bjarne.
| bhaak wrote:
| > A little appreciated fact: Rust was largely built by students,
| and many of them interned at Mozilla.
|
| The article doesn't mention it but this is of course a very good
| long term strategy. Things students learn during their formative
| years at university will bear fruit once they enter the work
| force.
|
| How many of those students are now at or about to enter important
| positions in the industry?
|
| Do you think Java could have become this big if it wasn't teached
| at so many universities at the entry level?
| brson wrote:
| Having so many students involved in Rust was huge. Definitely
| the most rewarding thing about working on Rust was seeing
| students get involved, grow, then turn that experience into a
| career, while seeding the industry with Rust talent.
| bhaak wrote:
| Yes, but it goes both ways. As a student, I was always
| thrilled to see bits of future technology today.
|
| I am still sad that some of the things I've seen or have
| taken part in didn't materialize and haven't taken a hold in
| the present.
|
| The students you had were certainly as happy as being with
| you as you were having them. :-)
| camehere3saydis wrote:
| The converse is also true: students are relatively less
| fettered by today's "best practices", less constrained by non-
| academical pursuits, and thus would be more capable of dreaming
| up a better paradigm for the future.
| yitchelle wrote:
| It is a double edge sword. No doubt if the students are
| motivated and dedicated, they could build the next metaphoric
| rocket ship. Also they also runs the risk of causing the
| project to off course and failed.
|
| It sounds like the leadership of Dave was key to getting the
| team to focus and to delivery high quality results.
| Decabytes wrote:
| Having written Racket code myself I was surprised when I saw that
| Rust had Hygenic macros.
|
| I've never learned how to use macros effectively, but once I've
| gotten more comfortable in Rust I'd like to give it a good shot.
| Given Dave's background with Racket and Macros, this feels like a
| worthwhile endeavor.
|
| On a side note there are a lot of cool language oriented
| programming stuff that Racket does through it's macro system, and
| I wonder if it is at all possible to do something like that in
| Rust
| yw3410 wrote:
| I was super-surprised when I used rust macros (specifically
| macro rules) about how lispy it was.
|
| There was an aha-moment when I realised that it was token based
| and not AST based like some other macro systems I've worked
| with in some other languages.
|
| Case in point is how to express varargs in macro rules which is
| expressed roughly like a comma followed by an expression
| repeated n times. Super nice.
| zozbot234 wrote:
| The OP mentions in passing that Brendan Eich "was solidly on team
| Rust" prior to leaving Mozilla, but adds no further details to
| that intriguing statement. Wouldn't that make Eich _the_ Most
| Unrecognized Contributor? I don 't think his name would be on any
| commit repo, after all.
| kevingadd wrote:
| Having sat next to / worked with a lot of the rust core people
| (and Eich) I think while his support was important, that
| doesn't make him more important/pivotal than people like Dave
| Herman
| coldtea wrote:
| > _I don 't think his name would be on any commit repo, after
| all._
|
| Not only his name is on the Rust commit repo, he's also in the
| list of top 10 commiters the article features as an early Rust
| development example (although for just 6 commits or so).
| theobeers wrote:
| Here's one of the Eich commits in the prehistory repo (which is
| fun to browse):
|
| https://github.com/graydon/rust-prehistory/commit/8952f420ae...
| ealexhudson wrote:
| I understood that point as relating more to management than
| technical contribution - that the support of people like Eich
| was imperative to keep the project funded, and as key
| supporters left the project became more susceptible to
| cancellation.
| flakiness wrote:
| Reading "JavaScript: the first 20 years" [1], Dave Hermans name
| is popping up here and there as well. His contribution in this
| case was highlighted in the story of the (failed) ES4. I wonder
| how these early experience has shaped his thoughts on Rust.
|
| [1] https://dl.acm.org/doi/10.1145/3386327
| chalst wrote:
| Dave Herman has been a high signal-to-noise contributor to Lambda
| the Ultimate over the years; if you want to get an idea as to
| where he is coming from, looking at his contributions there [1],
| his slightly active blog [2], and on his now pretty much inactive
| joint blog [3] are good places to start.
|
| [1]: http://lambda-the-
| ultimate.org/user/825/track?sort=desc&orde...
|
| [2]: http://calculist.org/
|
| [3]: https://www.thefeedbackloop.xyz/
| rektide wrote:
| another random mention, Dave was also the main driver of
| EcmaScript Modules.
| lifeisstillgood wrote:
| The big takeaway for me is that inside our daily corporate world,
| we should strive for more open discussion about the work we do -
| I keep trying to do more discussion-list style work with my team,
| even though it often is easier to jump on a video call.
|
| It has a payback a long way down the road but my gut knows it is
| worth it.
| varispeed wrote:
| > A little appreciated fact: Rust was largely built by students,
| and many of them interned at Mozilla.
|
| So now companies make billions off of the software written in
| Rust and has even one student become a millionaire? Companies
| that appropriate such projects should start paying their fair
| share to people who made it possible for them to make such
| profits.
| Ericson2314 wrote:
| Yes workers are exploited, but it's also harder to create value
| when you insist on capturing it.
|
| This is arguable a big idea of free software: trying to
| jealously hoard the value for ideas that are naturally freely
| copied and shared is just plain inefficient.
|
| So yes, in this case it would be nice if these interns got a
| big pay out, but if they did, then the megacorps wouldn't
| bother using Rust because they plan is already to just outbid
| all the non-monopolists for workers rather than actually be
| productive with their workforce. And C++ and whatever else are
| _already_ free, so Rust has to complete with those.
|
| The only way to make things more fair is just give up on
| meritocratic value capture, and just do a big tax and big UBI,
| so just as free software is free to use by all, some of the
| value created in the use of free software is also freely shared
| by all.
| rover0 wrote:
| Being in the team that created rust would look great on any CV.
| I think millionaire is reachable for many of them.
| varispeed wrote:
| Under the current framework, you cannot get wealthy off of
| salary. If you working a wage, then you are a corporate slave
| most of the time.
| staticassertion wrote:
| > Under the current framework, you cannot get wealthy off
| of salary.
|
| You can make hundreds of thousands of dollars a year as an
| engineer, without even talking about stock. I'd call that
| wealthy. If you're an engineer of some stature, 7 figures
| TC yearly is not out of reach.
| seabrookmx wrote:
| I don't know what your definition of corporate slave is,
| but you can certainly become wealthy off a salary.
|
| Just limiting to software engineering (there's other
| lucrative fields out there) you can easily make a six-
| figure income remotely. This gives you the freedom to live
| somewhere with very low cost of living. It's not hard to
| build wealth this way.
|
| You could debate that getting the necessary skills to get a
| job like this is harder than it should be.. that
| corporations themselves are broken.. whatever your
| worldview is that's fine but "cannot get wealthy off
| salary" is just plain false.
| varispeed wrote:
| > This gives you the freedom to live somewhere with very
| low cost of living. It's not hard to build wealth this
| way.
|
| This is quite contradictory and proves my point.
| cies wrote:
| Are you familiar with (a) open source licenses, and (b) the
| profit maximization principle?
| jrochkind1 wrote:
| > Hiring Yehuda Katz to design Cargo
|
| I did not realize this; that explains why cargo is so similar to
| ruby bundler (which Katz also wrote).
| hardwaregeek wrote:
| He also worked on Yarn. Yehuda Katz has probably the most
| experience of anyone on dependency management
| jrochkind1 wrote:
| I haven't heard much from him lately not sure what he's up
| to.
|
| I'd love to see an interview with him on his experiences with
| dependency management. What did he learn? What things in
| earlier attempts did he change in later attempts (from
| bundler to cargo to yarn)? What does he think he got
| rightest? What mistakes does he think he made? What mistakes
| does he think _other_ people are still making? What features
| of a language or platform faciliate or challenge good
| dependency management? etc etc etc.
|
| In general, I think there isn't much "learning from prior
| art" in our field that _crosses language /platform
| boundaries_. Katz being personally driving the implementing
| popular dependency management solutions on three different
| langauges/platforms was one way to actually learn from cross-
| language experience! I think in dependency management in
| particular, there are still a lot of lessons people are
| learning on their own not realizing another language/platform
| already learned some painful lessons on it... or maybe
| differences in langauges/platform mean some things aren't
| transferable...
| whoisburbansky wrote:
| The name Katz set off bells in my head while I was reading the
| article, but it was only until I saw your comment that I
| realized why. Cool bit of connection-making there!
| jxf wrote:
| I confess I'm pretty ignorant about the history and origins of
| Rust, and it's not something I tend to investigate deeply for a
| lot of my tools.
|
| But I derive a great deal of my current livelihood from Rust and
| helping firms use it well, so thank you, Dave.
|
| If nothing else, maybe I'll be looking more closely at my next
| tools, and hoping they have their own Daves quietly advocating
| for their success.
| galangalalgol wrote:
| Have you ever helped a firm use rust on airgapped or nexus
| ptoxies developer networks? The nexus module appears abandoned,
| and the documentation on running an offline crates.io mirror is
| very lacking.
| xpe wrote:
| This seems like a non-sequitor and off topic. There are
| plenty of better places to give this feedback.
| galangalalgol wrote:
| I think maybe my question was taken differently than I
| meant it. I was legitimately asking if the gp had/could
| help with such a task.
| Ar-Curunir wrote:
| It's a very niche question. You're better served asking
| in Rust support channels like the discord or the
| subreddit.
| [deleted]
| melling wrote:
| Haven't learned Rust yet. I see they debated this:
| let and let mut let and var
|
| And went with the verbose option.
|
| Swift went with the succinct option, which I love about the
| language. In practice I suppose I do mostly type "let" in Swift
| so it doesn't matter much
|
| Swift, however, chose 'func' instead of 'fn', after much debate.
|
| Those little things that are debated initially, then forever
| Thiez wrote:
| In Rust the `mut` does not apply to the `let`, but to the
| variable binding. So you can do this: let (x,
| mut y) = (5, 10);
|
| After this statement `x` will not be mutable, but `y` will be.
| You _cannot_ do let mut (x, y) = (5, 10);
|
| So the way Rust currently works just doesn't map clearly on
| `let` and `var`.
| Macha wrote:
| This is true, but the decision was made far back enough that
| other design decisions would have been weighed with
| consistency with the short behaviour in mind had that been
| the option chosen, and Rust would work slightly differently
| than how it currently works.
|
| This is in the era of a new version having patch notes like
| (paraphrased) "Of the four pointer types with special syntax,
| we've converted two of them to regular types with names and
| deleted the fourth" - it predated that much concern with
| backwards compatibility.
| MrBuddyCasino wrote:
| Kotlin's version is even better: val & var
|
| Super clear. The "let" version smells a lot of "I have a
| CompSci PhD".
| melling wrote:
| Practically, I prefer let and var because of autocompletion.
| Type one letter then tab. Of course, if I could dictate I
| might prefer something else.
|
| I think of it as being more math like rather than PhD.
|
| Nothing wrong with borrowing from math.
| BiteCode_dev wrote:
| A good IDE will let you type "mu", and autocomplete with
| "let mu", cycling on tab will give you more options.
| rocqua wrote:
| From the perspective of "language designers influencing
| programmers", the difficulty of auto-completing to `let
| mut` could be seen as something positive.
| fuck_google wrote:
| Obviously you haven't had to maintain code written by
| mathematicians that prefer to use one letter names for
| functions and variables among other peculiarities.
| wink wrote:
| No, not at all. I hate var & val because I never can remember
| which is which (from Scala, which I never really used a lot).
|
| let vs let mut is /clear/ - you can simply not mix them up.
| akvadrako wrote:
| How is it not clear that var is variable?
| mkl wrote:
| Yes. I think the problem may be with the other one. "val"
| (and "let") don't seem obviously constant to me.
| jeltz wrote:
| Yes, whenever I get confused I recall that var is
| obviously variable so therefore the other one must be
| val.
| nicoburns wrote:
| Let is definitely confusing given that JS has let and
| const (with let being mutable)
| wink wrote:
| But that is cross-language, which is not ideal but not an
| internal problem if you work in one code base. (O)Caml
| also has `let` and is quite a bit older than JS.
| jodrellblank wrote:
| C# uses "var" to mean "infer the type", nothing to do
| with mutability or not.
|
| "Let" feels like some in-joke, coming from a math via
| lisp heritage of "let k be any number..." to distinguish
| it in English from the surrounding writing. I have to
| guess that in early lisp (= k 5) would be an error as k
| isn't defined and (k 5) errors because k isn't a function
| and (let (k 5)) comes out of need for a binding function
| and why not "let".
|
| In c-like languages "k=5" is an established binding that
| both programmers and compilers can deal with. What does
| "let k=5;" add to Rust over "k=5;" ?
| rovolo wrote:
| "val" is short for "value"
| rover0 wrote:
| I'm a javascript developer.
|
| if mutable is expensive, and should be difficult then
| "let mut" makes more sense.
|
| var looks like a default to me, not a special case that
| needs care.
| leshow wrote:
| Nitpick: "expensive" may be the wrong word there, to me
| that implies some kind of runtime cost. The stated reason
| for the keyword is that it forces users to think a little
| bit more about mutability. You may want do this because
| safe mutability requires exclusive ownership.
| mjw1007 wrote:
| It's interesting if "let" nowadays has mostly 'academic'
| connotations.
|
| 30 years ago I think it would have reminded people more of
| BASIC or Fortran than (say) Scheme.
| Macha wrote:
| I think this would have been more true 10 years ago when
| Haskell and Lisp were the most likely place for people to
| have encountered "let".
|
| Now? It's in Javascript in its ES6 evolution and related
| languages, Swift, Rust, and probably other "newer"
| languages I'm not aware of. Scala had it ten years ago
| also, but is more mainstream than it was then.
| Ar-Curunir wrote:
| The hamming distance between val and var is tiny; easy to
| miss in a code review.
| chrismorgan wrote:
| A relevant period of history here is the _mutpocalypse_ , where
| the question was raised "why are we calling this &mut and
| teaching it as being about mutability when what we actually
| care about (for memory safety) is uniqueness and aliasing?" Had
| that side prevailed, &mut would have been renamed (the main
| candidates presented were &uniq and &only), and all bindings
| would have become mutable (`let mut` would have disappeared),
| because that concept wouldn't make a great deal of sense any
| more. These are the only technical changes that it would have
| entailed (the biggest change would have been in pedagogy).
|
| In the end, social factors and inertia trumped technical
| precision and consistency. I am strongly inclined to think this
| was a mistake. Mutability is easier to explain initially, but
| teaches an incorrect mental model that hinders a correct
| understanding of Rust's approach to memory safety, falling
| apart as soon as you touch things like atomics, RefCell or
| Mutex, which mutate self despite taking it as &self, a
| supposedly immutable reference.
| NanoCoaster wrote:
| > Mutability is easier to explain initially, but teaches an
| incorrect mental model that hinders a correct understanding
| of Rust's approach to memory safety, falling apart as soon as
| you touch things like atomics, RefCell or Mutex.
|
| Could you elaborate or link to some material / discussion
| regarding that? I'd be very interested in how the alternative
| approach you're describing would change (or make unnecessary)
| constructs like RefCell.
| chrismorgan wrote:
| The changes I described for the mutpocalypse vision are
| basically all there is to it, because &mut has always been
| a misnomer, never about being a _mutable_ reference as its
| name replies, but rather about being a _unique_ reference,
| that nothing else holds a reference while you have that
| one. The main thing the mutpocalypse sought to achieve was
| to adjust Rust's syntax to match its semantics (including
| to remove mutability tracking on bindings, because that
| wasn't part of Rust's _necessary_ semantics, and wouldn't
| make as much sense after the trivial syntax change).
|
| The thing I'm noting about atomics, RefCell and Mutex is
| how they have methods that (safely) mutate themselves,
| despite taking &self, a supposedly immutable reference.
|
| (I've modified the final sentence in my original comment to
| clarify this.)
| NanoCoaster wrote:
| I see, interesting point. Thank you :)
| chrismorgan wrote:
| I feel like making one more note. I said that "mutable
| references" was a misnomer and that it's actually about
| _unique_ references, but even that's a bit of a misnomer,
| because it's not quite about uniqueness, but uniqueness
| of _access_. You can have multiple &mut borrows to the
| same thing, but only one of them is _accessible_ at any
| given time: let mut x = 1; let y =
| &mut x; let z = &mut *y; *z += 1; *y +=
| 1; assert_eq!(x, 3);
|
| z and y both point to x, but only one is accessible at
| any point in time. Touching y finishes the z borrow; if
| you swapped the increment lines, it wouldn't compile.
|
| My memory is fuzzy (this was quite some years back), but
| I have a vague feeling that this lack of precision in the
| use of the word "unique" was a factor in some baulking at
| the proposed change. ("You're trying to fix something
| that we admit is strictly wrong, but you're not even
| making it _right_!")
| xfer wrote:
| Would this have worked pre-NLL?
| Thiez wrote:
| The pre-NLL version would need some additional scopes. In
| some ways the current borrow-checker is a lot friendlier
| (there are also some things possible today that weren't
| before) but it was also a simpler time, where one could
| easily imagine the various lifetimes. Getting started
| with the language was harder, but I think internalizing
| the borrow-checker was easier, because the rules were
| simpler and you were forced to learn them for anything
| more complex than 'hello world'. let
| mut x = 1; { let y = &mut x;
| { let z = &mut *y; *z +=
| 1; } *y += 1; }
| assert_eq!(x, 3);
| steveklabnik wrote:
| > Getting started with the language was harder, but I
| think internalizing the borrow-checker was easier,
|
| So here's a funny thing: depending on what you mean, I
| don't think this is actually true. Let me explain.
|
| The shortest way of explaining lexical lifetimes vs NLL
| is "NLL is based on a control-flow graph, lexical
| lifetimes are based on lexical scope." CFGs _feel_ more
| complex, and the implementation certainly is. So a lot of
| people position this as "NLL is harder to understand."
|
| But that assumes programmers think in the simple way. I
| think one of Rust's under-appreciated contributions is
| that programmers intuitively understand control flow
| graphs better than we may think, and may not intuitively
| understand lexical scope. Sure, by some metric, NLL may
| be "more complex" but practically, people only report it
| being easier to learn and do what they would naturally
| expect.
| Thiez wrote:
| Hey Steve :-) I've been following and using Rust since
| early 2013 (so starting around the same time you did,
| when I compare our contributions to the compiler) and
| back then I definitely did not find the lexical lifetimes
| hard to understand. I remember also noticing an increase
| in "dumb" lifetime-related questions after NLL landed,
| seemingly caused by a lack of understanding of how they
| work.
|
| Perhaps it's all just confirmation bias on my end, but I
| think truly understanding lifetimes was easier the way I
| learned it back then. That said, I have never bothered to
| write documentation for the Rust project, whereas few
| Rust contributors can claim to be in the same league as
| you in that area. We probably have very different
| perspectives.
| steveklabnik wrote:
| Oh totally, I know you :) It's interesting how our
| perceptions are different though, I think a lot of the
| "dumb" questions went away since NLL. I wonder if there's
| a way to quantify this.
|
| So, I think this is the thing: I also think that it was
| easier to learn lexically, personally. I too was worried
| that it would make things harder. But, I just don't think
| that's been demonstrated to be true across most people.
| It is, however, only my gut-check feeling for what I've
| seen. I could be wrong.
|
| (And, the borrowcheck documentation is _very_ minimal,
| and didn 't really change with NLL, other than needing to
| add some println!s to make things not compile again. So
| it's certainly not because I wrote some amazing docs and
| explained it in a good way, hehe.)
| chrismorgan wrote:
| I started in mid-2013 too, and my position is similar to
| yours. I'd characterise it like this: lexical lifetimes
| are easier to grok, but NLL turns out to be more
| practical, doing what people actually want (where LL
| didn't) enough that it overcomes the greater conceptual
| complexity, because you have to actually _think about_
| the concepts less often.
| xfer wrote:
| Yes, the pre-NLL version makes it clear to see why
| swapping the assignment lines wouldn't work.
|
| EDIT: i think some tooling showing lifetimes for borrows
| would be very helpful. Can mir do this? I haven't tried
| it.
| jeltz wrote:
| I agree with that thinking about it in terms of mutability is
| a bit missleading but I am not sure how your idea would fix
| the issues with RefCell and Mutex. Additionally I think that
| some code is clearer with enforced single assignment in the
| syntax.
| est31 wrote:
| > falling apart as soon as you touch things like atomics,
| RefCell or Mutex.
|
| Does it really fall apart? None of these constructs change
| the fact that if a _& mut T_ is available, you can call
| functions on that type that take _& mut self_. The only thing
| that breaks is the assumption that non-presence of mut
| implies that there is no way to call those _& mut self_
| functions. If you change it to "non-prsence of mut implies
| that you need extra constructs like atomics, RefCell or
| Mutexes in order to get mutable access" it works out again.
| chrismorgan wrote:
| The mental model of & being immutable and &mut being
| mutable, that's what falls apart. Here are types that are
| taking &, and yet are mutating themselves.
|
| This becomes a _huge_ deal when people think that they have
| an immutable data structure just because they have an &
| reference to it. Someone will inevitably stash a mutex or
| similar in there because they just need to be able to
| mutate it this once... I mean these three times... I mean
| all the time. Oh, you wanted this immutable data structure
| so you could diff it for your VDOM or incremental
| calculations or whatever? Heh, guess you'll have to find
| some other way or structure things so that mutations can be
| propagated through the object tree or something. And you'll
| keep on having cache issues from time to time when people
| forget to jump through the right hoops. Sorry about that.
|
| So yeah, the mental model of &/&mut references being about
| mutability is just completely _and harmfully_ wrong. Rust
| does not have a way of guaranteeing immutability.
| est31 wrote:
| > The mental model of & being immutable and &mut being
| mutable, that's what falls apart. Here are types that are
| taking &, and yet are mutating themselves.
|
| &mut still implies mutability, and even the constructs
| like Mutex or RefCell still expose their mutability
| support via &mut references. Only atomics don't (they
| don't provide any &mut access). Note that you don't add
| const like in C/C++, you add &mut.
|
| As for the VDOM caching thing, you have a point. But even
| if Rust had &uniq and &shared pointers, the challenge
| would be the same. Users might still use constructs like
| RefCell.
| pkfoo wrote:
| It's bastardized OCaml. Instead of OCaml's _mutable_ they
| inexplicably chose _mut_ , which is ugly (same as _pub_ ).
|
| But everyone is cheering them on.
| rtoway wrote:
| I think their reasoning for things that are shortened is that
| if it's something you will be writing a lot, it's nicer to
| have it shortened. So pub fn mut etc. are shortened, but
| return isn't
| jerryluc wrote:
| In rust it played out well due to the usage of mut in other
| places. As in: fn (&mut T)
| dom96 wrote:
| Same for Nim which uses let and var: proc
| (x: var T)
| aome510 wrote:
| The same story [0] was posted several hours ago by the author I
| suppose.
|
| [0]: https://news.ycombinator.com/item?id=27016848
| joseluisq wrote:
| Yep, this needs a `dup` mark somewhere.
|
| Edit for down-voters: the typical HN behaviour. Don't be lazy
| and take a time to explain why you downvote.
| Macha wrote:
| https://news.ycombinator.com/newsfaq.html
|
| > Are reposts ok?
|
| > If a story has not had significant attention in the last
| year or so, a small number of reposts is ok. Otherwise we
| bury reposts as duplicates.
|
| > Please don't delete and repost the same story. Deletion is
| for things that shouldn't have been submitted in the first
| place.
|
| Dupes are not against the rules. You're likely getting
| downvoted by people aware of that.
| joseluisq wrote:
| If your affirmation is true, why many of HN users (me
| included) get [dupe] at first place? In general, Is not the
| HN intention to decrease number of duplicates? If not so
| then HN should provide a solution for prevent this, such
| prevention that is not happening today. Example search
| input.
|
| Sorry but I'm seeing big contradictions in the so called
| rules.
|
| Just one example:
|
| > If a story has not had significant attention in the last
| year or so, a small number of reposts is ok. Otherwise we
| bury reposts as duplicates.
|
| > "in the last year or so"
|
| Not in the same month or even after some hours later.
|
| > "a small number of reposts is ok"
|
| Well, HN what to prevent duplications or not ?
|
| > Dupes are not against the rules. You're likely getting
| downvoted by people aware of that.
|
| With that premise in mind, let's continue making duplicate
| content. right?
|
| So don't misunderstand me, since my intention here is just
| to put in evidence the same recurrent problem to improve
| HN. For instance I have also faced the same problem in the
| past so there is nothing agains rules or things like that,
| but instead is more a improvement for HN.
|
| The reason because I'm interested on this is because I feel
| part of the community and this is a concern for me (I
| suppose for others too). Otherwise I could take the easy
| and dirty way to just say nothing and ignore the problem.
| Macha wrote:
| > > If a story has not had significant attention in the
| last year or so, a small number of reposts is ok.
| Otherwise we bury reposts as duplicates.
|
| > > "in the last year or so"
|
| > Not in the same month or even after some hours later.
|
| A year is the expiration date on reposts of items that
| _have_ had significant discussion. Items which did not
| have significant discussion, and also did not have a
| large quantity of reposts already are exempt. In some
| cases the mods have reached out to submitters and
| suggested they repost items which the mods felt were
| interesting but did not catch on.
| joseluisq wrote:
| Unfortunately this is not clarifying my concerns about
| duplications in this particular case. I understand about
| the year of expiration and moderators can reach out
| submitters but for me is not clear what `significant
| discussion` means as well as `moderators could suggest
| submitters repost items which the mods felt were
| interesting but did not catch on`.
|
| Essentially I still don't understand why some get label
| as duplicated and some others not.
|
| Anyway, Unfortunately
| https://news.ycombinator.com/newsfaq.html is not clear at
| all for me and I think HN needs to make it more obvious
| to help members to understand without doubts or
| contradictions, which was the case for me.
|
| So I will contact HN soon in order to request an account
| deletion.
|
| Thanks for try to explain me about it.
|
| PD. Sorry for the deviation of these comments from the
| main topic here. But I think my concern is already
| expressed on previous comments.
| dang wrote:
| The issue with duplicates isn't reposts of articles as
| such, it's not wanting significant duplicate discussions.
| We allow reposts as a way of mitigating the randomness of
| /newest. But once a story has gotten _significant_
| attention, we bury reposts as duplicates. (But after a
| year or so, enough time has gone by that a repost is ok
| again.)
|
| In the current case, the previous submission didn't get
| much attention, so we didn't count this one as a dupe. In
| the case of your post
| https://news.ycombinator.com/item?id=26812145, the
| previous submission of the story did get a big
| discussion, so we marked the repost as a dupe. There's no
| contradiction.
|
| Does that make sense? If not, take a look at some of the
| previous explanations. If you still have questions after
| that, let us know.
|
| https://hn.algolia.com/?dateRange=all&page=0&prefix=true&
| que...
|
| https://hn.algolia.com/?dateRange=all&page=0&prefix=true&
| que...
| dang wrote:
| Downvoters on HN are not required to explain why they
| downvote. That would just lead to massive numbers of low-
| quality "explanations" and tons more flamewars.
|
| I'll respond to the point about duplicates below.
| pvg wrote:
| _Downvoters on HN are not required to explain why they
| downvote_
|
| Maybe by this point this belongs in the document that talks
| about voting meta, given that it's one of the most
| persistent and common voting meta comments.
| neilv wrote:
| Before going to Mozilla, Dave Herman was also a prolific
| contributor of open source libraries for PLT Scheme (Racket).
___________________________________________________________________
(page generated 2021-05-03 23:02 UTC)