digitalmars.D - [std.database] at compile time
- foobar (6/6) Oct 14 2011 Has anyone looked at Nemerle's design for this?
- Jacob Carlborg (5/11) Oct 14 2011 You cannot connect to a database in D at compile time. You could some
- Andrei Alexandrescu (4/18) Oct 14 2011 A little SQL interpreter can be written that figures out e.g. the names
- foobar (6/27) Oct 14 2011 The downsides with writing a separate SQL interpreter are:
- Dmitry Olshansky (5/32) Oct 14 2011 The upside is that you can at least rebuild your app when database is
- foobar (2/42) Oct 14 2011 That's just silly, why would you use a validating SQL macro if you do no...
- Jacob Carlborg (5/25) Oct 14 2011 But you still won't be able to verify the columns to the actual database...
- Graham Fawcett (8/35) Oct 14 2011 One approach would be to write a separate tool that connects to the
- Justin Whear (7/20) Oct 14 2011 This is actually possible now. I wrote a little CTFE parser for CREATE
- bls (11/17) Oct 15 2011 Cool! Hesitate to share the code?
- Justin Whear (20/31) Oct 17 2011 Sure, here it is: http://pastebin.com/KSyuk8HN
- Adam D. Ruppe (7/7) Oct 17 2011 Justin Whear:
- dennis luehring (19/23) Oct 14 2011 what about data/fields that don't comes out of the model?
- Graham Fawcett (7/34) Oct 14 2011 Good point. I wasn't thinking of a tool to validate arbitrary SQL
- dennis luehring (9/13) Oct 14 2011 what i like to see here are both parts - staticaly checked (if possible)...
- Ary Manzana (5/39) Oct 15 2011 Yeah, but you need a separate tool.
- Marco Leise (5/50) Oct 15 2011 I wonder if that would work well with cross-compiling. If you blindly JI...
- foobar (4/59) Oct 15 2011 That is a good question.
- Don (5/58) Oct 15 2011 Exactly. I don't see how that could work. Cross compilation is a
- bls (18/20) Oct 15 2011 What about Compiler Hooks (enable LanguageXYZ to D Translation)
- Ary Manzana (34/87) Oct 15 2011 I don't understand this quite well. I want JITted functions to just
- Don (5/68) Oct 15 2011 You're assuming that the compiler can run the code it's generating. This...
- foobar (12/83) Oct 16 2011 This is quite possible in Nemerle's model of compilation.
- Ary Manzana (2/85) Oct 16 2011 Exactly!! :-)
- Ary Manzana (5/74) Oct 16 2011 Compile the function to be compile-time evaluated in X86. Compile the
Has anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.
Oct 14 2011
On 2011-10-14 12:19, foobar wrote:Has anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database. -- /Jacob Carlborg
Oct 14 2011
On 10/14/11 6:08 AM, Jacob Carlborg wrote:On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 14 2011
Andrei Alexandrescu Wrote:On 10/14/11 6:08 AM, Jacob Carlborg wrote:The downsides with writing a separate SQL interpreter are: a) No connection to the DB means no way to validate the schema, e.g. the db might not even have a 'name' column in the employees table. b) No way to validate the SQL per the exact version the DB uses. E.g. LIMIT vs. TOP and also DB vendor specific extensions to SQL syntax. c) NIH - implementing your own SQL interpreter when the DB vendor already provides it. oh, well, perhaps it would be possible with D3 once it supports proper macros. In any case, such a macro probably would be built atop the DB API currently being discussed.On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 14 2011
On 14.10.2011 19:13, foobar wrote:Andrei Alexandrescu Wrote:The upside is that you can at least rebuild your app when database is down or compile it on a separate machine.On 10/14/11 6:08 AM, Jacob Carlborg wrote:The downsides with writing a separate SQL interpreter are: a) No connection to the DB means no way to validate the schema, e.g. the db might not even have a 'name' column in the employees table.On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.b) No way to validate the SQL per the exact version the DB uses. E.g. LIMIT vs. TOP and also DB vendor specific extensions to SQL syntax. c) NIH - implementing your own SQL interpreter when the DB vendor already provides it. oh, well, perhaps it would be possible with D3 once it supports proper macros. In any case, such a macro probably would be built atop the DB API currently being discussed.-- Dmitry Olshansky
Oct 14 2011
Dmitry Olshansky Wrote:On 14.10.2011 19:13, foobar wrote:That's just silly, why would you use a validating SQL macro if you do not want (or don't have the environment set up) to validate the SQL?Andrei Alexandrescu Wrote:The upside is that you can at least rebuild your app when database is down or compile it on a separate machine.On 10/14/11 6:08 AM, Jacob Carlborg wrote:The downsides with writing a separate SQL interpreter are: a) No connection to the DB means no way to validate the schema, e.g. the db might not even have a 'name' column in the employees table.On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.b) No way to validate the SQL per the exact version the DB uses. E.g. LIMIT vs. TOP and also DB vendor specific extensions to SQL syntax. c) NIH - implementing your own SQL interpreter when the DB vendor already provides it. oh, well, perhaps it would be possible with D3 once it supports proper macros. In any case, such a macro probably would be built atop the DB API currently being discussed.-- Dmitry Olshansky
Oct 14 2011
On 2011-10-14 15:26, Andrei Alexandrescu wrote:On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme? -- /Jacob CarlborgOn 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 14 2011
On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler. GrahamOn 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 14 2011
Graham Fawcett wrote:This is actually possible now. I wrote a little CTFE parser for CREATE TABLE... statements, used mysql to dump a db, then used import() to include the dump and parse it at compile-time. I was actually using it to generate classes which mapped to the contents of each table (i.e. a "things" table would result in a "Thing" class which mapped the fields as properties). Obviously you need to keep the db dump up to date via an external tool.But you still won't be able to verify the columns to the actual database scheme?One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler. Graham
Oct 14 2011
Am 14.10.2011 22:29, schrieb Justin Whear:This is actually possible now. I wrote a little CTFE parser for CREATE TABLE... statements, used mysql to dump a db, then used import() to include the dump and parse it at compile-time. I was actually using it to generate classes which mapped to the contents of each table (i.e. a "things" table would result in a "Thing" class which mapped the fields as properties). Obviously you need to keep the db dump up to date via an external tool.Cool! Hesitate to share the code? I think we should have a two way tool. 1) Dump database structure and generate ORM classes. 2) ORM classes should validate against the database. (classname == tablename, or f.i. class customer { string tablename = "contact";) In case that the db-table does not exist, create it. In case that the ORM class is not in sync with the db-table a) alter the db-table or b) throw an exception. priority : datetimestamp. tools : std.traits and the orange serialisation lib my 2 cents
Oct 15 2011
Sure, here it is: http://pastebin.com/KSyuk8HN Usage would be something like: import std.stdio; import ccb.io.automap_table; mixin( MapTables!(import("school_system.sql"), true) ); void main() { Student a = new Student; a.student_name = "John Smith"; a.term = 1; writeln(a.student_name, ", ", a.term); students.insert(new Student()); students.commit(); } The sql file can be generated like so: $ mysqldump -d -h dbhost -u username -p password database_name Note that it's super hacky, literally written on the spur of the moment. I have a much cleaner, more robust version, but it currently sends the compiler into an infinite loop and I haven't touched it in a couple months. JustinAm 14.10.2011 22:29, schrieb Justin Whear:This is actually possible now. I wrote a little CTFE parser for CREATE TABLE... statements, used mysql to dump a db, then used import() to include the dump and parse it at compile-time. I was actually using it to generate classes which mapped to the contents of each table (i.e. a "things" table would result in a "Thing" class which mapped the fields as properties). Obviously you need to keep the db dump up to date via an external tool.Cool! Hesitate to share the code?
Oct 17 2011
Justin Whear: That's very similar to what I wrote in my database.d https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff Mine is super hacky, but hey, it works for me. I write up my tables as .sql files anyway so it's no added hassle. Then the mysql.queryDataObject function can create a dynamic object for a query. It works reasonably well.
Oct 17 2011
One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model.what about data/fields that don't comes out of the model? for example: select name_length_add_1, count(*) as counted from ( select (len(p.firstname) + 1) as name_length_add_1, p.* from persons as p inner join members as m on p.firstname == m.firstname ) as blub group by name_length_add_1 how is the "counted" field or "name_length_add_1" staticaly verified? people tend to think that sql is just simple table querying stuff - but thats not, not in the real world
Oct 14 2011
On Fri, 14 Oct 2011 23:58:45 +0200, dennis luehring wrote:Good point. I wasn't thinking of a tool to validate arbitrary SQL statements, but one that could validate a D model's correspondence with the database schema. Presumably the queries would be generated by the library. Best, GrahamOne approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model.what about data/fields that don't comes out of the model? for example: select name_length_add_1, count(*) as counted from ( select (len(p.firstname) + 1) as name_length_add_1, p.* from persons as p inner join members as m on p.firstname == m.firstname ) as blub group by name_length_add_1 how is the "counted" field or "name_length_add_1" staticaly verified? people tend to think that sql is just simple table querying stuff - but thats not, not in the real world
Oct 14 2011
Good point. I wasn't thinking of a tool to validate arbitrary SQL statements, but one that could validate a D model's correspondence with the database schema. Presumably the queries would be generated by the library.what i like to see here are both parts - staticaly checked (if possible) for faster development - but also runtime checked (maybe in form of an check-mode) for example: you've got a varchar(12) field - how many times have you seen an check for the inputsize not exceeding the 12 chars? or datetime, etc. not all databases got the same range for special type values but something like that could be to database/version specific
Oct 14 2011
On 10/14/11 5:16 PM, Graham Fawcett wrote:On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 15 2011
Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana <ary esperanto.org.ar>:On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 15 2011
Marco Leise Wrote:Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana <ary esperanto.org.ar>:That is a good question. In Nemerle's case, the language compiles to .NET bytecode. In addition, Nemerle Plugins are essentially compiler plugins which are compiled separately and loaded during compilation of your actual program. In D's case, If we choose the Nemerle design of separate compilation, the macro would be compiled for the host machine (32 bits in your example).On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 15 2011
On 15.10.2011 22:00, Marco Leise wrote:Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana <ary esperanto.org.ar>:Exactly. I don't see how that could work. Cross compilation is a critical feature for a systems language. It's a totally different situation from Nemerle, which has the luxury of restricting itself to systems with a .net JIT compiler.On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 15 2011
Am 16.10.2011 00:09, schrieb Don:It's a totally different situation from Nemerle, which has the luxury of restricting itself to systems with a .net JIT compiler.What about Compiler Hooks (enable LanguageXYZ to D Translation) Sure, strange idea but IMHO worth a second look. Consider that language _SQL_ will be translated into D at compile-time. void GetCustomersInParis(ref RowSet lhs_rs) { // Compiler Hook, call SQL2DTranslator. SQL { <DVALUE> lhs_rs = SELECT * FROM CUSTOMER WHERE CITY = "Paris"; } } // Generates lhs_rs = db.exexuteSQL("SELECT * FROM CUSTOMER WHERE CITY = 'Paris'") Assert( SQL2DTranslator("lhs_rs = SELECT * FROM CUSTOMER WHERE CITY = Paris" == "lhs_rs = db.exexuteSQL("SELECT * FROM CUSTOMER WHERE CITY = 'Paris'")" well it is late, maybe I need some sleep...
Oct 15 2011
On 10/15/11 5:00 PM, Marco Leise wrote:Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana <ary esperanto.org.ar>:I don't understand this quite well. I want JITted functions to just generate code that ultimately will be compiled. It's like what CTFE is doing now, except that instead of doing it by interpreting every bit and spec of the language you would compile the function, run it to generate code, and then compile the code for the target machine. An example: enum host = "localhost"; enum port = 3306; enum database = "foo"; enum password = "whatever"; string code_db(host, port, database, password) { auto db = new Database(host, port, database, password); auto str = ""; foreach(auto table; db) { str ~= "class " ~ table.name ~ " : Table {"; foreach(auto column; table.columns) { // Well, you get the idea... } str ~= "}"; } } // Now code_db must be executed at compile-time because it's assigned to an enum. Oh, but currently CTFE wouldn't be able to open a connection to the database. Well, it could, if you'd JIT it and then execute it. code_db just generates a string containing the table classes... so why, oh why, does the endianess of size_t matters? enum db = code_db(host, port, database, password); mixin(db); // I want to paste the string into the code, not sure this is the syntax --- Maybe I'm not taking something into account... what is it? Thanks, AryOn 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.
Oct 15 2011
On 16.10.2011 04:16, Ary Manzana wrote:On 10/15/11 5:00 PM, Marco Leise wrote:[snip]Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana <ary esperanto.org.ar>:I don't understand this quite well. I want JITted functions to just generate code that ultimately will be compiled. It's like what CTFE is doing now, except that instead of doing it by interpreting every bit and spec of the language you would compile the function, run it to generate code, and then compile the code for the target machine.On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.Maybe I'm not taking something into account... what is it?You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.
Oct 15 2011
Don Wrote:On 16.10.2011 04:16, Ary Manzana wrote:This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target. 2. cross-compiler loads the plugin and uses it during compilation of your code to the TARGET machine (arm). E.g. the SQL plugin will connect to db and verify your query against the db schema and will *generate* D code to query the db. the generated D code is compiled to the TARGET machine. The JIT to .net is merely an implementation detail for Nemerle which makes it much easier to implement. I don't see how Endianess or word size affects this model in any way.On 10/15/11 5:00 PM, Marco Leise wrote:[snip]Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana <ary esperanto.org.ar>:I don't understand this quite well. I want JITted functions to just generate code that ultimately will be compiled. It's like what CTFE is doing now, except that instead of doing it by interpreting every bit and spec of the language you would compile the function, run it to generate code, and then compile the code for the target machine.On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.Maybe I'm not taking something into account... what is it?You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.
Oct 16 2011
On 10/16/11 4:56 AM, foobar wrote:Don Wrote:Exactly!! :-)On 16.10.2011 04:16, Ary Manzana wrote:This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target. 2. cross-compiler loads the plugin and uses it during compilation of your code to the TARGET machine (arm). E.g. the SQL plugin will connect to db and verify your query against the db schema and will *generate* D code to query the db. the generated D code is compiled to the TARGET machine. The JIT to .net is merely an implementation detail for Nemerle which makes it much easier to implement. I don't see how Endianess or word size affects this model in any way.On 10/15/11 5:00 PM, Marco Leise wrote:[snip]Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana<ary esperanto.org.ar>:I don't understand this quite well. I want JITted functions to just generate code that ultimately will be compiled. It's like what CTFE is doing now, except that instead of doing it by interpreting every bit and spec of the language you would compile the function, run it to generate code, and then compile the code for the target machine.On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.Maybe I'm not taking something into account... what is it?You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.
Oct 16 2011
On 16.10.2011 17:39, Ary Manzana wrote:On 10/16/11 4:56 AM, foobar wrote:YES!!! This is the whole point. That model requires TWO backends. One for the host, one for the target. That is, it requires an entire backend PURELY FOR CTFE. Yes, of course it is POSSIBLE, but it is an incredible burden to place on a compiler vendor.Don Wrote:On 16.10.2011 04:16, Ary Manzana wrote:This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target.On 10/15/11 5:00 PM, Marco Leise wrote:[snip]Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana<ary esperanto.org.ar>:I don't understand this quite well. I want JITted functions to just generate code that ultimately will be compiled. It's like what CTFE is doing now, except that instead of doing it by interpreting every bit and spec of the language you would compile the function, run it to generate code, and then compile the code for the target machine.On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.Maybe I'm not taking something into account... what is it?You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.
Oct 16 2011
Don Wrote:On 16.10.2011 17:39, Ary Manzana wrote:How does that differ from the current situation? We already have a separate implementation of a D interpreter for CTFE. I disagree with the second point as well - Nothing forces the SAME compiler to contain two separate implementations as is now the case. In Fact you could compile the macros with a compiler of a different vendor. After all that's the purpose of an ABI, isn't it? In fact it makes the burden on the vendor much smaller since you remove the need for a separate interpreter.On 10/16/11 4:56 AM, foobar wrote:YES!!! This is the whole point. That model requires TWO backends. One for the host, one for the target. That is, it requires an entire backend PURELY FOR CTFE. Yes, of course it is POSSIBLE, but it is an incredible burden to place on a compiler vendor.Don Wrote:On 16.10.2011 04:16, Ary Manzana wrote:This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target.On 10/15/11 5:00 PM, Marco Leise wrote:[snip]Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana<ary esperanto.org.ar>:I don't understand this quite well. I want JITted functions to just generate code that ultimately will be compiled. It's like what CTFE is doing now, except that instead of doing it by interpreting every bit and spec of the language you would compile the function, run it to generate code, and then compile the code for the target machine.On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.Maybe I'm not taking something into account... what is it?You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.
Oct 16 2011
foobar Wrote:Don Wrote:I forgot to mention an additional aspect of this design - it greatly simplifies the language which also reduces the burden on the compiler vendor. You no longer need to support static constructs like "static if", CTFE, is(), pragma, etc. You also gain more capabilities with less effort, e.g you could connect to a DB at compile time to validate a SQL query or use regular IO functions from phobos.How does that differ from the current situation? We already have a separate implementation of a D interpreter for CTFE. I disagree with the second point as well - Nothing forces the SAME compiler to contain two separate implementations as is now the case. In Fact you could compile the macros with a compiler of a different vendor. After all that's the purpose of an ABI, isn't it? In fact it makes the burden on the vendor much smaller since you remove the need for a separate interpreter.YES!!! This is the whole point. That model requires TWO backends. One for the host, one for the target. That is, it requires an entire backend PURELY FOR CTFE. Yes, of course it is POSSIBLE, but it is an incredible burden to place on a compiler vendor.You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target.
Oct 16 2011
On 17.10.2011 01:43, foobar wrote:foobar Wrote:That's true, but it's quite different from a separate backend. The CTFE interpreter doesn't have much in common with a backend. It's more like a glue layer. Most of what's in there at the moment, is doing marshalling and error checking. Suppose instead, you made calls into a real backend. You'd still need a marshalling layer, first to get the syntax trees into native types for the backend, and secondly to convert the native types back into syntax trees. The thing is, you can be changing only part of a syntax tree (just one element of an array, for example) so if you used a native backend, the majority of the code in the CTFE interpreter would remain. Yes, there is an actual CTFE backend in there, but it's tiny.Don Wrote:How does that differ from the current situation? We already have a separate implementation of a D interpreter for CTFE.YES!!! This is the whole point. That model requires TWO backends. One for the host, one for the target. That is, it requires an entire backend PURELY FOR CTFE. Yes, of course it is POSSIBLE, but it is an incredible burden to place on a compiler vendor.You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target.I disagree with the second point as well - Nothing forces the SAME compiler to contain two separate implementations as is now the case. In Fact you could compile the macros with a compiler of a different vendor. After all that's the purpose of an ABI, isn't it? In fact it makes the burden on the vendor much smaller since you remove the need for a separate interpreter.I forgot to mention an additional aspect of this design - it greatly simplifies the language which also reduces the burden on the compiler vendor. You no longer need to support static constructs like "static if", CTFE, is(), pragma, etc. You also gain more capabilities with less effort, e.g you could connect to a DB at compile time to validate a SQL query or use regular IO functions from phobos.Statements of the form "XXX would make the compiler simpler" seem to come up quite often, and I can't remember a single one which was made with much knowledge of where the complexities are! For example, the most complex thing you listed is is(), because is(typeof()) accepts all kinds of things which normally wouldn't compile. This has implications for the whole compiler, and no changes in how CTFE is done would make it any simpler.e.g you could connect to a DB at compile time to validate a SQL queryor use regular IO functions from phobos. You know, I'm ýet to be convinced that that it's really desirable. The ability to put all your source in a repository and say, "the executable depends on this and nothing else", is IMHO of enormous value. Once you allow it to depend on the result of external function calls, it depends on all kinds of hidden variables, which are ephemeral, and it seems to me much better to completely separate that "information gathering" step from the compilation step. Note that since it's a snapshot, you *don't* have a guarantee that your SQL query is still valid by the time the code runs. BTW there's nothing in the present design which prevents CTFE from being implemented by doing a JIT to native code. I expect most implementations will go that way, but they'll be motivated by speed. Also I'm confused by this term "macros" that keeps popping up. I don't know why it's being used, and I don't know what it means.
Oct 18 2011
Don Wrote:On 17.10.2011 01:43, foobar wrote:I'm not sure I follow you here. macros as defined in Nemerle are simply compiler plugins that use hooks in the compiler front-end. Nemerle supports hooks at several levels, mostly at parsing and semantic analysis passes but I think also during lexing in order to allows syntax extensions. for instance at the parsing stage, the macro's input and output would be token streams. I don't understand how that requires a separate backend. It does require APIs/hooks into the compiler passes. The macro itself is a regular program - implemented in Nemerle and compiled into a dll.foobar Wrote:That's true, but it's quite different from a separate backend. The CTFE interpreter doesn't have much in common with a backend. It's more like a glue layer. Most of what's in there at the moment, is doing marshalling and error checking. Suppose instead, you made calls into a real backend. You'd still need a marshalling layer, first to get the syntax trees into native types for the backend, and secondly to convert the native types back into syntax trees. The thing is, you can be changing only part of a syntax tree (just one element of an array, for example) so if you used a native backend, the majority of the code in the CTFE interpreter would remain. Yes, there is an actual CTFE backend in there, but it's tiny.Don Wrote:How does that differ from the current situation? We already have a separate implementation of a D interpreter for CTFE.YES!!! This is the whole point. That model requires TWO backends. One for the host, one for the target. That is, it requires an entire backend PURELY FOR CTFE. Yes, of course it is POSSIBLE, but it is an incredible burden to place on a compiler vendor.You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target.I actually said it would make the _language_ simpler. it makes the language more regular in that you use the same syntax to implement the macro itself. No need to maintain an additional set of compile-time syntax. This in turn would simplify the implementation of the compiler. the above list should contain all compile-time features (I didn't mention templates and traits) Since a macro has hooks into the semantic pass it can do all sorts of transforms directly on the abstract syntax tree - modifying the data structures in the compiler's memory. this means you use _regular_ code in combination with a compiler API instead of special syntax. E.g. traits and is(typof()) would be regular functions (part of the API) instead of language features.I disagree with the second point as well - Nothing forces the SAME compiler to contain two separate implementations as is now the case. In Fact you could compile the macros with a compiler of a different vendor. After all that's the purpose of an ABI, isn't it? In fact it makes the burden on the vendor much smaller since you remove the need for a separate interpreter.I forgot to mention an additional aspect of this design - it greatly simplifies the language which also reduces the burden on the compiler vendor. You no longer need to support static constructs like "static if", CTFE, is(), pragma, etc. You also gain more capabilities with less effort, e.g you could connect to a DB at compile time to validate a SQL query or use regular IO functions from phobos.Statements of the form "XXX would make the compiler simpler" seem to come up quite often, and I can't remember a single one which was made with much knowledge of where the complexities are! For example, the most complex thing you listed is is(), because is(typeof()) accepts all kinds of things which normally wouldn't compile. This has implications for the whole compiler, and no changes in how CTFE is done would make it any simpler.> e.g you could connect to a DB at compile time to validate a SQL query or use regular IO functions from phobos. You know, I'm yet to be convinced that that it's really desirable. The ability to put all your source in a repository and say, "the executable depends on this and nothing else", is IMHO of enormous value. Once you allow it to depend on the result of external function calls, it depends on all kinds of hidden variables, which are ephemeral, and it seems to me much better to completely separate that "information gathering" step from the compilation step. Note that since it's a snapshot, you *don't* have a guarantee that your SQL query is still valid by the time the code runs.I agree this adds dependencies to the compilation process. However, IIUC, D already allows adding vendor extensions with pragma. At the moment this requires to changes the compiler's source. macros simply extend this notion with shared objects. Look for example at the pragma for printing at compile-time. instead of implementing it in as part of the compiler, you could simply use phobos' writeln.BTW there's nothing in the present design which prevents CTFE from being implemented by doing a JIT to native code. I expect most implementations will go that way, but they'll be motivated by speed. Also I'm confused by this term "macros" that keeps popping up. I don't know why it's being used, and I don't know what it means.The term comes from lisp.
Oct 18 2011
On 19.10.2011 01:52, foobar wrote:Don Wrote:On 17.10.2011 01:43, foobar wrote:I'm not sure I follow you here. macros as defined in Nemerle are simply compiler plugins that use hooks in the compiler front-end. Nemerle supports hooks at several levels, mostly at parsing and semantic analysis passes but I think also during lexing in order to allows syntax extensions. for instance at the parsing stage, the macro's input and output would be token streams. I don't understand how that requires a separate backend.foobar Wrote:That's true, but it's quite different from a separate backend. The CTFE interpreter doesn't have much in common with a backend. It's more like a glue layer. Most of what's in there at the moment, is doing marshalling and error checking. Suppose instead, you made calls into a real backend. You'd still need a marshalling layer, first to get the syntax trees into native types for the backend, and secondly to convert the native types back into syntax trees. The thing is, you can be changing only part of a syntax tree (just one element of an array, for example) so if you used a native backend, the majority of the code in the CTFE interpreter would remain. Yes, there is an actual CTFE backend in there, but it's tiny.Don Wrote:How does that differ from the current situation? We already have a separate implementation of a D interpreter for CTFE.YES!!! This is the whole point. That model requires TWO backends. One for the host, one for the target. That is, it requires an entire backend PURELY FOR CTFE. Yes, of course it is POSSIBLE, but it is an incredible burden to place on a compiler vendor.You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.This is quite possible in Nemerle's model of compilation. This is the same concept as XLST - a macro is a high level transform from D code to D code. 1. compile the macro ahead of time into a loadable compiler module/plugin. the plugin is compiled for the HOST machine (x86) either by a separate compiler or by a cross-compiler that can also compile to its HOST target.It does require APIs/hooks into the compiler passes.Whatever code the compiler calls (compiler plugin, or JITted code), the compiler needs to be able to pass parameters to it, and return them. How can it do that? For example, all extant D compilers are written in C++ and they can't call D code directly.The macro itself is a regular program - implemented in Nemerle and compiled into a dll.I don't understand. D has almost no compile-time syntax.I actually said it would make the _language_ simpler. it makes the language more regular in that you use the same syntax to implement the macro itself. No need to maintain an additional set of compile-time syntax.I disagree with the second point as well - Nothing forces the SAME compiler to contain two separate implementations as is now the case. In Fact you could compile the macros with a compiler of a different vendor. After all that's the purpose of an ABI, isn't it? In fact it makes the burden on the vendor much smaller since you remove the need for a separate interpreter.I forgot to mention an additional aspect of this design - it greatly simplifies the language which also reduces the burden on the compiler vendor. You no longer need to support static constructs like "static if", CTFE, is(), pragma, etc. You also gain more capabilities with less effort, e.g you could connect to a DB at compile time to validate a SQL query or use regular IO functions from phobos.Statements of the form "XXX would make the compiler simpler" seem to come up quite often, and I can't remember a single one which was made with much knowledge of where the complexities are! For example, the most complex thing you listed is is(), because is(typeof()) accepts all kinds of things which normally wouldn't compile. This has implications for the whole compiler, and no changes in how CTFE is done would make it any simpler.This in turn would simplify the implementation of the compiler.Syntax is trivial. It's a negligible fraction of the compiler (provided you retain D's rigid seperation between parsing and semantic pass).the above list should contain all compile-time features (I didn't mention templates and traits) Since a macro has hooks into the semantic pass it can do all sorts of transforms directly on the abstract syntax tree - modifying the data structures in the compiler's memory. this means you use _regular_ code in combination with a compiler API instead of special syntax. E.g. traits and is(typof()) would be regular functions (part of the API) instead of language features.I don't have a clue how you would do that. Most of the simple traits could be implemented in D in the existing compiler, but is(typeof()) is a different story. It practically runs the entire compiler with errors suppressed. The complexity isn't in is(typeof()) itself, but rather in the fact that the whole compiler has to cope with errors being suppressed.To date, no vendor extensions introduce additional dependencies.> e.g you could connect to a DB at compile time to validate a SQL query or use regular IO functions from phobos. You know, I'm yet to be convinced that that it's really desirable. The ability to put all your source in a repository and say, "the executable depends on this and nothing else", is IMHO of enormous value. Once you allow it to depend on the result of external function calls, it depends on all kinds of hidden variables, which are ephemeral, and it seems to me much better to completely separate that "information gathering" step from the compilation step. Note that since it's a snapshot, you *don't* have a guarantee that your SQL query is still valid by the time the code runs.I agree this adds dependencies to the compilation process. However, IIUC, D already allows adding vendor extensions with pragma.At the moment this requires to changes the compiler's source. macros simply extend this notion with shared objects. Look for example at the pragma for printing at compile-time. instead of implementing it in as part of the compiler, you could simply use phobos' writeln."simply"? Let me show you the code for pragma(msg). The whole thing, in all its complexity: ------------------- Statement *PragmaStatement::semantic(Scope *sc) { if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); StringExp *se = e->toString(); if (se) fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } } -------------------The word is much older than Lisp (macro assemblers are ancient; CAR and CDR were asm macros). The uses of the word on these forums are clearly influenced by Lisp macros, but the mapping of 'macro' from Lisp to the usage here is by no means clear. I feel that a lot of extra assumptions are being smuggled in through the word. Most commonly, it seems to mean "some compile-time programming system, which is completely undescribed except for the fact that it's almost perfect in every way" <g>. Sometimes it seems to mean "macros as implemented by Nemerle". Even then, it's unclear which aspects of Nemerle macros are considered to be important. Occasionally, macro means "any compile-time programming system", including what we have in D at the moment.BTW there's nothing in the present design which prevents CTFE from being implemented by doing a JIT to native code. I expect most implementations will go that way, but they'll be motivated by speed. Also I'm confused by this term "macros" that keeps popping up. I don't know why it's being used, and I don't know what it means.The term comes from lisp.
Oct 19 2011
On 10/16/11 2:35 AM, Don wrote:On 16.10.2011 04:16, Ary Manzana wrote:Compile the function to be compile-time evaluated in X86. Compile the function that will go to the obj files/executables in ARM. (you'd eventually compile the first ones in ARM if they are used in run-time). What's bad about that?On 10/15/11 5:00 PM, Marco Leise wrote:[snip]Am 15.10.2011, 18:24 Uhr, schrieb Ary Manzana <ary esperanto.org.ar>:I don't understand this quite well. I want JITted functions to just generate code that ultimately will be compiled. It's like what CTFE is doing now, except that instead of doing it by interpreting every bit and spec of the language you would compile the function, run it to generate code, and then compile the code for the target machine.On 10/14/11 5:16 PM, Graham Fawcett wrote:I wonder if that would work well with cross-compiling. If you blindly JIT functions, they may end up using structs of the wrong size, or integers with different endianness. Compile for 64-bit on a 32-bit machine. What size is size_t during CTFE?On Fri, 14 Oct 2011 21:10:29 +0200, Jacob Carlborg wrote:Yeah, but you need a separate tool. In Nemerle it seems you can do everything just in Nemerle... It would be awesome if CTFE would be implemented by JITting functions, not by reinventing the wheel and implementing a handcrafted interpreter...On 2011-10-14 15:26, Andrei Alexandrescu wrote:One approach would be to write a separate tool that connects to the database and writes out a representation of the schema to a source file. At compile time, the representation is statically imported, and used to verify the data model. If we had preprocessor support, the tool could be run as such, checking the model just before passing the source to the compiler.On 10/14/11 6:08 AM, Jacob Carlborg wrote:But you still won't be able to verify the columns to the actual database scheme?On 2011-10-14 12:19, foobar wrote:A little SQL interpreter can be written that figures out e.g. the names of the columns involved. AndreiHas anyone looked at Nemerle's design for this? They have an SQL macro which allows to write SQL such as: var employName = "FooBar" SQL (DBconn, "select * from employees where name = $employName"); what that supposed to do is bind the variable(s) and it also validates the sql query with the database. This is all done at compile-time. My understanding is that D's compile-time features are powerful enough to implement this.You cannot connect to a database in D at compile time. You could some form of validation and escape the query without connecting to the database.Maybe I'm not taking something into account... what is it?You're assuming that the compiler can run the code it's generating. This isn't true in general. Suppose you're on x86, compiling for ARM. You can't run the ARM code from the compiler.
Oct 16 2011