Live data from Hacker News

Dave Herman’s contributions to Rust

brson.github.io

111–120 of 174 posts

Re: Dave Herman’s contributions to Rust

#111
post #67
post #42

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 great…

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.

> 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.

Re: Dave Herman’s contributions to Rust

#112

> 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.

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.

Re: Dave Herman’s contributions to Rust

#113
post #76

Earlier quoted context omitted.

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

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…

> 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.

Re: Dave Herman’s contributions to Rust

#114
post #90

Earlier quoted context omitted.

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...

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?

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, 
            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.

Re: Dave Herman’s contributions to Rust

#115
post #105
post #98

Earlier quoted context omitted.

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 , barbaz: String }, }

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.

> 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

Re: Dave Herman’s contributions to Rust

#116
post #105
post #98

Earlier quoted context omitted.

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 , barbaz: String }, }

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.

> 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.

Re: Dave Herman’s contributions to Rust

#117
post #111
post #67

Earlier quoted context omitted.

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.

> 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…

Rust reminds me a lot of Scala in that respect. Not really a functional language, but with functional goodies sprinkled throughout.

Re: Dave Herman’s contributions to Rust

#118
post #113

Earlier quoted context omitted.

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…

> 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.

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.

Re: Dave Herman’s contributions to Rust

#119
post #105

Earlier quoted context omitted.

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.

> 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? Enumeratio…

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".

Post reply on HN