www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Short list with things to finish for D2

reply yigal chripun <yigal100 gmail.com> writes:
aarti_pl Wrote:

 Walter Bright pisze:
 Don wrote:
 There's not many sensible operators anyway. opPow is the only missing 
 one that's present in many other general-purpose languages. The only 
 other ones I think are remotely interesting are dot and cross product.

Yup.
 Anything beyond that, you generally want a full DSL, probably with 
 different precendence and associativity rules. Eg, for regexp, you'd 
 want postfix * and + operators. There are examples of clever things 
 done in C++  with operator overloading, but I think that's just 
 because it's the only way to do DSLs in C++.

I was enthralled with the way C++ did it for regex for a while, but when I think more about it, it's just too clever. I think it's more operator overloading abuse now.
 I don't think the applications are there.

I agree.

Well, I can understand your fear about operator abuse. And I agree that code might be awful when operator overloading will be abused. But I have in mind one very convincing example. I defined in D/Java SQL syntax. They are also other frameworks which do the same. What can I say about my experiences with using such framework: it is very, very powerful concept. It cuts time necessary to develop application, makes sql statements type safe and allows to pass around parts of sql statements inside application. It also makes easy refactoring of sql statement (especially in Java). Its huge win comparing it to defining DSL as strings. It's hard to explain just in few sentences all details. I have already done it long time ago, and in my first post I provided links. Problem with current approach is that I have to define SQL in D/Java in following way: auto statement = Select(visitcars.name).Where(And(More(visitcards.id, 100), Like(visitcards.surname, "A*"))); Please look at code in Where(). It's so awfuuuuulllllll! It would be so much better to write: auto statement = Select(visitcars.name).Where((visitcards.id `>` 100) `AND` (visitcards.surname `Like` "A*")); I used here syntax which you have proposed with delimiter ``. I think it is good enough solution for such purpose. But please, don't underestimate problem! Many DSL languages would never appear if languages would be good enough. As I said solution with delimiter is good enough for me. It has another advantage that it clearly shows in code that you have overloaded operator here, so no surprises here. Additionally when you implement template function: opInfix('AND')(val0, val1); you pass string into template. So I see it quite intuitive that you use string as operator: ``. Maybe there will be not necessary to change current behavior that `` defines string. I think we have good possibility to open this door now. It can be even implemented later, but I would wish just not to close this door now :-) BR Marcin Kuszczak (aarti_pl)

There's nothing more hideous than all those frameworks in Java/C++ that try to re-enginer SQL into functions, templates, LINQ, whatever. SQL *is* a perfectly designed language for its purpose and it doesn't need to be redisnged! The only problem with this is the type-safety when embedding sql as string in a host language. the solution is two-phased: phase a is simple, look at the C# API for postgres (I think). The query is one string like: "select * from table where :a > 42", the :name is a place holder for the host-language variable, and you call an API to bind those :names to variables in a type-safe way. the downside is that it's verbose. phase b is what Nemerle does with the above - it has an AST macro to wrap the above so you can write your query directly and it is checked as compile-time. No operators were abused in implementing this.
Nov 23 2009
next sibling parent reply Don <nospam nospam.com> writes:
yigal chripun wrote:
 aarti_pl Wrote:
 
 Walter Bright pisze:
 Don wrote:
 There's not many sensible operators anyway. opPow is the only missing 
 one that's present in many other general-purpose languages. The only 
 other ones I think are remotely interesting are dot and cross product.

 Anything beyond that, you generally want a full DSL, probably with 
 different precendence and associativity rules. Eg, for regexp, you'd 
 want postfix * and + operators. There are examples of clever things 
 done in C++  with operator overloading, but I think that's just 
 because it's the only way to do DSLs in C++.

I think more about it, it's just too clever. I think it's more operator overloading abuse now.
 I don't think the applications are there.


code might be awful when operator overloading will be abused. But I have in mind one very convincing example. I defined in D/Java SQL syntax. They are also other frameworks which do the same. What can I say about my experiences with using such framework: it is very, very powerful concept. It cuts time necessary to develop application, makes sql statements type safe and allows to pass around parts of sql statements inside application. It also makes easy refactoring of sql statement (especially in Java). Its huge win comparing it to defining DSL as strings. It's hard to explain just in few sentences all details. I have already done it long time ago, and in my first post I provided links. Problem with current approach is that I have to define SQL in D/Java in following way: auto statement = Select(visitcars.name).Where(And(More(visitcards.id, 100), Like(visitcards.surname, "A*"))); Please look at code in Where(). It's so awfuuuuulllllll! It would be so much better to write: auto statement = Select(visitcars.name).Where((visitcards.id `>` 100) `AND` (visitcards.surname `Like` "A*")); I used here syntax which you have proposed with delimiter ``. I think it is good enough solution for such purpose. But please, don't underestimate problem! Many DSL languages would never appear if languages would be good enough. As I said solution with delimiter is good enough for me. It has another advantage that it clearly shows in code that you have overloaded operator here, so no surprises here. Additionally when you implement template function: opInfix('AND')(val0, val1); you pass string into template. So I see it quite intuitive that you use string as operator: ``. Maybe there will be not necessary to change current behavior that `` defines string. I think we have good possibility to open this door now. It can be even implemented later, but I would wish just not to close this door now :-) BR Marcin Kuszczak (aarti_pl)

There's nothing more hideous than all those frameworks in Java/C++ that try to re-enginer SQL into functions, templates, LINQ, whatever. SQL *is* a perfectly designed language for its purpose and it doesn't need to be redisnged! The only problem with this is the type-safety when embedding sql as string in a host language. the solution is two-phased: phase a is simple, look at the C# API for postgres (I think). The query is one string like:

 "select * from table where :a > 42", the :name is a place holder for the
host-language variable, and you call an API to bind those :names to variables
in a type-safe way. the downside is that it's verbose. 
  
 phase b is what Nemerle does with the above - it has an AST macro to wrap the
above so you can write your query directly and it is checked as compile-time. 
 
 No operators were abused in implementing this. 

I quite agree. What we can do already is: auto statement = db.execute!(`select $a from table where $b > 100 && $c Like "A*"`)(visitcars.name,visitcars.id, visitcars.surname); which I personally like much better than the proposed goal:
 It would be so much better to write:
 auto statement = Select(visitcars.name).Where((visitcards.id `>` 100)
 `AND` (visitcards.surname `Like` "A*"));


(Replace $a with your preferred method for defining placeholder variables). And the question then is, can we improve the existing solution? And if so, how? I just don't think the solution involves overloading operators. I think this a great example of why we *don't* want arbitrary operator overloading: there's no point overloading && and > if you can't make 'from', 'where', and 'like' to all be infix operators, as well!
Nov 23 2009
next sibling parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Don wrote:
 yigal chripun wrote:
 aarti_pl Wrote:

 Walter Bright pisze:
 Don wrote:
 There's not many sensible operators anyway. opPow is the only
 missing one that's present in many other general-purpose languages.
 The only other ones I think are remotely interesting are dot and
 cross product.

 Anything beyond that, you generally want a full DSL, probably with
 different precendence and associativity rules. Eg, for regexp,
 you'd want postfix * and + operators. There are examples of clever
 things done in C++  with operator overloading, but I think that's
 just because it's the only way to do DSLs in C++.

