carbon-lang icon indicating copy to clipboard operation
carbon-lang copied to clipboard

I think it's better to use the 'const' keyword than to use 'let' for constant values

Open sirlordt opened this issue 2 years ago • 19 comments

I think it's better to use the const keyword than to use let for constant values

In my opinion us much clear

const Pi: f32 = 3.14;

to use

let Pi: f32 = 3.14;

The c++ developer had the const keyword very clear. And const is universal for all kind of software developer no matter the language to use.

Another problem is a conflict with javascript developers use the let keyword to declare variables. I known the goal is include to c++ developer, but take good ideas from another languages and tools in my opinion never is bad.

sirlordt avatar Jul 22 '22 20:07 sirlordt

I agree.

Ubuntufanboy avatar Jul 22 '22 22:07 Ubuntufanboy

I also agree.

SpaghettDev avatar Jul 22 '22 22:07 SpaghettDev

const and let should be different. I think carbon should have both of them at the same time. const is a compile time constant and let is a runtime constant like Kotlin and Swift, but the specific content needs to be discussed

C-BJ avatar Jul 23 '22 01:07 C-BJ

const and let should be different. I think carbon should have both of them at the same time. const is a compile time constant and let is a runtime constant like Kotlin and Swift, but the specific content needs to be discussed

And why we need two kind of const? This add more complexity to language. In my opinion one kind of const is enough. Clear and easy please not again the 1000 crazy concept of c++.

sirlordt avatar Jul 23 '22 01:07 sirlordt

const and let should be different. I think carbon should have both of them at the same time. const is a compile time constant and let is a runtime constant like Kotlin and Swift, but the specific content needs to be discussed

And why we need two kind of const? This add more complexity to language. In my opinion one kind of const is enough.

like Kotlin and Swift. For example, class declared with let

C-BJ avatar Jul 23 '22 01:07 C-BJ

If it helps, it's reminiscent of constexpr versus const. The guarantees differ.

jonmeow avatar Jul 23 '22 01:07 jonmeow

comp const pi:f32 = 3.14;

compile const pi:f32 = 3.14;

compile_time const pi:f32 = 3.14;

All compile time expressions use comp or compile or compile_time prefix keyword. Is very clear and easy. I prefer compile_time keyword no way to confusion.

sirlordt avatar Jul 23 '22 02:07 sirlordt

All compile time expressions use comp or compile or compile_time prefix keyword. Is very clear and easy. I prefer compile_time keyword no way to confusion.

+1

I think it expresses the intention better than let. And no c++ newbies can figure out the difference between const and constexpr without checking, doesn't matter how many years of coding experience from other languages they might have

mo-xiaoming avatar Jul 23 '22 04:07 mo-xiaoming

I agree with this. It makes it inconsistent with other languages that use let to mean the complete opposite thing. It's not the end of the world but it's a papercut for anyone jumping into the language.

andrewfenn avatar Jul 24 '22 06:07 andrewfenn

I agree too, const reads better and has more meaning.

anton-roos avatar Jul 24 '22 06:07 anton-roos

While I agree const would be a better keyword instead of let, there are some other things to consider:

  • Is this something we're holding on to from C++ / other languages?
  • Is Pi: const f32 = 3.14; really better than let Pi: f32 = 3.14;?
  • Do we want to break being consistent with var Pi: f32 = 3.14;?

Because I believe that Carbon's syntax should consistent I have to overall disagree with changing let to const. Additionally, let is less typing.

Alternatively, a rust approach could be taken where all variables are const unless mut is applied. However I imagine changing this would be quite the task. Eg. var Pi: f32 = 3.14 and var Pi: mut f32 = 3.14.

WarEagle451 avatar Jul 24 '22 08:07 WarEagle451

In my opinion, let means a constant object, but for pointer I meet some trouble.

var i : i32 = 0;
let pi : i32* = &i;

