Re: Interface/abstract constructors

2011-05-16 Thread Timon Gehr
 Hey guys,

 is there any chance to create an abstract constructor like:

 abstract class ABC {

abstract this();

 }

 DMD always says ...this non-virtual functions cannot be abstract -
 when I use an interface like:

 interface ABC {

this();

 }

 I get a similar error: ...constructors, destructors, postblits,
 invariants, unittests, new and delete functions are not allowed in
 interface ABC

 Is there any solution or is it possible to create such inheritances
 in DMD?

How about:
abstract class ABC{
this();
}

Timon


Re: Interface/abstract constructors

2011-05-16 Thread Jonathan M Davis
On 2011-05-16 12:32, useo wrote:
 Hey guys,
 
 is there any chance to create an abstract constructor like:
 
 abstract class ABC {
 
abstract this();
 
 }
 
 DMD always says ...this non-virtual functions cannot be abstract -
 when I use an interface like:
 
 interface ABC {
 
this();
 
 }
 
 I get a similar error: ...constructors, destructors, postblits,
 invariants, unittests, new and delete functions are not allowed in
 interface ABC
 
 Is there any solution or is it possible to create such inheritances
 in DMD?

An abstract constructor makes no sense. It also makes no sense for an 
interface to have a constructor. A constructor is specific to the class that 
it's on. It is not virtual at all and has nothing to do with the inheritance 
hierarchy beyond the fact that subclasses can and will call the constructors 
of base classes in their own constructors.

- Jonathan M Davis


Re: Interface/abstract constructors

2011-05-16 Thread Steven Schveighoffer

On Mon, 16 May 2011 15:32:43 -0400, useo unkn...@unknown.com wrote:


Hey guys,

is there any chance to create an abstract constructor like:

abstract class ABC {

   abstract this();

}

DMD always says ...this non-virtual functions cannot be abstract -
when I use an interface like:

interface ABC {

   this();

}

I get a similar error: ...constructors, destructors, postblits,
invariants, unittests, new and delete functions are not allowed in
interface ABC

Is there any solution or is it possible to create such inheritances
in DMD?


I think what you are trying to do is say, if a class implements interface  
ABC, it must have a default constructor.  Such a requirement is faulty.   
The point of an interface is to able to pass a portion of a class'  
functionality to a function during runtime.  However, the instance must  
*already exist*.  It makes no sense to posit requirements on the  
constructor.


What you want is a compile-time requirement using a template constraint.   
You may think damn, but I don't want to make my function a template, I'd  
say see previous point ;)


-Steve


Re: Interface/abstract constructors

2011-05-16 Thread nrgyzer
== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel
 On Mon, 16 May 2011 15:32:43 -0400, useo unkn...@unknown.com
wrote:
  Hey guys,
 
  is there any chance to create an abstract constructor like:
 
  abstract class ABC {
 
 abstract this();
 
  }
 
  DMD always says ...this non-virtual functions cannot be
abstract -
  when I use an interface like:
 
  interface ABC {
 
 this();
 
  }
 
  I get a similar error: ...constructors, destructors, postblits,
  invariants, unittests, new and delete functions are not allowed in
  interface ABC
 
  Is there any solution or is it possible to create such
inheritances
  in DMD?
 I think what you are trying to do is say, if a class implements
interface
 ABC, it must have a default constructor.  Such a requirement is
faulty.
 The point of an interface is to able to pass a portion of a class'
 functionality to a function during runtime.  However, the instance
must
 *already exist*.  It makes no sense to posit requirements on the
 constructor.
 What you want is a compile-time requirement using a template
constraint.
 You may think damn, but I don't want to make my function a
template, I'd
 say see previous point ;)
 -Steve

Okay, thanks... perhaps someone know a better solution: I have one
big file which contains some other files (let's say: blocks). Each
block has it's own signature... by reading the big file, I read the
signature of each block. Based on the signature, I read block A,
block B or another Block. To do that, I want call the block-specific
constructor which reads the next bytes.

!Semicode:

...
ABC[] blocks;
...
while (!eof(bigfile)) {
  read(signature);
  if (signature==A) blocks ~= new A(bigfile);
  else if (signature==B) blocks ~= new B(bigfile);
  ...
}
...


Re: Interface/abstract constructors

2011-05-16 Thread Steven Schveighoffer

On Mon, 16 May 2011 16:12:05 -0400, nrgyzer nrgy...@gmail.com wrote:


== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel

On Mon, 16 May 2011 15:32:43 -0400, useo unkn...@unknown.com

wrote:

 Hey guys,

 is there any chance to create an abstract constructor like:

 abstract class ABC {

abstract this();

 }

 DMD always says ...this non-virtual functions cannot be

abstract -

 when I use an interface like:

 interface ABC {

this();

 }

 I get a similar error: ...constructors, destructors, postblits,
 invariants, unittests, new and delete functions are not allowed in
 interface ABC

 Is there any solution or is it possible to create such

inheritances

 in DMD?
I think what you are trying to do is say, if a class implements

interface

ABC, it must have a default constructor.  Such a requirement is

faulty.

The point of an interface is to able to pass a portion of a class'
functionality to a function during runtime.  However, the instance

must

*already exist*.  It makes no sense to posit requirements on the
constructor.
What you want is a compile-time requirement using a template

constraint.

You may think damn, but I don't want to make my function a

template, I'd

say see previous point ;)
-Steve