when I think more about it, it's just too clever. I think it's more operator overloading abuse now.
 I don't think the applications are there.


that code might be awful when operator overloading will be abused. But I have in mind one very convincing example. I defined in D/Java SQL syntax. They are also other frameworks which do the same. What can I say about my experiences with using such framework: it is very, very powerful concept. It cuts time necessary to develop application, makes sql statements type safe and allows to pass around parts of sql statements inside application. It also makes easy refactoring of sql statement (especially in Java). Its huge win comparing it to defining DSL as strings. It's hard to explain just in few sentences all details. I have already done it long time ago, and in my first post I provided links. Problem with current approach is that I have to define SQL in D/Java in following way: auto statement = Select(visitcars.name).Where(And(More(visitcards.id, 100), Like(visitcards.surname, "A*"))); Please look at code in Where(). It's so awfuuuuulllllll! It would be so much better to write: auto statement = Select(visitcars.name).Where((visitcards.id `>` 100) `AND` (visitcards.surname `Like` "A*")); I used here syntax which you have proposed with delimiter ``. I think it is good enough solution for such purpose. But please, don't underestimate problem! Many DSL languages would never appear if languages would be good enough. As I said solution with delimiter is good enough for me. It has another advantage that it clearly shows in code that you have overloaded operator here, so no surprises here. Additionally when you implement template function: opInfix('AND')(val0, val1); you pass string into template. So I see it quite intuitive that you use string as operator: ``. Maybe there will be not necessary to change current behavior that `` defines string. I think we have good possibility to open this door now. It can be even implemented later, but I would wish just not to close this door now :-) BR Marcin Kuszczak (aarti_pl)

There's nothing more hideous than all those frameworks in Java/C++ that try to re-enginer SQL into functions, templates, LINQ, whatever. SQL *is* a perfectly designed language for its purpose and it doesn't need to be redisnged! The only problem with this is the type-safety when embedding sql as string in a host language. the solution is two-phased: phase a is simple, look at the C# API for postgres (I think). The query is one string like:

 "select * from table where :a > 42", the :name is a place holder for
 the host-language variable, and you call an API to bind those :names
 to variables in a type-safe way. the downside is that it's verbose.  
 phase b is what Nemerle does with the above - it has an AST macro to
 wrap the above so you can write your query directly and it is checked
 as compile-time.
 No operators were abused in implementing this. 

I quite agree. What we can do already is: auto statement = db.execute!(`select $a from table where $b > 100 && $c Like "A*"`)(visitcars.name,visitcars.id, visitcars.surname); which I personally like much better than the proposed goal:
 It would be so much better to write:
 auto statement = Select(visitcars.name).Where((visitcards.id `>` 100)
 `AND` (visitcards.surname `Like` "A*"));


(Replace $a with your preferred method for defining placeholder variables). And the question then is, can we improve the existing solution? And if so, how? I just don't think the solution involves overloading operators. I think this a great example of why we *don't* want arbitrary operator overloading: there's no point overloading && and > if you can't make 'from', 'where', and 'like' to all be infix operators, as well!

This sounds like a job for better mixin syntax. So let "template#(args)" be equivalent to "mixin(template!(args))". Then you can do auto statement = db.execute#(`select $visitcars.name from table where $visitcars.id > 100 && $visitcars.surname Like "A*"`);
Nov 23 2009
parent reply Don <nospam nospam.com> writes:
Chad J wrote:
 Don wrote:
 yigal chripun wrote:
 aarti_pl Wrote:

 Walter Bright pisze:
 Don wrote:
 There's not many sensible operators anyway. opPow is the only
 missing one that's present in many other general-purpose languages.
 The only other ones I think are remotely interesting are dot and
 cross product.

 Anything beyond that, you generally want a full DSL, probably with
 different precendence and associativity rules. Eg, for regexp,
 you'd want postfix * and + operators. There are examples of clever
 things done in C++  with operator overloading, but I think that's
 just because it's the only way to do DSLs in C++.

when I think more about it, it's just too clever. I think it's more operator overloading abuse now.
 I don't think the applications are there.


that code might be awful when operator overloading will be abused. But I have in mind one very convincing example. I defined in D/Java SQL syntax. They are also other frameworks which do the same. What can I say about my experiences with using such framework: it is very, very powerful concept. It cuts time necessary to develop application, makes sql statements type safe and allows to pass around parts of sql statements inside application. It also makes easy refactoring of sql statement (especially in Java). Its huge win comparing it to defining DSL as strings. It's hard to explain just in few sentences all details. I have already done it long time ago, and in my first post I provided links. Problem with current approach is that I have to define SQL in D/Java in following way: auto statement = Select(visitcars.name).Where(And(More(visitcards.id, 100), Like(visitcards.surname, "A*"))); Please look at code in Where(). It's so awfuuuuulllllll! It would be so much better to write: auto statement = Select(visitcars.name).Where((visitcards.id `>` 100) `AND` (visitcards.surname `Like` "A*")); I used here syntax which you have proposed with delimiter ``. I think it is good enough solution for such purpose. But please, don't underestimate problem! Many DSL languages would never appear if languages would be good enough. As I said solution with delimiter is good enough for me. It has another advantage that it clearly shows in code that you have overloaded operator here, so no surprises here. Additionally when you implement template function: opInfix('AND')(val0, val1); you pass string into template. So I see it quite intuitive that you use string as operator: ``. Maybe there will be not necessary to change current behavior that `` defines string. I think we have good possibility to open this door now. It can be even implemented later, but I would wish just not to close this door now :-) BR Marcin Kuszczak (aarti_pl)

that try to re-enginer SQL into functions, templates, LINQ, whatever. SQL *is* a perfectly designed language for its purpose and it doesn't need to be redisnged! The only problem with this is the type-safety when embedding sql as string in a host language. the solution is two-phased: phase a is simple, look at the C# API for postgres (I think). The query is one string like: "select * from table where :a > 42", the :name is a place holder for the host-language variable, and you call an API to bind those :names to variables in a type-safe way. the downside is that it's verbose. phase b is what Nemerle does with the above - it has an AST macro to wrap the above so you can write your query directly and it is checked as compile-time. No operators were abused in implementing this.

auto statement = db.execute!(`select $a from table where $b > 100 && $c Like "A*"`)(visitcars.name,visitcars.id, visitcars.surname); which I personally like much better than the proposed goal:
 It would be so much better to write:
 auto statement = Select(visitcars.name).Where((visitcards.id `>` 100)
 `AND` (visitcards.surname `Like` "A*"));


