When I have same name for a closure, macro & a function then I see closure takes precedence over macro over function. I do not get any compilation errors. Wondering if this is expected behavior with crystal 1.0.0 & LLVM 10.0.0 and if yes then any documentation would be helpful to understand. I assumed my code should have thrown some compilation errors.
Last example, when same function is defined multiple times then the last definition is being considered while I would have expected a compilation error. For comparison, if a same variable name is re-declared (of same or different type) then I do get variable already declared error which is what I would have expected for function name as well.
Iām pretty sure all of these are working as expected. Something that may help the first and second example is that ()can be supplied to force the compiler to invoke the macro/method, otherwise itāll assume the value of the variable as youāve seen. However Iām not sure this is explicitly noted anywhere.
The last example kinda relates to Methods and instance variables - Crystal. I remember seeing an issue about raising an error when more than 1 function with the same signature is defined. However I canāt seem to find it :/.
Thanks @Blacksmoke16 , yes the ticket you referred would fix the function redefinition I have posted in my last example.
While your comment on using ā()ā for function works but still it is ambiguous IMHO. How would the user know if there was no closure or macro or variable by that name defined before? Else, users should be forced (via a compilation error) to always call a function with ā()ā, but I think this would not be liked by all.
Here function func() is never called. IMHO, there should be compilation error for all these cases of same name being used by macro, function, closure or variable, else developers are going to find hard time troubleshooting if they have a very large code base. The current working behavior also implies before declaring a variable, function, closure or macro, the developer has to do a full check if anything by that name already exists, as this would not be caught by the compiler.
I.e. the method func never gets a chance to be invoked anyway.
Only within the scope where the var/macro/method is defined. I.e. itās unlikely a dev in a large project would have a bunch of methods/macros/vars with the same name all in the same scope, e.g. the top level namespace.
I really like that one issue I linked earlier, but really the solution here is to just not have macros and methods with the same name in the same scope. Iām not so sure I agree with making that not possible because it shouldnāt be prevented to have the macro generate code that uses the method version of it.
EDIT: On second thought maybe it wouldnāt be that bad because it seems you cant even do that due to an infinite recursion errorā¦
PS: Can you please not include the line numbers in your code blocks. It makes it harder to just copy/paste and run them.
@Blacksmoke16 Sure, I thought line numbers was easy to refer to code, but got it, will not paste my code with line numbers going forward.
By the way, I am new to crystal world. So, is this (macro, function, closure & var names should not conflict with each other) something I should file as a feature request in github ?
Iād maybe wait until some other people see/respond to this thread. I think itās unclear on if thereās anything actually actionable here, or if there is, what could actually be done.
I canāt really say iāve experienced this problem (or heard anyone who did), so Iām under the impression that yes this may be a āproblemā, but not as much so in the real world.
How would you not know about the local variables in the current scope? Iām pretty sure this is the behaviour that almost anyone would expect. Itās the same in Ruby, btw.
I second to that. Iām not aware of anyone actually working on large code bases complaining about anything thatās described here as a theoretical āproblemā.
I think #10071 would be great to help avoid some mistakes, though. It should probably treat macros and methods alike.
But the differentiation between local variable and call is rarely an issue. Variables are usually scoped to a small section of code and you should be aware of them. If a single scope grows too big to be grasped, itās a strong sign that it should be refactored into smaller pieces.
As someone never used Ruby, I think I should keep in mind to check Ruby rules first if I have any doubts. Thanks for pointing that out and the answers.
Youāre welcome. And please continue pointing out things you donāt understand (or only understood after looking at Ruby docs)! We should have all that in our documentation.
Many of these things we (the current Crystal users) might take for granted because it works more or less the same as Ruby, so we probably forgot to document them.