www.digitalmars.com         C & C++   DMDScript  

D - Pre-initialized constants.

reply Ilya Minkov <midiclub tiscali.de> writes:
A while ago in a "preprocessor" thread, a need to have constants defined 
in a flexible way was shown. Most people used macros for this purpose. 
You use tools spewing some code. I think there is a better solution.

I also used a kind of a tiny tool, "bin2c", which generated constant 
attays of pre-calculations, images, music, etc., which i needed to 
include into the application in binary. Resulting files are huge, the 
GCC went on my 'bit older notebook into swapping and got so slow that it 
took more than ten minutes to compile the project. And though it had 64 
MB RAM and was running Windows 98. Plenty of ram IMO to compile a 
project using 3 Megs of code and generating less-then-a-meg executable. 
Most of the size were precalcs, bitmaps and sound. I just wanted to have 
it in one EXE and with less then a meg of binary data it does make sense.

It all boils down to the same class of problems. I propose the following 
"hint". When a global constant is defined using a function call, for 
example:

const SomeType = callGenerator("StringPar", 2, 3);

It could be understood to execute the function at compile time with 
these parameters and to save the result into the executable. This 
function could, for exampe, do one of the following:
  - load a file into this constant array, so that the binary file gets 
compiled into the executable;
  - pre-compute an internal representation of a pattern-matching machine 
or similar. So that text can be typed inside a D programme, which is not 
evaluated at runtime into a usable structure, but instead at compile 
time. Even more useful for larger things like parsers, which take much 
less space in parsed representation;
  - simply compile strings out of parts ;)

I don't think there is any ambiguity, since if someone wants to 
initialize his precalcs at run-time, he simply has to remove the const 
qulifier. He shouldn't be able to change an immutable array anyway. ;)

This basically puts a number of limitation on such a function:
  - it may not use globals, as it would be an unnecessary complication 
and almost always a sign of a bug;
  - it may use APIs at its own risc... just not to leave any post-effects.
It is very important for programmers to understand that this function 
may or may not be run during program execution, so that they can't rely 
upon the effects it may leave, nor may it be allowed to corrupt anything 
that a running programme may be using. You might call it "pure", but you 
can't actually check the purity when it uses external APIs to access the 
disk or something.

Since not everything is an array, the implemetation would get complex. 
I'm sure there has to be a possibility to explore types at runtime, 
which would allow to:
  - optimise GC drastically without further complication to the compiler;
  - write a "persistent" library, allowing to save any structured data 
to disc (with pointer analysis and such), and read it back easily.

As soon as a persistent library is done, making such things is a trivial 
matter, so it would better get delayed till then. I'll try to devise a 
consistent and compiler-friendly way to implement type browsing. I think 
that we would make use of type methods (it's their purpose, right?), 
apart from classes which already have a type information.

The easy way would be to be able to retrieve pointer positions inside 
structures, and save the rest as "raw". However, that leads to problems 
when endianness has to be taken care of.

-i.
Jan 21 2003
parent reply "Walter" <walter digitalmars.com> writes:
I think that could be done without changing the semantics of D, but it would
require a much more advanced compiler. -Walter

"Ilya Minkov" <midiclub tiscali.de> wrote in message
news:b0jif1$2kc2$1 digitaldaemon.com...
 A while ago in a "preprocessor" thread, a need to have constants defined
 in a flexible way was shown. Most people used macros for this purpose.
 You use tools spewing some code. I think there is a better solution.

 I also used a kind of a tiny tool, "bin2c", which generated constant
 attays of pre-calculations, images, music, etc., which i needed to
 include into the application in binary. Resulting files are huge, the
 GCC went on my 'bit older notebook into swapping and got so slow that it
 took more than ten minutes to compile the project. And though it had 64
 MB RAM and was running Windows 98. Plenty of ram IMO to compile a
 project using 3 Megs of code and generating less-then-a-meg executable.
 Most of the size were precalcs, bitmaps and sound. I just wanted to have
 it in one EXE and with less then a meg of binary data it does make sense.

 It all boils down to the same class of problems. I propose the following
 "hint". When a global constant is defined using a function call, for
 example:

 const SomeType = callGenerator("StringPar", 2, 3);

 It could be understood to execute the function at compile time with
 these parameters and to save the result into the executable. This
 function could, for exampe, do one of the following:
   - load a file into this constant array, so that the binary file gets
 compiled into the executable;
   - pre-compute an internal representation of a pattern-matching machine
 or similar. So that text can be typed inside a D programme, which is not
 evaluated at runtime into a usable structure, but instead at compile
 time. Even more useful for larger things like parsers, which take much
 less space in parsed representation;
   - simply compile strings out of parts ;)

 I don't think there is any ambiguity, since if someone wants to
 initialize his precalcs at run-time, he simply has to remove the const
 qulifier. He shouldn't be able to change an immutable array anyway. ;)

 This basically puts a number of limitation on such a function:
   - it may not use globals, as it would be an unnecessary complication
 and almost always a sign of a bug;
   - it may use APIs at its own risc... just not to leave any post-effects.
 It is very important for programmers to understand that this function
 may or may not be run during program execution, so that they can't rely
 upon the effects it may leave, nor may it be allowed to corrupt anything
 that a running programme may be using. You might call it "pure", but you
 can't actually check the purity when it uses external APIs to access the
 disk or something.

 Since not everything is an array, the implemetation would get complex.
 I'm sure there has to be a possibility to explore types at runtime,
 which would allow to:
   - optimise GC drastically without further complication to the compiler;
   - write a "persistent" library, allowing to save any structured data
 to disc (with pointer analysis and such), and read it back easily.

 As soon as a persistent library is done, making such things is a trivial
 matter, so it would better get delayed till then. I'll try to devise a
 consistent and compiler-friendly way to implement type browsing. I think
 that we would make use of type methods (it's their purpose, right?),
 apart from classes which already have a type information.

 The easy way would be to be able to retrieve pointer positions inside
 structures, and save the rest as "raw". However, that leads to problems
 when endianness has to be taken care of.

 -i.

Jan 21 2003
parent Ilya Minkov <midiclub 8ung.at> writes:
Walter wrote:
 I think that could be done without changing the semantics of D, but it would
 require a much more advanced compiler. -Walter

Yes, I figured it out by the time I wrote that, so we'll wait 'till we've got persistancy, then it shouldn't be a problem anymore. Just an idea. And i think that it is important that the result is well-defined, so that it's no "surprise" that some structure wasn't compiled and thus the EXE is dependant on some other file which should be a part of it. But maybe implement it for a simple case when these are arrays? Or an intrinsic initializer function, which would basically only load binaries from disk? -i.
Jan 21 2003