And the question then is, can we improve the existing solution? And if so, how? I just don't think the solution involves overloading operators. I think this a great example of why we *don't* want arbitrary operator overloading: there's no point overloading && and > if you can't make 'from', 'where', and 'like' to all be infix operators, as well!

This sounds like a job for better mixin syntax. So let "template#(args)" be equivalent to "mixin(template!(args))". Then you can do auto statement = db.execute#(`select $visitcars.name from table where $visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if macro foo(args...) foo(args) meant mixin(foo(args)). then the syntax would be: db.execute(`select $visitcars.name from table where $visitcars.id > 100 && $visitcars.surname Like "A*"`); which has advantages and disadvantages. So there's quite a bit of flexibility. A lot of potential for brainstorming!
Nov 23 2009
next sibling parent yigal chripun <yigal100 gmail.com> writes:
Don Wrote:

 Chad J wrote:
 Don wrote:
 I quite agree. What we can do already is:

 auto statement = db.execute!(`select $a from table where $b > 100 && $c
 Like "A*"`)(visitcars.name,visitcars.id, visitcars.surname);

 which I personally like much better than the proposed goal:

 It would be so much better to write:
 auto statement = Select(visitcars.name).Where((visitcards.id `>` 100)
 `AND` (visitcards.surname `Like` "A*"));


And the question then is, can we improve the existing solution? And if so, how? I just don't think the solution involves overloading operators. I think this a great example of why we *don't* want arbitrary operator overloading: there's no point overloading && and > if you can't make 'from', 'where', and 'like' to all be infix operators, as well!

This sounds like a job for better mixin syntax. So let "template#(args)" be equivalent to "mixin(template!(args))". Then you can do auto statement = db.execute#(`select $visitcars.name from table where $visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if macro foo(args...) foo(args) meant mixin(foo(args)). then the syntax would be: db.execute(`select $visitcars.name from table where $visitcars.id > 100 && $visitcars.surname Like "A*"`); which has advantages and disadvantages. So there's quite a bit of flexibility. A lot of potential for brainstorming!

a few points I want to add: 1) I though that :name was in some version of the SQL standard or a know extension so if we use this in APIs for D we should use the standard notation (can anyone verify this?) 2) I don't want to mix this discussion with infix functions and operator overloading. I'm not sure I want to limit these and perhaps there are other legitimate uses for general purpose infix functions. In this post I just pointed out that SQL is *not* a legitimate use case for that. 3) the Nemerle macros for SQL allow for: db.execute(`select $visitcars.name from table where $visitcars.id > 100 && $visitcars.surname Like "A*"`); the $ in Nemerle is used for controled breaking of hygene. Their Macro translates such a query into a sql string with :names and calls for the bind API to connect those with the given variables in a type-safe way. IIRC, they use the db connection object to conncet to the DB at compile-time and check the syntax and also existence of the objects (tables, columns, etc) in the DB schema.
Nov 23 2009
prev sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Bill Baxter wrote:
 On Mon, Nov 23, 2009 at 3:12 AM, Don <nospam nospam.com> wrote:
 
 This sounds like a job for better mixin syntax.
 .
 So let "template#(args)" be equivalent to "mixin(template!(args))".

 Then you can do

 auto statement = db.execute#(`select $visitcars.name from table where
 $visitcars.id > 100 && $visitcars.surname Like "A*"`);

macro foo(args...) foo(args) meant mixin(foo(args)).

This is what I've been thinking too. But we might want there to be more to a macro than that. For instance most macro parameters are strings and the '(string this, string that, string theOther)', list of parameters doesn't look so great. And requiring the strings to be quoted on the calling side, also makes the call side rather ugly. It may be better to have arguments automatically convert to some sort of AST type which supports some introspection, and can be converted back to a string of code easily. So I think jumping on just making macro mean "mixin automatically" right now may limit our future choices too much.

I think the community has come to expect a lot more from the macro keyword. I, at least, would be disappointed if this is what comes out of it. :) How about auto template MixMeInAutomatically(T) { ... } void main() { MixMeInAutomatically!int; ... } Would this be ambiguous? It would be using auto for something completely new, but it would at least make sense. (More so than macro, in my opinion.) -Lars
Nov 23 2009
parent Don <nospam nospam.com> writes:
Lars T. Kyllingstad wrote:
 Bill Baxter wrote:
 On Mon, Nov 23, 2009 at 3:12 AM, Don <nospam nospam.com> wrote:

 This sounds like a job for better mixin syntax.
 .
 So let "template#(args)" be equivalent to "mixin(template!(args))".

 Then you can do

 auto statement = db.execute#(`select $visitcars.name from table where
 $visitcars.id > 100 && $visitcars.surname Like "A*"`);

macro foo(args...) foo(args) meant mixin(foo(args)).

This is what I've been thinking too. But we might want there to be more to a macro than that. For instance most macro parameters are strings and the '(string this, string that, string theOther)', list of parameters doesn't look so great. And requiring the strings to be quoted on the calling side, also makes the call side rather ugly. It may be better to have arguments automatically convert to some sort of AST type which supports some introspection, and can be converted back to a string of code easily. So I think jumping on just making macro mean "mixin automatically" right now may limit our future choices too much.

I think the community has come to expect a lot more from the macro keyword. I, at least, would be disappointed if this is what comes out of it. :)

Oh, me too. But, this establishes a minimum. We've got a very long time to get macros right.
 
 How about
 
     auto template MixMeInAutomatically(T) { ... }
 
     void main()
     {
         MixMeInAutomatically!int;
         ...
     }
 
 Would this be ambiguous? It would be using auto for something completely 
 new, but it would at least make sense. (More so than macro, in my opinion.)
 
 -Lars

Nov 23 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Mon, Nov 23, 2009 at 3:12 AM, Don <nospam nospam.com> wrote:

 This sounds like a job for better mixin syntax.
.
 So let "template#(args)" be equivalent to "mixin(template!(args))".

 Then you can do

 auto statement =3D db.execute#(`select $visitcars.name from table where
 $visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if macro foo(args...) foo(args) meant =A0mixin(foo(args)).

This is what I've been thinking too. But we might want there to be more to a macro than that. For instance most macro parameters are strings and the '(string this, string that, string theOther)', list of parameters doesn't look so great. And requiring the strings to be quoted on the calling side, also makes the call side rather ugly. It may be better to have arguments automatically convert to some sort of AST type which supports some introspection, and can be converted back to a string of code easily. So I think jumping on just making macro mean "mixin automatically" right now may limit our future choices too much. --bb
Nov 23 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 23 Nov 2009 07:38:32 -0500, Bill Baxter <wbaxter gmail.com> wrote:

 On Mon, Nov 23, 2009 at 3:12 AM, Don <nospam nospam.com> wrote:

 This sounds like a job for better mixin syntax.
 .
 So let "template#(args)" be equivalent to "mixin(template!(args))".

 Then you can do

 auto statement = db.execute#(`select $visitcars.name from table where
 $visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if macro foo(args...) foo(args) meant mixin(foo(args)).

