Most active commenters

    ←back to thread

    Nim 2.2.6

    (nim-lang.org)
    159 points xz18r | 11 comments | | HN request time: 0.285s | source | bottom
    1. jp57 ◴[] No.45773165[source]
    Nim has a python-like syntax, but I wish they'd gone farther, using `def` instead of `proc` and a `print` function instead of the `echo` statement. Though even if they did those things, I'm not sure it would really feel like programming Python.

    As a long-time Python programmer, I was drawn to trying the language partly because of the syntax, but as soon as I tried to write something substantial, Nim's heritage in languages like Pascal, Modula, and Ada starts to show. Syntax notwithstanding, programming in it really felt more like programming in Pascal/Modula.

    I in fact did not know anything about Nim's history or design choices when I started using it, but I'm old enough to have written a fair amount of Pascal, and I was not long into using Nim when I started thinking, "this feels weirdly familiar." `type` and `var` blocks, ordinal types, array indexing with enums, etc.

    replies(4): >>45773290 #>>45773306 #>>45773801 #>>45774822 #
    2. cenamus ◴[] No.45773290[source]
    From https://nim-lang.org/faq.html :

    Why is it named proc?

    Procedure used to be the common term as opposed to a function which is a mathematical entity that has no side effects. And indeed in Nim func is syntactic sugar for proc {.noSideEffect.}. Naming it def would not make sense because Nim also provides an iterator and a method keyword, whereas def stands for define.

    3. whalesalad ◴[] No.45773306[source]
    I have been meaning to explore Nim for a while because it feels like "golang, but python syntax and dev experience." I vibe coded a simple tool, tt, that allows me to track time to a central log from all my devices. Realllly simple:

        $ tt stats
        Time Tracking Stats
          Total entries: 39
          First entry:   Oct 21, 2025 23:04
          Last entry:    Oct 30, 2025 18:29
          Tracking since: 228h 34m
          Days tracked:  5
    
        $ tt "working on xyz today"
         Logged at 11:38:44
    
        $ tt today
        Today (1 entries)
        11:38:44 working on xyz today
    
    The code is pretty damn ugly though, I feel like I am working with perl:

        proc groupIntoThreads(entries: seq[Entry], threshold: Duration): seq[seq[Entry]] =
          if entries.len == 0:
            return @[]
    
          var sorted = entries
          sorted.sort(proc (a, b: Entry): int =
            if a.timestamp < b.timestamp: -1
            elif a.timestamp > b.timestamp: 1
            else: 0
          )
    
          result = @[]
          var currentThread = @[sorted[0]]
    
          for i in 1..<sorted.len:
            let gap = sorted[i].timestamp - sorted[i-1].timestamp
            if gap > threshold:
              result.add(currentThread)
              currentThread = @[sorted[i]]
            else:
              currentThread.add(sorted[i])
    
          if currentThread.len > 0:
            result.add(currentThread)
    replies(1): >>45773541 #
    4. pansa2 ◴[] No.45773541[source]
    What are the `@` characters for? Are they what makes it feel like Perl?

    Because other than them I don’t think the equivalent Python code would look much different. Maybe more concise, e.g. you could replace the second section with something like `sorted = entries.sorted(key=lambda entry: entry.timestamp)`.

    replies(4): >>45773601 #>>45773604 #>>45774115 #>>45775835 #
    5. johnisgood ◴[] No.45773601{3}[source]
    Yeah, the code doesn't seem very Perl-ish to me.
    6. SJMG ◴[] No.45773604{3}[source]
    `@` makes the array (stack allocated) into a sequence (heap allocated).

    Edit: Just read the second half of your post—

    > I don’t think the equivalent Python code would look much different. Maybe more concise

    He could be leveraging [std/sugar](https://nim-lang.org/docs/sugar.html) to make this look cleaner.

    7. cb321 ◴[] No.45773801[source]
    Actually echo is not a statement - Nim's syntax is just much more flexible than Python so what looks like a statement in Python is actually just a UFCS/Command-Line "call" (of macro/template/generic/procedure aka "routine"). It is super easy to roll your own print function [1] and there is no penalty for doing so except that the std lib does not provide a "common parlance". So, that wheel might get reinvented a lot.

    A lot of things like this in cligen because it is a leaf dependency (the literally 1..3 identifier CLI "api") and so many "drive by" PLang tester-outers might want to roll a little CLI around some procs their working on.

    Also, beyond the echo x,y is same as echo(x,y) or x.echo(y) or x.echo y, the amount of syntax flexibility is dramatically more than Python. You can have user-defined operators like `>>>` or `!!!` or `.*`. There are also some experimental and probably buggy compiler features to do "term re-writing macros" so that your matrix/bignum library could in theory re-write some bz*ax+y expression into a more one-pass loop (or maybe conditionally depending upon problem scale).

    I sometimes summarize this as "Nim Is Choice". Some people don't like to have to/get to choose. To others it seems critical.

    Someone even did some library to make `def` act like `proc`, but I forget its name. Nim has a lot more routine styles than Python, including a special iterator syntax whose "call" is a for-construct.

    [1] https://github.com/c-blake/cligen/blob/master/cligen/print.n...

    8. juki ◴[] No.45774115{3}[source]
    There are shorter options in Nim too, depending on your stylistic preferences

        let sorted = entries.sorted(proc (a, b: Entry): int = cmp(a.timestamp, b.timestamp))
        let sorted = entries.sorted((a, b) => cmp(a.timestamp, b.timestamp))
        let sorted = entries.sortedByIt(it.timestamp)
    
    I suppose you could change the whole proc to something like

        proc groupIntoThreads(entries: seq[Entry], threshold: int): seq[seq[Entry]] =
          let sorted = entries.sortedByIt(it.timestamp)
    
          for i, entry in sorted:
            if i == 0 or entry.timestamp - sorted[i - 1].timestamp > threshold:
              result.add(@[sorted[i]])
            else:
              result[^1].add(sorted[i])
    9. miguel_martin ◴[] No.45774822[source]
    If your really want to use the keyword def instead of proc: you can do that with sed.

    In all serious-ness, don't do that. I've used Python a lot, but Nim is a different language. Writing the proc keyword helps condition your brain to realize you are writing Nim, not Python.

    replies(1): >>45775422 #
    10. jp57 ◴[] No.45775422[source]
    Nim is indeed a different language, which was the point of my comment, for those who got past the first sentence. However, if folks are going to tout its “python-like” syntax as a selling point, it’s not really fair to then turn around and say, “no, it’s a different language”, when a Python programmer points out that it’s not really all that python-like after all, and maybe it could be more so.

    If one is going to take pains to point out that there are good reasons why it is different from Python, then we can carry that as far as we like. There’s no particular reason to use indentation to denote blocks. BEGIN and END worked just fine, after all, and would be more true to Nim’s intellectual heritage. Or maybe just END, and continue to open the block with a colon.

    11. auxym ◴[] No.45775835{3}[source]
    @[] is syntax for a "seq", which is similar to a C++ vector, ArrayList in Java/C#, or a python list. It's a heap-allocated array that automatically resizes.

    In contrast with [], which is mostly identical to a C array: fixed size and lives on the stack.