Re: Nimble package, multiple backends
`when` blocks allow for different code based on backends, Nim versions, command line options and so on. The [fatal pragma section of the Nim manual](https://nim-lang.org/docs/manual.html#pragmas-fatal-pragma) gives an example that shows how to error when the user doesn't use the `objc` command to compile. If you want to just warn, you can also do that. An example for your use case, you put this at the top of your nimble package module: when defined(macos) or defined(macosx): when not defined(objc): {.warn: "this package is supposed to work with objc on macosx".} elif not defined(c) or not defined(cpp): {.warn: "this package is supposed to work with c/c++ on linux/windows".} Run The [browsers](https://github.com/nim-lang/Nim/blob/version-1-2/lib/pure/browsers.nim) module in the standard library is a short example of how to write OS-specific code.
Does Nim have a binary serializer similar to Gos "encoding/gob"?
Hi, I'm looking for a binary serializer that will hopefully allow newer versions of my program that for example add new fields to a type to still load data created by older versions of that same program. Is there anything like that? Thanks!
Could Nim use Cmake to invoke the C compiler?
I'm curious, would it be hard or beneficial to change the nim compiler so that every time you build a project, it generates a cmake_lists.txt file and uses Cmake to run the C or C++ compiler to compile the project. This seems to be at least one of the things that Cmake was made for. You might also be able to include other C code that's built by Cmake. I'm not really suggesting anything be changed, but am curious if it would be useful.
Re: Nim version of Flask Web Framework
If you want to add auth to existing frameworks: [https://github.com/FedericoCeratto/nim-httpauth](https://github.com/FedericoCeratto/nim-httpauth)
Re: generate c++ code from .nim file
ok, thanks!
Nimble package, multiple backends
What is the best way to distribute a Nimble package that would use Objective-C on Mac OS X and C/C++ on Linux/Windows? Is there anything special that needs to be done? Also, if a Nimble package uses a particular backend like Objective-C, do users of the that project need to compile their code with the same backend?
Re: Nim Forum build error
Yep, it's trying to install karax and that fails for some reason (I think there might be a Nimble bug here). Try to install it manually by running nimble install karax@#f6bda9a.
Re: AsyncHTTPClient crashes saying invalid http version
Stop mixing callbacks and async procs. Your `download` async proc finishes before your download operation finishes because you are not awaiting the `download` proc. Just do this: await downloader.downloadFile(node.mediaLink(board, thread), downFileName) Run
Re: AsyncHTTPClient crashes saying invalid http version
> Is this a wrong link? because that doesn't look synchronous. Ops sorry I had changed the link. > One important thing to know is that you should never use waitFor in an async > procedure, use await. If I use await, the main thread doesn't stop until all the coroutines I create inside the loop finishes proc download(node: JsonNode; downPath, board, thread: string): Future[void] {.async.} = var tim = node["tim"].getInt() ext = node["ext"].getStr() downloader = newAsyncHttpClient() downFileName = fmt"{downPath}/{tim}{ext}" echo("Downloading ", node.mediaLink(board, thread), " as ", downFileName, "...") var downloadFuture = downloader.downloadFile(node.mediaLink(board, thread), downFileName) downloadFuture.callback= proc() = echo("Downloading ", downFileName, " complete") result = downloadFuture proc main() {.async.} = var boardAndThread = parseBoardAndThread(getRawLink()) downPath = getCurrentDir() & "/" & getRawDownPath() board = boardAndThread[0] thread = boardAndThread[1] if not downPath.existsDir(): echo("Local path not recognized. Creating directory: ", downPath) createDir downPath var webClient = newAsyncHttpClient() link = getAPILink(board, thread) j: string = await webClient.getContent(link) var jsonArray = parseJson(j)["posts"].getElems() filteredArray = jsonArray.filter(proc(it: JsonNode): bool = it{"tim"} != nil) downloadSignaledArray = filteredArray.map(proc(it: JsonNode): Future[void] = it.download(downPath, board, thread)) for it in downloadSignaledArray: await it waitFor main() # never gets to finish downloading. Run For context, this is how the json looks like: [https://a.4cdn.org/po/thread/570368.json](https://a.4cdn.org/po/thread/570368.json) I have to extract `tim` and `ext` from each item in the JArray. Then from the program argument I have to parse `po` and build the download link like: `https://i.4cdn.org/po/1546293948883.png`. I need to download from any JsonNode that has `tim` asynchronously.
Re: Nim Forum build error
` Verifying dependencies for nimforum@2.0.2 Reading official package list Checking for jester@#d8a03aa Info: Dependency on jester@#d8a03aa already satisfied Verifying dependencies for jester@#d8a03aa Reading official package list Checking for httpbeast@>= 0.2.2 Info: Dependency on httpbeast@>= 0.2.2 already satisfied Verifying dependencies for httpbeast@0.2.2 Reading official package list Checking for https://github.com/timotheecour/asynctools@#pr_fix_compilation Info: Dependency on https://github.com/timotheecour/asynctools@#pr_fix_compilation already satisfied Verifying dependencies for asynctools@#pr_fix_compilation Reading official package list Checking for https://github.com/timotheecour/asynctools@#pr_fix_compilation Info: Dependency on https://github.com/timotheecour/asynctools@#pr_fix_compilation already satisfied Verifying dependencies for asynctools@#pr_fix_compilation Reading official package list Checking for bcrypt@#head Info: Dependency on bcrypt@#head already satisfied Verifying dependencies for bcrypt@#head Reading official package list Checking for hmac@#9c61ebe2fd134cf97 Info: Dependency on hmac@#9c61ebe2fd134cf97 already satisfied Verifying dependencies for hmac@#9c61ebe2fd134cf97 Reading official package list Checking for nimSHA2@any version Info: Dependency on nimSHA2@any version already satisfied Verifying dependencies for nimSHA2@0.1.1 Reading official package list Checking for sha1@any version Info: Dependency on sha1@any version already satisfied Verifying dependencies for sha1@1.1 Reading official package list Checking for recaptcha@#d06488e Info: Dependency on recaptcha@#d06488e already satisfied Verifying dependencies for recaptcha@#d06488e Reading official package list Checking for sass@#649e0701fa5c Info: Dependency on sass@#649e0701fa5c already satisfied Verifying dependencies for sass@#649e0701fa5c Reading official package list Checking for karax@#f6bda9a Installing karax@#f6bda9a Reading official package list Downloading https://github.com/pragmagic/karax using git Executing git clone --recursive https://github.com/pragmagic/karax /var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a Finished with exit code 0 Output Cloning into '/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a'... Executing git checkout --force f6bda9a Finished with exit code 0 Output Note: switching to 'f6bda9a'. ... You are in 'detached HEAD' state. You can look around, make experimental ... changes and commit them, and you can discard any commits you make in this ... state without impacting any branches by switching back to a branch. ... If you want to create a new branch to retain commits you create, you may ... do so (now or later) by using -c with the switch command. Example: ... git switch -c ... Or undo this operation with: ... git switch - ... Turn off this advice by setting config variable advice.detachedHead to false ... HEAD is now at f6bda9a Reactive value (#129) Executing git submodule update --recursive Finished with exit code 0 Debug: Executing nim e --hints:off --verbosity:0 -p:/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimblecache '/private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims' /var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468.out printPkgInfo Warning: Not removing temporary path because of debug verbosity: /var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468.out Warning: Not removing temporary path because of debug verbosity: /private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims Info /private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims(5, 22) Warning: imported and not used: 'strutils' [UnusedImport] Debug: Executing nim e --hints:off --verbosity:0 -p:/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimblecache '/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims' /var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468.out printPkgInfo Info /private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims(5, 22) Warning: imported and not used: 'strutils' [UnusedImport] Verifying dependencies for karax@#f6bda9a Installing karax@#f6bda9a Warning: Not removing temporary path because of debug verbosity: /var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468 Error: No binaries built, did you specify a valid binary name? ` Run
Re: generate c++ code from .nim file
You'll need to copy this file beside your .cpp file. This is supposed to be copied automatically when using `--genScript` (if you're using 1.0.6 it should work), with latest versions of Nim it doesn't get copied (see [https://github.com/nim-lang/Nim/issues/13826)](https://github.com/nim-lang/Nim/issues/13826\)).
Re: Nim Forum build error
Are you sure you're not getting this error because of a dependency that's being installed? Can you paste the full output of `nimble c -r src/buildcss --debug`?
Re: how to get some (partial) type resolution within a macro ?
> Can parseEnum help you with what you want to do? Thank you for your assistance. At the very end, `{.experimental: "dynamicBindSym".}` did the trick for me. I got three different solutions: via typedesc, via template (forwarding) and with `bindSym` at compile-time. The least mentioned was I was looking for. import macros {.experimental: "dynamicBindSym".} type Qa = object field: int Qb = array[0..23,NimNode] Qc = tuple[tfa : int, tfb : int, tfc : string] macro helper(a : typed, acomm : string): untyped = echo "helper ",acomm," ", treeRepr getImpl a macro resolve(ta : typedesc, tb : untyped, tc : untyped) : untyped = echo "entry ", ta.strVal, tb.strVal, tc.strVal var dyn = strVal tc echo "typedesc ", treeRepr getImpl ta template tpl(v) = helper v, "forwarded" let retv = getAst tpl tb let NNode = bindsym dyn echo "dyn. bind ", treeRepr getImpl NNode result = retv resolve(Qa,Qb,Qc) # prints type description in order : Qa, Qc, Qb echo " done. " Run
Re: AsyncHTTPClient crashes saying invalid http version
> To keep multiple connections open at a time you will need a separate > HttpClient for each. Ah that fixes it. Thanks a bunch.
Re: Iterate over fields
First of all see of course the docs here: [https://nim-lang.github.io/Nim/macros.html#quote%2Ctyped%2Cstring](https://nim-lang.github.io/Nim/macros.html#quote%2Ctyped%2Cstring) and the macro tutorial, specifically: [https://nim-lang.github.io/Nim/tut3.html#introduction-generating-code](https://nim-lang.github.io/Nim/tut3.html#introduction-generating-code) So the basic idea is that quote do allows you to write exactly the code you want to generate. However, in most cases that's not really very helpful, because if you can explicitly write your code, you could also just write a template / proc. That's where the back ticks come in to perform actual quoting of NimNodes defined in the current scope. They will be inserted in those places. quote do is thus just a nice way to avoid having to build the AST manually (as I for instance do in the newVar proc), but keep the ability to insert NimNodes you calculate / determine somehow based on what the macro is supposed to accomplish. Another thing to keep in mind when using quote do is about the stuff that's not quoted with back ticks. As a rule of thumb (someone please correct me): * any procedure / template you use within quote do will be bound in the scope where the macro code is injected * any variables you introduce will be "gensym'd", that is for each symbol you introduce a unique symbol will be created. So if you write var x = 5 within quote do, the final code won't have the variable x, but something like x_12345. The second means that if you want to refer to some variable that will be known in the scope in which the macro is used, you have to create the identifier manually and quote it. Due to the first point you fortunately don't have to do the same for procedures you want to use.
Re: AsyncHTTPClient crashes saying invalid http version
> Writing a synchronous downloader script was a breeze: > [https://gitlab.com/snippets/1967018](https://gitlab.com/snippets/1967018) Is this a wrong link? because that doesn't look synchronous. You're doing a number of things incorrectly here. One important thing to know is that you should never use waitFor in an async procedure, use await. What I believe is the problem though, is that you are reusing the same AsyncHttpClient instance for multiple concurrent requests. You need to create one AsyncHttpClient instance for each request that you want to be running concurrently. I'm going to create an issue on GitHub to show a better error message for this case. The easiest way to make this work would probably be to split up parseJson(j)["posts"] into x many lists, then run x async procs on each list which create their own AsyncHttpClient and iterate through the list downloading each one-by-one (using await instead of storing each future and awaiting them all).
Re: AsyncHTTPClient crashes saying invalid http version
To keep multiple connections open at a time you will need a separate HttpClient for each. Try moving webClient = newAsyncHttpClient() into the for loop so each call to webClient.downloadFile has it's own client
Re: generate c++ code from .nim file
i get this error every time, when i compile my main file : @msecond.nim.cpp:9:10: fatal error: 'nimbase.h' file not found #include "nimbase.h" ^~~ 1 error generated. Run
Re: Nim Forum build error
Check [https://github.com/nim-lang/nimforum/blob/master/nimforum.nimble](https://github.com/nim-lang/nimforum/blob/master/nimforum.nimble) and you'll find: task backend, "Compiles and runs the forum backend": exec "nimble c src/forum.nim" exec "./src/forum" Run task frontend, "Builds the necessary JS frontend (with CSS)": exec "nimble c -r src/buildcss" exec "nimble js -d:release src/frontend/forum.nim" mkDir "public/js" cpFile "src/frontend/forum.js", "public/js/forum.js" Run so execute "nimble backend" to build backend and "nimble frontend" to build frontend (see other tasks too)
Re: Nim Forum build error
Tried both (verbose & individual command). Same error: No binaries built, did you specify a valid binary name?
Re: Nim Forum build error
Try to run the commands inside nimforum.nimble to find the error messages, alternatively look for a nimble verbose option that doesn't hide the build commands output
Nim Forum build error
I used the latest code from github. Issued git submodule update --init --recursive nimble frontend Run I get this error: Error: No binaries built, did you specify a valid binary name?. Nim version: Nim Compiler Version 1.0.6 [MacOSX: amd64] How to go further?
Re: I think we can really do better...
@other_mods: Guys, didn't you notice that @brianwil2727 has put one link to some Bitcoin stuff to his post? It is a well-masked spam.
Re: Iterate over fields
There is also [json.to](https://github.com/nim-lang/Nim/blob/devel/lib/pure/json.nim#L1201) as an example.
Re: Compile-time string obfuscation
https://github.com/Yardanico/nim-strenc
Re: I think we can really do better...
It's not about claiming to be something revolutionary. It's about the message. The fact that I don't know about Modula and Ada says nothing. We live in the world of internet. I can read the wiki page of those lang. It doesn't make me "knowing Ada/Modula" Of course, all languages built on each other and if I would like to know who influenced Nim I'll read the wiki. This is not the information that can be valuable for me as a user in the first place. This is my point :) With all respect to Ada, Modula, and other great languages.
Re: Iterate over fields
I didn't about the quote do tricks, that's useful ! Why do you have to use backtick "`" inside quote do ? Is it to interpret macro inside a block of code ?
Re: I think we can really do better...
Note, my initial suggestion was "Nim combines successful concepts from mature language like Python, Ada and Modula with a few sounding features of latest research." Unfortunately they discarded the last part, I think to fit it all to one page. But I have copied all my advertisings to my book: [http://ssalewski.de/nimprogramming.html](http://ssalewski.de/nimprogramming.html) Section [http://ssalewski.de/nimprogramming.html#_nim_has_a_encouraging_future](http://ssalewski.de/nimprogramming.html#_nim_has_a_encouraging_future) is maybe too much advertising, maybe I will remove that. The fact that you do not know Modula and Ada is not that great, Modula was an important milestone in development of languages, it was the successor of Pascal and introduced the module concept around 1980 which current C++ is still missing. And Ada, designed by a committee it may be a bit ugly, but it has been improved and is still used in critical areas like aircraft. All languages built on each other in a way, each new languages has learned from previous ones and tries to avoid their mistakes. I guess even V-Lang will not claim to be something revolutionary new? And Rust -- it is indeed a better C++, and has a large company behind it and much hype.
Re: I think we can really do better...
just my 5 cents about the theme itself. I think it would be great to understand the audience of Nim. I think the topic is not about languages. It's about people who stand behind. People are valued. Fresh blood and young programmers who are trying to make new stuff. Why? Because It's hard to convince people that already earn money and have robust working toolsets on other langs to drop it in favor of other lang. So the audience is not about programmers that came from Python, Ada, Modula, Whatever. The audience is people who are 1. new to programming 2. have money/will to shift to new tech ( a much smaller group ) 3. hobbyist and who program for fun in a spare time I want to point on Rust and Nim sites: * Rust A language empowering everyone to build reliable and efficient software. Obviously I find Rust description sexy, elegant and I understand the mission of the language. And I understand why game dev fellas like this description. * Nim Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. The first part about typed compiled lang is ok and this is why I came here :) But I know nothing about Ada or Modula. I even never heard of those languages. And I think I don't want to. ( Not because I think they are bad of course ) >From my mentality "we take a,b,c,d from there and do better mixing stuff" is >not cool. It's like "drink my custom Pepsi, it took best of Cola". Those who >are fine with Cola won't look at custom Pepsi, and those who never tasted Cola >can't make a decision on drinking custom Pepsi that advertises flavors they >never tried. The Nim language is cool. Period. It doesn't need to compare itself with other languages. It's not a selling point. I want a language that helps me solve real problems, not a language that solves the problems of other languages. What problems I have as a game developer? The first problem is that system languages are great for writing core but often too hard for scripting and writing the game itself. Many reasons from syntax to more strict rules of how to write code. Maybe core developers fill confident but your teammate might have less experience and just want to script. That's why we have Lua and so on. That's why Unity is on the C++ side and scripting is on C# side and they're a lot of silly "optimizations" about caching variables and stuff not to make an extra call on the C++ side. That's why Unity makes "subsets of C#" to put everything in one scope. A lot of hard, dirty work I think. The second problem is portability. Pc, Mac, Linux, Consoles, Ios, Androids. It would be super nice if you can port your game to every device without rewriting the game to another language. As Nim compiles to C/C++/JS I can at least hope that I will be able to get on every possible platform. just few examples of what I find like selling points: * Write code once, deploy everywhere - selling point * You will do more typing less - selling point * The language is expressive and versatile, you can write efficiently core stuff and game scripts in the same language and scope ( I don't need to mention here C++/Lua, it's obvious ) - my personal game dev selling point. PS, I 'm 30 years old and came to programming accidentally. I developed games in C# with Unity for a decade and never identified myself as a programmer. With experience, I realized that I don't need an aircraft carrier to make 2d games. The safe options are C/C++. The other 3 options were D, Rust, and Nim. And I've started looking at Rust. Why? Everyone said that IT'S THE THING for game dev. From every corner. No one said to me to use Rust because it's like C++ but better. No. I was advertised that I can write safe code and Rust will solve my problems. It took me some time to realize that I don't like Rust language ( simple as that ). But it hooked me more than Nim at first.
AsyncHTTPClient crashes saying invalid http version
Hi, I'm still trying to figure out async/await. I am writing a script that parses a json returned by a forum API and tries to download all the files described by the json. Writing a synchronous downloader script was a breeze: [https://play.nim-lang.org/#ix=2gcb](https://play.nim-lang.org/#ix=2gcb) However I have been struggling with making the downloads asynchronous. First of all I used the `AsyncHTTPClient` called `webClient`. Then I iterate over the json nodes to look for parts that I need to construct file download link. Then I created a `seq[Future[void]]` caled `futures` to store all the futures returned by `downloadFile()` method. Then I start the loop. Each time I make a call to `downloadFile()`, I store the future into `futures` seq. Lastly when the loop finishes I call `waitFor futures.all()` to wait for the future returned by the `all()` function ([https://nim-lang.org/docs/asyncfutures.html#all%2Cvarargs%5BFuture%5BT%5D%5D](https://nim-lang.org/docs/asyncfutures.html#all%2Cvarargs%5BFuture%5BT%5D%5D)) to yield. And at the very last I `waitFor` my main function. import strutils, os, json, strformat, httpclient, asyncdispatch proc mediaLink(node: JsonNode; board, thread: string): string = let fileID = node["tim"].getInt() ext = node["ext"].getStr() result = fmt"https://i.4cdn.org/{board}/{fileID}{ext}; proc parseBoardAndThread(uri: string): (string, string) = var slashCount = 0 board = newStringOfCap(2) thread = newStringOfCap(8) for c in uri: if c == '/': slashCount += 1 elif slashCount == 3: board &= c elif slashCount == 5: if c >= '0' and c <= '9': thread &= c else: break return (board, thread) proc getAPILink(board, thread: string): string = fmt"https://a.4cdn.org/{board}/thread/{thread}.json; proc getRawLink(): string = if os.paramCount() < 1: when not defined release: # debugging purposes so I can just call ./threadgrabber without any link and dir result = "https://boards.4channel.org/wsg/thread/3360760; else: quit("Link required. Usage: $threadgrabber ") else: result = paramStr(1) proc getRawDownPath(): string = if os.paramCount() < 2: when not defined release: result = "out" else: quit("Download destination required. Usage: $threadgrabber ") else: result = paramStr(2) proc main() {.async.} = var boardAndThread = parseBoardAndThread(getRawLink()) downPath = getCurrentDir() & "/" & getRawDownPath() board = boardAndThread[0] thread = boardAndThread[1] if not downPath.existsDir(): echo("Local path not recognized. Creating directory: ", downPath) createDir downPath var webClient = newAsyncHttpClient() link = getAPILink(board, thread) j: string = await webClient.getContent(link) futures: seq[Future[void]] for node in parseJson(j)["posts"]: if node{"tim"} != nil: var tim = node["tim"].getInt() ext = node["ext"].getStr() downFileName = fmt"{downPath}/{tim}{ext}" echo("Downloading ", node.mediaLink(board, thread), " as ", downFileName, "...") var downloadFuture = webClient.downloadFile(node.mediaLink(board, thread), downFileName) downloadFuture.callback= proc() = echo("Downloading ", tim, ext, " Complete") futures &= downloadFuture waitFor futures.all() waitFor main() Run The program crashes with vague error messages, complaining that the http version is not correct: [https://pastebin.com/2jXHKbMV](https://pastebin.com/2jXHKbMV) I'm compiling with `--d:ssl --threads:on` flag. Any pointers?