This is what I've been thinking too. But we might want there to be more to a macro than that. For instance most macro parameters are strings and the '(string this, string that, string theOther)', list of parameters doesn't look so great. And requiring the strings to be quoted on the calling side, also makes the call side rather ugly. It may be better to have arguments automatically convert to some sort of AST type which supports some introspection, and can be converted back to a string of code easily. So I think jumping on just making macro mean "mixin automatically" right now may limit our future choices too much.

What about this: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=17853 -Steve
Nov 23 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Mon, Nov 23, 2009 at 5:32 AM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 On Mon, 23 Nov 2009 07:38:32 -0500, Bill Baxter <wbaxter gmail.com> wrote=

 On Mon, Nov 23, 2009 at 3:12 AM, Don <nospam nospam.com> wrote:

 This sounds like a job for better mixin syntax.
 .
 So let "template#(args)" be equivalent to "mixin(template!(args))".

 Then you can do

 auto statement =3D db.execute#(`select $visitcars.name from table wher=




 $visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if macro foo(args...) foo(args) meant =A0mixin(foo(args)).

This is what I've been thinking too. But we might want there to be more to a macro than that. =A0For instance most macro parameters are strings and the '(string this, string that, string theOther)', list of parameters doesn't look so great. =A0And requiring the strings to be quoted on the calling side, also makes the call side rather ugly. =A0It may be better to have arguments automatically convert to some sort of AST type which supports some introspection, and can be converted back to a string of code easily. So I think jumping on just making macro mean "mixin automatically" right now may limit our future choices too much.

What about this: http://www.digitalmars.com/webnews/newsgroups.php?art_group=3Ddigitalmars=

Quoting from there: """ macro doit(x, y, z) mixin("x" ~ "y" ~ "z"); // allow easy syntax for quoting parameters, since mixins are all about stringification. doit(a, b, c) =3D> mixin("abc"); """ What happens if you want to have the string "x", just a plain x, in the mix= in? Other than that, I think I don't know enough about the lessons to be learned from Lisp, Scheme, and Nemerle. I'd like to study more how macros work in those systems before I'd feel comfortable committing to any particular design. For instance what's the best way to handle hygene issues mentioned here: http://en.wikipedia.org/wiki/Hygienic_macro . There are probably some hygene issues there that should be considered for template mixins too. For instance it's a long-standing issue that if you use a mixin from a library, you must import all the modules that mixin depends on, which breaks a kind of encapsulation of the mixin. Mixins are probably also subject to the kind of environmental hygene problem described on that page, where a common function redefined in the current scope alters the intended behavior of the mixin. I think Walter had intended template mixins to take the place of macros. They offer some features of macros but not all. So once real macros exist, I wonder if there will be any real reason for them to continue existing. --bb
Nov 23 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 23 Nov 2009 12:49:01 -0500, Bill Baxter <wbaxter gmail.com> wrote:

 On Mon, Nov 23, 2009 at 5:32 AM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 On Mon, 23 Nov 2009 07:38:32 -0500, Bill Baxter <wbaxter gmail.com>  
 wrote:

 On Mon, Nov 23, 2009 at 3:12 AM, Don <nospam nospam.com> wrote:

 This sounds like a job for better mixin syntax.
 .
 So let "template#(args)" be equivalent to "mixin(template!(args))".

 Then you can do

 auto statement = db.execute#(`select $visitcars.name from table where
 $visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if macro foo(args...) foo(args) meant mixin(foo(args)).

This is what I've been thinking too. But we might want there to be more to a macro than that. For instance most macro parameters are strings and the '(string this, string that, string theOther)', list of parameters doesn't look so great. And requiring the strings to be quoted on the calling side, also makes the call side rather ugly. It may be better to have arguments automatically convert to some sort of AST type which supports some introspection, and can be converted back to a string of code easily. So I think jumping on just making macro mean "mixin automatically" right now may limit our future choices too much.

What about this: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=17853

Quoting from there: """ macro doit(x, y, z) mixin("x" ~ "y" ~ "z"); // allow easy syntax for quoting parameters, since mixins are all about stringification. doit(a, b, c) => mixin("abc"); """ What happens if you want to have the string "x", just a plain x, in the mixin?

Don't name your parameter x. The author of the macro is charge of the names of its parameters, if you need a certain string, don't use it as a parameter name. I would say that I wouldn't expect a global search and replace, only matching symbols would be replaced, for example: macro doit(x) mixin("xx = x;"); doit(hi); would result in xx = hi;
 Other than that, I think I don't know enough about the lessons to be
 learned from Lisp, Scheme, and Nemerle.  I'd like to study more how
 macros work in those systems before I'd feel comfortable committing to
 any particular design.  For instance what's the best way to handle
 hygene issues mentioned here:
 http://en.wikipedia.org/wiki/Hygienic_macro .

 There are probably some hygene issues there that should be considered
 for template mixins too.  For instance it's a long-standing issue that
 if you use a mixin from a library, you must import all the modules
 that mixin depends on, which breaks a kind of encapsulation of the
 mixin.  Mixins are probably also subject to the kind of environmental
 hygene problem described on that page, where a common function
 redefined in the current scope alters the intended behavior of the
 mixin.

