Re: Doc error
There is an issue listed now: [https://github.com/nim-lang/Nim/issues/7438](https://forum.nim-lang.org/postActivity.xml#https-github-com-nim-lang-nim-issues-7438).
Re: how to call a function by name?
Nim is statically typed so only compile-time reflection (see module typetraits for instance) is possible. Runtime reflection like in java is not possible (all metadata stripped away by the backend compiler)
Re: how to call a function by name?
But is it possible in Nim to call procedure with parameters who name and parameters will be known at runtime (and get result value)? Does Nim support reflection?
Re: scope guards
> Note that if you use except/finally as a statement your code will do > unexpected things if you try to concatenate it into a single line with a > semicolon (see > [https://github.com/Araq/Nimrod/issues/412)](https://github.com/Araq/Nimrod/issues/412\)). this bug has been fixed [https://github.com/nim-lang/Nim/issues/412](https://github.com/nim-lang/Nim/issues/412) > Presumably working nimrod code matching your example would be: ... IIRC now we use defer: instead of finally: for that although both seem to work. see also: [https://github.com/timotheecour/D_vs_nim/pull/20#issuecomment-377364528](https://github.com/timotheecour/D_vs_nim/pull/20#issuecomment-377364528)
Re: proc(t: typedesc): var t -- expected 'None' error
Thank you guys! I stayed with templates, don't know why I didn't use them from the beginning. But typedesc[T] is really, really evil and black magic: proc getMutableVal[T](key: int, desc: typedesc[T]): var T = getTableOf(T)[key]
Re: How to return Unicode in shared library
Thanks jangko .These solutions are c specific. I am on Windows and in winapi there are two functions multibytetowidechar and widechartomultibyte .if Utf8 string contains character with size of more than one byte then multibytetowidechar with cp_utf8 we can get utf16 string. Is there similar functions available for Linux and Mac. Actually I want to use Nim language for making shared libraries for all 3 major desktop plateforms. It is a supplement to use plateforms API embedded in Nim proc, exported in dll,so,dylib.. etc. For C backend it is ok but cpp backend ABI is problem.
Re: Doc error
The docs are missing.
Doc error
Hello, I am getting a 404 for `asyncstreams` and `asyncfutures` when I navigate to them from the Imports section of this documentation page: [https://nim-lang.org/docs/asyncdispatch.html#6](https://forum.nim-lang.org/postActivity.xml#https-nim-lang-org-docs-asyncdispatch-html-6) Do these modules still exist, or are the docs missing?
Is there reflection in Nim?
Hi. Is it possible in Nim to call procedure with parameters who name and parameters will be known at runtime (and get result value)?
Re: How to dealloc complex object correctly?
thanks!
Re: a proc returning void creates 1 arg, not 0: breaking generic code
> in D, variadic argument size will be 0 when calling fun(bar()); since bar > returns void isn't that a better behavior? if not what would be downsides of > that? It doesn't? Aside from the wrong semi-colon in the for-loop it gives an error: [https://run.dlang.io/is/6sfUA5](https://run.dlang.io/is/6sfUA5) "cannot deduce function from argument types !()(void)" It seems like weird behavior if that were the case. What would fun(1, bar(), 1); do, give a list of 2 integers?
Re: cpp compilation into own namespace
PRs are welcome.
Re: Algorithms must decouple from containers
@cdome the openArray makes no difference in this regard. It's a (pointer, length) tuple, so you have to increment an iterating pointer, or keep an integer offset and do pointer arithmetics from the start pointer. both are stateful, and just equally as stateful as an interator. Except you've just made a regression, because iterators support linked lists or any esoteric memory layout, but (pointer, length) do not. I insist, this is not bad design, decoupling is a good principle. c.f. [https://www.youtube.com/watch?v=ltBdTiRgSaw](https://www.youtube.com/watch?v=ltBdTiRgSaw) from 1':00
Re: complex statement requires indentation
@mashingan that's the problem. I suggest to remove this feature from ?? and put it in ???.
Re: how to call a function by name?
Oh yes of course, you can store the procs in a table. Though you might have issue with type-checking if they don't have the exact same arguments.
Re: cpp compilation into own namespace
I did some deeper research. wrapping the nimbase.h would be wrong it is enough to wrap the TFrame stuff conditionally into a namespace Nim. In the generated code the wrapping should start after the #undef unix or before the first declaration until the end. Would you accept a pull request when I try to do the change ? With my manual patches I can compile in debug and release mode, and the above code reduces to: import vcl/stdctrls, vcl/forms, vcl/sysutils, strutils {.this:self.} type TForm2* {.importcpp:"TForm2", header:"uFNimHelloCBuilder.h".} = object of TForm Button1*: ptr TButton Label1*: ptr TLabel TNotifyCode* = proc(self: ptr DelphiObject, sender: ptr DelphiObject) {.fastcall.} var counter = 0 proc myClick(self: ptr TForm2, sender: ptr DelphiObject) {.fastcall.} = Button1.Caption = "greetings from nim".capitalize proc test(self: ptr TForm2) {.exportc, fastcall.} = inc counter Button1.Caption = Button1.Caption & $counter var mycall: TMethod mycall.Data = self #var call: TNotifyCode = cast[TNotifyCode](myClick) mycall.Code = cast[TNotifyCode](myClick) Label1.OnClick := mycall
Re: a proc returning void creates 1 arg, not 0: breaking generic code
> @timothee > > Why don't you write D as d? Please learn to write Nim with a capital letter. > This is disrespectful at least. I seriously doubt @timothee meant it in a disrespectful way. This is a programming forum, not a parliamentary chambers so no need to call people out for such things.
Re: a proc returning void creates 1 arg, not 0: breaking generic code
> fun(bar()) # n.len=1 ?? why not 0? Because fun is a macro, not a function. A macro call is not supposed to "evaluate" its arguments - definitely not untyped ones - before using them. It takes pieces of code, transforms them into AST nodes (in this case: one node, hence n.len = 1) and makes a new AST node out of them. Your D example shows a function, which is a completely different animal. Imagine bar had side effects. Would you really want fun(bar()) to result in code which does nothing (since the varargs argument would be considered "empty")?
Re: cpp compilation into own namespace
I am trying to use Embarcadero C++ Builder with Nim. The problem is that by default C++ Builder pulls in all namespaces. So you have name clashes for example with TFrame or Exception. There is a way to avoid this by defining DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE which should prevents this. But still it is APITA to work with this colliding names and till now I can only compile with -d:release. I think it would get easier if the generated Nim code would be wrapped into its own namespace Nim. This means the #include "nimbase.h" and the generated code to illustrate my problem in the following code I need to include uFNimHelloCBuilder.h in order to use TForm2, but this needs to pull in some namespaces of the VCL which pulls ins TFrame for example. This uFNimHelloCBuilder.h is managed by the C++ Builder and uses only unqualified names like TForm or TButton or TFrame... import vcl/stdctrls, vcl/forms, vcl/sysutils, strutils {.emit:"""/*TYPESECTION*/ using namespace System; using namespace Vcl; using namespace Vcl::Controls; using namespace Vcl::Stdctrls; using namespace Vcl::Forms; #include "uFNimHelloCBuilder.h" """.} {.this:self.} type TForm2* {.importcpp:"TForm2" .} = object of TForm Button1*: ptr TButton Label1*: ptr TLabel TNotifyCode* = proc(self: ptr DelphiObject, sender: ptr DelphiObject) {.fastcall.} var counter = 0 proc myClick(self: ptr TForm2, sender: ptr DelphiObject) {.fastcall.} = Button1.Caption = "greetings from nim".capitalize proc test(self: ptr TForm2) {.exportc.} = inc counter Button1.Caption = Button1.Caption & $counter var mycall: TMethod mycall.Data = self #var call: TNotifyCode = cast[TNotifyCode](myClick) mycall.Code = cast[TNotifyCode](myClick) Label1.OnClick := mycall
Re: Partial code upgrades: important or meh?
Please, focus on Nimble lockfiles. > Nimble (and Nim itself for that matter) don't support a dependency on two > different versions of the same package. Is this a problem that will bite us > in the future? No, IMO it's a very reasonable limitation.
Re: vtref and vtptr vs method !!!
I haven't made up my mind yet. `vtref` and `vtptr` are about giving Nim interfaces, yes. But `concept` is still to rough to base yet another feature on top of it and larger OO projects in Nim are full of `method` already, so removing it would be a slow painful process.
Re: a proc returning void creates 1 arg, not 0: breaking generic code
> Maybe I'm missing some valid use case I haven't thought about? Nim macros cannot be directly compared to D templates/generics. You can use Nim macros to implement DSL, such as assembler, JIT engine, shader language, etc: macro my_asm_engine(n: varargs[untyped]): typed = bla bla bla my_asm_engine: mov eax, ebx xor eax, eax whatever if Nim macros choose to ignore void returning function call, it would be unusable to implement DSL at all.
Re: How to return Unicode in shared library
if your unicode string is encoded in UTF8 and your C shared library also accept UTF8 encoded, then it is safe to export nim string to cstring. the Nim compiler will automatically handle the conversion. actually, no conversion take place, only pointer passing. if it is not UTF8 encoded, or the C library cannot accept UTF8, you can do some conversion and pass the pointer of your unicode string to C. #assume both of this function deals with UTF8 encoded string proc get_c_unicode(): cstring {.importc: bla bla bla.} proc put_c_unicode(x: cstring): cint {.importc: bla bla bla.} var nim_unicode_string = $get_c_unicode() #do something with unicode module if put_c_unicode(nim_unicode_string) != 0.cint: echo "ok" as simple as that, if both party agree to use UTF8 unicode codepoints it self it not too hard to program, but rendering and formatting the unicode font/typeface, that is the real nightmare.
Re: a proc returning void creates 1 arg, not 0: breaking generic code
@rpowers thanks, that solves my problem! and thanks for the rationale, makes sense.
Re: a proc returning void creates 1 arg, not 0: breaking generic code
@timothee Why don't you write D as d? Please learn to write Nim with a capital letter. This is disrespectful at least.
Re: how to call a function by name?
@timothee, use `procvar` annotation if you have the proc defined proc echoa() {.procvar.} = echo "proca" proc echob() {.procvar.} = echo "procb" let echos = @[echoa, echob] for f in echos: f() You can use together with enum as matching case or any other method, like using index of array or string key table etc
Re: a proc returning void creates 1 arg, not 0: breaking generic code
Oh, right! I guess it's testing it on untyped rather than the actual type in the macro. Anyways, this one is definitely working, it just tests for void-typed arguments: import macros import typetraits import strformat macro fun*(n: varargs[typed]): typed = result = newNimNode(nnkStmtList, n) var echoedCount = 0 for x in n: if x.getTypeInst.typeKind != ntyVoid: result.add(newCall("echo", x)) echoedCount += 1 result.add(newCall("echo", newStrLitNode($(echoedCount proc bar() = echo "ok" fun(1+1) # n.len=1 fun() # n.len=0 # comment this to make it work fun(bar()) > isn't that a better behavior? if not what would be downsides of that? No, I think automatically filtering void arguments in a macro is not a better or intuitive behavior. What if you remove a return type from a function and the compiler just silently starts ignoring it in argument lists instead of producing a type mismatch error? That seems like it could be an interesting source of bugs. I guess what you're asking for is not SFINAE, but it feels similar -- it's a hack used to make template systems have some limited metaprogramming. I think that you'll find that sort of thing is not necessary with Nim, you can just write a macro that does what you want. Is there something specific that you're trying to do that requires the argument-ignoring approach used in D? Maybe we could help you come up with a good solution for it in Nim.
Re: Is there any way to create template with await?
The following code is extracted from asyncpg. template withConnection*(pool: apgPool, conn, body: untyped) = ## Retrieves first available connection from pool, assign it ## to variable with name `conn`. You can use this connection ## inside withConnection code block. mixin getFreeConnection var connFuture = getFreeConnection(pool) yield connFuture var index = connFuture.read block: var conn = pool.connections[index] body pool.futures[index].complete() When code in 'body' raise a exception, the last line "pool.future[index].complete()" will not be executed and the connection in the pool will be leaked. Wrapper the body in a proc is not possible when body contains async call itself. I have no idea how to make the above code works right.
Re: a proc returning void creates 1 arg, not 0: breaking generic code
> bar returns nothing, how could you echo it. I see nothing to fix here, > especially not the involved lengths. if nim treated a void-returning function call as being 0 arguments as in D (as if no argument was passed) then there would be no call to echo (ie, fun(bar()) would call bar() and then fun()) ; this introduces less edge cases (no need to consider void variables). Maybe I'm missing some valid use case I haven't thought about? > I guess that D has implemented some kind of SFINAE that won't run for args > that cause errors? no, it's simpler than that: as I was explaining above, in D, variadic argument size will be 0 when calling fun(bar()); since bar returns void isn't that a better behavior? if not what would be downsides of that? > it doesn't need those sorts of things, but you can certainly emulate the > behavior. your code doesn't work, compiles(echo(x)) still returns true; here's a full modified example so you can click run: import macros import typetraits import strformat macro fun*(n: varargs[untyped]): typed = result = newNimNode(nnkStmtList, n) var echoedCount = 0 for x in n: if compiles(echo(x)): result.add(newCall("echo", x)) echoedCount += 1 result.add(newCall("echo", newStrLitNode($(echoedCount proc bar() = echo "ok" fun(1+1) # n.len=1 fun() # n.len=0 # comment this to make it work fun(bar())
vtref and vtptr vs method !!!
I'm reading the concept documentation in the devel branch and I noticed the new (I think) descriptions of vtref and vtptr. Are these intended to replace method? I haven't seen these features discussed on the forum yet. From the brief description, it appears that these would provide interfaces, a much requested feature for Nim. If that's the intention, maybe IfcRef/IfcPtr could be used as names? My initial impression is that I like this a lot, to me it appears much more harmonious with the rest of Nim than multimethods, but that having both would not be a good thing. I've still not written anything using the new features, but I generally avoid method so I'm not the ideal judge.
Re: a proc returning void creates 1 arg, not 0: breaking generic code
I guess that D has implemented some kind of SFINAE that won't run for args that cause errors? Since Nim has a full macro system, it doesn't need those sorts of things, but you can certainly emulate the behavior. Use the proc compiles, which will return true if an expression compiles without errors: macro fun*(n: varargs[untyped]): typed = result = newNimNode(nnkStmtList, n) var echoedCount = 0 for x in n: if compiles(echo(x)): result.add(newCall("echo", x)) echoedCount += 1 result.add(newCall("echo", newStrLitNode($(echoedCount proc bar() = echo "ok"
Re: Is there any way to create template with await?
The document is about exception raised by async proc, my problem is about the exception raised by called proc between async code using resource, they are something different. Maybe I can wrapper the body with a proc which turn exception into return value.