Thread overview
[Suggestion] Version import
Oct 19, 2004
Stewart Gordon
Oct 19, 2004
Regan Heath
Oct 19, 2004
Sjoerd van Leent
Oct 19, 2004
Regan Heath
Oct 20, 2004
Sjoerd van Leent
Oct 20, 2004
Walter
Oct 20, 2004
Stewart Gordon
October 19, 2004
Change in 0.101:

"Kris pointed out that version identifiers have global effect, and are dependent on which order modules are imported. This is clearly wrong. Now, only version and debug definitions on the command line have global effect. Others only influence the module they are declared in. Furthermore, version and debug definitions can only be done at module scope."

With this change, we've lost a capability that the C preprocessor has: to use an include file to manipulate version identifiers.

Consider a typical case of version manipulation:
(http://www.digitalmars.com/d/version.html)

    version (ProfessionalEdition)
    {
        version = FeatureA;
        version = FeatureB;
        version = FeatureC;
    }
    version (HomeEdition)
    {
        version = FeatureA;
    }
    ...
    version (FeatureB)
    {
        ... implement Feature B ...
    }

and imagine having to maintain a separate copy of these version assignments in each module!

I therefore suggest we allow something like this:

----- versions.d -----
version (ProfessionalEdition) {
    version = FeatureA;
    version = FeatureB;
    version = FeatureC;
}
version (HomeEdition) {
    version = FeatureA;
}
----- somemodule.d -----
version import versions;

version (FeatureB) {
    // ...
}

// ...
----------

The 'version import' declaration would import the version assignments in the specified module.  IMO the rules would be:

- version import imports only the version assignments, not the module symbol table.

- Version imports in a source file must be declared before regular imports and actual module content.

- Where a module has more than one version import, I'm guessing that the versions assigned in each would affect those that follow.  This means that version imports can depend on each other.

- I'm guessing that version importing would be transitive, but I'm not sure if it should be.

- There's no need for a separate 'debug import' declaration - indeed, this already means something else.  Rather, version import would import debug assignments as well as version assignments.

Stewart.
October 19, 2004
On Tue, 19 Oct 2004 18:32:40 +0100, Stewart Gordon <smjg_1998@yahoo.com> wrote:
> Change in 0.101:
>
> "Kris pointed out that version identifiers have global effect, and are dependent on which order modules are imported. This is clearly wrong. Now, only version and debug definitions on the command line have global effect. Others only influence the module they are declared in. Furthermore, version and debug definitions can only be done at module scope."
>
> With this change, we've lost a capability that the C preprocessor has: to use an include file to manipulate version identifiers.
>
> Consider a typical case of version manipulation:
> (http://www.digitalmars.com/d/version.html)
>
>      version (ProfessionalEdition)
>      {
>          version = FeatureA;
>          version = FeatureB;
>          version = FeatureC;
>      }
>      version (HomeEdition)
>      {
>          version = FeatureA;
>      }
>      ...
>      version (FeatureB)
>      {
>          ... implement Feature B ...
>      }
>
> and imagine having to maintain a separate copy of these version assignments in each module!
>
> I therefore suggest we allow something like this:
>
> ----- versions.d -----
> version (ProfessionalEdition) {
>      version = FeatureA;
>      version = FeatureB;
>      version = FeatureC;
> }
> version (HomeEdition) {
>      version = FeatureA;
> }
> ----- somemodule.d -----
> version import versions;
>
> version (FeatureB) {
>      // ...
> }
>
> // ...
> ----------
>
> The 'version import' declaration would import the version assignments in the specified module.  IMO the rules would be:
>
> - version import imports only the version assignments, not the module symbol table.
>
> - Version imports in a source file must be declared before regular imports and actual module content.
>
> - Where a module has more than one version import, I'm guessing that the versions assigned in each would affect those that follow.  This means that version imports can depend on each other.
>
> - I'm guessing that version importing would be transitive, but I'm not sure if it should be.
>
> - There's no need for a separate 'debug import' declaration - indeed, this already means something else.  Rather, version import would import debug assignments as well as version assignments.

I've not run into this problem before (yet) so I may be way off base here, but why not simply allow an optional 'public' or 'private' eg.

private version = A;
public version = B;
version = C;

so, when a module imports a module containing the above it see's 'version = B' but not 'version = A' or 'version = C' (as I think version should be private by default)

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
October 19, 2004
Regan Heath wrote:
> On Tue, 19 Oct 2004 18:32:40 +0100, Stewart Gordon <smjg_1998@yahoo.com> wrote:
> 
>> Change in 0.101:
>>
>> "Kris pointed out that version identifiers have global effect, and are dependent on which order modules are imported. This is clearly wrong. Now, only version and debug definitions on the command line have global effect. Others only influence the module they are declared in. Furthermore, version and debug definitions can only be done at module scope."
>>
>> With this change, we've lost a capability that the C preprocessor has: to use an include file to manipulate version identifiers.
>>
>> Consider a typical case of version manipulation:
>> (http://www.digitalmars.com/d/version.html)
>>
>>      version (ProfessionalEdition)
>>      {
>>          version = FeatureA;
>>          version = FeatureB;
>>          version = FeatureC;
>>      }
>>      version (HomeEdition)
>>      {
>>          version = FeatureA;
>>      }
>>      ...
>>      version (FeatureB)
>>      {
>>          ... implement Feature B ...
>>      }
>>
>> and imagine having to maintain a separate copy of these version assignments in each module!
>>
>> I therefore suggest we allow something like this:
>>
>> ----- versions.d -----
>> version (ProfessionalEdition) {
>>      version = FeatureA;
>>      version = FeatureB;
>>      version = FeatureC;
>> }
>> version (HomeEdition) {
>>      version = FeatureA;
>> }
>> ----- somemodule.d -----
>> version import versions;
>>
>> version (FeatureB) {
>>      // ...
>> }
>>
>> // ...
>> ----------
>>
>> The 'version import' declaration would import the version assignments in the specified module.  IMO the rules would be:
>>
>> - version import imports only the version assignments, not the module symbol table.
>>
>> - Version imports in a source file must be declared before regular imports and actual module content.
>>
>> - Where a module has more than one version import, I'm guessing that the versions assigned in each would affect those that follow.  This means that version imports can depend on each other.
>>
>> - I'm guessing that version importing would be transitive, but I'm not sure if it should be.
>>
>> - There's no need for a separate 'debug import' declaration - indeed, this already means something else.  Rather, version import would import debug assignments as well as version assignments.
> 
> 
> I've not run into this problem before (yet) so I may be way off base here, but why not simply allow an optional 'public' or 'private' eg.
> 
> private version = A;
> public version = B;
> version = C;
> 
> so, when a module imports a module containing the above it see's 'version = B' but not 'version = A' or 'version = C' (as I think version should be private by default)
> 
> Regan.
> 

Wrong. In D every declaration is defaulted to be public. No matter what happens. By the way, why not use version and import alongside?

Versions are not meant for other modules. They are for the compiler. If you enter dmd -version A ... you will compile everything in version A but not in version B and C.

Regards,
Sjoerd
October 19, 2004
On Tue, 19 Oct 2004 23:10:25 +0200, Sjoerd van Leent <svanleent@wanadoo.nl> wrote:
> Regan Heath wrote:
>> On Tue, 19 Oct 2004 18:32:40 +0100, Stewart Gordon <smjg_1998@yahoo.com> wrote:
>>
>>> Change in 0.101:
>>>
>>> "Kris pointed out that version identifiers have global effect, and are dependent on which order modules are imported. This is clearly wrong. Now, only version and debug definitions on the command line have global effect. Others only influence the module they are declared in. Furthermore, version and debug definitions can only be done at module scope."
>>>
>>> With this change, we've lost a capability that the C preprocessor has: to use an include file to manipulate version identifiers.
>>>
>>> Consider a typical case of version manipulation:
>>> (http://www.digitalmars.com/d/version.html)
>>>
>>>      version (ProfessionalEdition)
>>>      {
>>>          version = FeatureA;
>>>          version = FeatureB;
>>>          version = FeatureC;
>>>      }
>>>      version (HomeEdition)
>>>      {
>>>          version = FeatureA;
>>>      }
>>>      ...
>>>      version (FeatureB)
>>>      {
>>>          ... implement Feature B ...
>>>      }
>>>
>>> and imagine having to maintain a separate copy of these version assignments in each module!
>>>
>>> I therefore suggest we allow something like this:
>>>
>>> ----- versions.d -----
>>> version (ProfessionalEdition) {
>>>      version = FeatureA;
>>>      version = FeatureB;
>>>      version = FeatureC;
>>> }
>>> version (HomeEdition) {
>>>      version = FeatureA;
>>> }
>>> ----- somemodule.d -----
>>> version import versions;
>>>
>>> version (FeatureB) {
>>>      // ...
>>> }
>>>
>>> // ...
>>> ----------
>>>
>>> The 'version import' declaration would import the version assignments in the specified module.  IMO the rules would be:
>>>
>>> - version import imports only the version assignments, not the module symbol table.
>>>
>>> - Version imports in a source file must be declared before regular imports and actual module content.
>>>
>>> - Where a module has more than one version import, I'm guessing that the versions assigned in each would affect those that follow.  This means that version imports can depend on each other.
>>>
>>> - I'm guessing that version importing would be transitive, but I'm not sure if it should be.
>>>
>>> - There's no need for a separate 'debug import' declaration - indeed, this already means something else.  Rather, version import would import debug assignments as well as version assignments.
>>
>>
>> I've not run into this problem before (yet) so I may be way off base here, but why not simply allow an optional 'public' or 'private' eg.
>>
>> private version = A;
>> public version = B;
>> version = C;
>>
>> so, when a module imports a module containing the above it see's 'version = B' but not 'version = A' or 'version = C' (as I think version should be private by default)
>>
>> Regan.
>>
>
> Wrong. In D every declaration is defaulted to be public.

While that seems to be the pattern, in some cases I think it's a bad thing (TM).

> No matter what happens. By the way, why not use version and import alongside?

I have no idea what you mean :)
Example?

> Versions are not meant for other modules. They are for the compiler. If you enter dmd -version A ... you will compile everything in version A but not in version B and C.

While you are correct, I think you have missed the point of this post (either that or I have).

The problem is not with version statements supplied on the command line, but with version statements in the code, i.e.

--[a.d]--
version = Foo;

--[b.d]--
import a;

--[c.d]--
import a;

The C pre-processor allowed you to specify a version in a file, include that file into other files and share that version information. D doesn't allow this currently.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
October 20, 2004
I understand where you're coming from on this. But hear me out, I'll explain why D versions are the way they are.

Most C/C++ projects that have been maintained for a few years tend to sink into an incomprehensible rat's nest of #ifdef's. Each new set of maintainers tends to leave the old stuff as is and add a new layer of overlapping, redundant #ifdef identifiers. Sometimes the number of #ifdefs seem to dwarf the actual code. Trying to figure out which sections of code actually get compiled can get to be a big problem.

There are also some design principles of D at work here:

1) the contents of a module should not be influenced by whoever imports it,
this is so that the same module will generate the same code no matter who
imports it
2) the order in which imports are given should not affect the meaning
3) parsing needs to be independent of semantics