Yes, my scheme would suffer from those issues also. For those who are interested in a problem case, here is the first one identified on that page written in the proposed form: macro INCI(i) mixin("{int a = 0; i++;}"); void main() { int a = 0; int b = 0; INCI(a); // translates to {int a = 0; a++;} INCI(b); // translates to {int a = 0; b++;} } Now a won't be incremented as expected because the local a declared by the macro shadows the behavior. I'll put it this way -- any problem that mixins suffer from, macros would suffer from as well. If we can fix those problems in mixins, then macros also become fixed. I don't see it worthwhile to propose a fixed macro system when mixins still suffer from the same issue.
 I think Walter had intended template mixins to take the place of
 macros.  They offer some features of macros but not all.  So once real
 macros exist, I wonder if there will be any real reason for them to
 continue existing.

The thing I think macros give you over mixins is their usage is simple and looks like part of the API. Other than that, I don't think mixins are any less powerful. For example, instead of writing: log.logError("bad error occurred with object: " ~ expensiveObjectStringification(obj)); I can do the correct thing via a mixin with: mixin(doLog("log", "error", "\"bad error occurred with object: \" ~ expensiveObjectStringification(obj))")); Where doLog is a CTFE function that rewrites the code as the macro does. But the first looks *sooo* much better :) -Steve
Nov 23 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Mon, Nov 23, 2009 at 12:11 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 On Mon, 23 Nov 2009 12:49:01 -0500, Bill Baxter <wbaxter gmail.com> wrote=

 On Mon, Nov 23, 2009 at 5:32 AM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 On Mon, 23 Nov 2009 07:38:32 -0500, Bill Baxter <wbaxter gmail.com>
 wrote:

 On Mon, Nov 23, 2009 at 3:12 AM, Don <nospam nospam.com> wrote:

 This sounds like a job for better mixin syntax.
 .
 So let "template#(args)" be equivalent to "mixin(template!(args))".

 Then you can do

 auto statement =3D db.execute#(`select $visitcars.name from table wh=






 $visitcars.id > 100 && $visitcars.surname Like "A*"`);

Yeah, something like that. Or it could mixin automatically. eg if macro foo(args...) foo(args) meant =A0mixin(foo(args)).

This is what I've been thinking too. But we might want there to be more to a macro than that. =A0For instan=




 most macro parameters are strings and the '(string this, string that,
 string theOther)', list of parameters doesn't look so great. =A0And
 requiring the strings to be quoted on the calling side, also makes the
 call side rather ugly. =A0It may be better to have arguments
 automatically convert to some sort of AST type which supports some
 introspection, and can be converted back to a string of code easily.

 So I think jumping on just making macro mean "mixin automatically"
 right now may limit our future choices too much.

What about this: http://www.digitalmars.com/webnews/newsgroups.php?art_group=3Ddigitalma=



 Quoting from there:
 """
 macro doit(x, y, z) mixin("x" ~ "y" ~ "z"); // allow easy syntax for
 quoting parameters, since mixins are all about stringification.

 doit(a, b, c) =3D> mixin("abc");
 """

 What happens if you want to have the string "x", just a plain x, in the
 mixin?

Don't name your parameter x. =A0The author of the macro is charge of the =

 of its parameters, if you need a certain string, don't use it as a parame=

 name. =A0I would say that I wouldn't expect a global search and replace, =

 matching symbols would be replaced, for example:

 macro doit(x) mixin("xx =3D x;");

 doit(hi);

 would result in xx =3D hi;

 Other than that, I think I don't know enough about the lessons to be
 learned from Lisp, Scheme, and Nemerle. =A0I'd like to study more how
 macros work in those systems before I'd feel comfortable committing to
 any particular design. =A0For instance what's the best way to handle
 hygene issues mentioned here:
 http://en.wikipedia.org/wiki/Hygienic_macro .

 There are probably some hygene issues there that should be considered
 for template mixins too. =A0For instance it's a long-standing issue that
 if you use a mixin from a library, you must import all the modules
 that mixin depends on, which breaks a kind of encapsulation of the
 mixin. =A0Mixins are probably also subject to the kind of environmental
 hygene problem described on that page, where a common function
 redefined in the current scope alters the intended behavior of the
 mixin.

Yes, my scheme would suffer from those issues also. =A0For those who are interested in a problem case, here is the first one identified on that pa=

 written in the proposed form:

 macro INCI(i) mixin("{int a =3D 0; i++;}");

 void main()
 {
 =A0int a =3D 0;
 =A0int b =3D 0;
 =A0INCI(a); // translates to {int a =3D 0; a++;}
 =A0INCI(b); // translates to {int a =3D 0; b++;}
 }

 Now a won't be incremented as expected because the local a declared by th=

 macro shadows the behavior.

 I'll put it this way -- any problem that mixins suffer from, macros would
 suffer from as well. =A0If we can fix those problems in mixins, then macr=

 also become fixed. =A0I don't see it worthwhile to propose a fixed macro
 system when mixins still suffer from the same issue.

 I think Walter had intended template mixins to take the place of
 macros. =A0They offer some features of macros but not all. =A0So once re=


 macros exist, I wonder if there will be any real reason for them to
 continue existing.

The thing I think macros give you over mixins is their usage is simple an=

 looks like part of the API. =A0Other than that, I don't think mixins are =

 less powerful.

Note that I was talking about template mixins, not string mixins. But really if we have macros, both template mixins and string mixins may be redundant. --bb
Nov 23 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 23 Nov 2009 15:22:35 -0500, Bill Baxter <wbaxter gmail.com> wrote:

 On Mon, Nov 23, 2009 at 12:11 PM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 On Mon, 23 Nov 2009 12:49:01 -0500, Bill Baxter <wbaxter gmail.com>  
 wrote:
 I think Walter had intended template mixins to take the place of
 macros.  They offer some features of macros but not all.  So once real
 macros exist, I wonder if there will be any real reason for them to
 continue existing.

The thing I think macros give you over mixins is their usage is simple and looks like part of the API. Other than that, I don't think mixins are any less powerful.

Note that I was talking about template mixins, not string mixins.

Yes, template mixins seem to be less useful because you cannot simply write statements inside a template block.
 But really if we have macros, both template mixins and string mixins
 may be redundant.

The nice thing about having macros be a simpler syntax to do mixins is that mixins are a proven entity that work to do just about anything. Some of the wizardry I've seen is amazing! I'm unsure that a) macros could make mixins obsolete and b) macros should be significantly different than mixins. -Steve
Nov 23 2009
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:

 How about

      auto template MixMeInAutomatically(T) { ... }

      void main()
      {
          MixMeInAutomatically!int;
          ...
      }

 Would this be ambiguous? It would be using auto for something completely  
 new, but it would at least make sense. (More so than macro, in my  
 opinion.)

 -Lars

I believe I have suggested this syntax earlier: mixin template foo( ) { } struct S { foo!(); } I'm unsure if there would be ambiguities, though. -- Simen
Nov 23 2009
prev sibling next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
yigal chripun wrote:

 aarti_pl Wrote:

 
 There's nothing more hideous than all those frameworks in Java/C++ that
 try to re-enginer SQL into functions, templates, LINQ, whatever. SQL *is*
 a perfectly designed language for its purpose and it doesn't need to be
 redisnged! The only problem with this is the type-safety when embedding
 sql as string in a host language. the solution is two-phased:

I disagree. There are a couple of problems with using Sql strings inside regular code: - no help from the IDE whatsoever. Imagine writing your D program in notepad, then instead of compiling it in advance, you compile it at runtime: losing all benefit from the static type checking and whatever the IDE offers you (highlighting and autocomplete). This would be completely absurd yet you prefer it with sql? Of course you can write queries in a specialized environment, somewhat better but it also sucks. - mapping relational data to objects is a sucky, boring, lengthy and error prone task. In my experience a simple ORM tool such as Linq-to-Sql makes life so much easier. RoR has this too, it's a blessing. Now if you want to do a big part of your logic on the database instead of simply using it as storage, that may be a different story. (I still think it sucks though)
 phase a is simple, look at the C# API for postgres (I think). The query is
 one string like: "select * from table where :a > 42", the :name is a place
 holder for the host-language variable, and you call an API to bind those
 :names to variables in a type-safe way. the downside is that it's verbose.
  
 phase b is what Nemerle does with the above - it has an AST macro to wrap
 the above so you can write your query directly and it is checked as
 compile-time.
 
 No operators were abused in implementing this.

I fail to see how this is any different than Linq. Granted, you just reproduce the SQL language and ignore any mapping to Objects, but other than that it is just the same but with a different technology. (Linq is not only about abstracting sql by the way, it does a lot more)
Nov 23 2009
next sibling parent reply aarti_pl <aarti interia.pl> writes:
Lutger pisze:
 yigal chripun wrote:
 
 aarti_pl Wrote:

 There's nothing more hideous than all those frameworks in Java/C++ that
 try to re-enginer SQL into functions, templates, LINQ, whatever. SQL *is*
 a perfectly designed language for its purpose and it doesn't need to be
 redisnged! The only problem with this is the type-safety when embedding
 sql as string in a host language. the solution is two-phased:

I disagree. There are a couple of problems with using Sql strings inside regular code: - no help from the IDE whatsoever. Imagine writing your D program in notepad, then instead of compiling it in advance, you compile it at runtime: losing all benefit from the static type checking and whatever the IDE offers you (highlighting and autocomplete). This would be completely absurd yet you prefer it with sql? Of course you can write queries in a specialized environment, somewhat better but it also sucks.

Thanks for this post. It is basically answer to other (rather dismissive) posts. In addition to what you said, you get from IDE also possibility to refactor your database columns/names/types etc. All with static checks in your code. After change you know immediately what should be changed. (*it is possible at least in my framework, I don't know if it is possible in other frameworks).
 - mapping relational data to objects is a sucky, boring, lengthy and error 
 prone task.
 In my experience a simple ORM tool such as Linq-to-Sql makes life so much 
 easier. RoR has this too, it's a blessing.
 
 Now if you want to do a big part of your logic on the database instead of 
 simply using it as storage, that may be a different story. (I still think it 
 sucks though)

Well, I have different view on this. Personally I think that it is much better (faster, easier) to pass tables in the application. But after defining SQL query (in object oriented way) you can do whatever you want: you can change your SQL object into table of data or into objects. You can also use these object oriented queries to generate different SQL dialects for different databases or you can generate hashes for using them as keys in your cache. Additionally in my framework you can pass around parts of SQL e.g. : WhereExpression exp = Where(More(visitcards.id, 100)); You basically *CAN NOT* do it when just using strings. So I think such a way of defining DSLs in mother language have its merits. String is not enough.
 phase a is simple, look at the C# API for postgres (I think). The query is
 one string like: "select * from table where :a > 42", the :name is a place
 holder for the host-language variable, and you call an API to bind those
 :names to variables in a type-safe way. the downside is that it's verbose.
  
 phase b is what Nemerle does with the above - it has an AST macro to wrap
 the above so you can write your query directly and it is checked as
 compile-time.

 No operators were abused in implementing this.

I fail to see how this is any different than Linq. Granted, you just reproduce the SQL language and ignore any mapping to Objects, but other than that it is just the same but with a different technology. (Linq is not only about abstracting sql by the way, it does a lot more)

I would like to add that probably many of DSL languages would never be created if mother languages would be expressive enough. And additionally, can any of opponents explain what is so wrong with operator overloading suggested by me in last emails? (Pseudocode - I didn't check exact syntax): RES opInfix(alias str)(T val) { ... } ... auto expr = Where((visitcards.id `>` 100) `AND` (visitcards.surname `Like` "A*")); (Please note that when overloaded operator is used it is denoted with `` (it can be probably any definition of string). I think it would be good enough solution and thanks to this operator overloading will be clearly visible in calling code). And dear opponents please propose how to solve above mentioned problems with DSL languages as strings ;-) If there will be a way to solve all those problems cleanly - I am all for not using operator overloading :-) Best Regards Marcin Kuszczak
Nov 23 2009
parent reply Don <nospam nospam.com> writes:
aarti_pl wrote:
 Lutger pisze:
 yigal chripun wrote:

 aarti_pl Wrote:

 There's nothing more hideous than all those frameworks in Java/C++ that
 try to re-enginer SQL into functions, templates, LINQ, whatever. SQL 
 *is*
 a perfectly designed language for its purpose and it doesn't need to be
 redisnged! The only problem with this is the type-safety when embedding
 sql as string in a host language. the solution is two-phased:

I disagree. There are a couple of problems with using Sql strings inside regular code: - no help from the IDE whatsoever. Imagine writing your D program in notepad, then instead of compiling it in advance, you compile it at runtime: losing all benefit from the static type checking and whatever the IDE offers you (highlighting and autocomplete). This would be completely absurd yet you prefer it with sql? Of course you can write queries in a specialized environment, somewhat better but it also sucks.

Thanks for this post. It is basically answer to other (rather dismissive) posts. In addition to what you said, you get from IDE also possibility to refactor your database columns/names/types etc. All with static checks in your code. After change you know immediately what should be changed. (*it is possible at least in my framework, I don't know if it is possible in other frameworks).

Yes, I think IDE integration is one of the biggest issues facing macros.
 Additionally in my framework you can pass around parts of SQL e.g. :
 WhereExpression exp = Where(More(visitcards.id, 100));
 
 You basically *CAN NOT* do it when just using strings. 

Of course you can define a where clause using strings. (I'm not sure when you'd want to, though. I suspect that the fact that you can do it in your framework, is an implementation detail rather than a design goal. It's easy to think of uses for run-time generated naked WHERE clauses, but much harder for compile-time ones).
 phase a is simple, look at the C# API for postgres (I think). The 
 query is
 one string like: "select * from table where :a > 42", the :name is a 
 place
 holder for the host-language variable, and you call an API to bind those
 :names to variables in a type-safe way. the downside is that it's 
 verbose.
  
 phase b is what Nemerle does with the above - it has an AST macro to 
 wrap
 the above so you can write your query directly and it is checked as
 compile-time.

 No operators were abused in implementing this.

I fail to see how this is any different than Linq. Granted, you just reproduce the SQL language and ignore any mapping to Objects, but other than that it is just the same but with a different technology.


That *is* the difference! It's exactly what you'd do in a run-time API, but it is checked at compile time. IMHO, the ideal for metaprogramming is that you can hardly tell that you are using it. (BTW, that's why I'm a huge fan of CTFE).
 (Linq is not only about abstracting sql by the way, it does a lot more)

I would like to add that probably many of DSL languages would never be created if mother languages would be expressive enough.

Yes, I've worked with some DSLs for which that was definitely true.
 And additionally, can any of opponents explain what is so wrong with 
 operator overloading suggested by me in last emails? (Pseudocode - I 
 didn't check exact syntax):
 
 RES opInfix(alias str)(T val) {
 ...
 }
 ...
 auto expr = Where((visitcards.id `>` 100) `AND` (visitcards.surname 
 `Like` "A*"));

 
 (Please note that when overloaded operator is used it is denoted with `` 
 (it can be probably any definition of string). I think it would be good 
 enough solution and thanks to this operator overloading will be clearly 
 visible in calling code).

`AND` is not operator overloading in the traditional sense. This is something else. You're proposing a whole new infix notation, and it's difficult to evaluate it without knowing how it would work. I don't understand why `Like` is an operator, but `Where` is not. You haven't addressed operator precedence. And I still don't think it looks terribly good for SQL. With: id `>` 100 users would always be thinking, "why can't I just write id > 100 ? That ` is so annoying!"
Nov 24 2009
parent reply aarti_pl <aarti interia.pl> writes:
Don pisze:
 
 Additionally in my framework you can pass around parts of SQL e.g. :
 WhereExpression exp = Where(More(visitcards.id, 100));

 You basically *CAN NOT* do it when just using strings. 

Of course you can define a where clause using strings. (I'm not sure when you'd want to, though. I suspect that the fact that you can do it in your framework, is an implementation detail rather than a design goal. It's easy to think of uses for run-time generated naked WHERE clauses, but much harder for compile-time ones).

Not exactly. At least it was not the case last time we talked about it: *I will give here only NG post numbers* 79272 Domain Specific Languages in D; was: C++, D: Dinosaurs? 81026 Operator overloading 81078 81393 And you finally agreed with me that it is not possible. So I take it proven :-) 81424 Possibility to split whole SQL statement into parts is useful. You can mix & match these parts together as you want. It is similar as you want to split you big chunk of code into smaller parts. You can for example make separate expressions objects and then put them one by one into Where().
 `AND` is not operator overloading in the traditional sense. This is 
 something else. You're proposing a whole new infix notation, and it's 
 difficult to evaluate it without knowing how it would work.

Well, with Andrei's proposition it is obvious for me that it should be generalized. I stated it already in: 81392 (almost one year ago) I will cite part of this e-mail: *<citation>* Exactly. My first thoughts was to allow defining infix keywords/operators in a similar way as today we can define prefix operators: myFunc a b or just: myFunc(a, b); Why? Because they are use cases where infix notation is much, much more natural than prefix notation. So we still need: 1. a myFunc b - infix operator 2. a b myFunc - postfix operator *</citation>* After reading my old e-mail it seems that it can be further generalized: prefix(tuple_args) (tuple_args)postfix (tuple_args)infix(tuple_args) Ok. Just a thought :-) Some more about more precise definition of this feature (proposals, to think about it): 1. I don't agree that it is something different than traditional operator overloading. It is just generalization. 2. After including Andrei's proposal the biggest part of this feature will be already in language. 3. The only think to define is just how the caller side should like: a. Always demand `` when using operator overloading; (Pros: no abuse of operators - you always know when operator overloading is involved; Cons: doesn't look so good, especially in cases where you would expect plain symbols) b. Don't demand `` in case of some standard operators like <>+-*/ etc. In other cases demand ``(Pros: Looks better; Cons: you will not always know that operator overloading is involved) c. Demand `` always when there is standard operator defined or operator is not symbol, but identifier. d. Don't allow redefinition of same operator Above concepts must be discussed, but it seems that there is not enough courage in NG to change current situation. Well it's strange that the feature is called 'operator overloading' - it's quite obvious that it's about defining some special functions. And IMHO some other languages got it right.
 I don't understand why `Like` is an operator, but `Where` is not. You 
 haven't addressed operator precedence.

