Live data from Hacker News

An incoherent Rust

boxyuwu.blog

31–40 of 175 posts

Re: An incoherent Rust

#31
I never understood why Rust couldn't figure this shit out. Scala did.

> If a crate doesn’t implement serde’s traits for its types then those types can’t be used with serde as downstream crates cannot implement serde’s traits for another crate’s types.

You are allowed to do this in Scala.

> Worse yet, if someone publishes an alternative to serde (say, nextserde) then all crates which have added support for serde also need to add support for nextserde. Adding support for every new serialization library in existence is unrealistic and a lot of work for crate authors.

You can easily autoderive a new typeclass instance. With Scala 3, that would be:

  trait Hash[A]:
    extension (a: A) def hash: Int

  trait PrettyPrint[A]:
    extension (a: A) def pretty: String

  // If you have Hash for A, you automatically get PrettyPrint for A
  given autoDerive[A](using h: Hash[A]): PrettyPrint[A] with
    extension (a: A) def pretty: String = s""
> Here we have two overlapping trait impls which specify different values for the associated type Assoc.

  trait Trait[A]:
    type Assoc

  object A:
    given instance: Trait[Unit] with
      type Assoc = Long

    def makeAssoc: instance.Assoc = 0L

  object B:
    given instance: Trait[Unit] with
      type Assoc = String

    def dropAssoc(a: instance.Assoc): Unit =
      val s: String = a
      println(s.length)

  @main def entry(): Unit =
    B.dropAssoc(A.makeAssoc) // Found: Playground.A.instance.Assoc Required: Playground.B.instance².Assoc²

Scala catches this too.

Re: An incoherent Rust

#32
post #10

Note the use case - someone wants to have the ability to replace a base-level crate such as serde. When something near the bottom needs work, should there be a process for fixing it, which is a people problem? Or should there be a mechanism for bypassing it, which is a technical solution to a people problem? This is one of the curses of open source. The first approach means that there will be confrontations which mus…

It's a social problem that's created by a technical problem.

In many languages, if you want to integrate package A with package B, you can make and share a package AB, which people can reuse. That scales, and facilitates reuse, and avoids either package having to support everything.

In Rust, if the integration involves traits, integration between package A and package B must happen either in A or in B. That creates a scaling problem, and a social problem.

Re: An incoherent Rust

#33
post #15

This is one of the (several?) things that make me very worried about Rust long-term. I love the language, and reach for it even when it sometimes isn't the most appropriate thing. But reading some of the made-up syntax in the "Removing Coherence" section makes my head hurt. When I used to write Scala, I accepted the fact that I don't have a background in type/set/etc. theory, and that there were some facets of the la…

Rust opened the door to innovation in the low-level languages space, but as long as it is already the most theoretically advanced practical language there, it will always attract the audience that actually wants to push it further. I don't know if there is a way to satisfy both audiences.

I think there is: a schism. Another language, inspired, intelligible and interoperable with Rust, but with other goals, likely ease of use or surface simplicity. In my mind it would be pretty much the same as Rust, but whenever a compile error gives you a suggestion in rustc would instead compile (and at most be a warning in this hypothetical language). Migrating from Rust to this language would be changing a single setting in Cargo.toml. The other way around would be fixing a bunch of compile errors. You could use the entire crate ecosystem in a native way. This language could also serve as a test bed for features that might or might not be suitable for Rust. It can also have a more aggressive evolution schedule, meaning that it wouldn't be perma-1.x, so it can be bolder on what is attempted.

Re: An incoherent Rust

#34
post #31

I never understood why Rust couldn't figure this shit out. Scala did. > If a crate doesn’t implement serde’s traits for its types then those types can’t be used with serde as downstream crates cannot implement serde’s traits for another crate’s types. You are allowed to do this in Scala. > Worse yet, if someone publishes an alternative to serde (say, nextserde) then all crates which have added support for serde also…

Perhaps I'm insufficiently caffeinated, but isn't the author describing the expression problem? That basically nails what type classes are for (in Scala and elsewhere), no?

Re: An incoherent Rust

#36
post #9
post #4

There's a well-known (and frequently encouraged) workaround for the orphan rule: Create a wrapper type. Let's say you have one library with: pub struct TypeWithSomeSerialization { /* public fields here */ } And you want to define a custom serialization. In this case, you can write: pub struct TypeWithDifferentSerialization(TypeWithSomeSerialization) Then you just implement Serialize and Deserialize for TypeWithDiffer…

The gotcha is what happens when TypeWithSomeSerialization is not something you’re using directly but is contained within SomeOtherTypeWithSomeSerialization which you are using directly. Then things get messy.

In that case, wrap a reference maybe?

    pub struct TypeWithDifferentSerialization(&TypeWithSomeSerialization)

Re: An incoherent Rust

#37
post #15

This is one of the (several?) things that make me very worried about Rust long-term. I love the language, and reach for it even when it sometimes isn't the most appropriate thing. But reading some of the made-up syntax in the "Removing Coherence" section makes my head hurt. When I used to write Scala, I accepted the fact that I don't have a background in type/set/etc. theory, and that there were some facets of the la…

Rust opened the door to innovation in the low-level languages space, but as long as it is already the most theoretically advanced practical language there, it will always attract the audience that actually wants to push it further. I don't know if there is a way to satisfy both audiences.

A similar thing happened with C++: The fact that it had a relatively high complexity of interacting features (already 30+ years ago) that you could use to do smart things, did attract smart people with a high tolerance for complexity. And with such an audience, complexity tends to expand up to the limits of tolerance (or even a little beyond).

Rust had a better start, not the least because it wasn’t designed on top of an existing language like C++ was, but who knows what it will look like in 30 years.

Re: An incoherent Rust

#38
post #15

This is one of the (several?) things that make me very worried about Rust long-term. I love the language, and reach for it even when it sometimes isn't the most appropriate thing. But reading some of the made-up syntax in the "Removing Coherence" section makes my head hurt. When I used to write Scala, I accepted the fact that I don't have a background in type/set/etc. theory, and that there were some facets of the la…

> But reading some of the made-up syntax in the "Removing Coherence" section makes my head hurt.

Articles discussions new features always have difficult syntax. There have been proposals like this going on from the start.

Fortunately the language team is cognizant of the syntax and usability issues with proposals. There have been a lot of proposals that started off as very unwieldy syntax but were iterated for years until becoming more ergonomic.

Re: An incoherent Rust

#39
Language changes could help for sure. There’s a library implementation we can use right now though: https://facet.rs/ Basically a derive macro for reflection. Yeah it’s one (more) trait to derive on all your types but then users can use that to do reflection or pretty printing or diffing or whatever they want.
Post reply on HN