Re: How do you add switched to the build task?

2020-01-12 Thread sflennik
Thank you, that worked. I created a config.nims file in my main folder and 
added one line: switch("define", "ssl")


Re: stdlib pegs: Accessing optional subexpressions

2020-01-12 Thread sky_khan
Afaik, stdlib peg is designed for nim compiler itself and somewhat limited. So, 
you may consider using [npeg :](https://github.com/zevv/npeg)


import npeg

let parser = peg("example"):
  example <- >?word * >?number
  word <- +Alpha
  number <- +Digit

echo parser.match("abc").captures # @["abc", ""]
echo parser.match("123").captures # @["", "123"]


Run


Re: Newbie question: Why am I getting the too many variables error on my loop index variable?

2020-01-12 Thread sky_khan
if that "split(',')" is from strutils, it returns seq[string], not tuple. I 
guess you need to use something like this: 


for line in readFile(day02PathAndName):
  var data = line.split(',')
  if data.len() == 2:
myKey = data[0]
myValue = data[1]
result...
  else:
echo "Error in input: ", line


Run


Re: How do you add switched to the build task?

2020-01-12 Thread mikra
just put the switch into a "config.nims". it's nimscript. further reading 
[https://github.com/nim-lang/Nim/wiki/Using-nimscript-for-configuration](https://github.com/nim-lang/Nim/wiki/Using-nimscript-for-configuration)


Newbie question: Why am I getting the too many variables error on my loop index variable?

2020-01-12 Thread freeflow
I'm currently having a bash at using nim by converting my efforts for Advent of 
Code from VBA to nim. Unfortunately I've got stuck when trying to iterate over 
the input from a file and push that input into an OrderedTable.


proc GetDay02Program(): OrderedTable[int64,int64]  =
for myKey, myValue in  readFile(day02PathAndName).split(','):
result[myKey.int64]=myValue.parseint.int64

Run

'''

In the code above the myKey variable is flagged and the error message is 'wrong 
number of variables'. I'm a bit perplexed as the reading I've done indicates 
that my for statement is as expected.

I'd appreciate being enlighteded as to why iI'm getting the error.


Re: How do you add switched to the build task?

2020-01-12 Thread sflennik
Where do I put the line: switch("define", "ssl")?

I tried a few more things without luck:

  * I tried adding a "before build" task:




before build:
  switch("define", "ssl")


Run

  * I tried adding it by itself in the my project nimble file.
  * I tried adding it to different cnf files.
  * I tried adding it to a project .nims file.
  * I've reviewed the nimble readme and the nimscript docs.



In the nimble docs I found this:

> Make sure that Nimble is configured to run with SSL, adding a -d:ssl flag to 
> the file src/nimble.nim.cfg. After that, you can run src/nimble install and 
> overwrite the existing installation.

I'm not sure what "run src/nimble install" means but adding -d:ssl to the cfg 
wasn't enough.

I'm running on a Mac.


Re: grim - graph structures in Nim

2020-01-12 Thread ebran
The short answer is probably that I've probably been exposed to too much Python 
over the last years... The longer answer is that I am thinking of a much more 
general data structure than a graph of ints, or floats, or any other single 
type. One where general data can be stored and searched efficiently, leveraging 
modern graph theory for performance. (Not there yet, though...)

Regarding the Object vs ref Object it may be a misunderstanding of the concepts 
from my side... I was thinking of the ref as a shared data structure and the 
object as being copied around. For performance, I imagined that having one ref 
on the heap was better than copying data on the stack. But I could be wrong 
here, and I am glad to be enlightened by someone with more Nim experience.

Thanks for the feedback.


Re: I wrote some nim code that works, but I don't understand how/why it works.

2020-01-12 Thread spip
I think my problem is another case of [issue 
#11167](https://github.com/nim-lang/Nim/issues/11167). I've written a smaller 
code example that I added to the issue.


Re: I wrote some nim code that works, but I don't understand how/why it works.

2020-01-12 Thread spip
Thanks **mashingan** for showing how to work around the error message.

I just wanted confirmation that the problem is on the compiler side or the 
libraries and not in my minimal code before opening an issue. The strange thing 
is that the errors does not always appear, as I've shown when you use a single 
file instead of 2 modules.

Like found by **MrZoraman** who opened that thread for the same compiler error, 
this bug is based on a small change in the code making it appear or not. It 
does not appear any more with the current compiler version for his code.


Setup Nim with Vim/NeoVim

2020-01-12 Thread sbr
Hello,

I'm new to Nim and I wanted to use Vim/NeoVim as my main editor.

Here's my setup with language server support, etc.

Maybe it helps someone else.

Prerequisites:

  * NeoVim or Vim8 installed
  * Nim installed



The original blog post (with better formatting) is here: 
[https://www.rockyourcode.com/setup-nim-with-neovim](https://www.rockyourcode.com/setup-nim-with-neovim)/

# Language Server

Install a language server protocol implementation for Vim. 
**[LanguageClient-neovim][languageclient]** is the only one I could get working 
with several languages (Elixir, Reason, JavaScript, Nim).

For example, with [vim-plug](https://github.com/junegunn/vim-plug):


Plug 'autozimu/LanguageClient-neovim', {
\ 'branch': 'next',
\ 'do': 'bash install.sh',
\ }

Run

Install **[nimlsp][nimlsp]**. Run this command in your terminal:


nimble install nimlsp

Run

Configure the plugins within your vim configuration (`~/.vimrc` or similar):


set hidden

nnoremap  :call LanguageClient_contextMenu()

let g:LanguageClient_serverCommands = {
\   'nim': ['~/.nimble/bin/nimlsp'],
\ }

Run

The setup specifies the location of nimlsp. On your computer, it might be 
different.

Now you can open a Nim file, and hit `F5`. The LanguageClient menu will pop up. 
 
You can fine-tune the LanguageClient configuration to your liking.  
Use `:h LanguageClient` within Vim to get more information.  
[nimlsp][nimlsp] can be a bit peculiar about its setup. [The language server 
needs some of Nim's files in order to work 
properly.](https://github.com/PMunch/nimlsp/issues/22).  
You might want to check out the [GitHub repository][nimlsp] for further 
trouble-shooting.  


# (Tab) Completion

You can use [Vim's inbuilt completion][vimtyping], but the easier way is to 
install a completion plugin.

**[VimCompletesMe][vimcompletesme]** is a minimal plugin that does everything I 
need.


Plug 'ajh17/VimCompletesMe'

Run

# Linting and Formatting Code

> [ALE (Asynchronous Lint Engine)][ale] is a plugin providing linting (syntax 
> checking and semantic errors) in NeoVim 0.2.0+ and Vim 8 while you edit your 
> text files.

Install it with your package manager (or find alternative instructions on 
[GitHub](https://github.com/dense-analysis/ale#3-installation)):


Plug 'dense-analysis/ale'

Run

Example setup in your `init.vim` (or `~/.vimrc`, etc.):


let g:ale_sign_error  = '✘'
let g:ale_sign_warning= '⚠'
highlight ALEErrorSign ctermbg=NONE ctermfg=red
highlight ALEWarningSign ctermbg  =NONE ctermfg=yellow
let g:ale_linters_explicit= 1
let g:ale_lint_on_text_changed= 'never'
let g:ale_lint_on_enter   = 0
let g:ale_lint_on_save= 1
let g:ale_fix_on_save = 1

let g:ale_linters = {
\   'nim':  ['nimlsp', 'nimcheck'],
\}

let g:ale_fixers = {
\   'nim':  ['nimpretty'],
\   '*':['remove_trailing_lines', 'trim_whitespace'],
\}

Run

Improve ALE's performance by setting the linters you need and don't lint every 
time you type in something.  
Fix a file when you save or call `:ALEFix` manually.  
See `:h ale` for more information.  


## Links

  * [Nim language](https://nim-lang.org/)
  * [NeoVim](https://neovim.io/)




Re: Compile-time string obfuscation

2020-01-12 Thread LeFF
I wonder if it is possible to apply the encryption code to a module 
automatically, so that it won't be needed to mark all strings with "xs". I was 
trying something like that few years ago, I even created a topic about it on 
the forum I believe, but I don't remember how it all ended. 


Re: Compile-time string obfuscation

2020-01-12 Thread LeFF
I found it: [https://forum.nim-lang.org/t/338](https://forum.nim-lang.org/t/338)


Re: Compilation failure 1.0.4 on Pi3

2020-01-12 Thread mratsim
What distribution are you using? Because if it's Raspbian it's 32-bit even if 
the hardware supports 64-bit.

Also depending on your RAM you might need to increase your swap, see 
[https://github.com/status-im/nim-beacon-chain#raspberry-pi](https://github.com/status-im/nim-beacon-chain#raspberry-pi)


sudo vi /etc/dphys-swapfile
# Set CONF_SWAPSIZE=2048
# :wq
sudo reboot


Run


Re: How do you add switched to the build task?

2020-01-12 Thread juancarlospaco
switch("define", "ssl")


stdlib pegs: Accessing optional subexpressions

2020-01-12 Thread sschwarzer
Assume I have the following PEG definition:


import pegs

let examplePeg = peg"""
  A <- {L}? {D}?
  L <- \a+
  D <- \d+
"""


Run

If I test strings against this PEG, I get: 


if "abc" =~ examplePeg:
  # `["abc", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 
"", "", "", ""]`
  echo matches

if "123" =~ examplePeg:
  # `["123", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 
"", "", "", ""]
  echo matches


Run

Now, since the subexpressions `L` and `D` are optional, it seems I need to look 
at the matched strings and check them _again_ despite the PEG already defines 
whether I expect letters or digits for these subexpressions.

The only API I found that gives more control is `eventParser`, which on the 
other hand seems far too complicated for a relatively simple case as this.

Is there a simpler API (or a combination of them) in the `pegs` module, which I 
may have missed?


How do you add switched to the build task?

2020-01-12 Thread sflennik
My nim package needs the -d:ssl compile switch. How do I add the switch to the 
nimble build task used by nimble install? I tried a number of things but none 
of them worked for me.

  * I tried making a cfg file with the line "-d:ssl" in it.
  * I tried adding a switch("d", "ssl") in a nimble build task.
  * I tried overwriting the build task with an exec statement to run: "nim c 
-d:ssl ...". It seems the you cannot overwrite the build task.




Re: How to create and manage a http users sessions?

2020-01-12 Thread mrhdias
Thank you @enthus1ast and everyone for showing me the way. Now all code 
compiles without errors or warnings. 


import asynchttpserver, asyncdispatch
import tables
import times
import oids
import cookies
import strformat
import strtabs
import strutils

type
  Session = ref object
id: string
map: TableRef[string, string]
request_time: DateTime
callback: proc (id: string): Future[void]

type
  AsyncHttpSessions = ref object of RootObj
pool: TableRef[string, Session]
session_timeout: int
sleep_time: int


proc sessions_manager(self: AsyncHttpSessions): Future[void] {.async.} =
  while true:
await sleepAsync(self.sleep_time)

if self.pool == nil:
  continue

echo "Number of active sessions: ", self.pool.len
echo "check for sessions timeout..."
var to_del = newSeq[string]()
for key, value in self.pool:
  if (now() - self.pool[key].request_time).inSeconds > 
self.session_timeout:
echo "session id timeout:", key
to_del.add(key)

for key in to_del:
  if self.pool[key].callback != nil:
await self.pool[key].callback(key)
  echo "the session will be deleted:", key
  self.pool.del(key)

proc set_session(self: AsyncHttpSessions): Session =
  let session_id = genOid()
  
  return (self.pool[$session_id] = Session(
id: $session_id,
map: newTable[string, string](),
request_time: now(),
callback: nil
  ); self.pool[$session_id])

proc get_session(self: AsyncHttpSessions, id: string): Session =
  (self.pool[id].request_time = now(); self.pool[id])

proc new_async_http_sessions(
  sleep_time: int = 5000,
  session_timeout: int = 3600): AsyncHttpSessions =
  
  let self = AsyncHttpSessions()
  self.sleep_time = sleep_time
  self.session_timeout = session_timeout
  self.pool = newTable[string, Session]()
  
  asyncCheck self.sessions_manager()
  
  return self


proc login(): string =
  return """







  Username: 
  Password: 
  



"""

proc cb(req: Request, sessions: AsyncHttpSessions) {.async.} =
  
  if req.url.path == "/login" and req.reqMethod == HttpPost:
var params = initTable[string, string]()
for part in req.body.split('&'):
  let pair = part.split('=')
  if pair.len == 2:
params[pair[0]] = pair[1]

if params.hasKey("username") and params["username"] == "test" and
  params.hasKey("password") and params["password"] == "12345678":
  
  proc timeout_session(id: string) {.async.} =
echo "expired session:", id
  
  var session = sessions.set_session()
  session.map["username"] = params["username"]
  session.map["password"] = params["password"]
  session.callback = timeout_session
  
  let headers = newHttpHeaders([("Set-Cookie", 
&"session={session.id}")])
  await req.respond(Http200, &"""Hello User 
{session.map["username"]}""", headers)

else:
  await req.respond(Http200, login())
  
  else:
var id = ""
if req.headers.hasKey("Cookie"):
  let cookies = parseCookies(req.headers["Cookie"])
  if cookies.hasKey("session"):
id = cookies["session"]

if id != "" and sessions.pool.hasKey(id):
  var session = sessions.get_session(id)
  await req.respond(Http200, &"""Hello User {session.map["username"]} 
Again :-)""")
else:
  await req.respond(Http200, login())


proc main() =
  let server = newAsyncHttpServer()
  let sessions = newAsyncHttpSessions(
sleep_time=1000,
session_timeout=30
  )
  
  waitFor server.serve(
Port(8080),
proc (req: Request): Future[void] = cb(req, sessions)
  )

main()


Run


Re: Compilation failure 1.0.4 on Pi3

2020-01-12 Thread blippy
I downloaded the latest nightly build 
[https://github.com/nim-lang/nightlies/releases/download/2020-01-11-devel-767592a/nim-1.1.1-linux_armv6.tar.xz](https://github.com/nim-lang/nightlies/releases/download/2020-01-11-devel-767592a/nim-1.1.1-linux_armv6.tar.xz)
 which worked OK. So maybe things will work out better in the next release.

Just something in the way of a feature request: I tried to cross-compile some 
code for ARM, like so:


nim c --cpu=arm proc.nim


Run

and it was trying to use the gnueabifh compiler. Cross-compiling is a bit of a 
mystery to me, but I think gnueabifh assumes an architecture that is 
incompatible with armv6 (?). So it would be nice if I could do something like


nim c --cpu=armv6 proc.nim


Run

Or maybe you already have some flags that I can set that actually does this?


Re: Compilation failure 1.0.4 on Pi3

2020-01-12 Thread Yardanico
Well, "internal compiler error: Segmentation fault" is not Nim's problem, it's 
your C compiler's problem (crash) I'd suggest updating GCC to a newer version 


Re: How to create and manage a http users sessions?

2020-01-12 Thread enthus1ast
well, as i've already written, i would not use globals to store sessions. I 
would create a session object that holds all your data and pass it to every 
procedure.

so feed the session table into your http callback:


import asynchttpserver, asyncdispatch, tables


type
  Session = ref object
## your stuff
  Sessions = Table[string, Session]


proc cb(req: Request, sessions: Sessions) {.async.} =
  ## do stuff
  echo sessions.len

proc main() =
  let server = newAsyncHttpServer()
  var sessions: Table[string, Session]
  # ...
  waitFor server.serve(
Port(8080),
proc (req: Request): Future[void] = cb(req, sessions)
  )

main()


Run


Compilation failure 1.0.4 on Pi3

2020-01-12 Thread blippy
I downloaded the sources for 1.0.4 and tried to compile them on my Raspberry Pi 
3, which uses armv7l architecture). The first stage worked, but when I typed 
./koch tools, it eventually aborted with the message:


CC: ../compiler/ast.nim
Error: execution of an external compiler program 'gcc -c  -w -pthread -O3 
-fno-strict-aliasing  -I/home/pi/Downloads/nim-1.0.4/lib 
-I/home/pi/Downloads/nim-1.0.4/nimsuggest -o 
/home/pi/.cache/nim/nimsuggest_r/@m..@scompi...@sint128.nim.c.o 
/home/pi/.cache/nim/nimsuggest_r/@m..@scompi...@sint128.nim.c' failed with exit 
code: 1

during RTL pass: cse_local
/home/pi/.cache/nim/nimsuggest_r/@m..@scompi...@sint128.nim.c: In function 
'divMod__hJyv3l2B2Q9cPG2G6osz9cmA':
/home/pi/.cache/nim/nimsuggest_r/@m..@scompi...@sint128.nim.c:1030:1: 
internal compiler error: Segmentation fault
 }
 ^
0x76af411f ???
../sysdeps/unix/sysv/linux/arm/sigrestorer.S:64
0x76ade717 __libc_start_main
/build/glibc-FUvrFr/glibc-2.28/csu/libc-start.c:308
Please submit a full bug report,


Run


Re: grim - graph structures in Nim

2020-01-12 Thread c0ntribut0r
Thanks Erik for this lib. I'm curious why you store node attributes in 
heterogenous table. In compiled language i expect graph to be a generic with 
custom Node and Edge types known at compile time, smth like 


var g = newGraph[MyNodeType, MyEdgeType]()


Run


Compile-time string obfuscation

2020-01-12 Thread Yardanico
If someone's still interested in this, updated code for latest Nim: 


import macros

proc `xor` *(x, y: char): char {.magic: "BitxorI", noSideEffect.}

proc fnv32a*[T: 
string|openArray[char]|openArray[uint8]|openArray[int8]](data: T): int32 =
  result = -18652613'i32
  for b in items(data):
result = result xor int32(ord(b))
result = result *% 16777619

proc decodeStr*(s: string, key: int32): string =
  var k = key
  result = newString(s.len)
  for i in s.low .. s.high:
result[i] = s[i]
result[i] = result[i] xor chr(uint8(k and 0xFF))
result[i] = result[i] xor chr(uint8((k shr 8) and 0xFF))
result[i] = result[i] xor chr(uint8((k shr 16) and 0xFF))
result[i] = result[i] xor chr(uint8((k shr 24) and 0xFF))
k = k +% 1

proc encodeStr*(s: string, key: int32): string = decodeStr(s, key)

var encodedCounter {.compiletime.}: int32 = fnv32a(CompileTime & 
CompileDate) and 0x7FFF

macro xs*(s: untyped): untyped =
  var encodedStr = encodeStr($s, encodedCounter)
  result = quote do:
decodeStr(`encodedStr`, `encodedCounter`)
  encodedCounter = (encodedCounter *% 16777619) and 0x7FFF


when isMainModule:
  echo xs("invisible")
  echo xs("strings")


Run


Re: How to create and manage a http users sessions?

2020-01-12 Thread Yardanico
Well, you can just ignore these warnings, they tell you that your code wouldn't 
compile if you were to use threads


Re: How to create and manage a http users sessions?

2020-01-12 Thread mrhdias
I made some changes that corrected several warnings now it works as expected 
with cookies. But it still shows warnings like these: 


Warning: Cannot prove that 'n' is initialized. This will become a compile 
time error in the future. [ProveInit]
Warning: 'set_session' is not GC-safe as it accesses 'sessions' which is a 
global using GC'ed memory [GcUnsafe2]
Warning: 'get_session' is not GC-safe as it accesses 'sessions' which is a 
global using GC'ed memory [GcUnsafe2]


Run

Can someone help me fix these warnings? 


import asynchttpserver, asyncdispatch
import tables
import times
import oids
import cookies
import strformat
import strtabs

type
  Session = object
id: string
map: TableRef[string, string]
request_time: DateTime
callback: proc (id: string): Future[void] {.gcsafe.}

var sessions: Table[string, Session]

const sessionTimeout = 30

proc sessions_manager(session_timeout: int = 3600): Future[void] {.async.} =
  while true:
await sleepAsync(1000)

echo "Number of sessions: ", sessions.len
echo "check for sessions timeout..."

var to_del = newSeq[string]()
for key, value in sessions:
  if (now() - sessions[key].request_time).inSeconds > session_timeout:
echo "session id timeout:", key
to_del.add(key)

for key in to_del:
  if sessions[key].callback != nil:
await sessions[key].callback(key)
  echo "the session will be deleted:", key
  sessions.del(key)

proc set_session(): Session {.gcsafe.} =
  let session_id = genOid()
  
  return (sessions[$session_id] = Session(
id: $session_id,
map: newTable[string, string](),
request_time: now(),
callback: nil
  ); sessions[$session_id])

proc get_session(id: string): Session = (sessions[id].request_time = now(); 
sessions[id])

proc cb(req: Request) {.async,gcsafe.} =
  
  proc timeout_session(id: string) {.async.} =
echo "expired session:", id
  
  var id = ""
  if req.headers.hasKey("Cookie"):
let cookies = parseCookies(req.headers["Cookie"])
if cookies.hasKey("session"):
  id = cookies["session"]
  
  var session: Session
  if id != "" and sessions.hasKey(id):
session = get_session(id)
  else:
session = set_session()
session.map["login"] = "test"
session.map["password"] = "123456789"
session.callback = timeout_session
  
  
  let headers = newHttpHeaders([("Set-Cookie", &"session={session.id}")])
  await req.respond(Http200, "Hello World", headers)


proc main() =
  let server = newAsyncHttpServer()
  
  asyncCheck sessions_manager(sessionTimeout)
  
  waitFor server.serve(Port(8080), cb)

main()


Run

Code compilation messages 


$ nim c test.nim
...
/home/hdias/Downloads/StatorHTTPServer/test.nim(49, 19) template/generic 
instantiation of `[]=` from here
/usr/local/programs/x86_64/nim-1.0.4/lib/pure/collections/tableimpl.nim(49, 
12) template/generic instantiation of `enlarge` from here
/usr/local/programs/x86_64/nim-1.0.4/lib/pure/collections/tables.nim(270, 
10) Warning: Cannot prove that 'n' is initialized. This will become a compile 
time error in the future. [ProveInit]
/home/hdias/Downloads/StatorHTTPServer/test.nim(46, 6) Warning: 
'set_session' is not GC-safe as it accesses 'sessions' which is a global using 
GC'ed memory [GcUnsafe2]
/home/hdias/Downloads/StatorHTTPServer/test.nim(58, 25) template/generic 
instantiation of `async` from here
/home/hdias/Downloads/StatorHTTPServer/test.nim(56, 6) Warning: 
'get_session' is not GC-safe as it accesses 'sessions' which is a global using 
GC'ed memory [GcUnsafe2]
/home/hdias/Downloads/StatorHTTPServer/test.nim(58, 25) template/generic 
instantiation of `async` from here
/usr/local/programs/x86_64/nim-1.0.4/lib/pure/asyncmacro.nim(272, 31) 
Warning: 'cbIter' is not GC-safe as it calls 'get_session' [GcUnsafe2]
Hint:  [Link]
Hint: operation successful (66967 lines compiled; 0.960 sec total; 
89.562MiB peakmem; Debug Build) [SuccessX]


Run


Re: Check if a procedure exists for a given type at compile time

2020-01-12 Thread ducdetronquito
Wow, I didn't think about cyclic imports at first !

I ended up with the approach you mentioned: using a proc type field with a 
default value that can be overriden by the end user with a setter.

Finally, messing around with type introspection would have been more 
complicated to understand compared to this simple solution.


.
   # Define in the library
type
Callback = proc (self: Car)
Car = ref object
speed: int
drive_callback*: Callback
 
 
 proc new*(car_type: type[Car]) Car =
  return Car (drive_callback: default_drive)
 
 
 proc default_drive(self: Car):
  echo "vroom"

proc set_drive_callback*(self: Car, callback: Callback) =
self.drive_callback = callback
   
   
   # Define by the user
var car = Car()
car.set_drive_callback(
 proc (self: Car) =
 echo "VROOM !!"
)



Run

PS: Thanks @dawkot for the hint, I might use it for another thing !


grim - graph structures in Nim

2020-01-12 Thread ebran
Hi all,

My first post to this forum. I found out about Nim a month or so ago and have 
been playing around since. It's been a very pleasant experience, with Nim's 
clean syntax (especially coming recently from Python) and friendly learning 
curve.

A big shout-out to the developers and the Nim community, you are doing a great 
job and if you keep going more great things will lie ahead.

I'll also take the opportunity to share my first Nim project - 
[grim](https://github.com/ebran/grim). It brings graph data structures to Nim, 
similar to the Neo4j-style database. Probably there are similar libraries 
already available, this is my attempt to learn Nim. I'll happily discuss 
improvements and or PRs. In the future, if I have time, I hope to add graph 
searching tools and other cool graph algorithms + Neo4j integration.

Best,


Re: Check if a procedure exists for a given type at compile time

2020-01-12 Thread mashingan
Same case 
[https://forum.nim-lang.org/t/5792#35941](https://forum.nim-lang.org/t/5792#35941)


Re: Check if a procedure exists for a given type at compile time

2020-01-12 Thread dawkot

var car: Car
when compiles (drive car):
  ..
else:
  ..


Run

When is a compile-time version of if


Re: Check if a procedure exists for a given type at compile time

2020-01-12 Thread Stefan_Salewski
A basic test is generally "when compiles()".

But I think your case can not really work: The user of your lib would import 
your lib, and on the other hand your lib would import drive() proc from user 
module. So you have cyclic imports.

Maybe your lib can define and export a proc var of type drive(), which is nil 
by default and user can assign his own proc to it?


Check if a procedure exists for a given type at compile time

2020-01-12 Thread ducdetronquito
Hello everyone,

I would like to know if Nim allows me to check if a procedure exists for a 
given type at compile time ?


.
# As a library author I define a type `Car`
type
Car = object
speed: int
 
 proc default_drive(self: Car):
  echo "vroom"
 
 
 # A user of this library define a procedure `drive` on this `Car` type
 proc drive(self: Car):
 echo "VROOM !!"

var car = Car()

# Somewhere in my library, I want to check if the procedure `drive` 
exists on type `Car`
# NB: The code below is pseudo code
if prodecure_exists(Car, "drive"):
car.drive()
else:
car.default_drive()


Run

Have a nice day :)