'Like' against 'Where': it's definitely implementation detail of my framework. I don't think we should discuss it.
 
 And I still don't think it looks terribly good for SQL. With:
 id `>` 100
 users would always be thinking, "why can't I just write id > 100 ? That 
 ` is so annoying!"

Please believe me: it's 3000 times better than current situation. Additionally using such framework is pure pleasure and you want miss string SQLs even in current, bad situation :-) Best Regards Marcin Kuszczak (aarti_pl)
Nov 24 2009
parent reply Don <nospam nospam.com> writes:
aarti_pl wrote:
 Don pisze:
 Additionally in my framework you can pass around parts of SQL e.g. :
 WhereExpression exp = Where(More(visitcards.id, 100));

 You basically *CAN NOT* do it when just using strings. 

Of course you can define a where clause using strings. (I'm not sure when you'd want to, though. I suspect that the fact that you can do it in your framework, is an implementation detail rather than a design goal. It's easy to think of uses for run-time generated naked WHERE clauses, but much harder for compile-time ones).

Not exactly. At least it was not the case last time we talked about it: *I will give here only NG post numbers* 79272 Domain Specific Languages in D; was: C++, D: Dinosaurs? 81026 Operator overloading 81078 81393 And you finally agreed with me that it is not possible. So I take it proven :-) 81424

I believe I was agreeing that it wasn't possible to do it with a single SQL ctfe function.
 
 Possibility to split whole SQL statement into parts is useful. You can 
 mix & match these parts together as you want. It is similar as you want 
 to split you big chunk of code into smaller parts. You can for example 
 make separate expressions objects and then put them one by one into 
 Where().
 
 `AND` is not operator overloading in the traditional sense. This is 
 something else. You're proposing a whole new infix notation, and it's 
 difficult to evaluate it without knowing how it would work.

Well, with Andrei's proposition it is obvious for me that it should be generalized. I stated it already in: 81392 (almost one year ago) I will cite part of this e-mail: *<citation>* Exactly. My first thoughts was to allow defining infix keywords/operators in a similar way as today we can define prefix operators: myFunc a b or just: myFunc(a, b); Why? Because they are use cases where infix notation is much, much more natural than prefix notation. So we still need: 1. a myFunc b - infix operator 2. a b myFunc - postfix operator *</citation>* After reading my old e-mail it seems that it can be further generalized: prefix(tuple_args) (tuple_args)postfix (tuple_args)infix(tuple_args) Ok. Just a thought :-)

To quote something I said in that last post: "My point is simply: creating syntax trees is what you're using operator overloading for. You're actually not creating operations."
 Some more about more precise definition of this feature (proposals, to 
 think about it):
 1. I don't agree that it is something different than traditional 
 operator overloading. It is just generalization.
 2. After including Andrei's proposal the biggest part of this feature 
 will be already in language.
 3. The only think to define is just how the caller side should like:
 a. Always demand `` when using operator overloading; (Pros: no abuse of 
 operators - you always know when operator overloading is involved; Cons: 
 doesn't look so good, especially in cases where you would expect plain 
 symbols)
 b. Don't demand `` in case of some standard operators like <>+-*/ etc. 
 In other cases demand ``(Pros: Looks better; Cons: you will not always 
 know that operator overloading is involved)
 c. Demand `` always when there is standard operator defined or operator 
 is not symbol, but identifier.
 d. Don't allow redefinition of same operator
 
 Above concepts must be discussed, but it seems that there is not enough 
 courage in NG to change current situation.

Please. It's been very clearly stated, long ago, that : MACROS ARE DEFERRED TO D3.
 Well it's strange that the feature is called 'operator overloading' - 
 it's quite obvious that it's about defining some special functions. And 
 IMHO some other languages got it right.

IMHO, equating 'operator overloading' with special functions is a colossal mistake. I'm convinced that C++ got it badly wrong.
 And I still don't think it looks terribly good for SQL. With:
 id `>` 100
 users would always be thinking, "why can't I just write id > 100 ? 
 That ` is so annoying!"

