Aliasing other things

Let's say you have a Color.

struct Color { }

You can have a Colour

type Colour = Color;

let's say you have a color or a color():

struct Foo {
  color: i32
}

trait Bar {
  fn color();
}

there's no way to have a colour or colour().

importantly, when implementing a trait with aliases, any alias may be used, and the compiler should still error if a method isn't implemented. specifically this is not the case in the example below:

trait DoesntWork {
  fn color() {
    Self::colour()
  }
  fn colour() {
    Self::color()
  }
}

struct Foo {}
impl DoesntWork for Foo {}

my suggestion would be to group aliases together:

struct Foo {
  {color, colour}: i32
}

trait Bar {
  fn {color, colour}();
}

Why? You can fix DoesntWork by doing

trait DoesntWork {
  fn color();

  fn colour() {
    Self::color()
  }
}

Then you must implement color (you can flip the defaults if you want). But why would you want two ways to do the same thing, it seems needlessly confusing. With type aliases, they are usually used to simplify type expressions.

For example in parking_lot you can say Mutex<Vec<i32> instead of lock_api::Mutex<parking_lot::RawLock, Vec<i32>> (there are other examples). But this doesn't apply to functions. There doesn't seem to be a need to alias functions in this way, because there isn't a need to simplify function signatures as much as types.

7 Likes

I use "alias" here to mean "different name" only

strictly speaking we do not have aliases for types, but rather something we can use to constrain type bounds.

so this syntax should also let you do struct {Color, Colour} {} ofc.

some names should be interchangeable because of the nature of the language they're written in. however, there's no good way to decide that stuff. the best solution is to let the developers do so.

No, the best solution is to stick with one. Probably with the U.S. spelling since the majority of technology-related English is U.S. English anyway. Or really, just pick either one and move on. There are way more important problems than that in software design, and using many different names for the same thing only causes confusion.

6 Likes

Hi @Soni

Although your suggestion seems to be a great solution for the problem you are trying to solve, I don't think this is a "problem" that should be solved. One idea in Rust's design is to have "exactly one thing to do something", so having synonyms would be going against Rust's philosophy. Then you could ask why we have type aliases in the first place. And my view on this, is that aliases are more a "nickname" than a "different name". Just as nicknames, aliases become more useful when the actual names are longer:

//Useful alias
type MyAlias = <SomeGenericType<Long,Types> as VeryLongTrait<More,Generics>>::OutputType;
//Not so useful alias
type Point3d = Point<3>

So imo, aliases should be used only to make your code more readable, not to have different names. And as @RustyYato said:

3 Likes

aliases should be used so you don't cause confusion about which name to use - either will work.

this is especially important if you decide to use two different crates, which happen to have picked different dialects.

the idea here is that they'd each stick to one dialect over the other, but expose both on their public API. the API consumer would then have the choice to stick with one dialect over the other for both crates, and everyone's happy.

That's what causes confusion. Now I need to remember that these two different names mean the same thing. More things to remember, for relatively little gains.

8 Likes

let me fix that for you: now you no longer need to remember which types/traits come from which crates so you can know which spelling to use for them! you can just do it and it'll work!

Yes, when writing code, but when reading code and it becomes measurably harder to figure out what's going on when there are two names for the same thing.

5 Likes

no, you should still pick one and stick with it. that's not gonna change.

If I use two crates with a Color/Colour type, I would be happy if they use different dialects, because these types would not be compatible anyway, so I want to distinguish them.

How would you enforce that when you work in a team? People can just use the other synonym(s) as they please.

Also, with your reasoning, why stop at dialects? There are other words with the same meaning, abbreviations and even other languages. This would lead to something like this for the color example:

struct Foo {
  {color, colour, rgb, spectrum, couleur, farbe, kleur, chroma, ...}: i32
}

trait Bar {
  fn {color, colour, rgb, spectrum, couleur, farbe, kleur, chroma, ...}();
}
2 Likes

To create a function alias, this works on nightly today:

#![feature(impl_trait_in_bindings)]

fn foo(a: usize) -> usize { a }

const bar: impl Fn(usize) -> usize = foo;

fn main() {
    dbg!(bar(42));
}

you can do the same thing to create an alias of associated fn. There's currently no way to alias the fields, but, i think we shouldn't.

3 Likes

There's currently no way to alias the fields

Well, I mean unions do exist.

Please don't use unions for this!

ppl wouldn't do that, because that's a slippery slope fallacy.

anyway, here's the motivation: real ppl, working on real projects, found the inconsistencies extremely frustrating to deal with.

this solves that by allowing them to pick their own inconsistencies. it's one of those minor ergonomics/accessibility things that don't affect anyone else but ppl are gonna bikeshed to hell anyway simply because they're not affected by it. .-.

1 Like

The discussion is getting rather heated, I think it'd be better to take a breather. :wink:

Attempting to getting things back onto a hopefully more productive line of discussion: Rather than adding aliases, the same thing could be achieved by properties (with getter and setter functions) as they exist in other languages, which I think would be more generally useful.

Personally I'm not a huge fan, FWIW, but obviously those languages disagree with me there.

while you could abuse properties (and unions) for this, that's not their intended purpose.

also none of the workarounds proposed here work when implementing trait method. indeed, not even properties.

[Mod note: Deleted a few comments above. Please carefully make your points and then let them stand for themselves; try to avoid getting pulled into rapid back-and-forth arguments.]

7 Likes

This post was flagged by the community and is temporarily hidden.