Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
April 14, 2012 A "general" tag | ||||
---|---|---|---|---|
| ||||
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. |
April 14, 2012 Re: A "general" tag | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xan | 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. |
April 14, 2012 Re: A "general" tag | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aleksandar Ružičić | 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
|
April 16, 2012 Re: A "general" tag | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xan | 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 |
April 16, 2012 Re: A "general" tag | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis Shelomovskij | 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.
|
April 25, 2012 Re: A "general" tag | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xan | 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 |
Copyright © 1999-2021 by the D Language Foundation