Is there any way to look something up in a Table using a pre-computed Hash value?

2019-11-18 Thread drkameleon
OK, so basically let's say we have a Table and we're either trying to retrieve 
a value using a specific key, or trying to see if our Table contains a specific 
key.

The normal way I guess would be with a call to hasKey.

Now, what if we're - possibly - going to perform the same lookup many times? 
Wouldn't it be more practical instead of doing Table.hasKey(someKey) and having 
the hash value of someKey calculated over and over again, to be able to do a 
lookup by Hash value? (provided I've already calculated it and stored it 
somewhere)

Is it even possible? (I've been looking in the sources and specifically into 
rawGetImpl() from lib/pure/collections/hashcommon.nim, but still not sure how 
it would be possible to circumvent this


Re: Force mutable Seq returns

2019-11-18 Thread drkameleon
What would you think of using... ?:


type
SeqRef[T] = ref seq[T]

proc newSeq[T](s:seq[T]): SeqRef[T] =
new(result)
result[] = s


Run


Re: Karax Components

2019-11-18 Thread moigagoo
Thanks for the sample!

Do you use this xName naming convention to make procs look more like types? 
Makes sense, just clarifying.

Also, how would you handle state in your app model?


Re: NaN tagging in Nim?

2019-11-18 Thread cumulonimbus
You could have tables-of-refs-to-objects, e.g. allInts:@seq[int], 
allFloat:@seq[float], and NaN tag the indices to those lists; it would require 
one more redirection to actually get the value, but would otherwise work well 
with any gc.

Also, subnormals (neƩ denormals) are also useful for tagging. And unlike NaNs 
which could be a result of a computation (e.g. 0.0/0.0) which you must 
differentiate from your tagged values, if you set the FPU "flush to zero" mode, 
they will not be generated as a result of a computation; see e.g. 
[https://stackoverflow.com/questions/54531425/is-it-possible-in-floating-point-to-return-0-0-subtracting-two-different-values/54532647#54532647](https://stackoverflow.com/questions/54531425/is-it-possible-in-floating-point-to-return-0-0-subtracting-two-different-values/54532647#54532647)


Re: Confused about how to use ``inputStream`` with ``osproc.startProcess``

2019-11-18 Thread pmags
Thank you, Vindaar. That's very helpful!


Re: Karax Components

2019-11-18 Thread kidandcat
You can use components with local state, but I haven't experimented with them, 
I'm more than fine with functions and variables, each in their own file: 
[https://github.com/kidandcat/nimforum2](https://github.com/kidandcat/nimforum2)


Re: Differences between simple assignment, shallowCopy and deepCopy

2019-11-18 Thread cdunn2001
deepCopy has value independent of memory management. I don't use it much, if 
it's not a problem I'd vote for it to remain.


Re: Force mutable Seq returns

2019-11-18 Thread mratsim
Pass the sequence to `shallow()` before processing or create a custom object


type MyShallowSeq[T] {.shallow.} = object
  buffer: seq[T]


Run

Your solution will create 2 pointer indirections, it's idiomatic but slower.


Karax Components

2019-11-18 Thread moigagoo
I've tried exploring component-based architecture in Karax once: 
[https://moigagoo.svbtle.com/exploring-karax](https://moigagoo.svbtle.com/exploring-karax)

However, I now see there is VCompoment type in Karax and there are 
examples/tests that demonstrate its usage.

Is this the official way to have components in Karax now? Is there any project 
I could look at built with these components?

There's so little information available in Karax repo, the docs don't exist, 
and there's no sample project. It's a shame, Karax deserves better.


Re: How to avoid recursive module dependency ?

2019-11-18 Thread treeform
I second dom96, recursive module dependency is a sign of bad code organization.

Avoid it.


Re: Web pages with data entry in unicode and unidecode

2019-11-18 Thread treeform
Looks cool!


Re: Force mutable Seq returns

2019-11-18 Thread drkameleon
I was thinking of packaging the seq in a ref object, and then move those ref 
objects around. but wouldn't that be an overkill?


Re: Force mutable Seq returns

2019-11-18 Thread drkameleon
But this makes a copy of the sequence, doesn't it?

Is there any way to do the same thing, using the reference? (after all, it's a 
pointer, if I'm not mistaken... all I want to do is change the value/sequence 
to which that pointer is pointing)


Force mutable Seq returns

2019-11-18 Thread drkameleon
I have a template like this:


template ARR(v:Val):seq[Val] =
cast[seq[Val]](bitand(v,bitnot(UNMASK)))


Run

however, I want to be able to change the result like :


a = ARR(x)
a[0] = 


Run

How can I return a var seq[Val] (or sth like that) ?


Re: Force mutable Seq returns

2019-11-18 Thread mratsim
`var a: seq[Val] a = ARR(x) a[0] =  `

Run


Re: How to avoid recursive module dependency ?

2019-11-18 Thread mratsim
Second that, `include` will effectively duplicate your type declarations and 
will probably cause your code to get ambiguous symbol warnings.


Re: How to avoid recursive module dependency ?

2019-11-18 Thread dom96
I would strongly recommend avoiding `include` as much as possible, and in 
particular in this case.

What works usually is to create a module for your types, or to think about how 
you structure your program, usually you will see that you aren't organising 
your code in the best way.


Re: Confused about how to use ``inputStream`` with ``osproc.startProcess``

2019-11-18 Thread Vindaar
Sorry, I didn't see the post before.

You're almost there. There's two small things missing in your code.

  1. you should add a newline to the string you write to the input stream. cat 
wants that newline
  2. instead of closing the input stream, you flush it.



Note however that with cat at least the output stream will never be "done". So 
you need some stopping criteria.


import osproc, streams

proc cat(strs: seq[string]): string =
  var command = "cat"
  var p = startProcess(command, options = {poUsePath})
  var inp = inputStream(p)
  var outp = outputStream(p)
  
  for str in strs:
# append a new line!
inp.write(str & "\n")
  
  # make sure to flush the stream!
  inp.flush()
  var line = ""
  var happy = 0
  while p.running:
if happy == strs.len:
  # with `cat` there will always theoretically be data coming from the 
stream, so
  # we have some artificial stopping criterium (maybe just Ctrl-C)
  break
elif outp.readLine(line):
  result.add(line & "\n")
inc happy
  close(p)

echo cat(@["hello", "world"])


Run


Re: Confused about how to use ``inputStream`` with ``osproc.startProcess``

2019-11-18 Thread pmags
Still hoping someone can offer some insight on the use of inputStream. Is the 
documentation simply wrong on this point?


Re: Jester memory usage keep rising using sqlite

2019-11-18 Thread treeform
In c it depends which allocator you use. Most people don't use the default 
malloc because it's slow. They have a layer above it which uses it for big 
chunks while using internal thing for small chunks.

For really big chunks Nim will use the standard is malloc and they will free 
back. This does not happen in web servers.


Re: Jester memory usage keep rising using sqlite

2019-11-18 Thread leorize
No, the memory will be released to the OS.


Re: Jester memory usage keep rising using sqlite

2019-11-18 Thread leorize
The GC does release memory under certain 
[circumstances](https://github.com/nim-lang/Nim/blob/b07694cd90ab7c6eb4660971ddb818b461d4eed8/lib/system/alloc.nim#L861).
 The code is rather hard to follow though, and I'm not sure _when_ exactly 
would the GC release memory back to OS. But if you allocate a 2GB string then 
discard it, the GC will later collect that memory and release it to the OS 
(this can be forced via a call to `GC_fullCollect`).


Re: Jester memory usage keep rising using sqlite

2019-11-18 Thread mindplay
Is this true with manual memory management as well, or just the built-in memory 
management and GC?

Like, if you were to, say, manually allocate space to load and copy/resize a 20 
megapixel photo, will the app continue to occupy 200 MB of RAM even after the 
memory is released by the app? 


Re: Binary resulting much larger with --opt:size?

2019-11-18 Thread mratsim
\--opt:speed implies -O3|   
---|---  
\--opt:size implies -Os|   
  
passing -O4 will impli -O3

It's either -O3 or -Os, you can't have both at the same time hence the conflict.

Now it seems like there might still be an issue but without reproducible 
example it's hard to investigate. You can check with bloaty 
([https://github.com/google/bloaty](https://github.com/google/bloaty)) to have 
an idea if it's just text symbols that are taking space or if it's actual code 
for example.


Re: Binary resulting much larger with --opt:size?

2019-11-18 Thread drkameleon
I don't think they are interfering. The -O4 option is only set for speed and 
I'm getting the exact same result (900+KB vs 600+KB) even after completely 
removing it.


Re: NaN tagging in Nim?

2019-11-18 Thread drkameleon
Hmm... I see your point. But then how would I be able to store an object's 
address? (perhaps, the solution would be to use no GC whatsoever which is 
pretty much what I'm doing?)

Btw... here is an experimental implementation of NaN-tagging I've just written 
(roughly based on this article: 
[https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-representations.html)](https://nikic.github.io/2012/02/02/Pointer-magic-for-efficient-dynamic-value-representations.html\)).
 I believe it's working though I haven't had time to thoroughly test it.

**Code:**


import bitops

type
ObjType = enum
strObj, arrObj

Obj = ref object
case kind: ObjType:
of strObj: s: string
of arrObj: a: seq[Obj]

Val {.final,union,pure.} = object
asDouble: float64
asBits: int64

const MaxDouble = cast[int64](0xfff8)
const Int32Tag  = cast[int64](0xfff9)
const PtrTag= cast[int64](0xfffa)

proc newVal(num:int64): Val {.inline.} =
Val(asBits: bitor(num,Int32Tag))

proc newVal(num: float64): Val {.inline.} =
Val(asDouble:num)

proc newVal(obj: Obj): Val {.inline.} =
Val(asBits: bitor(cast[int64](obj),PtrTag))

proc isDouble(v: Val): bool {.inline.} =
v.asBits < MaxDouble

proc isInt32(v: Val): bool {.inline.} =
bitand(v.asBits,Int32Tag) == Int32Tag

proc isObj(v: Val): bool {.inline.} =
bitand(v.asBits,PtrTag) == PtrTag

proc getDouble(v: Val): float64 {.inline.} =
v.asDouble

proc getInt32(v: Val): int32 {.inline.} =
cast[int32](bitand(v.asBits,bitnot(Int32Tag)))

proc getObj(v: Val): Obj {.inline.} =
result = cast[Obj](bitand(v.asBits,bitNot(PtrTag)))

let a = newVal(32)
echo a.getInt32()

let b = newVal(34.53)
echo b.getDouble()

let c = newVal(Obj(kind:strObj, s:"hello"))
echo c.getObj().s


Run

**Output:**


32
34.53
hello


Run


Re: Binary resulting much larger with --opt:size?

2019-11-18 Thread mratsim
`-O4` will conflict with building for size `-Os`


Re: NaN tagging in Nim?

2019-11-18 Thread mratsim
Don't cast ref objects unless the underlying representation is compatible 
(seq[byte] and strings).

Definitely don't cast ref objects to int. How would the garbage collector 
collect that?


Re: NaN tagging in Nim?

2019-11-18 Thread drkameleon
Do you see anything wrong (particularly memory-safety-wise) with this code?


let v = Value(kind: stringValue, s: "hello")
let z = cast[int](v)

echo repr(cast[Value](z))
echo cast[Value](z).stringify()


Run


Re: NaN tagging in Nim?

2019-11-18 Thread Araq
I've yet to see such code for Nim, but Nim's `cast` is well prepared for it.


Re: Binary resulting much larger with --opt:size?

2019-11-18 Thread Araq
The only difference is the `-d:mini` flag, you don't use `--opt:size`.


Re: Differences between simple assignment, shallowCopy and deepCopy

2019-11-18 Thread Araq
In additon to what @mratsim said both `shallowCopy` and `deepCopy` will likely 
be deprecated. `shallowCopy(x, y)` should have been `x = move(y)` and 
`deepCopy` should be something like `send` (send data to a different thread).