DMD 1.005 release

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Fri Feb 9 16:14:48 PST 2007


janderson wrote:
> Yauheni Akhotnikau wrote:
>> On Thu, 08 Feb 2007 10:08:29 +0300, Walter Bright 
>> <newshound at digitalmars.com> wrote:
>>
>>> Yauheni Akhotnikau wrote:
>>>> I'm use Ruby a lot and much metaprogramming things done via creating 
>>>> strings with Ruby code and evaluating it by various 'eval' methods. 
>>>> It is very simple method -- easy in writting, debugging and testing. 
>>>> And there isn't two different Ruby -- only one language.
>>>
>>> That's possible because Ruby is interpreted - its compilation 
>>> environment is also the execution environment.
>>>
>>> But D is a statically compiled language, so there's a distinction 
>>> between a compile time variable, and a runtime variable.
>>
>> Yes, I undertand that. But that is my point: in Ruby there are three 
>> steps:
>> 1) use ordinal Ruby code to produce string with another ordinal Ruby 
>> code;
>> 2) translation of string with ordinal Ruby code into bytecode;
>> 3) run of bytecode.
>>
>> In D we now have steps 2) and 3) implemented: step 2) is a compilation 
>> phase. The question is: how to perform step 1)?
>>
>> If it is necessary to use special constructs to build strings with 
>> ordinal D code then I will prefer to use pre-compile-time generation 
>> with help of external tools.
>>
>> For example, in last four years I have used home-made serialization 
>> framework for C++. It requires special description of serializable 
>> type in special Data Definition Language, like this:
>>
>> {type {extensible}    handshake_t
>>   {attr    m_version {of oess_1::uint_t}}
>>   {attr    m_client_id {of std::string}}
>>
>>   {extension
>>     {attr  m_signature
>>        {of signature_setup_t}
>>        {default {c++ signature_setup_t()}}
>>     }
>>     {attr  m_compression
>>        {of compression_setup_t}
>>        {default {c++ compression_setup_t()}}
>>     }
>>
>>     {extension
>>        {attr m_traits
>>           {stl-map {key oess_1::int_t}}
>>           {of handshake_trait_shptr_t}
>>           {default {c++ std::map< int, handshake_trait_shptr_t >()}
>>               {present_if {c++ m_traits.size()}}
>>           }
>>        }
>>     }
>>   }
>> }
>>
>> The library for parsing such s-expression is about 7K lines in C++ and 
>> 2.5K lines in Ruby. Comparable size it will have in D. But, if I want 
>> to use such DDL as DSL in mixin expression I must write two version of 
>> s-expression parsing -- for run-time and compile-time :(
>>
>> But if I can use ordinal D code at compile time then the situation is 
>> much better.
>>
>> --Regards,
>> Yauheni Akhotnikau
> 
> On the note of serialization I think you could be able to write 
> something like this:
> 
> mixin(serialize(
> "
>     class A
>     {
>         ...
>         serialize(10) int x; //(10 = default)
>         serialize B y;
>         int z; //Not serialized
>     }
> "
> ));
> 
> The serialize would pickup the serialize attributes and re-arrange the 
> code however it wanted (ie strip the serialize and put in a serialize 
> function)
> 
> You probably could do it now, however it will be much easier when a 
> method of writing functions like serialize is invented.

Probably an easier way to go would be:

class A
{
   ...
   int x;
   B y;
   int z;
}

mixin(serialize!(A, "x=10, y"));

This way you leave to the compiler the task of parsing the class, and 
you only deal with the annotations. If you prefer to not centralize them 
(although for serialization it's probably better), you can write:

class A
{
   ...
   mixin(serialize!(int, x, 10));
   mixin(serialize!(B, y));
   int z;
}

Again, you let the compiler to the heavylifting and you limit your 
annotation to the smallest notational unit.


Andrei



More information about the Digitalmars-d-announce mailing list