Please believe me: it's 3000 times better than current situation.

I don't disagree with that. I just think we should aim higher.
Nov 25 2009
parent reply Don <nospam nospam.com> writes:
Don wrote:
 aarti_pl wrote:
 Don pisze:
 Additionally in my framework you can pass around parts of SQL e.g. :
 WhereExpression exp = Where(More(visitcards.id, 100));

 You basically *CAN NOT* do it when just using strings. 

Of course you can define a where clause using strings.



Even today, it's easy to take a CTFE/string mixin front-end and create a wrapper over your framework! So it's trivially easy to prove it can be done. You can literally do anything. Functionality is not the problem -- the challenge is to make it nice. The CTFE/mixin combo is not nice, but it definitely has the power. I'm thinking something like: auto result = SQL{ SELECT * FROM :localvar WHERE name LIKE 'abc*' AND price > 300 ORDER BY date DESC } where SQL is a DSL macro, and the {} are delimiters indicating that it's a DSL, not normal D code. That's a syntax which is currently available.
Nov 25 2009
parent Don <nospam nospam.com> writes:
Denis Koroskin wrote:
 On Wed, 25 Nov 2009 11:42:53 +0300, Don <nospam nospam.com> wrote:
 
 Don wrote:
 aarti_pl wrote:
 Don pisze:
 Additionally in my framework you can pass around parts of SQL e.g. :
 WhereExpression exp = Where(More(visitcards.id, 100));

 You basically *CAN NOT* do it when just using strings.