Okay, thanks... perhaps someone know a better solution: I have one
big file which contains some other files (let's say: blocks). Each
block has it's own signature... by reading the big file, I read the
signature of each block. Based on the signature, I read block A,
block B or another Block. To do that, I want call the block-specific
constructor which reads the next bytes.

!Semicode:

...
ABC[] blocks;
...
while (!eof(bigfile)) {
  read(signature);
  if (signature==A) blocks ~= new A(bigfile);
  else if (signature==B) blocks ~= new B(bigfile);
  ...
}
...


No special requirements are necessary.  How would this compile if A or B  
did not have a bigfile constructor?  The interface specification is not  
needed.


If D supported runtime reflection (and it does to a very very small  
degree), then you could use it to ensure the correct constructor is  
available.


-Steve


Re: Interface/abstract constructors

2011-05-16 Thread nrgyzer
== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel
 On Mon, 16 May 2011 16:12:05 -0400, nrgyzer nrgy...@gmail.com
wrote:
  == Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel
  On Mon, 16 May 2011 15:32:43 -0400, useo unkn...@unknown.com
  wrote:
   Hey guys,
  
   is there any chance to create an abstract constructor like:
  
   abstract class ABC {
  
  abstract this();
  
   }
  
   DMD always says ...this non-virtual functions cannot be
  abstract -
   when I use an interface like:
  
   interface ABC {
  
  this();
  
   }
  
   I get a similar error: ...constructors, destructors,
postblits,
   invariants, unittests, new and delete functions are not
allowed in
   interface ABC
  
   Is there any solution or is it possible to create such
  inheritances
   in DMD?
  I think what you are trying to do is say, if a class implements
  interface
  ABC, it must have a default constructor.  Such a requirement is
  faulty.
  The point of an interface is to able to pass a portion of a
class'
  functionality to a function during runtime.  However, the
instance
  must
  *already exist*.  It makes no sense to posit requirements on the
  constructor.
  What you want is a compile-time requirement using a template
  constraint.
  You may think damn, but I don't want to make my function a
  template, I'd
  say see previous point ;)
  -Steve
 
  Okay, thanks... perhaps someone know a better solution: I have one
  big file which contains some other files (let's say: blocks). Each
  block has it's own signature... by reading the big file, I read
the
  signature of each block. Based on the signature, I read block A,
  block B or another Block. To do that, I want call the block-
specific
  constructor which reads the next bytes.
 
  !Semicode:
 
  ...
  ABC[] blocks;
  ...
  while (!eof(bigfile)) {
read(signature);
if (signature==A) blocks ~= new A(bigfile);
else if (signature==B) blocks ~= new B(bigfile);
...
  }
  ...
 No special requirements are necessary.  How would this compile if A
or B
 did not have a bigfile constructor?  The interface specification is
not
 needed.
 If D supported runtime reflection (and it does to a very very small
 degree), then you could use it to ensure the correct constructor is
 available.
 -Steve

It's semicode, so I haven't try to implement it... it should only
show what I'm trying to do.
I'm currently thinking about an empty constructor in an abstract
class like:

abstract class ABC {
   this(Stream) {
  // do nothing
   }
}

class A : ABC {

   this(Stream s) {
  super(s);
  // read my block-specific bytes
   }

}


Re: Interface/abstract constructors

2011-05-16 Thread Steven Schveighoffer

On Mon, 16 May 2011 16:34:20 -0400, nrgyzer nrgy...@gmail.com wrote:


== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel



If D supported runtime reflection (and it does to a very very small
degree), then you could use it to ensure the correct constructor is
available.
-Steve


It's semicode, so I haven't try to implement it... it should only
show what I'm trying to do.
I'm currently thinking about an empty constructor in an abstract
class like:

abstract class ABC {
   this(Stream) {
  // do nothing
   }
}

class A : ABC {

   this(Stream s) {
  super(s);
  // read my block-specific bytes
   }

}


First, this should work.  Second, there is no good reason to do this.  An  
abstract class is allowed to have an empty constructor, but does not force  
one to implement a Stream-accepting constructor.


For example, this would be a valid subclass:

class A : ABC {
   this() { super(null); }
}

I'm not very good at explaining things sometimes, but if you think about  
this for a while, it should sink in.  Construction is a concrete activity,  
you need to have all information about a class to construct it.   
Interfaces and polymorphism is an abstract activity, you do not need to  
have the full definition of the class to call virtual methods.


There is no point to have a constructor definition to force a signature,  
because it just won't matter.  The derived class does not have to override  
base constructors because base constructors are not virtual methods.


What you probably want is a factory method such as:

ABC abcfactory(Stream s)
{
   header = readHeader(s);
   if(header == Aheader)
  return new A(s);
   ...
   else
  throw new Exception(Unknown header);
}

What you should put in ABC is methods you would call on the objects  
*after* they are constructed.


Now, with runtime reflection, you can look up classes based on the class  
names and their appropriate constructors.  I've written such systems in  
C#, and it's not extremely easy to do it safely.  It's much more  
straightforward and less error prone to just use a factory method like the  
above.


-Steve