Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nim stored procedure reference in tuple

Tags:

nim-lang

Nim Compiler Version 0.13.0 (2016-01-19) [Windows: i386]

How would I store a reference to a procedure in a tuple:

Job = tuple[every:int, timescale:string, timestr:string, jobfunc:proc]

proc run(job: Job, jobfunc: proc): Job =
  result = job
  result.jobfunc = addr jobfunc

In the run proc jobfunc: proc gets accepted. In the tuple I get:

Error: 'proc' is not a concrete type.

So whats the type of proc?

[edit]

My ultimate goal is to pass a function with arbitrary parameters to run.

Atm I've managed to work around this by using an seq[string] but maybe one knows a more generic way.

type
    Job = tuple[every:int, timescale:string, timestr:string, jobfunc: proc(args:seq[string]) {.gcsafe, locks: 0.}]


proc run(job: Job, jobfunc: proc,args:seq[string]= @[""] ): Job =
  # ...
  discard


proc myfunc(args:seq[string]) =
  echo "hello from myfunc ", args
  discard

schedule every(10).seconds.run(myfunc,args= @["foo","uggar"])     
like image 764
enthus1ast Avatar asked Aug 30 '16 16:08

enthus1ast


2 Answers

Storing a reference to proc accepting any combination of arguments in a non-generic way is not possible without losing compile-time type safety. If you really need it (in your case most likely you don't), you should use something like variant types with runtime type checks. However it looks like an overkill for your case. I don't think you have to store arguments user provides to his proc, but rather store a proc (closure) without arguments, allowing your user to wrap his arguments in a closure. Basically, rewrite your run to smth like:

proc run(job: Job, jobfunc: proc()): Job =
  # ...

Now your user would do:

proc myfunc(args:seq[string]) =
    echo "hello from myfunc ", args
discard

var myArgs = @["foo","uggar"]

schedule every(10).seconds.run do(): # Do is a sugar for anonymous closure in this context
    myfunc(myArgs)
like image 60
uran Avatar answered Oct 13 '22 11:10

uran


There are different proc types, like proc: int, proc(x: int): string, in your case this should work:

type Job = tuple[every: int, timescale, timestr: string, jobfunc: proc()]

That specifies that jobfunc is a proc that takes no arguments and returns nothing.

like image 34
def- Avatar answered Oct 13 '22 11:10

def-