[HN Gopher] Nim 2.0 thoughts
___________________________________________________________________
Nim 2.0 thoughts
Author : michaelsbradley
Score : 191 points
Date : 2021-05-15 14:08 UTC (8 hours ago)
(HTM) web link (forum.nim-lang.org)
(TXT) w3m dump (forum.nim-lang.org)
| sergiotapia wrote:
| The restructuring of the system namespaces come as a very welcome
| addition. --threads:on by default is awesome too!
|
| I love this language so much, I am so happy to see this much
| momentum coming from Araq and the gang. They are very kind people
| that help you in the Discord server.
|
| For all the help I've been given for free time and time again by
| these guys, I'm working on a series of exercises to hopefully
| minimize the onboarding time for people looking to explore Nim.
| https://github.com/sergiotapia/nimlings
| Jorge1o1 wrote:
| I think you should include "thoughts" (as it says in the forum
| post) in the title or in some way disclose that this is just a
| design/planning/brainstorming session for Nim 2.0 and not
| actually a major new release.
| michaelsbradley wrote:
| I included it in the title as originally submitted and seen in
| the _new_ page, must have been edited out.
| thinkyfish wrote:
| The biggest thing that nim needs isn't a language change, it is
| to make it easy (or more expected) to put .dll's in nimble
| libraries. Wheels in python is one of the major reasons i'm using
| it. Who needs to figure out how to compile qt? I can just pip
| install PySide6, why can't I do that with nim? Yes, it's a lot
| more work vetting licenses and testing/patching things to make
| them work on various platforms (about the same amount of work as
| a linux distro), but thats the best road I can see for adoption.
| planetis wrote:
| I just love the new numeric literals syntax: proc
| `'i128`(n: string): Int128 = parseDecimalInt128(n) assert
| fib(184) == 127127879743834334146972278486287885163'i128
|
| It's so sexy!
| shomyo wrote:
| '/tmp/hc.nim(5, 1) Error: tabs are not allowed, use spaces
| instead'
|
| Fundamentally broken.
| komuher wrote:
| Man nim is such a cool language it just need some more community
| and better docs to get some hype.
| pindab0ter wrote:
| What's the main use case of Nim, would you say? Is it good for
| personal project/automation, for desktop or web apps? Etc.
| TylerE wrote:
| When you want the performance of a low level compiled
| language with the ease of use and powerful constructs of a
| high level language - and don't want all the bondage and
| discipline of rust.
| otherme123 wrote:
| I started using it for parsing heavy files, just for the
| speed. Slowly I replaced Python with Nim for almost
| everything, even when it doesn't make much sense (e.g. for
| controlling Selenium), and only use Python when I need
| graphics (Matplotlib) or some other libraries that I cannot
| replace.
|
| IMO the main case is when you need C speed but you don't want
| to code in C.
| mrweasel wrote:
| Nim as a replacement for Python makes sense to me. We often
| hear that many Python developers went on to choose Go when
| needing more performance, but Nim feels like an easier
| move.
| cb321 wrote:
| Nim code also tends to run faster than Go code (in my
| experience).
| mrweasel wrote:
| I didn't meassure, but I also don't have any experience
| saying otherwise. Both are great languages and depending
| on the problem I'd be happy to use either.
| V1ndaar wrote:
| > use Python when I need graphics (Matplotlib)
|
| I'm always open to suggestions etc. as to what's missing in
| ggplotnim [0]. I'd hope that by now the majority of use
| cases are covered.
|
| [0]: https://github.com/Vindaar/ggplotnim
| adenozine wrote:
| Potentially unpopular opinion, please go easy on me, I'm a python
| lover:
|
| 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.
| adsharma wrote:
| If you prefer python syntax, you can code in python and
| transpile? Py2many supports nim.
|
| I wonder if there is sufficient interest in having a python
| stdlib compatible library for nim.
| xigoi wrote:
| https://github.com/Yardanico/nimpylib
| adsharma wrote:
| https://github.com/adsharma/py2many/issues/229
| khaledh wrote:
| I love python as well, and I literally just started exploring
| Nim yesterday, so this is very timely.
|
| 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.
| bobbylarrybobby wrote:
| One thing that's always bugged me about snake case is that
| people are so averse to the additional length of strings that
| they just omit the underscores. So you end up with methods
| like array.tolist() and itertools.ziplongest(*lists,
| fill_value=None) -- that last one isn't even internally
| consistent. In an ideal world I would find snake case more
| readable, but people actually adhere to camel case, which
| makes it more readable than snake case overall.
| osmarks wrote:
| It matches identifiers style-insensitively so you can
| actually use other conventions if you want. Although the
| online docs are still camelcased.
| michaelsbradley wrote:
| Nim is partially case-insensitive:
|
| 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.
| dunefox wrote:
| > my_foo, myfoo, and myFoo are interchangeable. MyFoo is
| different because the first letter is capitalized.
|
| God, that's horrible.
| khaledh wrote:
| Good to know. Although I'd argue that this is something
| that I'd count _against_ the language. I'm also biased
| against languages that allow you to do the same thing in
| multiple ways (hint: Scala). Code bases tend to vary
| according to the team's own conventions, so you have to
| keep adapting to whatever code base you happen to be
| reading.
| dragonwriter wrote:
| > I'm also biased against languages that allow you to do
| the same thing in multiple ways
|
| So you oppose languages supporting both recursion and
| iteration?
| khaledh wrote:
| recursion vs. iteration, inheritance vs. composition,
| interfaces vs. abstract classes, etc. are design choices
| that depend on the problem being solved. 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. It's what gives the language its
| identity.
|
| 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
| jjnoakes wrote:
| I'm having trouble contrasting that to the many ways I
| can add 2 and 3, and this doesn't bother me:
| 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 + 2
| dragonwriter wrote:
| > recursion vs. iteration, inheritance vs. composition,
| interfaces vs. abstract classes, etc. are design choices
| that depend on the problem being solved.
|
| Recursion 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
| sp33der89 wrote:
| I get what you're at with the multiple ways to do stuff,
| but in Nim it actually makes it more consistent (imo).
|
| 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.
| DangitBobby wrote:
| Me too. I do a lot of grepping on codebases and this
| seems like it could bite me at some point. But it is a
| very interesting approach to solving the naming
| convention problem.
| planetis wrote:
| --styleCheck:on to enforce the style every identifier is
| declared in your code base.
| tubbyjr wrote:
| Your bias is your own problem. There's clearly a solution
| that allows you to use snake_case and those that
| potentially import your library to seamlessly use all
| exports as camelCase, yet you're still bothered by that.
| It's nonsensical, Nim literally came up with the absolute
| most elegant solution to this.
| jb1991 wrote:
| >my_foo, myFoo, and myFoo are interchangeable.
|
| I'm confused, two of those are myFoo, so I hope they are
| interchangeable!
| dragonwriter wrote:
| I think it intended my_foo, myFoo, and myfoo.
| michaelsbradley wrote:
| Fixed. The second or third one should have been all
| lowercase.
| sp33der89 wrote:
| Even though it's not according to the styleguide, you can
| just use snake_case whenever and wherever you want, consumers
| of your libraries or other way around will never notice!
| khaledh wrote:
| Then you end up with an ecosystem with mixed conventions.
| Not good IMO.
| 0-_-0 wrote:
| Actually, in Nim "functionName", "function_name" and
| "functionname" are equivalent and interchangeable
| [deleted]
| patrickmn wrote:
| You can literally do whatever you want with any library
| you use in your own codebase and have a consistent
| convention in your own code regardless of what your
| dependencies' authors preferences are. In other words, if
| the library authors used camelCase but you want to use
| snake_case in your code, you just do it.
|
| 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 :) )
| WesolyKubeczek wrote:
| I can't get used to the fact that for builtin types grow
| methods, you need to import corresponding modules everywhere.
|
| 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.
| michaelsbradley wrote:
| > you need to import corresponding modules everywhere
|
| 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...
| michaelsbradley wrote:
| Can you give an example of noisy syntax? Is it in relation to
| the type system?
|
| 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.
| adenozine wrote:
| Sure.
|
| 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.
| xigoi wrote:
| The equivalent in Python would be: 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...
| adenozine wrote:
| Yeah, I guess you're right.
| memco wrote:
| Does Nim have comprehensions? Even if you're striving for
| equivalent signatures the inner body of the function can
| be expressed as a comprehension in Python:
| T = TypeVar("T") def odd_numbers(a: Iterable[T]) ->
| Iterator[T]: yield from (n for n in a if n % 2 ==
| 1)
| michaelsbradley wrote:
| See _collect_ : https://nim-
| lang.org/docs/sugar.html#collect.m%2Cuntyped%2Cu...
| xigoi wrote:
| Unfortunately, Nim doesn't have `yield from`, which would
| make a comprehension useless here. That's one of the
| things I'm missing in the language.
| xioren00 wrote:
| Static typing aside, I don't find it any more verbose (noisy)
| than Python. In fact I find it strikes a perfect balance.
| sp33der89 wrote:
| Do you have examples of what you mean with unnecessarily noise?
| For me it's the JSON operators. `@[]` for sequences could also
| be a thing, but it's really minor(for me).
| Nimitz14 wrote:
| I agree. The syntax is the main reason I don't use it.
| mrweasel wrote:
| Completely fair, syntax is something that resonate
| differently from person to person. I love the idea of Rust,
| it's speed, capabilities, it's politics and it's
| independence, but I cannot stand it's syntax.
|
| That's fine, I can use other languages and it doesn't take
| anything away from Rust or the people who love the syntax.
| [deleted]
| BracketMaster wrote:
| One thing people don't often bring up is how great nim is for
| writing DSLs.
|
| DSLs really matter in the hardware and digital design space - a
| space that seems to be completely devoid of innovation when it
| comes to tooling.
|
| A couple languages that try to bring RTL into the 21st century
| are nMigen-Python and Chisel-Scala.
|
| I'm currently writing an RTL in Nim.
|
| Nim's macro system allows you to do really cool things like
| instantiate named RTL wires and create custom operators like `:=`
| for Signal assignment. Really excited about tier 1 BigNum support
| coming soon - which will make it easier to simulate arbitrary
| width integer signal arithmetic.
| Siira wrote:
| Isn't the bottleneck there the core software being proprietary?
| I think even verilog (which is quite old) doesn't have a mature
| FOSS compiler+IDE.
|
| There are also probably not that many hardware designers in the
| world?
| BracketMaster wrote:
| Yosys is a very capable FOSS synthesizer and Verilator is a
| FOSS simulator actually used in production at ARM.
| georgelyon wrote:
| This sounds cool, I would be very interested if you had any
| public code. It's _very_ early days but I'm working on a
| similar project in Swift: https://github.com/circt/Edith
| thechao wrote:
| Do you have anything public? I've been following LLHD for a
| while; I like the idea of a shared middle end. LLHD's front end
| is Verilog/VHDL which are ... not great.
|
| Are you translating, or building your own sim runtime?
| BracketMaster wrote:
| Not yet - but keep an eye out here:
| https://github.com/chipeleven
| BracketMaster wrote:
| Simulator is written internally in Nim. There isn't really a
| good FOSS IR for RTL sims on the market currently. I
| absolutely refuse to use MLIR or anything based on LLVM for
| that matter. LLVM takes up to 40 minutes to rebuild on my
| Apple silicon. This is completely unacceptable in terms of
| rapid iteration.
| elcritch wrote:
| Nim really had fantastic potential for RTL and other
| hardware interaction languages. Best of luck in making
| progress with the RTL! I'd be really interested if it could
| become something for program CPLD or FPGA included in some
| microcontrollers now.
| thechao wrote:
| LLHD is greenfield code, so it's not based on LLVM. I'm
| familiar with the authors both academically (15 years ago),
| and on an engineering level (now). I think it is definitely
| worth reviewing what they're bringing to the table.
|
| Anyways, I think the RTL market is ripe for disruption.
| There was a lot of great language work done by, for
| instance, Ronald Garcia, directly aimed at fixing pain
| points in HDLs, like parsmetrization.
| coolreader18 wrote:
| Yep, one of the main things I did with nim for the month or 2 I
| was really into it was write a duktape wrapper[0] (in
| retrospect, I should have made the name a pun related to
| wrapping with tape...). It was pretty interesting given the
| stack-based nature of almost every duktape operation.
|
| [0]: https://github.com/coolreader18/duk
| Oreb wrote:
| I started using Nim recently and have been very impressed. It
| feels like a better Rust than Rust, and a better Go than Go. Why
| doesn't Nim get more attention?
| davidkunz wrote:
| I think one reason is that there's no big corporation behind
| it, for Rust it was Mozilla and now the members of the Rust
| Foundation, for Go it is Google.
|
| But I totally agree, Nim is an awesome language and definitely
| deserves more attention!
| open-source-ux wrote:
| " _I think one reason is that there 's no big corporation
| behind it_"
|
| I agree. The popularity of some programming languages is
| undoubtedly buoyed by corporate sponsorship or the
| association with a company. This is not a bad thing, but it
| means other languages struggle to generate as much interest.
|
| Also, without a generous benefactor, open source languages
| have to scrape funding together piecemeal from different
| sources. For example, both Rust and Go have had (or still
| have) dedicated staff writing documentation for the language.
| This is a luxury that other languages cannot fund or afford.
|
| I actually posted a Ask HN question of this very topic
| recently: _Can new programming languages attract developers
| without funding? "_
|
| https://news.ycombinator.com/item?id=27043717
| sp33der89 wrote:
| "a better Go than Go", this is exactly how I use Nim currently,
| and I couldn't have said it better myself!
| serverholic wrote:
| Nim has a garbage-collector right? In that case I don't see how
| you can compare Nim and Rust. The Go comparison makes more
| sense.
| ilaksh wrote:
| You can avoid it if you want. That is what a lot of the
| recent changes are about.
| fastball wrote:
| Yes garbage-collected, with a caveat. From the website:
|
| > Nim's memory management is deterministic and customizable
| with destructors and move semantics, inspired by C++ and
| Rust. It is well-suited for embedded, hard-realtime systems.
| throwaway894345 wrote:
| This is interesting. The hard-realtime folks are a
| conservative bunch (understandably so); I wonder how much
| traction Nim is getting in that space.
| michaelsbradley wrote:
| The reference counter with "destructors and move
| semantics..." is not presently the default, though it will
| be in the future. The OP mentions that.
|
| The current default GC involves a somewhat unusual memory
| model that can make certain kinds of multi-threaded
| programming difficult: each thread has its own heap and
| independent GC; memory subject to GC cannot be read/written
| across threads and locks can't be used to remedy the
| situation; if you force the compiler to accept code that
| violates the "no shared" rule, the ref count of the GC on
| one thread or another will eventually get corrupted and the
| program will crash with SIGSEGV.
|
| However, by allocating on and copying to/from the shared
| heap (which is never subject to garbage collection) you can
| do message passing across threads.
| kaba0 wrote:
| I think Erlang has something similar.
| Zababa wrote:
| Would comparing it to Swift be fair? At least on the memory
| management side.
| michaelsbradley wrote:
| It has a garbage collector by default, though it can be
| disabled (--gc:none) and then you can manage memory manually.
|
| In the future, Nim's default memory management will use
| reference counting with destructors and _move_ semantics
| inspired by Rust and C++.
|
| https://nim-lang.org/blog/2020/10/15/introduction-to-arc-
| orc...
|
| https://nim-lang.org/docs/destructors.html
|
| https://nim-lang.org/docs/nimc.html
| one2three4 wrote:
| How's Nim faring with regards to easy programming for
| multicores? (I think that's the main selling point of Go).
| cb321 wrote:
| First, I like that you said "multicores" and not
| "multithreads". Default-sharing of all memory is overrated.
| _Sometimes_ it is useful /necessary, but people reach for
| threads too readily, IMO.
|
| For multiprocessing (like Python's module of that name), you
| can roll your own little system in probably 100 lines of code
| or use something like this [1] with an example program [2].
| For me, that toy program runs 1.5-2x faster than ripgrep on
| the same (admittedly limited) problem on Linux. { I _suspect_
| this perf diff is due to mmap IO being faster than syscall IO
| due to SIMD register use as discussed here [3], but this
| deserves deeper investigation than I have time for right now.
| If my hunch is right, that _may_ constitute further
| argumentative support for not leaping to threads even if the
| programming language "makes them 'easy'", though. }
|
| As for threads/parallelism with shared memory in
| Nim..Honestly, there is probably too much to recap. Weave [4]
| would be a good place to start reading, though, or searching
| the Nim Forum. [1] https://github.com/c-blake
| /cligen/blob/master/cligen/procpool.nim [2] https:
| //github.com/c-blake/cligen/blob/master/examples/grl.nim
| [3] https://news.ycombinator.com/item?id=24842648
| [4] https://github.com/mratsim/weave
| skynet-9000 wrote:
| and channels... extremely useful for network servers.
| eikenberry wrote:
| How is the compiler, speed wise? One thing I really like about
| Go and really don't like about Rust are their relative compiler
| speeds. I think it makes a big different for the language and
| Nim has a chance to get this right as they didn't make the
| mistake of using LLVM and it's bad compiler UX.
| mrweasel wrote:
| For my small learning projects, on old hardware, I'd say
| about the same as Go.
| TylerE wrote:
| Pretty good. The actual compilation is via clang, so there's
| a lot of heavy lifting done by that.
|
| So basically nim actually compiles .nim -> .c -> binary
| elcritch wrote:
| It's good to note that the C/C++ generated by Nim compiles
| much faster than normal C/C++ code since they don't include
| a lot of headers.
| nimmer wrote:
| Nim compiles to C and then runs GCC (not LLVM) to compile the
| binary. Overall, it's much faster than Go and Rust.
| ilaksh wrote:
| It would be interesting to see a compilation of all of the
| times people asked that question. Like literally every time
| anything about Nim is posted, someone asks that.
| mrweasel wrote:
| What made me pick Go over Nim is a bigger standard library. For
| my use Nim is missing a good http server package/module and
| templating.
|
| If those two things had been present I would pick Nim over Go,
| it's just a nice language for some like me, who have mostly
| done Python.
|
| I'm not sure if this was a bug in a third party module, but I
| also struggled a little with unicode support.
| otherme123 wrote:
| Templating as in Jinja? I'm using Karax
| (https://github.com/karaxnim/karax#server-side-html-
| rendering) and it's awesome.
| forgotpwd16 wrote:
| It may be better than Go but I don't see how it is comparable
| to Rust. Rust's biggest selling point is compilation-checked
| memory and thread safety guarantee without garbage collection.
| Nim instead uses a garbage collector, or a reference counter
| similar (but deterministic) to Swift which can cause memory
| leaks, or manual memory management.
| nimmer wrote:
| Nim is getting very close to Rust in terms of safety (but
| without the verbose ownership management)
|
| https://nim-lang.org/blog/2020/10/15/introduction-to-arc-
| orc...
|
| https://nim-lang.org/blog/2020/12/08/introducing-orc.html
| planetis wrote:
| It was discussed recently: https://forum.nim-lang.org/t/7905
|
| > to Swift which can cause memory leaks
|
| The Nim compiler can detect cycles and warn you. And --gc:orc
| collects them successfully at runtime. Orc is going to be the
| default.
| nicoburns wrote:
| > The bundler takes specific commits of Nimble packages and makes
| it part of the official Nim distribution (that is, the zips and
| tarballs you can download from our website). Documentation of
| these modules is included, there is CI integration and to bring a
| new commit into the distribution, the changes need to have been
| reviewed, exactly like stdlib PRs are handled. I hope this will
| keep the benefits of today's monorepo but with more flexibility
| -- we can then more easily place modules
|
| I wish more languages would take this approach. Modules that are
| officially endorsed and shipped with the compiler, but versioned
| rather than perma-stable like the standard library.
|
| It would work fantastically for lots of Rust's defacto standard
| crates.
___________________________________________________________________
(page generated 2021-05-15 23:01 UTC)