The actual behavior is to enforce the first character capitalization on Object names (uppercase) and methods (lowercase or _
).
For example:
class A_b ; end #=> OK
class ab ; end #=> expecting token 'CONST', not 'ab'
def yEaH ;end #=> OK
def YeAh ;end #=> unexpected token: ;
For variables and constants, the first letter matter:
MYCONST
is a constant
myvar
is a variable
But...
aBC
is a variable
_BC
is a variable
Abc
is a constant
However the standard Crystal way is Object names in Camel Case, method/variable names in snake case and all uppercase for constants.
What do you think of enforcing this styles, that are already standard?
I think it's strange to only take into account the first letter.
All uppercase object names should be allowed, if nothing else to allow using abbreviations as class names.
Enforcing styles isn't nice. It's better to have a style guide and recommend to follow it, and sometimes its valid to break out of the rules.
The main point here is why enforcing only the first character capitalization? Either we enforce a style for names, or no style at all to let people choosing their styles.
What are the benefits of this?
We had a very strict rule for lib function names. Then we had to introduce fun name aliases to workaround it, and then we finally allowed fun names to start with uppercase letters and also calls.
If anything, I'd like to loosen up some of the restrictions (though the first letter rule won't change for classes and constants, I think).
Please let's not enforce more rules if they don't provide a real benefit. Some people have other conventions, they come from other languages. It would be bad if, when learning the language, the compiler complained because they don't follow one style. Imagine how annoying it would be if they wanted to write some code, but the compiler complained that for purely style reasons, when they are just learning some relevant rules. Once they learn the language and when and if they want to contribute to other projects, they will probably have to follow some style. But forcing it upfront, and making that an error, is not good.
If it's not broken, don't change it.
Rust, Go, Python and more languages hasn't strict restrictions.
@asterite the compiler already complains about _purely style reasons_, if I come from Go:
def Println
end
# => Syntax error in a:1: unexpected token: NEWLINE
Actually Crystal has similar restrictions like Ruby. I don't have heard much complaints from newcomers about the style anyway.
If we don't want to enforce a style, thus logically the first letter style restriction has to be removed, of course except if this restrictions is required for the compiler.
Either choice is fine to me.
@j8r I personally wouldn't mind removing all name restrictions.
There's a small problem, though, and that is that you can do:
Foo(Int32*)
Foo(Int8[10])
And you can't write:
Foo(x + 1)
That is, the compiler considers something that starts with uppercase as a type, and parentheses means it's a generic instantiation, and only types (following the type grammar), not expressions, must follow.
Then what happens with:
def Foo(x)
end
class Foo(x)
end
Foo(Int32) # ?
I guess methods and types will now have to start sharing a same namespace...
We could try to change the language to allow mixed case for types, methods and constants. It will make the implementation a bit harder, but I wouldn't mind it (though I have no idea how I would implement it, so that means I at least won't do it, also because I think it's not a big deal).
What I wouldn't like is to make the language stricter for just visual reasons.
"Actually Crystal has similar restrictions like Ruby"
Similar, but not identical. Ruby has support for uppercase methods:
irb(main):001:0> def Foo
irb(main):002:1> puts 'hi'
irb(main):003:1> end
=> :Foo
irb(main):004:0> Foo
NameError: uninitialized constant Foo
from (irb):4
from /home/linus/.rubies/ruby-2.4.1/bin/irb:11:in `<main>'
irb(main):005:0> Foo()
hi
=> nil
irb(main):006:0>
though they have usually not been used, except for a few factory methods like Integer()
This is not an argument for or against, just pointing out a difference.
@j8r Go actually has a naming restriction about names of private/public package members. And it's purely functional since it defines the visibility of a member by the case of the name's first letter. I, as well as many other people, have never felt uncomfortable about that and find it extremely handy for code readers who always can see the visibility of a variable/function/type without jumping to its definition.
@yxhuvud That's true, but it's inconsistent:
$ irb
irb(main):001:0> class Foo
irb(main):002:1> end
=> nil
irb(main):003:0> def Foo
irb(main):004:1> "the method"
irb(main):005:1> end
=> :Foo
irb(main):006:0> Foo
=> Foo
irb(main):007:0> Foo()
=> "the method"
Ruby says you can omit parentheses from calls... except when the name is uppercase, and there's a class named like that. Well, that except is an exception to the rules, and that's why I think we shouldn't copy that.
I think the consensus here so far is that we don't want to do this. I vote to close this.
Most helpful comment
What are the benefits of this?
We had a very strict rule for lib function names. Then we had to introduce fun name aliases to workaround it, and then we finally allowed fun names to start with uppercase letters and also calls.
If anything, I'd like to loosen up some of the restrictions (though the first letter rule won't change for classes and constants, I think).
Please let's not enforce more rules if they don't provide a real benefit. Some people have other conventions, they come from other languages. It would be bad if, when learning the language, the compiler complained because they don't follow one style. Imagine how annoying it would be if they wanted to write some code, but the compiler complained that for purely style reasons, when they are just learning some relevant rules. Once they learn the language and when and if they want to contribute to other projects, they will probably have to follow some style. But forcing it upfront, and making that an error, is not good.
If it's not broken, don't change it.