www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A "general" tag

reply "Xan" <xancorreu gmail.com> writes:
Hi,

I try to translate a script I wrote in Fantom [www.fantom.org]. 
In my script, I have a type "Tag" defined as a triple of:
- String (the name of the tag),
- Type (the type of the tag: could be Str, Date, Int, etc.)
- Obj (the value of the tag; Fantom has Objects of Top-Class 
hierachy).

(normally the tag has Type = Obj.Type, but you can manually set).

For example,
you could have:
(name, Str#, "John")

or

(date, Date#, 2011-09-02)


(# is the Fantom way for specifying type: Str# is the sys::Str 
type)


Is there any way for emulating this? My main trouble is how to 
define Type and Object in D.

Thanks in advance,
Xan.

PS: Please, be patient, I'm a newbee.
Apr 14 2012
next sibling parent reply "Aleksandar =?UTF-8?B?UnXFvmnEjWnEhyI=?= <aleksandar ruzicic.info> writes:
On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote:
 Hi,

 I try to translate a script I wrote in Fantom [www.fantom.org]. 
 In my script, I have a type "Tag" defined as a triple of:
 - String (the name of the tag),
 - Type (the type of the tag: could be Str, Date, Int, etc.)
 - Obj (the value of the tag; Fantom has Objects of Top-Class 
 hierachy).

 (normally the tag has Type = Obj.Type, but you can manually 
 set).

 For example,
 you could have:
 (name, Str#, "John")

 or

 (date, Date#, 2011-09-02)


 (# is the Fantom way for specifying type: Str# is the sys::Str 
 type)


 Is there any way for emulating this? My main trouble is how to 
 define Type and Object in D.

 Thanks in advance,
 Xan.

 PS: Please, be patient, I'm a newbee.

For "Type" look at enum (http://dlang.org/enum.html) and for "Object" look at std.variant (http://dlang.org/phobos/std_variant.html). And since Variant can tell you what type it contains you might no longer need that "Type" parameter.
Apr 14 2012
parent Denis Shelomovskij <verylonglogin.reg gmail.com> writes:
15.04.2012 0:31, Xan написал:
 On Saturday, 14 April 2012 at 19:40:06 UTC, Aleksandar Ružičić wrote:
 On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote:
 Hi,

 I try to translate a script I wrote in Fantom [www.fantom.org]. In my
 script, I have a type "Tag" defined as a triple of:
 - String (the name of the tag),
 - Type (the type of the tag: could be Str, Date, Int, etc.)
 - Obj (the value of the tag; Fantom has Objects of Top-Class hierachy).

 (normally the tag has Type = Obj.Type, but you can manually set).

 For example,
 you could have:
 (name, Str#, "John")

 or

 (date, Date#, 2011-09-02)


 (# is the Fantom way for specifying type: Str# is the sys::Str type)


 Is there any way for emulating this? My main trouble is how to define
 Type and Object in D.

 Thanks in advance,
 Xan.

 PS: Please, be patient, I'm a newbee.

For "Type" look at enum (http://dlang.org/enum.html) and for "Object" look at std.variant (http://dlang.org/phobos/std_variant.html). And since Variant can tell you what type it contains you might no longer need that "Type" parameter.

I think it's not what I expect. Can I have a generic object type? Something like an assigment like: Any a ? With templates? Please, guide me. I'm a newbee

What you are looking for is a boxing. http://en.wikipedia.org/wiki/Boxing_(computer_science)#Boxing D doesn't support auto boxing/unboxing. For a reason see, e.g. this thread: http://forum.dlang.org/thread/ckoaum$1lbg$1 digitaldaemon.com http://forum.dlang.org/thread/cr7njl$18j3$1 digitaldaemon.com There was std.boxer module, but it was deprecated and removed, this is the last version before removal: https://github.com/D-Programming-Language/phobos/blob/c20d454d63861a0c4bab647b37c01b0dd981a3f8/std/boxer.d std.variant is really what you are looking for. See example: --- import std.stdio; import std.variant; import std.string: format; struct Tag { string name; Variant entity; } class C { int i; this(int i) { this.i = i; } string toString() { return format("C(i: %s)", i); } } struct SmallStruct { int a; } struct Huge { real a, b, c, d, e, f, g; } void writeTag(Tag tag) { writeln(tag); with(tag.entity) if(auto intVal = peek!int()) { writeln(" Contains int: ", *intVal); // Arithmetic is supported too writeln(" + 3: ", tag.entity + 3); writeln(" * 2: ", tag.entity * 2); } else if(auto hugeVal = peek!Huge()) // Don't use *hugeVal for now, there is a bug in peek writeln(" Contains Huge struct: ", tag.entity.get!Huge()); else if(auto classInfo = cast(TypeInfo_Class)type) writefln(" Contains class %s: %s", classInfo.name, get!Object()); else if(auto structInfo = cast(TypeInfo_Struct)type) writefln(" Contains struct %s: %s", structInfo.name, tag.entity); // else if etc. } void main() { writeTag(Tag("tag1", Variant(12))); writeTag(Tag("tag2", Variant("str"))); writeTag(Tag("tag3", Variant(["str1", "str2"]))); writeTag(Tag("tag4", Variant(new C(17)))); writeTag(Tag("tag4", Variant(SmallStruct(3)))); // Variant isn't enough to hold Huge so a copy // will be accocated in GC heap. // Yes, this isn't documented yet and `peek` will give you garbage // for this case because of a bug. writeTag(Tag("tag4", Variant(Huge(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7)))); } --- std.variant has some bugs for now but is usable: http://d.puremagic.com/issues/buglist.cgi?query_format=advanced&short_desc=variant&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&short_desc_type=allwords Templates are usable in other cases, not this. -- Денис В. Шеломовский Denis V. Shelomovskij
Apr 16 2012
prev sibling next sibling parent "Xan" <xancorreu gmail.com> writes:
On Saturday, 14 April 2012 at 19:40:06 UTC, Aleksandar Ružičić 
wrote:
 On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote:
 Hi,

 I try to translate a script I wrote in Fantom 
 [www.fantom.org]. In my script, I have a type "Tag" defined as 
 a triple of:
 - String (the name of the tag),
 - Type (the type of the tag: could be Str, Date, Int, etc.)
 - Obj (the value of the tag; Fantom has Objects of Top-Class 
 hierachy).

 (normally the tag has Type = Obj.Type, but you can manually 
 set).

 For example,
 you could have:
 (name, Str#, "John")

 or

 (date, Date#, 2011-09-02)


 (# is the Fantom way for specifying type: Str# is the sys::Str 
 type)


 Is there any way for emulating this? My main trouble is how to 
 define Type and Object in D.

 Thanks in advance,
 Xan.

 PS: Please, be patient, I'm a newbee.

For "Type" look at enum (http://dlang.org/enum.html) and for "Object" look at std.variant (http://dlang.org/phobos/std_variant.html). And since Variant can tell you what type it contains you might no longer need that "Type" parameter.

I think it's not what I expect. Can I have a generic object type? Something like an assigment like: Any a ? With templates? Please, guide me. I'm a newbee
Apr 14 2012
prev sibling next sibling parent "Xan" <xancorreu gmail.com> writes:
Uf!, it's more than I can process....
It's really a **complicated** thing to do that in D.

On Monday, 16 April 2012 at 07:50:28 UTC, Denis Shelomovskij
wrote:
 15.04.2012 0:31, Xan написал:
 On Saturday, 14 April 2012 at 19:40:06 UTC, Aleksandar 
 Ružičić wrote:
 On Saturday, 14 April 2012 at 19:17:52 UTC, Xan wrote:
 Hi,

 I try to translate a script I wrote in Fantom 
 [www.fantom.org]. In my
 script, I have a type "Tag" defined as a triple of:
 - String (the name of the tag),
 - Type (the type of the tag: could be Str, Date, Int, etc.)
 - Obj (the value of the tag; Fantom has Objects of Top-Class 
 hierachy).

 (normally the tag has Type = Obj.Type, but you can manually 
 set).

 For example,
 you could have:
 (name, Str#, "John")

 or

 (date, Date#, 2011-09-02)


 (# is the Fantom way for specifying type: Str# is the 
 sys::Str type)


 Is there any way for emulating this? My main trouble is how 
 to define
 Type and Object in D.

 Thanks in advance,
 Xan.

 PS: Please, be patient, I'm a newbee.

For "Type" look at enum (http://dlang.org/enum.html) and for "Object" look at std.variant (http://dlang.org/phobos/std_variant.html). And since Variant can tell you what type it contains you might no longer need that "Type" parameter.

I think it's not what I expect. Can I have a generic object type? Something like an assigment like: Any a ? With templates? Please, guide me. I'm a newbee

What you are looking for is a boxing. http://en.wikipedia.org/wiki/Boxing_(computer_science)#Boxing D doesn't support auto boxing/unboxing. For a reason see, e.g. this thread: http://forum.dlang.org/thread/ckoaum$1lbg$1 digitaldaemon.com http://forum.dlang.org/thread/cr7njl$18j3$1 digitaldaemon.com There was std.boxer module, but it was deprecated and removed, this is the last version before removal: https://github.com/D-Programming-Language/phobos/blob/c20d454d63861a0c4bab647b37c01b0dd981a3f8/std/boxer.d std.variant is really what you are looking for. See example: --- import std.stdio; import std.variant; import std.string: format; struct Tag { string name; Variant entity; } class C { int i; this(int i) { this.i = i; } string toString() { return format("C(i: %s)", i); } } struct SmallStruct { int a; } struct Huge { real a, b, c, d, e, f, g; } void writeTag(Tag tag) { writeln(tag); with(tag.entity) if(auto intVal = peek!int()) { writeln(" Contains int: ", *intVal); // Arithmetic is supported too writeln(" + 3: ", tag.entity + 3); writeln(" * 2: ", tag.entity * 2); } else if(auto hugeVal = peek!Huge()) // Don't use *hugeVal for now, there is a bug in peek writeln(" Contains Huge struct: ", tag.entity.get!Huge()); else if(auto classInfo = cast(TypeInfo_Class)type) writefln(" Contains class %s: %s", classInfo.name, get!Object()); else if(auto structInfo = cast(TypeInfo_Struct)type) writefln(" Contains struct %s: %s", structInfo.name, tag.entity); // else if etc. } void main() { writeTag(Tag("tag1", Variant(12))); writeTag(Tag("tag2", Variant("str"))); writeTag(Tag("tag3", Variant(["str1", "str2"]))); writeTag(Tag("tag4", Variant(new C(17)))); writeTag(Tag("tag4", Variant(SmallStruct(3)))); // Variant isn't enough to hold Huge so a copy // will be accocated in GC heap. // Yes, this isn't documented yet and `peek` will give you garbage // for this case because of a bug. writeTag(Tag("tag4", Variant(Huge(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7)))); } --- std.variant has some bugs for now but is usable: http://d.puremagic.com/issues/buglist.cgi?query_format=advanced&short_desc=variant&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&short_desc_type=allwords Templates are usable in other cases, not this.

Apr 16 2012
prev sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Mon, 16 Apr 2012 20:52:16 +0200
schrieb "Xan" <xancorreu gmail.com>:

 Uf!, it's more than I can process....
 It's really a **complicated** thing to do that in D.

Too much information, yes. Too complicated no. :) D is statically typed (Fantom allows both static and dynamic typing). That means that for every variable in your program you know beforehand what type it is. You say you have String, Type and Obj. Here we cannot say what type Obj is, because it depends on what Type says. Now you want something from a statically typed language, that it wasn't designed for. You may want to adapt to the style of a statically typed language and use a struct: import std.datetime; struct Person { string name; // a person has a field 'name' of type string Date date; } This means that you cannot change the type of 'date' or 'name', and you cannot have a person without a date. If you really, *really*, REALLY need the full flexibility, you can use Variants. You can store any data in a Variant, so it would replace Type and Obj in your code. struct Tag { string description; // <String>: store "name", "date", etc. in this Variant data; // <Type & Obj>: store "John" or Date(2012, 4, 25) in this } Many more solutions are possible, but we'd need to take a look at your code. Also one solution may be more flexible while another is faster. It depends a bit on what you expect. Every language has its pros and cons. Dynamic typing is not one of D's strengths, but execution speed is, for example. -- Marco
Apr 25 2012