-
-
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
Be precise about "arguments", "parameters", and "variables" #10374
Comments
Sounds good. However, I'm not sure about the particular first example:
This feels odd to me. It should be "default values for the last parameters". They're not arguments passed to the method. The parameters have a default value when the arguments are omitted. |
The default arguments are arguments provided at the method definition site rather than at the invocation site. I don't see why these expressions aren't arguments. |
They could be seen as arguments, yes. But the values are assigned at the parameter definition. To me it seems less confusing to just talk about values than to pick on the difference between parameters and arguments in this case. |
"default argument" is a weird turn of phrase. It's not incorrect, but "default value" feels so much more common. "default argument values for the last parameters" is probably the most technically accurate, but that feels a bit verbose. I think "value" and "argument" might be interchangable? |
So I tried to gather the reference manuals of a bunch of programming languages to see which terms they use:
"Default argument value" is redundant; the value (or the expression) is the argument. |
Though it's a bit wordy, I think "default parameter value" strikes a good balance between accuracy and understandability. |
Judging from those languages it seems Ruby's documentation is ironically the loosest one with regard to "arguments" and "parameters", though the Japanese reference is better (it also uses the Eiffel convention):
"If a default expression is supplied to a formal argument, it becomes that argument's default value when the actual argument is omitted in a method call." |
Slight preference for "Default value" for me. I can understand "default argument" as "argument that's being passed if nothing else is". But an argument is something that a user of the function actively passes, by writing it into parentheses, so to say. But here it's kind of always been there, you don't need to pass it. It's certainly not wrong, just sounds weird indeed. In Python, though... oh, this would definitely be wrong. Python has actual default values that just sit there attached to the function as a (mutable!) singleton. |
I noticed an incorrect usage use of arg/param terms in the parser’s source code too. I would suggest to update all variable names used to store param names and values from ‘arg_’ to ‘param_’. Examples:
|
For going all the way, we should probably also rename the |
I was thinking the same and I was also wandering if Crystal has aliases for keeping the backward compatibility. I can publish a PR for renaming the class. There are also a couple of struct fields that should be renamed. |
The reference manual and the compiler source use the terms "arguments", "parameters", and "variables" interchangeably, sometimes in a way inconsistent with most other programming languages. There is a clear distinction between the three terms: (quotes taken from Wikipedia)
We should follow the same terminology in Crystal to minimize chances of confusion. (The Eiffel convention of "formal arguments" and "actual arguments" seems rather verbose so I'll use the usual meanings.) An example in the reference manual is Default values and named arguments:
Another place of misuse is break:
Whereas in the source code, there is
#type_vars
, which represents all three concepts:Crystal::GenericType#type_vars
corresponds to the generic type parameters (T, N
forStaticArray
andT, R
forProc
);Crystal::GenericInstanceType#type_vars
is the one that really means variables (T => Int32, N => 4
forStaticArray(Int32, 4)
andT => Tuple(Int32, Bool), R => String
forProc(Int32, Bool, String)
);Crystal::Macros::TypeNode#type_vars
returns the parameters on an uninstantiated generic, but arguments on an instantiated generic (after splat collection):Crystal::Macros::Generic#type_vars
also corresponds to type arguments: (note that uninstantiated generics passed in the same manner result in aPath
instead)The docs changes are relatively easy, followed by compiler error messages and internal names in the compiler. Names that appear in the macro land are the hardest to replace, and require proper deprecation, but IMO we should do this in the future even if they don't make it for 1.0. For the particular case of
#type_vars
, perhaps we could:Crystal::GenericType#type_vars
to#type_params
;Crystal::Macros::Generic#type_vars
to#type_args
;Crystal::Macros::TypeNode#type_params
always return the generic type parameters, even on instantiated generics;Crystal::Macros::TypeNode#type_vars
not return anything on uninstantiated generics, or expose#type_args
here to return aHashLiteral
. (This would also allow us to remove the hacks inTuple.new
andSlice#[]
.)And
Crystal::Macros::Arg
should becomeParam
. This affects#class_name
directly and I don't know if a deprecation route is possible there.The text was updated successfully, but these errors were encountered: