Re: Problem with UI notification system

2019-07-10 Thread rayman22201
I edited my response above :-)

> the user checks which type of action it is, before it tries to access any 
> fields

Yeah. This is the crux of the problem. There is no other way around it. The key 
is making that check as robust as possible so it doesn't blow up when you don't 
expect it to :-)

In Nim, that basically means Variant types + case statements.


Re: Problem with UI notification system

2019-07-10 Thread Skaruts
That problem is true with python dictionaries too, btw. I think it's up to the 
user to know which fields to deal with. Or at least I'm running with that 
notion, that the user checks which type of action it is, before it tries to 
access any fields. For example:


proc handle_actions() =
var action:Action
while messenger.poll_actions(action):# loop the stack
case action.kind
of CellChangeSize:   resize_cells( action.dir )
of LayerAddRemove:   layer_add_rem( action.add )
of LayerToggleVisible:   layer_toggle_vis( action.vis )
of LayerRename:  layer_rename( action.new_name )
of LayerChangeAlgo:  layer_change_algo( action.algo )
else:discard


Run


Re: dynamic lib works properly when interfacing with python, fails with nim

2019-07-10 Thread okapi210
Yeah I jumped the gun... after some further testing it was just luck python was 
returning a 0. @Araq it's a closed source dll to make this even more annoying, 
but the functions are being exported as `stdcall` as far as I've been told.

I set up this test. Delphi dll code: 


library wrapd;

uses
   System.SysUtils;

{$R *.res}

function OpenDataFile(FileName: PChar): int32; stdcall;
begin
  WriteLn(FileName);
  WriteLn('test test test');
  Result := 99;
end;

exports OpenDataFile;

end.


Run

nim code: 


proc OpenDataFile(filename: cstring): int32 {.stdcall, dynlib: "wrapd.dll", 
importc.}

let fpath: cstring = r"C:\Users\okapi210\Desktop\test.file"
var fhandle = OpenDataFile(fpath)
echo fhandle


Run

result: 


?e
test test test
99


Run

So passing a cstring to PChar isn't working I probably just need a byte array


Re: Problem with UI notification system

2019-07-10 Thread rayman22201
Templates are very powerful, and it's cool that Nim can do this. Nim is all 
about flexibility :-)

> in case an empty Action is needed, or to not have to type the whole 
> properties: %*{} thing (might be redundant, I was just trying out things and 
> stumbled on that. Still trying to grasp templates).

Yes. You could make your own template that does the Actions( properties:... ) 
stuff for you.


# I used &&, but you could use whatever you wanted.
template `&&`(fields: untyped): untyped =
  Action( properties: %*`fields` )

var a2 = &&{
  "layer": 1,
  "add": true,
  "vis": false,
  "new_name": "woohoo less typing!"
}


Run

But, here are some examples on why the json dictionary type is not as type safe 
(dynamically typed):


# assume all the code @mratsim wrote above is included

proc doSomething(a: Action) =
  if a.Foo != 42:
echo "sorry, not the answer to the universe"

var a1 = Action(
  properties: %*{
"foo" = 10
  }
)
var a2 = Action(
  properties: %*{
# oops, I'm missing `foo`
"bar" = "I'm a string"
  }
)
var a3 = Action(
  properties: %*{
"foo" = "oops, I'm a string now!"
  }
)

doSomething(a1) # cool
doSomething(a2) # uh-oh, I don't a have a bar, but the compiler won't tell 
me, I will get a run time Exception!
doSomething(a3) # even worse! I won't get any error, but the result will be 
wrong! a3.foo will be interpreted as 0 and just keep going! Have fun debugging 
this one in a large program.


Run

A Variant type on the other hand will yell at you at compile time that the 
variant is either missing the field or the field is the wrong type.

As far as the fix for Variant types go: I don't really care what syntax we end 
up going with, but I do hope it will get fixed eventually. It's more of an 
inconvenience imo. Variant types are still usable and capable without this 
feature! 


Re: Problem with UI notification system

