March 10, 2005
That's what I wanted, and proposed some days ago. The code I've manually provided is what I hope would be built in to the compiler. It's efficient - I bet more efficient than any based on AAs, esp. given the value==index optimisation - and does not do any runtime allocation. If the compiler simply did that for us - with expanded syntax for the strings (or string ids!!) - I think it'd be great.

"Kris" <Kris_member@pathlink.com> wrote in message news:d0op0e$1bnh$1@digitaldaemon.com...
> Why not push to get the enum-names exposed via reflection instead? I
> wouldn't
> wish to have to re-type them all over again, in a different manner.
> Doesn't make
> sense.
>
> - Kris
>
>
>
> In article <d0onfb$1afp$1@digitaldaemon.com>, Andrew Fedoniouk says...
>>
>>Thanks a lot,
>>
>>What about this:
>>
>>enum E {
>>  ZERO,
>>  ONE,
>>  TWO
>>}
>>
>>char[] toString(E e)
>>{
>>  static char[][] map =
>>  [
>>    E.ZERO  :"primordial",
>>    E.ONE   :"first",
>>    E.TWO   :"second"
>>  ];
>>  return map[e];
>>}
>>
>>for simple continuous enums?
>>
>>Anyway enums which are sets of bits (0x01,0x02, 0x04...) in fact
>>need different toString implementation (string composition)
>>
>>Andrew.
>>
>>
>>
>>
>>"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0omiq$19o7$1@digitaldaemon.com...
>>> No worries
>>>
>>> "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d0ollq$17ud$1@digitaldaemon.com...
>>>> Matthew, could you attach this as  d source file?
>>>> Beg my pardon, but it is hardly readable.
>>>>
>>>> Thanks in advance,
>>>>
>>>> Andrew Fedoniouk.
>>>>
>>>>
>>>> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0oiuc$13r3$1@digitaldaemon.com...
>>>>> Just thought I'd share what I came up with for the enum => string
>>>>> stuff,
>>>>> which is currently resident in std/openrj.d. If it receives a +ve
>>>>> reaction
>>>>> we can move it into somewhere common, and use it for all enums.
>>>>> (That's
>>>>> assuming, of course, we don't get something in the language to do
>>>>> it for
>>>>> us.)
>>>>>
>>>>> Let me know what you think.
>>>>>
>>>>>    private struct EnumString
>>>>>    {
>>>>>        int     value;
>>>>>        char[]  str;
>>>>>    };
>>>>>
>>>>>    private template enum_to_string(T)
>>>>>    {
>>>>>        char[] enum_to_string(EnumString[] strings, T t)
>>>>>        {
>>>>>            // 'Optimised' search.
>>>>>            //
>>>>>            // Since many enums start at 0 and are contiguously
>>>>> ordered,
>>>>> it's quite
>>>>>            // likely that the value will equal the index. If it
>>>>> does, we
>>>>> can just
>>>>>            // return the string from that index.
>>>>>            int index   =   cast(int)(t);
>>>>>
>>>>>            if( index >= 0 &&
>>>>>                index < strings.length &&
>>>>>                strings[index].value == index)
>>>>>            {
>>>>>                return strings[index].str;
>>>>>            }
>>>>>
>>>>>            // Otherwise, just do a linear search
>>>>>            foreach(EnumString s; strings)
>>>>>            {
>>>>>                if(cast(int)(t) == s.value)
>>>>>                {
>>>>>                    return s.str;
>>>>>                }
>>>>>            }
>>>>>
>>>>>            return "<unknown>";
>>>>>        }
>>>>>    }
>>>>>
>>>>>    /*
>>>>> /////////////////////////////////////////////////////////////////////////////
>>>>>     * Enumerations
>>>>>     */
>>>>>
>>>>>    /** Flags that moderate the creation of Databases */
>>>>>    public enum ORJ_FLAG
>>>>>    {
>>>>>            ORDER_FIELDS                    =   0x0001  /*!<
>>>>> Arranges the
>>>>> fields in alphabetical order                  */
>>>>>        ,   ELIDE_BLANK_RECORDS             =   0x0002  /*!< Causes
>>>>> blank
>>>>> records to be ignored                         */
>>>>>    }
>>>>>
>>>>>    public char[] toString(ORJ_FLAG f)
>>>>>    {
>>>>>        const EnumString    strings[] =
>>>>>        [
>>>>>                {   ORJ_FLAG.ORDER_FIELDS,           "Arranges the
>>>>> fields
>>>>> in alphabetical order" }
>>>>>            ,   {   ORJ_FLAG.ELIDE_BLANK_RECORDS,    "Causes blank
>>>>> records
>>>>> to be ignored"        }
>>>>>        ];
>>>>>
>>>>>        return enum_to_string!(ORJ_FLAG)(strings, f);
>>>>>    }
>>>>>
>>>>>    /** General error codes */
>>>>>    public enum ORJRC
>>>>>    {
>>>>>            SUCCESS                      =   0          /*!<
>>>>> Operation
>>>>> was
>>>>> successful                                   */
>>>>>        ,   CANNOT_OPEN_JAR_FILE                        /*!< The
>>>>> given
>>>>> file
>>>>> does not exist, or cannot be accessed       */
>>>>>        ,   NO_RECORDS                                  /*!< The
>>>>> database
>>>>> file contained no records                     */
>>>>>        ,   OUT_OF_MEMORY                               /*!< The
>>>>> API
>>>>> suffered memory exhaustion                         */
>>>>>        ,   BAD_FILE_READ                               /*!< A read
>>>>> operation failed                                    */
>>>>>        ,   PARSE_ERROR                                 /*!<
>>>>> Parsing of
>>>>> the
>>>>> database file failed due to a syntax error  */
>>>>>        ,   INVALID_INDEX                               /*!< An
>>>>> invalid
>>>>> index was specified                             */
>>>>>        ,   UNEXPECTED                                  /*!< An
>>>>> unexpected
>>>>> condition was encountered                    */
>>>>>        ,   INVALID_CONTENT                             /*!< The
>>>>> database
>>>>> file contained invalid content                */
>>>>>    }
>>>>>
>>>>>    public char[] toString(ORJRC f)
>>>>>    {
>>>>>        const EnumString    strings[] =
>>>>>        [
>>>>>                {   ORJRC.SUCCESS,              "Operation was
>>>>>             }
>>>>>            ,   {   ORJRC.CANNOT_OPEN_JAR_FILE, "The given file
>>>>> does not
>>>>> exist, or cannot be accessed"          }
>>>>>            ,   {   ORJRC.NO_RECORDS,           "The database file
>>>>> contained no records"                        }
>>>>>            ,   {   ORJRC.OUT_OF_MEMORY,        "The API suffered
>>>>> memory
>>>>> exhaustion"                            }
>>>>>            ,   {   ORJRC.BAD_FILE_READ,        "A read operation
>>>>>         }
>>>>>            ,   {   ORJRC.PARSE_ERROR,          "Parsing of the
>>>>> database
>>>>> file failed due to a syntax error"     }
>>>>>            ,   {   ORJRC.INVALID_INDEX,        "An invalid index
>>>>> was
>>>>> specified"                                }
>>>>>            ,   {   ORJRC.UNEXPECTED,           "An unexpected
>>>>> condition
>>>>> was encountered"                       }
>>>>>            ,   {   ORJRC.INVALID_CONTENT,      "The database file
>>>>> contained invalid content"                   }
>>>>>        ];
>>>>>
>>>>>        return enum_to_string!(ORJRC)(strings, f);
>>>>>    }
>>>>>
>>>>>    /** Parsing error codes */
>>>>>    public enum ORJ_PARSE_ERROR
>>>>>    {
>>>>>            SUCCESS                         =   0       /*!<
>>>>> Parsing was
>>>>> successful
>>>>> */
>>>>>        ,   RECORD_SEPARATOR_IN_CONTINUATION            /*!< A
>>>>> record
>>>>> separator was encountered during a content line continuation */
>>>>>        ,   UNFINISHED_LINE                             /*!< The
>>>>> last
>>>>> line
>>>>> in the database was not terminated by a line-feed
>>>>> */
>>>>>        ,   UNFINISHED_FIELD                            /*!< The
>>>>> last
>>>>> field
>>>>> in the database file was not terminated by a record separator   */
>>>>>        ,   UNFINISHED_RECORD                           /*!< The
>>>>> last
>>>>> record in the database file was not terminated by a record
>>>>> separator */
>>>>>    }
>>>>>
>>>>>    public char[] toString(ORJ_PARSE_ERROR f)
>>>>>    {
>>>>>        const EnumString    strings[] =
>>>>>        [
>>>>>                {   ORJ_PARSE_ERROR.SUCCESS, "Parsing was }
>>>>>            ,   {
>>>>> ORJ_PARSE_ERROR.RECORD_SEPARATOR_IN_CONTINUATION, "A
>>>>> record separator was encountered during a content line }
>>>>>            ,   {   ORJ_PARSE_ERROR.UNFINISHED_LINE, "The last line
>>>>> in
>>>>> the
>>>>> database was not terminated by a }
>>>>>            ,   {   ORJ_PARSE_ERROR.UNFINISHED_FIELD, "The last
>>>>> field in
>>>>> the database file was not terminated by a record separator"  }
>>>>>            ,   {   ORJ_PARSE_ERROR.UNFINISHED_RECORD, "The last
>>>>> record
>>>>> in
>>>>> the database file was not terminated by a record separator" }
>>>>>        ];
>>>>>
>>>>>        return enum_to_string!(ORJ_PARSE_ERROR)(strings, f);
>>>>>    }
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>>
>
> 


March 10, 2005
Maybe D should have enums that are Java-like. See
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

Jason

Matthew wrote:
> Just thought I'd share what I came up with for the enum => string stuff, which is currently resident in std/openrj.d. If it receives a +ve reaction we can move it into somewhere common, and use it for all enums. (That's assuming, of course, we don't get something in the language to do it for us.)
> 
March 10, 2005
Jason Mills wrote:

> Maybe D should have enums that are Java-like. See
> http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

You mean classes ? But if strings and arrays are not classes in D,
then why should enumerations be ? Heck, sometimes not even classes
are classes in D (!) - but just structs, for performance reasons ?

I think this could be solved with better TypeInfo and some props...
Like http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/12594
(from the http://www.prowiki.org/wiki4d/wiki.cgi?FeatureRequestList)

--anders
March 10, 2005
In article <d0ossh$1f4t$1@digitaldaemon.com>, Andrew Fedoniouk says...
>
>Ideally these Enum strings should come in different languages. Right? So reflection will not help you here.
>
>Reflection might help in other places but not too much.
>I can see only couple areas where it may help:
>persistent storages/OODB, and SOAP alike use cases.
>Does anybody know other areas where reflection is desirable?

AFAIK: the goal of getting an enum's name is really just a form of a "lexical cast"; something that isn't typically more than just raw reflection.  I think the notion here is "locale be damned" and just give up the name of the constant used in the source.

As you mentioned, generic persistence via reflection would be a welcome addition.  SOAP, RPC, CORBA (et al.) and DLL interop can all benefit hugely from reflection, and is by no means a fringe use of the technology.  D could easily be a business language of choice if you had runtime-generated transparent proxies like .NET.

As for other areas?  A (future) D-specific debugger could make very good use of deeper reflection information.  Also, generic programming could benefit greatly from richer runtime (and compile time!) type information.

Outside that, it really just lends to the language's flexibility overall which can only help its adoption rate.  We really don't want "D.Boost" when we can have all of its capability built-into the D/phobos itself.

- EricAnderton at yahoo
March 10, 2005
Hey Andrew;

I figured Matthew was using these enum-names for a non-i18n application only ~ once you start getting into locale-specifics, there's a whole lot more to consider (as I'm sure you know) and the strings themselves would very likely be externalized in one manner or another: making this topic somewhat moot?

Of course, this is probably now way-off topic; so I'll mention the ICU tools/APIs once again (WRT this domain) and then shuttup ...

- Kris


Andrew Fedoniouk wrote:
> Hi, Kris,
> 
> Ideally these Enum strings should come in different
> languages. Right? So reflection will not help you here.
> 
> Reflection might help in other places but not too much.
> I can see only couple areas where it may help:
> persistent storages/OODB, and SOAP alike use cases.
> Does anybody know other areas where reflection is desirable?
> 
> Andrew.
> 
> 
> 
> "Kris" <Kris_member@pathlink.com> wrote in message news:d0op0e$1bnh$1@digitaldaemon.com...
> 
>>Why not push to get the enum-names exposed via reflection instead? I wouldn't
>>wish to have to re-type them all over again, in a different manner. Doesn't make
>>sense.
>>
>>- Kris
>>
>>
>>
>>In article <d0onfb$1afp$1@digitaldaemon.com>, Andrew Fedoniouk says...
>>
>>>Thanks a lot,
>>>
>>>What about this:
>>>
>>>enum E {
>>> ZERO,
>>> ONE,
>>> TWO
>>>}
>>>
>>>char[] toString(E e)
>>>{
>>> static char[][] map =
>>> [
>>>   E.ZERO  :"primordial",
>>>   E.ONE   :"first",
>>>   E.TWO   :"second"
>>> ];
>>> return map[e];
>>>}
>>>
>>>for simple continuous enums?
>>>
>>>Anyway enums which are sets of bits (0x01,0x02, 0x04...) in fact
>>>need different toString implementation (string composition)
>>>
>>>Andrew.
>>>
>>>
>>>
>>>
>>>"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message
>>>news:d0omiq$19o7$1@digitaldaemon.com...
>>>
>>>>No worries
>>>>
>>>>"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message
>>>>news:d0ollq$17ud$1@digitaldaemon.com...
>>>>
>>>>>Matthew, could you attach this as  d source file?
>>>>>Beg my pardon, but it is hardly readable.
>>>>>
>>>>>Thanks in advance,
>>>>>
>>>>>Andrew Fedoniouk.
>>>>>
>>>>>
>>>>>"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message
>>>>>news:d0oiuc$13r3$1@digitaldaemon.com...
>>>>>
>>>>>>Just thought I'd share what I came up with for the enum => string stuff,
>>>>>>which is currently resident in std/openrj.d. If it receives a +ve
>>>>>>reaction
>>>>>>we can move it into somewhere common, and use it for all enums. (That's
>>>>>>assuming, of course, we don't get something in the language to do it for
>>>>>>us.)
>>>>>>
>>>>>>Let me know what you think.
>>>>>>
>>>>>>   private struct EnumString
>>>>>>   {
>>>>>>       int     value;
>>>>>>       char[]  str;
>>>>>>   };
>>>>>>
>>>>>>   private template enum_to_string(T)
>>>>>>   {
>>>>>>       char[] enum_to_string(EnumString[] strings, T t)
>>>>>>       {
>>>>>>           // 'Optimised' search.
>>>>>>           //
>>>>>>           // Since many enums start at 0 and are contiguously 
>>>>>>ordered,
>>>>>>it's quite
>>>>>>           // likely that the value will equal the index. If it does, 
>>>>>>we
>>>>>>can just
>>>>>>           // return the string from that index.
>>>>>>           int index   =   cast(int)(t);
>>>>>>
>>>>>>           if( index >= 0 &&
>>>>>>               index < strings.length &&
>>>>>>               strings[index].value == index)
>>>>>>           {
>>>>>>               return strings[index].str;
>>>>>>           }
>>>>>>
>>>>>>           // Otherwise, just do a linear search
>>>>>>           foreach(EnumString s; strings)
>>>>>>           {
>>>>>>               if(cast(int)(t) == s.value)
>>>>>>               {
>>>>>>                   return s.str;
>>>>>>               }
>>>>>>           }
>>>>>>
>>>>>>           return "<unknown>";
>>>>>>       }
>>>>>>   }
>>>>>>
>>>>>>   /*
>>>>>>/////////////////////////////////////////////////////////////////////////////
>>>>>>    * Enumerations
>>>>>>    */
>>>>>>
>>>>>>   /** Flags that moderate the creation of Databases */
>>>>>>   public enum ORJ_FLAG
>>>>>>   {
>>>>>>           ORDER_FIELDS                    =   0x0001  /*!< Arranges 
>>>>>>the
>>>>>>fields in alphabetical order                  */
>>>>>>       ,   ELIDE_BLANK_RECORDS             =   0x0002  /*!< Causes 
>>>>>>blank
>>>>>>records to be ignored                         */
>>>>>>   }
>>>>>>
>>>>>>   public char[] toString(ORJ_FLAG f)
>>>>>>   {
>>>>>>       const EnumString    strings[] =
>>>>>>       [
>>>>>>               {   ORJ_FLAG.ORDER_FIELDS,           "Arranges the 
>>>>>>fields
>>>>>>in alphabetical order" }
>>>>>>           ,   {   ORJ_FLAG.ELIDE_BLANK_RECORDS,    "Causes blank
>>>>>>records
>>>>>>to be ignored"        }
>>>>>>       ];
>>>>>>
>>>>>>       return enum_to_string!(ORJ_FLAG)(strings, f);
>>>>>>   }
>>>>>>
>>>>>>   /** General error codes */
>>>>>>   public enum ORJRC
>>>>>>   {
>>>>>>           SUCCESS                      =   0          /*!< Operation
>>>>>>was
>>>>>>successful                                   */
>>>>>>       ,   CANNOT_OPEN_JAR_FILE                        /*!< The given
>>>>>>file
>>>>>>does not exist, or cannot be accessed       */
>>>>>>       ,   NO_RECORDS                                  /*!< The 
>>>>>>database
>>>>>>file contained no records                     */
>>>>>>       ,   OUT_OF_MEMORY                               /*!< The API
>>>>>>suffered memory exhaustion                         */
>>>>>>       ,   BAD_FILE_READ                               /*!< A read
>>>>>>operation failed                                    */
>>>>>>       ,   PARSE_ERROR                                 /*!< Parsing of
>>>>>>the
>>>>>>database file failed due to a syntax error  */
>>>>>>       ,   INVALID_INDEX                               /*!< An invalid
>>>>>>index was specified                             */
>>>>>>       ,   UNEXPECTED                                  /*!< An
>>>>>>unexpected
>>>>>>condition was encountered                    */
>>>>>>       ,   INVALID_CONTENT                             /*!< The 
>>>>>>database
>>>>>>file contained invalid content                */
>>>>>>   }
>>>>>>
>>>>>>   public char[] toString(ORJRC f)
>>>>>>   {
>>>>>>       const EnumString    strings[] =
>>>>>>       [
>>>>>>               {   ORJRC.SUCCESS,              "Operation was
>>>>>>            }
>>>>>>           ,   {   ORJRC.CANNOT_OPEN_JAR_FILE, "The given file does 
>>>>>>not
>>>>>>exist, or cannot be accessed"          }
>>>>>>           ,   {   ORJRC.NO_RECORDS,           "The database file
>>>>>>contained no records"                        }
>>>>>>           ,   {   ORJRC.OUT_OF_MEMORY,        "The API suffered 
>>>>>>memory
>>>>>>exhaustion"                            }
>>>>>>           ,   {   ORJRC.BAD_FILE_READ,        "A read operation
>>>>>>        }
>>>>>>           ,   {   ORJRC.PARSE_ERROR,          "Parsing of the 
>>>>>>database
>>>>>>file failed due to a syntax error"     }
>>>>>>           ,   {   ORJRC.INVALID_INDEX,        "An invalid index was
>>>>>>specified"                                }
>>>>>>           ,   {   ORJRC.UNEXPECTED,           "An unexpected 
>>>>>>condition
>>>>>>was encountered"                       }
>>>>>>           ,   {   ORJRC.INVALID_CONTENT,      "The database file
>>>>>>contained invalid content"                   }
>>>>>>       ];
>>>>>>
>>>>>>       return enum_to_string!(ORJRC)(strings, f);
>>>>>>   }
>>>>>>
>>>>>>   /** Parsing error codes */
>>>>>>   public enum ORJ_PARSE_ERROR
>>>>>>   {
>>>>>>           SUCCESS                         =   0       /*!< Parsing 
>>>>>>was
>>>>>>successful                                                         */
>>>>>>       ,   RECORD_SEPARATOR_IN_CONTINUATION            /*!< A record
>>>>>>separator was encountered during a content line continuation */
>>>>>>       ,   UNFINISHED_LINE                             /*!< The last
>>>>>>line
>>>>>>in the database was not terminated by a line-feed                */
>>>>>>       ,   UNFINISHED_FIELD                            /*!< The last
>>>>>>field
>>>>>>in the database file was not terminated by a record separator   */
>>>>>>       ,   UNFINISHED_RECORD                           /*!< The last
>>>>>>record in the database file was not terminated by a record separator */
>>>>>>   }
>>>>>>
>>>>>>   public char[] toString(ORJ_PARSE_ERROR f)
>>>>>>   {
>>>>>>       const EnumString    strings[] =
>>>>>>       [
>>>>>>               {   ORJ_PARSE_ERROR.SUCCESS, "Parsing was }
>>>>>>           ,   {   ORJ_PARSE_ERROR.RECORD_SEPARATOR_IN_CONTINUATION, 
>>>>>>"A
>>>>>>record separator was encountered during a content line }
>>>>>>           ,   {   ORJ_PARSE_ERROR.UNFINISHED_LINE, "The last line in
>>>>>>the
>>>>>>database was not terminated by a }
>>>>>>           ,   {   ORJ_PARSE_ERROR.UNFINISHED_FIELD, "The last field 
>>>>>>in
>>>>>>the database file was not terminated by a record separator"  }
>>>>>>           ,   {   ORJ_PARSE_ERROR.UNFINISHED_RECORD, "The last record
>>>>>>in
>>>>>>the database file was not terminated by a record separator" }
>>>>>>       ];
>>>>>>
>>>>>>       return enum_to_string!(ORJ_PARSE_ERROR)(strings, f);
>>>>>>   }
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
> 
> 
March 10, 2005
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0p18e$1l2q$1@digitaldaemon.com...
>
> "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d0oodt$1ba0$1@digitaldaemon.com...
>> enum E {
>>  FIRST = 0x01,
>>  SECOND =  0x02 ,
>>  THIRD =  0x04
>> }
>>
>> alias char[] string8;
>>
>> string8 toString(E e)
>> {
>>  static string8[int] map; if(!map.length)
>>  {
>>    map[E.FIRST] = "first";
>>    map[E.SECOND]  = "second";
>>    map[E.THIRD] = "third one";
>>  }
>>  return map[e];
>> }
>>
>> Huh?
>
> It's going to use more memory, though it's only a bit.
>
> It allocates memory at runtime, with the consequent, though unlikely, possibility of being out of memory

Yes, it is. See below.

>
> It's going to run slower, though it's only a bit. Linear searches are generally more efficient for small data sets, which most enums are.
>

Well, it depends on implementation of assoc. map in D.
It could be an adaptive hash map which is
either simple list if number of items is less than threshold
and a real hasmap otherwise.

But in D as far as I can see assosiative arrays made as
lookup binary trees. So they are not so much expensive
for small sets - but not so effective on big sets -
reasonable compromise for built-ins.

For small sets D's AA is close to linear search,

> It doesn't optimise for the common case where an enum value is equal to its index.

Yes, but I've provided another implementation for "consequent" enums.

>
> It doesn't handle the case where the value is unrecognised, though that could be added by using some horrible 'in' construction.

Life is life.

>
> All these are small matters, to be sure, but are persuasive, at least to me.
>
> Please note: the solution I gave is what I would hope would become built-in. In that case it's only drawback, its verbosity, would be moot.

Built-in.... Do you mean they will be implemented inside D compiler/runtime
by default?
If yes this is absolutely another case.

1) I don't want *all* enums to be "stringizeable" this way.
2) I would like to be able to define different string sets for different
locales for the same enum.

For me personally it would be enough to have hash map static initializers -
static hash maps.
They can be implenmented using (Minimal) Perfect Hash similar to what
gnu::gperf.exe
does - this is not the must but desirable.

int[char[]] m = { "one":1, "two":2 }
char[][int] m = { 1:"one", 2: "two" }













March 10, 2005
> Embedded Scripting, I'd imagine.

I would agree if your Script will share same basic constructions with D: types, classes, arrays, etc.

Anyway it is extremely bad design to allow to script
"to see private parts" of host implementation.
So you will create an isolation layer. Which will be anyway sort of
IDispatch with VARIANT or the like with function table like:

delegate value (uint argn, value[] argv) functbl[symbol_t];

Andrew Fedoniouk.
http://terrainformatica.com




"Paul Bonser" <misterpib@gmail.com> wrote in message news:d0p15l$1l13$1@digitaldaemon.com...
>
>> Does anybody know other areas where reflection is desirable?
>
>
> Embedded Scripting, I'd imagine.
>
> I'm working on a game engine (in D, of course) and I'm going to want to embed a scripting language of some sort into it (haven't decided what to use yet, but I really want something that is bytecode-compiled...but that's another topic). It would be really handy to be able to call any function (and access any variable) I wanted from a script, without having to manually add a hook for each function I wanted to call or variable I wanted to access. Just add a couple of functions that look up the name you gave, call it if it's there, give an error if it isn't. It would make the scripting language better integrated into the program, without all the extra coding of doing it manually.
>
> Also, I'd like to be able to pop up a scripting console in-game (for when I'm developing it, at least..) and instantiate objects of various types and call functions wilily-nilly, as well as modifying objects and such that already exist. (again, without having to manually tell the scripting language about each and every data type that's out there.)
>
> Oh it would make me so happy to be able to do that.
>
> I believe it is also good for debugging and adding class-browsers and did I mention scripting? :P
>
> So I guess until reflection is made part of the language (or something) I'll have to just do a "sorta" reflection by making every class a subclass of a Reflection class and have to keep an associative array of all the function names and variable names with delegates and pointers and...blah, that's what I want to not have to do :(
>
> -- 
> -PIB
>
> --
> "C++ also supports the notion of *friends*: cooperative classes that are permitted to see each other's private parts." - Grady Booch


March 10, 2005
> Built-in.... Do you mean they will be implemented inside D
> compiler/runtime by default?
> If yes this is absolutely another case.

That's what I'd like, as a default

> 1) I don't want *all* enums to be "stringizeable" this way.

That'd be easy. Just don't provide any strings! :-)

> 2) I would like to be able to define different string sets for different locales for the same enum.

Agreed. The only way it'd be 'default' would be if one provided strings within the definition, as in:


enum E1
{
        val1 : "This represents something"
    ,   val2 : "This represents something else"
}

enum E2
{
        val3
    ,    val4
}

enum E3
{
        val5
    ,    val6
}

char[] toString(E3 e);    // Your localisation-aware implementation

E1    e1    =    E1.val1;
E2    e2    =    E2.val4;
E3    e3    =    E3.val5;

char[] s1 = toString(e1);    // This would use the compiler generated
version, with the same impl as I've provided explicitly
char[] s2 = toString(e2);    // This would be a compilation error, since
E2 does not have one provided
char[] s3 = toString(e3);    // Calls the explicitly provided function


> For me personally it would be enough to have hash map static
> initializers - static hash maps.
> They can be implenmented using (Minimal) Perfect Hash similar to what
> gnu::gperf.exe
> does - this is not the must but desirable.
>
> int[char[]] m = { "one":1, "two":2 }
> char[][int] m = { 1:"one", 2: "two" }

I think that's a separate issue, but I agree we should be able to have them



March 10, 2005
It's that, in Open-RJ, two of the three enums are error codes. In the C library there's a static array of structs mapping the value to a string.

This is a really common idiom, but painfully verbose and also very fragile - it's all too easy to get the Doxygen doc strings out of step with the string literals used in the translation - so I figured that D might address this. I still feel that that's worthwhile. (Note: in C, one can keep it all in the DRY SPOT by using macros, which we, er, cannot do in D. <g>)

Of course, this does not address localisation, and I don't suggest it does. It's just a safer shortcut for what we do now anyway.

I've been thinking that rather than strings we might also associate string identifiers, which would be hooked into the i18n framework that, as yet, does not exist. ;)


"kris" <fu@bar.org> wrote in message news:d0ps0h$2fbt$1@digitaldaemon.com...
> Hey Andrew;
>
> I figured Matthew was using these enum-names for a non-i18n application only ~ once you start getting into locale-specifics, there's a whole lot more to consider (as I'm sure you know) and the strings themselves would very likely be externalized in one manner or another: making this topic somewhat moot?
>
> Of course, this is probably now way-off topic; so I'll mention the ICU tools/APIs once again (WRT this domain) and then shuttup ...
>
> - Kris
>
>
> Andrew Fedoniouk wrote:
>> Hi, Kris,
>>
>> Ideally these Enum strings should come in different languages. Right? So reflection will not help you here.
>>
>> Reflection might help in other places but not too much.
>> I can see only couple areas where it may help:
>> persistent storages/OODB, and SOAP alike use cases.
>> Does anybody know other areas where reflection is desirable?
>>
>> Andrew.
>>
>>
>>
>> "Kris" <Kris_member@pathlink.com> wrote in message news:d0op0e$1bnh$1@digitaldaemon.com...
>>
>>>Why not push to get the enum-names exposed via reflection instead? I
>>>wouldn't
>>>wish to have to re-type them all over again, in a different manner.
>>>Doesn't make
>>>sense.
>>>
>>>- Kris
>>>
>>>
>>>
>>>In article <d0onfb$1afp$1@digitaldaemon.com>, Andrew Fedoniouk says...
>>>
>>>>Thanks a lot,
>>>>
>>>>What about this:
>>>>
>>>>enum E {
>>>> ZERO,
>>>> ONE,
>>>> TWO
>>>>}
>>>>
>>>>char[] toString(E e)
>>>>{
>>>> static char[][] map =
>>>> [
>>>>   E.ZERO  :"primordial",
>>>>   E.ONE   :"first",
>>>>   E.TWO   :"second"
>>>> ];
>>>> return map[e];
>>>>}
>>>>
>>>>for simple continuous enums?
>>>>
>>>>Anyway enums which are sets of bits (0x01,0x02, 0x04...) in fact
>>>>need different toString implementation (string composition)
>>>>
>>>>Andrew.
>>>>
>>>>
>>>>
>>>>
>>>>"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0omiq$19o7$1@digitaldaemon.com...
>>>>
>>>>>No worries
>>>>>
>>>>>"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:d0ollq$17ud$1@digitaldaemon.com...
>>>>>
>>>>>>Matthew, could you attach this as  d source file?
>>>>>>Beg my pardon, but it is hardly readable.
>>>>>>
>>>>>>Thanks in advance,
>>>>>>
>>>>>>Andrew Fedoniouk.
>>>>>>
>>>>>>
>>>>>>"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:d0oiuc$13r3$1@digitaldaemon.com...
>>>>>>
>>>>>>>Just thought I'd share what I came up with for the enum => string
>>>>>>>stuff,
>>>>>>>which is currently resident in std/openrj.d. If it receives a +ve
>>>>>>>reaction
>>>>>>>we can move it into somewhere common, and use it for all enums.
>>>>>>>(That's
>>>>>>>assuming, of course, we don't get something in the language to do
>>>>>>>it for
>>>>>>>us.)
>>>>>>>
>>>>>>>Let me know what you think.
>>>>>>>
>>>>>>>   private struct EnumString
>>>>>>>   {
>>>>>>>       int     value;
>>>>>>>       char[]  str;
>>>>>>>   };
>>>>>>>
>>>>>>>   private template enum_to_string(T)
>>>>>>>   {
>>>>>>>       char[] enum_to_string(EnumString[] strings, T t)
>>>>>>>       {
>>>>>>>           // 'Optimised' search.
>>>>>>>           //
>>>>>>>           // Since many enums start at 0 and are contiguously
>>>>>>> ordered,
>>>>>>>it's quite
>>>>>>>           // likely that the value will equal the index. If it
>>>>>>> does, we
>>>>>>>can just
>>>>>>>           // return the string from that index.
>>>>>>>           int index   =   cast(int)(t);
>>>>>>>
>>>>>>>           if( index >= 0 &&
>>>>>>>               index < strings.length &&
>>>>>>>               strings[index].value == index)
>>>>>>>           {
>>>>>>>               return strings[index].str;
>>>>>>>           }
>>>>>>>
>>>>>>>           // Otherwise, just do a linear search
>>>>>>>           foreach(EnumString s; strings)
>>>>>>>           {
>>>>>>>               if(cast(int)(t) == s.value)
>>>>>>>               {
>>>>>>>                   return s.str;
>>>>>>>               }
>>>>>>>           }
>>>>>>>
>>>>>>>           return "<unknown>";
>>>>>>>       }
>>>>>>>   }
>>>>>>>
>>>>>>>   /*
>>>>>>>/////////////////////////////////////////////////////////////////////////////
>>>>>>>    * Enumerations
>>>>>>>    */
>>>>>>>
>>>>>>>   /** Flags that moderate the creation of Databases */
>>>>>>>   public enum ORJ_FLAG
>>>>>>>   {
>>>>>>>           ORDER_FIELDS                    =   0x0001  /*!<
>>>>>>> Arranges the
>>>>>>>fields in alphabetical order                  */
>>>>>>>       ,   ELIDE_BLANK_RECORDS             =   0x0002  /*!<
>>>>>>> Causes blank
>>>>>>>records to be ignored                         */
>>>>>>>   }
>>>>>>>
>>>>>>>   public char[] toString(ORJ_FLAG f)
>>>>>>>   {
>>>>>>>       const EnumString    strings[] =
>>>>>>>       [
>>>>>>>               {   ORJ_FLAG.ORDER_FIELDS,           "Arranges the
>>>>>>> fields
>>>>>>>in alphabetical order" }
>>>>>>>           ,   {   ORJ_FLAG.ELIDE_BLANK_RECORDS,    "Causes blank
>>>>>>>records
>>>>>>>to be ignored"        }
>>>>>>>       ];
>>>>>>>
>>>>>>>       return enum_to_string!(ORJ_FLAG)(strings, f);
>>>>>>>   }
>>>>>>>
>>>>>>>   /** General error codes */
>>>>>>>   public enum ORJRC
>>>>>>>   {
>>>>>>>           SUCCESS                      =   0          /*!<
>>>>>>> Operation
>>>>>>>was
>>>>>>>successful                                   */
>>>>>>>       ,   CANNOT_OPEN_JAR_FILE                        /*!< The
>>>>>>> given
>>>>>>>file
>>>>>>>does not exist, or cannot be accessed       */
>>>>>>>       ,   NO_RECORDS                                  /*!< The
>>>>>>> database
>>>>>>>file contained no records                     */
>>>>>>>       ,   OUT_OF_MEMORY                               /*!< The
>>>>>>> API
>>>>>>>suffered memory exhaustion                         */
>>>>>>>       ,   BAD_FILE_READ                               /*!< A
>>>>>>> read
>>>>>>>operation failed                                    */
>>>>>>>       ,   PARSE_ERROR                                 /*!<
>>>>>>> Parsing of
>>>>>>>the
>>>>>>>database file failed due to a syntax error  */
>>>>>>>       ,   INVALID_INDEX                               /*!< An
>>>>>>> invalid
>>>>>>>index was specified                             */
>>>>>>>       ,   UNEXPECTED                                  /*!< An
>>>>>>>unexpected
>>>>>>>condition was encountered                    */
>>>>>>>       ,   INVALID_CONTENT                             /*!< The
>>>>>>> database
>>>>>>>file contained invalid content                */
>>>>>>>   }
>>>>>>>
>>>>>>>   public char[] toString(ORJRC f)
>>>>>>>   {
>>>>>>>       const EnumString    strings[] =
>>>>>>>       [
>>>>>>>               {   ORJRC.SUCCESS,              "Operation was
>>>>>>>            }
>>>>>>>           ,   {   ORJRC.CANNOT_OPEN_JAR_FILE, "The given file
>>>>>>> does not
>>>>>>>exist, or cannot be accessed"          }
>>>>>>>           ,   {   ORJRC.NO_RECORDS,           "The database file
>>>>>>>contained no records"                        }
>>>>>>>           ,   {   ORJRC.OUT_OF_MEMORY,        "The API suffered
>>>>>>> memory
>>>>>>>exhaustion"                            }
>>>>>>>           ,   {   ORJRC.BAD_FILE_READ,        "A read operation
>>>>>>>        }
>>>>>>>           ,   {   ORJRC.PARSE_ERROR,          "Parsing of the
>>>>>>> database
>>>>>>>file failed due to a syntax error"     }
>>>>>>>           ,   {   ORJRC.INVALID_INDEX,        "An invalid index
>>>>>>> was
>>>>>>>specified"                                }
>>>>>>>           ,   {   ORJRC.UNEXPECTED,           "An unexpected
>>>>>>> condition
>>>>>>>was encountered"                       }
>>>>>>>           ,   {   ORJRC.INVALID_CONTENT,      "The database file
>>>>>>>contained invalid content"                   }
>>>>>>>       ];
>>>>>>>
>>>>>>>       return enum_to_string!(ORJRC)(strings, f);
>>>>>>>   }
>>>>>>>
>>>>>>>   /** Parsing error codes */
>>>>>>>   public enum ORJ_PARSE_ERROR
>>>>>>>   {
>>>>>>>           SUCCESS                         =   0       /*!<
>>>>>>> Parsing was
>>>>>>>successful */
>>>>>>>       ,   RECORD_SEPARATOR_IN_CONTINUATION            /*!< A
>>>>>>> record
>>>>>>>separator was encountered during a content line continuation */
>>>>>>>       ,   UNFINISHED_LINE                             /*!< The
>>>>>>> last
>>>>>>>line
>>>>>>>in the database was not terminated by a line-feed
>>>>>>>*/
>>>>>>>       ,   UNFINISHED_FIELD                            /*!< The
>>>>>>> last
>>>>>>>field
>>>>>>>in the database file was not terminated by a record separator
>>>>>>>*/
>>>>>>>       ,   UNFINISHED_RECORD                           /*!< The
>>>>>>> last
>>>>>>>record in the database file was not terminated by a record separator */
>>>>>>>   }
>>>>>>>
>>>>>>>   public char[] toString(ORJ_PARSE_ERROR f)
>>>>>>>   {
>>>>>>>       const EnumString    strings[] =
>>>>>>>       [
>>>>>>>               {   ORJ_PARSE_ERROR.SUCCESS, "Parsing was }
>>>>>>>           ,   {
>>>>>>> ORJ_PARSE_ERROR.RECORD_SEPARATOR_IN_CONTINUATION, "A
>>>>>>>record separator was encountered during a content line }
>>>>>>>           ,   {   ORJ_PARSE_ERROR.UNFINISHED_LINE, "The last
>>>>>>> line in
>>>>>>>the
>>>>>>>database was not terminated by a }
>>>>>>>           ,   {   ORJ_PARSE_ERROR.UNFINISHED_FIELD, "The last
>>>>>>> field in
>>>>>>>the database file was not terminated by a record separator"  }
>>>>>>>           ,   {   ORJ_PARSE_ERROR.UNFINISHED_RECORD, "The last
>>>>>>> record
>>>>>>>in
>>>>>>>the database file was not terminated by a record separator" }
>>>>>>>       ];
>>>>>>>
>>>>>>>       return enum_to_string!(ORJ_PARSE_ERROR)(strings, f);
>>>>>>>   }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>> 

March 11, 2005
In article <d0qish$7hl$1@digitaldaemon.com>, Matthew says...
>
>It's that, in Open-RJ, two of the three enums are error codes. In the C library there's a static array of structs mapping the value to a string.
>
>This is a really common idiom, but painfully verbose and also very fragile - it's all too easy to get the Doxygen doc strings out of step with the string literals used in the translation - so I figured that D might address this. I still feel that that's worthwhile. (Note: in C, one can keep it all in the DRY SPOT by using macros, which we, er, cannot do in D. <g>)


If it is so common, then it should be exposed by the compiler via reflection. That way it would not be fragile, and would stay in that DRY SPOT.


>
>Of course, this does not address localisation, and I don't suggest it does. It's just a safer shortcut for what we do now anyway.
>
>I've been thinking that rather than strings we might also associate string identifiers, which would be hooked into the i18n framework that, as yet, does not exist. ;)


That i18n framework *does* exist. It's called ICU, and it has a slew of tools for producing, configuring, editing, and managing such resources. The best part about ICU is the level of maturity, and the vast sums of money poured into it by IBM et. al.

It may not be ideal, but it's a long way down a reasonable path.




>"kris" <fu@bar.org> wrote in message news:d0ps0h$2fbt$1@digitaldaemon.com...
>> Hey Andrew;
>>
>> I figured Matthew was using these enum-names for a non-i18n application only ~ once you start getting into locale-specifics, there's a whole lot more to consider (as I'm sure you know) and the strings themselves would very likely be externalized in one manner or another: making this topic somewhat moot?
>>
>> Of course, this is probably now way-off topic; so I'll mention the ICU tools/APIs once again (WRT this domain) and then shuttup ...
>>
>> - Kris