Re: How to get string representation of int inside of the macros?
many thanks, it works! (I'll try to search and read about static types)
Re: Custom pragma on type
Looks like a bug, type pragmas are not seen on the user side type User {.exportc, packed.} = object id: int import macros macro test(t: typedesc): untyped = echo t.getType()[1].symbol.getImpl.treerepr test(User) gives TypeDef Sym "User" Empty ObjectTy Empty Empty RecList IdentDefs Ident ident"id" Sym "int" Empty no pragmas to be found
Re: How to get string representation of int inside of the macros?
add static to the type import macros macro initNui(a: static[int]): typed = result = parseStmt("const b = " & $a) initNui 1
Re: Protocol Buffer library for Nim
see also [https://github.com/PMunch/protobuf-nim](https://github.com/PMunch/protobuf-nim) (doesn't rely on protoc compiler; cf [https://github.com/oswjk/protobuf-nim/issues/2](https://github.com/oswjk/protobuf-nim/issues/2)) + a discussion of related packages here: [https://github.com/PMunch/protobuf-nim/issues/1](https://github.com/PMunch/protobuf-nim/issues/1)
How to get string representation of int inside of the macros?
Hello. I tried to represent int to string inside a macros: import macros macro initNui(a:int): typed = result = parseStmt("const b=" & $a) initNui(1) but I had compilcation error: unhandled exception: false Invalid node kind nnkIntLit for macros.`$` What I'm doing wrong? How I can to get string representation of int without $ operator?
Re: Protocol Buffer library for Nim
Very nice! I tried to go a different route and make the entire parser in Nim as well. The result is being able to only call the macro with the name of your protobuf specification file and have Nim do the rest. This means that you don't even need the protoc compiler to use protobuf in Nim! I know timotheecour on GitHub made an issue in both our repos to make us aware of each others project but for the others if you want to check out my version it can be found [here](https://github.com/PMunch/protobuf-nim)
Re: use fork() to speed up compilation testing.
@twetzel59 - I use fork (and even vfork) all the time. They work just fine. @Krux02 - I have never used compiler-as-a-service mode which seems originally targeted at IDEs, but that feature may apply to testing as well. See `compiler/service.nim` and `tests/testament/caasdriver.nim`..maybe search for "caas". That said, I suspect a lot of the time is actually the C compiler, not the Nim compiler. If you can set up a nim.cfg to run tests with TinyCC/tcc (the mob branch), things could probably go much faster.
Re: Dynamic import of packages at macro-time
well, I'm found [similar theme](https://forum.nim-lang.org/t/3061/2). This works: import macros macro load*(modulesSeq: varargs[untyped]): untyped = result = newStmtList() for module in modulesSeq: result.add parseStmt("from " & $module & " import nil") const a = 0 when a == 0: load strutils echo strutils.join(@[1,2,3], ", ") elif a == 2: load asdsadasd # will excepted if set a to 2 cool
Re: use fork() to speed up compilation testing.
Not having worked on the compiler, I can't guarantee anything, but here would be my first 3 questions: * Has anyone successfully used `fork()` from Nim? * Does this memmapping mess up the GC? * What about handling dead processes? Before too many tests are executed the compiler would need to handle the `SIGCHLD` signal (anyone with Unixlike knowledge sure about this?) To start, I would try simple Nim programs and see if forking works properly. This could be a good way to do things...
Re: vtref and vtptr vs method !!!
Cool! I ran it and got similar results.
Dynamic packages import at macro-time
Hi. Does Nim supports anything like a "dynamic packges loading"? For example, I have 3 packages: pack0.nim (root package) contains: var dstBack = 0 # some variable-indetifier (will indicate, from wich poackage someProc will be called) macro init*(back:int) = # some initialization macros, who sets variables value before "someProc" called dstBack = back value macro someProc*(a:int) = # some macros, who will return "someProc" from destination package (in choice of "dstBack") case: dstBack of 0: pack1.someProc of 1: pack2.someProc else: proc (a:int) = discard pack1.nim: proc someProc*(a:int): int = result a += 1 pack2.nim: proc someProc*(a:int): int = result a -= 1 Is it possible to realize this scheme in Nim? Thanks.
Re: vtref and vtptr vs method !!!
If performance is your concern, use Nim methods. I benchmarked them vs procs and closures and I found out that they are only 3 times slower than regular proc: [Bench](https://github.com/mratsim/Arraymancer/blob/master/benchmarks/implementation/proc_method_closure_bench.nim). Don't run it on the website or without -d:release import times type FooBase = ref object {.inheritable.} dummy: int type Foo{.final.} = ref object of FooBase value : float32 proc inplace_add_proc(x: var Foo, a: float32) = x.value += a proc inplace_add_closure(x: var float32, a: float32) = # Note that we create a closure inside a critical hot path # if in your use case you can do it outside of a hot loop it will be much faster proc add_closure(v: var float32) = v += a add_closure(x) method inplace_add_method(x: FooBase, a: float32) {.base.} = discard method inplace_add_method(x: Foo, a: float32) = x.value += a # Procs serve as a warmup, so they might be a little bit faster in reality. var bar : Foo new bar var start = cpuTime() for i in 0..<100_000_000: inplace_add_proc(bar, 1.0f) echo " Proc with ref object ", cpuTime() - start var x : float32 start = cpuTime() for i in 0..<100_000_000: inplace_add_closure(x, 1.0f) echo " Closures ", cpuTime() - start var baz : Foo new baz start = cpuTime() for i in 0..<100_000_000: inplace_add_method(baz, 1.0f) echo " Methods ", cpuTime() - start # Results with -d:release on i5-5257U (dual-core mobile 2.7GHz, turbo 3.1) # Proc with ref object 0.03 # Closures 2.708598 # Methods 0.31222198
Re: scope guards
It's a post from 2013 . Anyway the idiomatic way to do scope guard is with a template that does try: body finally: as it's done by Udiknedormin [here](https://forum.nim-lang.org/t/3205/1#20223). There is an example in the [guards and lock section](https://nim-lang.org/docs/manual.html#guards-and-locks) of the manual too.
Re: how to call a function by name?
Thanks for clarification regarding Nim! (but, as I know, "reflection" is a conception relating only for runtime. everything else is something different)
SIGSEGV using lines(filename)
In the following code, with the error line marked with a "119", I get a SIGSEGV. Software distribution is arch linux on this machine. var envs, wavs, fms, macros: seq[tuple[name: string, values: string]] var name, artist: string = "" var tickrate: int16 = 0 ... proc loadfile(filename: string): seq[tuple[blk: string, lin: string]] = var wavblock, envblock, mublockplay, mublockloop, fmblock: bool = false var metablock: bool = true var counter: int = 0 block load: for line in lines(filename): counter.inc echo counter block read: if line.startsWith('#'): break read elif line.startsWith("END"): break load elif line.isNilOrEmpty(): break read elif line.isNilOrWhitespace(): break read elif line.startsWith("/env"): envblock = true metablock = false mublockplay = false mublockloop = false fmblock = false wavblock = false break read elif line.startsWith("/wav"): wavblock = true metablock = false mublockplay = false mublockloop = false fmblock = false envblock = false break read elif line.startsWith("/fm"): fmblock = true metablock = false mublockplay = false mublockloop = false envblock = false wavblock = false break read elif line.startsWith("/mu1"): mublockplay = true fmblock = false metablock = false mublockloop = false envblock = false wavblock = false break read elif line.startsWith("/mu2"): mublockloop = true fmblock = false metablock = false mublockplay = false envblock = false wavblock = false break read elif metablock and line.startsWith("name="): name = line name.removePrefix("name=") break read elif metablock and line.startsWith("artist="): artist = line name.removePrefix("artist=") break read elif metablock and line.endsWith("hz"): var templine = line templine.removeSuffix("hz") tickrate = templine.parseInt().int16 break read elif mublockplay or mublockloop: if mublockplay: result.add(("mP", line)) break read else: result.add(("mL", line)) break read elif envblock and not line.isNilOrEmpty(): 119 result.add(("e", line)) break read elif wavblock and not line.isNilOrEmpty(): result.add(("w", line)) break read elif fmblock and not line.isNilOrEmpty(): result.add(("f", line)) break read else: break read return The code being read is in [this link ](https://github.com/kinkinkijkin/kPMML/blob/master/examples/referenceexample4.txt) File exists. SIGSEGV happens after reading the first 6 lines (up to /env) Possibly a bug?
Re: Bug (?) with templates
I think maybe this is template bug. These code doesn't compile from @zielmicha. template bar() {.dirty.} = echo a template foo() = let a = 5 bar() foo() But when we turn foo into proc, the code works. template bar() {.dirty.} = echo a proc foo() = let a = 5 bar() foo() So it is doesn't matter if the foo is hygienic or not.
Custom pragma on type
Is there a way to check an object type for a custom pragma? In the manual there's an example of a custom annotation on a type, but it isn't ([https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-custom-annotations](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-custom-annotations) ): const tblspace {.strdefine.} = "dev" # switch for dev, test and prod environments: type User {.dbTable("users", tblspace).} = object id {.dbKey(primary_key = true).}: int name {.dbKey"full_name".}: string is_cached {.dbIgnore.}: bool age: int UserProfile {.dbTable("profiles", tblspace).} = object id {.dbKey(primary_key = true).}: int user_id {.dbForeignKey: User.}: int read_access: bool write_access: bool admin_acess: bool I tried using `hasCustomPragma` but it only works for fields and procs. Then I tried using `getImpl` but it only includes the pragmas on the fields and ignores the pragmas on the type itself. Am I doing something wrong and there is a way to do this, or is this a bug?
Re: vtref and vtptr vs method !!!
Araq, should I be avoiding the use of `method`? I generally consider it useful, especially as it allows dynamic dispatch through dispatch trees as opposed to function pointers. Due to performance concerns, I am often (unreasonably?) averse to function pointers. * * * Here's my two cents: I basically like the approach in `streams` with `proc` members used to form an interface, and this could be adapted to allow static dispatch when available as well by making all derived `proc` s exported and leveraging overloading. The advantage of a VTable is that we don't have to waste memory on interface pointers for every procedure, for each instance. I believe the `streams` implementation does this to allow arbitrary runtime selection of an implementation, more like signals. In real code, I am not sure how much the performance of this pattern is a concern. I tend to over-worry about performance and compromise expressiveness. Nim, as I understand, aims for both so the `vtref` makes sense to me, because it can remove boilerplate code in these `streams` -like interfaces. Oh, and I like the powerful idea of `concept`, especially as a constraint on generics. I hope it stays in the spec - typeclassing and traditional OO classes are definitely not the same, and can coexist in harmony * That was more than two cents, LOL
Re: a proc returning void creates 1 arg, not 0: breaking generic code
@Dennis my bad I should've verified the D code I posted; with tuples though we have: import std.stdio:writeln; void fun(T...)(T n) { static foreach (x; n) writeln(x); writeln("L=", T.length); } void main(){ import std.typecons:tuple; fun(tuple(1,2).expand); // L=2 fun(tuple(1).expand); // L=1 fun(tuple().expand); // L=0 } in any case, the previous answers make total sense regarding Nim's behavior.