In this case, pi can't change, and I know carbon do not support pointer arithmetic, but can I change i by pi ? I think in this case I can do it. But when I don't want to change some values by their pointers, how can I do it. For pointer I need a keyword make it can't change the value it points. Maybe I need something like this :

let pi :  const i32 * = &i;

I think we need const. It doesn't only mean some values is constant. let can't do this work well in this case.

By the way , I like this syntax better:

let pi : i32 const * = &i;

For types, modifiers are placed on the right in order. This is that we only need to read from one direction to easily understand its meaning. In this example, if we read from right to left, we can know that it is a pointer, pointing to a constant, and the constant type is i32. But this way is far from C++, and C++ programmers need energy to adapt, so it is not too May appear in carbon. If someone can help me solve this case, I can accept let even it doesn't mean constant directly.

pache-Ak avatar Jul 24 '22 17:07 pache-Ak

While I agree const would be a better keyword instead of let, there are some other things to consider:

  • Is this something we're holding on to from C++ / other languages?

Yes!!. Is it goal to be succesor of c++ the good ideas and keyword must be implemented in carbon.

The real question for me. What are good ideas and bad ideas from c++?

  • Is Pi: const f32 = 3.14; really better than let Pi: f32 = 3.14;?

the idea are

const Pi : f32 = 3.14;

not

Pi: const f32 = 3.14;

const keyword must be to left of the var name not to the right. The const to the right of is historical fix of c++ because c and c++ the types of variables are inverted. First the type and later the name. With pascal syntax of the first var name and later the type is not needed the const to the right.

And yes. For me is most clear use const to let in a expression to define a constant.

  • Do we want to break being consistent with var Pi: f32 = 3.14;?

In my opinion the const keyword is the natural and consistent opposite of var keyword. Of course your never use both in the same declaration. Let keyword look very out of place for express a constant. The constant is a concept universal of programming languages no only of c and c++. With const keyword not way to confusion.

Because I believe that Carbon's syntax should consistent I have to overall disagree with changing let to const. Additionally, let is less typing.

Alternatively, a rust approach could be taken where all variables are const unless mut is applied. However I imagine changing this would be quite the task. Eg. var Pi: f32 = 3.14 and var Pi: mut f32 = 3.14.

sirlordt avatar Jul 24 '22 17:07 sirlordt

Why not have const for constexprs, let for immutable runtime variables, and var for variables? Makes sense if you think about it :)

By the way, I think you do need to have a differentiation between declaring constant compile-time and runtime-values, if the developers are planning to use constexprs in some exclusive way...

ghost avatar Jul 25 '22 01:07 ghost

the idea are

const Pi : f32 = 3.14;

not

Pi: const f32 = 3.14;

const keyword must be to left of the var name not to the right. The const to the right of is historical fix of c++ because c and c++ the types of variables are inverted. First the type and later the name. With pascal syntax of the first var name and later the type is not needed the const to the right.

I'm highly against putting the const to the left of the name.

In C++ I would write code as const int number = 1.

  • type = const int
  • name = number
  • value = 1

It would only make sense that in Carbon the syntax would go as Number: const i32 = 1

  • type = const int
  • name = number
  • value = 1

Another big issue with putting const to the left of the name is const pointers. const PiPtr: f32 const* = Π looks like a mess, var PiPtr: const f32 const* = Π looks a lot better because all the qualifiers are in one spot. (Personally I would like to have it be var PiPtr: const* const f32 = Π Because is would read perfectly as variable PiPtr is a constant pointer to a constant f32)

Additional reasons:

  • const is a type qualifier so it should be to the left of the type not the name.
  • The syntax is name: type = value;, const f32 is not the same type as f32.
  • Adding the const in the beginning would misalign variable names, which I suspect maybe part of the reason let and var where chosen.
  • Reads as constant 32 bit floating point.

In C++ const to the left or right usually does not matter, and most modern C++ uses const to the left of the type. But there are cases const to the left or right does matter.

  • int* const = a const pointer to an int
  • const int* or int const* = a pointer to a const int
  • const int* const or int const* const = a const pointer to a const int

