Partial casing is simply the next logical step, IMHO. As our editors grow smarter and smarter they should allow us to present the code in the way we're most comfortable with. This means the freedom to render fooBar as foo_bar instead. What's necessary to accomplish this goal? fooBar has to be the same as foo_bar to begin with.
@Araq, the easy foreign-function interface is an important selling point of Nim, but the partial-casing causes problems. You seem to be the only person who thinks this is not problematic. Would you be willing to weigh the pros and cons again before 1.0? Maybe at least a compiler flag could turn it off.
I agree it causes problems, but having identifiers in existing libraries with same partial-cased names is very rare. (It might be a good idea to allow _XX and XX_)
Making partial-casing a compiler flag is a worse idea than disabling it (most existing code anyway won't compile with this flag).
@cdunn2001 > partial-casing causes problems.
Can you provide examples?
For the gtk related libs, I had initially indeed problems two years ago when Nimrod was fully style insensitive. But now with partial casing there are no problems, types like Buffer start with capital letter, and procs or templates are written buffer(). (Indeed it was not that easy, there where private C types with underscore like _buffer which are mapped to public types without underscore -- but I was able to solve that with text substitution scripts.)
If you can provide examples with real problems: I suggested long time ago to allow underscore as first or last character of an identifier and use that as the same time to indicate that this identifier is fully case sensitive. That is easy to implement and allows to fix ALL of the rare real problems.
That is easy to implement and allows to fix ALL of the rare real problems.
It doesn't fix the problem that I don't want to write _foo. Nim is not Python, it doesn't need ugly naming to indicate "that's private" or "that's a member" or whatever the distinction between _foo and foo should be.
The only time I got a problem so far is in Nim-Screeps. There I would need something like this:
type
StructureTypes = enum
STRUCTURE_SPAWN
STRUCTURE_TOWER
Structure = object of RootObj
structureType: StructureTypes
StructueSpawn = object of Structure
...
StructureTower = object of Structure
...
I solved such problems by naming the enum values "STRUCTURE_TYPE_xxx" which works but makes code different to the original examples.
So no unsolvable problem here.
I mostly think that there should be nothing like FooBar == FOOBAR or fooBar == foobar. I still don't like the whole concept and even if there is a point I would limit it to snake_case vs. camelCase equality and making underlines only optional in ALL_UPPERCASE or all_lower_case. Allowing leading and trailing _ would be very much appreciated too.
But I think that will not be changed anymore and made my peace with it. I also don't like "type" being a keyword as this always comes up in my code. But then. I can still code when I use another word and it is again mostly while interfacing stuff.
We generally do not have to write _foo. My suggestion was only for the few people who needs this feature, maybe to wrap an exotic lib without being willing to put much work in text mangling. That people can use full case sensitivity with underscores for VERY FEW identifiers and are happy. And we dont have to use their libs and we can have a style guide which says that one should try hard to avoid that style. I just remembered -- there may exist scientific libs that needs underscores and case sensitivity everywhere... May be very hard to rename all that properly, and may be hard for people coming from other languages and having used that libs for long time.
Personally I see some advantages in partial-casing -- so I do not have to remember if identifier is textView or textview. But of course disadvantages exists, for example not every text editor may be able to do style insensitive search.
As said, this all has been discussed already a lot, and maybe that is a good reason to honsetly reevaluate this topic, because a lot of people seem to dislike this feature. I do not like the style insensitve, and I don't think I ever will. But I can live with it for now, and I think when I am working longer in Nim I will write a linting tool that gives me a warning whenever I break case sensitive identifier equality (possibly with auto fixes). I already had a bug in OpenGl code, where I tried to pass the constant GL_INT to an opengl call not knowing that in the background this identifier was resolved as the type GLint. This bug did puzzle me a bit until I found out about cGL_INT. But of course this problem can also be addressed by better error messages, me reading error messages better, and better documentation on the nim opengl package.
Araq if you want to succeed with this language you need to realize how silly it is to have style insensitive name parsing.
It really isn't that big of a deal. Don't judge a book by its cover. Try the language and if you find some genuine problems with style insensitivity then report them. I am yet to hear of anyone who has written a significant portion of Nim refuse to use it because of style insensitivity.
It seems like most of the style insensitivity issues are to do with FFI to case sensitive languages like C, where library developers have relied on case to distinguish variables, rather than problems developing in native Nim itself.
In regard to aliasing, I often find myself wanting a shorter name as a direct reference to something without a copy. A small wrapper for the template declaration makes things a bit nicer, if you don't need parameters.
template alias(original, newName: untyped): untyped =
template newName: auto = original
# easier deep referencing
type
MyObj3 = object
data: string
MyObj2 = object
obj3: MyObj3
MyObj1 = object
obj2: MyObj2
var obj1: MyObj1
alias obj1.obj2.obj3.data, data
data = "Test"
assert obj1.obj2.obj3.data == "Test"
# replacing result
import strutils
proc starredWords(curStr: string): string =
alias result, words
words = ""
for s in curStr.split(' '):
alias "*" & s.strip.capitalizeAscii & "* ", starredWord
words &= starredWord
var sw = starredWords("hello I like teapots")
echo sw
# only allow alias template in block scope
template alias(original, newName, actions: untyped): untyped =
block:
template newName: auto = original
actions
var inputStr = "abc"
alias inputStr.toUpperAscii, t:
echo t # t is only defined here
EDIT: Back ticks are not needed in the alias template.
Thanks, interesting alias syntax!
Also, there's some nice syntax for aliasing over in the issue tracker over here:
https://github.com/nim-lang/Nim/issues/7090
Edit: Have also requested that this be added to the Nim Cookbook:
dom96
YES! There is a genuine problem with the underscore magic that allows different spelling of the same names: The problem is readability.
The also relaxed rules for referencing imports has exactly the same problem of readability.
To make it very clear, consider these two examples:
So there is a general design concept in Nim obviously, to make it more flexible to write but less concise to read. This will doom the language. As Python has shown so well, readability is very important.
I did read the FAQ which defends style insensivity on the basis that it is actually a convenience in the user's interest. It is not something like whitespace or brackets that users can just get used to. It is functionally more complex, and users are complaining about it.
Sometimes users are wrong Dom but sometimes an open source project fails to attract users by failing to respect their common sense.
A user is reading someone's code and wants to see all instances of a name. So they go using find in their editor and fail to pick up on all because some instances have underscores in their name.
There is an easy solution to this problem: case insensitive and style insensitive search (which is supported by nimgrep)
A user is reading someone elses code and has no idea what package certain functions are imported from come from because it does not say.
So this is referring to a completely different feature of Nim. Nim isn't Python, there are good reasons why Python's import rules will not work, mainly because of UFCS. Try writing Nim code with from module import nil and you will see what I mean. If you can come up with a solution to these problems then I am willing to evaluate making this modification.
But in all honesty, it's much too late for this. These are fundamental features of Nim, we can't change them now.
There is an easy solution to this problem: case insensitive and style insensitive search (which is supported by nimgrep)
Most people edit their code in an editor or IDE, not with an external program. And they don't like it when a language pushes another tool on them that, from their perspective, doesn't add value to their work flow. Most editors/IDEs can wrap their head around case insensitivity, but not Nim's identifier style insensitivity (ISI), at least not without some effort. That may be enough for a considerable number of devs to just dismiss the language before they can see its strengths.
Let's look at the two main benefits of ISI.
Programming style flexibility:
We want to be able to stick to our own identifier style in our own code modules while still being able to immediately use identifiers from other modules with other naming styles. ISI gives us that, but unfortunately it also gives us something else: the ability to use different styles for the same identifier in the same module. I suppose there are not many people who want that. As a matter of pure style, style flexibility would be better solved -- like "syntax skins" -- in editor plugins. As a technical requirement, a smart import statement with pattern-based aliasing would be better, more flexible and possibly even doable with metaprogramming.
Interfacing with the C language family:
Aforementioned pattern-based aliasing could be added to the importc and importcpp pragmas.
I had headeaches trying to find why my first opengl triangle looks like that
https://nsm09.casimages.com/img/2018/11/16//18111610551424237015998588.png
After two days I accidentally discovered that in a certain file (not all files) I can't do casting with my GLfloat type, which is a kind of alias I made for float32. The output says there is no "GLfloat()" procedure.
In the file I written that.
GL_FLOAT = 0x1406
Ha ha... I generally like Nims approach a lot - but I think that @Araq is too hard on this. The guiding rule should be "Nim prohibits false and dangerous things". Naming (e.g.) private variables '_foo is not dangerous and whether it's false is largely a "religious" question. Whether a user prefers CamelCase or snake_naming should be entirely his decision. A language has no solid basis to make quite arbitrary rules. Looking objectively, Araq's approach is confusing (e.g. for tools) and limiting both the set of available var names as well as the set of var naming classes.
Example: One might decide to snake_name procs or Types (with a capital 1st letter) but to CamelCase variables. And I do not see any solid reason for a language to limit the developers choice.
Finally, smartly guessing what the developer wants is one thing but to change what he writes is a different thing and a bad one. To turn e.g. '_foo into 'foo' behind the users back is tricky and creating problems instead of avoiding them.
Araq, you have made many very smart choices when to be strict to avoid problems and when to be lenient and to give us some comfort and luxury. The weird naming rules imo are the one bad exception. For a start nobody should force his opinion upon us. We respect yours but kindly don't get in our way without solid and objectively explainable good reason. Moreover the fact that this issue comes up again and again clearly demonstrates that your naming rules are confusing - which btw. also translates to "failing to win developers to have a closer look and use Nim". In fact, I've seen people call Nim an "exotic weirdo language" based on this issue.
Let us stick to the well working rule "we care about structure and correctness. Style is everyone's own choice". Yes, this sometimes leads to very ugly style choices but 'freedom' is more important than 'nice' and freedom should never be limited for the sake of 'nice' or -subjective- 'right'.
A compiler should digest what the developer wrote and complain only about real problems, not about your subjective personal opinion (no matter how reasonable you feel it to be).