rerunning CI works for github actions, sr.ht, but not azure pipelines

2020-05-13 Thread timothee
I'd like to be able to re-run CI just for what needs to be re-run without 
having to re-run everything to save CI cycles.

this works fine for sr.ht (if you have an account), and for github actions 
(when it fails, IIRC you can rerun at least if project member), but somehow not 
for azure pipelines. Anything can be done?

(related: 
[https://github.com/nim-lang/Nim/pull/13556](https://github.com/nim-lang/Nim/pull/13556)
 which would enable [nimDocOnly] in commit msg ; but needs to be updated to 
reflect how CI is split amongst github actions and azure)


Re: How to instantiate `ptr object`

2020-05-13 Thread dataPulverizer
One of the things that intrigued me about Nim was it's object system, you could 
create value, reference and pointer types with/without inheritance. As I 
understand it, an important distinction between ptr and ref classes is that ref 
classes are managed by the garbage collector while ptr classes have to be 
manually allocated and deallocated.

In this case for me that _is_ the distinction between both of them, I see 
inheritance from a ptr class as the same as inheritance from a ref class and 
polymorphism in the same way:


type:
  Animal = ptr object of RootObj
  Cat = ptr object of Animal

var x: Animal = create(Cat)


Run

But I also want to be able to dispatch against Cat (x) at runtime, so send it 
as a parameter in a function marked with Animal but within that function call 
the cat method and allow the right method to be dispatched. In exactly the same 
way as in my kernel function:


proc calculateKernelMatrix*(K: AbstractKernel, data: Matrix[F]): Matrix[F] =
  let n = int64(ncol(data));
  var mat = Matrix[F](data: newSeq[F](n*n), dim: @[n, n]);
  for j in 0..

Re: Idea why this does not compile?

2020-05-13 Thread Stefan_Salewski
> need to define your destructor earlier

Yes, my initial guess was indeed that, as it was done in that way in the 
earlier gintro code.

But I became unsure if it would work really fine also that way.

And it remains strange, as my fnew template should fully hide the use of the 
finalizer when we compile with --gc:arc. So I assume that both branches of the 
when construct are processed by the compiler and that confuses the compiler? In 
the same way as discarded code is always syntax checked?

Unfortunately ordering the code is not that easy, as it is autogenerated from 
the gobject-introspection database, and for latest gtk 3.98.3 which will become 
4.0 there are some serious changes. I can not just put the =destroy just after 
the type declaration, as =destroy calls low level procs like 
gdk_event_unref(self.impl) above. So carefully sorting will be necessary.

Note that forward declarations like below do not compile:


proc gdk_event_unref(self: ptr Event00)

proc gdk_event_unref(self: ptr Event00) {.importc, libprag.}


Run


Error: pragmas are only allowed in the header of a proc; redefinition of 
'gdk_event_unref'


Run

What should work is declaring a special unref function before declaring the 
=destroy and using that one in the =destroy like


proc destroy_gdk_event_unref(self: ptr Event00) {.importc: gdk_event_unref, 
libprag.}


Run


Re: A good word for idiomatic nim?

2020-05-13 Thread treeform
nimatic


Re: Sorting JSON data by a specified field

2020-05-13 Thread Hlaaftana
`import json, algorithm let j = parseJson"""[{"id":"5","name":"A"}, 
{"id":"6","name":"C"}, {"id":"3","name":"B"}]""" let x = j.getElems.sorted(proc 
(a, b: JsonNode): int = cmp(a["name"].getStr, b["name"].getStr)) echo x # 
@[{"id": "5", "name": "A"}, {"id": "3", "name": "B"}, {"id": "6", "name": "C"}] 
`

Run


Re: Having problems porting a Python script for computing two cofactors of a number

2020-05-13 Thread pietroppeter
Yes, there is definitely room for improvements. I just wanted to check if using 
bigints with minimal changes would be working. And I am actually surprised it 
does, since I was not able to find a gcd prox overloaded for BigInt (I was 
expecting to have to provide an implementation). Not sure what is being used 
there. Also, I I think in place addition and multiplication are not exported in 
bigints.

Regarding the usage of stint, I would guess the actual Telegram protocol might 
go beyond uint64 and might have a specific size that one can work with.


Re: Idea why this does not compile?

2020-05-13 Thread Araq
I know why it doesn't compile but my reply would be identical to the compiler's 
error message. You need to define your destructor earlier, like so:


when defined(gcDestructors):
  proc `=destroy`*(self: var typeof(Event()[])) =
if not self.ignoreFinalizer and self.impl != nil:
  echo "gdk_event_unref(self.impl)"
  self.impl = nil

template fnew*(a: untyped; finalizer: untyped) =
  when defined(gcDestructors):
new(a)
  else:
new(a, finalizer)

proc `ref`*(self: Event): Event =
  fnew(result, generic_gdk_event_unref)
  echo "result.impl = gdk_event_ref(cast[ptr Event00](self.impl))"

proc generic_gdk_event_unref*[T](self: ref T) =
  if not self.ignoreFinalizer:
echo "gdk_event_unref(self.impl)"



Run


Re: Having problems porting a Python script for computing two cofactors of a number

2020-05-13 Thread mratsim
You need to use in-place addition and multiplication instead of out-of-place 
otherwise you will bottleneck on memory allocation/deallocation during all 
those loops with nim-bigint.

If it fits in an uint64, stint is not needed, but otherwise as it's all stack 
allocated you won't suffer from allocation, the tradeoff is that you cannot 
have an arbitrary size.


Re: How to instantiate `ptr object`

2020-05-13 Thread mratsim
The allure of undocumented behaviors ;)