I could go either way with const, I just lean towards not changing it. If it was to be changed I'd rather have all variables immutable by default like rust. Additionally the rust way would also solve the issue of const pointers

WarEagle451 avatar Jul 25 '22 04:07 WarEagle451

const and let should be different. I think carbon should have both of them at the same time. const is a compile time constant and let is a runtime constant like Kotlin and Swift, but the specific content needs to be discussed

And why we need two kind of const? This add more complexity to language. In my opinion one kind of const is enough. Clear and easy please not again the 1000 crazy concept of c++.

I'm not sure we should be using other successor languages as syntax inspiration - just their concept of language design/development.

I also think let as the constant value keyword just simply isn't as clear in purpose as something like const.

Whether two (or more) kinds of const is really needed is I think yet to be seen.

MichaelBonnet avatar Jul 25 '22 18:07 MichaelBonnet

After digging though the design docs I found this on const.

The example in that section implements const (not currently implemented) as I suggested in my previous post except it uses let. Giving it further thought, if const is already planned to be implemented what is the point of let?

IMO const should affect both the base type and type qualifier and let should be removed. Eg. let Ptr: const i32* = &Number; to var Ptr: const i32*;

Additionally from what I understand the design doc mentions that let is suppose to act as an equivalent to C++'s const references (here under "Binding Patterns"), if that is the case I suggest that let should be renamed to ref. Ref would maintain the 3 letters, IMO make the intention more clear and ref is a well known shortening of reference, the only difference is that in carbon a reference would be constant.

WarEagle451 avatar Jul 25 '22 20:07 WarEagle451

I don't want to have to be discouraged from making everything immutable. Maybe I'm just ridiculously lazy, but two extra characters... :-). From what I've seen, C++ programmers don't usually make all local variables const, so a briefer way to express this desired default of immutability is nice, in my opinion. Defining an immutable variable should not be less brief than defining a mutable variable, because immutability should be the default.

The c++ developer had the const keyword very clear. And const is universal for all kind of software developer no matter the language to use.

I don't personally find this very compelling. Many languages (let in Rust, let in Swift, val in Scala, val in Kotlin, etc.) use a brief three letter keyword for immutable local variables. I don't believe it is a barrier to readability in those languages - at least to anyone who has studied the language even a little bit.

I personally find "let x = y" to read beautifully, but maybe that's due to some of my more mathematical background. Obviously someone who works 99% with C++ and has never seen Carbon will understand "const" right out of the box, but is it really necessary to optimize for that? Spend even 10 minutes learning the basics, and most people won't struggle. Rust is not an easy language overall by any means, but this was definitely not one of the aspects I struggled with when learning it from previously having programmed almost exclusively C/C++.

As others have suggested, I like const more for compile-time constants, or some other stronger notion of "constness". This is the approach taken by Rust and Kotlin. This also avoids the need to resort to more lengthy keywords like comptime, constexpr, etc. for this use. It's annoying to "constexpr all the things" when you have to type out constexpr before "all the things" :-)

h3har avatar Jul 27 '22 05:07 h3har

const and let should be different. I think carbon should have both of them at the same time. const is a compile time constant and let is a runtime constant like Kotlin and Swift, but the specific content needs to be discussed

And why we need two kind of const? This add more complexity to language. In my opinion one kind of const is enough. Clear and easy please not again the 1000 crazy concept of c++.

Compile time programming is one of the few strengths of C++. It used to look really ugly when only posible via templates, but later on C++ has gotten constexpr to create logic that is compile time evaluated and then const. To my understanding at least, this seems like a necessary feature to have

  • runtime mutable
  • runtime immutable (const)
  • compile time evaluated

I'd prefer to introduce each var via let to be honest, and then have modifiers to it, such as let mut (mutable at runtime), let const (or however you'd prefer to name the modifier, to declare compile time const names.

