mac nano editor syntax highlight
hello I am new to the language found out about it like 6 hour ago and i loved it. I looked at them tutorials from the website and I cant wait to start coding but, I am not sure if someone already asked this question(does anyone knows how to add syntax highlight in nim using terminal mac nano editor) cant wait to use NIM in nano terminal ! thanks.
Re: Why does `setCommand` exist?
Are you sure it's not specific to nimble build?
Re: Code review request
I don't have a stackoverflow account so I'll have to answer here. What do you think the output of the following code should be? type Person = object id: int name: string proc newPerson(name: string): Person = var next_id = 1 result.id = next_id inc next_id result.name = name for p in ["Adam", "Billy", "Charlie", "David", "Eric"]: echo newPerson(p).id Run If you thought it would print 1-5 then you need to brush up on your variable scoping (newPerson resets the starting IDs to 1 and -1 each time it's called). If you change your print function to print out the IDs of everyone you'll see that all men share the same ID and all women share the same ID. If I were you I would drop the ID bit altogether and simply compare objects directly, e.g. personRef == other. If you fix your same-ID bug you'll run into other issues though.
Re: Another state of generating Android APK thread...
@yglukhov: > I'm not into writing tutorials right now, but I can answer any concrete > questions. I can appreciate that not everyone is into writing tutorials; thus I am proposing that I will write the tutorial so that others can refer to it from their documentation, including yourself, but I need some help getting it working so that I can document it... Perhaps I need to start with a repo showing my problems so far in which I can produce an APK file, but can't install the file and you can quickly spot my problems and make suggestions on how I can improve the process. > Jnim at this point allows "implementing" java classes in nim (still > experimental feature though). It seem that many things in Nim are still "experimental" including the memory management model, but unless we provide some reasonably easy-to-use methods to use these features, they will never get beyond being "experimental". > One important point to consider is how pure-nim you wanna go with the > toolchain. Surely we want to build apks without java, android sdk, gradle, > etc The above would seem to be the @akavel/Dali approach, but other than problem with the restrictive license he chose, I see the same problems as you do with the required reverse engineering, etc. I also look at why we must insist on a pure Nim toolchain as to advantages, as we already have a usable NDK/JDK/Android Studio/Gradle toolchain and the main problem is that I don't want to be forced to write C/C++ code but just have a way to cause the output of the Nim compiler to be used instead. This is what I would like to document as to how to go about it. > Then comes the runtime question, in particular: on which android thread is > your nim "main" thread. Your mentioned use-case suggests nim main thread is > equal to activity UI thread, but any high-fps opengl/vk app would likely > prefer a secondary thread ... controlling this threading aspect from nim > still remains unsolved afaik, partly because of nim threading nuances. Am I right that if Nim procedures are just called from Java/Kotlin through JNI that they will then just run on the activity thread from which they are called? If this is true, the threading control would be from the JDK end and would only be a problem if inter thread communication were needed at the Nim end, which isn't always required. Also, I seem to see that Nim multi-threading on Android probably already works but the main problems are due to Nim's legacy GC'ed memory management. For simple app's, manual C-style memory management is likely enought, and for the future, \--gc:arc or \--newruntime will likely work (as per @araq's aims) and provide what is needed. My main drive for trying to do this at this time is to be able to demonstrate the speed of a multi-threading algorithm on Android, which algorithm can actually be written to use manual memory management (although working \--gc:arc, channels, and spawn'ing that worked with \--gc:arc would make it more beautiful in terms of code and minimize extra "glue" code); however, in order to easily change test parameters, it would be good to have a user interface and an easy way to do it would seem to be as proposed. I guess if the above is too difficult to get working, I could take the alternate approach of using a working example of SDL2 with a working interface and just patch in the algorithm I am trying to show working, but it would seem that SDL2 would be more complex am more something to be used for writing native games that what I am trying to do here.
Re: Nim for Beginners Video Series
Your work is awesome!
Re: Nim for Beginners Video Series
Your videos are very excellent, I hope to continue watching new content on your channel to continue learning since I am new
Re: Performance test agains Python
You are also testing cache effect times at least as much as you are testing the code you are running; Either take minimum-of-5 sequential runs, or an average of 10 loops or so (or both); Not sure about Win10, but for sure Windows used to report times in multiples of ~16ms at least as late as Win7, unless you took special care -- so as long as you are measuring times so small, that may also be a confounding factor.
Code review request
I think stackoverflow is a better platform for asking such question but I'm only opening this thread to increase visibility. Here is the original: [https://stackoverflow.com/q/60582785/12029705](https://stackoverflow.com/q/60582785/12029705) The code is about stable matching.
Re: FFI: from seq[int] to C array
Solved with unsafeAddr(arr[0]) instead of unsafeAddr(arr)
Re: Nested list comprehension
I generally only put brackets where neccessary. You can write this using devel version of nim (you can use choosenim) import tables, sugar, sets, sequtils proc cross(xs, ys: string): seq[string] = for x in xs: (for y in ys: result.add x & y) let rows = "ABCDEFGHI" cols = "123456789" squares = cross(rows, cols) let unitSeq = collect(newSeq, for c in cols: cross(rows, $c)) & collect(newSeq, for r in rows: cross($r, cols)) & collect(newSeq, for rs in ["ABC", "DEF", "GHI"]: for cs in ["123", "456", "789"]: cross(rs, cs)) let units = collect newOrderedTable: for s in squares: {s: collect(newSeq, for u in unitSeq: (if s in u: u))} let peers = collect newOrderedTable: for s in squares: var v = units[s].foldl(a & b) v.delete v.find s {s: v} echo "unitSeq:"; for u in unitSeq: echo u echo "\nunits"; for k, v in units: echo k, ": ", v echo "\npeers"; for k, v in peers: echo k, ": ", v Run For some reason peers isn't what it should, but the rest is ok.
FFI: from seq[int] to C array
I have wrapped a C function with the following signature: type VSAPI* {.bycopy.} = object ... propSetIntArray*: proc(map:ptr VSMap, key:cstring, i:ptr int64, size:cint):cint ... Run I want to make easier to deal with it with something like the following: proc propSetIntArray(vsmap:ptr VSMap, key:string, arr:seq[int]) = let p = cast[ptr int64](unsafeAddr(arr)) let ret = API.propSetIntArray(vsmap, key.cstring, p, arr.len.cint) if ret == 1: raise newException(ValueError, "Size is negative") Run This is not working. I am getting (probably the addresses): integers: @[94379288560544, 94379288560512, 94379297070336] instead of: integers: @[1, 3, 5]
Re: Creating functions at runtime
Thanks for the clarifications. I'll try to improve it if I manage to get everything working beforehand.
Re: Nim for Beginners Video Series
#19 is live at: [https://youtu.be/uZ7jdkx4pKE](https://youtu.be/uZ7jdkx4pKE) Scopes and When Statements.
Re: How does one get a mutable iterator?
To make datum a variable you need to use mitems: import options type T = ref object data: seq[Option[T]] proc p(t: var T) = for datum in t.data.mitems: datum = none(T) Run
Re: How does one get a mutable iterator?
ok I worked around it like I would in C#... using indices.
Re: Creating functions at runtime
I've created a plugin system that's ready for use. It was part of the feud text editor I was working on and was recently extracted into a standalone repo and package. It has diverged since extraction and feud is yet to be ported to use it but that will happen eventually. Appreciate all reviews and feedback. [https://github.com/genotrance/plugins](https://github.com/genotrance/plugins) [https://github.com/genotrance/feud](https://github.com/genotrance/feud)
How does one get a mutable iterator?
import options type T = ref object data: seq[Option[T]] proc p(t: var T) = for datum in t.data: datum = none(T) Run /usercode/in.nim(8, 5) Error: 'datum' cannot be assigned to| ---|---
Re: Another state of generating Android APK thread...
I'm not into writing tutorials right now, but I can answer any concrete questions. Jnim at this point allows "implementing" java classes in nim (still experimental feature though). So as long as you know how to write your app in java, it's just a matter of 1-to-1 porting. One important point to consider is how pure-nim you wanna go with the toolchain. Surely we want to build apks without java, android sdk, gradle, etc. But then comes reality and you want to add e.g. firebase push notifications to your project, and it's straightforward for gradle, but for a hypothetical custom toolchain... realistically impossible, imo. Then comes the runtime question, in particular: on which android thread is your nim "main" thread. Your mentioned use-case suggests nim main thread is equal to activity UI thread, but any high-fps opengl/vk app would likely prefer a secondary thread, as it is less runloop overhead, larger stack size, and allowed to "hang" without activity being killed (that might be a useful or harmful feature, depending on the usecase). And if pretty much all of your logic lives in secondary thread, it would be handy/logical to run nim "main" thread on it as well, like it is done with e.g. SDL2, ndk_native_glue (and thus glfm). And controlling this threading aspect from nim still remains unsolved afaik, partly because of nim threading nuances.
Re: Like C extern pragma?
Ok. I found the problem. It was I use c2nim and it puts asterisk after procedure name. That was obvious. Procedure must been defined in the same file, because it was marked as to be exported. Because It was C header file (and after use of c2nim it was nim file contains only signature/prototypes/etc.), I revert state of file and removes asterisk.
Re: Creating functions at runtime
@mantielero Nim does not support creating functions at runtime. Generally, compiled languages such as Nim get around this by compiling a source file into a DLL and then loading that. It's unfortunately not as simple as you want it to be. The library @Hlaaftana linked to is being created by @shashlick (which is probably not ready yet) and it will likely allow an easy interface for creating plugins in Nim. In the meantime, this is how you would do it. Put the following 3 files in the same directory. # english.nim proc greet*(): string {.exportc, dynlib, cdecl.} = result = "Hello!" Run Compile the above with `nim c --app:lib english.nim`. This will result in `libenglish.dylib` on Mac, `libenglish.so` on other Unix, and `english.dll` on Windows. # french.nim proc greet*(): string {.exportc, dynlib, cdecl.} = result = "Hello!" Run Compile the above with `nim c --app:lib french.nim`. This will result in `libfrench.dylib` on Mac, `libfrench.so` on other Unix, and `french.dll` on Windows. # testplugin.nim import dynlib type greetFunction = proc(): string {.nimcall.} proc main() = echo "Enter a language: " let lang = stdin.readLine() let lib = case lang of "french": loadLib("./libfrench.dylib") # Rename for your OS else: loadLib("./libenglish.dylib") # Rename for your OS if lib == nil: echo "Error loading library" quit(QuitFailure) let greet = cast[greetFunction](lib.symAddr("greet")) if greet == nil: echo "Error loading 'greet' function from library" quit(QuitFailure) let greeting = greet() echo greeting unloadLib(lib) main() Run Then compile and run the above with `nim c -r testplugin.nim`. You should get a prompt to enter your language. Enter "french" for "Bonjour!" or anything else for "Hello!". You could easily extend the above to get a function name from a list of plugin paths. Hope this is helpful to you.
Like C extern pragma?
I found information about extern pragma, but It don't describe what it does. I need C-like extern pragma or way to use only function prototype (and include file with these prototypes). That's because I have problem with circual import of modules. Nim compiler complain about missing function implementation, when I tries to do that (only declaration of function in file, implementation in another).
Re: Creating functions at runtime
I see that this [nimeval - execute](https://forum.nim-lang.org/t/1319#8265) could be useful for my problem. But it looks like it is no longer available. What is the alternative?
Re: Creating functions at runtime
I am trying to make something like the following: macro gen_function(plugin:string, functionName:string) = var source = fmt""" proc {functionName}():ptr VSMap = let plug = getPluginById("{plugin}") let args = createMap() return API.invoke(plug, "{functionName}".cstring, args) """ result = parseStmt(source) when isMainModule: let plugins = getPlugins() for plugin in plugins: if plugin[0] == "ffms2": for f in plugin[3]: gen_function( plugin[1], f[0]) Run
Re: Creating functions at runtime
I don't get exactly what you're trying to do except that you can use dynamic libraries to load plugins at runtime. Here is a related Nimble package: [https://github.com/genotrance/plugins](https://github.com/genotrance/plugins)
Creating functions at runtime
I am wrapping VapourSynth and I facing a problem that I don't how to best face it. I want to make available a number of functions that are available from plugins. The plugins available are known at runtime. For example the following works: macro gen_functions():typed = var source = """ proc Version():ptr VSMap = let plugins = getPlugins() for plugin in plugins: if plugin[0] == "ffms2": let plug = getPluginById(plugin[1]) let args = createMap() return API.invoke(plug, "Version".cstring, args) """ result = parseStmt(source) Run It works, because I know there is function call "Version" provided by the plugin "ffms2", so I provide the information to the compiler. What I would like to do is moving: let plugins = getPlugins() for plugin in plugins: ... Run outside of the "source" variable. But if I do that, obviously nim complains becuase getPlugins requires information only available at runtime. Can I create functions at runtime? How? Can you think in a better strategy to create all those functions?
Re: How does one get a `var` from a `ref` object?
In your case you probably want reference semantics all the way, unless you duplicate "Person" instances so type Person = ref object prefers: Person proc engage(p1, p2: Person) = p1.prefers = p2 p2.prefers = p1 Run
Re: How does one get a `var` from a `ref` object?
ok I simplified the code so I hope people understand my problem better. I don't quite think dereferencing will help in such a case?
Re: Nested list comprehension
It would be nice if when something is deprecated in the standard library there was a link to the associated discussion/decision summary (if any). I found the deprecated list comprehension type a while ago and was curious about why it was deprecated.
Re: Karax: Adding elements
Thank you @jyapayne. It seems very simple now that I see code that works.
Re: How can I simulate "name[id]" behaviour?
It works. Thanks a lot.