I tried to find a way of calling base class constructor with Nimrod classes like I used to do in other object-oriented languages, in Python for example:
class ClassA:
    
    def __init__(self):
        self.x = 1

class ClassB(ClassA):
    
    def __init__(self):
        ClassA.__init__(self)
        self.y = 1

b = ClassB()

print "x =", b.x, "y =", b.y

output: x = 1 y = 1

So for now I made this:

type
  # parent object
  PObjectA = ref TObjectA
  TObjectA = object of TObject
    x: int
  
  # child object
  PObjectB = ref TObjectB
  TObjectB = object of TObjectA
    y: int

# parent object constructor
proc newObjectA(child: PObjectA = nil): PObjectA =
  if child == nil: new(result) # if creates a new object
  else: result = child # if ref to child provided
  # init object fields
  result.x = 1

# child object constructor
proc newObjectB(child: PObjectB = nil): PObjectB =
  if child == nil: new(result)
  else: result = child
  discard newObjectA(result) # calling parent object consructor
  # init object fields
  result.y = 2

var b: PObjectB = newObjectB()
echo("x=", b.x, " y=", b.y)

output: x=1 y=2

But don't I miss some easier way to do this?

2012-05-03 18:36:34
I'd use this instead:
type
  PObjectA = ref TObjectA
  TObjectA = object of TObject
    x: int
  
  PObjectB = ref TObjectB
  TObjectB = object of TObjectA
    y: int

proc initA(a: PObjectA) =
  a.x = 1

# parent object constructor
proc newObjectA(): PObjectA =
  new(result)
  initA(result)

# child object constructor
proc newObjectB(): PObjectB =
  new(result)
  initA(result)
  # init object fields
  result.y = 2

var b = newObjectB()
echo("x=", b.x, " y=", b.y)
2012-05-03 21:21:19

Thanks for reply.

Also I've got a related question. When I try to call base class method I get segmentation fault. It seems that this is not the right way to do it:

type
  PObjectA = ref TObjectA
  TObjectA = object of TObject
  
  PObjectB = ref TObjectB
  TObjectB = object of TObjectA

method update(obj: PObjectA) =
  echo("update parent")

method update(obj: PObjectB) =
  #PObjectA(obj).update() # This is causes a segfault
  echo("update child")

proc newObjectA(): PObjectA =
  new(result)

proc newObjectB(): PObjectB =
  new(result)

var x: PObjectA = newObjectB()
x.update()
2012-05-12 18:54:00

method update(obj: PObjectB) =
  PObjectA(obj).update()
Your explicit type conversion does not inhibit dynamic binding so you create an endless recursion here, causing a stack overflow and thus a segfault. Again, to get "super"-like functionality, you need to use a helper proc:

type
  PObjectA = ref TObjectA
  TObjectA = object of TObject
  
  PObjectB = ref TObjectB
  TObjectB = object of TObjectA

proc updateA(obj: PObjectA) =
  echo "update parent"

method update(obj: PObjectA) =
  updateA(obj)

method update(obj: PObjectB) =
  updateA(obj)

proc newObjectA(): PObjectA =
  new(result)

proc newObjectB(): PObjectB =
  new(result)

var x: PObjectA = newObjectB()
x.update()

2012-05-12 21:55:58
Hm A little messy but works as intended. Thanks again! 2012-05-12 22:09:28

> Your explicit type conversion does not inhibit dynamic binding so you create an endless recursion here, causing a stack overflow and thus a segfault

Should a thing like this be detected at compile time? Or at least raise another exception other than SIGSEGV?

2012-05-14 07:31:54

Detecting this at compile time seems hard. I'm still thinking about how to improve it.

Detecting stack overflows at runtime properly is also non-trivial; previous attempts never really worked: It's hard (but not impossible) to call a stack overflow handler when there is no space left in the stack.

2012-05-16 08:07:23

Hello,

I just discovered Nimrod and I like many aspects of it, but it seems that object oriented code will be very verbose if this example is any indication: I think that the equivalent code in Scala would be much, much shorter (Python's initial example is already terser than Nimrod)..

I'm a bit worried by this aspect of Nimrod..

BR, renoX

2012-05-30 20:37:33

It's possible to design a 'class' macro but nobody ever wrote it.

# implementation left as an exercise for the reader
import classes

class MyClass(refsemantics):
  proc init() =
     x = 3 # 'class' could make implicit field definitions possible
  method doIt() =
    # aka 'virtual'
    echo "do it"

2012-05-30 22:01:30

> It's possible to design a 'class' macro but nobody ever wrote it.

To study what would be a good design, why not? But for a "base" feature in the end, it must be built-in in the language otherwise it will make debugging more difficult (thinking long term with a "native" compiler).

2012-06-04 07:48:05
<<<••12••>>>