Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread Krux02
@moigagoo Just be prepared, there might be some cases wher it is not that great 
after all.

@LeuGim Basically what you are saying was what I meant with "Strangely, on my 
computer it did work. The compiler did not complain that value was not 
declared, but you were missing a len call to the parameter". But maybe it did 
need different words to be understood.


Re: NimYAML 0.7.0 released

2016-11-08 Thread flyx
NimYAML 0.8.0 is now available. Its focus was on making it more capable of 
being used for configuration files:

  * You can now set default values of object fields with `setDefaultValue`.
  * You can now mark object fields as transient with `markAsTransient` so that 
they are not serialized or expected in YAML input.
  * You can now ignore input keys with `ignoreInputKey`. This makes it easier 
to parse YAML input that contains data which is not of interest.



Moreover, timestamps can now be parsed into `Time` values. However, this is 
only usable with most recent Nim devel version, since timezones are broken in 
0.15.2. 


Re: netwatch 1.0.0 - network monitor written in nim

2016-11-08 Thread JohnS
@federico3: Trying to! :) I'm doing Linux first and unfortunately it's only 
when I get some free time. Help & PRs are welcome!

The idea (from @endragor) is to rip out most of the low-level interface/network 
stuff that's in netwatch and use a psutil library instead.

As an aside, Nim makes it _really_ nice to port the psutil Python code. The 
original library has shared Python code that calls platform-specific Python 
code that _then_ calls platform-specific C code. Nim doesn't need any of that 
extra C layer! I'm curious to see the LOC comparison after it's done. Not sure 
I'll get there thought b/c the author moves fast ;)


Re: netwatch 1.0.0 - network monitor written in nim

