digitalmars.D - DI File Generation
- Adam Wilson (49/49) Dec 14 2011 Hello everyone,
- Timon Gehr (7/54) Dec 14 2011 Yes, it is always possible to include the function bodies manually or to...
- Adam Wilson (10/74) Dec 14 2011 At the moment, it doesn't do anything with them that I know off, but I
- Timon Gehr (4/78) Dec 14 2011 I think currently it just creates a corrupted .di file if it encounters
- Adam Wilson (9/100) Dec 14 2011 We'll have to complain loudly enough to Walter about that then. I'm not ...
- Paulo Pinto (9/54) Dec 14 2011 Thanks for the nice work.
- Timon Gehr (3/11) Dec 14 2011 I agree, but sometimes code is part of the interface, eg if it is
- Jonathan M Davis (26/78) Dec 14 2011 Considering that you must have the bodies of functions to do either inli...
- Adam D. Ruppe (9/12) Dec 14 2011 I agree with you in general. I think the main use of .di files
- Timon Gehr (10/21) Dec 14 2011 If a project grows sufficiently large, the possibility of having
- Jonathan M Davis (6/32) Dec 14 2011 But it doesn't contain any CTFE information beyond the source code itsel...
- Paulo Pinto (9/12) Dec 14 2011 I think that Modula-3, Eiffel and Ada don't have issues with having
- Adam Wilson (14/30) Dec 14 2011 As a note for this discussion, when you export stuff via DI gen, it
- Jonathan M Davis (13/27) Dec 14 2011 As similar as they may appear, templates and generics are completely dif...
- Paulo Pinto (7/36) Dec 14 2011 Sorry, but that is not correct.
Hello everyone, As some of you may be aware I have been working on improvements to the .di file generation capabilities in D and I've run across a few things that I think should be put to the community. The first involves the handling of variable instantiation. Say you create the following member variable in a class: export int Foo = 1; Currently the di generation output is identical to the above line. My understanding is that, similar to C/C++, D doesn't care if you keep the initializer in the include file so this is primarily a stylistic question. Should we keep the output as is, or remove the initializer? My personal preference is to remove the initializer but I think the community should decide. Another question that has come up pertains to the reason for the original implementation of DI generation, inlining. According to what I've read on these newsgroups and various other sources, DI generation is supposed to include the implementation for some small functions that would be good inlining candidates, however, it looks like is actually happening is that all DMD does is check to see if there are any cases where the compiler would fail if it attempted to inline the function. As long as the compiler can compile it, it gets thrown into the DI file, regardless of size. My current patches never include the implementation, and I think that for most people this is a reasonable solution, if not ideal. All of the people I've talked to seemed to agree. What do you think? Does this work for you? Should there be a way to specify the maximum size of an inline function? NOTE: Doing this would require at least a command line switch and probably some significant reworking of the function symbol exporter. As such it'd take a lot more time to get into to D; I'd recommend implementing the simple solution first then adding this only if it's requested by a significant number of people. The next question is primarily directed at Walter, but anybody who knows anything about the compiler internals is welcome to chime in. For functions defined in Class and Interfaces, calling isFuncDeclaration() as I iterate through the symbol tree works as expected and returns the Function. However, when I try to call that on a function that is declared in a module (with no surrounding class) or in a struct, it always returns null, regardless of whether or not it's actually a function. Is there any way to determine if the symbol is a function when it's not a class member? NOTE: As near as I can tell, it is actually a FuncDeclaration. The final bit of DI generation revolves around the handling of protected functions in exported classes. But that's better suited to a separate topic as that involves the general design of scoping in D2 and isn't limited to DI generation. I'll be posting another topic on that soon. Thank you all for taking the time to read and chime in on this! -- Adam Wilson Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Dec 14 2011
On 12/14/2011 07:47 PM, Adam Wilson wrote:Hello everyone, As some of you may be aware I have been working on improvements to the .di file generation capabilities in DNice!and I've run across a few things that I think should be put to the community. The first involves the handling of variable instantiation. Say you create the following member variable in a class: export int Foo = 1; Currently the di generation output is identical to the above line. My understanding is that, similar to C/C++, D doesn't care if you keep the initializer in the include file so this is primarily a stylistic question. Should we keep the output as is, or remove the initializer? My personal preference is to remove the initializer but I think the community should decide. Another question that has come up pertains to the reason for the original implementation of DI generation, inlining. According to what I've read on these newsgroups and various other sources, DI generation is supposed to include the implementation for some small functions that would be good inlining candidates, however, it looks like is actually happening is that all DMD does is check to see if there are any cases where the compiler would fail if it attempted to inline the function. As long as the compiler can compile it, it gets thrown into the DI file, regardless of size. My current patches never include the implementation, and I think that for most people this is a reasonable solution, if not ideal. All of the people I've talked to seemed to agree. What do you think? Does this work for you?Yes, it is always possible to include the function bodies manually or to compile the modules together for release mode if inlining is that important. For now, .di generation should ideally just work.Should there be a way to specify the maximum size of an inline function? NOTE: Doing this would require at least a command line switch and probably some significant reworking of the function symbol exporter. As such it'd take a lot more time to get into to D; I'd recommend implementing the simple solution first then adding this only if it's requested by a significant number of people. The next question is primarily directed at Walter, but anybody who knows anything about the compiler internals is welcome to chime in. For functions defined in Class and Interfaces, calling isFuncDeclaration() as I iterate through the symbol tree works as expected and returns the Function. However, when I try to call that on a function that is declared in a module (with no surrounding class) or in a struct, it always returns null, regardless of whether or not it's actually a function. Is there any way to determine if the symbol is a function when it's not a class member? NOTE: As near as I can tell, it is actually a FuncDeclaration. The final bit of DI generation revolves around the handling of protected functions in exported classes. But that's better suited to a separate topic as that involves the general design of scoping in D2 and isn't limited to DI generation. I'll be posting another topic on that soon. Thank you all for taking the time to read and chime in on this!How will your patch handle top level string mixins/static if's/version declarations?
Dec 14 2011
On Wed, 14 Dec 2011 10:58:30 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:On 12/14/2011 07:47 PM, Adam Wilson wrote:At the moment, it doesn't do anything with them that I know off, but I don't know enough about how the compiler handles those constructs to give a good answer. Although if you have a piece of code that you can share for testing against my patches, i'll let you know. -- Adam Wilson Project Coordinator The Horizon Project http://www.thehorizonproject.org/Hello everyone, As some of you may be aware I have been working on improvements to the .di file generation capabilities in DNice!and I've run across a few things that I think should be put to the community. The first involves the handling of variable instantiation. Say you create the following member variable in a class: export int Foo = 1; Currently the di generation output is identical to the above line. My understanding is that, similar to C/C++, D doesn't care if you keep the initializer in the include file so this is primarily a stylistic question. Should we keep the output as is, or remove the initializer? My personal preference is to remove the initializer but I think the community should decide. Another question that has come up pertains to the reason for the original implementation of DI generation, inlining. According to what I've read on these newsgroups and various other sources, DI generation is supposed to include the implementation for some small functions that would be good inlining candidates, however, it looks like is actually happening is that all DMD does is check to see if there are any cases where the compiler would fail if it attempted to inline the function. As long as the compiler can compile it, it gets thrown into the DI file, regardless of size. My current patches never include the implementation, and I think that for most people this is a reasonable solution, if not ideal. All of the people I've talked to seemed to agree. What do you think? Does this work for you?Yes, it is always possible to include the function bodies manually or to compile the modules together for release mode if inlining is that important. For now, .di generation should ideally just work.Should there be a way to specify the maximum size of an inline function? NOTE: Doing this would require at least a command line switch and probably some significant reworking of the function symbol exporter. As such it'd take a lot more time to get into to D; I'd recommend implementing the simple solution first then adding this only if it's requested by a significant number of people. The next question is primarily directed at Walter, but anybody who knows anything about the compiler internals is welcome to chime in. For functions defined in Class and Interfaces, calling isFuncDeclaration() as I iterate through the symbol tree works as expected and returns the Function. However, when I try to call that on a function that is declared in a module (with no surrounding class) or in a struct, it always returns null, regardless of whether or not it's actually a function. Is there any way to determine if the symbol is a function when it's not a class member? NOTE: As near as I can tell, it is actually a FuncDeclaration. The final bit of DI generation revolves around the handling of protected functions in exported classes. But that's better suited to a separate topic as that involves the general design of scoping in D2 and isn't limited to DI generation. I'll be posting another topic on that soon. Thank you all for taking the time to read and chime in on this!How will your patch handle top level string mixins/static if's/version declarations?
Dec 14 2011
On 12/14/2011 09:05 PM, Adam Wilson wrote:On Wed, 14 Dec 2011 10:58:30 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:I think currently it just creates a corrupted .di file if it encounters the construct. Ideally it would just expand them to make their compilation faster.On 12/14/2011 07:47 PM, Adam Wilson wrote:At the moment, it doesn't do anything with them that I know off, but I don't know enough about how the compiler handles those constructs to give a good answer. Although if you have a piece of code that you can share for testing against my patches, i'll let you know.Hello everyone, As some of you may be aware I have been working on improvements to the .di file generation capabilities in DNice!and I've run across a few things that I think should be put to the community. The first involves the handling of variable instantiation. Say you create the following member variable in a class: export int Foo = 1; Currently the di generation output is identical to the above line. My understanding is that, similar to C/C++, D doesn't care if you keep the initializer in the include file so this is primarily a stylistic question. Should we keep the output as is, or remove the initializer? My personal preference is to remove the initializer but I think the community should decide. Another question that has come up pertains to the reason for the original implementation of DI generation, inlining. According to what I've read on these newsgroups and various other sources, DI generation is supposed to include the implementation for some small functions that would be good inlining candidates, however, it looks like is actually happening is that all DMD does is check to see if there are any cases where the compiler would fail if it attempted to inline the function. As long as the compiler can compile it, it gets thrown into the DI file, regardless of size. My current patches never include the implementation, and I think that for most people this is a reasonable solution, if not ideal. All of the people I've talked to seemed to agree. What do you think? Does this work for you?Yes, it is always possible to include the function bodies manually or to compile the modules together for release mode if inlining is that important. For now, .di generation should ideally just work.Should there be a way to specify the maximum size of an inline function? NOTE: Doing this would require at least a command line switch and probably some significant reworking of the function symbol exporter. As such it'd take a lot more time to get into to D; I'd recommend implementing the simple solution first then adding this only if it's requested by a significant number of people. The next question is primarily directed at Walter, but anybody who knows anything about the compiler internals is welcome to chime in. For functions defined in Class and Interfaces, calling isFuncDeclaration() as I iterate through the symbol tree works as expected and returns the Function. However, when I try to call that on a function that is declared in a module (with no surrounding class) or in a struct, it always returns null, regardless of whether or not it's actually a function. Is there any way to determine if the symbol is a function when it's not a class member? NOTE: As near as I can tell, it is actually a FuncDeclaration. The final bit of DI generation revolves around the handling of protected functions in exported classes. But that's better suited to a separate topic as that involves the general design of scoping in D2 and isn't limited to DI generation. I'll be posting another topic on that soon. Thank you all for taking the time to read and chime in on this!How will your patch handle top level string mixins/static if's/version declarations?
Dec 14 2011
On Wed, 14 Dec 2011 12:30:33 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:On 12/14/2011 09:05 PM, Adam Wilson wrote:We'll have to complain loudly enough to Walter about that then. I'm not familiar enough with the compiler internals to tackle that issue myself. :-) -- Adam Wilson Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Wed, 14 Dec 2011 10:58:30 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:I think currently it just creates a corrupted .di file if it encounters the construct. Ideally it would just expand them to make their compilation faster.On 12/14/2011 07:47 PM, Adam Wilson wrote:At the moment, it doesn't do anything with them that I know off, but I don't know enough about how the compiler handles those constructs to give a good answer. Although if you have a piece of code that you can share for testing against my patches, i'll let you know.Hello everyone, As some of you may be aware I have been working on improvements to the .di file generation capabilities in DNice!and I've run across a few things that I think should be put to the community. The first involves the handling of variable instantiation. Say you create the following member variable in a class: export int Foo = 1; Currently the di generation output is identical to the above line. My understanding is that, similar to C/C++, D doesn't care if you keep the initializer in the include file so this is primarily a stylistic question. Should we keep the output as is, or remove the initializer? My personal preference is to remove the initializer but I think the community should decide. Another question that has come up pertains to the reason for the original implementation of DI generation, inlining. According to what I've read on these newsgroups and various other sources, DI generation is supposed to include the implementation for some small functions that would be good inlining candidates, however, it looks like is actually happening is that all DMD does is check to see if there are any cases where the compiler would fail if it attempted to inline the function. As long as the compiler can compile it, it gets thrown into the DI file, regardless of size. My current patches never include the implementation, and I think that for most people this is a reasonable solution, if not ideal. All of the people I've talked to seemed to agree. What do you think? Does this work for you?Yes, it is always possible to include the function bodies manually or to compile the modules together for release mode if inlining is that important. For now, .di generation should ideally just work.Should there be a way to specify the maximum size of an inline function? NOTE: Doing this would require at least a command line switch and probably some significant reworking of the function symbol exporter. As such it'd take a lot more time to get into to D; I'd recommend implementing the simple solution first then adding this only if it's requested by a significant number of people. The next question is primarily directed at Walter, but anybody who knows anything about the compiler internals is welcome to chime in. For functions defined in Class and Interfaces, calling isFuncDeclaration() as I iterate through the symbol tree works as expected and returns the Function. However, when I try to call that on a function that is declared in a module (with no surrounding class) or in a struct, it always returns null, regardless of whether or not it's actually a function. Is there any way to determine if the symbol is a function when it's not a class member? NOTE: As near as I can tell, it is actually a FuncDeclaration. The final bit of DI generation revolves around the handling of protected functions in exported classes. But that's better suited to a separate topic as that involves the general design of scoping in D2 and isn't limited to DI generation. I'll be posting another topic on that soon. Thank you all for taking the time to read and chime in on this!How will your patch handle top level string mixins/static if's/version declarations?
Dec 14 2011
Thanks for the nice work. Personally I would like that DI files would work like the interfaces work in another module aware languages. The interface is just that, the interface. Everything that has to do with code or variable initialization is part of the implementation part. -- Paulo Am 14.12.2011 19:47, schrieb Adam Wilson:Hello everyone, As some of you may be aware I have been working on improvements to the .di file generation capabilities in D and I've run across a few things that I think should be put to the community. The first involves the handling of variable instantiation. Say you create the following member variable in a class: export int Foo = 1; Currently the di generation output is identical to the above line. My understanding is that, similar to C/C++, D doesn't care if you keep the initializer in the include file so this is primarily a stylistic question. Should we keep the output as is, or remove the initializer? My personal preference is to remove the initializer but I think the community should decide. Another question that has come up pertains to the reason for the original implementation of DI generation, inlining. According to what I've read on these newsgroups and various other sources, DI generation is supposed to include the implementation for some small functions that would be good inlining candidates, however, it looks like is actually happening is that all DMD does is check to see if there are any cases where the compiler would fail if it attempted to inline the function. As long as the compiler can compile it, it gets thrown into the DI file, regardless of size. My current patches never include the implementation, and I think that for most people this is a reasonable solution, if not ideal. All of the people I've talked to seemed to agree. What do you think? Does this work for you? Should there be a way to specify the maximum size of an inline function? NOTE: Doing this would require at least a command line switch and probably some significant reworking of the function symbol exporter. As such it'd take a lot more time to get into to D; I'd recommend implementing the simple solution first then adding this only if it's requested by a significant number of people. The next question is primarily directed at Walter, but anybody who knows anything about the compiler internals is welcome to chime in. For functions defined in Class and Interfaces, calling isFuncDeclaration() as I iterate through the symbol tree works as expected and returns the Function. However, when I try to call that on a function that is declared in a module (with no surrounding class) or in a struct, it always returns null, regardless of whether or not it's actually a function. Is there any way to determine if the symbol is a function when it's not a class member? NOTE: As near as I can tell, it is actually a FuncDeclaration. The final bit of DI generation revolves around the handling of protected functions in exported classes. But that's better suited to a separate topic as that involves the general design of scoping in D2 and isn't limited to DI generation. I'll be posting another topic on that soon. Thank you all for taking the time to read and chime in on this!
Dec 14 2011
On 12/14/2011 08:44 PM, Paulo Pinto wrote:Thanks for the nice work. Personally I would like that DI files would work like the interfaces work in another module aware languages. The interface is just that, the interface. Everything that has to do with code or variable initialization is part of the implementation part. -- PauloI agree, but sometimes code is part of the interface, eg if it is supposed to be usable in CTFE.
Dec 14 2011
On Wednesday, December 14, 2011 10:47:17 Adam Wilson wrote:Hello everyone, As some of you may be aware I have been working on improvements to the .di file generation capabilities in D and I've run across a few things that I think should be put to the community. The first involves the handling of variable instantiation. Say you create the following member variable in a class: export int Foo = 1; Currently the di generation output is identical to the above line. My understanding is that, similar to C/C++, D doesn't care if you keep the initializer in the include file so this is primarily a stylistic question. Should we keep the output as is, or remove the initializer? My personal preference is to remove the initializer but I think the community should decide. Another question that has come up pertains to the reason for the original implementation of DI generation, inlining. According to what I've read on these newsgroups and various other sources, DI generation is supposed to include the implementation for some small functions that would be good inlining candidates, however, it looks like is actually happening is that all DMD does is check to see if there are any cases where the compiler would fail if it attempted to inline the function. As long as the compiler can compile it, it gets thrown into the DI file, regardless of size. My current patches never include the implementation, and I think that for most people this is a reasonable solution, if not ideal. All of the people I've talked to seemed to agree. What do you think? Does this work for you? Should there be a way to specify the maximum size of an inline function? NOTE: Doing this would require at least a command line switch and probably some significant reworking of the function symbol exporter. As such it'd take a lot more time to get into to D; I'd recommend implementing the simple solution first then adding this only if it's requested by a significant number of people. The next question is primarily directed at Walter, but anybody who knows anything about the compiler internals is welcome to chime in. For functions defined in Class and Interfaces, calling isFuncDeclaration() as I iterate through the symbol tree works as expected and returns the Function. However, when I try to call that on a function that is declared in a module (with no surrounding class) or in a struct, it always returns null, regardless of whether or not it's actually a function. Is there any way to determine if the symbol is a function when it's not a class member? NOTE: As near as I can tell, it is actually a FuncDeclaration. The final bit of DI generation revolves around the handling of protected functions in exported classes. But that's better suited to a separate topic as that involves the general design of scoping in D2 and isn't limited to DI generation. I'll be posting another topic on that soon. Thank you all for taking the time to read and chime in on this!Considering that you must have the bodies of functions to do either inlining or CTFE, stripping _anything_ from a .di file carries a definite cost. Now, maybe large functions shouldn't be put in there, but certainly anything which could be reasonably inlined should be, and depending on what you're doing with CTFE, you're going to need the big ones anyway - though that depends on the particular usage more than inlining does, so having to add the function bodies manually for CTFE isn't as big a deal as it would be for inlining. Also, _all_ templated _anything_ has to be put in the .di file, and a lot of stuff tends to be templated in D (especially in the standard library), so it's pretty easy to need to put a large portion of your code in the .di file anyway. Personally, I think that .di files aren't a great idea in general, precisely because of the issues with inlining and CTFE, so I never use them. They generally complicate things needlessly. In some cases, it probably does make sense to use them (e.g. you have a very large project that needs the additional boost in compilation speed or if you have a number of classes with large function bodies which aren't going to be used with CTFE and can't be inlined, because they're virtual), but in general, I just don't think that they're worth messing with - especially when you consider having to keep the .di and .d files in sync. dmd is very fast compiler, and I really think that in the majority of cases, there's not really any point to .di files. And when you _do_ use them, a lot of code has to be in them anyway, or you lose the ability to inline or use CTFE, which would harm performance and impede what your code can do. And if you're using templates much, then it all ends up in the .di file anyway. - Jonathan M Davis
Dec 14 2011
On Wednesday, 14 December 2011 at 20:14:42 UTC, Jonathan M Davis wrote:Considering that you must have the bodies of functions to do either inlining or CTFE, stripping _anything_ from a .di file carries a definite cost.I agree with you in general. I think the main use of .di files is for closed source libraries... which means we should probably go with putting as little in as possible. If you want it all, use your .d files directly. If you want a closed source lib, go with .di, then add back only what you want to release the source for (templates, ctfe functions, inline things) manually.
Dec 14 2011
On 12/14/2011 09:24 PM, Adam D. Ruppe wrote:On Wednesday, 14 December 2011 at 20:14:42 UTC, Jonathan M Davis wrote:If a project grows sufficiently large, the possibility of having separate compilation is certainly important too. The compilation of my current project takes about 1.3s. If I compile every module on its own, I get a compile time of ~6s. That is because the semantic analysis of the code involves a fair bit of CTFE, and imported modules need to be semantically analyzed to a certain extent. Autogenerated .di files should work in a way that reduces this cost so that an efficient incremental compilation setup gets easy. If the autogenerated .di file contains the CTFE'd information, compilation gets a lot faster.Considering that you must have the bodies of functions to do either inlining or CTFE, stripping _anything_ from a .di file carries a definite cost.I agree with you in general. I think the main use of .di files is for closed source libraries... which means we should probably go with putting as little in as possible. If you want it all, use your .d files directly. If you want a closed source lib, go with .di, then add back only what you want to release the source for (templates, ctfe functions, inline things) manually.
Dec 14 2011
On Wednesday, December 14, 2011 21:37:14 Timon Gehr wrote:On 12/14/2011 09:24 PM, Adam D. Ruppe wrote:But it doesn't contain any CTFE information beyond the source code itself. There's no question that .di files could be improved to work better with regards to CTFE, but that would require redesigning .di files on some level, which probably can't be done for D2 at this point. - Jonathan M DavisOn Wednesday, 14 December 2011 at 20:14:42 UTC, Jonathan M Davis wrote:If a project grows sufficiently large, the possibility of having separate compilation is certainly important too. The compilation of my current project takes about 1.3s. If I compile every module on its own, I get a compile time of ~6s. That is because the semantic analysis of the code involves a fair bit of CTFE, and imported modules need to be semantically analyzed to a certain extent. Autogenerated .di files should work in a way that reduces this cost so that an efficient incremental compilation setup gets easy. If the autogenerated .di file contains the CTFE'd information, compilation gets a lot faster.Considering that you must have the bodies of functions to do either inlining or CTFE, stripping _anything_ from a .di file carries a definite cost.I agree with you in general. I think the main use of .di files is for closed source libraries... which means we should probably go with putting as little in as possible. If you want it all, use your .d files directly. If you want a closed source lib, go with .di, then add back only what you want to release the source for (templates, ctfe functions, inline things) manually.
Dec 14 2011
Am 14.12.2011 21:13, schrieb Jonathan M Davis:I think that Modula-3, Eiffel and Ada don't have issues with having "template" declaration in the interface part, with the definition being done in the implementation part. Then again, what they support is what is more commonly known as generics. I imagine you mean that metaprogramming requires the template code to be in the .di file as well, right? -- PauloAlso, _all_ templated _anything_ has to be put in the .di file, and a lot ofstuff tends to be templated in D (especially in the standard library), so it's pretty easy to need to put a large portion of your code in the .di file anyway.
Dec 14 2011
On Wed, 14 Dec 2011 15:26:05 -0800, Paulo Pinto <pjmlp progtools.org> wrote:Am 14.12.2011 21:13, schrieb Jonathan M Davis:As a note for this discussion, when you export stuff via DI gen, it includes templates. In the cases of classes it wraps the class inside the template. My patches don't effect this template code, they work on members. The only potential issue I can see is that my patch would execute after a function level template and leave the template hanging without the corresponding function. Does anyone have some test code that I can run to verify this behavior? -- Adam Wilson Project Coordinator The Horizon Project http://www.thehorizonproject.org/I think that Modula-3, Eiffel and Ada don't have issues with having "template" declaration in the interface part, with the definition being done in the implementation part. Then again, what they support is what is more commonly known as generics. I imagine you mean that metaprogramming requires the template code to be in the .di file as well, right? -- PauloAlso, _all_ templated _anything_ has to be put in the .di file, and a lot ofstuff tends to be templated in D (especially in the standard library), so it's pretty easy to need to put a large portion of your code in the .di file anyway.
Dec 14 2011
On Thursday, December 15, 2011 00:26:05 Paulo Pinto wrote:Am 14.12.2011 21:13, schrieb Jonathan M Davis:As similar as they may appear, templates and generics are completely different. With templates, you're literally generating code, and the compiler needs to full source of the template to generate that code. Generics typically means that you have one set of code which is just used with different types (typically enabled by the fact that all of the type have a base class which they share). So, with generics, you can separate interface and implementation, but that's impossible with templates (C++ has the same issue). The code which is generated could vary drastically depending on what you try and instantiate a template with, unlike with generics. And ultimately, what it comes down to is the fact that templates literally generate code, so their full source is required. - Jonathan M DavisI think that Modula-3, Eiffel and Ada don't have issues with having "template" declaration in the interface part, with the definition being done in the implementation part. Then again, what they support is what is more commonly known as generics. I imagine you mean that metaprogramming requires the template code to be in the .di file as well, right?Also, _all_ templated _anything_ has to be put in the .di file, and a lot of>stuff tends to be templated in D (especially in the standard library), so it's pretty easy to need to put a large portion of your code in the .di file anyway.
Dec 14 2011
Sorry, but that is not correct. I don't know if that is your case, but many people confuse generics with the dumb implementation that Java has. The languages that support proper generics, have the compiler store a kind of code template in the module with placeholders. This code is then extracted from the module during compile time and the placeholders get replaced by the code required for the specific type. One reason why the C++ templates are the way they are, is that C++ designers always wanted to support the primitive compiler/linker toolchains in UNIX. This is not an issue in languages that have proper module support without toolchain constraints. -- Paulo Jonathan M Davis Wrote:On Thursday, December 15, 2011 00:26:05 Paulo Pinto wrote:Am 14.12.2011 21:13, schrieb Jonathan M Davis:As similar as they may appear, templates and generics are completely different. With templates, you're literally generating code, and the compiler needs to full source of the template to generate that code. Generics typically means that you have one set of code which is just used with different types (typically enabled by the fact that all of the type have a base class which they share). So, with generics, you can separate interface and implementation, but that's impossible with templates (C++ has the same issue). The code which is generated could vary drastically depending on what you try and instantiate a template with, unlike with generics. And ultimately, what it comes down to is the fact that templates literally generate code, so their full source is required. - Jonathan M DavisI think that Modula-3, Eiffel and Ada don't have issues with having "template" declaration in the interface part, with the definition being done in the implementation part. Then again, what they support is what is more commonly known as generics. I imagine you mean that metaprogramming requires the template code to be in the .di file as well, right?Also, _all_ templated _anything_ has to be put in the .di file, and a lot of>stuff tends to be templated in D (especially in the standard library), so it's pretty easy to need to put a large portion of your code in the .di file anyway.
Dec 14 2011