I played with Nim a little bit, loving it for a while, and I quickly ran into the same issue I had with Julia, which was that I had trouble staying in the basic language. Both Nim and Julia's documentation, and many modules/imports/includes/whatever of those languages, immediately jump to "holy shit we have macros! Importing this module changes the syntax! Isn't that awesome?!" And I'm like, no, it's not awesome. New syntax, new syntactic sugar, etc. is a learning curve every time for me. I'm often skeptical of operator overloading in C++ and python, so macro crazy languages are even worse. I feel like I must be in the minority, or I haven't hit that programming nirvana.
Yes! I'm constantly seeing people enthuse about how awesome macros are, and done well they're great, but I don't want every library I use to have a whole new set of syntax.
While I don't claim to have a comprehensive numbers, I did a quick `rg` on a full clone of nimble package list, and found that macros constitute approximately 0.4% of all definitions (functions, procedures, templates, methods).
proc: 401673
macro: 1869
template: 16255
func: 8746
converter: 3538
iterator: 1833
method: 9025
You would be surprised how much can be accomplished just using simpler language constructs - even for the complex operations. Manual for example advises to use the least powerful construct for the job https://nim-lang.org/docs/manual.html#macros-caseminusof-mac... > Style note: For code readability, it is the best idea to use the least powerful programming construct that still suffices. So the "check list" is:
> Use an ordinary proc/iterator, if possible.
> Else: Use a generic proc/iterator, if possible.
> Else: Use a template, if possible.
> Else: Use a macro.
Also - notable portion of the commonly used macros is for embedded DSLs that in other languages would require you to use a separate build step with some external tool, or give way to horrible clutches like operator overloading-based DSL.Note that I did the full clone several months back, and it is missing around two hundred packages that were added in this time, but I doubt it changes numbers greatly.
While that may be true, my experience was that you immediately see folks assuming you're using the 'sugar' macros, and then I went to do something with JSON and that was macros as well. Honestly curious, while .4% of all definitions are macros, how many things are using those macros? That's probably hard to tell, but I feel like that would be closer to representing the need for learning all the macros. I hear you, though, that I might have been nearing the end of the steep part of the learning curve.
Anyway, since Nim has user-defined new operators, using those might also bother some. E.g., there could be a proc `=>` meaning something very different from that sugar module macro of the same name. Really, these work just like other procs modularity-wise. The syntax/grammar does not actually change, though. It's just flexible in the first place.
These complaints sound more like excuses to me. Every language has calls, styles, idioms, etc. you need to learn as a client of whatever it is you're calling/doing. And every language has quirky syntax corners. E.g., many are unaware that C lets you say "(a,b,c,d)" { which evaluates but ignores the result of "a,b,c" }. Yet you still often hear people proclaim how simple C syntax is. "Compared to what?", I guess (e.g. C++).
I do get where you are coming from "overloading"-wise - not just operators, but also regular procs (which in Nim are the same...there is just a proc `<`). When learning an alien language/code-base/libraries it really helps to have jump-to-definition. Nim via nimsuggest has great support for this if you configure your editor (vim, emacs, VisualStudio Code, etc.). You may have skipped that step but might love it more if you did it next time. nimsuggest can be aware of local and global --path modifications and the type context of the jump-to-definition. So, it can do a much better job than, say, ctags. (and yes, nimsuggest works for all the various definition types like macros, templates, etc., even the ones named like an operator such as `<`).