Of course you can define a where clause using strings.



Even today, it's easy to take a CTFE/string mixin front-end and create a wrapper over your framework! So it's trivially easy to prove it can be done. You can literally do anything. Functionality is not the problem -- the challenge is to make it nice. The CTFE/mixin combo is not nice, but it definitely has the power. I'm thinking something like: auto result = SQL{ SELECT * FROM :localvar WHERE name LIKE 'abc*' AND price > 300 ORDER BY date DESC } where SQL is a DSL macro, and the {} are delimiters indicating that it's a DSL, not normal D code. That's a syntax which is currently available.

Interesting! Then q{ Foo } syntax would be just a simple macro that returns a string, not a built-in language construct.

I'm just brainstorming, though.
Nov 25 2009
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 25 Nov 2009 11:42:53 +0300, Don <nospam nospam.com> wrote:

 Don wrote:
 aarti_pl wrote:
 Don pisze:
 Additionally in my framework you can pass around parts of SQL e.g. :
 WhereExpression exp = Where(More(visitcards.id, 100));

 You basically *CAN NOT* do it when just using strings.

Of course you can define a where clause using strings.



Even today, it's easy to take a CTFE/string mixin front-end and create a wrapper over your framework! So it's trivially easy to prove it can be done. You can literally do anything. Functionality is not the problem -- the challenge is to make it nice. The CTFE/mixin combo is not nice, but it definitely has the power. I'm thinking something like: auto result = SQL{ SELECT * FROM :localvar WHERE name LIKE 'abc*' AND price > 300 ORDER BY date DESC } where SQL is a DSL macro, and the {} are delimiters indicating that it's a DSL, not normal D code. That's a syntax which is currently available.

Interesting! Then q{ Foo } syntax would be just a simple macro that returns a string, not a built-in language construct.
Nov 25 2009
prev sibling parent aarti_pl <aarti interia.pl> writes:
yigal chripun pisze:
 aarti_pl Wrote:
 
 Walter Bright pisze:
 Don wrote:
 There's not many sensible operators anyway. opPow is the only missing 
 one that's present in many other general-purpose languages. The only 
 other ones I think are remotely interesting are dot and cross product.

 Anything beyond that, you generally want a full DSL, probably with 
 different precendence and associativity rules. Eg, for regexp, you'd 
 want postfix * and + operators. There are examples of clever things 
 done in C++  with operator overloading, but I think that's just 
 because it's the only way to do DSLs in C++.

I think more about it, it's just too clever. I think it's more operator overloading abuse now.
 I don't think the applications are there.


code might be awful when operator overloading will be abused. But I have in mind one very convincing example. I defined in D/Java SQL syntax. They are also other frameworks which do the same. What can I say about my experiences with using such framework: it is very, very powerful concept. It cuts time necessary to develop application, makes sql statements type safe and allows to pass around parts of sql statements inside application. It also makes easy refactoring of sql statement (especially in Java). Its huge win comparing it to defining DSL as strings. It's hard to explain just in few sentences all details. I have already done it long time ago, and in my first post I provided links. Problem with current approach is that I have to define SQL in D/Java in following way: auto statement = Select(visitcars.name).Where(And(More(visitcards.id, 100), Like(visitcards.surname, "A*"))); Please look at code in Where(). It's so awfuuuuulllllll! It would be so much better to write: auto statement = Select(visitcars.name).Where((visitcards.id `>` 100) `AND` (visitcards.surname `Like` "A*")); I used here syntax which you have proposed with delimiter ``. I think it is good enough solution for such purpose. But please, don't underestimate problem! Many DSL languages would never appear if languages would be good enough. As I said solution with delimiter is good enough for me. It has another advantage that it clearly shows in code that you have overloaded operator here, so no surprises here. Additionally when you implement template function: opInfix('AND')(val0, val1); you pass string into template. So I see it quite intuitive that you use string as operator: ``. Maybe there will be not necessary to change current behavior that `` defines string. I think we have good possibility to open this door now. It can be even implemented later, but I would wish just not to close this door now :-) BR Marcin Kuszczak (aarti_pl)

There's nothing more hideous than all those frameworks in Java/C++ that try to re-enginer SQL into functions, templates, LINQ, whatever. SQL *is* a perfectly designed language for its purpose and it doesn't need to be redisnged! The only problem with this is the type-safety when embedding sql as string in a host language. the solution is two-phased: phase a is simple, look at the C# API for postgres (I think). The query is one string like:

 "select * from table where :a > 42", the :name is a place holder for the
host-language variable, and you call an API to bind those :names to variables
in a type-safe way. the downside is that it's verbose. 
  
 phase b is what Nemerle does with the above - it has an AST macro to wrap the
above so you can write your query directly and it is checked as compile-time. 
 
 No operators were abused in implementing this. 

Please see for my comments into answer to Lutger post. BR Marcin Kuszczak (aarti_pl)
Nov 23 2009