Above all, I wanted to avoid that morass of #ifdef's and where they came from.

The solution was to have only two levels of version identifiers - ones local to a module, and ones global to all the module. The latter are specified on the command line.

You can achieve the version configuration file approach by putting the following in a file called, say, version.cmd:

    version=FeatureA
    version=FeatureB
    version=FeatureC

and then add the following to the command line:

    dmd @version.cmd


October 20, 2004
Walter wrote:
> I understand where you're coming from on this. But hear me out, I'll explain
> why D versions are the way they are.
> 
> Most C/C++ projects that have been maintained for a few years tend to sink
> into an incomprehensible rat's nest of #ifdef's. Each new set of maintainers
> tends to leave the old stuff as is and add a new layer of overlapping,
> redundant #ifdef identifiers. Sometimes the number of #ifdefs seem to dwarf
> the actual code. Trying to figure out which sections of code actually get
> compiled can get to be a big problem.

Having only one or two version imports to traverse, rather than a whole bunch of nested #includes, simplifies this considerably.

> There are also some design principles of D at work here:
> 
> 1) the contents of a module should not be influenced by whoever imports it,
> this is so that the same module will generate the same code no matter who
> imports it
> 2) the order in which imports are given should not affect the meaning

Yes, that's true of the imports we have at the moment.  But in my idea, the whole point of version imports is that you specifically want to import something that will influence the module content.

