I'm writing Nim every day recently; I haven't experienced it being noisy, but I also don't have extensive or recent experience with Python.
I'm on phone, so hopefully this paste doesn't look awful, but it's right from the website homepage
iterator oddNumbers[Idx, T](a: array[Idx, T]): T = for x in a: if x mod 2 == 1: yield x
The three different sets of brackets, the mixed : and =, it just seems inelegant to me.
I don't really know how I'd improve it, so it's just pointless, ignorant complaining on my part. Pay me little mind.
T = TypeVar("T")
def odd_numbers(a: list[T]) -> Iterator[T]:
# implementation
I don't really find that less verbose, in terms of brackets and symbols… T = TypeVar("T")
def odd_numbers(a: Iterable[T]) -> Iterator[T]:
yield from (n for n in a if n % 2 == 1) T = TypeVar("T")
def odd_numbers(nums: Iterable[T]) -> Iterator[T]:
for n in nums:
if n % 2 == 1:
yield n
Although yet another option is to just return the generator instead of immediately yielding from it: T = TypeVar("T")
def odd_numbers(nums: Iterable[T]) -> Iterator[T]:
return (n for n in a if n % 2 == 1)You import module X, which gets you objects as defined in the module Y. To use methods defined for that type, you need to import Y yourself. Python, of course, by virtue of binding objects to methods, doesn't need it.
There are some more namespacing quirks that may require one to give up on that sweet syntactic sugar to disambiguate things (two unrelated modules defining methods on a single type, with the same signature but different behaviors, and you need both modules imported for some reason?), but this is, again, something one would have to get used to. It's not a different world like Rust or Prolog.
It's not a complete showstopper, just something I keep bumping my head into now and then.
It's a good practice to re-export "all modules whose types appear in public symbols of the current module".
For that and other good advice, see The Status Nim style guide:
https://status-im.github.io/nim-style-guide/03_language.html...
The one thing that stuck out to me like a sore thumb is the camelCase convention. I know it's a minor thing (and a personal preference), but I'm a bit biased against languages that use camelCase (Java, JavaScript, etc). There's something uneasy about it IMHO.
https://nim-lang.github.io/Nim/manual.html#lexical-analysis-...
my_foo, myfoo, and myFoo are interchangeable. MyFoo is different because the first letter is capitalized.
If it's not clear, what I mean is that if you've imported a module that exports myFoo, you can refer to it in your code as my_foo, if you prefer.
Some people love this aspect of Nim, others loathe it. I don't have strong feelings about it, though one has to be mindful of it when searching through a codebase with e.g. the_silver_searcher.
Strong convention is much better than pleasure of everyone.
That's unfounded, please try it at least once in the playground play.nim-lang.org/. To me it's very cool that wrapped C libs with identifiers like ATOMIC_RELEASE can be written as AtomicRelease without any trouble.
If my codebase enforces camelCase and a library uses snake_case, then I can still use that library using camelCase, and Nim has nimgrep to make this easier all the way.
So you oppose languages supporting both recursion and iteration?
For example, here's how you can iterate over a list in scala to print each element:
List(1, 2, 3).foreach(element => println(element))
List(1, 2, 3) foreach { element => println(element) }
List(1, 2, 3).foreach(println(_))
List(1, 2, 3).foreach { println(_) }
List(1, 2, 3).foreach { println _ }
List(1, 2, 3).foreach(println)
List(1, 2, 3) foreach (println)
List(1, 2, 3) foreach { println }
List(1, 2, 3) foreach println x = 2 + 3
x = 3 + 2
x = (2 + 3)
x = (3 + 2)
x = 2; x += 3
x = 3; x += 2
x = 2; x = x + 3
x = 3; x = x + 2Recursion and inheritance are interchangeable (in fact, either can be implemented as syntax sugar over the other); while some people find one or the other more natural for a particular problem, there is considerable disagreement among people over which is more natural for which problems. In practice people choose between them based on personal preference and what the language they are using favors (e.g., you probably [0] don’t use recursion unless it is of fairly tightly bounded depth in a language like Python that doesn’t optimize tail calls.
> Language syntax is different; it's an opinion of the language designer which gives the language its distinctive style, and IMO shouldn't have much leeway in expressing the same thing in multiple ways.
As noted, recursion vs. iteration is exactly a syntax-preference decision, and one on which some languages are highly opinionated (Python) forming an important part of their distinctive style, while others are not.
[0] though you could use a tail call optimization decorator
Did you mean Recursion and Iteration?
Some recursion could be translated into iteration only if there is stack managed by hands. It decreases readability significantly.
Simplest example: Ackermann function.
And it works both way: some algorithms are better read as iteration.
God, that's horrible.
I'm confused, two of those are myFoo, so I hope they are interchangeable!
It's very strange at first, and I had the same reaction as you, but it's actually quite nice. (I say that as somebody who strongly dislikes snake_case :) )
Or do you just mean use a mixture just like you could in most other languages?
Instead, you can import and use libraries that use a different stile without breaking your convention.
Thanks for telling me about it, I hadn't taken it seriously before.
I wonder if there is sufficient interest in having a python stdlib compatible library for nim.
That’s fine, I can use other languages and it doesn’t take anything away from Rust or the people who love the syntax.
I find a lot of Nim syntax just unnecessarily noisy. I wish that it had stuck much closer to Python syntax.
I'm really excited about Nim, don't get me wrong. I like Araq, he's got a real hacker spirit not oft found at the head of big projects.
Anyhow. I'm sure the experts in that topic will sort it all out. ORC is wildly impressive all around.