-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Voluntary, scoped, "explicit"/"strict" modes (constraints and demands on code) #900
Comments
One thing I'd like to note is that "this would not affect anyone who doesn't touch the constraint directives" is never true, no matter what the language feature is. If person A decides to use it but then person B wants to collaborate with A, B needs to learn the feature to understand the code. And B will probably want to follow A's style. |
This reminds me of two things I'd like to see:
|
@asterite - of course you're right about that. Project owners dictates style. I reckon above 'hardening directives' would be in hard core central code, though, so anyone getting in to that is probably prepared to cope with a few additional rules. Macros is by far the greatest leap in making a language 'need to figure stuff out and learn more all the time', past that, I don't really see anything that can make it harder in that respect. For instance, I had an impossibly hard time figuring out where 'parse_or' was in the compiler until I was pointed to the macro via IRC ;-) @kirbyfan64 - Use an uppercase letter as initial for a symbol you assign to: voila, constant. |
Having debugged scores of subtle issues that boil down to typing mistakes in variable names (several that involve conditionally resetting a variable to a predetermined value), I have always felt that "declare before use" would be a great boon. I am, of course, talking about experiences with Ruby. Crystal being a compiled language, it makes even more sense to have that rule. On the smaller matter of syntax, I first encountered " |
Yeah, @js-ojus, if type annotation was to be unified (see #758), it would be very natural, (if assignment was parsed after type annotation [seems more natural]):
Still though - I think the requirement should just be when "explicitly demanded" for the scope (be it |
As recently as last week, I was stumped by this "declaration" problem yet again. In a current project, I encountered a puzzling compilation error when running tests. It was something like (I do not remember the exact message):
pointing to a line in some method in the struct and a constructor. I checked the constructors, and could not find any problem. After a few confused minutes, I realised that the name I declared there was Life would have been uneventfully simple if the compiler just said However, since declaration is not mandatory, the compiler possibly goes through a complicated process of scope hierarchy lookups upon encountering a new variable. Finally, its error message is technically correct but practically unhelpful. I urge @asterite and team - yet again - to consider introducing mandatory declaration of variables, with |
I don't think will ever make variable declarations mandatory. That's what makes dynamic languages nice to work with: "Need a variable? Just assign it a value". The philosophy change in the language will be huge, and we wouldn't want that. So I'm closing this. |
Something like TypeScript would be useful. |
Having variable types be specified at assignment is pretty pointless as we have flow typing, for example: foo : Int32? = self.foo
foo : String = "fail" unless foo
# what type is foo here? It's not any of the ones specified above. If you want to know what type your variables are all the time without having to think, use another language. Or write an ide to tell you the types, I know which I'd rather have. |
I was hacking around in the lexer a bit for fun, refactored a bit, and had some errors that showed up some times, aka "slightly harder to debug than consistent ones".
In this case local vars keeps states over several screen pages in this long function. Refactoring gives no error because assigning to a symbol declares and allocate the variable.
The implicit allocation is a very nice feature in prototyping, script-style one-off programs, and shorter methods (which they should be, but reality...), which is one of those things that attract me to Crystal. In longer and/or more complex scenarios however, a bit of voluntary compile time protection is essential to remain efficient.
My proposal is something similar to "use strict mode" in some (semi) dynamic languages.
Some voluntary constraints that come to mind, with loose syntactic ideas:
my_var : _
my_var := 47
or similar could be used for tersenesslet my_var = 47
for explicitly immutable (with "immutable by default", this would be equivalent to prior example, then some syntax to explicitly make vars mutable would be needed [perhapsmut
like in rust, or an assign-modifier])The single one I find most important is the "require variable declaration" directive.
[ed: update:] And even more important: "require instance variable declaration".
I realize that this will complicate parsing a bit, making it more conditional, especially if many different combinations are allowed, and immutable must be introduced conceptually in semantics (strings are though, but only the value I guess?). The different constraints could be distilled to fewer parsing/constraint directives to simplify a bit.
And, I repeat, for those cringing: this would not affect anyone who doesn't touch the constraint directives, it would only be a help for writing more secure applications for those who find it useful to express their intentions a bit more verbose in order to get help from the compiler catching potential bugs earlier.
The text was updated successfully, but these errors were encountered: