Re: Regression: range initialization: [ProveInit] hint: Cannot prove that
Hmm, I thought the compiler would be smart enough to have a range type default to its type.low value. Although, even adding a c.g = 'a' immediately below the declaration doesn't remove the warning. It seems that the only way to avoid this is by fusing declaration and definition, like this: var c: Cell = (g: Glyph('a'), fg: 0, bg: 0)
Re: how to get value of object's field from second thread?
For simply passing value, use [channels](https://nim-lang.org/docs/channels.html) . Looking at your case, I guess you should use channels. You have two separate thread, first is qml thread and 2nd server thread. Using channel, you can apply producer-consumer pattern to both.
Re: Regression: range initialization: [ProveInit] hint: Cannot prove that
That's not a bug, although it can be annoying. The default value for a variable is always binary zero. Since binary zero is not a valid value for the type `Glyph`, the compiler complains.
Regression: range initialization: [ProveInit] hint: Cannot prove that
Yo guyz, I'm on Nim devel (nim -v says 0.18.1). This snippet of code gives me the ProveInit warning. type Glyph = range['a'..'z'] type Cell = tuple g: Glyph fg, bg: int var c: Cell Specifically, the last line gives me the warning. [I checked on GitHub, and it seems that this issue was solved in 0.18.](https://github.com/nim-lang/Nim/issues/6474) Anyone else having the same problem?
Re: cpuTime not in JS backend?
> In some old version of times.nim cpuTime was mapped to epochTime if the > platform would not support cpuTime. I think we can do that again; best effort > approximations for the JS target are a fact of life. I disagree. The whole point of a monotonic clock is that it's guaranteed to be monotonic. A non-monotonic clock should not be used as a approximation. If `cpuTime` has to work in the browser (and I don't think it has to if the `times` module gets a proper monotonic time type) it should use `performance.now`. If the user decides that a non-monotonic clock is an acceptable fallback for their use case they can use a shim for `performance.now`.
Re: how to get value of object's field from second thread?
I trying to do workaround for [this issue](https://github.com/filcuc/nimqml/issues/21) and also try to understand, how to correctly pass data beetween threads in Nim for future projects (in other languages I had not any difficulties or problems with this ).
Re: how to get value of object's field from second thread?
Oops. `loopThr` needs a loop, or the program will exit immediately.
Re: how to get value of object's field from second thread?
I think I should note that I'm not sure if you really intended using `async*` with threadpools. Async stuff in Nim is still single threaded (even though its concurrent, it is not parallel). You should instead use a single-threaded program, declare `loopThr` as `{.async.}` and then use `await` in `loopThr`. Please let me know if you need any help with the `async` stuff, it can indeed be a bit weird... I can't test this now, but try: type Server* = ref object socket: AsyncSocket started*: bool ... ... proc newServer*(): Server = Server( socket: nil, false, ... ) proc loopThr(server: Server, serverPort: int) {.async.} = server.socket = newAsyncSocket() server.socket.bindAddr(serverPort.Port) server.socket.listen() server.started = true # server.loopTask = loop(server) # not sure what this is here # waitFor server.loopTask # you can do some non-blocking IO now. eg: let line = await server.socket.recvLine() # this will not block proc start*(server: Server, serverPort: int) = waitFor loopThr(server, serverPort) # changed this to ``waitFor`` for example's sake. sleep(100)
Re: how to get value of object's field from second thread?
How to do it correctly and, probably, elegantly? (sorry, but constructions like [this](https://forum.nim-lang.org/t/1572/2#9868) looks a bit mad for this easy task I tried something like a: import os, threadpool type MyObj = object flag: bool proc subThr(pObj: ptr MyObj) {.gcsafe.} = pObj.flag = true var pShr = cast[ptr MyObj](allocShared0(sizeof(MyObj))) var o: MyObj = pShr[] o.flag = false spawn subThr(pShr) sleep 100 echo o.flag But it's don't write data by pointer. Maybe somebody have ideas?
Re: Introducing loopfusion: loop over any number of sequences of any single type.
> Syntactically I would prefer something that aligns the loop variables with > the containers Yes, this looks nice. Btw, a similar syntax exists in Julia, but what it does is completely different - it is syntactic sugar for nested for-loops. > Indeed that's a much better syntax, I have absolutely no idea how to > introduce it though. For me, a step forward to a better syntax would be just introducing in instead of , between elements and containers: forEach [x, y, z] in [a, b, c]: Also, changing square brackets to parentheses looks more intuitive to me, as I expect zip to yield tuples: forEach (x, y, z) in (a, b, c):
Re: cpuTime not in JS backend?
In some old version of `times.nim` `cpuTime` was mapped to `epochTime` if the platform would not support `cpuTime`. I think we can do that again; best effort approximations for the JS target are a fact of life.
Re: Emscripten/WebAssembly GC considerations?
Reference counting is not done for the references kept on stack. That means that the GC could potentially kill a living object in some situations. In order to avoid that I disable the GC, and call it (e.g. GC_step) in the bottom of the stack.
Re: How to cross-compile a Nim executable for Android
Have you tried `/` in path string instead of `\` as path separator ? Also you can try adding `"`. Very likely because you were using `\` so gcc couldn't find the correct path. See my example above all using `/`.
Re: How to get the last error from db_mysql?
Not tested, so dunno if it's correct or not, also, very likely unsafe especially if used in multithreaded try: ... ... except DbError: var err = cast[DbError](getCurrentException()) msg = err.msg
Re: How to cross-compile a Nim executable for Android
Hi, I tried last example. Unfortunately doesn't work for me. C:\Users\uname\Documents\nimapps\jnijava\nimcache>arm-linux-androideabi-gcc.exe -I C:\Nim\lib hello.c stdlib_system.c -o hello --sysroot=C:\Users\uname\Documents\apps\android-ndk-r16b\platforms\android-19\arch-arm In file included from c:\users\uname\documents\apps\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\include-fixed\syslimits.h:7:0, from c:\users\uname\documents\apps\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\include-fixed\limits.h:34, from C:\Nim\lib/nimbase.h:255, from hello.c:7: c:\users\uname\documents\apps\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\include-fixed\limits.h:168:61: error: no include path in which to search for limits.h #include_next /* recurse down to the real one */ ^ In file included from c:\users\uname\documents\apps\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\include-fixed\syslimits.h:7:0, from c:\users\uname\documents\apps\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\include-fixed\limits.h:34, from C:\Nim\lib/nimbase.h:255, from stdlib_system.c:7: c:\users\uname\documents\apps\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\include-fixed\limits.h:168:61: error: no include path in which to search for limits.h #include_next /* recurse down to the real one */ ^ stdlib_system.c:8:20: fatal error: setjmp.h: No such file or directory #include ^ compilation terminated. What I do wrong? Could you please help...
Re: Compiler won't scale (still)
> @jzakiya: The limit is at one billion now. +1!!
Re: How to get the last error from db_mysql?
What about db.tryInsertId()? It can return -1 without rasing exception. Is there a way to get error msg?
Re: cpuTime not in JS backend?
`cpuTime` is not supported for the JS backend, because there is no way to get the CPU time from the browser. I suppose it would be possible to implement it for Nodejs though. Your best bet for measuring time in the browser is to wrap [performance.now](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now), or to use `times.epochTime` (which is not monotonic). I plan to add a proper monotonic time type to the `times` module (which will use `performance.now` for the JS backend) after my nanosecond resolution PR has been merged.
Re: Emscripten/WebAssembly GC considerations?
Sorry if it's not answering your question, but could you share the exact example on how to compile to emscripten ? I know there's a thread about compiling to emscripten but it would be nice you could share it too.
Re: how to get value of object's field from second thread?
in your case, it would be sharing memory, share variable between threads and modify it atomically or through mutex.
Re: socket.close crashes in multithreaded application
my bad, this works fine proc stop*(server: Server) = server.started = false server.clients.setLen(0) if server.loopTask != nil: server.loopTask.complete() server.loopTask = nil if server.socket != nil: server.socket.close() server.socket = nil
socket.close crashes in multithreaded application
Hi. Why does crash "socket.close" when it called from second thread? server.nim: ... type Server* = ref object socket: AsyncSocket ... ... ... proc newServer*(): Server = Server( socket: nil, ... ) proc loopThr(server: Server, serverPort: int) = server.socket = newAsyncSocket() server.started = true server.socket.bindAddr(serverPort.Port) server.socket.listen() server.loopTask = loop(server) waitFor server.loopTask proc start*(server: Server, serverPort: int) = spawn loopThr(server, serverPort) sleep(250) ... ... proc stop*(server: Server) = server.started = false server.clients.setLen(0) if server.loopTask != nil: server.loopTask.complete() server.loopTask = nil server.socket.close() server.socket = nil main.nim: ... var srv* {.threadvar.}: Server srv = newServer() srv.start(port) srv.stop() ... exception: Thread 1 "main" received signal SIGSEGV, Segmentation fault. 0x00443294 in close_4mI4pLGMcv9cE68sJstU7IQ (socket=0x0) at /usr/lib/nim/pure/asyncnet.nim:628 628 socket.closed = true # TODO: Add extra debugging checks for this. undefinedTraceback (most recent call last) main.nim(22) main server.nim(78) stop asyncnet.nim(628)close SIGSEGV: Illegal storage access. (Attempt to read from nil?) Couldn't get registers: No such process. [Thread 0x76be5700 (LWP 30355) exited] [Thread 0x76e64700 (LWP 30354) exited] [Thread 0x770e3700 (LWP 30353) exited] [Thread 0x772e2700 (LWP 30352) exited] [Inferior 1 (process 30348) exited with code 01] Program exited with code 01 What I'm doing wrong?
Re: How to turn thread spawn call into an async call
nice
cpuTime not in JS backend?
Dear All, In compiling my Nim code [here](https://gist.github.com/sdwfrost/7c660322c6c33961297a826df4cbc30d) using the Javascript backend, I got an error message: nim js -d:release -o:sir_opt.js sir_opt sir_opt.nim(55, 12) Error: undeclared identifier: 'cpuTime' Is cpuTime not defined within the times package (which in the docs, says it is compatible with JS)? Best wishes Simon
Re: generic proc not instantiated depending on calling syntax
Never lost sleep over undefined and bottom. You are really lucky I'm not Libman, this could be a two page excursion.
Re: generic proc not instantiated depending on calling syntax
> The first definition is just a complicated way to write the second one. Huh. Looks like you're right: proc test(T: typedesc): proc(x: T) = (proc(x: T) = echo x) test(string)("foo") Never occurred to me that you can use it this way. > I find consistency far more important (Haskell changed my mind quite a bit). Then you should be disturbed by the fact that Haskell's type system corresponds to an inconsistent logic. ;^)
Re: generic proc not instantiated depending on calling syntax
@StasB: The first definition is just a complicated way to write the second one. typedesc parameters make a proc generic, just like square bracket parameters (apart from special binding behaviour). And yes, that's an ambiguity and therefore should result in a compiler error. About the ugliness: you have a point here, but I find consistency far more important (Haskell changed my mind quite a bit).
Re: generic proc not instantiated depending on calling syntax
@Lando: that would create ambiguities: proc test(x: typedesc): proc(x: int) = (proc(x: int) = echo x) proc test(A)(x: int) = echo x test(int)(123) # which one is it? Personally, I also think it looks far uglier.
Re: generic proc not instantiated depending on calling syntax
Never liked using a special bracket character for generic type parameters. # this is not a "generic procedure", it's a procedure constructor. proc threeOf[A](a: A): array[3, A] = for i in 0 .. 2: result[i] = a # the procedure constructor is called with a type parameter to *produce* a proc. var p = threeOf[int] # then, the proc is called with a value parameter. echo p(5) The fact that the constructor call can happen at compile time and sometimes the type parameter can be implied doesn't change that. IMHO it would make more sense to use parentheses for type parameters, because that's what we use for parametrization anyway: proc threeOf(A)(a: A): array[3, A] = ... threeOf(int)(5) Type and value parameters are distinguishable by the case of the leading character or - for builtins - by syntax highlighting. Square brackets are reserved to indcate indexing, as they should.
Re: How to turn thread spawn call into an async call
It works finally. To make the {.async.} works in quoted code, the 'await' and Future variable must be ident!! type Result* = ref object of RootObj body*: string proc waitEvent(evt: AsyncEvent): Future[void] = var fut = newFuture[void]("callAsync") addEvent(evt, (fd: AsyncFD) => (fut.complete(); true)) return fut macro callAsync(p: untyped): untyped = let await = ident("await") let fut = ident("fut") quote do: block: proc callp(evt: AsyncEvent): Result = let v = `p` evt.trigger() v proc async_call(): Future[Result] {.async.} = let evt = newAsyncEvent() let `fut` = waitEvent(evt) let val = spawn callp(evt) `await` `fut` return ^val async_call() proc ff1(v: int): Result = echo "work ", v sleep(1000) Result(body: "hello " & $v) proc ff2(v1, v2: int): Result = echo "work ", v1, " ", v2 sleep(1000) Result(body: "hello " & $v1 & " " & $v2) when isMainModule: block: let val = waitFor callAsync(ff1(1)) print "future return", val.body block: let val = waitFor callAsync(ff2(1, 2)) print "future return", val.body
Emscripten/WebAssembly GC considerations?
I've been using Nim to generate WebAssembly using Emscripten and everything seems to be working very well. Are there any special considerations I should make for the GC? I know that it's impossible to scan the stack in WASM, but that shouldn't be much of a problem for Nim due to reference counting. However, cycle detection also has to run, which (I'm assuming) does need to scan the stack to find roots. Will that be called automatically? Or do I need to call it manually? I imagine I could occasionally call it on Emscripten's frame callback emscripten_set_main_loop when the Nim stack is basically empty.
Re: Introducing loopfusion: loop over any number of sequences of any single type.
1\. For your first question, it shouldn't introduce overhead as it's an inline iterator. You can check the generated C code. If we take a simple seq this is equivalent to the following iterator foo_item[T](s: seq[T]): T = for i in 0 ..< s.len: yield s[i] let a = @[1, 2, 3, 4] for val in foo_item(a): echo val The reason why I use an intermediate zip is for Arraymancer. This is a proof of concept before I generalize it to tensors. On tensors, it would be wrapped in an OpenMP template that splits the work on multiple cores like [here](https://github.com/mratsim/Arraymancer/blob/e801b78169b59f1213a2e046997cfecf99ed4feb/src/tensor/higher_order_applymap.nim#L31-L43). I also really need an iterator because the "next" item is not straightforward if the tensor is not contiguous, see [here](https://github.com/mratsim/Arraymancer/blob/e801b78169b59f1213a2e046997cfecf99ed4feb/src/tensor/private/p_accessors.nim#L144-L148). 2\. Thanks, fixed. Yes if they are not the same length it generates an error. 3\. Indeed that's a much better syntax, I have absolutely no idea how to introduce it though. Bonus, I added loopFusion: import loopfusion let a = @[1, 2, 3] let b = @[11, 12, 13] let c = @[10, 10, 10] let d = @[5, 6, 7] loopFusion(d,a,b,c): let z = b + c echo d + a * z
Re: Compiler won't scale (still)
@jyapayne: Not sure, I like it to error out. Warning&continue doesn't seem right for what is ultimately a batch process. @jzakiya: The limit is at one billion now.
Re: Nim syntax Quiz
The only remaining issue is `var myTuple: MyTuple = [a: 10, b: 10]` which is hard to fix. All the others have better error messages now.