Re: Can I disable the GC and use "gc:none" or the "new runtime" for only parts of the code?
I am okay with managing my own memory. I mostly statically allocate, allocate on the stack and/or have large memory pools. Thank you for all those examples. They answer more questions than what I was asking for, like alignment and prefetching :D. My current C code divides work in batches and distributes them over multiple worker threads where they are run through kernels as decided by a scheduler managing batch dependencies etc. (a -> transform -> b -> transform -> c). I also have to do several atomic operations for everything to be completely lock / wait free, but I already found out how.
Re: Can I disable the GC and use "gc:none" or the "new runtime" for only parts of the code?
@Araq I see you already answered this question once when I used another username I forgot about. Sorry :D Also Nim seems to prefer that you copy list collection data-structures like seq etc. instead of sharing them between threads, but this time I really have to share them between multiple worker threads. I want to write the scheduler code that guarantees that no worker threads are working on the same batch at the same time myself.
Re: Can I disable the GC and use "gc:none" or the "new runtime" for only parts of the code?
So should I enable Nim's soft realtime GC for everything and then use `ptr` where I want to manage memory myself? Is that the default, what should I do to use it? Can I compile using C99 to be able to use the `restrict` keyword with `emit`? As an example, this is how I implemented one batch processor in C99 that can be used by any of the worker threads that picks it up (that is available for work): void waves_integrate(XRESTRICT(waves_t*) waves) { size_t wave_index = 0; XRESTRICT(float*) velocities = waves->velocity; XRESTRICT(float*) last_heights = waves->last_height; XRESTRICT(float*) target_heights = waves->target_height; for(wave_index = 0; wave_index < WAVE_COUNT; wave_index++) { // Load float velocity = velocities[wave_index]; float last_height = last_heights[wave_index]; float target_height = target_heights[wave_index]; // Transform float force = (TENSION * (target_height - last_height) - velocity * DAMPENING); // Store last_heights[wave_index] = last_height + velocity + force; velocities[wave_index] = velocity + force; } } Run Here `XRESTRICT` is replaced by the `restrict` keyword that the C compiler supports. The `waves_t*` argument is a pointer to one of the batches. Sorry for the C code, but I just want to know if I can do this in Nim.
Can I disable the GC and use "gc:none" or the "new runtime" for only parts of the code?
For parts of the code I want to have full control over memory, but for other parts I still need a GC. Is this possible? Basically I want a part to be more like C where I have to manage my own memory and do not mind to not use any extra features that require a GC. I finally want the application to have the following layers: high level: non-compiled game code for modding using Nim script ([https://github.com/komerdoor/nim-embedded-nimscript](https://github.com/komerdoor/nim-embedded-nimscript)) mid level: compiled game code using garbage-collector low level: data-oriented game engine not using a garbage-collector I've been coming back to Nim multiple times waiting for the moment that I can finally switch. I also use several C libraries that I have to create bindings for, hopefully that is now easier as well. Is using Nim as a scripting language still a good idea of would you recommend to use Lua there instead?
Re: Been away for 9 months. What changed? Need some help to get back on track.
Thanks. I will have a look.
Been away for 9 months. What changed? Need some help to get back on track.
I've been away from Nim for about 9 months. Can anyone give me a quick update about what happened in this time to help me get back on track? A summary of the last things I did and my level of understanding Nim at that time: [https://news.ycombinator.com/item?id=13357533](https://news.ycombinator.com/item?id=13357533) Anything improved, like the better concept system from @zahary? New interesting projects / repositories?
Re: How to start NIM on Linux ?
Knoppix 6.2 is from 2009, that is pretty old for something as organic as most open-source projects ;) You should really use a more recent Linux distro release. P.S. Subscribe to the YT channel Cosmic Soundwaves, it has more of this kind of music.
Re: How to start NIM on Linux ?
I think this is because Knoppix is based on Debian Stable which has no official Nim package. Do the following in a terminal to download the package: `wget http://http.us.debian.org/debian/pool/main/n/nim/nim_0.15.2-2_i386.deb` And then after running that command do the following to install the downloaded package: `sudo dpkg -i nim*.deb` >From there on it should be easy.
Re: How to start NIM on Linux ?
I already answered that question above. Knoppix is Debian based. Try `sudo apt-get install nim` from a terminal. Also no need to start and end with a greeting everytime ;)
Re: How to start NIM on Linux ?
Yes, at (you may also try the unstable one): [https://packages.debian.org/stretch/amd64/nim/download](https://packages.debian.org/stretch/amd64/nim/download) You may also find other packages there. Just search for them. Sometimes you have to download all the dependencies you are missing as well, but `dpkg` will tell you what is missing. If you are using Debian Stable it could be that the Testing or Unstable Nim package will not install. In that case you will have to rebuild the "deb" package using `dpkg-buildpackage`, hopefully you do not have to do that :D.
Re: GUI programming
Just try them all (not only libui) and see what you like best. Create a simple _hello word_ button. You will also learn that most GUI libraries are not that different from each other. May be only some features. The same counts for different programming languages as well. New paradigms are more difficult to learn, but once you know them it is easy to adapt.
Re: GUI programming
Yes. But for most of them you are actually using and learning the same interface as the one you would use when using C, Python etc. I am not sure if you are new to programming. In modern programming it is best to be flexible about learning new libraries. The way all the different GUI libraries work are not that different from each other. It is more like learning MS Word and Open/LibreOffice Writer. If you learn how to use a GUI library at a abstract level (the concept behind it) it will be easier to adapt that knowledge to other situations (different library / language etc.).
Re: Newyear is coming , is 2017 the year for nim?
`lim v -> 1` or buffer overflow / out of memory :D
Re: GUI programming
You can also use `libui`. A simple cross platform UI library. I found a Nim wrapper at (by Araq): [https://github.com/nim-lang/ui](https://github.com/nim-lang/ui) If you need a UI for use in a game or very interactive application you may try out a Immediate Mode Graphical User Interface. Have a look at: [https://github.com/vurtun/nuklear](https://github.com/vurtun/nuklear) You need to create a wrapper for it using `c2nim`.
Re: How to start NIM on Linux ?
I updated my comment above. If the computer is offline. Download the packages from a computer with an internet connection and store them on a USB drive. In Debian and Ubuntu you can use `apt-get download nim`. Store the downloaded files on a USB drive. On the offline computer, after mounting and changing directory to the USB drive, you can then do `dpkg -i *.deb` (yes, Debian and Ubuntu use another utility called `dpkg` for doing local package management). Most if not all package managers can install loose package files (deb, rpm etc.) from disk as well. It will tell you when it misses a dependency. A more advanced way, but sometimes used because of security policies is creating your own package source (instead of one from the internet). You can also mirror an existing online package source on disk and use it offline. In debian you can use `apt-mirror` for that. **Note**: if you install packages you usually need to do it as `root` (like Administrator on Windows) or else it will tell you it failed. It is better to prepend every command that needs to be `root` with `sudo`. Example.: `sudo apt-get install nim`.
Re: How to start NIM on Linux ?
Hello Menno, To add a directory inside the path you can do `export ${PATH}:/some/directory`. Modify `/some/directory` to the directory where the `nim` binary (executable) resides. You can also add this line inside the hidden files (every file or dir that has a dot . in front) named `.profile` or `.bash_profile` inside your home directory so this command is executed automatically the next time you log in. For most Linux distributions it is not needed to compile everything yourself or find packages on the Word Wide Web like you have to do with Windows. Always try the official package manager first. Most package managers support adding extra sources of packages. In Debian they call it "sources", in Ubuntu they call it "repositories" and in Gentoo (which I use) they call it "overlays". If you cannot find the package you need, first look if you can add one of those package sources that contain the package you need (make sure the source is official, can be trusted and is stable). After you added the package source you should be able to install the package you need. To install Nim in Ubuntu or Debian you can do `apt-get install nim`. In case you use a Redhat / Fedora based distribution may be someone else can help you with that. It could be that you need to add a package source or still have to download and install an RPM package. Make sure to update your Linux once in a while.
Re: Using concepts for generic structures
Tnx. I read the document `generics.txt` before I started using the `concept` keyword. Somehow I was under the impression concepts could be parameterized for me to refer to the contained value. Of course a container type may not even have `value` (it could be a function type or have a pair of values [if not a tuple]) while still being valid according to what I want. It would have been nice if I could do `T & T` or `T is Semigroup` because then `concept` does not need to know about the structure of contained types. Emmy looks interesting. It seems to extend the basic number types to be monoids under addition and multiplication (which they are). I already created `NumberSum`, `NumberProduct`, `LogicalOr` and `LogicalAnd` whose values are then under the their respective operation. I like how Emmy uses `zero` and `id` to denote identity for addition and multiplication. In a C library I wrote I called it `sum_identity` and `product_identity`. I would like something like `zero`, `one` or `id`, `half`, `double` to be standard.
Re: Using Nimscript as an embedded scripting language?
I added an example of how I embedded Nimscript in my Nim application at: [https://github.com/komerdoor/nim-embedded-nimscript](https://github.com/komerdoor/nim-embedded-nimscript) Still working (between other things) on the automatic binding generator.
Using concepts for generic structures
I want to do the following in a generic way: type Constant[T] = object value: T # For testing: 'int' acts as monoid under addition proc `&`(a: int, b: int): int = a + b proc `$`[T](a: Constant[T]): string = $a.value proc `==`[T](a: Constant[T], b: Constant[T]): bool = a.value == b.value proc `&`[T](a: Constant[T], b: Constant[T]): Constant[T] = Constant[T](value: a.value & b.value) proc identity[T](a: Constant[T]): Constant[T] = Constant[T](value: 0) # For testing: forced as identity for 'int' under addition let ca = Constant[int](value: 3) let cb = Constant[int](value: 6) let cc = Constant[int](value: 6) echo("Compare setoid: ", cb == cc) echo("Identity monoid: ", identity(ca)) echo("Appended semigroup (=9): ", ca & cb) I tried the following: type Setoid[T] = concept a, b a.value is T a == b is bool Semigroup[T] = concept a, b a.value is T a & b is Semigroup[T] Monoid[T] = concept a of Semigroup[T] identity(a) is Monoid[T] Constant[T] = object value: T # For testing: 'int' acts as monoid under addition proc `&`(a: int, b: int): int = a + b proc `$`[T](a: Constant[T]): string = $a.value proc `==`(a: Setoid, b: Setoid): bool = echo "Compared" # For testing a.value == b.value proc `&`[T](a: Semigroup[T], b: Semigroup[T]): Semigroup[T] = Semigroup[T](value: a.value & b.value) proc identity[T](a: Monoid[T]): Monoid[T] = Monoid[T](value: 0) # For testing: forced as identity for 'int' under addition let ca = Constant[int](value: 3) let cb = Constant[int](value: 6) let cc = Constant[int](value: 6) echo("Compare setoid: ", cb == cc) echo("Identity monoid: ", identity(ca)) echo("Appended semigroup (=9): ", ca & cb) But can only get the "Compare setoid" to work :( . I am sure I am doing something stupid. But what?
Re: Error: illegal capture 'a' -- I have no idea what that means
**Krux02**: I found the following document earlier today that explains some of the internals: [here](http://forum.nim-lang.org///nim-lang.org/docs/intern.html#code-generation-for-closures) I also made [this](https://gist.github.com/komerdoor/70d9c25820952624cf797890a18f9cd5) several months ago to test out functional programming in Nim. Had been away from Nim for a while so I am not sure if there are better libraries doing that now. I could not get it to work without the `pipe` function.
Re: Code generation from AST with annotations in Nim like in C
I will be happy to share my project as soon as I get the first parts to work. A long time ago I created a portal renderer. It used recursion and frustums that extended from each portal. Something like this: # Pseudo proc cellRender(cell, frustum): ... for o in cell.objects: if frustum.contains(o.bsphere): case o.type: of drawable: drawableRender(o, frustum) of portal: cellRender(o.cell, o.frustum) ... cellRender(startingCell, camera.frustum) The same code can be used for each light as well. The portal and camera should then test for collision to decide if the observer enters an new cell. About the conflict. The file `fancygl.nim` imports a regexp module called `nre` which is part of the Nim standard library. The module `nre` imports a module called `options`, but there are 2 modules called `options` inside the searchPath, `compile/options` and `pure/options`. This causes a conflict. I assume this is a bug in the master branch version I am using.
Re: Code generation from AST with annotations in Nim like in C
**Krux02**: I had a look at your opengl-sandbox code and got most of the examples to compile. Had to modify the font path and remove the regexp code that triggers a conflict between `pure/options` (nice to know Nim has them :) ) and `compiler/options`. Your code really shows the power of what is possible and is not too far from what I want to achieve.
Re: Code generation from AST with annotations in Nim like in C
I did something similar to `array[M, Vec[N,T]` when I wrote my math library in C, but somehow it did not occur to me to do the same in Nim. The reason that I am looking into Nim (again) is because I ran into limits creating a compute kernel DSL for C. I want to be able to write formulas (using Nim) and output them as OpenCL C, GLSL, SPIR-V using a function or expand them to (Nim) code for CPU execution (using scalar or SIMD etc.) using a macro. Nim seems to be perfect for this.
Re: Using Nimscript as an embedded scripting language?
> Read nimble's source code of how to accomplish this. Thank you. I had a look at the Nimble code and tried some pretty complex things already. The only thing I could not get to work are macros, but am really happy with what Nimscript can already do. Some more things I should be aware of? I already know about the FFI limitation.
Re: Using Nimscript as an embedded scripting language?
Thanks. I had a look at the compiler code and found `scriptconfig.nim`. Still figuring out what exactly I should do to integrate it in my Nim application.
Re: Code generation from AST with annotations in Nim like in C
Thank you, that worked perfectly. I can now finally create and initialize objects on the stack. I also just found out that arrays in Nim get initialized to zero automatically ;)
Re: Code generation from AST with annotations in Nim like in C
> Then when you are on the development branch of nim, error has a second > optional argument, that allows you to pass a NimNode, so that positional > information from that node gets printed on the cosole whe the error occurs. I am using that now. Tnx. Do you by the way know if Nim supports static constructors? I want to do something like the following: # Pseudo type Matrix[M, N: static[int], T] = object data: array[M * N, T] proc newIdentityMatrix[N, T](): Matrix[N, N, T] = # fill result with zeroes? for row in 0 ..
Re: Code generation from AST with annotations in Nim like in C
> Does your own answer mean you already answered the question yourself? Yes, the second post describes how I solved it. > instead of this ... you can do this: definition.expectKind(nnkProcDef) Nice to know this exists, but I want the switch / case / match to generate different code depending on the node-kind that is being passed. > And for the AST generation I really recommend you to use quote do Never expected there to be a sort of DSL for this. This is really what I needed. So it implicitly creates a template and parses it using getAST. It feels much more like Lisp now. Thank you for the advice.
Re: Code generation from AST with annotations in Nim like in C
I managed to create a macro that creates a wrapper for functions that have the "scriptExport" pragma. It was easier than I expected. import macros proc expandFormalParamsForCall(formalParamsNode: NimNode): seq[NimNode] {.compileTime.} = result = @[] for i in 1 ..< formalParamsNode.len: if formalParamsNode[i].kind == nnkIdentDefs: for j in 0 ..< formalParamsNode[i].len - 2: result.add(formalParamsNode[i][j]) proc expandFormalParamsForProc(formalParamsNode: NimNode): seq[NimNode] {.compileTime.} = result = @[] for i in 0 ..< formalParamsNode.len: if formalParamsNode[i].kind == nnkIdent: result.add(formalParamsNode[i]) if formalParamsNode[i].kind == nnkIdentDefs: for j in 0 ..< formalParamsNode[i].len - 2: result.add(newNimNode(nnkIdentDefs).add(formalParamsNode[i][j], formalParamsNode[i][^2], newEmptyNode())) macro scriptExport(definition: untyped): typed = case definition.kind of nnkProcDef: var scriptDefinition = newProc(newIdentNode($definition.name & "_script"), expandFormalParamsForProc(definition.pa newCall(!"echo", newStrLitNode($definition.name & "_script called.")), newCall(definition.name, expandFormalParamsForCall(definition.params)) )) return newStmtList(definition, scriptDefinition) else: error("Only works with procedures for now") proc sum(x, y: int): int {.noSideEffect,scriptExport.} = x + y echo(sum(1, 2)) echo(sum_script(1, 2)) Still have to do the same for other types etc. as well. From this I can write code that will create bindings etc.
Using nimscript as an embedded scripting language?
Is it possible to use Nimscript as an embedded scripting language instead of for example using Lua? And if possible, can I create bindings for my own functions and restrict which built-in functions can be called from the scripting language?