2016-11-08 Thread federico3
@JohnS: are you developing this? 
[https://github.com/johnscillieri/psutil-nim](https://github.com/johnscillieri/psutil-nim)


Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread moigagoo
@LeuGim Wow! Well, this is just amazing, thanks a lot for the tip!

This is another case of Nim being awesome. I literally wrote the first sample 
as a throw-away-this-just-cannot-work-this-easily piece, and here it is, 
working perfectly well with just a pair of back ticks added.


Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread LeuGim
> it's more readable than using `setterProc.params[2][0]`

You don't have to use `setterProc.params[2][0]` with your first approach (with 
`quote do`). Just `value` works - identifier will be resolved in the procedure 
being transformed, not in macro. Oppositely, to use the macro's symbol, you 
have to quote it with backticks. So what you had to change in your first 
example is to add backticks around `limit` (like in _Krux02_'s example), using 
`value` as is (just with `.len` appended).


Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread moigagoo
@Krux02 Thanks for the hint! I've already gone with the solution advised by 
@Araq though:


import macros

type
  ValidationError* = object of Exception

template validateLength(limit: Natural) {.dirty.} =
  if len(value) > limit:
raise newException(ValidationError, "The value is too long.")

macro maxLength*(limit: Natural, setterProc: untyped): untyped =
  setterProc.body.insert(0, getAst(validateLength(limit)))
  result = setterProc


I think it's more readable than using `setterProc.params[2][0]`, because these 
indices don't really tell anything to the code reader. So it may be a good 
thing I couldn't make it work the `quote` way :)

Still, I wonder if using dirty templates in conjunction with `getAst` is the 
easiest way to emulate decorator behavior. I have a sense there must be a 
better way (not that this way is bad).


Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread Krux02
Strangely, on my computer it did work. The compiler did not complain that value 
was not declared, but you were missing a `len` call to the parameter. By the 
way, you can also extract the exact identifier that is used in the setter, and 
therefore make shure that it is defined.


macro maxLength*(limit: Natural, setterProc: untyped): untyped =
  let paramIdent = setterProc.params[2][0]
  let lengthValidation = quote do:# This is the part I 
can't figure out.
if len(`paramIdent`) > `limit`:   # Obviously, this 
doesn't work since: value is undeclared,
  raise newException(RangeError, "Too long")  # and even if I 
extract the variable from ``setterProc``, its value is unknown
  
  setterProc.body.insert(0, lengthValidation)
  
  result = setterProc



Re: Fun with deduplicate

2016-11-08 Thread Stefan_Salewski
There is currently another point that confuses me:

I tested with an initial array increased in size by factor 10:


var x: array[1, int]

Compiled with -d:release and default -O3 for gcc gcc takes 28 seconds to 
generate the binary and binary size is 650k. And with -Os or -O2 results are 
similar. Well 10k ints global should result in 80k BSS section when int size is 
8 byte. But what may go on? This is for gcc 5.4

@Krux: I have to think about your comment some more still. But sorting may be 
indeed a problem I guess, when array elements are objects, we have to provide a 
cmp() proc to sort, and that cmp() proc has to compare all the fields of the 
object, and is called often. So that should be not very fast.

And of course deduplicate operation should prevent the order in the seq and 
keep always the first candidate. 


Re: Fun with deduplicate

2016-11-08 Thread Krux02
As far as I know, there are three ways to deduplicate the elements of a list, 
and all of them can be implemented by modifying the argument or returning a new 
seq. You introduced the method that uses the set, but your implementation 
destroys the order of elements in a seq, I think that is not necessary. The 
third alternative is, to sort the collection, and then deduplicate _O(n log 
n)_. This is clearly faster than _O(n²)_, but destroys definitively the order. 
The advantage compared to the hashing implementation is, that it can be 
implemented without any allocation. 


Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread LeuGim
`{.dirty.}` \- makes a template not to create a new scope, what is declared in 
it is created in the calling site.


Fun with deduplicate

2016-11-08 Thread Stefan_Salewski
I wonder if sequtils.deduplicate() should be renamed to deduplicated() as it 
returns a seq like sorted()? And maybe it should be noted that it is O(n^2), 
which is fine for small collections, but not so nice for large ones.

And maybe we should add a O(n) deduplicate to stdlib -- sets modul is really 
fast as shown below.


import sets
import random, times
import sequtils # deduplicate

# O(n)
proc uniqCopy[T](s: openArray[T]): seq[T] =
  let h = s.toOrderedSet
  newSeq(result, h.len) # can we avoid the unnecessary initialization?
  var i = 0 # is there no items with index for sets?
  for el in h:
result[i] = el
inc(i)

# O(n)
proc uniq[T](s: var seq[T]) =
  let h = s.toOrderedSet
  var i = 0
  for el in h:
s[i] = el
inc(i)
  s.setLen(h.len)

# O(n^2)
proc xdeduplicate[T](s: var seq[T]) =
  var i, j: int
  while i < s.len:
s[j] = s[i]
var k = j
while k > 0:
  dec k
  if s[k] == s[j]:
dec(j)
break
inc(j)
inc(i)
  s.setlen(j)

var a = @[1, 3, 1, 2, 2, 5, 2]
var b = a
echo a.uniqCopy
a.xdeduplicate
b.uniq
echo a
echo b

var t: float # cpuTime()
var x: array[1000, int]
for el in mitems(x): el = random(1000)

var z = @x
t = cpuTime()
z = z.deduplicate
echo "sequtils.dedublicate: ", cpuTime() - t

z = @x
t = cpuTime()
z.xdeduplicate
echo "inplace dedublicate: ", cpuTime() - t

z = @x
t = cpuTime()
z = z.uniqCopy
echo "uniqCopy: ", cpuTime() - t

z = @x
t = cpuTime()
z.uniq
echo "uniq: ", cpuTime() - t

# nim c -d:release t.nim
# Output
# @[1, 3, 2, 5]
# @[1, 3, 2, 5]
# @[1, 3, 2, 5]
# sequtils.dedublicate: 0.0001411
# inplace dedublicate: 0.0001329
# uniqCopy: 3.099e-05
# uniq: 2.711e-05



Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread moigagoo
Thanks for the quick response!

> dirty template+getAst (the preferred way to construct ASTs these days).

Could you please point me to sample code where this technique is used? I'm 
pretty bad at using `quote`, but `getAst` is a totally unknown thing to me, and 
the docs don't say much.

Also, what do you mean by using a dirty template? Namely, what makes a template 
dirty?


Re: Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread Araq
Your solution is just fine once you replace `quote do:` by a dirty 
template+getAst (the preferred way to construct ASTs these days). 


Re: WINAPI Select Folder

2016-11-08 Thread Araq
`nimble install dialogs`


import dialogs

let dir = chooseDir(nil, r"C:\start\here")
echo dir, " has been picked"



Access procedure arguments from a macro when the procedure is called

2016-11-08 Thread moigagoo
Hi!

I need a way to validate the value during attribute assignment for an object. 
Using macros as pragmas sounds like a good idea, and the syntax would be sane 
and clear:


{.this: self.}

type
  Person* = ref object of RootObj
name: string

proc name*(self: Person): string = name

proc `name=`*(self: var Person, value: string) {.maxLength: 100.} =
  name = value

proc newPerson*(name: string, age: int = 0): Person =
  new result
  result.name = name


The `maxLength` macro would look something like this:


macro maxLength*(limit: Natural, setterProc: untyped): untyped =
  let lengthValidation = quote do:# This is the part I 
can't figure out.
if value > limit: # Obviously, this 
doesn't work since: value is undeclared,
  raise newException(ValidationError, "Too long") # and even if I 
extract the variable from ``setterProc``, its value is unknown
  
  setterProc.body.insert(0, lengthValidation)
  
  result = setterProc


I can't figure out how to extract the runtime value of the `value` argument.

Maybe my approach is totally wrong. If you have a better suggestion, please 
advise—I'm a novice and am very keen to learn from pros.

I come from the Python background, so I'm viewing macro in this example sort of 
like a decorator. I know they're very much different, but I don't know a better 
alternative to decorators or can't find a better programming pattern for the 
task. Again, any advice is appreciated.


WINAPI Select Folder

2016-11-08 Thread geezer9
This question is relative to the ms windows api.

Found SHBrowseForFolder function in the oldwinapi module to build a dialog to 
select a folder. Needed that since GetOpenFileName only selects files. That 
works, but requires selection to always begin at the very topmost master root.

To specify the selection root in SHBrowseForFolder requires an ITEMIDLIST for 
that root. This seems to be some kind of generalized internal filesystem path.

How do I convert an ordinary file path string (e.g. C:\Moo\Gai\Folly) into such 
an ITEMIDLIST?

The function ParseDisplayName might do that, but I cannot find it in the 
oldwinapi module?

Or is there some old-style winapi for a gui to select a folder??

Thanks