#How to tell Mojo that something is intended to be constant?

70 messages · Page 1 of 1 (latest)

gaunt roost
#

In mojo 24.1.0 (55ec12d6) I get a new warning:

'let' is being removed, please use 'var' instead

I think it is good practice to make explicity my intention that something is constant. How to I do that (in the future) since let is deprecated?

flint copper
gaunt roost
#

Of course I know of the existence of alias, it is just that there is a very large semantic difference between var x = 8 and let x = 8, namely that it is my intention (the programmer) that a variable (not a compile constant) is constant, how are my colleagues to know my intentions if i cannot make that explicit? What were the reasons for removing this?

flint copper
sharp crownBOT
#

Congrats @flint copper, you just advanced to level 1!

gaunt roost
#

I did not comment on the proposal when it was made, but now that it has been executed, I'm interested in the 'official' reason let will be removed.

#

Because now I cannot tell that something is intended to be constant, which is, for me, a very important concept.

supple barn
#

well, atleast from how I see it, this becomes the same argument as when I proposed private struct fields. The effect you need can be made with changing naming scheme, though the compiler will not recognize it officially. The same way I can say _data is a private field, although not enforced, you can say var DATA is a constant, hence the naming scheme

gaunt roost
#

@supple barn you mean that by naming a variable with eg capitals we can communicate that it is not intended to be changed, but the compiler will not enforce it (anymore). Similar, that all fields are public, but by naming it differently my colleagues can know that it should not be used.

supple barn
#

correct

#

you can imply behavior without it being enforced, which i believe is intended

#

i personally am not sure I agree with this, but i see both sides of the arguments

gaunt roost
#

Thus, our ability to write bug free code is sacrificed for ...., i hope it is something important...

eternal peak
#

A workaround is to create a function. In a function signature, it's possible to declare that an input value can't be mutated. And it works with references too.

supple barn
#

along with this, I can think of few cases where I 1. don’t know the value or the function to get the value, and 2. need it to be immutable during runtime. I’m not saying there aren’t any, there are, i’m just saying alias can and should be used wherever possible, and i believe that is what that change is trying to emphasize

#

plus there are some other issues with let/var being used with pointer/referencd

#

since semantically you aren’t changing the pointer, rather the value it points to, if given the choice it can be ambiguous for new developers to choose let or var for that use case

#

whereas alias is a little more imperative that the pointer itself is immutable while its underlying data may not be

#

^something that reference improves on even more, explicitly saying if it’s a mutable or immutable reference

hushed dock
hushed dock
sharp crownBOT
#

Congrats @cinder pasture, you just advanced to level 1!

gaunt roost
#

I want Mojo to do well because it gives us access to top-notch MLIR lowering capabilities (translation: it compiles to speedy code).

For Mojo to succeed, the company Modular is creating a product called Max (written in Mojo) aimed at companies with highly profitable but complicated AI technology setups. And anyone who's dealt with such setups knows what a complete and total nightmare they can be.

So, Modular, help us out (for us programmers' sake). How do we convince others (meaning management, who aren't keen on changing a highly profitable AI stack) that Mojo is a solid language? What does not quite helps is that it lacks basic Encapsulation (no private member fields) and has dropped Immutability. But that's okay if there are solid reasons behind it. Arguments like "it makes the compiler tricky" or "it's tough for new hires to grasp const int * const foo" just won't cut it. Even more challenging is how to persuade that Mojo can match Rust's capabilities without these fundamentals.

hushed dock
#

I think every company should use what they feel is the best tool for their job. If all these features are important then Rust is the obvious choice.
For people having problems Mojo is intended to solve, these things are a non-factor. I'm talking AI Researchers, Python developers, and C/C++ devs writing extensions for Python.

lost goblet
gaunt roost
#

@lost goblet Yes, and forgetting a const where it should have been is an error because it signals that something is allowed to be changed, and someday someone will change it, not knowing that it was intended to be immutable. For a compiler this is trivial to check, and absurd that it is dropped from a otherwise sound language.

