View mode: basic / threaded / horizontal-split · Log in · Help
February 08, 2007
Re: DMD 1.005 release
Yauheni Akhotnikau wrote:
>> The main difficulty is if the DSL needs to access symbols in the rest 
>> of the D code.
> 
> I agree.
> But how do you think do such things in the current approach?

int i = 4;
mixin("writefln(i)");

will print:

4
February 08, 2007
Re: DMD 1.005 release
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.
February 08, 2007
Re: DMD 1.005 release
On Thu, 08 Feb 2007 10:06:04 +0300, Walter Bright  
<newshound@digitalmars.com> wrote:

> Yauheni Akhotnikau wrote:
>>> The main difficulty is if the DSL needs to access symbols in the rest  
>>> of the D code.
>>  I agree.
>> But how do you think do such things in the current approach?
>
> int i = 4;
> mixin("writefln(i)");
>
> will print:
>
> 4

I understand that :)
But suppouse than string "writefln(i)" has been produced by some DSL  
transformator:

 int i = 4;
 mixin( ProduceWritefln("i") );

The content of ProduceWritefln() need no access to variable i -- it makes  
some string which transformed to D code only in mixin(), not in  
ProduceWritefln. So the main task of ProduceWritefln is manipulating of  
string without access to any existed D code.

So my point is to allow to ProduceWritefln be ordinary D code which  
executed at compilation time.

-- 
Regards,
Yauheni Akhotnikau
February 08, 2007
Re: DMD 1.005 release
Charles D Hixson wrote:
...
> Forth is very similar to LISP, only with a simpler grammar. I.e., the 
> grammar is simple serial execution, with  certain words (those marked 
> immediate) able to manipulate the input stream to determine what will be 
> the next in order.

I think the comparison to LISP is a good way to think about forth:

1. Write a lisp program, but put the function name after its arguments
   for every expression.  This will be hard to read but by following
   the parenthesis you can just barely tell what is happening.

2. Remove all the parenthesis.

At least 90% of the time, if you remove a symbol from a valid forth 
program, you get a valid (but incorrect) forth program -- there is 
almost zero redundancy in the language so errors are almost never 
detectable at compile time, which means you should write short clear 
functions.

But the central feature of FORTH is that the compiler and runtime can be 
made mind-bogglingly small.  I think the run time speed for a naive 
interpretation is probably somewhere between C and interpreted bytecode.

From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th

"The run-time engine takes up less than 1K of code space and the p-codes 
are so dense that you can get a lot of robot functionality in just 2K."

Of course, that's a compiler; an interactive language environment can be 
used for prototyping (like with lisp) and that will run a bit bigger.

Kevin
February 08, 2007
Re: DMD 1.005 release
Yauheni Akhotnikau wrote:
> On Thu, 08 Feb 2007 10:06:04 +0300, Walter Bright 
> <newshound@digitalmars.com> wrote:
> 
>> Yauheni Akhotnikau wrote:
>>>> The main difficulty is if the DSL needs to access symbols in the 
>>>> rest of the D code.
>>>  I agree.
>>> But how do you think do such things in the current approach?
>>
>> int i = 4;
>> mixin("writefln(i)");
>>
>> will print:
>>
>> 4
> 
> I understand that :)
> But suppouse than string "writefln(i)" has been produced by some DSL 
> transformator:
> 
>  int i = 4;
>  mixin( ProduceWritefln("i") );
> 
> The content of ProduceWritefln() need no access to variable i -- it 
> makes some string which transformed to D code only in mixin(), not in 
> ProduceWritefln. So the main task of ProduceWritefln is manipulating of 
> string without access to any existed D code.
> 
> So my point is to allow to ProduceWritefln be ordinary D code which 
> executed at compilation time.

I see your point, but passing arguments "by name", which is what your 
example does, means the function has no access to whatever that name is 
- such as its type, size, etc.
February 08, 2007
Re: DMD 1.005 release
On Thu, 08 Feb 2007 10:08:29 +0300, Walter Bright  
<newshound@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
February 08, 2007
Re: DMD 1.005 release
>>  So my point is to allow to ProduceWritefln be ordinary D code which  
>> executed at compilation time.
>
> I see your point, but passing arguments "by name", which is what your  
> example does, means the function has no access to whatever that name is  
> - such as its type, size, etc.

Yes, but here we have two alternative approaches:

1) generation of strings with D code without access to addition  
information (my sample above). This is approach largely used in Ruby  
metaprogramming. And this is very useful approach in many situations, i.e.  
it is not an ideal solution, but useful (in my expirience);

2) manipulation of syntax tree in compilation phase, where the macros code  
has access to all information about programm's symbols (identifiers, types  
and so on). This approach is used in Nemerle, but there macroses received  
as input not string, but ordinal Nemerle code.

So my problem with understanding role of new D constructs (mixin  
expressions and import expressions) is: if the Ruby's approach with string  
generation is not appropriate then how to get something like Nemerle's  
approach if we use strings in mixin expressions?

-- 
Regards,
Yauheni Akhotnikau
February 08, 2007
Re: DMD 1.005 release
BCS wrote:
> Derek Parnell wrote:
>> On Wed, 07 Feb 2007 11:50:50 -0800, BCS wrote:
>>
>> So in your example above ...
>>
>>   version(build) pragma(export_version, Foo, Bar);
>>
> 
> Cool, but I think that would be
> 
>  version(Foo) pragma(export_version, Bar);

No, you need both version()s:
    version(build) version(Foo) pragma(export_version, Bar);
or
    version(Foo) version(build) pragma(export_version, Bar);

An unknown pragma is an error, so you need to put build-specific pragmas 
in a version(build).
February 08, 2007
Re: DMD 1.005 release [another wow-thankyou-post]
Walter Bright wrote:
> Fixes many bugs, some serious.
> 
> Some new goodies.
> 
> http://www.digitalmars.com/d/changelog.html
> 
> http://ftp.digitalmars.com/dmd.1.005.zip

Wow, This is just sweet! Thanks, Walter! :D I'll see what kind of abuse 
can be done with the new mixin stuff ;)
Still, we must find a way to reduce the memory requirements of 
evaluating more complex templates - as at one point, they are going to 
contain pretty arbitrary code.


--
Tomasz Stachowiak
February 08, 2007
Re: DMD 1.005 release
Kevin Bealer wrote:
> Charles D Hixson wrote:
> But the central feature of FORTH is that the compiler and runtime can be 
> made mind-bogglingly small.  I think the run time speed for a naive 
> interpretation is probably somewhere between C and interpreted bytecode.
> 
>  From this page about tiny4th: http://www.seanet.com/~karllunt/tiny4th
> 
> "The run-time engine takes up less than 1K of code space and the p-codes 
> are so dense that you can get a lot of robot functionality in just 2K."

Before someone thinks, Forth is only a play-thing, see http://www.forth.com/

There are also excellent freeware versions around, f.ex.
http://win32forth.sourceforge.net/

There is even ans ANS / ISO standard for the language.

Andreas
10 11 12 13 14 15 16 17 18
Top | Discussion index | About this forum | D home