www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Recursive data-types

reply "ponce" <contact gam3sfrommars.fr> writes:
I'm dabbling with Scheme interpreter and ultimately I would need 
to declare the following types.

--------------

struct Function
{
     Environment env;
     Atom params;
     Atom body_;
}

// An atom is either a string, a double, a symbol, a function or 
a list of atoms
alias Atom = Algebraic!(string, double, Symbol, Function, This[]);

--------------

These definitions can't work since Function and Atom need each 
other in this recursive definition.

How to get out of this trap?
Do I have to drop Algebraic and go back to manual tagged unions?
Sep 27 2014
next sibling parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 27/09/2014 11:26 p.m., ponce wrote:
 I'm dabbling with Scheme interpreter and ultimately I would need to
 declare the following types.

 --------------

 struct Function
 {
      Environment env;
      Atom params;
      Atom body_;
 }

 // An atom is either a string, a double, a symbol, a function or a list
 of atoms
 alias Atom = Algebraic!(string, double, Symbol, Function, This[]);

 --------------

 These definitions can't work since Function and Atom need each other in
 this recursive definition.

 How to get out of this trap?
 Do I have to drop Algebraic and go back to manual tagged unions?
Converting Function to a class. No where near ideal. But it'll work.
Sep 27 2014
next sibling parent "ponce" <contact gam3sfrommars.fr> writes:
On Saturday, 27 September 2014 at 11:40:19 UTC, Rikki Cattermole 
wrote:
 How to get out of this trap?
 Do I have to drop Algebraic and go back to manual tagged 
 unions?
Converting Function to a class. No where near ideal. But it'll work.
It does work! Thanks. Actually it's quite appropriate to make it a reference type.
Sep 27 2014
prev sibling parent "thedeemon" <dlang thedeemon.com> writes:
On Saturday, 27 September 2014 at 11:40:19 UTC, Rikki Cattermole 
wrote:

 These definitions can't work since Function and Atom need each 
 other in
 this recursive definition.

 How to get out of this trap?
 Do I have to drop Algebraic and go back to manual tagged 
 unions?
Converting Function to a class. No where near ideal. But it'll work.
Interesting, I didn't expect this to work... Got a longer workaround using some category theory and higher kinded types: http://www.infognition.com/blog/2014/recursive_algebraic_types_in_d.html
Sep 27 2014
prev sibling next sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Sat, Sep 27, 2014 at 11:26:31AM +0000, ponce via Digitalmars-d-learn wrote:
 I'm dabbling with Scheme interpreter and ultimately I would need to
 declare the following types.
 
 --------------
 
 struct Function
 {
     Environment env;
     Atom params;
     Atom body_;
 }
 
 // An atom is either a string, a double, a symbol, a function or a
 // list of atoms
 alias Atom = Algebraic!(string, double, Symbol, Function, This[]);
 
 --------------
 
 These definitions can't work since Function and Atom need each other
 in this recursive definition.
[...] What about using Atom*[] instead of Atom[]? T -- Microsoft is to operating systems & security ... what McDonalds is to gourmet cooking.
Sep 27 2014
parent "ponce" <contact gam3sfrommars.fr> writes:
On Saturday, 27 September 2014 at 14:08:18 UTC, H. S. Teoh via 
Digitalmars->
 What about using Atom*[] instead of Atom[]?
Atom[] seems simpler to me.
Sep 27 2014
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Saturday, 27 September 2014 at 11:26:33 UTC, ponce wrote:
 I'm dabbling with Scheme interpreter and ultimately I would 
 need to declare the following types.

 --------------

 struct Function
 {
     Environment env;
     Atom params;
     Atom body_;
 }

 // An atom is either a string, a double, a symbol, a function 
 or a list of atoms
 alias Atom = Algebraic!(string, double, Symbol, Function, 
 This[]);

 --------------

 These definitions can't work since Function and Atom need each 
 other in this recursive definition.

 How to get out of this trap?
 Do I have to drop Algebraic and go back to manual tagged unions?
You can also use a pointer to a Function. Basically, any indirection will solve this problem, whether it be via class or pointer. struct Function { Environment env; //Either do this: Atom* params; Atom* body_; } //Or this //Now a pointer alias Atom = Algebraic!(string, double, Symbol, Function*, This[]); Also, you might want to use This* instead of This[], unless you want an Atom to be able to contain a whole array of other atoms.
Sep 27 2014
parent "ponce" <contact gam3sfrommars.fr> writes:
On Saturday, 27 September 2014 at 15:45:20 UTC, Meta wrote:
 Also, you might want to use This* instead of This[], unless you 
 want an Atom to be able to contain a whole array of other atoms.
That's indeed what I want.
Sep 27 2014