Nim programming language

  • Robyn [She/Her]
    Don't get how it's confusing, but can add visual noise ig
  • nocturn9x
    yeah, that
  • I think it does the opposite of adding clarity, is all
  • Robyn [She/Her]
    Fair
  • nocturn9x
    one question
  • would it make sense, to limit resource leaks, to have a private seq inside my module that stores the ref Thread objects
  • and reuse them instead of creating them every time?
  • polylokh_39446
    _
    that makes sense in general since there's an expense just in creating a thread
  • nocturn9x
    yeah, fair enough
  • zumi.dxy
    This reply could not be found.
    maybe it should be named AuRC? :p
  • nocturn9x
    xD
  • Elegantbeef
    Gold RC interesting
  • polylokh_39446
    _
    it's also a good tunable, the size of your threadpool.
  • nocturn9x
    In reply to
    _
    polylokh_39446

  • it's also a good tunable, the size of your threadpool.
  • that is determined via UCI options, but yes
  • I can add and remove workers at my leisure
  • since when is high deprecated for seqs??
  • Deprecated since v1.4; there should not be `high(value)`. Use `high(type)`.; high is deprecated [Deprecated]
    system.high: proc (x: T: Ordinal or enum or range): T: Ordinal or enum or range{.noSideEffect, raises: <inferred> [].}
    Returns the highest possible value of an ordinal value x.
    
    As a special semantic rule, x may also be a type identifier.
    
    This proc is deprecated, use this one instead:
    
    [high(typedesc) ](#high,typedesc[T])
    high(2) # => 9223372036854775807
  • I don't think that high() is the same one I mean, haha (aka len() - 1)
  • Elegantbeef
    You're doing high(type)
  • nocturn9x
    ah, what a dumbass I am. I have shadowed workers (a seq), with an int
  • facepalm
  • I was so confused
  • question
  • does deepCopy() copy pointers or does it copy the underlying values too
  • I need to pass basically a copy of self but with some values changed to multiple threads
  • but I want the pointers to stay shared
  • Elegantbeef
    I don't think deep copy deep copies pointers
  • nocturn9x
    okay so they should stay the same
  • Elegantbeef
    Only refs
  • nocturn9x
    gotcha
  • nocturn9x
    question
  • can I pass var T to threads
  • I'm getting weird type errors in createThread
  • Elegantbeef
    No cause var T is not a valid field type
  • nocturn9x
    got it
  • proc workerFunc(args: tuple[self: SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move],
                      timePerMove, ponder: bool]) {.thread.} =
        ## Worker that calls findBestLine in a new thread
        # Gotta lie to nim's thread analyzer lest it shout at us that we're not
        # GC safe!
        {.cast(gcsafe).}:
            var self = args.self
            discard self.findBestLine(args.timeRemaining, args.increment, args.maxDepth, args.maxNodes, args.searchMoves, args.timePerMove, args.ponder)
    
    var workers: seq[ref Thread[tuple[self: SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move],
                      timePerMove, ponder: bool]]] = @[]
    
    
    proc parallelSearch*(self: var SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move],
                      timePerMove=false, ponder=false, numWorkers: int): seq[Move] =
        while workers.len() + 1 < numWorkers:
            workers.add(new Thread[tuple[self: SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move],
                      timePerMove, ponder: bool]])
        for i in 0..<numWorkers:
            # Create a new search manager to send off to a worker thread
            var localSearcher = newSearchManager(self.board.position, self.board.positions, self.transpositionTable, self.history, self.killers, false)
            # Fill in our shared atomic metadata
            localSearcher.stop = self.stop
            localSearcher.pondering = self.pondering
            localSearcher.searching = self.searching
            localSearcher.nodeCount = self.nodeCount
            localSearcher.maxNodes = self.maxNodes
            createThread(workers[i][], (localSearcher, timeRemaining, increment, maxDepth, maxNodes, searchMoves, timePerMove, ponder))
  • I really have no idea what's wrong:

    /home/nocturn9x/CPG/Chess/nimfish/nimfishpkg/search.nim(799, 21) Error: type mismatch
    Expression: createThread(workers[i][], (localSearcher, timeRemaining, increment, maxDepth,
                                maxNodes, searchMoves, timePerMove, ponder))
      [1] workers[i][]: Thread[tuple[self: SearchManager, timeRemaining: int64, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move], timePerMove: bool, ponder: bool]]
      [2] (localSearcher, timeRemaining, increment, maxDepth, maxNodes, searchMoves,
     timePerMove, ponder): (SearchManager, int64, int64, int, uint64, seq[Move], bool, bool)
    
    Expected one of (first mismatch at [position]):
    [1] proc createThread(t: var Thread[void]; tp: proc () {.thread, nimcall.})
    [2] proc createThread[TArg](t: var Thread[TArg];
                            tp: proc (arg: TArg) {.thread, nimcall.}; param: TArg)
  • *
    proc workerFunc(args: tuple[self: SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move], timePerMove, ponder: bool]) {.thread.} =
        ## Worker that calls findBestLine in a new thread
        # Gotta lie to nim's thread analyzer lest it shout at us that we're not
        # GC safe!
        {.cast(gcsafe).}:
            var self = args.self
            discard self.findBestLine(args.timeRemaining, args.increment, args.maxDepth, args.maxNodes, args.searchMoves, args.timePerMove, args.ponder)
    
    var workers: seq[ref Thread[tuple[self: SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move], timePerMove, ponder: bool]]] = @[]
    
    
    proc parallelSearch*(self: var SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move], timePerMove=false, ponder=false, numWorkers: int): seq[Move] =
        while workers.len() + 1 < numWorkers:
            workers.add(new Thread[tuple[self: SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move], timePerMove, ponder: bool]])
        for i in 0..<numWorkers:
            # Create a new search manager to send off to a worker thread
            var localSearcher = newSearchManager(self.board.position, self.board.positions, self.transpositionTable, self.history, self.killers, false)
            # Fill in our shared atomic metadata
            localSearcher.stop = self.stop
            localSearcher.pondering = self.pondering
            localSearcher.searching = self.searching
            localSearcher.nodeCount = self.nodeCount
            localSearcher.maxNodes = self.maxNodes
            createThread(workers[i][], (localSearcher, timeRemaining, increment, maxDepth, maxNodes, searchMoves, timePerMove, ponder))
  • ah ups
  • I'm not passing it the proc....
  • what an idiot x2
  • it's late, I apologize for the noise
  • it would be nice if nim made arity issues more clear
  • nocturn9x
    wow, this was surprisingly painless
  • haven't done any extensive testing but other than an out of bounds access cuz I'm stupid, I pretty much just wrote the code and it worked
  • neat
  • Elegantbeef
    Just mark all your thread procs as raises: [] for style points
  • nocturn9x
    XDD
  • Robyn [She/Her]
    In reply to
    nocturn9x

  • it's late, I apologize for the noise
  • Noise as in using the channel? Don't see why it'd be an issue aha
  • nocturn9x
    huh
  • In reply to
    Robyn [She/Her]

  • Noise as in using the channel? Don't see why it'd be an issue aha
  • lol thx...
  • an interesting problem has occurred
  • I can run my project fine on my laptop
  • but when I try to execute the uci command on the same project compiled on my server
  • which is an intel mini pc with a fairly old i5
  • it segfaults
  • at a completely random place, with a fucked up traceback (i.e. the line numbers are completely wrong)
  • if it were a CPU compatibility issue, I'd expect the executable to not boot up at all
  • but other things are working fine
  • nocturn9x
    is create returning nil?
  • this is a segmentation fault
  • Robyn [She/Her]
    Maybe it's using an instruction unavailable on the current CPU?
  • nocturn9x
    so that's not the issue
  • that would trigger an IOT fault
  • I have confirmed that the constructor runs until the end
  • Robyn [She/Her]
    Ah
  • nocturn9x
    it's a memory issue
  • Robyn [She/Her]
    is SearchManager is a reference?
  • nocturn9x
    nope
  • value type
  • as I said, everything works fine on my laptop
  • it just breaks on my server
  • same exact code
  • Robyn [She/Her]
    Yeah I'm not gonna be useful then, sorry and good luck
  • nocturn9x
    thanks for trying anyway :)
  • yeah, create is returning nil
  • what in the-
  • it's even using the same allocator on both machines
  • how
  • and it's nil only for one thing too
  • lol wtf-
  • systemdsucks[IRC]#0000
    but is it the same nim version?
  • nocturn9x
    (venv) [nocturn9x@pyra Chess]$ nim -v
    Nim Compiler Version 2.0.4 [Linux: amd64]
    Compiled at 2024-03-28
    Copyright (c) 2006-2023 by Andreas Rumpf
    
    git hash: b47747d31844c6bd9af4322efe55e24fefea544c
    active boot switches: -d:release


    ➜  Chess git:(master) ✗ nim -v
    Nim Compiler Version 2.0.4 [Linux: amd64]
    Compiled at 2024-03-28
    Copyright (c) 2006-2023 by Andreas Rumpf
    
    git hash: b47747d31844c6bd9af4322efe55e24fefea544c
    active boot switches: -d:release
  • down to the same exact commit hash
  • yeah, if I switch from create to cast[ptr T](alloc0(sizeof(T))) it works
  • what
  • so create is failing only on one platform and only for one type
  • again, what
  • I have several other create calls sprinkled over the code and those work fine
  • or, at least, it seems they do
  • nothing is segfaulting, and it would happen immediately if any of those were in any way corrupted or null
  • well at least the fix was simple but like
  • weird
  • gonna have to investigate
  • polylokh_39446
    _
    proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, benign, raises: [].} =
      cast[ptr T](alloc0(sizeof(T) * size))

    a. your server hits some memory corruption that's also present on your laptop, and changing the source to something that should be equivalent, it just causes the object to change just slightly enough (changed debug information?) that your server joins your laptop in dodging the consequences of that corruption. You'll see probably see these same crashes later as you try it on other machines or develop further.
    b. these aren't equivalent due to those pragmas
  • polylokh_39446
    _
    benign is a mysterious undocumented pragma from 2014, which seems to be a read-only gcsafe, so I think it might really be (b), and due to data races.
  • amarevite
    image.png
  • is there any way in nim to fill out this information?i just learned that c# has [assembly attributes](https://learn.microsoft.com/en-us/dotnet/standard/assembly/set-attributes) and i wanted to play with them but i cant figure out how to do this in nim or if it's even possible
  • * is there any way in nim to fill out this information? i just learned that c# has [assembly attributes](https://learn.microsoft.com/en-us/dotnet/standard/assembly/set-attributes) and i wanted to play with them but i cant figure out how to do this in nim or if it's even possible
  • pusewicz
    Mmmm, recursive module dependencies!
  • Do I just put all the type definitions in a separate file then? 😐
  • Elegantbeef
    You can do delayed imports
  • But yea most people do not futz with that
  • I do cause I hate myself
  • pusewicz
    Yeah, not very elegant.
  • Elegantbeef
    Single pass compiler does be single pass 😄
  • pusewicz
    Ew. now I have to export all the types.
  • FFS
  • Elegantbeef
    Then try delayed imports
  • Though that only works well if procedures are not cyclically dependant
  • polylokh_39446
    _
    or, just export them. That's not going to pollute the namespace of code importing your modules unless you re-export
  • pusewicz
    Actually, you are right
    _
    polylokh_39446
    . I'll just make it work, then I'll make it pretty.
  • Elegantbeef
    It does leak internal details that might not be apart of the actual API that people will use 😄
  • pusewicz
  • Elegantbeef
    You did = array
  • This compiler error sucks but it should be : array
  • pusewicz
    urg
  • Thank you!
  • pusewicz
  • Elegantbeef
    What a wild issue 😄
  • pusewicz
    I don’t understand. It’s exported, defined. What am I doing wrong?
  • polylokh_39446
    _
    you haven't updated your code yet, the version on github still has the =array
  • pusewicz
    True
  • Pushed
  • Elegantbeef
    For me with that code there is a neighbours error
  • polylokh_39446
    _
    I don't see your bug. I get other circular dependencies, like model.nim importing cell.nim which needs cellAt from model.nim
  • pusewicz
    Correct.
  • Which is also defined and exported?
  • polylokh_39446
    _
    which is also a circular dependency between cell and model
  • pusewicz
    Right, so... ugh. I need to re-structure the code?
  • polylokh_39446
    _
    yep.
  • looks like model and cell are the only problems there
  • minimally, you could combine them in a single model and use foreward declarations and call it a day
  • but it's probably not that bad
  • NimEventer[IRC]#0000
    New Nimble package! nimtk - High-level Tk wrapper for Nim, see https://github.com/neroist/nimtk
  • Amun-Ra[IRC]#0000
    I know it works but… is it safe to cast[string](a_seq_of_chars)?
  • Elegantbeef
    Not if anything ever passes it to cstring
  • Amun-Ra[IRC]#0000
    I just print the value for debugging purposes, no other conversions are made
  • Elegantbeef
    Could do toOpenArray(0, str.high) 😄
  • That's safe
  • Amun-Ra[IRC]#0000
    oh
  • right
  • it'd be nice to end with compile error any attempt to mark an object containing any ref type with noinit pragma; it segfaults otherwise
  • hmm, I wanted to write an example but it works on play.nim, weird…
  • pmunch
    _
    In reply to
    Elegantbeef

  • Not if anything ever passes it to cstring
  • Why wouldn't that work?
  • ringabout
    Should views support implicitly converting to openarray for corresponding fields or give an error?
    {.experimental: "views".}
    
    type
      Lexer* = object
        source: openArray[char]
    
    let source = "+-;+"
    var lexer = Lexer(source: source)
    # toOpenArray works
  • solitudesf
    In reply to
    _
    pmunch

  • Why wouldn't that work?
  • because '\0' terminator would be missing
  • pmunch
    _
    In reply to
    solitudesf

  • because '\0' terminator would be missing
  • Ah right, I assumed that this was string data that came from some low-level API
  • ieltan
    In reply to
    ringabout

  • Should views support implicitly converting to openarray for corresponding fields or give an error?
    {.experimental: "views".}
    
    type
      Lexer* = object
        source: openArray[char]
    
    let source = "+-;+"
    var lexer = Lexer(source: source)
    # toOpenArray works
  • I don't know about the implications of converting string to openarray implicitly like that but I do know that views types are kind of buggy already, last time I tried (when Nim 2.0 first came out) I had confusing behavior iirc any method called on my openArray[char] would do it twice (like echo would print the string twice)
  • I feel like the feature should be bug-free and polished first 😅
  • intellij_gamer
    In reply to
    ringabout

  • Should views support implicitly converting to openarray for corresponding fields or give an error?
    {.experimental: "views".}
    
    type
      Lexer* = object
        source: openArray[char]
    
    let source = "+-;+"
    var lexer = Lexer(source: source)
    # toOpenArray works
  • Imo would make sense since it already does it for parameters
  • pusewicz
    Which is the preferred LSP server for Nim?
  • nnsee
    In reply to
    pusewicz

  • Which is the preferred LSP server for Nim?
  • nimlangserver
  • nocturn9x
    quick question
  • any idea why spawning 12 threads would consume a fuckton of memory?
  • like I have 48GiB of RAM and the chess engine manages to occupy over 32
  • and there's nothing even remotely close to that size
  • the biggest item is a shared 64MiB transposition table
  • but as I said that's shared across threads
  • also, createThread() is slow af
  • does atomicArc fuck with multiple threads somehow?
  • In reply to
    nocturn9x

  • like I have 48GiB of RAM and the chess engine manages to occupy over 32
  • correction: over 42
  • In reply to
    nocturn9x

  • does atomicArc fuck with multiple threads somehow?
  • happens with bare ARC too
  • Phil
    I assume something gets allocated 1000 times and given the thread doesn't get destroyed it keeps staying around
  • nocturn9x
    but what could it possibly be
  • let me show you the code
  • Phil
    I'm out of crystal balls
  • solitudesf
    In reply to
    nocturn9x

  • any idea why spawning 12 threads would consume a fuckton of memory?
  • does it grow proportionally with more threads?
  • nocturn9x
    yes
  • it seems like it's duplicating the entire address space
  • as if it were forking
  • let me test with just one extra worker
  • solitudesf
    fork doesnt actually copy the entire address space
  • nocturn9x
    yeah it grows with every thread
  • yeah I know it's CoW
  • also did not realize how slow creating a thread is, damn
  • might wanna use a thread pool
  • but that doesn't explain the huge memory usage
  • while workers.len() + 1 < numWorkers:
        workers.add(new Thread[tuple[self: ptr SearchManager, timeRemaining, increment: int64, maxDepth: int, maxNodes: uint64, searchMoves: seq[Move],
                  timePerMove, ponder: bool]])
    self.searching[].store(true)
    for i in 0..<numWorkers - 1:
        # Copy the history and killers table, as those are meant to be thread-local
        var
            history = create(HistoryTable, sizeof(HistoryTable))
            killers = create(KillersTable, sizeof(KillersTable))
        # Copy in the data
        for color in PieceColor.White..PieceColor.Black:
            for i in Square(0)..Square(63):
                for j in Square(0)..Square(63):
                    history[color][i][j] = self.history[color][i][j]
        for i in 0..<MAX_DEPTH:
            for j in 0..<NUM_KILLERS:
                killers[i][j] = self.killers[i][j]
        self.children.add(create(SearchManager, sizeof(SearchManager)))
        self.children[i][] = newSearchManager(self.board.position, self.board.positions, self.transpositionTable, history, killers, false)
        self.children[i].stop = self.stop
        self.children[i].pondering = self.pondering
        self.children[i].searching = self.searching
        createThread(workers[i][], workerFunc, (self.children[i], timeRemaining, increment, maxDepth, maxNodes div numWorkers.uint64, searchMoves, timePerMove, ponder))
    result = self.findBestLine(timeRemaining, increment, maxDepth, maxNodes div numWorkers.uint64, searchMoves, timePerMove, ponder)
    for i in 0..<numWorkers - 1:
        if workers[i][].running:
            joinThread(workers[i][])
    # If we set the atomics any earlier than this, our
    # search threads would never stop!
    self.searching[].store(false)
    self.stop[].store(false)
    # Ensure local searchers get destroyed
    for child in self.children:
        child[].`destroy=`()
        dealloc(child)
    self.children.setLen(0)
  • for reference this is the code that spawns the workers
  • as soon as they're all created, memory usage goes through the roof
  • workers is a global module-level variable that's private
  • it's just a seq
  • the history table is about 400KiB and the killers table is even smaller
  • so that can't be it
  • it wasn't doing this before, when I didn't allocate SearchManager objects on the heap
  • ohhhh
  • create doesn't take n * sizeof(T)...
  • does it
  • it already does the multiplication internally?
  • oh my god what an idiot
  • nocturn9x
    so yeah apparently I was allocating over 70 GiB to each thread
  • for no reason
  • I just didn't think create already did the multiplication on its own... upsie
  • System64 ~ Flandre Scarlet
    In reply to
    ringabout

  • Should views support implicitly converting to openarray for corresponding fields or give an error?
    {.experimental: "views".}
    
    type
      Lexer* = object
        source: openArray[char]
    
    let source = "+-;+"
    var lexer = Lexer(source: source)
    # toOpenArray works
  • views ? What is that?
  • kots
  • madonuko
    why can't I do {.push async.}
  • invalid pragma: async
  • odexine
    Async isn’t a “regular pragma”
  • Push can’t push certain pragma
  • Phil
    Does asyncdispatch have an equivalent to threadsignalptr in chronos?
  • pusewicz
    _
    ElegantBeef
    I merged the code into one file: https://github.com/pusewicz/wave-function-collapse-nim/blob/main/src/model.nim#L113:
    Error: type mismatch
    Expression: neighbors(cell, self)
      [1] cell: Cell:ObjectType
      [2] self: Model
    
    Expected one of (first mismatch at [position]):
    [1] proc neighbors(self: Cell; model: Model): Cell.neighbors
  • pusewicz
    Figured it out, neighbors is a property on Model too, so had to rename the neighbors proc to something else. Not sure if there's a better fix.
  • pusewicz
    https://play.nim-lang.org/#pasty=SzSKpvqb
    /usercode/in.nim(143, 14) template/generic instantiation of new from here
    /usercode/in.nim(34, 27) Error: cannot evaluate at compile time: wangid

    Ugh, not sure what those mean.
  • ringabout
    wangid is not a value can be computed in the compile time. You Could use let instead of const
  • pusewicz
    Ah, idiot me, Have not noticed that I put const.
  • @safsaf94:matrix.org
    S

    This message is being deleted (Suspicious looking as well as no justification as for why this was posted.)…

  • bung8954

    This message is being deleted…

  • pusewicz
    In reply to
    ringabout

  • wangid is not a value can be computed in the compile time. You Could use let instead of const
  • Thank you!
  • ringabout
    No problem
  • @safsaf94:matrix.org
    S

    This message is being deleted…

  • nnsee
    er... what?
  • Phil (he/him)
    In reply to
    S
    @safsaf94:matrix.org

  • This message is being deleted…

  • Please elaborate or I'll have to assume you're a bot/spammer and act accordingly 
  • odexine
    id say just assume its a mispaste
  • anddam[IRC]#0000
    pfff only 2 bytes IP address masking…
  • Phil (he/him)
    In reply to
    odexine

  • id say just assume its a mispaste
  • I would agree with you if the only 2 interactions I'd seen so far weren't just 1 uploaded file that never made it to discord and this 1 link
  • Phil
    ... How exactly do you add the raises pragma to a proc?
  • *generated via macro
  • odexine
    what happened with what you tried?
  • Phil
    import std/macros
    
    macro genProc(): typed =
      let myProc = newProc(procType = nnkLambda)
      let raisesPragma = nnkPragma.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("raises"),
          nnkBracket.newTree(
          )
        )
      )
      myProc.body = quote do: echo "Potato"
      myProc.addPragma(raisesPragma)
      
      echo myProc.repr
      return myProc
    
    let x = genProc()

    proc () {.raises: [].} = echo "Potato" # <-- This is from the echo myProc.repr
    /home/isofruit/dev/playground/src/playground.nim(89, 16) template/generic instantiation of `genProc` from here
    /home/isofruit/.choosenim/toolchains/nim-2.0.4/lib/core/macros.nim(1118, 22) Error: invalid pragma:  {.raises: [].}
  • Robyn [She/Her]
    In reply to
    Phil

  • import std/macros
    
    macro genProc(): typed =
      let myProc = newProc(procType = nnkLambda)
      let raisesPragma = nnkPragma.newTree(
        nnkExprColonExpr.newTree(
          newIdentNode("raises"),
          nnkBracket.newTree(
          )
        )
      )
      myProc.body = quote do: echo "Potato"
      myProc.addPragma(raisesPragma)
      
      echo myProc.repr
      return myProc
    
    let x = genProc()

    proc () {.raises: [].} = echo "Potato" # <-- This is from the echo myProc.repr
    /home/isofruit/dev/playground/src/playground.nim(89, 16) template/generic instantiation of `genProc` from here
    /home/isofruit/.choosenim/toolchains/nim-2.0.4/lib/core/macros.nim(1118, 22) Error: invalid pragma:  {.raises: [].}
  • Change the macro return tyoe to untyped, maybe?
  • Phil
    Not the problem really 😛
  • Robyn [She/Her]
    Same result either way?
  • odexine
    what's myproc as a treerepr
  • Phil
    In reply to
    Robyn [She/Her]

  • Same result either way?
  • Yeh
  • Lambda
      Empty
      Empty
      Empty
      FormalParams
        Empty
      Pragma
        Pragma
          ExprColonExpr
            Ident "raises"
            Bracket
      Empty
      Command
        Sym "echo"
        StrLit "Potato"

    ... oh come on
  • odexine
    lol
  • that made me physically laugh lmao
  • Robyn [She/Her]
    In reply to
    Phil

  • Lambda
      Empty
      Empty
      Empty
      FormalParams
        Empty
      Pragma
        Pragma
          ExprColonExpr
            Ident "raises"
            Bracket
      Empty
      Command
        Sym "echo"
        StrLit "Potato"

    ... oh come on
  • Welp, you found your issue? :P
  • Phil
    basically addPragma is busted
  • Just assign directly via the pragma operator
  • Robyn [She/Her]
    Lovely
  • You gonna PR a fix?
  • Wait
  • No, that seems like expected behaviour, Phil
  • Passing the colon expr would be no problem
  • @safsaf94:matrix.org
    S

    This message is being deleted…

  • Phil (he/him)
    In reply to
    S
    @safsaf94:matrix.org

  • This message is being deleted…

  • You have 60 seconds to describe why you posted this or you're getting banned for spam.
  • saint.___.
    This app fair thing is interesting actually
  • But the person does look like a spammer I guess
  • Maybe he's a benevolent spammer
  • odexine
    been way longer than 60 seconds though so unfortunately...
  • saint.___.
    Or some bot that someone is testing out
  • Phil
    Perfectly fine if I'm informed. If I have to assume they're a spammer that's just testing the waters before posting whatever else I'm going to just pre-emptively ban
  • saint.___.
    Makes sense!
  • threefour
    How should I go about passing an AsyncSocket into another thread through a channel? The sending-over-channel part seems to be working fine, but when I try to .send() on the socket in the recipient thread, it tells me that the file descriptor is not registered. I tried doing inheritable = true thinking that had something to do with it, but I must be missing something still, because nothing changed. Are file descriptors / socket handles tracked per-thread? If so, how do I transfer them to another thread?
  • michaelb.eth
    In reply to
    threefour

  • How should I go about passing an AsyncSocket into another thread through a channel? The sending-over-channel part seems to be working fine, but when I try to .send() on the socket in the recipient thread, it tells me that the file descriptor is not registered. I tried doing inheritable = true thinking that had something to do with it, but I must be missing something still, because nothing changed. Are file descriptors / socket handles tracked per-thread? If so, how do I transfer them to another thread?
  • you may just want to open a socket/s between threads and send/recv data as if they
  • as if they're network agents talking to each other
  • threefour
    That's a decent solution, but I'm sure it adds overhead (network stack) that I'd like to avoid if possible.
  • michaelb.eth
    if you're not on Windows, what about unix sockets, should avoid network overhead, though you'll still need to de/serialize
  • threefour
    Better, but I'd still be creating two file descriptors per connection, instead of one. If there's no solution to socket passing, then I might have to settle for that.
  • Well actually I guess I wouldn't need to create multiple on every connection. Just on startup per thread. But I still feel like that's a bandaid fix to what should be a simple message-passing solution.
  • polylokh_39446
    _
    In reply to
    threefour

  • How should I go about passing an AsyncSocket into another thread through a channel? The sending-over-channel part seems to be working fine, but when I try to .send() on the socket in the recipient thread, it tells me that the file descriptor is not registered. I tried doing inheritable = true thinking that had something to do with it, but I must be missing something still, because nothing changed. Are file descriptors / socket handles tracked per-thread? If so, how do I transfer them to another thread?
  • conventionally fds are not per-thread, and they certainly aren't in your program. On linux the underlying clone() syscall can change that.
  • this difficulty is due to all the layers of abstraction between you and the fd.
  • but you can confirm this with strace.
  • clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
    that's what default createThread gives me. CLONE_FILES has them sharing fds
  • inheritable's about the close-on-exec flag, which shouldn't apply. You're not exec'ing.
  • System64 ~ Flandre Scarlet
    Hi, does Nim have List Comprehension?
  • bulletxbt
    import streams
    import struct
    
    func toString*(bytes: openArray[byte]): string =
        let length = bytes.len
        if length > 0:
            result = newString(length)
            copyMem(result.cstring, bytes[0].unsafeAddr, length)
    
    proc open(path: string) =
        var stream = newFileStream(path, fmRead)
        var buffer: array[16, byte]
        discard stream.readData(addr(buffer), 16)
        
        var struct_data = unpack("<4I", toString(buffer))
        let headerStringSize = struct_data[3].getInt
    
        var headerData: array[headerStringSize, byte] # here
        discard stream.peekData(addr(headerData), headerStringSize) # here

    I know arrays must have a fixed size at compile time, that's why this wouldn't work, how else can I?
    Tried using seq[byte] and I get: Error: execution of an external program failed: '"pathtomyfile.nim"'
  • odexine
    In reply to
    System64 ~ Flandre Scarlet

  • Hi, does Nim have List Comprehension?
  • sugar has collect
  • saint.___.
    In reply to
    System64 ~ Flandre Scarlet

  • Hi, does Nim have List Comprehension?
  • Ya sugar collect is really good
  • System64 ~ Flandre Scarlet
    In reply to
    saint.___.

  • Ya sugar collect is really good
  • Does it work with const too?
  • saint.___.
    In reply to
    System64 ~ Flandre Scarlet

  • Does it work with const too?
  • Not sure!
  • kots
    what does working with const mean?
  • import std/sugar
    
    const Stuff = collect:
      for i in 1..3:
        i * 2
    echo Stuff
  • michaelb.eth
  • kots
    great minds
  • nocturn9x
    anyone know of any nice-ish wrapper around __builtin_prefetch for clang/gcc?
  • speaking of which, how would I use a C compiler intrinsic from Nim?
  • michaelb.eth
    In reply to
    nocturn9x

  • speaking of which, how would I use a C compiler intrinsic from Nim?
  • importc with <intin.h>?
  • polylokh_39446
    _
    if it works like a function, you wrap it like anything. In a pinch you can always use emit
  • pointless example of emit:
    func `*`(a: float, b: int64): float =
       {.emit: [result, " = ", a, " * ", b, ";"].}

    C code with interpolated Nim names
  • michaelb.eth
    I may have misunderstood what
    _
    nocturn9x
    is asking about, but the question made me think of things I've seen in the weave codebase:
    https://github.com/mratsim/weave/blob/master/benchmarks/matmul_gemm_blas/gemm_pure_nim/common/simd.nim
  • nocturn9x
    something like

    {.pragma: intrin, noDecl, header:"<intrin.h>".}
    
    func mm_load_ps*(p: ptr) {.importc: "__builtin_prefetch", intrin.}


    this?
  • * something like

    {.pragma: intrin, noDecl, header: "<intrin.h>".}
    
    func mm_load_ps*(p: ptr) {.importc: "__builtin_prefetch", intrin.}


    this?
  • * something like

    {.pragma: intrin, noDecl, header: "<intrin.h>".}
    
    func __builtin_prefetch*(p: ptr) {.importc: "__builtin_prefetch", intrin.}


    this?
  • System64 ~ Flandre Scarlet
    Perfect for lookup tables!
  • kots
    In reply to
    bulletxbt

  • import streams
    import struct
    
    func toString*(bytes: openArray[byte]): string =
        let length = bytes.len
        if length > 0:
            result = newString(length)
            copyMem(result.cstring, bytes[0].unsafeAddr, length)
    
    proc open(path: string) =
        var stream = newFileStream(path, fmRead)
        var buffer: array[16, byte]
        discard stream.readData(addr(buffer), 16)
        
        var struct_data = unpack("<4I", toString(buffer))
        let headerStringSize = struct_data[3].getInt
    
        var headerData: array[headerStringSize, byte] # here
        discard stream.peekData(addr(headerData), headerStringSize) # here

    I know arrays must have a fixed size at compile time, that's why this wouldn't work, how else can I?
    Tried using seq[byte] and I get: Error: execution of an external program failed: '"pathtomyfile.nim"'
  • send reproducible code / full compiler error? it should work with a seq
  • In reply to
    System64 ~ Flandre Scarlet

  • Perfect for lookup tables!
  • my example was pretty good too :(
  • bulletxbt
    In reply to
    kots

  • send reproducible code / full compiler error? it should work with a seq
  • SIGSEGV: Illegal storage access. (Attempt to read from nil?)
    Error: execution of an external program failed: '"mypath\Nim\asar.exe"'
    occurs when I use seq[byte], when I use array[size, byte] it works fine but I can't provide the size dynamically due to compile time errors
  • Can't really provide the data, it's 180mb and contains private info
  • * Can't really provide the data I'm unpacking, it's 180mb and contains private info
  • kots
    try headerData[0].addr
  • you also need to newSeq(headerStringSize )
  • * you also need to newSeq[byte](headerStringSize )
  • bulletxbt
    In reply to
    kots

  • you also need to newSeq(headerStringSize )
  • Like this?
    var headerData: seq[byte]
    discard stream.peekData(headerData[0].addr, newSeq[byte](headerStringSize))
  • Or
    var headerData: newSeq[byte](headerStringSize)
    discard stream.peekData(headerData[0].addr, headerStringSize)
  • kots
    yeah the latter
  • bulletxbt
    Thanks I'll try
  • kots
    with = instead of : there
  • bulletxbt
    👍
  • In reply to
    kots

  • with = instead of : there
  • It worked, thanks :)
  • kots
    pog
  • :3
  • bulletxbt
    func toString* is the asterisk used so you can import it from another module? I've forgotten
  • kots
    yes
  • bulletxbt
    Alr
  • motatertot
    _
    # Teen content and onlyfans leaks here :peach: :underage: : https://discord.gg/xxxhubs @everyone @here
  • # Teen content and onlyfans leaks here :peach: :underage: : https://discord.gg/xxxhubs @everyone @here
  • raynei486
    @Moderator
  • threefour
    _
    polylokh_39446
    could you point me in a direction of how to achieve what I'm wanting? I don't know where to go with this.
  • __sxp__
    What's the current imgui binding for Nim? There's a NimGL which seem to be updated 3 years ago and there some other dropped / experimental ones.
  • Or should I just import the header manually / support myself with Futhark and call it a day?
  • NimEventer[IRC]#0000
    New Nimble package! cozylogwriter - Basic zero-dependency logging with automatic colors and styling for Nim., see https://github.com/indiscipline/cozytaskpool
  • Phil
    squint
  • squint
  • Nah, got excited too early, not usebal for me. They're doing an abstraction level halfway between what I need and what I want to build on top of
  • * Nah, got excited too early, not usable for me. They're doing an abstraction level halfway between what I need and what I want to build on top of
  • Zoom
    And what do you need?
  • Phil
    A threadpool that doesn't basically hotspin if I try to run an async task on it
  • Which currently happens on both weave_io and taskpool due to the way their work-stealing algo works
  • Can't cope with chronos ThreadSignalPtr
  • https://github.com/status-im/nim-taskpools/issues/41

    So basically sth with the exact same abstraction level as taskpool, but also functional.
    It doesn't have to be the fastest, it just needs to flipping work
  • * https://github.com/status-im/nim-taskpools/issues/41

    So basically sth with the exact same abstraction level as taskpool, but also functional with async.
    It doesn't have to be the fastest, it just needs to flipping work
  • ~~I also need a way to deal with exceptions getting thrown in the async block of chronos, but that's separate
  • * I also need a way to deal with exceptions getting thrown in the async block of chronos, but that's separate
  • Zoom
    I wouldn't call that library above abstraction at all. More of a "shove it out of sight" approach.
  • Phil
    If I don't see (and care to see) what happens in between the layers of "createThread" and "pool.spawn myproc(value)" then it's an abstraction layer 😄
  • I just vaguely know it does the thing and distributes function calls across groups of threads, I don't see how, that's an abstraction 😛
  • Zoom
    Fair enough
  • threefour
    Doing createThread with a bunch of infinite-looping procs that await a Channel.recv() seems to be working so far for me.
  • * Doing createThread with a bunch of infinite-looping procs that block on Channel.recv() seems to be working so far for me.
  • nocturn9x
    question
  • is it possible to manipulate numpy arrays with numpy without scinim?
  • it's a pretty heavy dependency
  • and I only need this for quite literally 3 lines of code
  • if I do like arr[0] = 1 the entire array is set to 1
  • * is it possible to manipulate numpy arrays with nimpy without scinim?
  • nocturn9x
    I guess I need toTensor()?
  • nocturn9x
    I think I'm almost there
  • only thing I need to figure out is how to turn a "numpy array in nim" back into PyObject
  • so I can return it from my exportpy func
  • also scinim doesn't compile: /home/nocturn9x/.nimble/pkgs2/scinim-0.2.5-123625cbd61116b14d229ace3cd62269e4b63f7e/scinim.nim(1, 24) Error: cannot open file: ./scinim/signals/signals
  • fixed it by importing just scinim/numpyarrays
  • kinda clunky tho
  • graveflo
    anyone know why nimsuggest would crash every time it tries to run with a Error: cannot open '/usr/lib/system.nim'. It doesn't seem to matter where I run nimsuggest from, or the PWD. I haven't had an issue building from source like this before. The only thing that has changed (that I know of)is that /etc/nim/nim.cfg exists
  • actually it seems like removing the config file stops that from happening. I presume that is a bug since that config location is supposed to be valid?
  • NimEventer[IRC]#0000
    New thread by alexeypetrushin: Why not use AI to create momentum in Nim?, see https://forum.nim-lang.org/t/11601
  • .bobbbob
    using norm with sqlite, what's the RIght Way™️ to retry inserting something when DbError: database is locked ie something is concurrently being inserted?
  • .bobbbob
    In reply to
    .bobbbob

  • using norm with sqlite, what's the RIght Way™️ to retry inserting something when DbError: database is locked ie something is concurrently being inserted?
  • is this a remotely good idea?
    var exobj = newWtvr(wtvr)
    while true:
        try:
            db.insert(exobj)
        except DbError:
            continue
        break
  • Phil
    In reply to
    .bobbbob

  • is this a remotely good idea?
    var exobj = newWtvr(wtvr)
    while true:
        try:
            db.insert(exobj)
        except DbError:
            continue
        break
  • No because you can crash your server like that or let your user wait forever for a response. Write yourself a template that does a couple retries and give up after that.
    If this does not suffice you should solve the underlying problem that causes your dB to be locked all the time
  • .bobbbob
    In reply to
    Phil

  • No because you can crash your server like that or let your user wait forever for a response. Write yourself a template that does a couple retries and give up after that.
    If this does not suffice you should solve the underlying problem that causes your dB to be locked all the time
  • Sounds good, should I maybe put a teensy pause between retries? It's not all the time, it just very occasionally loses stuff when two things are inserted at the same time.
  • Phil
    In reply to
    .bobbbob

  • Sounds good, should I maybe put a teensy pause between retries? It's not all the time, it just very occasionally loses stuff when two things are inserted at the same time.
  • That's up to you. If you do that I'd try to do that with sleep async to not block the thread (if your underlying Webserver can process multiple requests on the same thread via async).
  • Phil
    Actually, how many connections do you use?
  • .bobbbob
    I think one per thread?
  • .bobbbob
    I think Im gonna have to rework a lot of my code to use transactions too
  • Phil
    In reply to
    .bobbbob

  • I think Im gonna have to rework a lot of my code to use transactions too
  • Wait, do you have multiple queries that depend on one another and you aren't putting them in transactions?
  • Then that's definitely the point to start on.
    Transactions are the absolute baseline you must be using (when you need them) to ensure correctness.
  • Generally I'd recommend writing a template that starts and ends the transaction within a scope automatically so you can't possibly forget to close it
  • .bobbbob
    who would've thought concurrent database programming was tricky
  • Phil
    Me, I would've thought that
    PTSD flashes in the background
  • thatben
    Hi!
    I'm trying to glue a C-library to nim. It's been going quite well but now I need to check for the existence of certain symbols, and set #defines based on it. Here's the idea:
      when defined(fdatasync): # may or may not exist in 'unistd.h'
        {.passc: "-DHAVE_FDATASYNC=1".}

    The above when is always false. I need a way to tell nim to check for the availability of this symbol in its C context.
    If you have any ideas, please reach out in DM or tag-reply to this message so I get pinged.
  • demotomohiro
    At compile time, write C code that uses the symbols you want to check then compile it by calling C compiler with gorgeEx.
    If it compiles without errors, you have the symbols.
  • In reply to
    thatben

  • Hi!
    I'm trying to glue a C-library to nim. It's been going quite well but now I need to check for the existence of certain symbols, and set #defines based on it. Here's the idea:
      when defined(fdatasync): # may or may not exist in 'unistd.h'
        {.passc: "-DHAVE_FDATASYNC=1".}

    The above when is always false. I need a way to tell nim to check for the availability of this symbol in its C context.
    If you have any ideas, please reach out in DM or tag-reply to this message so I get pinged.
  • I forgot to reply.
  • thatben
    Thanks, I'll give that a try rightaway
  • pusewicz
    https://github.com/pusewicz/wave-function-collapse-nim/blob/main/src/model.nim#L198 I'm getting:

    src/wave_function_collapse_nim.nim(200) wave_function_collapse_nim
    src/model.nim(198) iterate
    /opt/homebrew/Cellar/nim/2.0.4/nim/lib/system/orc.nim(504) nimDecRefIsLastCyclicStatic
    SIGSEGV: Illegal storage access. (Attempt to read from nil?)


    What am I doing wrong?
  • Elegantbeef
    You made a cyclical data type and hit an orc bug. On an off chance try --d:useMalloc
  • Seems it's fixed in devel
  • Just an orc issue and unrelated to the allocator
  • Though refc is lame you could also just do --mm:refc and avoid that cyclical issue
  • The cool stylish solution is to avoid cyclical data types but using an a seq and storing indexes into that instead of referencces
  • But yea orc does work with devel and this is a bug
  • demotomohiro
    In reply to
    pusewicz

  • https://github.com/pusewicz/wave-function-collapse-nim/blob/main/src/model.nim#L198 I'm getting:

    src/wave_function_collapse_nim.nim(200) wave_function_collapse_nim
    src/model.nim(198) iterate
    /opt/homebrew/Cellar/nim/2.0.4/nim/lib/system/orc.nim(504) nimDecRefIsLastCyclicStatic
    SIGSEGV: Illegal storage access. (Attempt to read from nil?)


    What am I doing wrong?
  • https://github.com/pusewicz/wave-function-collapse-nim/blob/main/src/model.nim#L182
    This code looks wrong as index can equal to lowestEntropyCells.len.
    I think sample proc is better: https://nim-lang.org/docs/random.html#sample%2CopenArray%5BT%5D
  • pusewicz
    Oooh, there is sample, nice!
  • This solved the issue, thanks!
  • In reply to
    Elegantbeef

  • The cool stylish solution is to avoid cyclical data types but using an a seq and storing indexes into that instead of referencces
  • Yeah, I'm trying to get this whole thing to work, and then figure out ways to improve it. I'll definitely will be asking for some code reviews! 😄
  • ringabout
    How I can configure a new gcc compiler for Nim compiler.?I want to switch to /usr/bin/gcc-14
  • It seems that I need to change gcc.exe in congig/nim.cfg
  • bandithedoge
    In reply to
    ringabout

  • How I can configure a new gcc compiler for Nim compiler.?I want to switch to /usr/bin/gcc-14
  • use the --cc option
  • ringabout
    I don't think this will work
  • Anyway I changed compilerExe: "gcc-14" which works for me
  • System64 ~ Flandre Scarlet
    proc setTilemap*(layer: Layer, value: ptmap.Tilemap): ptmap.Tilemap|pbmap.Bitmap =
      if(value.getTilengine()): raise newException(OwnershipError, "This object already belongs to Tilengine")
      var
        t: tilengine.Tilemap
        b: tilengine.Bitmap
        o: tilengine.ObjectList
      let ltype = layer.getType()
      case ltype:
      of LayerTile:
        result = newTilemap(layer.getTilemap(), false) 
      of LayerBitmap:
        result = newBitmap(layer.getBitmap(), false)
      of LayerObject: 
        result = nil # TODO
      of LayerNone: result = nil # TODO
      setTilemap(layer, value.getData())
      value.setTilengine(true)

    Wait, this is legal???
  • So it can either return a Tilemap or a Bitmap?
  • demotomohiro
    When return type is or type class, return type must be determined at compile time.
  • System64 ~ Flandre Scarlet
    In reply to
    demotomohiro

  • When return type is or type class, return type must be determined at compile time.
  • type
      BitmapImpl = object
        data: tilengine.Bitmap
        fromTilengine: bool
    
      Bitmap* = ref BitmapImpl
    
    type
      TilemapImpl = object
        data: tilengine.Tilemap
        fromTilengine: bool
    
      Tilemap* = ref TilemapImpl

    Those are my objects
  • demotomohiro
    In reply to
    System64 ~ Flandre Scarlet

  • type
      BitmapImpl = object
        data: tilengine.Bitmap
        fromTilengine: bool
    
      Bitmap* = ref BitmapImpl
    
    type
      TilemapImpl = object
        data: tilengine.Tilemap
        fromTilengine: bool
    
      Tilemap* = ref TilemapImpl

    Those are my objects
  • In your case, unless ltype is const, your proc cannot have multiple return types.
  • System64 ~ Flandre Scarlet
    In reply to
    demotomohiro

  • In your case, unless ltype is const, your proc cannot have multiple return types.
  • My code still compiles 🤔
  • What can I do if a function can return either a Tilemap or a Bitmap on runtime?
  • odexine
    In reply to
    System64 ~ Flandre Scarlet

  • What can I do if a function can return either a Tilemap or a Bitmap on runtime?
  • Object variant
  • System64 ~ Flandre Scarlet
  • odexine
    Yes
  • System64 ~ Flandre Scarlet
    So I can basically do a LayerItem object and depending of the type, I can set the right field?
  • odexine
    I think you got the right thinking yes
  • System64 ~ Flandre Scarlet
    In reply to
    odexine

  • I think you got the right thinking yes
  • Oh alright, and does it have to be a ref object?
  • odexine
    No
  • References only needed when the object stores itself
  • System64 ~ Flandre Scarlet
    Oh alright
    Nim is quite neat, you can replicate some kind of dynamic typing
  • System64 ~ Flandre Scarlet
    In reply to
    odexine

  • I think you got the right thinking yes
  • type
      LayerItem* = object
        case kind: LayerType
        of LayerTile: tilemap*: ptmap.Tilemap
        of LayerBitmap: bitmap*: pbmap.Bitmap
        else: discard

    Well, quite trivial to do
  • System64 ~ Flandre Scarlet
    Now can I access the Kind parameter?
  • like myLayerItem.kind?
  • odexine
    Yeah, its just another field
  • But you can’t assign after construction
  • System64 ~ Flandre Scarlet
    In reply to
    odexine

  • But you can’t assign after construction
  • Is it for all the fields?
  • Or only the kind field?
  • Oh alright
    Makes sense
  • bung8954
    is not GC-safe as it performs an indirect call is this certain or just possible ?
  • threefour
    When I had that, I had to add the {.gcsafe.} pragma to the caller function to reveal what the actual issue was with indirectly-called function.
  • bung8954
    my dependent lib cause this, it use json key store function name, seems safe, but am not sure safe to use cast forced mark it safe or not
  • NimEventer[IRC]#0000
    New thread by Hobbyman: Conversion-to-string-function is hard to find, see https://forum.nim-lang.org/t/11605
  • grumblygibson
    In reply to
    odexine

  • But you can’t assign after construction
  • _
    System64 ~ Flandre Scarlet

    In C++ you can assign variants after construction, which is very powerful. Nim is "safe by default" and does not let you modify after construction to change the type, but always lets you trade brevity for power if you really want to do that.
    https://nim-lang.org/docs/manual.html#types-cast-uncheckedassign
  • System64 ~ Flandre Scarlet
    In reply to
    grumblygibson

  • _
    System64 ~ Flandre Scarlet

    In C++ you can assign variants after construction, which is very powerful. Nim is "safe by default" and does not let you modify after construction to change the type, but always lets you trade brevity for power if you really want to do that.
    https://nim-lang.org/docs/manual.html#types-cast-uncheckedassign
  • Quite interesting
  • And C++ has variants too?
  • System64 ~ Flandre Scarlet
    Didn't even knew that
    Well, C++ is (VERY) complex
  • grumblygibson
    Just FYI because it's interesting, c++ also has views, iterators (generators), and slices (spans). It's pretty great, but still unsafe by default, and quite verbose. cpp2 pushes cpp closer to nim-like with the safe by default and laconic syntax philosophy.
  • System64 ~ Flandre Scarlet
    In reply to
    grumblygibson

  • Just FYI because it's interesting, c++ also has views, iterators (generators), and slices (spans). It's pretty great, but still unsafe by default, and quite verbose. cpp2 pushes cpp closer to nim-like with the safe by default and laconic syntax philosophy.
  • Wait CPP2 exists?
  • grumblygibson
    cpp2 is an experimental front end for c++ exploring what the syntax could be like. it generates c++ and compiles for you in the back end, a lot like nim and C. It's being actively developed.
  • System64 ~ Flandre Scarlet
    In reply to
    grumblygibson

  • cpp2 is an experimental front end for c++ exploring what the syntax could be like. it generates c++ and compiles for you in the back end, a lot like nim and C. It's being actively developed.
  • https://github.com/hsutter/cppfront
    Is it that?
  • And can we already use CPP2?
  • grumblygibson
    As I understand it, it lacks some of the fancier c++ stuff, but most things are already implemented.
  • just look at the commit history timestamps. the energy is impressive
  • System64 ~ Flandre Scarlet
    What about the build system and library management?
  • grumblygibson
    one thing cpp2 has I wish nim had, which is a better gradual workflow for how to migrate to the new language from existing code. cpp2 is a modular seamless drop-in, allowing heterogeneous code in c++ and cpp2, even within the same file. I'd love nim tooling to get to a point allowing something like this.
  • In reply to
    System64 ~ Flandre Scarlet

  • What about the build system and library management?
  • I don't think they touch that, existing tools will keep working for those needs.
  • System64 ~ Flandre Scarlet
    Oh alright
    I don't really like the build and library workflow of C++
  • System64 ~ Flandre Scarlet
    nimble does its job quite well
  • System64 ~ Flandre Scarlet
    proc `bitmap=`*(layer: Layer, value: pbmap.Bitmap) =
      if(value.getTilengine()): raise newException(OwnershipError, "This object already belongs to Tilengine")
      var
        t: tilengine.Tilemap
        b: tilengine.Bitmap
        o: tilengine.ObjectList
      let ltype = layer.getType()
      case ltype:
      of LayerTile:
        t = layer.getTilemap() 
      of LayerBitmap:
        b = layer.getBitmap()
      of LayerObject: 
        o = layer.getObjects()
      of LayerNone: discard
      setBitmap(layer, value.getData())
      value.setTilengine(true)
      case ltype:
      of LayerTile:
        if(t != nil): t.delete()
      of LayerBitmap:
        if(b != nil): b.delete()
      of LayerObject: 
        if(o != nil): o.delete()
      of LayerNone: discard
    
    proc `bitmapCopy=`*(layer: Layer, value: pbmap.Bitmap) =
      var
        t: tilengine.Tilemap
        b: tilengine.Bitmap
        o: tilengine.ObjectList
      let ltype = layer.getType()
      case ltype:
      of LayerTile:
        t = layer.getTilemap() 
      of LayerBitmap:
        b = layer.getBitmap()
      of LayerObject: 
        o = layer.getObjects()
      of LayerNone: discard
      setBitmap(layer, value.getData().clone())
      case ltype:
      of LayerTile:
        if(t != nil): t.delete()
      of LayerBitmap:
        if(b != nil): b.delete()
      of LayerObject: 
        if(o != nil): o.delete()
      of LayerNone: discard

    Knowing the fact you can do bitmap.clone() to create a copy
    Is it necessary to keep this bitmapCopy= accessor?
  • Imo it just complexifies the API
  • xkonti
    Has anybody used the export with except keyword? The manual mentions it but doesn't show it.

    Let's say I have a Dir* type and I defined getPath*() and setPath*() procs on it (in the same module). The same module contains many other procs that are marked as exported (*). How can I reexport the module but specifically skip the getPath, setPath?

    import private/dir
    
    export dir # but ignore getPath and setPath
  • rakgew
    R

    xkonti : thx for the new nim stream/videos (-:

  • xkonti
    In reply to
    R
    rakgew

  • xkonti : thx for the new nim stream/videos (-:

  • ♥️ I'm happy to hear some find them useful!
  • solitudesf
    In reply to
    xkonti

  • Has anybody used the export with except keyword? The manual mentions it but doesn't show it.

    Let's say I have a Dir* type and I defined getPath*() and setPath*() procs on it (in the same module). The same module contains many other procs that are marked as exported (*). How can I reexport the module but specifically skip the getPath, setPath?

    import private/dir
    
    export dir # but ignore getPath and setPath
  • export dir except getPath, setPath
  • In reply to
    xkonti

  • Has anybody used the export with except keyword? The manual mentions it but doesn't show it.

    Let's say I have a Dir* type and I defined getPath*() and setPath*() procs on it (in the same module). The same module contains many other procs that are marked as exported (*). How can I reexport the module but specifically skip the getPath, setPath?

    import private/dir
    
    export dir # but ignore getPath and setPath
  • the same as import
  • xkonti
    Aaaah... I thought it'd be export dir except [getPath, setPath]. Silly me 🤪
  • _
    solitudesf
    What if I have 2 overloads of getPath and I want to exclude only a specific one? I know I'm pushing it...
  • solitudesf
    In reply to
    xkonti

  • _
    solitudesf
    What if I have 2 overloads of getPath and I want to exclude only a specific one? I know I'm pushing it...
  • cant be bothered to test it, but i think if your provide the argument list it should work
  • xkonti
    Ok. I'll try it 🙂
  • Instantly turning into errors. I guess that functionality would be a stretch.
  • rakgew
    R
    In reply to
    xkonti

  • ♥️ I'm happy to hear some find them useful!
  • for sure. went through the short ones already, now I am looking into the longer stream recordings.

  • xkonti
    In reply to
    R
    rakgew

  • for sure. went through the short ones already, now I am looking into the longer stream recordings.

  • That's great to hear! Tonight will be another stream focusing on the commonFs and osFs. I'm doing some organizing in the project now so that it's easier to follow.
    I plan to make more short videos (10-20min), where I focus on a single topic and cover EVERYTHING about it (unlike the usual tutorials). Also I hope to make some videos that cover some smaller specific projects. But that will be probably more at a pace of 0.5-1 video per week.
  • rakgew
    R

    very nice - looking forward!
    really happy to see a stream where a nim project gets built from scratch.

  • xkonti
    I hope it's obvious that I have no idea what I'm doing 😅
  • .lisuwu_
    In reply to
    xkonti

  • I hope it's obvious that I have no idea what I'm doing 😅
  • hey you'll get over it eventually
  • just have some self confidence :P
  • xkonti
    In reply to
    .lisuwu_

  • hey you'll get over it eventually
  • That's why I decided to live-stream. Forces me to try explain things I don't understand instead of rage-quitting 😂
  • .lisuwu_
    creative idea actually
  • you have no choice but to go through the pain
  • xkonti
    Yup...
  • rakgew
    R
    In reply to
    xkonti

  • I hope it's obvious that I have no idea what I'm doing 😅
  • well you bring experience from other languages, which is vecry interesting to see.

  • In reply to
    xkonti

  • That's why I decided to live-stream. Forces me to try explain things I don't understand instead of rage-quitting 😂
  • dong a good job, as far as I seen. (-:

  • xkonti
    That's what's fun about learning new programming languages. You notice similarities, differences, and what consequences those changes bring. Gives you a different perspective on what you already know.
  • Currently I'm upset that Primeagen is learning Zig instead of Nim 😠
  • rakgew
    R

    sad to hear that. his "review" of nim 2.0 release I found a little strange.

  • In reply to
    xkonti

  • That's what's fun about learning new programming languages. You notice similarities, differences, and what consequences those changes bring. Gives you a different perspective on what you already know.
  • right on.

  • pmunch
    _
    @rakgew if you want more Nim stream content you might enjoy mine: https://youtube.com/@peterme
  • rakgew
    R

    pmunch (@_discord_392962235737047041:t2bot.io) thank you - I did already, quite enjoyed your streams and videos! :-D

  • ..also: every advent of code I hope for pmunch content. (-;
  • System64 ~ Flandre Scarlet
    image.png
  • Is it normal I always have this?
  • jmgomez
    Nope, fill an issue with a small repro pls
  • System64 ~ Flandre Scarlet
    In reply to
    jmgomez

  • Nope, fill an issue with a small repro pls
  • I just open VS Code
  • and I'm on Linux
  • System64 ~ Flandre Scarlet
    Btw
    Do you think there is something missing in the Math library?
  • bulletxbt
    Any good books for nim?
  • System64 ~ Flandre Scarlet
    In reply to
    bulletxbt

  • Any good books for nim?
  • Nim in Action and Mastering Nim
  • bulletxbt
    Is there a nim equivalent for python's if __name__ == "__main__"?
  • that_dude.
    Something along the lines of 'If ismainmodule'
  • polylokh_39446
    _
    when isMainModule:
  • that_dude.
    When for compile time, if for run time
  • __nycto__
    Is there a way to enable allocation logging in Nim such that I can see the types that are being created and destroyed? I’m fighting a memory overwrite issue in a large-ish Nim app, and setting a breakpoint in the underlying allocator means I only have visibility into the raw pointer
  • Elegantbeef
    For destroy you could use finalizers/destructors
  • You really should just use valgrind with -d:useMalloc
  • bulletxbt
    setFilePos(self.stream, self.baseOffset + info["offset"].getInt)

    type mismatch
    
    Expression: setFilePos(self.stream, self.baseOffset + getInt(info["offset"], 0))
    [1] self.stream: FileStream
    [2] self.baseOffset + getInt(info["offset"], 0): int
    
    Expected one of (first mismatch at [position]):
    [1] proc setFilePos(f: File; pos: int64; relativeTo: FileSeekPos = fspSet)
    Because it's FileStream instead of File right, how else do I seek pos with the stream
  • Elegantbeef
    setPosition
  • bulletxbt
    Literally just saw it in the docs
  • Idk how I missed it
  • Elegantbeef
    Reading is hard
  • bulletxbt
    With 2hr sleep yeah
  • xkonti
    I get that roughly 15 times an hour. VsCode connected to WSL2.
    Purely on Windows, NimSuggest doesn't even try. It just crashes 100% of time.
  • System64 ~ Flandre Scarlet
    In reply to
    xkonti

  • I get that roughly 15 times an hour. VsCode connected to WSL2.
    Purely on Windows, NimSuggest doesn't even try. It just crashes 100% of time.
  • very weird!
    Well, this is the Nim's big con
  • xkonti
    In reply to
    System64 ~ Flandre Scarlet

  • very weird!
    Well, this is the Nim's big con
  • Yup 😦
  • bulletxbt
    echo "Base Offset: ", self.baseOffset, " | Offset: ", info["offset"], " | Setting position to: ", self.baseOffset + info["offset"].getInt

    >>> Base Offset: 120624 | Offset: "130815185" | Setting position to: 120624

    ? Can someone explain
  • polylokh_39446
    _
    sounds like that .getInt is returning 0
  • bulletxbt
    info["offset"].getInt is returning 0
  • But I get JsonNode errors when I don't use .getInt
  • type mismatch
    
    Expression: parseInt(info["offset"])
    [1] info["offset"]: JsonNode
    
    Expected one of (first mismatch at [position]):
    [1] func parseInt(s: string): int
  • polylokh_39446
    _
    .getInt returns 0 if it's not a JInt. Probably because it's a string
  • try .getStr.parseInt
  • bulletxbt
    In reply to
    _
    polylokh_39446

  • try .getStr.parseInt
  • undeclared field: 'getInt' for type system.string
  • polylokh_39446
    _
    ok, now try .getStr.parseInt
  • parseInt is provided by strutils
  • bulletxbt
    In reply to
    _
    polylokh_39446

  • ok, now try .getStr.parseInt
  • Worked :)
  • Thanks
  • polylokh_39446
    _
    import std/[json, strutils]
    
    let j = parseJson "\"123\""
    # ("JsonNode(isUnquoted: false, kind: JString, str: \"123\")", "\"123\"", 123, 0)
    echo (j.repr, j.getStr.repr, j.getStr.parseInt, j.getInt)
  • zumi.dxy
    In reply to
    xkonti

  • I get that roughly 15 times an hour. VsCode connected to WSL2.
    Purely on Windows, NimSuggest doesn't even try. It just crashes 100% of time.
  • i think its problem is that it polls continuously and it can't exactly handle incomplete syntax
  • yet, hopefully
  • __nycto__
    In reply to
    Elegantbeef

  • For destroy you could use finalizers/destructors
  • Is there a generic way to do this for all types?
  • In reply to
    Elegantbeef

  • You really should just use valgrind with -d:useMalloc
  • I’m integrating with an emulator that has its own allocators, which has made this tougher than I was expecting
  • Elegantbeef
    Nope sadly not
  • sOkam! 🫐
    what could make HashSet[Path].items fail as if it didn't exist, but HashSet[Path].pairs work normally?
  • Elegantbeef
    Are you explicitly calling the iterator inside a generic?
  • sOkam! 🫐
    nope, afaik. its in a for loop
  • # does not work, says items does not exist for HashSet[Path]
    for entry in connectors: result.add entry
    # does not work either, same error
    result = entry.toSeq
    
    # works
    for entry in connectors.pairs: result.add entry.value
  • *
    var connectors = initHashSet[Path]()
    
    # does not work, says items does not exist for HashSet[Path]
    for entry in connectors: result.add entry
    # does not work either, same error
    result = entry.toSeq
    
    # works
    for entry in connectors.pairs: result.add entry.value
  • Elegantbeef
    and does connectors.items work?
  • odexine
    How do you import sets
  • Maybe you excluded it by mistake
  • horizonrce
    Is there smth like .replace() in nim
  • For strings
  • So like "abcd".replace("cd", "ba")
  • * So like "abcd".replace("cd", "ba") = "abba"
  • polylokh_39446
    _
    strutils has that
  • horizonrce
    In reply to
    _
    polylokh_39446

  • strutils has that
  • Aight ty
  • brotherbrother1
    Hey everyone, in windows. I dont succeed to list other running process by name and pid.
    do you think its possible with nim ?
  • PMunch[IRC]#0000
  • Using either winim if things are wrapper there, or Futhark to automatically wrap the required headers
  • m4ul3r
    In reply to
    brotherbrother1

  • Hey everyone, in windows. I dont succeed to list other running process by name and pid.
    do you think its possible with nim ?
  • import winim
    import std/[strutils, strformat]
    
    proc printNameAndPid() =
      var pe32: PROCESSENTRY32W
      var hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
      if INVALID_HANDLE_VALUE == hProcSnap: 
        return 
      pe32.dwsize = sizeof(PROCESSENTRY32W).DWORD
      if Process32First(hProcSnap, pe32):
        while Process32Next(hProcSnap, pe32):
          var 
            name = $$pe32.szExeFile
            pid = pe32.th32ProcessId
          echo &"{name}: {pid}"
      CloseHandle(hProcSnap)
    
    printNameAndPid()
  • gogolxdong666
  • brotherbrother1
    _
    m4ul3r
    and
    _
    pmunch
    , thank you very much for your usefull and fast response !!

    I will test that right now!
  • jmgomez
    In reply to
    System64 ~ Flandre Scarlet

  • I just open VS Code
  • the issue is with your code, not because you open vscode 🙂
  • System64 ~ Flandre Scarlet
    In reply to
    jmgomez

  • the issue is with your code, not because you open vscode 🙂
  • My code is fine?
  • jmgomez
    so nimsuggest doesnt crash?
  • System64 ~ Flandre Scarlet
    In reply to
    jmgomez

  • so nimsuggest doesnt crash?
  • It does
    And I don't have good autocompletion
  • jmgomez
    So fill an issue with the code that makes it crash
  • System64 ~ Flandre Scarlet
    $ nimsuggest --find
    Error: cannot open '/usr/lib/system.nim'
    lineinfos.nim(314)       raiseRecoverableError
    Error: unhandled exception: cannot open '/usr/lib/system.nim' [ERecoverableError]
  • Is that normal?
  • this file is stored in /usr/lib/nim
  • I wonder if it's the reason, and if it's possible to override this path
  • System64 ~ Flandre Scarlet
    I think using the right path would solve the problem
  • goerge_lsd
    _
    simplest way to set -d:ssl in project settings :-?
  • System64 ~ Flandre Scarlet
    In reply to
    jmgomez

  • So fill an issue with the code that makes it crash
  • I think I solved the issue??
    https://github.com/nim-lang/Nim/issues/23201
  • polylokh_39446
    _
    In reply to
    _
    goerge_lsd

  • simplest way to set -d:ssl in project settings :-?
  • nim.cfg, e.g.:
    $ cat nimble/tests/nim.cfg
    --path:"$nim/"
    --path:"../src/"
    --mm:refc
  • jmgomez
    does the solution work for you then?
  • dawidek.2137
    is there a command in nimble to "install" the project I am working on (just like you would install an external library) or do I have to expose the generated binaries to system path myself?
  • nnsee
    er, nimble install?
  • dawidek.2137
    🤦
  • System64 ~ Flandre Scarlet
    In reply to
    jmgomez

  • does the solution work for you then?
  • Yes!
  • I finally have autocompletion!
  • ravinder387
    _
    what is NimNode?
  • Zoom
    In reply to
    _
    ravinder387

  • what is NimNode?
  • It's an object, representing a node in an abstract syntax tree - a data structure used to parse, manipulate and compile Nim.
  • System64 ~ Flandre Scarlet
    Is it a good idea to do an iterator that yelds mutable objects?
  • griffith1deadly
    In reply to
    System64 ~ Flandre Scarlet

  • Is it a good idea to do an iterator that yelds mutable objects?
  • depends of use case
  • if object very big - maybe good, because dont cause copies
  • System64 ~ Flandre Scarlet
    In reply to
    griffith1deadly

  • if object very big - maybe good, because dont cause copies
  • I want the object to be mutable
    It's an array of Colors, and I wrote some converters
  • System64 ~ Flandre Scarlet
    for color in dat.dataPtr.toOpenArray(0, dat.len):

    Is it possible to declare color as var?
  • daichimpo
    Who the mods?
  • @Moderator got a steam scam DM from a user here
  • pmunch
    _
    Did you report the user to Discord?
  • daichimpo
    Ye
  • pmunch
    _
    Could you PM me the username?
  • daichimpo
    Done
  • Thanks, Munch!
  • System64 ~ Flandre Scarlet
    for color in (dat.dataPtr.toOpenArray(0, dat.len)).mitems:
        color.convert(convert)

    is it normal it says mitems is undeclared?
  • nervecenter
    In reply to
    System64 ~ Flandre Scarlet

  • for color in (dat.dataPtr.toOpenArray(0, dat.len)).mitems:
        color.convert(convert)

    is it normal it says mitems is undeclared?
  • Is it a var openarray?
  • You may need to do the conversion beforehand
    var color_array = dat.dataPtr.toOpenArray(0, dat.len)
    for color in color_array.mitems:
        color.convert(convert)
  • System64 ~ Flandre Scarlet
    In reply to
    nervecenter

  • You may need to do the conversion beforehand
    var color_array = dat.dataPtr.toOpenArray(0, dat.len)
    for color in color_array.mitems:
        color.convert(convert)
  • invalid type: 'openArray[Color]' for var
  • type
      Span*[T] = object
        data: ptr UncheckedArray[T]
        length: int
    
    func new*[T](_: typedesc[Span], data: ptr UncheckedArray[T], length: int): Span[T] =
      return Span[T](data: data, length: length)
    
    func `len`*[T](span: Span[T]): int =
      return span.length
    
    func `dataPtr`*[T](span: Span[T]): ptr UncheckedArray[T] =
      return span.data
    
    func `[]`*[T](span: Span[T]; idx: SomeInteger): T =
      return span.data.toOpenArray(0, span.length)[idx]
    
    proc `[]=`*[T](span: Span[T]; idx: SomeInteger, value: T) =
      span.data.toOpenArray(0, span.length)[idx] = T

    This is the type I'm working on
  • nervecenter
    Should probably be a seq then, openarray is technically just a receptor for either array or seq
  • System64 ~ Flandre Scarlet
    In reply to
    nervecenter

  • Should probably be a seq then, openarray is technically just a receptor for either array or seq
  • and what if I implement an iterator in my Span object?
  • nervecenter
    What's the point of it? To give a window into a raw array from a pointer?
  • A "slice" so to speak?
  • demotomohiro
  • System64 ~ Flandre Scarlet
    thanks!
  • Bruh fuck CPU endianess
  • Amun-Ra[IRC]#0000
    chainsaw it even
  • pmunch
    _
    In reply to
    System64 ~ Flandre Scarlet

  • Bruh fuck CPU endianess
  • Without endianess all the bits would just be stored in a big jumble!
  • That'd be terrible!
  • odexine
    mixed endian
  • every odd byte is little, every even byte is big
  • zidsal
    _
    everything should use big endian as bigger is always better
  • odexine
    bigger endian
    across 8 bytes, all LSBs are on byte 1, next on byte 2, until MSB on byte 8
  • zidsal
    _
    I think endian should be tied to daylight savings of the server. little endian if we're +1 hour ahead else +0. servers on time zones without daylight savings are undefined behaviour and are left to the implementation detail of the server
  • odexine
    RIP asia
  • strogon14[IRC]#0000
    I promote use of the imperial byte, which is 12 bits.
  • odexine
    12 sounds neat for imperial. try 11.647
  • strogon14[IRC]#0000
    1 foot = 12 inch
  • odexine
    bit isnt imperial
  • 1 foot = ? cm
  • Amun-Ra[IRC]#0000
    $1 = 1€
  • odexine
    i dont know what the current values for both are
  • Amun-Ra[IRC]#0000
    same
  • lives in non-euro country
  • odexine
    lives in neither-europe-nor-north-america
  • strogon14[IRC]#0000
    $ = € * 1.085
  • odexine
    lets make that the constant for the imperial bit
  • imperial bit = SI bit * 1.085
  • then an imperial byte can be 12 imperial bits
  • Amun-Ra[IRC]#0000
    and imperial yardbyte 60 imperial bytes
  • odexine
    sounds great
  • Amun-Ra[IRC]#0000
    and fun
  • odexine
    why note call it a yarte
  • not*
  • Amun-Ra[IRC]#0000
    :P
  • odexine
    then a myle
  • Amun-Ra[IRC]#0000
    yarte looks british to me, let's call it yart
  • odexine
    isnt imperial british
  • Amun-Ra[IRC]#0000
    yes, but some uk and us units differ
  • odexine
    oh does that mean we'll have long bytes and short bytes too then
  • Amun-Ra[IRC]#0000
    ounce, gallon, cup…
  • let's 1 implerial nibble be an 1/3 of imperial byte
  • odexine
    implerial sounds cool as a new kind of unit category ngl
  • Amun-Ra[IRC]#0000
    right, until you look in the details
  • System64 ~ Flandre Scarlet
    mySeq <- myElement

    Would it be a good syntaxic sugar to append an element to a seq?
  • zidsal
    _
    just because you can make custom dsl's doesn't mean you should make custom dsls at every opportunity
  • nervecenter
    In reply to
    System64 ~ Flandre Scarlet

  • mySeq <- myElement

    Would it be a good syntaxic sugar to append an element to a seq?
  • Just use add without parens:
    mySeq.add myElement
  • System64 ~ Flandre Scarlet
    In reply to
    nervecenter

  • Just use add without parens:
    mySeq.add myElement
  • Oh wait, you don't have to use the ()?
  • nervecenter
    Not if it's just one argument, or a second argument but the first is using UFCS
  • System64 ~ Flandre Scarlet
    what is UFCS?
  • nervecenter
    add(mySeq, meElement)  # Not UFCS
    mySeq.add(myElement)   # With UFCS
  • *
    add(mySeq, myElement)  # Not UFCS
    mySeq.add(myElement)   # With UFCS
  • First arguments can be brought out front and the proc/func can be called almost like a method
  • This allows for easy chaining so long as the return types check out
  • threefour
    And they are equivalent. One's not necessarily better than the other.
  • System64 ~ Flandre Scarlet
    Ah yeah
  • they're equivalent
  • just different notations
  • nervecenter
    In reply to
    threefour

  • And they are equivalent. One's not necessarily better than the other.
  • Situational, and the use should be appropriate to the context, as with everything
  • .bobbbob
    why might defer: db.close() work in debug mode but not in release mode?
  • morgan
    are nimble tasks available in a repo which imports the package?
  • i am guessing no
  • i am splitting out my clap bindings from my plugin framework, and for the bindings, i'd like to have a nimble task to bundle the executable
  • i suppose i could write it as its own nimscript file though
  • but i'd like to have it in the bindings package, be usable in the framework package which imports the bindings, and if someone imports the framework library, to still have it be usable
  • Robyn [She/Her]
    In reply to
    morgan

  • are nimble tasks available in a repo which imports the package?
  • You could make a hybrid package and then the main package would have the tasks available as a command perhaps?
  • Or you could write a file that isn't imported by the main package, and is imported in the nimble file itself
  • morgan
    oh hm yea having it build a binary thats then made available
  • Robyn [She/Her]
    * You could make a hybrid package and then the main binary would have the tasks available as a command perhaps?
  • morgan
    either way it's cool to finally release a package
  • and i can pull that code out of my plugin framework and restructure its code a bit
  • grumblygibson
    How can I change debug message output?
    Let's say that I ship debug builds for customers to use to generate tracebacks and other kinds of messaging. (Obviously it would be better to not ship debug builds and improve try/except)
    The builds generate path information in the output like this:
    /home/me/software/nim/lib/system/fatal.nim(53) sysFatal

    If I wanted that to be anonymous, is the only way to then build in an environment with anonymous paths? Or is there a way to override such strings?
    I will be creating a formal environment for this, but I don't have it yet.
  • kdot_227

    This message is being deleted…

  • This message is being deleted…

  • griffith1deadly
    @Moderator
  • Elegantbeef
    Damn that was a real user at a pooint
  • point*
  • Seems their account was compromised
  • Amun-Ra[IRC]#0000
    hmm
  • Elegantbeef
    I figured they just were making bot accounts
  • NimEventer[IRC]#0000
    New Nimble package! clap - Clap audio plugin bindings, see https://github.com/morganholly/nim-clap
  • strogon14[IRC]#0000
    I would consider changing the name 'nimplugin' to something more specific, though.
  • _
    @_discord_277133333773811712:t2bot.io
    : congrats on getting your package released.
  • Elegantbeef
    I still like the dumb idea to name it quarterinch
  • strogon14[IRC]#0000
    or pluck
  • Elegantbeef
    I don't see any git tags! https://github.com/beef331/graffiti
  • morgan
    it's now called offbeat
  • im still renaming stuff
  • yea i should
  • Elegantbeef
    I religiously use graffiti after any commit, like someone that is holding on tight for sensible builds
  • threefour
    Do you have it in a Git hook?
  • Elegantbeef
    I have thought about it 😄
  • I do have a git hook to run nimble test --silent on a commit
  • 
    #! /usr/bin/env fish
    
    nimble dump --silent &> /dev/null
    
    if test $status -ne 0
      return 0
    else
      nimble test --silent
    end
    

    For the super complex hook if anyone cares

  • horizonrce
    how do I remove the first 2 lines in a multiline string
  • Elegantbeef
    std/strutils has delete
  • Robyn [She/Her]
    In reply to
    morgan

  • either way it's cool to finally release a package
  • Fair! I've released a few but don't know if anyone has actually used em
  • morgan
    In reply to
    morgan

  • it's now called offbeat
  • i added build instructions to offbeat and nim-clap, but the bundling part is just for mac at the moment
  • Robyn [She/Her]
    Random question: How hard would it be to make it so that the AST of an unchanged Nim file could be loaded from a cache instead of parsing the code and simplifying it?
  • Is that possible? Or do generics and macros ruin that?
  • As well as compile time variables I'd imagine
  • ...and code that uses staticRead ig
  • Elegantbeef
    The amount of times you've asked about IC indirectly robyn is too often
  • Robyn [She/Her]
    I know :>
  • This time it's on purpose
  • Elegantbeef
    Nim uses pointers for the AST so it's not possible without fixing the pointers
  • Robyn [She/Her]
    As in the ref objects and such?
  • PNode = ref TNode, etc
  • Elegantbeef
    Right
  • Nim uses pointer equality as matching for many things
  • Which means to have IC work without changing to a packed AST you need to remap pointers to their proper values
  • Robyn [She/Her]
    Wouldn't that be possible to fix via NodeIndexes and such? I think Nimskull talked about it, is there a reason why it's not already done?
  • Elegantbeef
    I mean that requires rewriting to a packed DOD AST
  • Robyn [She/Her]
    Ah
  • Elegantbeef
    Nim does have a packed AST for the IC but only for serialization
  • Robyn [She/Her]
    Via rod files?
  • Elegantbeef
    Yes
  • Robyn [She/Her]
    Weren't those also very buggy anyway?
  • Elegantbeef
    No?
  • Robyn [She/Her]
    not buggy, incomplete
  • Elegantbeef
    Well yea cause IC is not done
  • Robyn [She/Her]
    Fair enough
  • Elegantbeef
    Araq keeps working on other things, and we don't even know what he's working on now
  • Robyn [She/Her]
    So if it does get done, it'd be done by the community and likely not him?
  • Elegantbeef
    I'm not going to say anything for certain, but yea there are few public commits in Araq
  • Robyn [She/Her]
    Yeah fair enough
  • Oh well
  • Elegantbeef
    As it stands I think Ringabout now makes the most PRs
  • Robyn [She/Her]
    Yeah I remember
  • I seen their commits and fixes semi-often
  • .bobbbob
    god I finally found the fucking problem, I was sending image data to ImageMagick through execCmdEx with a pipe but if two threads did that at the same time imagemagick got stuck in an infinite loop for some reason, causing the db to never close and the client to eventually time out and of course no error message printed, so I write it to a tmp file first and it works
  • brotherbrother1
    Hey everyone, do you know how to deals with TLS/SSL in nim ?
    I dont see easy way to do that 😦
  • michaelb.eth
    In reply to
    brotherbrother1

  • Hey everyone, do you know how to deals with TLS/SSL in nim ?
    I dont see easy way to do that 😦
  • what’s the context?
  • Elegantbeef
    SSLContext 😛
  • michaelb.eth
    you may want to look at nim-bearssl and how its used by e.g. nim-chronos if you don’t want to involve OpenSSL
  • In reply to
    Elegantbeef

  • SSLContext 😛
  • i knew that was coming, was counting down from 10, only got to 6
  • Elegantbeef
    I forgive you
  • brotherbrother1
    I use 'import ws' to use websocket.
    And this code:
    var ws = await newWebSocket(vv)

    But as i rember, my first objectivr was using socket directly + tls
  • it was not nice with the additionnals DLL of openssl
  • michaelb.eth
    In reply to
    brotherbrother1

  • it was not nice with the additionnals DLL of openssl
  • maybe give nim-websock a look: https://github.com/status-im/nim-websock
  • it uses chronos so bearssl will be baked in
  • Robyn [She/Her]
    In reply to
    michaelb.eth

  • you may want to look at nim-bearssl and how its used by e.g. nim-chronos if you don’t want to involve OpenSSL
  • BearSSL itself doesn't seem like it has many recent commits, isn't that Not Great™️ with a project regarding internet security?
  • brotherbrother1
    In reply to
    michaelb.eth

  • i knew that was coming, was counting down from 10, only got to 6
  • I think i already find this library but i dont find a usefull example to use socket with it
  • So i stop using it
  • michaelb.eth
    In reply to
    Robyn [She/Her]

  • BearSSL itself doesn't seem like it has many recent commits, isn't that Not Great™️ with a project regarding internet security?
  • just depends, if it has implemented the functionality correctly for the subset of tls it satisfies, there’s not necessarily much to do
  • Robyn [She/Her]
    Fair
  • brotherbrother1
    I will thank youuu !
  • zidsal
    _
    _
    ElegantBeef
    I guess you'll need to make a new library just to use the name quarterinch
  • Elegantbeef
    Nah I do not do VST plugins
  • It only makes sense as an audio plugin or a dick joke!
  • zidsal
    _
    I was about to suggest the later but decided against it
  • I'm going to go brainstorm library ideas that can use the name quarterinch
  • congrats elegentbeef you're now writing a digital signal processing library and calling it quarterinch
  • Elegantbeef
    Insert sad lion meme here
  • zidsal
    _
    I legitimately just signed up for a chatgpt account just to ask for suggestions
  • Elegantbeef
    I'm sorry for your loss
  • It's not a name searching for a library
  • It was a library searching for a name
  • Quarter inch for a audio plugin is obscure enough that it tickles my brain
  • zidsal
    _
    tell me with a straight face that you don't just make librarys because you thin of cool names
  • * tell me with a straight face that you don't just make librarys because you think of cool names
  • Elegantbeef
    I don't
  • Though I did make an image comparison library like diffimg named pam for testing my game's rendering
  • zidsal
    _
    well played sir, I can't currently see your face
  • Elegantbeef
    Pam is a great name for an image diff library
  • zidsal
    _
    testing? we do that here? I thought we just slapped an early access label on it and charged users for the opportunity to test for you
  • Robyn [She/Her]
    In reply to
    _
    zidsal

  • * tell me with a straight face that you don't just make librarys because you think of cool names
  • For me it's the other way around :)
  • Napkins for a library describing a packet format for a protocol :P
  • Elegantbeef
    I just like puns or obscure names
  • Robyn [She/Her]
    Like Traitor? :p
  • Elegantbeef
    Yes
  • Kashae, Micros, Gooey, Seeya, Dodger, ....
  • The aforementioned Graffiti is the best methinks
  • Robyn [She/Her]
    Lol
  • Elegantbeef
    Dodger might be a bit of a think, but idk
  • "What does dodging have to do with matrix" is not a long path
  • Robyn [She/Her]
    I never seen the movies and I can guess :p
  • strogon14[IRC]#0000
    _
    ElegantBeef
    : btw, VST is the name of a specific audio plugin format, not a generic term for audio plugins. Though, I guess, it has become that in the minds of the computer audio users (not audio developers). Like we use "Tempo" as a generic term for paper handkerchiefs in Germany (I know US examples exists, but I don't know them off the top of my head).
  • Elegantbeef
    Kleenex is the Americanism for Tempo
  • strogon14[IRC]#0000
    Ah, yes.
  • Elegantbeef
    It's just genericized trademark
  • strogon14[IRC]#0000
    Yeah, I think there's a specific term for those, but I can't remember/didn't find it.
  • Anyway, today VST is just one format (though the the one with overwhelmingly the most support) amongst about half a dozen (AU, CLAP, LV2, whatever Protools uses, etc.)
  • weltraumpert
    im new in nim, is this correct information (i get it from chatgpt) :

    In Nim programming language, let and var are used to declare variables, and they have different characteristics:

    let:
    Declares a variable whose value can be changed.
    Similar to var in other languages.
    Must be initialized when declared.

    var:
    Declares a variable whose value can be changed.
    Can be declared without an initial value.
    Similar to var in other languages.
  • user2m
    _
    In reply to
    weltraumpert

  • im new in nim, is this correct information (i get it from chatgpt) :

    In Nim programming language, let and var are used to declare variables, and they have different characteristics:

    let:
    Declares a variable whose value can be changed.
    Similar to var in other languages.
    Must be initialized when declared.

    var:
    Declares a variable whose value can be changed.
    Can be declared without an initial value.
    Similar to var in other languages.
  • yes that's correct, but the best way to get a feel for let, var and const is simply to play with the language . also id look @ this book in conjunction with cgpt https://ssalewski.de/nimprogramming.html
  • NimEventer[IRC]#0000
    New thread by weltraumpert: Nim logo, see https://forum.nim-lang.org/t/11608
  • kots
    Uh, let is a variable whose value cannot be changed, isn't it?
  • odexine
    I HELPED YOU WITH THAT NAME
  • user2m
    _
    In reply to
    kots

  • Uh, let is a variable whose value cannot be changed, isn't it?
  • yeah lol I totally missed that !
  • kots
    There's a perfectly good manual right here that explains, among other things, the difference between let and var: https://nim-lang.org/docs/manual.html
  • There's no need to resort to things like chatgpt which are known to produce complete nonsense 90% of the time
  • Elegantbeef
    Who is
    _
    odexine
    ?
  • They have this weird notion that they helped with "Traitor"
  • odexine
    💀
  • Elegantbeef
    I'm just playing into the name
  • morgan
    In reply to
    kots

  • There's a perfectly good manual right here that explains, among other things, the difference between let and var: https://nim-lang.org/docs/manual.html
  • yeah read the manual instead of asking the incorrect plagiarism machine
  • Elegantbeef
    I have a name!
  • morgan
    In reply to
    strogon14[IRC]#0000

  • _
    ElegantBeef
    : btw, VST is the name of a specific audio plugin format, not a generic term for audio plugins. Though, I guess, it has become that in the minds of the computer audio users (not audio developers). Like we use "Tempo" as a generic term for paper handkerchiefs in Germany (I know US examples exists, but I don't know them off the top of my head).
  • yeah when people join the logic discord and ask about vsts (logic only supports au) when they mean plugins in general
  • lol
  • misigomartin
    _
    hey guys so i cant see my nim tokens on my dym wallet despite the explorer saying that the tokens are there what could be the problem?
  • Elegantbeef
    Damn this is a first
  • Nim is a programming language not a shitcoin
  • abaer
    In reply to
    Elegantbeef

  • Nim is a programming language not a shitcoin
  • Liar. It's a shitcoin.
  • Elegantbeef
    Have I been writing in shitcoin this entire time
  • I knew something was sticky
  • abaer
    In reply to
    Elegantbeef

  • I knew something was sticky
  • That's just my gum.
  • Robyn [She/Her]
    In reply to
    _
    misigomartin

  • hey guys so i cant see my nim tokens on my dym wallet despite the explorer saying that the tokens are there what could be the problem?
  • This is the Nim programming server, not the cryptocurrency, sorry!
  • solitudesf
    In reply to
    _
    misigomartin

  • hey guys so i cant see my nim tokens on my dym wallet despite the explorer saying that the tokens are there what could be the problem?
  • i stole it
  • Elegantbeef
    I thought I stole it
  • abaer
    I stole this honey.
  • Elegantbeef
    Your name is aforg but you're clearly abaer
  • abaer
    In reply to
    Elegantbeef

  • Your name is aforg but you're clearly abaer
  • I'm just going to borrow that now. Thank you for a new username idea.
  • odexine
    its not the first time beef lol
  • been a few times someone has asked about a cryptocurrency called NIM (this time all caps iirc)
  • ah, the shortcut (ticker?) is NIM, full name is Nimiq it seems
  • Robyn [She/Her]
    Honestly wondering if it'd be worth wrapping the Python library 'Langchain' in Nim
  • It probably isn't but idk
  • May just be better to wrap the REST API
  • weltraumpert
    In reply to
    _
    user2m

  • yes that's correct, but the best way to get a feel for let, var and const is simply to play with the language . also id look @ this book in conjunction with cgpt https://ssalewski.de/nimprogramming.html
  • I don't really understand about "the similar aspect" between var and let, var value can be change while let can't, for me it's like a const, not a var.
  • Elegantbeef
    Except const exists and is a compile time constant
  • weltraumpert
    In reply to
    Elegantbeef

  • Except const exists and is a compile time constant
  • So, "let" is more like "const" instead of "var," right? The only difference is that "const" is evaluated at compile time, whereas "let" is evaluated at run time. Or is there something wrong in my understanding?
  • Elegantbeef
    let and var are similar cause they're runtime values
  • const is a static value and the most different
  • Since let is at runtime it's totally possible to mutate using unsafe mechanisms
  • weltraumpert
    ok now I'm understand 🤣, The book I read was too long-winded, I was almost confused because of it
  • griffith1deadly
    In reply to
    Elegantbeef

  • Since let is at runtime it's totally possible to mutate using unsafe mechanisms
  • const also can be mutated with some unsafe mechanisms (in C for sure, in Nim idk)
  • Elegantbeef
    Const does not have an address in Nim
  • So to change it you have to write in the .data segment
  • So whilst you can do it... good luck
  • griffith1deadly
    In reply to
    Elegantbeef

  • So to change it you have to write in the .data segment
  • .data also can be mofidied in runtime
  • so..
  • Elegantbeef
    Sure
  • griffith1deadly
    atleast on windows
  • * .data also can be modified in runtime
  • Elegantbeef
    The amount of work you have to do to change a const is more complex than myLet.addr[] = ...
  • griffith1deadly
    sure
  • Amun-Ra[IRC]#0000
    const often can't be mutated in any way in C
  • tamada_.
    Hello, is nim stable?
  • solitudesf
    In reply to
    tamada_.

  • Hello, is nim stable?
  • yeah, just dont use async, orc, threading or nimble

    stable enough
  • horizonrce
    In reply to
    tamada_.

  • Hello, is nim stable?
  • Is anything stable
  • Define "stable"
  • A lot of things are unpredictable
  • Amun-Ra[IRC]#0000
    stable? a house full of horses
  • abaer
    In reply to
    tamada_.

  • Hello, is nim stable?
  • dont use pointers or fuck your mother and you should be good.
  • i need a drink after reading backlog.
  • Amun-Ra[IRC]#0000
    try not to use cast[]()

You're viewing a snapshot of events from 2024-05-17. Use a Matrix client to start chatting in this room.

May 2024

  1. Sun
  2. Mon
  3. Tue
  4. Wed
  5. Thu
  6. Fri
  7. Sat
  8. 1
  9. 2
  10. 3
  11. 4
  12. 5
  13. 6
  14. 7
  15. 8
  16. 9
  17. 10
  18. 11
  19. 12
  20. 13
  21. 14
  22. 15
  23. 16
  24. 17
  25. 18
  26. 19
  27. 20
  28. 21
  29. 22
  30. 23
  31. 24
  32. 25
  33. 26
  34. 27
  35. 28
  36. 29
  37. 30
  38. 31

Official Matrix channel for the Nim programming language. This channel is bridged with our main Discord and Gitter channels.

This room is accessible because it was set to world readable by @dom96:matrix.org on 2021-06-18.

This room is being indexed by search engines (more info).

Developer options

Toggles

Backend timing

todo: window.tracingSpansForRequest

Room ID

!EtGqjSRNQoJCbpCJSF:matrix.org