Add binding keyword that prohibits shadowing / rebinding: val foo = "bar"
#1840
Replies: 6 comments 17 replies
-
Overall, I'm in favor of this addition as it reduces possible confusion when reading code: However, this slightly increases language complexity (one more keyword to know about) and increases project variability: there's no longer 'one way to do things'. See all the (pointless?) debates about |
Beta Was this translation helpful? Give feedback.
-
I find shadowing undesirable when working with nested folds. It is very easy to repeat a variable name ending up with unexpected results. e.g.
This is a simple example, but I have made some others (doing advent of code) where it not very obvious that you are making a mistake. In this case I wish the compiler would disallow shadowing. i.e. tell me that I cannot use |
Beta Was this translation helpful? Give feedback.
-
I forgot about
... and would result into clear signaling: If there is a |
Beta Was this translation helpful? Give feedback.
-
I don't think this is a good idea. It complicates the language for no good reason. I know some may think this could reduce confusion but I don't think that's true. There are two ways this could be implemented: 1- The distinction between 2- If someone declares a variable with I think till now Gleam has been able to maintain an incredible balance between simplicity and expressiveness and that's actually the main thing I love about it. I don't think the issue presented here is enough of a reason to disturb that simplicity. |
Beta Was this translation helpful? Give feedback.
-
Another approach, which is not backward compatible would be to have a sigil for variables that are shadowed or shadowable like $var or ~var or something along those lines. That would make it even more explicit that rebinding is taking place for a certain variable.
I would emphasize the value of making it easier to read other people's code and I would argue that this should be prioritized. It would be trivial for a developer who knows the code they are writing super well and knows that the language does not permit implicit rebinding (if that were the case) to add a dollar sign when shadowing (and given the simplicity of this, compiler errors are unlikely to be generated, unless you are unwittingly shadowing). Then, as we would have this as a compiler guarantee... for ever after, for all Gleam code, everywhere, it's just a bit easier for people already grappling with the complexities of other people's code to understand it, as the burden of tracking when something may or may not be rebound is on the compiler and not me, and its also made explicit. I appreciate that many people don't value being explicit about rebinding (not saying that was the intention of the comment above), and even more I realize that there are circumstances were it is quite handy to be able to rebind. But being explicit about rebinding gives the best (more or less) of both worlds, or it's a good compromise between no rebinding and full implicit rebinding. But for me and others who would prefer to have the compiler track that detail over doing it ourselves, having only full implicit rebinding is unfortunate. I realize this is a trade off in terms of the simplicity of the language, and having a tiny added learning overhead, and there would be a sacrifice in terms of backward compatibility. However, either we make that sacrifice or we sacrifice the advantage we would have of offloading to the compiler the burden of tracking rebinding. For me, the one time learning of the fact that i need to prefix a shadowing variable with something would by far be worth it if it makes reading all Gleam code everywhere a bit easier for all time. |
Beta Was this translation helpful? Give feedback.
-
@lpil Thanks for elaborating on your thinking on this. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Today when reading gleam-lang compiler Rust code I've encountered a binding that seemed to appear directly below in an interpolated string that was sprintf'ed. I was pretty confused at first why one can interpolate a non string variable. Then I realized the binding was shadowed.
I think readability and explicitness could be improved by adding a binding keyword that prohibits rebinding like
be
,final
, orfin
orval
.This enhancement would not affect current Gleam usage and allow future library and application developers to make their intentions clear by writing - say -
val foo ...
instead oflet foo ...
if their intention is to not rebind and have the compiler warn if they later dolet foo ...
orval foo ...
.Unlike mutateable languages (where I feel
const
vsfinal
vsval
vsvar
vslet
need a deeper understanding on what's going on) there is also no confusion:let
would signify a variable: binding mutable, value immutableval
would signify a value: binding immutable, value immutableBeta Was this translation helpful? Give feedback.
All reactions