# import sets
import strformat
{.experimental:"callOperator".}
type
Object = ref object of RootObj
name : string
Morphism = ref object of Object
domain : ref Object
codomain : ref Object
method `()`(g:ref Morphism, f:ref Morphism):Morphism {.base.} =
let h = new Morphism
h.domain = f.domain
h.codomain = g.codomain
h.name = fmt"{g.name}⚬{f.name}"
return h
let X = Object(name:"X")
let Y = Object(name:"Y")
let Z = Object(name:"Z")
var f = Morphism(domain:X, codomain:Y)
var g = Morphism(domain:Y, codomain:Z)
var h = g(f)
echo h.name
I've tried about 20 other permutations of code. It's really dumb that we have no easy way to create objects. What is the point of all this complexity? Please keep the language design simple.
This would compile for me:
# import sets
import strformat
{.experimental:"callOperator".}
type
Object = ref object of RootObj
name : string
Morphism = ref object of Object
domain : Object
codomain : Object
method `()`(g: Morphism, f: Morphism):Morphism =# {.base.} =
let h = new Morphism
h.domain = f.domain
h.codomain = g.codomain
h.name = fmt"{g.name}⚬{f.name}"
return h
let X = Object(name:"X")
let Y = Object(name:"Y")
let Z = Object(name:"Z")
var f = Morphism(domain:X, codomain:Y)
var g = Morphism(domain:Y, codomain:Z)
var h = g(f)
echo h.name
As your Object is already a reference, ref Object would be a ref to ref, which is generally not intended. I don't know about {.experimental:"callOperator".}, sorry.
Please keep your example simple. Here is a much shorter example, with the same error:
import strformat
type
Object = ref object of RootObj
name : string
Morphism = ref object of Object
domain : ref Object
codomain : ref Object
let X = Object(name:"X")
let Y = Object(name:"Y")
var f = Morphism(domain:X, codomain:Y)
The error is explained p.108 in "Mastering Nim", I quote: "The subtype relation does not extend from A and B to var ref A and var ref B. Doing so would open a hole in the type system."All day to search for and correct the issue. I can't move at this rate. I have switched back to C++. I really liked how Nim allows you define your own operators and that it's as fast as C. As far as productivity goes though, it's slower (for me) than C++, and hence no where near Python's level of productivity. I am sorry, but I'm leaving you, community. Thank you for the introduction to Nim.
C++ has an overloadable -> operator, which is namely the one I wanted (working with morphisms in categories). I don't want to create a whole new language. I am creating a library to piggy back on top of an existing language. I'm having some success with C++ since this morning & Code::Blocks is much nicer than VSCode. I hate VSCode now too. You have to fight it to compile some code... Code::Blocks works out-of-the-box, and I'll probably include instructions for using it along with my C++ library.
I'm had a similar experience with Nim as I had with D. Also not a mature language. Everything requires you to be the original language designer to use it. Why couldn't Nim be simpler?
Anyway, sorry for the bummer, but life is too short to fight for 5 years to learn each small thing in a computer language. So I'll just find happiness with what I know & have.
@enjoysmath, @Stefan_Salewski outlined your problem, but in case it got lost, it was that you were trying to create a ref object and assign it to a ref ref object.
Arguably, this should be a compiler error because it doesn't quite make sense, but Nim gives you this flexibility if you somehow find a use for it (just as you can create a ptr ptr object type)
So to initialize an object, all you had to do was:
type
Object = ref object of RootObj
name: string
Morphism = ref object of Object
domain: Object # No `ref Object` needed because `Object` is already a ref
codomain: Object
let X = Object(name:"X")
let Y = Object(name:"Y")
let Z = Object(name:"Z")
var f = Morphism(domain: X, codomain: Y)
var g = Morphism(domain: Y, codomain: Z)
Similarly, in your method signature, you don't need ref Morphism, just Morphism because it is already a ref object.
That aside, of course C++ is going to be more productive if you've been programming using it for a long time. This would be true even if you switched to Python from only writing C++. Initially, while you learn how to use Python, it will be much slower because syntax, semantics, etc works differently. There are certain features in Python that take a long time to wrap your head around (like meta classes). But your issue was mainly one of semantics, your past experience, and the compiler not giving you a useful error message.
If you need stability and reliability, of course the big guys like Java, C++, and Python are going to be where you should develop your application or library. If you want to experiment, have fun, and potentially eat up time, try a less mainstream language like Nim or Rust.
I'm having some success with C++ since this morning & Code::Blocks is much nicer than VSCode. I hate VSCode now too. You have to fight it to compile some code... Code::Blocks works out-of-the-box,
Yeah it's a well kept secret that Code::Blocks is in fact the superior solution and ultimate IDE; In fact professional developers made a secret pact not to use this too powerful IDE or we'd become too productive and there wouldn't be enough work for everyone.
life is too short to fight for 5 years to learn each small thing in a computer language
You should try using brainfuck. It's very simple but Turing complete, you can learn it in a few days so obviously it's a better programming language.