Re: tye and container whoes
Yes you can nest objects.
Re: application file/folder structure. passing nim options from nimble build.
That's one way of doing it.
Re: tye and container whoes
> [https://peterme.net/tips-and-tricks-with-implicit-return-in-nim.html](https://peterme.net/tips-and-tricks-with-implicit-return-in-nim.html) Haha, you're going to fast for me :) my programming skills are 'minimal' and mostly POV-Ray SDL so I try to go step by step. I'll study! Thanks.
Re: tye and container whoes
You can probably shorten the code even more by: * using implicit result variable [https://peterme.net/tips-and-tricks-with-implicit-return-in-nim.html](https://peterme.net/tips-and-tricks-with-implicit-return-in-nim.html) * using the fact that arrays start at [] * doing the 0th case of the for loop import vmath type Seg = array[4, Vec2] Spline = object t: seq[float32] xy: seq[Vec2] v: seq[Vec2] a: seq[Vec2] length: seq[float32] proc bezier(segment: Seg, res: int): Spline = let t1 = 1 / float32(res) t2 = t1 * t1 t3 = t2 * t1 b0 = segment[0] b1 = segment[1] b2 = segment[2] b3 = segment[3] a = -b0 + 3 * b1 + -3 * b2 + b3 b = 3 * b0 + -6 * b1 + 3 * b2 c = -3 * b0 + 3 * b1 var d = b0 fd1 = a * t3 + b * t2 + c * t1 #initial velocity fd2 = 6 * a * t3 + 2 * b * t2 #initial acceleration fd3 = 6 * a * t3#acceleration change for i in 0 .. res: result.t.add(float32(i)*t1) result.xy.add(d) result.v.add(fd1) result.a.add(fd2) result.length.add(length(d)) d += fd1 fd1 += fd2#speed fd2 += fd3#acceleration Run
Re: tye and container whoes
Using objects is the right thing to do here. You can always create a spline object and just: spline.v.add(fd1) Run import vmath type Seg = array[4, Vec2] Spline = object t: seq[float32] xy: seq[Vec2] v: seq[Vec2] a: seq[Vec2] length: seq[float32] proc bezier(segment: Seg, res: int): Spline = let t1 = 1 / float32(res) t2 = t1 * t1 t3 = t2 * t1 b0 = segment[0] b1 = segment[1] b2 = segment[2] b3 = segment[3] a = -b0 + 3 * b1 + -3 * b2 + b3 b = 3 * b0 + -6 * b1 + 3 * b2 c = -3 * b0 + 3 * b1 var d = b0 fd1 = a * t3 + b * t2 + c * t1 #initial velocity fd2 = 6 * a * t3 + 2 * b * t2 #initial acceleration fd3 = 6 * a * t3#acceleration change var spline = Spline() spline.t = @[float32(0.0)] spline.xy = @[d] spline.v = @[fd1] spline.a = @[fd2] spline.length = @[length(d)] for i in 1 .. res: d += fd1 fd1 += fd2#speed fd2 += fd3#acceleration spline.t.add(float32(i)*t1) spline.xy.add(d) spline.v.add(fd1) spline.a.add(fd2) spline.length.add(length(d)) return spline Run
Re: A critique of Nim
I wouldn't be so harsh. Sometimes things seem so "obvious" that it doesn't occur to you that you may be wrong. I think this can happen to everyone. As the article I linked points out, the imports in Nim are often misunderstood. When I learned about Nim, I was also at least a bit suspicious.
Re: A critique of Nim
There's a pretty good article on this subject at [https://narimiran.github.io/2019/07/01/nim-import.html](https://narimiran.github.io/2019/07/01/nim-import.html) :-)
Re: tye and container whoes
Thanks for pointing out the distinction in use of table and object. That helps. In python I would probably do: spline = { 't': [], 'xy': [], 'v': [], 'a': [], 'length': [] } Run and then instead of seqfd1.add(fd1) in the final loop I'd directly use the dict: spline['v'].append(fd1) Run
Re: Java GC causes a crash a library Nim runtime on linux
Try to compile with `-d:noSignalHandler`, Java's GC uses signal handlers to intercept threads for collecting.
Re: tye and container whoes
I don't get your second question. If you have python dictionary with keys that are always changing use table, if keys are fixed and known use an object. If have a small snip-it, paste your python code so that we could give better advice.
Re: tye and container whoes
I think you are just having an issue with the named tuple syntax. I don't think you can have the names in the constructor of a tuple. I feel like a tuple is a wrong thing to use here, just create a normal object Fixed: import vmath type Seg = array[4, Vec2] Segs = array[4, Seg] Spline = object t: seq[float32] xy: seq[Vec2] v: seq[Vec2] a: seq[Vec2] lengt: seq[float32] proc bezier(segment: Seg, res: int): Spline = var t: seq[float32] let t1 = 1 / float32(res) t2 = t1 * t1 t3 = t2 * t1 b0 = segment[0] b1 = segment[1] b2 = segment[2] b3 = segment[3] a = -b0 + 3 * b1 + -3 * b2 + b3 b = 3 * b0 + -6 * b1 + 3 * b2 c = -3 * b0 + 3 * b1 var d = b0 fd1 = a * t3 + b * t2 + c * t1 #initial velocity fd2 = 6 * a * t3 + 2 * b * t2 #initial acceleration fd3 = 6 * a * t3#acceleration change seqt = @[float32(0.0)] seqxy = @[d] seqfd1 = @[fd1] seqfd2 = @[fd2] seqlen = @[length(d)] for i in 1 .. res: d += fd1 fd1 += fd2#speed fd2 += fd3#acceleration seqt.add(float32(i)*t1) seqxy.add(d) seqfd1.add(fd1) seqfd2.add(fd2) seqlen.add(length(d)) let spline = Spline(t: seqt, xy: seqxy, v: seqfd1, a: seqfd2) return spline Run
Re: A critique of Nim
thats a cool opinion, having 0 language experience and extensively using language that does something opposite. would be nice if people instead of imagining things and speculating how they could work actually tried to use them.
Re: A critique of Nim
I think the imports in Nim are great. Absolutely no complaints. And I do large projects.
Re: A critique of Nim
Nim is statically typed, unlike Python if you call a function from the wrong module you will not compile. Always prefixing with module name does not play well with the unified call syntax of Nim. Lastly, on big projects you can choose to use modulename.function(arg0, arg1, ...) in your codebase. But like code style, linting and code organization, this is a social contract between all contributors. Nim gives you the choice between using the Python syntax or a lightweight syntax, you're free to enforce the module.function(arg0, arg1, ...) in your code. Also, C has been doing it that way for 30+ years. Now that said, I agree that it's less easy when reading random code on Github, however just looking at arguments' types should help knowing which module the function came from. On your machine you have your editor that does that for you.
tye and container whoes
Being new at this I ran into several problems. First some code: import vmath type Seg = array[4, Vec2] Segs = array[4, Seg] Spline = tuple[t: seq[float32], xy: seq[Vec2], v: seq[Vec2], a: seq[Vec2], lengt: seq[float32]] proc bezier(segment: Seg, res: int): Spline = #var t: seq[float32] let t1 = 1 / float32(res) t2 = t1 * t1 t3 = t2 * t1 b0 = segment[0] b1 = segment[1] b2 = segment[2] b3 = segment[3] a = -b0 + 3 * b1 + -3 * b2 + b3 b = 3 * b0 + -6 * b1 + 3 * b2 c = -3 * b0 + 3 * b1 var d = b0 fd1 = a * t3 + b * t2 + c * t1 #initial velocity fd2 = 6 * a * t3 + 2 * b * t2 #initial acceleration fd3 = 6 * a * t3#acceleration change seqt = @[float32(0.0)] seqxy = @[d] seqfd1 = @[fd1] seqfd2 = @[fd2] seqlen = @[length(d)] for i in 1 .. res: d += fd1 fd1 += fd2#speed fd2 += fd3#acceleration seqt.add(float32(i)*t1) seqxy.add(d) seqfd1.add(fd1) seqfd2.add(fd2) seqlen.add(length(d)) let spline: Spline = [t: seqt, xy: seqxy, v: seqfd1, a: seqfd2] return spline Run Error: undeclared identifier t after uncomment t I get: Error: cannot evaluate at compile time: t Simple question, what to do. Second question, in python I would use a dictionary to hold the several lists and work directly with that. What would a suitable container be with Nim. I tried tables (can't work with mixed type?), put it all in a seq (gets a bit cumbersome) and tuples so far.
Re: A critique of Nim
great take on nim, totally agree on module import method being inadequate, esp coming from python in Nim, everything is this, import os which really means, from os import * this is fine for small projects, but if youre importing several modules in same file, you quickly lose track of what function is from what module, since module namespace is absent that seems like a crazy way to import stuff.
Re: Screenshot / Screencapture
Oh that's really straightforward, nice! I'll try to get a minute this weekend to send a PR over to nsu.
Java GC causes a crash a library Nim runtime on linux
Hi All! this week i tried to implement JNI library written on Nim(v.1.0.2) using templates from [https://gist.github.com/jangko/48ba0b76716d0631560e5f2ff470256d](https://gist.github.com/jangko/48ba0b76716d0631560e5f2ff470256d) and also jnim [https://github.com/yglukhov/jnim](https://github.com/yglukhov/jnim) but unfortunately on linux OS got error at runtime: > No stack traceback available > > SIGSEGV: Illegal storage access. (Attempt to read from nil?) i recognized that it happens when Java starts GC collect. Steps to reproduce: * empty.nim (exactly absolute empty file) compile it with nim c --app:lib empty.nim * Sample.java compile with javac Sample.java (see code bellow) public class Sample { public static void main(String[] args) { System.load("/absolute/path/to/libempty.so"); //System.load("absolute\\path\\to\\empty.dll"); for(int j=0; j<5; j++){ System.out.println("Java GC starts..."); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.gc(); System.out.println("Java GC finished..."); } } } Run But on windows OS it works properly. Please any suggestion on it, perhaps additional switches for Nim compiler? Thanks.
Re: Current status of Nim for Webassembly?
For Nim devel a pure refcounting GC is in development, you can enable it via `--gc:destructors`. It avoids all these problems by design. But as I said, it's in development, I hope we'll get it into version 1.2.
Re: Using forward declarations
maybe you can just add `{.reorder: on.}` at the top of your file
Re: manual tail call optimization
It should be in sugar! (which is very empty at the moment)
Re: Suggestion for optimizations (for better performance/speed) for an interpreter written in Nim
Look, I'm now 33 and having been programming since I was 7 - and working as a professional programmer for the past (many) years. Back then in 1993, I was dreaming of creating languages, operating systems, and all this low-level stuff. Fast forward to now, my work aside (which definitely involves more mundane stuff), this is **exactly** what I love doing. I guess... you cannot escape who you are! ;) Good luck!
Re: Suggestion for optimizations (for better performance/speed) for an interpreter written in Nim
Cool. Played around with it. I have always wanted to create language myself. I found out that if Im gonna be skilled enough in the future I will make a translator to python. That way I can use python libraries, yet write in my own style.
Using forward declarations
Currently I'm dealing with quite a large codebase and a file with many different proc declarations inside. That being said, it's not unusual to come across the dreaded _" undeclared identifier 'X'"_ message meaning "X is declared alright, but I have to insert a forward declaration". The question is: could I just add forward declarations for all of my declared proc's (regardless of whether they are currently used or not) at the top of my file? Would there be any drawbacks to this approach?
Re: Screenshot / Screencapture
I found the same error with png library. Treeform your example looks good enough to start with. After that I just have to port the rest of my c#
Converting a python thread toy application to nim
I'm learning nim and porting some of my python code. Here's a python program I'm trying to convert: from threading import Thread, Lock import time lock=Lock() threadlist=[] data=0 threadAdata=0 threadBdata=0 def threadA(): global lock global data global threadAdata threadAdata = 0 while threadAdata < 20 : lock.acquire() data+=1 threadAdata+=1 lock.release() time.sleep(.5) def threadB(): global lock global data global threadBdata threadBdata = 0 while threadBdata < 20 : lock.acquire() data+=1 threadBdata+=1 lock.release() time.sleep(0.25) t=Thread(target=threadA,args=()) t.start() threadlist.append(t) t=Thread(target=threadB,args=()) t.start() threadlist.append(t) for t in threadlist : t.join() print("data:",data) print("dataA:",threadAdata) print("dataB:",threadBdata) Run This is my attempt at conversion so far. Doesn't compile - see comments. import system, os, locks, tables, lists var lock : Lock data = 0 threadAdata=0 threadBdata=0 threadslist : array[5,Thread] # this is wrong. it should NOT be fixed size. HAS to be runtime extensible. What is a better list/table? proc A() {.thread.} = threadAdata=0 while threadAdata < 20 : acquire(L) data = data + 1 threadAdata = threadAdata + 1 release(L) sleep(500) proc B() {.thread.} = threadBdata=0 while threadBdata < 20 : acquire(L) data = data + 1 threadBdata = threadBdata + 1 release(L) sleep(250) # is this procedure even necessary? proc AddThread(tp: proc (arg: TArg) {.thread, nimcall.}; param: TArg) : Thread = # this is meant to create the thread and return a Thread var r : Thread createThread(tp,r) result = r when isMainModule: initLock(lock) threadlist.append(AddThread(A)) threadlist.append(AddThread(B)) joinThreads(threadlist) echo "data = " & data # should be 40 echo "dataA = " & threadAdata # should be 20 echo "dataB = " & threadBdata # should be 20 Run I'd like to keep the list of threads as I've got many threads to manage but the number of threads should be decided at runtime. This is just a simplified example to be clearer to understand.