Why does `:` not convert the type from a var to another var?

Rust supports : in working on a value or a variable, e.g.

  1. b = 3; => b's value is always 3
  2. b = 3 + a; => b's value is dynamic, according to a's value. Once I changed code on a's value, b's value will be changed.(dependent relation on value between variables)

But rust doesn't support = do the same way on variables, instead, it only support type value&struct name instead variable.

Rust does not support

  1. let a : i32 = 0;
  2. let b : a;
  3. b = 1;

Why a variable after = can be converted into a value but after : can not be converted into a type?

The thing after the : is a type ascription, and a is a variable, not a type (while i32 is a type).


  1. Nice username BTW :sweat_smile: ↩︎


The thing after the = is a value ascription, and a is a variable, not a value(while 0 is a value).

"value ascription" is not a thing, in Rust anyway. the thing after = is an expression.

Anyway, is something still unclear?


The topic is not about what it is now.

The topic is about why it is ... and why it is not ..., to make rust reasonable to understand in learning.


name foo has info set {
    self {
        type-binding-symbol: null (recognized by let or () or : or name?)
        type: variable, (not fn, not struct...)
        type-symbol: "null"
        type-symbol-position: "null"
    its binding {
        mutability-binding-symbol: "null"
        mutability: immut, or mut
        mutability-symbol: "null" or "mut"
        mutability-symbol-position: ahead of name
    its binding value {
        value-type-binding-symbol: ":"
        value-type-binding-symbol-position: after name
        value-type: i32,
        value-type-symbol: "i32"
        value-type-symbol-position: after ":"
        value-binding-symbol: "="
        value: 0,
        value-symbol: "0"
        value-symbol-position: after "="

The = can be used to get the later expression's ["value"] already,

So I wondered why not support that using : to get the later expression's ["value-type"].

1 Like

I sense a language barrier here, but I also sense you're suggesting that

let a: i32 = 0;
let b: a;
b = 1

Should be possible and mean.... something. But I'm not 100% sure what you're proposing it means.

Perhaps this?

let a: i32 = 0;
let b: typeof!(a);
let b = 1;

Rust doesn't have typeof functionality, that's true.

If that's youre question, I don't have a concrete answer as to why. But usually inference is sufficient. Granted, not always.

Here's some prior discussion around typeof-like functionality. There are probably others too.

This forum is generally for questions about Rust as it exists today ("about what it is now"). Proposals and discussion about potential future directions are better suited to IRLO.

(I'm about to sign off for awhile; don't be surprised if I'm slow to respond.)


The answer to these question is always the same “what's the point”.

Features are added to the language because they are useful, not just because they can exist.

Because every feature, no matter how “small” or “obvious” brings something negative with it: you need to make language larger, people need to learn how that feature works and so on.

That means that every feature is starting from “-100” points and then you bring some positives to bring total score to more than zero.


Using : instead of = for initialization/assignment would not "make Rust reasonable to understand". The language is already reasonable, and this is completely independent of the lowest-level syntactic details like this.


Oh yeah, I agree with this 100%.

So why a struct use two symbols : and = to bind its inner item's value based on different environments, as rust already added a new style : using : to indicate the type

  1. s_variable.x = 0;
  2. s_variable = s_type {x : 0}

What's the point on that { x : 0 } , it uses :

As you mentioned above, it should be concise and easy for keeping itself not larger

  1. s_variable.x = 0;
  2. s_variable: s_type = { x = 0 }

or if the curly block has multi statements, let it be like a function using multi line:

mut struct s_type {
    let mut x = 0; // auto infer to : i32;
    let mut y = 0; // auto infer to : i32;
    let z = 0; // auto infer to : i32;
let s_variable: s_type = {
    x = 0;
    y = 0;

I've never seen something like leb b: a where a is a variable except in languages with dependent types, however in those cases the type of a must be the type of "some type" and i32 is clearly not. I would be very confused to read something like this in a mainstream language.

Moreover this currently compiles:

struct a {};
let a: i32 = 0;
let b: a;

So I'm not sure if you can even give a different meaning to let b: a than what it currently has.


Yeah, for simple usage, yes.

If users want to new a variable based on another variable's value-type, here is the method. The b will change its value-type if value-type of a is changed to u32 while coding.

This unsupported behavior is same as =. The value is not fixed. Once I change a's value, the b's value depends on a's value, so b's value will be changed too.

So why : is fixed on value-type , not like = on value. This behavior adds inconsistency and learning-cost when I learn rust.

I prefer to hear objective evidence and logic, however, thanks for your sharing of your favor.

And : is a value-type binding symbol between name and type right? I didn't see anyone saying want to replace = with :...

That one is easy. Let's consider valid C++ code:

    s_value.x = 0;
    s_value = s_type {x : 0};

Would it be easier to translate it to what Rust does now or to this:

    s_value.x = 0;
    s_value: s_type = { x = 0, }

Much of Rust's syntax is clever mimicry to attract C and C++ developers.

Rust is, often characterised as “an ML dialect in C++ trenchcoat” and while this is tongue-in-cheek characterisation yet it's not to far from the truth.

This leads to some decisions which would make no sense in a world without C/C++.

People don't want consistency. Lispers learned that the hard way. To much diversity makes code hard to read, but too much uniformity is detrimental, too. And making language more similar to C/C++ was obvious thing to do.

The argument that changing a single arbitrary sigil to another arbitrary one doesn't improve anything sounds pretty objective to me.

If you are proposing a language change, the burden of explaining it clearly to everyone else is on you. If you can't do that, don't be surprised that nobody gets what you actually want.


I was confused that the expression after = is dynamic depending on the variable it contains.

But the expression after : is fixed, and not allowed to contain variables.

This is expected to me: variables are not types, so of course I can't use them where a type is expected.

Edit: and the expression after : is not "fixed". You can use type MyType = i32; to create the equivalent of a variable for types, i.e.:

type MyType = i32;
let a: MyType = 0;
let b: MyType;
b = a;
1 Like

Yeah, it puzzled me too. In rust:

  1. the variable's value (which after symbol "=") is the result value after calculating the later expression.
  2. the variable's type (which after symbol ":") is not the result type after calculating the later expression.

Well, in a learner view. the difference between : and = is that one calculates the type and one calculate the value. That sounds easy.

But the reality is that the : is not same as =, I need to learn that one is static and another is dynamic. They're different not only on its object but also on its calculability on variables.

Look back to b = a + 4; the b will be changed if a is changed in source code. So the idea is that adding some implementation of rust to reduce learning cost for users. I heard that target in official site. Haha~

I think this would be ambiguous because Rust has separate namespaces for types and variables (I think! An expert should correct me.). So you could have both a variable called a and a type called a. Right now that's fine because there's no place you could legally put both the name of a type and the name of a variable. But this change would break that property.

1 Like

Wow, you found this, thank you. So it supports

  1. the : to get type from
    1. a type-name. e.g. i32
    2. a struct-name. e.g. a
  2. the = to get value from
    1. a value-name. e.g. 0
    2. a variable-name. e.g. a

The question is that a variable has a value-type :i32 and value 0. And a type only has a type... So here the : could be used on variable, after all a variable is not only a value, it has value-type, mutability... If I can get a value from a variable, why can't I get a type from a variable, and why can't I get the mutability from a variable!! haha

  1. let b : i32; // i32 is a type, supported
  2. let b : a; // name a is a struct, supported
  3. let b : a; // name a is a variable, not supported
  4. let b = 0; // 0 is a value, supported
  5. let b = a; // name a is a variable, supported

The notation you want works:

fn f<a>() {
    let b : a; // totally works

In your original example, your a was an integer variable, rather than a type variable, so you couldn't use it in a context where you want a type rather than an integer.

In my example, a is a type variable. Typically one would use upper-case letters for type variables (but it's not required):

fn f<T>() {
    let b : T;