scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

Inconsistencies in the Spec about class

Open fare opened this issue 6 months ago • 6 comments

  1. The Scala 3.4 specification uses the word "class" inconsistently, sometimes meaning "that Java-inherited concept that only supports single inheritance", sometimes meaning "class or trait". Please be consistent in the specification if nowhere else. Maybe introduce and systematically use a word for class-or-trait; or declare that class (or trait) encompasses both unless specified otherwise ("non-class trait" if trait encompasses both, "non-trait class" if class encompasses both), and use it consistently afterwards. It's a spec, it must be precise.
  2. The Scala 3.4 specification fails to explain that the most-specific superclass (if not Object) need not appear first among the direct super classes-or-traits of a class-or-trait, whereas it needed to in Scala 2.
  3. While we're at it, it really sucks that you use a variant of the LOOPS algorithm for class-or-trait linearization, instead of C3. For why the consistency constraints of C3 matter, see the 1992 and 1994 articles by Ducournau, Habib, Huchard, and Mugnier. I realize this breaks backward compatibility and thus may have to wait until a new major Scala version, though.

fare avatar Jun 04 '25 23:06 fare

Hey, can you link specific sections? Also, just a reminder that Scala 3.4 is no longer supported. We currently support 3.7 (the current Scala 3 Next) and 3.3 (the current Scala 3 LTS, soon to be replaced with 3.9)

Gedochao avatar Jun 05 '25 07:06 Gedochao

A trait is a class that is meant to be added to some other class as a mixin.

I don't detect the imprecision.

The section on linearization distinguishes "linearization of a class" and "linearization of mixins", but maybe it could say "linearization of a subclass" instead, for clarity.

The "published" spec calls itself 3.4 but includes latest edits. (I don't know the workflow.)

som-snytt avatar Jun 05 '25 08:06 som-snytt

The "published" spec calls itself 3.4 but includes latest edits. (I don't know the workflow.)

Oh, now that's worrying... 🤔 cc @WojciechMazur @sjrd

Gedochao avatar Jun 05 '25 08:06 Gedochao

The specification is synchronized on each commit to main (merged PR) - it's uploaded to LAMP server building all scala-lang websites

The version showed and the endpoint upon which it would be available is controlled by config https://github.com/scala/scala3/blob/0be20913a4005ea53097990521232f2a57b86e6e/docs/_spec/_config.yml#L1-L3 Currently these are pointing to 3.4.
We can change these, but it would also require additional changes on docs.scala-lang becuse the link to specification is hardcoded : https://github.com/scala/docs.scala-lang/blob/2b612762460ecde204d54fd2afcbd5d77d06fc78/index.md?plain=1#L72-L75

Probably it would be the best to change config and update entry in docs.scala-lang. There is no switch for different versions of specification on that side, but the old versions should still be reachable by links (unless when syncing these would be overrdined, we'd need to confirm that)

I think there is also one more problem - the specification is showing the state of main branch so nightly releases. I belive it would be better if spec would be synced only on stable releases. That's what we do with reference docs.

WojciechMazur avatar Jun 05 '25 09:06 WojciechMazur

A trait is a class that is meant to be added to some other class as a mixin.

I don't detect the imprecision.

Maybe for people familiar with CLOS or its predecessor Flavors, the word "mixin" will help, but otherwise "trait" and "mixin" are synonyms from Smalltalk vs Lisp traditions, and it doesn't help much to define one by the other. Worse than that: since 1990s, the term "mixin" has been repurposed in programming language research to mean something more primitive (in a good way) (see Bracha and Cook 1990 on Mixin Inheritance).

Also, furgossake, your language has a special distinct keywords for class and trait. If you start by saying that a trait is a class you're going to give readers a hard time. The least you could do is take responsibility for having two distinct keywords, hence two distinct names for distinct concepts. If you thereafter want a common word for the two, fine, but you still need a distinct word for "a class that isn't a trait". You could use "non-trait-class" which is ugly, "struct" to copy Common Lisp, "line" (a word I just made up, that means the same as trait in French, but suggests a linear order), "suffix" because its linearization is the suffix of the linearization of subclasses, or "prefix" because programmers specify it syntactically first (ugh). Or you could use "class-or-trait" or "class-or-trait-or-object" or indeed "mixin" for the inclusive variant and "class" for the exclusive variant. A friend also suggested 1-class vs n-class or ω-class. Possibilities are endless. Make up your mind between Scala high priests, and thereafter be consistent in the spec. It's a spec, it gotta be precise.

The section on linearization distinguishes "linearization of a class" and "linearization of mixins", but maybe it could say "linearization of a subclass" instead, for clarity.

Uh, the linearization is a list of a class's superclasses. If it contained only classes strictly speaking, it would be trivial, but if you call class-or-trait "mixin" then yes that works. Flavors (Cannon 1979, Moon 1986) just calls the list an ordering, and the word linearization is introduced later (though the concept is already in flavors). It's called the "class precedence list" in CLOS. SIMULA has a corresponding concept of "prefix sequence" in the same most-to-least-specific order interestingly, though it's a bit trivial since SIMULA only has single inheritance (the word "inheritance" does not exist in SIMULA though, it was introduced by KRL in 1975 and only the multiple kind at the time; Kay distinguishes single vs multiple inheritance in 1976 when he has Smalltalk only adopt single inheritance as a compromise).

Anyway, naming things is hard, especially when everyone does it differently.

The "published" spec calls itself 3.4 but includes latest edits. (I don't know the workflow.)

Yeah well I clicked on the "spec" link on https://docs.scala-lang.org/ and it still links to a version "3.4", whether that's a lie or not I can't tell.

fare avatar Jun 09 '25 23:06 fare

While we're at it, it really sucks that you use a variant of the LOOPS algorithm for class-or-trait linearization, instead of C3. For why the consistency constraints of C3 matter, see the 1992 and 1994 articles by Ducournau, Habib, Huchard, and Mugnier. I realize this breaks backward compatibility and thus may have to wait until a new major Scala version, though

I'm not familiar with different linearization algorithms, but offhand, this sounds like it could be an interesting thread on https://contributors.scala-lang.org , though I'd suggest kicking it off more positively (without the "it really sucks"), in order to get the discussion off on the right foot. We generally use this tracker just for bugs (one per ticket!), and the forum is the better place for more open-ended, speculative discussions about possible design changes.

SethTisue avatar Jun 17 '25 23:06 SethTisue