2019-07-10 Thread Skaruts
Well meanwhile I managed to find [a bit of a 
workaround](https://gist.github.com/Skaruts/11c9b4b8af153c5a4664eb46300455f4) 
for not being able to have attributes with the same name, for another part of 
my project.


Re: Problem with UI notification system

2019-07-10 Thread Skaruts
@rayman22201 indeed I wasn't thinking of anything that isn't type safe or 
outside of Nim's phylosophy. What @mratsim did above (1st post) with templates 
and the JSON module is what got me wondering, since it's actually not that far 
away from behaving like a python dictionary, from the POV of the user.


# Correction: it's actually closer to the behavior of GDScript dictionaries,
# since afaik python doesn't allow creating dict fields like:
a.foo = 10

# only like:
a["foo"] = 10


Run


Re: Macro to create a dictionary (table) like in python!

2019-07-10 Thread SolitudeSF
{} is a sugar for array of tuples, so @ already works with it by just making a 
sequence.


echo @{"key_1": "value_1", "key_2": "value_2"}


Run

results in 


@[("key_1", "value_1"), ("key_2", "value_2")]


Run


Re: Macro to create a dictionary (table) like in python!

2019-07-10 Thread cblake
I would have to agree with `@`. +1 vote.


Re: dynamic lib works properly when interfacing with python, fails with nim

2019-07-10 Thread Araq
It could also be something else, of course. But `ctypes` could get lucky with 
the stack layout and Nim doesn't.


Re: Nim vs V language

2019-07-10 Thread Libman
> [It](https://github.com/vlang/v) has 1k more Github stars than 
> [Nim](https://github.com/nim-lang/Nim).

Yet another reminder that [GitHub stars are an awful harmful way to 
measure](https://old.reddit.com/r/nim/comments/8q99ba/happy_5000_stars/e0i7etu/)
 anything...

> BTW, Nim is approaching 1000 nimble modules! 


Re: Macro to create a dictionary (table) like in python!

2019-07-10 Thread treeform
I think using @ instead of the % is perfect. Its just like the array syntax.


var a = @[1, 2, 3]
var b = @{"key_1": "value_1", "key_2": "value_2"}


Run


Re: dynamic lib works properly when interfacing with python, fails with nim

2019-07-10 Thread treeform
How does the python's ctypes work? ctypes supports register calling convention? 


Re: Problem with UI notification system

2019-07-10 Thread rayman22201
@mratsim's solution is very good for prototyping, and probably what you want. 
The Json module is the recommended way to get python dictionary behavior in 
Nim. It's the generally recommended way to transition Python programmers to Nim 
:-P

> if one couldn't come up with a Nim implementation of the exact behavior of 
> python dictionaries?

But, a native Python dictionary is probably never going to be put in the std 
library. Nim is a **statically typed language** , and this is dynamic behavior! 
You are setting the types of the dictionary at runtime. This is against the 
philosophy of statically typed languages like Nim.

Dynamic types like this have a cost. It's still much faster than Python, but it 
isn't free, and you loose most of the Nim type safety.

Variant types like in your initial post is the most idiomatic Nim, type safe 
way to do it. In fact, this is how Nim does it for the compiler: 
[https://nim-lang.org/docs/manual.html#types-object-variants](https://nim-lang.org/docs/manual.html#types-object-variants)

Unfortunately, as @doofenstein pointed out, you have hit a limitation of 
variant types in the current Nim. Either every variant that shares a field must 
be grouped together, or each variant must have a different field name. This is 
slightly inconvenient, I agree, and the proposed fix has stalled unfortunately 
(bigger fish to fry in the compiler).

The advantage of variant types is that the compiler can warn you at compile 
time if you attempt to access a field on an Action that doesn't exist for that 
action type. You won't get that with a Dictionary. You (or your user) will get 
a run time error instead (this is the point of static types).

One strategy may be to use the Json dictionary while you are prototyping, then 
once you have a better idea of what fields you need on each Action type, swap 
it out for a Variant type. Personally, I prefer to just use Variant types up 
front, because it lets me more clearly design my data types, and lets the 
compiler help me (by yelling at me) if I forgot a field somewhere. 


Re: Problem with UI notification system

2019-07-10 Thread doofenstein
looking at the problem as you detailed it in your first post it seems like 
you're searching for a way to have variant object, where fields are shared 
between specific cases. There has been 
[discussion](https://github.com/nim-lang/RFCs/issues/19) to implement this, 
though they've come to a standstill.

What other have suggested is making the fields completely dynamic, which is not 
ideal, since it undermines type safety and is slower than a simple field. 
Though in this case it's probably the best solution.


Re: Problem with UI notification system

2019-07-10 Thread Skaruts
There's a lot to take in in this, and I'm understanding some of it, but I'll 
take some more time to see if I can grasp it mostly. There's quite a few things 
that are new or still mysterious to me.

I noticed I can sort of shortcut it with 


template action():untyped = Action( properties: %*{} )
var a = action
a.algo = 10
echo a.algo# 10


Run

in case an empty Action is needed, or to not have to type the whole 
**properties: %*{}** thing (might be redundant, I was just trying out things 
and stumbled on that. Still trying to grasp templates).

Meanwhile, I am wondering -- and this is just a curiosity; I don't intend to 
explore this path myself -- if with some clever use of templates like this, and 
assuming one can overload the {} operators to this end, if one couldn't come up 
with a Nim implementation of the exact behavior of python dictionaries? 


# basically so that one could do just this:
let a = {
some_str:"bla bla",
some_int:10
}
# or like this
var a = {}
a.derp = 10
a.depier = "the derpest"

Run


Re: Macro to create a dictionary (table) like in python!

2019-07-10 Thread juancarlospaco
is sugar, so a literal is also possible. 


Re: Problem with UI notification system

2019-07-10 Thread mratsim
They allow rewriting a field access or field assignment call to the `Action` 
type to something else, there is more detail in the manual: 
[https://nim-lang.org/docs/manual_experimental.html#special-operators-dot-operators](https://nim-lang.org/docs/manual_experimental.html#special-operators-dot-operators).

In the example I'm using the template to instead access a properties json field 
and make those access/assignments feel seamless.

There is a remaining issue that the type returned is a `JsonNode` so in 
practice you would need:


a.new_name.getStr() # extract the string from the JsonNode
a.algo.getInt() # extract the int from the JsonNode


Run

If you want truly seamless calls without the need of `getStr` you would need 
something like the following, note the doAssert on the return type to make sure 
we don't get JsonNodes, and we don't need the . experimental template either:


import json

type
  Action = ref object
properties: JsonNode

template addPseudoField(A: typedesc, field: untyped, T: typedesc) =
  # A is for the type namespace (Action)
  
  template getType(args: varargs[untyped]): untyped =
# Alias the JsonNode getType function
when T is string:
  getStr(args)
elif T is int:
  getInt(args)
elif T is bool:
  getBool(args)
elif T is float:
  getFloat(args)
else:
  # You can add your own type special marshaller/deserializer
  raise newException(ValueError, "Unsupported type: " & $T)
  
  proc `field`*(a: A): T =
a.properties[astToStr(field)].getType()
  
  proc `field=`*(a: A, val: T) =
a.properties[astToStr(field)] = %val

Action.addPseudoField(layer, int)
Action.addPseudoField(add, bool)
Action.addPseudoField(vis, bool)
Action.addPseudoField(new_name, string)
Action.addPseudoField(algo, int)

var a = Action(
  properties: %*{
"layer": 0,
"add": true,
"vis": false,
"new_name": "fancy_name"
  }
)

echo a.new_name # "fancy_name"

a.algo = 10
echo a.algo # 10

doAssert a.algo is int
doAssert a.new_name is string


Run


Re: Problem with UI notification system

2019-07-10 Thread Skaruts
Hmm, I was just now reading about the JSON module and contemplating using it. 
Thanks for the examples.

I don't understand what the templates do though.