www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - compile-time access to parsed code

reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
alot of ideas for DSL that are coming up are really just additions of 
feature to already existing concepts in D.

For example, mapping a DB table/row to a D class/object.
One would probably do something like:
mixin( Model!(
    "Person:
      char[100] name;
      int       age;
      ForeignKey(Car)  car;
    "
))

and then one would have to write a parser for that, which will 
essentially produce a regular D class, with the same attributes, plus 
some additional magic:

class Person
{
      char[100] name;
      int       age;
      ForeignKey!(Car)  car;

      //magic
      load( ... );
      save( ... );
      query( ... );
      //etc
}


Here, one is essentially adding magic features to classes, but there's a 
lot of re-invention of the wheel going on here.

Wouldn't it be much better if we simply write the code in D, and get 
access to its parsed form at compile-time and modify it?

like, just write:
class Person
{
      char[100] name;
      int       age;
      ForeignKey!(Car)  car;

      mixin(DBMagic!( typeof(this) ));
}

then, somewhere else, we define DBMagic as a template or function or 
whatever, and this function would recieve a paramter of type Class which 
would have all the attributes of the Person class, the function can read 
those attributes and figure out how to return a string containing 
definitions of magic methods.

A better alternative is reading the class at compile-time and /changing/ 
the class (without emitting code) by adding attributes and methods to 
it, using something like:
class.addAttribute( Type, name );
class.addMethod( Type, name, params, ..... )

That would be much more robust than emitting strings .. no?
Feb 11 2007
next sibling parent reply "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> writes:
Hasan Aljudy wrote:
 alot of ideas for DSL that are coming up are really just additions of 
 feature to already existing concepts in D.
 
 For example, mapping a DB table/row to a D class/object.
 One would probably do something like:
 mixin( Model!(
    "Person:
      char[100] name;
      int       age;
      ForeignKey(Car)  car;
    "
 ))

I don't think so. The underlying motivation for mapping DB structure to D code is to "not repeat yourself". Here you are repeating yourself, because you specify a snippet of what looks like SQL, but inside D code so you'll need to write that somewhere in the database itself. The DRY approach is to have the D code peek the database structure directly and generate the appropriate code. Then you benefit of keeping the two in sync without effort.
 and then one would have to write a parser for that, which will 
 essentially produce a regular D class, with the same attributes, plus 
 some additional magic:
 
 class Person
 {
      char[100] name;
      int       age;
      ForeignKey!(Car)  car;
 
      //magic
      load( ... );
      save( ... );
      query( ... );
      //etc
 }
 
 
 Here, one is essentially adding magic features to classes, but there's a 
 lot of re-invention of the wheel going on here.
 
 Wouldn't it be much better if we simply write the code in D, and get 
 access to its parsed form at compile-time and modify it?
 
 like, just write:
 class Person
 {
      char[100] name;
      int       age;
      ForeignKey!(Car)  car;
 
      mixin(DBMagic!( typeof(this) ));
 }
 
 then, somewhere else, we define DBMagic as a template or function or 
 whatever, and this function would recieve a paramter of type Class which 
 would have all the attributes of the Person class, the function can read 
 those attributes and figure out how to return a string containing 
 definitions of magic methods.
 
 A better alternative is reading the class at compile-time and /changing/ 
 the class (without emitting code) by adding attributes and methods to 
 it, using something like:
 class.addAttribute( Type, name );
 class.addMethod( Type, name, params, ..... )
 
 That would be much more robust than emitting strings .. no?

I don't think so. This is pretty much getting back to the old way of doing things - writing things twice and crossing fingers that they'll stay in sync. Andrei
Feb 11 2007
parent reply Serg Kovrov <kovrov no.spam> writes:
Andrei Alexandrescu (See Website For Email) wrote:
 The DRY approach is to have the D code peek the database structure 
 directly and generate the appropriate code. Then you benefit of keeping 
 the two in sync without effort.

I disagree. Hasan meant different (from Rails) approach. I believe he referring to Django. And it is perfectly valid point.
 This is pretty much getting back to the old way of doing things - 
 writing things twice and crossing fingers that they'll stay in sync.

Could not agree on that either. An analogy is a binary file format - once defined it should not be changed. If changed externally (you would say out of sync) it's integrity should be considered broken. -- serg.
Feb 21 2007
parent reply "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> writes:
Serg Kovrov wrote:
 Andrei Alexandrescu (See Website For Email) wrote:
 The DRY approach is to have the D code peek the database structure 
 directly and generate the appropriate code. Then you benefit of 
 keeping the two in sync without effort.

I disagree. Hasan meant different (from Rails) approach. I believe he referring to Django. And it is perfectly valid point.

I'm lost here.
 This is pretty much getting back to the old way of doing things - 
 writing things twice and crossing fingers that they'll stay in sync.

Could not agree on that either. An analogy is a binary file format - once defined it should not be changed. If changed externally (you would say out of sync) it's integrity should be considered broken.

You are supporting my viewpoint. Because all I'm saying is that any "broken integrity" should be detected early and swiftly. Andrei
Feb 21 2007
parent Serg Kovrov <kovrov no.spam> writes:
Andrei Alexandrescu (See Website For Email) wrote:
 You are supporting my viewpoint. Because all I'm saying is that any 
 "broken integrity" should be detected early and swiftly.

It might be, or there might be some misunderstanding... Anyway my point is that primary (and sole, if adhering DRY) 'source' of database config (schema), should be code. Detecting broken integrity has nothing to do with subject, it's just a matter of defensive coding techniques. Original point was, to have ability to introspect code on compile time to generate SQL from classes representing data. Django (http://www.djangoproject.com/) is good example of such approach. -- serg.
Feb 22 2007
prev sibling parent reply janderson <askme me.com> writes:
Hasan Aljudy wrote:
 alot of ideas for DSL that are coming up are really just additions of 
 feature to already existing concepts in D.
 
 For example, mapping a DB table/row to a D class/object.
 One would probably do something like:
 mixin( Model!(
    "Person:
      char[100] name;
      int       age;
      ForeignKey(Car)  car;
    "
 ))
 
 and then one would have to write a parser for that, which will 
 essentially produce a regular D class, with the same attributes, plus 
 some additional magic:
 

In this case all the parser would do is find Token: and re-write it as "class Person" Then find ( and replace it with !(. Finally it would append the magic on the end. I hope we will eventually get lots of library functions to help this process out. This essentially makes the reuseable part easy to write at a cost of spending a little time writing the Model! library. In some respects I agree, when I originally posted an idea like this a few years ago, one of my suggestions asked to have access to D's symbolic tree passed into the template. -Joel
Feb 11 2007
parent janderson <askme me.com> writes:
janderson > In some respects I agree, when I originally posted an idea 
like this a
 few years ago, one of my suggestions asked to have access to D's 
 symbolic tree passed into the template.
 
 -Joel

Actually now that I think about it, this is probably not possible or would be very difficult to do. -Joel
Feb 11 2007