5 ms·
Nim has made 4 syntax choices that might seem bizarre to a C++ programmer: 1. blocks by indentation instead of braces (aka "Off-Side Rule" syntax [0]); 2. Unifo
by jboy 11y ago
Nim has made 4 syntax choices that might seem bizarre to a C++ programmer: 1. blocks by indentation instead of braces (aka "Off-Side Rule" syntax [0]); 2. Uniform Function Call Syntax [1][2]; 3. case-insensitivity for identifiers; and 4. dropping empty parens from a function call.
[0] https://en.wikipedia.org/wiki/Off-side_rule https://en.wikipedia.org/wiki/Off-side_rule , [1] https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax , [2] http://nim-lang.org/docs/manual.html#procedures-method-call-syntax http://nim-lang.org/docs/manual.html#procedures-method-call-...
Choice #2, Uniform Function Call Syntax (UFCS), allows you to write `a.someFunc(b)` or `someFunc(a, b)` interchangeably.
Choice #3 is case-insensitivity for identifiers: You can write `a.to_lower()`, `a.toLower()` or `a.tolower()` interchangeably.
Choice #4 is the ability to drop empty parens from the end of a function call: `a.len()` can be written as `a.len`. Combined with UFCS, this allows you to write `len(a)`, `a.len()` or `a.len` interchangeably.
I'd already been programming Python for years, so I wasn't surprised by choice #1 -- in fact, I was pleased. After initially being highly skeptical of Python's OSR syntax when I first encountered it, I've since come around completely. The most common complaint against Python's OSR syntax is that it allows both tabs & spaces, interchangeably, which has bitten just about everyone who has ever used Python in a team. Nim avoids this problem by allowing only spaces to be used for indentation, not tabs: http://nim-lang.org/docs/manual.html#lexical-analysis-indentation http://nim-lang.org/docs/manual.html#lexical-analysis-indent...
My eyebrows certainly went up about #2, #3 and #4 when I first encountered them. But you know what? Much like Python's OSR syntax, I've now come around completely. Now I actually prefer #2, #3 and #4 the way Nim does them. When I'm back in Python, C++ or C, I wish they behaved the same way as Nim!
Think about it: How many stylistic debates have there been about whether an operation in C++ should be a function or a method? How many times have you pondered whether an object attribute should be a member or a method? It's just a distracting detail with no benefit. And now you don't need to care! Apparently Bjarne Stroustrup is a convert to UFCS too: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4174.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n417...
Nim is, above all, a pragmatic language. I think that in another 5 or so years, Nim's syntax choices #2, #3 and #4 will seem just as sensible as #1 seems to Python programmers today.
- stewbrew 11y ago> Choice #3 is case-insensitivity for identifiers: You can write `a.to_lower()`, `a.toLower()` or `a.tolower()` interchangeably. This looks like an enjoyable source for weird bugs: Write to functions with similar names (e.g., to_me() and tome()) and be surprised when nim doesn't distinguish between these two.
- jboy 11y agoIf your functions take any parameters, Nim will use the parameter types to distinguish between them, just like C++ does when you overload functions. OTOH, if your hypothetical is that programmer X writes `to_me()` while a different programmer Y writes `tome()`, and the two functions just happen to be identical in all parameter types... well, that can already happen anyway where two programmers each independently write a function with the same name. Nim has a simple, clear specification of how identifiers will be compared: http://nim-lang.org/docs/strutils.html#normalize,string http://nim-lang.org/docs/strutils.html#normalize,string There's no secret magic happening.
- lomnakkus 11y agoIt's doubtful that "convert it to lower case" (as documented for the function you pointed to) actually means anything in this day and age, what with Unicode and all... Though, looking at the code for "normalize" it appears to only support ASCII. That's even worse since now "lowercase" doesn't even apply uniformly if your identifiers have non-ASCII characters in them[0]. Doing a general normalization (as in Unicode) would probably also be bad, but for different reasons: You probably don't want the validity of programs to depend on the current locale of the machine you're compiling on. (See e.g. the "Turkish I" problem.) In short: Case-insensitive identifiers[1] are a terrible, terrible idea. [0] Not generally a good idea, but it happens and there are legitimate cases for it. [1] Or, rather, "doing anything non-trivial to identifiers before lookup", I suppose.
- federico3 11y ago> This looks like an enjoyable source for weird bugs It's meant to prevent them: in Python applications it's not uncommon to see bugs introduced by an incorrect completion, e.g. updatePlayerstatus / updatePlayerStatus / update_player_status With case/underscore insensitivity you know in advance that there can be only one "updateplayerstatus" in your codebase and write it according to your style, e.g. always update_player_status