lost goblet
gaunt roost
#

Yes, agreed. I would have been happier that due to some weird regression Immutability would not have been enforceable anymore, while we kept a well established convention to convey our intent to future programmers.

gaunt roost
hushed dock
lost goblet
# hushed dock Interesting. I thought Rust

It goes way back. Dijkstra, for instance, does much of his work (proving the correctness of programs) without touching a computer or having a compiler at all. A Discipline of Programming is a must read, if you are interested in "bug-free code".

#

OCaml, which Rust was originally implemented in and got many of the good ideas from, was invented to implement Coq (a proof assistant). So you can kinda see Rust's lineage. The Software Foundations series is also an interesting read (uses Coq).

cursive hamlet
#

I was initially opposed to the removal of let, but I've since warmed up to it.

As a language feature, let basically does nothing. It has no influence on the runtime behaviour of a program. It's essentially just a #comment on steroids. (Albeit, a useful comment.)

It's weird to have a language feature that does nothing, especially when you have to teach everyone about this nothingness. So I can sympathize with its removal, even if I have historically been a fan of immutability.

As a "fancy comment", let has two main utilities:

  • It allows a programmer to signal that they don't intend for a variable's value to change.
  • It allows the compiler to alert the programmer that the program is not consistent with this intention.

There's no particular reason why this intention needs to manifest as a keyword. I suspect 90% of the benefit can be achieved just by using an IDE that colors variables differently depending on whether they are mutated at some point. If you accidentally mutate a variable, its color will change. Most of the time you'll notice this, and stop and think whether you've make a mistake. (Assuming you read your code before committing it!)

hushed dock
#

I think the problem of mutable variables is superficial, Mojo still enforces mutability in the important places. Namely, there can not be more than one owner, and there can't be two immutable borrows.

gaunt roost
#

@cursive hamlet

There's no particular reason why this intention needs to manifest as a keyword. I suspect 90% of the benefit can be achieved just by using an IDE that colors variables differently depending on whether they are mutated at some point.
Which brings me back to my question, how do I do that in Mojo? 1. How do I setup a warning that something is changed that should not be changed. 2. And how do I make such warning system explicit (read a new keyword) such that I can read that I made my intent clear. If i cannot do that i will consider "moving on".

cursive hamlet
#

I’m not here to convince you to use Mojo, so you’re always free to move on

lost goblet
lost goblet
gaunt roost
#

@Nick! you are just trolling, I want Mojo to be successful, but that is difficult if the basics are dropped without good reasons. If a language can be changed without good reasons, what are we doing here.

sharp crownBOT
#

Congrats @gaunt roost, you just advanced to level 5!

cursive hamlet
#

@lost goblet I just think the "moving on" comment sounded like it was imposing an obligation on me (or somebody else in this thread) to provide a satisfying answer to OP, which is a bit unfair, because I'm just a random person on the internet trying to provide some helpful information.

#

Immutability is one basic form of proof carrying code.

This is not something that needs to be part of the type system though, because it is a trivial property. A local variable is "immutable" iff you didn't mutate it.

#

A keyword doesn't make the lack of mutation any more official

lost goblet
gaunt roost
#

We and a lot of others are here to invest their personal time (on a Saturday), knowing that someday the need to convince others (read management) that Mojo makes sense, and that is hampered by big decisions that I cannot explain. Thus a nice explanation would be in order.

cursive hamlet
#

What about enforcing no uninitiated variable?

The type system needs to enforce that variables are initialized before use because that is required for soundness. Reading an uninitialized variable at runtime would cause undefined behaviour.

In contrast, reading a variable that has been mutated always yields defined behaviour. So let doesn't have the same level of importance/utility as requiring initialization.

lost goblet
cursive hamlet
#

No. The compiler needs to enforce initialization because that is required for memory safety. In contrast, immutability is not required to ensure memory safety.