So why let instead of var or val etc? I'm no native english, but to me it reads like a mathematical sentence, like let x = 4; aka. let x be four. - sounds pretty reasonable to me at least. :-)

Now, this wouldn't be ambiguous if the all kinds of names holding a value (of different kinds and storage) would be introduced the same (let) keyword but optionally appended with a modifier (such as mut or mutable or const, whatever is decided to). This sounds pretty uniform from my point of view.

christianparpart avatar Aug 01 '22 08:08 christianparpart

The original design of carbon language appears effective. The keyword const is provisionally in the carbon specification. There is good design in the original carbon language specifications. Further research would have to show why is let used, and can const replace let at the most rudimentary carbon levels of interpretation.

Kotlin uses val and var to differentiate between immutable and mutable. Kotlin is a beautiful transition from Java. Java programmers may still prefer to use Java with advanced programming patterns because Kotlin becomes somewhat hard to understand when advancing patterns.

Readability and simplicity are extremely important to capitalizing on what the coding world has learned from managed code. Easy to write and easily readable code that also increases productivity, favors staying with let in my opinion.

C language coders should understand what is happening at the assembly level. The use of the keyword let implies a different interpretation depending on context. I do not see any issues with using 'let' primarily and then adding const.

I don't personally find this very compelling. Many languages (let in Rust, let in Swift, val in Scala, val in Kotlin, etc.) use a brief three letter keyword for immutable local variables. I don't believe it is a barrier to readability in those languages - at least to anyone who has studied the language even a little bit.

I personally find "let x = y" to read beautifully, but maybe that's due to some of my more mathematical background. Obviously someone who works 99% with C++ and has never seen Carbon will understand "const" right out of the box, but is it really necessary to optimize for that? Spend even 10 minutes learning the basics, and most people won't struggle. Rust is not an easy language overall by any means, but this was definitely not one of the aspects I struggled with when learning it from previously having programmed almost exclusively C/C++.

As others have suggested, I like const more for compile-time constants, or some other stronger notion of "constness". This is the approach taken by Rust and Kotlin. This also avoids the need to resort to more lengthy keywords like comptime, constexpr, etc. for this use. It's annoying to "constexpr all the things" when you have to type out constexpr before "all the things" :-)

const and let should be different. I think carbon should have both of them at the same time. const is a compile time constant and let is a runtime constant like Kotlin and Swift, but the specific content needs to be discussed

And why we need two kind of const? This add more complexity to language. In my opinion one kind of const is enough. Clear and easy please not again the 1000 crazy concept of c++.

  • runtime mutable
  • runtime immutable (const)
  • compile time evaluated

I'd prefer to introduce each var via let to be honest, and then have modifiers to it, such as let mut (mutable at runtime), let const (or however you'd prefer to name the modifier, to declare compile time const names.

So why let instead of var or val etc? I'm no native english, but to me it reads like a mathematical sentence, like let x = 4; aka. let x be four. - sounds pretty reasonable to me at least. :-)

eeshvardasikcm avatar Oct 23 '22 23:10 eeshvardasikcm

The leads discussed this, and I want to be clear we appreciate the feedback and considered this carefully.

Ultimately, we would like to stick with the current design of let for now. There are a number of factors that lead in this direction:

  • The specific case where Carbon uses let is importantly different from one of the main meanings of const in C++ (const in C++ often refers to an access path and not to a declared immutable entity), and using const for this different construct already creates confusion in C++ and we expect the same or worse in Carbon.
    • For example, the let keyword covers an entire declaration, not just one type.
    • The semantics provided are in some ways even more powerful than what const could be used for even in C++, for example associated types in generic interfaces.
  • const in C++ means multiple different things, and it seems reasonable to separate those in Carbon, including with different keywords
    • We may need something that is more close to the common "access path" semantic from C++, and const seems more likely a good fit there.
  • While JavaScript/TypeScript are notable outliers, most languages using let follow a generally similar design direction for its semantics without issue.

chandlerc avatar Oct 24 '22 22:10 chandlerc