www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - questions on class definitions and mixins

reply "Patrick D. Jeeves" <pdj9 pitt.edu> writes:
One thing I've been trying to figure out is how to do the 
following in D:

class foo
{
     string bar();
};

void foo::bar()
{
     return "hello world!";
}

 From what I can gather constructs like this just aren't allowed 
in D, but I don't understand why, can anyone explain it please?  
I know they're only in C++ because it uses #include instead of 
importing compiled modules, but I find it hard to quickly get a 
general idea of what a class is supposed to do when there are 
function definitions strewn about it.

The other thing I want to know is about the mixin() command, and 
what the limitations of it are; I know it runs an interpreted 
version of D, but I get the feeling that it isn't as powerful as 
the compiled version, because no one seems to have tried making 
something like this:

class example : File
{
      mixin(d.flex(`lex_file.l`));
      mixin(d.bison(`bison_file.y`));
};

void main()
{
      example("some_file.txt");
      example.yyparse();
};

Is this because it isn't possible to do such things, or because 
it would be rather pointless to do so compared to simpler 
approaches, (in this case calling the C function output by 
flex/bison).
Feb 10 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 10 February 2014 at 15:35:00 UTC, Patrick D. Jeeves 
wrote:
 From what I can gather constructs like this just aren't allowed 
 in D, but I don't understand why, can anyone explain it please?
It just wasn't there but there's some people who think it would be a good idea to add (including Walter I think) so it might be in later. What you can do is write it all inline, then do a create an automatic documentation or interface file with dmd -D or dmd -H which strips out most the function bodies.
 The other thing I want to know is about the mixin() command, 
 and what the limitations of it are; I know it runs an 
 interpreted version of D
mixin basically copy/pastes the code inside right into the source file then compiles it normally. The interpreted part is only running the function to create teh code, but then the created code is compiled normally. So mixin(foo()); foo() is interpreted, then the return value of it is compiled in normally.
 Is this because it isn't possible to do such things, or because 
 it would be rather pointless to do so compared to simpler 
 approaches, (in this case calling the C function output by 
 flex/bison).
I think it is just that nobody has tried yet. There are parser generators that work at compile time in D though https://github.com/PhilippeSigaud/Pegged for example
Feb 10 2014
next sibling parent "Andrea Fontana" <nospam example.com> writes:
On Monday, 10 February 2014 at 15:41:06 UTC, Adam D. Ruppe wrote:
 On Monday, 10 February 2014 at 15:35:00 UTC, Patrick D. Jeeves 
 wrote:
 [...]
 Is this because it isn't possible to do such things, or 
 because it would be rather pointless to do so compared to 
 simpler approaches, (in this case calling the C function 
 output by flex/bison).
I think it is just that nobody has tried yet. There are parser generators that work at compile time in D though https://github.com/PhilippeSigaud/Pegged for example
I think it's not the only reason. I've tried to do something similar but not all libraries can be used at compile time. E.g: let's try to read a xml file at compile time...
Feb 10 2014
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 It just wasn't there but there's some people who think it would 
 be a good idea to add (including Walter I think) so it might be 
 in later.
It increases the syntactic variance of D code, and people coming from C++ will go using it straight (and not just in the uncommon cases discussed by Manu). Perhaps it could be added with an ugly syntax that discourages it usage in 99% of the cases, like: void __external_class_method ClassName.methodName() {} Bye, bearophile
Feb 10 2014
prev sibling next sibling parent "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Monday, 10 February 2014 at 15:35:00 UTC, Patrick D. Jeeves 
wrote:
 One thing I've been trying to figure out is how to do the 
 following in D:

 class foo
 {
     string bar();
 };

 void foo::bar()
 {
     return "hello world!";
 }

 From what I can gather constructs like this just aren't allowed 
 in D, but I don't understand why, can anyone explain it please?
  I know they're only in C++ because it uses #include instead of 
 importing compiled modules, but I find it hard to quickly get a 
 general idea of what a class is supposed to do when there are 
 function definitions strewn about it.
dmd's -H family of options allows you to generate .di files which strip definitions, leaving only declarations in place. I agree that sometimes finding your way around a huge class or module is difficult. However, D is not the only language that DDoc and .di files.
 The other thing I want to know is about the mixin() command, 
 and what the limitations of it are; I know it runs an 
 interpreted version of D,
It doesn't run any interpreters, it mixes in a string as D code and compiles it.
 but I get the feeling that it isn't as powerful as the compiled 
 version, because no one seems to have tried making something 
 like this:

 class example : File
 {
      mixin(d.flex(`lex_file.l`));
      mixin(d.bison(`bison_file.y`));
 };
There's a string import expression (http://dlang.org/expression.html#ImportExpression) that allows to import some text file at compile time and make a string literal out of it. vibe.d, for example, uses it to generate code for its 'Diet' HTML templates. Generally, if you can create compile-time parser for something, you can implement what you're describing above.
Feb 10 2014
prev sibling next sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Monday, 10 February 2014 at 15:35:00 UTC, Patrick D. Jeeves 
wrote:
 One thing I've been trying to figure out is how to do the 
 following in D:

 class foo
 {
     string bar();
 };

 void foo::bar()
 {
     return "hello world!";
 }

 From what I can gather constructs like this just aren't allowed 
 in D, but I don't understand why, can anyone explain it please?
  I know they're only in C++ because it uses #include instead of 
 importing compiled modules, but I find it hard to quickly get a 
 general idea of what a class is supposed to do when there are 
 function definitions strewn about it.
There have been lengthy discussions about this before, perhaps try searching the forums for them (I can't quite remember the title of the most recent one...). Personally I recommend generating documentation (using DDoc et al) for your types and referencing at that.
 The other thing I want to know is about the mixin() command, 
 and what the limitations of it are; I know it runs an 
 interpreted version of D, but I get the feeling that it isn't 
 as powerful as the compiled version, because no one seems to 
 have tried making something like this:

 class example : File
 {
      mixin(d.flex(`lex_file.l`));
      mixin(d.bison(`bison_file.y`));
 };

 void main()
 {
      example("some_file.txt");
      example.yyparse();
 };

 Is this because it isn't possible to do such things, or because 
 it would be rather pointless to do so compared to simpler 
 approaches, (in this case calling the C function output by 
 flex/bison).
There are D projects that do this kind of thing, e.g. Pegged[1] and a proposed std.lexer[2]. Mixin expressions can mixin any string available/computable at compile-time and there are no limits to what the mixed-in code can do. However, if the mixed-in code is subsequently executed *at compile-time*, it is limited by the same restrictions all compile-time executation have[3]. [1] https://github.com/PhilippeSigaud/Pegged [2] https://github.com/Hackerpilot/Dscanner/blob/master/stdx/lexer.d [3] http://dlang.org/function#interpretation
Feb 10 2014
prev sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Monday, 10 February 2014 at 15:35:00 UTC, Patrick D. Jeeves 
wrote:
 From what I can gather constructs like this just aren't allowed 
 in D, but I don't understand why, can anyone explain it please?
http://wiki.dlang.org/DIP47 There is a threadnaught related to the above DIP somewhere. I personally disagreed with the suggestion.
Feb 10 2014