I spent a few hours making a library seeing how far I could push things with dynamic typing. I ended up making a type called DynVal that's basically a box for all primitives and ref values inheriting from RootObj. It uses converters and operator overloads to make DynVal usable in any place where a primitive or string is used, including all the fun things like type coercion from strings to various primitive values.
I started doing this while playing around with the dot call operator overload experimental feature, which I used to make a table where you could access and call properties as if they were procs.
Here's my dynamic typing code: https://git.termer.net/termer/nim-dynval
You can look at the README and tests to see what it can do.
What's missing is the actual thing I started out trying to do: accessing and assigning arbitrary properties and calling procs dynamically. The dynamic properties is easy, all I need to do is have a Table of strings mapping to DynVal, but the proc thing is a little trickier. The call signature would need to be something like proc (args: varargs[DynVal]) to allow passing in any params, and then a macro would need to be used to generate type guards for any procs you assign.
For example, doing the following:
myDynVal.yellName = proc (name: string): string = name.toUpper() & '!'
...would need to wrap the proc in the something like the following:
proc yellNameWrapper(args: vararg[DynVal]): DynVal =
if args.len < 1:
raise newException(TypeError, "Expected 1 argument but got 0")
var nameArg = args[0]
if nameArg.kind != dvkString:
raise newException(TypeError, "Expected argument 1 to be of type string")
return newDynVal(yellName(nameArg.dynValString))
I don't know if macros have introspection ability for procs. If they can retrieve a proc's argument list and return type, then it should be possible.
The other thing I ran into is the fact the compiler doesn't like generic converters, and can't really make use of them to implicitly convert. Type inference isn't possible without arguments, so you can't infer what a converter's generic type should be based on the proc you're putting the value into. This makes it a lot less ergonomic.
You wrote an entire programming language whose namesake was a king synonymous with the concept of confusion, and with pages and pages of experimental features. You probably also know a thing or two about programming possibly nonsensical things for fun
There is nothing "experimental" about dynamic typing though, we have run this experiment for decades now. :P
"0" == -null
though?