sharp crownBOT
#

Congrats @cursive hamlet, you just advanced to level 6!

cursive hamlet
#

Or put another way: it is always wrong to use an uninitialized variable, but it is basically always correct to use a mutated variable

lost goblet
#

For a system without unmovable type, moving them would be wrong, e.g.

#

I don't think we will see eye to eye on this matter. Nice knowing your position, and having this conversation. Let's move on, though.

cursive hamlet
#

sure

gaunt roost
#

Now that Immutability checks are moved to some next round of analysis, e.g., "mojo analyze main" which will be allowed to spend hours of analyzing my complicated code littered with "lets". How do we tell such future analyzer that I intended to have something Immutable?

cursive hamlet
#

@gaunt roost Regarding your last comments, I am always trying to challenge my beliefs and take on new persectives as I learn new languages and develop as a programmer. Up until a few years ago, I was a major proponent of immutability and whatnot, but now I am more on the fence. Sometimes general principles (e.g. "immutability is better") don't hold up in all situations, so it's worth reflecting on each particular issue and trying to gauge just how important it is for a principle to be upheld in that setting.

At the end of the day, what matters is whether programmers are actually going to be negatively affected in any shape or form by not having a keyword for local variable immutability. And while I agree with most people in this thread that it feels comforting to declare a variable as immutable, it's quite possible that this comforting feeling is just a result of my prior exposure to programming cultures wherein people tended to praise immutability quite heavily.

So personally, I'm going to give Modular the benefit of the doubt (they have a lot of experience with programming languages), and see what a var-only world feels like. Will I ever encounter a bug that could have been prevented via a judicious use of let? I'm not actually sure. But I will find out with experience.

lost goblet
# cursive hamlet sure

Don't get me wrong. I do find you pointing out "it does nothing" interesting. Maybe I've taken immutability for granted for the wrong reasons.

gaunt roost
#

I have some issues with not declaring Immutability when people do not understand what that means (but that is a different problem). So, not using it when it's available is what I (and I suppose Sora) are contemplating. It is worth the experiment. However, Immutability has been a vital tool when sorting out dodgy quality C++ code over the past decade. I'm not sure any of those efforts would have worked without it. In an ideal world where code is clear and easy to understand, Immutability might not make much of a difference to ensuring correctness. But that's not the world I'm stuck in (unfortunately). When working in teams of programmers, I need a means to implement it, and I don't see any other way to enforce it.

#

I treat Mojo a programming framework for real world problems, and teams of programmers are part of the real world, as is layers of management...

willow moth
#

Okay so it aint crystal clear to me yet... but wasn't "let" one of the reasons why mojo was faster and better and more secure than python? And instead of removing it.. why not keep it optional?

fast jungle
# willow moth Okay so it aint crystal clear to me yet... but wasn't "let" one of the reasons w...

The proposal to remove 'let' says no one is aware of any performance implications of the change. You may be thinking of defaulting to passing by immutable reference (borrow) which does have large performance benefits and remains a key feature of the language.

GitHub

The Mojo Programming Language. Contribute to modularml/mojo development by creating an account on GitHub.

primal prawn
#

This may be impractical or undesirable, but could a future compiler track mutations made to SCREAMING_SNAKE_CASE variables and emit a warning? (As typically this naming scheme is used for constants in Python)

gaunt roost
# primal prawn This may be impractical or undesirable, but could a future compiler track mutati...

Ironically, we have that (approx.) at the moment. We can say

let START_TIME_NS = now()
# do lots of stuff, by other
let ELAPSED_TIME_NS = now() - START_TIME_NS
# however; in the future, we are not sure that START_TIME_NS has been
# mutated, and we may need to check that after every commit...

If we could switch on/off the semantics of keyword "let" such some don't need to understand what it does, while others can use it because they value their time.

hushed dock
#

It does not require a special language construct but Mojo has aliases

#

But this constant doesn't seem to be what people are mooning over.

final bay