Just thinking about it, if you have something like

    version import qwert;
    import yuiop;

then in the same way as versions assigned in this file don't affect yuiop, neither would the versions assigned in qwert.  Hence requiring version imports to be declared before regular imports isn't really necessary.

> 3) parsing needs to be independent of semantics

I don't see any way in which my idea would break this.

<snip>
> You can achieve the version configuration file approach by putting the
> following in a file called, say, version.cmd:
> 
>     version=FeatureA
>     version=FeatureB
>     version=FeatureC
> 
> and then add the following to the command line:
> 
>     dmd @version.cmd

Maybe this'll be adequate.  One'll have to see....

Stewart.
October 20, 2004
Regan Heath wrote:
>>>
>>
>> Wrong. In D every declaration is defaulted to be public.
> 
> 
> While that seems to be the pattern, in some cases I think it's a bad thing (TM).

I would say, go flaming on Walter, he made that decision, years ago... :)

> 
>> No matter what happens. By the way, why not use version and import alongside?
> 
> 
> I have no idea what you mean :)
> Example?
> 
>> Versions are not meant for other modules. They are for the compiler. If you enter dmd -version A ... you will compile everything in version A but not in version B and C.
> 
> 
> While you are correct, I think you have missed the point of this post (either that or I have).
> 
> The problem is not with version statements supplied on the command line, but with version statements in the code, i.e.
> 
> --[a.d]--
> version = Foo;
> 
> --[b.d]--
> import a;
> 
> --[c.d]--
> import a;
> 
> The C pre-processor allowed you to specify a version in a file, include that file into other files and share that version information. D doesn't allow this currently.
> 
> Regan
> 

But it is a question if this is a good thing (or not). Alright I missed out to note that down yesterday. Stil I think it shouldn't get to much muddled with. Currently I am doing dome D work in flex/bison and this is a real pain to implement.

Perhaps something like:

pragma(setVersion, Foo);

would do it nicely...

Regards,
Sjoerd