Re: How to get string representation of int inside of the macros?

2018-03-30 Thread r3d9u11
many thanks, it works! (I'll try to search and read about static types)


Re: Custom pragma on type

2018-03-30 Thread cdome
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?

2018-03-30 Thread mashingan
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

2018-03-30 Thread timothee
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?

2018-03-30 Thread r3d9u11
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

2018-03-30 Thread PMunch
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.

2018-03-30 Thread cblake
@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

2018-03-30 Thread r3d9u11
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.

2018-03-30 Thread twetzel59
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 !!!

2018-03-30 Thread twetzel59
Cool! I ran it and got similar results.


Dynamic packages import at macro-time

2018-03-30 Thread r3d9u11
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 !!!

2018-03-30 Thread mratsim
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

2018-03-30 Thread mratsim
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?

2018-03-30 Thread r3d9u11
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)

2018-03-30 Thread kinkinkijkin
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

2018-03-30 Thread slangmgh
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

2018-03-30 Thread doofenstein
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 !!!

2018-03-30 Thread twetzel59
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

2018-03-30 Thread timothee
@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.