@dataPulverizer, if you already use pointers you can use generic procs, why do 
you need inheritance for dispatch?


Sorting JSON data by a specified field

2020-05-13 Thread cburkhead
OK, first of all I am very new to Nim. I have JSON data that I am retrieving 
via a REST API and I want to sort it based on a field in that data. The data 
looks something like this:

[{"id":"582090251837636960","name":"Company 
1","url":"[https://website.com/LeauObI/manage/organization/overview"}](https://website.com/LeauObI/manage/organization/overview"}),
 {"id":"60291940011422","name":"Company 
10","url":"[https://website.com/o/2pFpYchb/manage/organization/overview"}](https://website.com/o/2pFpYchb/manage/organization/overview"}),
 {"id":"626000348204499553","name":"Company 
3","url":"[https://website.com/o/2r9-dbWb/manage/organization/overview"}](https://website.com/o/2r9-dbWb/manage/organization/overview"})]

I need to be able to sort this data by the "name" field. I have looked at the 
sort() function, but have not been able to figure out what needs to be done to 
get this data sorted. Has anyone done this or something similar?

Thanks in advance.


Re: How to instantiate `ptr object`

2020-05-13 Thread Araq
> you can't mix inheritance with un-managed raw pointers.

I can do it. In fact, I did in Nim's allocator.


Re: How to instantiate `ptr object`

2020-05-13 Thread Araq
> you can't mix inheritance with un-managed raw pointers.

I can do it. In fact, I did in Nim's allocator.


Idea why this does not compile?

2020-05-13 Thread Stefan_Salewski
I was just working a bit on gintro for latest GTK4 and got a really confusing 
error message.

Luckely I was just able to generate a minimal example, but I have still no real 
idea what the problem may be. I guess there must be something special in this 
code, because I have used similar constructs before and it was working fine...


type
  Event* = ref object of RootRef
impl*: pointer
ignoreFinalizer*: bool

template fnew*(a: untyped; finalizer: untyped) =
  when defined(gcDestructors):
new(a)
  else:
new(a, finalizer)

proc `ref`*(self: Event): Event =
  fnew(result, generic_gdk_event_unref)
  echo "result.impl = gdk_event_ref(cast[ptr Event00](self.impl))"

proc generic_gdk_event_unref*[T](self: ref T) =
  if not self.ignoreFinalizer:
echo "gdk_event_unref(self.impl)"

when defined(gcDestructors):
  proc `=destroy`*(self: var typeof(Event()[])) =
if not self.ignoreFinalizer and self.impl != nil:
  echo "gdk_event_unref(self.impl)"
  self.impl = nil

proc main =
  var x: Event
  fnew(x, generic_gdk_event_unref)

main()


Run


$ nim c --gc:arc t2.nim

/tmp/hhh/t2.nim(21, 3) Error: cannot bind another '=destroy' to: 
Event:ObjectType; previous declaration was constructed here implicitly: 
/tmp/hhh/t2.nim(13, 3)



Run


$ nim -v
Nim Compiler Version 1.3.3 [Linux: amd64]
Compiled at 2020-05-11
Copyright (c) 2006-2020 by Andreas Rumpf

git hash: 7c24250a575b4d441ba6d7301714cbb246425fb6
active boot switches: -d:release


Run


Re: How to instantiate `ptr object`

2020-05-13 Thread dataPulverizer
Isn't the point of inheritance method dispatch? Why isn't that a separate issue 
from objects that are dissociated from the garbage collector?


Re: Having problems porting a Python script for computing two cofactors of a number

2020-05-13 Thread pietroppeter
Hi, out of curiosity I decided to do a naive "port" of the algorithm to use 
[https://github.com/def-/nim-bigints](https://github.com/def-/nim-bigints)

Apart from the fact that doing that I ran into an issue with bigints 
([https://github.com/def-/nim-bigints/issues/27](https://github.com/def-/nim-bigints/issues/27))
 the result 
([https://play.nim-lang.org/#ix=2lU5](https://play.nim-lang.org/#ix=2lU5)) 
works and on my machine compiled with `-d:danger` it takes a bit more than 
500ms.

It might also be interesting to use 
[https://github.com/status-im/nim-stint](https://github.com/status-im/nim-stint)
 instead of bigints.


Re: Game unlock gui written with gintro

2020-05-13 Thread Dankrad
Hey guys,

a few days ago I've released version 0.9.3. In this version I'm using now glade 
and binding signals automatically. The source code and project structure is 
still not clean, because I never inteded to create a unlock gui (so please 
forgive me ;) ). The project will be delivered in the next version with a 
BF2142 mod. I also implemented multilingualism (but currently only in the 
gsparser branch). Please do not have a look into the `terminal.nim` file on the 
master branch, because it is a disaster (on gsparser branch I moved this into 
the main file `BF2142Unlocker.nim` and cleanuped this).

This might be helpfull for some peoples that want to use glade and 
multililingualism on windows and linux.

But be warned that I'm currently developing on the gspaser branch and that this 
currently does not compile on linux (but the master branch does).


Re: How to instantiate `ptr object`

2020-05-13 Thread Stefan_Salewski
> you can't mix inheritance with un-managed raw pointers

That is an interesting point, I was wondering about it this morning already 
when I wrote my first reply.

I am still not sure. I could generally imagine that inheritance can work with 
with un-managed raw pointers. But maybe not in Nim?

@dataPulverizer note that create() may be easier to use, as with create() no 
cast is necessary.

@snej The book is in a very early stage still, I wrote the two chapters in 
April. And it is mostly for people with very less programming experience.


Re: Nim version release notes?

2020-05-13 Thread Yardanico
For all changes in the latest devel (that's the development branch) you can 
read 
[https://github.com/nim-lang/Nim/blob/devel/changelog.md](https://github.com/nim-lang/Nim/blob/devel/changelog.md)


Re: How to instantiate `ptr object`

2020-05-13 Thread mratsim
`ptr object of RootObj` seems very strange, you can't mix inheritance with 
un-managed raw pointers.


Nim version release notes?

2020-05-13 Thread snej
I’ve been using Nim 1.2 so far, because it’s what Homebrew poured me, and 
because I figured it’s best to start with a stable release.

But a lot of devs seem to use 1.3.x ... and I’m curious what new goodies it 
has. But I can’t find release notes or a what’s-new list anywhere. Is there 
such a thing? Or should I try diffing the nightly docs against the 1.2 ones?

Or if someone just wants to reply and talk about their favorite new feature or 
improvement, that’s cool too :)

—Jens


Re: How to parse html wild?

2020-05-13 Thread snej
Browsers have _always_ supported “tag soup” HTML, back to Mosaic and Netscape. 
Unless the content type is XHTML, you cannot expect any sort of valid 
structure. For parsing “wild” HTML, preprocessing through some widely-used 
tidier is probably the best bet, since its interpretation of bad markup is 
hopefully similar to a browser’s.


Re: How to instantiate `ptr object`

2020-05-13 Thread snej
I wasn’t aware of that book, though I’ve been guzzling from the 
Nim-documentation firehose for a week now. You should get it linked from the 
Nim-lang “learning” page!


Re: Terminal based GINTRO(GTK) VTE

2020-05-13 Thread JPLRouge
In the last answer, the git shows how to make a console on the fly, and the 
possibility of executing a program in this console, basically this is what I do 
with termVte (in the example it is frozen but it was for my tests)


Re: Markdown test

2020-05-13 Thread dom96
We can already do italics and bold via * though, so it really isn't so bad. 
What is more annoying is the inability to respond with just a code block, those 
are bugs that need to be fixed.


Re: Markdown test

2020-05-13 Thread kaushalmodi
Thanks, except for those bold/italics, other rendering (especially the Markdown 
link syntax) is nicely supported in the newer nimforum version: 
[https://forum.my-toolbox.xyz/t/6](https://forum.my-toolbox.xyz/t/6)


Re: Is it possible for a macro to know the context it is used?

2020-05-13 Thread Araq
> Instead of having multiple small macros that don't play well together and 
> have only a local context, I'll apply a visitor-like pattern and I can 
> control the scopes in the DSL.

Yes! Now you're cooking.


Re: Markdown test

2020-05-13 Thread Araq
I think more things will work after a redeploy of nimforum. :-)


Markdown test

2020-05-13 Thread kaushalmodi
Testing quote block:

> some quote


echo "hello"


Run

_[Italics](https://forum.nim-lang.org/postActivity.xml#italics)

**Bold**

_ **Bold and italics** _

[Nim website]([https://nim-lang.org](https://nim-lang.org))

## heading level 2

## heading level 3


Re: Having problems porting a Python script for computing two cofactors of a number

2020-05-13 Thread mratsim
>From 
>[https://github.com/mratsim/number-theory/blob/12c54a7476327cf9ab00989c9964732e3eb68be7/src/modular_arithmetic.nim](https://github.com/mratsim/number-theory/blob/12c54a7476327cf9ab00989c9964732e3eb68be7/src/modular_arithmetic.nim)

Modular addition 


proc addmod*[T: SomeInteger](a, b, m: T): T =
  ## Modular addition
  
  let a_m = if a < m: a
else: a mod m
  if b == 0.T:
return a_m
  let b_m = if b < m: b
else: b mod m
  
  # We don't do a + b to avoid overflows
  # But we know that m at least is inferior to biggest T
  
  let b_from_m = m - b_m
  if a_m >= b_from_m:
return a_m - b_from_m
  return m - b_from_m + a_m


Run

Modular multiplication 


proc mulmod*[T: SomeInteger](a, b, m: T): T =
  ## Modular multiplication
  
  var a_m = a mod m
  var b_m = b mod m
  if b_m > a_m:
swap(a_m, b_m)
  while b_m > 0.T:
if b_m.isOdd:
  result = addmod(result, a_m, m)
#a_m = doublemod(a_m, m)
a_m = (a_m shl 1) - (if a_m >= (m - a): m else: 0)
b_m = b_m shr 1


Run

Modular inversion (via GCD, so can return the GCD) 


proc invmod*[T:SomeInteger](a, m: T): T =
  ## Modular multiplication inverse
  ## Input:
  ##   - 2 positive integers a and m
  ## Result:
  ##   - An integer z that solves `az ≡ 1 mod m`
  # Adapted from Knuth, The Art of Computer Programming, Vol2 p342
  # and Menezes, Handbook of Applied Cryptography (HAC), p610
  # to avoid requiring signed integers
  # http://cacr.uwaterloo.ca/hac/about/chap14.pdf
  
  # Starting from the extended GCD formula (Bezout identity),
  # `ax + by = gcd(x,y)`
  # with input x,y and outputs a, b, gcd
  # We assume a and m are coprimes, i.e. gcd is 1, otherwise no inverse
  # `ax + my = 1`
  # `ax + my ≡ 1 mod m`
  # `ax ≡ 1 mod m``
  # Meaning we can use the Extended Euclid Algorithm
  # `ax + by` with
  # a = a, x = result, b = m, y = 0
  
  var
a = a
x = 1.T
b = m
y = 0.T
oddIter = true # instead of requiring signed int, we keep track of 
even/odd iterations which would be in negative
  
  while b != 0.T:
let
  (q, r) = divmod(a,b)
  t = x + q * y
x = y; y = t; a = b; b = r
oddIter = not oddIter
  
  if a != 1.T:
# a now holds the gcd(a, m) and should equal 1
raise newException(ValueError, "No modular inverse exists")
  
  if oddIter:
return x
  return m - x


Run

The whole point of proof-of-work is to have non-trivial computation. 
Factorizing small number is very fast hence you need them at a decent bit-width 
but if you're really desperate, I have an arbitrary bigint factorization 
algorithm in BrainFuck here ;): 
[https://github.com/numforge/laser/blob/d1e6ae61/examples/ex07_jit_brainfuck_src/factor.bf](https://github.com/numforge/laser/blob/d1e6ae61/examples/ex07_jit_brainfuck_src/factor.bf)


Re: Is it possible for a macro to know the context it is used?

2020-05-13 Thread spip
Night has been enlightening. I understand my error. Instead of having multiple 
macros `algo1`, `evaluate`, etc. that are called when Nim compiler evaluates 
the syntax tree from the `dsl```call, I must see ``dsl` as a compiler itself. 
Now, I have only one macro, `dsl`, that is used to convert its argument to an 
AST, and then this AST is parsed/translated by procs in a new AST that will be 
used by the Nim compiler.

Instead of having multiple small macros that don't play well together and have 
only a local context, I'll apply a visitor-like pattern and I can control the 
scopes in the DSL.

Thanks @dawkot for forcing me to think out of the box with your example.


Re: Having problems porting a Python script for computing two cofactors of a number

2020-05-13 Thread miran
> As far as I can see one of the issues if that there's an overflow when two 
> big uint64's are multiplied.

Since after the multiplication you're taking a modulo, [these examples of 
modular 
arithmetic](https://en.wikipedia.org/wiki/Modular_arithmetic#Example_implementations)
 might come useful.


Re: Nimpy and Arraymancer

2020-05-13 Thread yglukhov
> Unfortunately that is a bug that is very hard to solve

Ok, but the workaround is trivial, no? Just use `nimpy.callMethod` directly 
instead of the `.()` magic.


Re: Nimpy and Arraymancer

2020-05-13 Thread Clonk
Uh wouldn't have guessed it would be such a complex issue actually.

Well, thanks for the heads up, i'll just use non-generic proc.


Re: llegal capture 'world' because ':anonymous' has the calling convention:

2020-05-13 Thread mratsim
`world` must be a parameter of your internal "closure".

Either you use `{.closure.}` and when the compiler sees that `world` is capture 
from the external context it will allocate a copy on the heap.

Or you use `{.nimcall.}` or `{.cdecl.}` and all the values captured must have a 
infinite lifetime (i.e. be globals) but in your case you are trying to capture 
`let world = world` which has the lifetime of the function.


Re: Is it possible for a macro to know the context it is used?

2020-05-13 Thread dawkot
If there's a pattern of doing init(...), evaluate: ..., let ... = getValue(), 
then you can convert it to something like this: 


dsl:
  algo1 as x:
echo x
algo2(x) as y:
  echo y


Run


llegal capture 'world' because ':anonymous' has the calling convention:

2020-05-13 Thread mantielero
I am trying to define the following callback from Nim: 


static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
  int i;
  
  //-- Get the body's ID
  dBodyID b1 = dGeomGetBody(o1);
  dBodyID b2 = dGeomGetBody(o2);
  
  //-- If they are connected by a joint, no collision detection is done. 
Finish
  if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) {
return;
  }
  
  //-- Configure the properties for the contact points
  dContact contact[MAX_CONTACTS];
  for (i=0; i


Run

It is simply not possible or to do it because of the calling convention or is 
it that I am not doing the closure properly?

Cheers


Re: Nimpy and Arraymancer

2020-05-13 Thread mratsim
> That would be awesome ! Is there a way to call numpy API directly in 
> arraymancer or do you still use Nimpy ?

No there is nothing for now.


Re: Nimpy and Arraymancer

2020-05-13 Thread mratsim
After further investigation it's not a name conflict issue.

This compiles


import ../src/arraymancer
import nimpy
import nimpy/raw_buffers
import sequtils

proc `+`[T](p: ptr T, val: int) : ptr T {.inline.}=
  cast[ptr T](cast[uint](p) + cast[uint](val * sizeof(T)))

proc pyBufToTensor[T](ndArray: PyObject): Tensor[T]=
  # Convert PyObject to RawPyBuffer
  var aBuf: RawPyBuffer
  ndArray.getBuffer(aBuf, PyBUF_WRITABLE or PyBUF_ND)
  aBuf.release()
  
  # Copy buffer into Tensor
  var shape: seq[int]
  for i in 0..https://github.com/yglukhov/nimpy/blob/b5401247](https://github.com/yglukhov/nimpy/blob/b5401247)

/nimpy.nim#L1285-L1289|   
---|---  
  

template `.()`*(o: PyObject, field: untyped, args: varargs[untyped]): 
PyObject =
  dotCall(o, field, args)

template `.`*(o: PyObject, field: untyped): PyObject =
  getAttr(o, astToStr(field))


Run

So it does not have the opportunity to transform `np.reshape` into a wrapped 
call before Nim compiler tries to check if the reshape symbol is valid in 
generic procs.

Unfortunately that is a bug that is very hard to solve.


Having problems porting a Python script for computing two cofactors of a number

2020-05-13 Thread Yardanico
Hello! So I decided to start trying to implement MTProto protocol (Telegram) in 
Nim, did the most basic things so I can get a reply from the server for the 
first time.

To continue I need to decompose a number `pq` into two prime cofactors `p` and 
`q`, such as `p` < `q`. So basically I need to find the largest prime cofactor 
of a number and then divide the number by that cofactor to get the second one. 
The Python version I found runs really fast in under 100ms:


from random import randint
from math import gcd


def brent(N):
if N % 2 == 0:
return 2
# y, c, m = randint(1, N - 1), randint(1, N - 1), randint(1, N - 1)
y = 398563423414958448
c = 259203014236224986
m = 359097073186387306

g, r, q = 1, 1, 1
while g == 1:
x = y
for i in range(r):
y = ((y * y) % N + c) % N
k = 0
while k < r and g == 1:
ys = y
for i in range(min(m, r - k)):
y = ((y * y) % N + c) % N
q = q * (abs(x - y)) % N
g = gcd(q, N)
k = k + m
r *= 2
if g == N:
while True:
ys = ((ys * ys) % N + c) % N
g = gcd(abs(x - ys), N)
if g > 1:
break

return g

def factors(n):
  a = brent(n)
  b = n // a
  return (a, b) if a < b else (b, a)

print(factors(1243804461473944423))


Run

I tried my hand at porting it to Nim but I guess I failed: 


import random, math

randomize()

proc brent*(n: uint64): uint64 =
  if n mod 2 == 0:
return 2
  
  var
# y = rand(1'u64 ..< n - 1)
y = 398563423414958448'u64
c = 259203014236224986'u64
m = 359097073186387306'u64
g, r, q = 1'u64
x, k, ys = 0'u64
  
  while g == 1:
x = y
for i in 0 ..< r:
  y = ((y * y) mod n + c) mod n
k = 0'u64
while k < r and g == 1:
  ys = y
  for i in 0 ..< min(m, r - k):
y = ((y * y) mod n + c) mod n
q = q * uint64(abs(int64(x - y))) mod n
  g = gcd(q, n)
  k = k + m
r *= 2
  if g == n:
while true:
  ys = ((ys * ys) mod n + c) mod n
  g = gcd(uint64(abs(int64(x - ys))), n)
  if g > 1:
break
  
  result = g

proc factors(n: uint64): (uint64, uint64) =
  let a = brent(n)
  let b = n div a
  if a < b: (a, b) else: (b, a)

echo factors(1243804461473944423'u64)


Run

As far as I can see one of the issues if that there's an overflow when two big 
uint64's are multiplied. So can someone recommend a good way to port this 
algorithm, or maybe I can use some other algorithm which won't use such big 
numbers for multiplication? (I also tried porting 
[https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm](https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm)
 and succeeded, but it's quite slow)


Re: How to instantiate `ptr object`

2020-05-13 Thread dataPulverizer
I just wasn't sure whether when allocating for objects you have to account for 
any "gubbings", just cautious I guess:


type
  MyTypeA = ptr object of RootObj
x: int64
  MyTypeB = ptr object of RootObj
x: array[0..4, int64]


var x0 = alloc(sizeof(int64));
var x1 = cast[MyTypeA](x0);
x1.x = 42;

echo "x: ", x1.x;
dealloc(x1); # or dealloc(x0)

var y0 = alloc(sizeof(int64)*5);
var y1 = cast[MyTypeB](y0);

y1.x = [1'i64, 2, 3, 4, 5];
echo "y1: ", y1.x;
dealloc(y1); # or dealloc(y0)


Run

I've now added your book to my Nim reading list. Thanks


Re: Multithreading Pt 2.5: Nichecache

2020-05-13 Thread Allin
Ok, technically reason is not GC per se, but thread-local values cannot be 
accessed from other threads. Also, when cache is full, new items will overwrite 
old items (idea of FIFO ring buffer) and then they will be garbage collected.

Here's a very simplified example that will cause SIGSEGV: 


from os import sleep
type Cache = array[1, string]
proc put(cache: ptr Cache) = cache[0] = "threadlocalstring"
var sharedcache: Cache
var thread: Thread[ptr Cache]
createThread(thread, put, addr sharedcache)
sleep(1000) # ensures that put happens here
echo sharedcache[0]


Run

But the good news is that with --gc:arc this program works as expected. 


Re: Multithreading Pt 2.5: Nichecache

2020-05-13 Thread Allin
I must admit that originally I wrote it this way by mistake. There goes my 
short-lived reputation as "the guy who invents really interesting AST hacks"... 
But the syntax stuck. In this rare occasion, it not only looks cool, it 
improves readability. Likely/unlikely is not an ordinary procedure call, for 
you it's a no-op, for me it's a reminder of where to (not) optimize, and for my 
compiler it's a hint of how to optimize.