www.digitalmars.com         C & C++   DMDScript  

D - variable/module collision

reply Helmut Leitner <helmut.leitner chello.at> writes:
Currently code like

   import c.stdio;
   ...
   char c;
   char buf[256];
   c.stdio.fgets(&buf[0],buf.size,c.stdio.stdin);
   c=buf[0];

won't compile because of an

   no property 'stdio' for type 'char'

error.

Could this be changed, so that the compiler checks for an 
interpretation that makes sense if there a more than one?
Otherwise any module in any library is a potential 
candidate for such collisions!

--
Helmut Leitner    leitner hls.via.at   
Graz, Austria   www.hls-software.com
Jun 08 2003
next sibling parent Mark T <Mark_member pathlink.com> writes:
In article <3EE2FA45.29B11971 chello.at>, Helmut Leitner says...
Currently code like

   import c.stdio;
   ...
   char c;
   char buf[256];
   c.stdio.fgets(&buf[0],buf.size,c.stdio.stdin);
   c=buf[0];

won't compile because of an

   no property 'stdio' for type 'char'

error.

Could this be changed, so that the compiler checks for an 
interpretation that makes sense if there a more than one?
Otherwise any module in any library is a potential 
candidate for such collisions!

compilation purposes like C does. "More than one" shouldn't have anything to do with it.
Jun 08 2003
prev sibling next sibling parent "Walter" <walter digitalmars.com> writes:
You can work around this by prepending the module name:

module foo;
...
foo.c.stdio.fgets(...

"Helmut Leitner" <helmut.leitner chello.at> wrote in message
news:3EE2FA45.29B11971 chello.at...
 Currently code like

    import c.stdio;
    ...
    char c;
    char buf[256];
    c.stdio.fgets(&buf[0],buf.size,c.stdio.stdin);
    c=buf[0];

 won't compile because of an

    no property 'stdio' for type 'char'

 error.

 Could this be changed, so that the compiler checks for an
 interpretation that makes sense if there a more than one?
 Otherwise any module in any library is a potential
 candidate for such collisions!

 --
 Helmut Leitner    leitner hls.via.at
 Graz, Austria   www.hls-software.com

Jun 09 2003
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
In the next version, I've added a module scope operator, ., which should
resolve this problem properly, as in:

.c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

It works analogously to the C++ global scope operator ::.


"Helmut Leitner" <helmut.leitner chello.at> wrote in message
news:3EE2FA45.29B11971 chello.at...
 Currently code like

    import c.stdio;
    ...
    char c;
    char buf[256];
    c.stdio.fgets(&buf[0],buf.size,c.stdio.stdin);
    c=buf[0];

 won't compile because of an

    no property 'stdio' for type 'char'

 error.

 Could this be changed, so that the compiler checks for an
 interpretation that makes sense if there a more than one?
 Otherwise any module in any library is a potential
 candidate for such collisions!

 --
 Helmut Leitner    leitner hls.via.at
 Graz, Austria   www.hls-software.com

Jun 09 2003
next sibling parent reply Mark T <Mark_member pathlink.com> writes:
In article <bc3343$1dgn$1 digitaldaemon.com>, Walter says...
In the next version, I've added a module scope operator, ., which should
resolve this problem properly, as in:

.c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to avoid this ?? I thought the whole idea was to be cleaner than C++.
Jun 12 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Mark T" <Mark_member pathlink.com> wrote in message
news:bc9r3j$1bpm$1 digitaldaemon.com...
 In article <bc3343$1dgn$1 digitaldaemon.com>, Walter says...
In the next version, I've added a module scope operator, ., which should
resolve this problem properly, as in:
.c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to avoid

No.
 I thought the whole idea was to be cleaner than C++.

If there's a better way to resolve that problem, I want to know about it!
Jun 12 2003
next sibling parent reply Georg Wrede <Georg_member pathlink.com> writes:
It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to avoid

No.
 I thought the whole idea was to be cleaner than C++.

If there's a better way to resolve that problem, I want to know about it!

I think this should be studied together with the Private Import b.a.A issue. Maybe a lot of folks have reasoned deeply into this, but so far the recent discussion here about this has been shallow, almost like "this looks nice, lets do it this way", when we should really consider the _meaning_ of imports, private imports, indirect inclusion (i.e. the b.a.A issue), visibility, and propagation of visibility, as manifestations of a single concept. Like _what_ is one really attempting to acheve with all these. We ought to get a crystal clear understanding, not least because if this is done wrong now then later there'll be hell to pay. Once we understand this, then the separate answers to these "separate" issues, I believe, will become obvious.
Jun 13 2003
next sibling parent reply Helmut Leitner <leitner hls.via.at> writes:
Georg Wrede wrote:
If there's a better way to resolve that problem, I want to know about it!

I think this should be studied together with the Private Import b.a.A issue. Maybe a lot of folks have reasoned deeply into this, but so far the recent discussion here about this has been shallow, almost like "this looks nice, lets do it this way", when we should really consider the _meaning_ of imports, private imports, indirect inclusion (i.e. the b.a.A issue), visibility, and propagation of visibility, as manifestations of a single concept. Like _what_ is one really attempting to acheve with all these. We ought to get a crystal clear understanding, not least because if this is done wrong now then later there'll be hell to pay. Once we understand this, then the separate answers to these "separate" issues, I believe, will become obvious.

I think you are absolutely right. I'm unhappy about the current situation but I can't offer a solution. But I think we should try to discuss this more thoroughly. Walters viewpoint as a compiler builder is naturally quite different from your viewpoint as an academic teacher. There are a number of other viewpoints in this group. I would summarize my own viewpoint as that of an "pragmatic application programmer". I started 1979 with an USCD Pascal statistical project done on an Apple II and I did about 120 projects during these 24 years. Currently I actively work at 5 projects and maintain about a dozen Most are written in C, Perl or VB. I own my code and I therefore care for my code and its reusability in a special way. In all my projects I want to create a single language space. I think of programming as building a new language on top of the programming language and the selected tool libraries. This new language should maintain its semantics across all borders of modules, projects and libraries without additional effort. In VB and Perl you work in a single namespace. In C you can work with a central header file, if you have collisions you will see them while compiling this central header, thats fine. In D you can use a central header file but the collisions are distributed across place and time. They turn up every now and then. This is IMHO an unbearable situation. It must be possible to change the language space and see its effects (correct any resulting problems) at the time of change. After separated decisions about the language space from the actual source written, it must be possible to use the selected functions in their native form. The problem I started this thread with, that the variable char c; created a problem to call fgets(...) can't be considered solved when a syntactical solution like .c.stdio.fgets(...) is possible. (The compiler builder will think so) It would be solved, when I can decide: prefer c.stdio over phobos.file; or: priorities: variable.namespace,c.stdio,phobos.file,....; where I can direct the compiler how to resolve ambiguities on a project level or a higher level. Solving such things at the source or module level creates "local language" and makes code dependant on these local decisions. This makes code hard to read, move, refactor and reuse. The projects of tomorrow will make us work with 10.000+ functions/methods/modules. Individually importing the mecessary modules and resolving conflicts is a mess. IMHO. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
Jun 13 2003
next sibling parent Andy Friesen <andy ikagames.com> writes:
Helmut Leitner wrote:
 [...]
 
 After separated decisions about the language space from the actual
 source written, it must be possible to use the selected functions
 in their native form. The problem I started this thread with,
 that the variable
    char c;
 created a problem to call
    fgets(...)
 can't be considered solved when a syntactical solution like
    .c.stdio.fgets(...)
 is possible. (The compiler builder will think so)
 
 It would be solved, when I can decide:
    prefer c.stdio over phobos.file;
 or:
    priorities: variable.namespace,c.stdio,phobos.file,....;
 
 where I can direct the compiler how to resolve ambiguities on a 
 project level or a higher level.
      
 Solving such things at the source or module level creates 
 "local language" and makes code dependant on these local decisions.
 This makes code hard to read, move, refactor and reuse.
 
 The projects of tomorrow will make us work with 10.000+ 
 functions/methods/modules. Individually importing the
 mecessary modules and resolving conflicts is a mess. 
 
 IMHO.
 

I think the solution in this case is pretty simple. Remove the fgets definition from phobos.file. In fact, it's not in my copy (0.66) at all, so I can't see the problem happening. If push comes to shove, you could always make an alias: alias fgets .c.stdio.fgets; Private imports should further alleviate this situation, as we now have explicit control over what gets dumped into a namespace.
Jun 13 2003
prev sibling parent reply "Fabian Giesen" <rygNO SPAMgmx.net> writes:
 After separated decisions about the language space from the actual
 source written, it must be possible to use the selected functions
 in their native form. The problem I started this thread with,
 that the variable
    char c;
 created a problem to call
    fgets(...)
 can't be considered solved when a syntactical solution like
    .c.stdio.fgets(...)
 is possible. (The compiler builder will think so)

 It would be solved, when I can decide:
    prefer c.stdio over phobos.file;
 or:
    priorities: variable.namespace,c.stdio,phobos.file,....;

 where I can direct the compiler how to resolve ambiguities on a
 project level or a higher level.

 Solving such things at the source or module level creates
 "local language" and makes code dependant on these local decisions.
 This makes code hard to read, move, refactor and reuse.

So does, IMHO, your prioritizing solution; while this solves the problem on a project-granular basis, it makes it hard to transfer code from one project to another, especially if you can't just copy the priorities over because the rest of your code assumes different ones. You don't get rid of this with moving it to user-level preferences or site-level preferences either - all this does is move what you call "local language" to a higher level, while not solving the actual problem at all; this is, in my opinion, unaccep- table. Other problems with that approach include that it introduces quite dubious name lookup rules (the point was getting it easier than C++, not more complicated, no? :) and actually suggests writing ambiguous code and resolving that ambiguities with priorities later. This kind of collisions should, ideally, either be disallowed by the language (like with redefinition of local variables) or atleast made harder to happen, which would be possible using coding standards only. To explain the coding standards point: Using a one-character identifier for a module ("c"), while convenient, is still a Bad Thing; was it named "clib" or something similar instead, the whole issue most likely wouldn't exist. While this doesn't solve the actual problem, I still think it would be a good idea to change the standard libraries and coding conventions to use atleast 3-character names; anything lower than that is bound to cause problems like this one. Now, for the language approach: I'd be for disallowing *any* kind of identifier to be identical to a (known, that is, imported in the module and scope being compiled) module name. This makes the ".c.stdio.fgets" notation unnecessary - such collisions simply cannot happen that way. This only solves the problem in the module being compiled, which means the following case could still be considered problematic: // a.d module a; // ... // b.d int a=3; // main.d import b; import a; Now, what is a? Obviously, it *should* be the module a in that case, because b's a can still be reached by using b.a, while the opposite is not true. There are two ways to solve the problem - either issue an error while compiling main.d, or introducing another rule that module names "hide" symbols defined in other modules. Both aren't particularly clean, but I consider the first to be the worse alternative, for three reasons: 1. It basically suggests that there can be errors in b's code that cannot necessarily be found while compiling b, because they are dependent on the context in which b is being used. This would be quite an awkward situation. 2. It's not orthogonal with the way D normally handles such ambi- guities - namely, *not* issuing an error, just requiring full qualification to resolve which symbol is meant. 3. Existing and perfectly valid code can break any time in the future when someone, somewhere adds another module that causes conflicting identifiers. That issue should have to be resolved by either the author of that module or by the one who attempts to use both modules. The second solution can never break existing code (unless there are issues I'm not aware of), and I think requiring module names to be unique is a good idea in any case. -fg
Jun 14 2003
parent reply Helmut Leitner <helmut.leitner chello.at> writes:
Fabian Giesen wrote:
 
 After separated decisions about the language space from the actual
 source written, it must be possible to use the selected functions
 in their native form. The problem I started this thread with,
 that the variable
    char c;
 created a problem to call
    fgets(...)
 can't be considered solved when a syntactical solution like
    .c.stdio.fgets(...)
 is possible. (The compiler builder will think so)

 It would be solved, when I can decide:
    prefer c.stdio over phobos.file;
 or:
    priorities: variable.namespace,c.stdio,phobos.file,....;

 where I can direct the compiler how to resolve ambiguities on a
 project level or a higher level.

 Solving such things at the source or module level creates
 "local language" and makes code dependant on these local decisions.
 This makes code hard to read, move, refactor and reuse.

So does, IMHO, your prioritizing solution; while this solves the problem on a project-granular basis, it makes it hard to transfer code from one project to another, especially if you can't just copy the priorities over because the rest of your code assumes different ones. You don't get rid of this with moving it to user-level preferences or site-level preferences either - all this does is move what you call "local language" to a higher level, while not solving the actual problem at all; this is, in my opinion, unaccep- table. Other problems with that approach include that it introduces quite dubious name lookup rules (the point was getting it easier than C++, not more complicated, no? :) and actually suggests writing ambiguous code and resolving that ambiguities with priorities later. This kind of collisions should, ideally, either be disallowed by the language (like with redefinition of local variables) or atleast made harder to happen, which would be possible using coding standards only. To explain the coding standards point: Using a one-character identifier for a module ("c"), while convenient, is still a Bad Thing; was it named "clib" or something similar instead, the whole issue most likely wouldn't exist. While this doesn't solve the actual problem, I still think it would be a good idea to change the standard libraries and coding conventions to use atleast 3-character names; anything lower than that is bound to cause problems like this one. Now, for the language approach: I'd be for disallowing *any* kind of identifier to be identical to a (known, that is, imported in the module and scope being compiled) module name. This makes the ".c.stdio.fgets" notation unnecessary - such collisions simply cannot happen that way. This only solves the problem in the module being compiled, which means the following case could still be considered problematic: // a.d module a; // ... // b.d int a=3; // main.d import b; import a; Now, what is a? Obviously, it *should* be the module a in that case, because b's a can still be reached by using b.a, while the opposite is not true. There are two ways to solve the problem - either issue an error while compiling main.d, or introducing another rule that module names "hide" symbols defined in other modules. Both aren't particularly clean, but I consider the first to be the worse alternative, for three reasons: 1. It basically suggests that there can be errors in b's code that cannot necessarily be found while compiling b, because they are dependent on the context in which b is being used. This would be quite an awkward situation. 2. It's not orthogonal with the way D normally handles such ambi- guities - namely, *not* issuing an error, just requiring full qualification to resolve which symbol is meant. 3. Existing and perfectly valid code can break any time in the future when someone, somewhere adds another module that causes conflicting identifiers. That issue should have to be resolved by either the author of that module or by the one who attempts to use both modules. The second solution can never break existing code (unless there are issues I'm not aware of), and I think requiring module names to be unique is a good idea in any case.

Rethinking the problem based on your excellent arguments... I think that the current problem has two parts. One is syntactical, because the system treats c.size (property or method of an "object") the same as c.stdio (module from a package) which feels not quite right. Using a different syntax for modules, e. g. c:stdio the problem would go away. (I do not suggest this solution) On the other hand, there is the semantical problem how to deal with ambiguities. This problem turns up here, but there is at least one other place where I met the same problem (parameter matching). The way that D currently chooses is that of complete qualification: in case of an ambiguity (and that is handled very strictly) you have to exactly say what you want. E. g. if you have a sqrt(long x) and sqrt(real x) doing float f; x=sqrt(f); is considered ambiguous and has to be resolved by float f; x=sqrt((real)f); This philosophical decision will turn up as a PITA in the future. Having a sqrt(real) in a distributed library and adding sqrt(long) will break the code of hundreds of developers and force them to exactly qualify what they now - after the library update - want. In the current case there is only an ambiguity at the first level, because we don't know what c (the variable ? the module?) is. But the way it is used c.stdio... there is no ambiguity, because only the module has this property. It would be nice if the D compiler had enough intelligence to cope with this situation. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
Jun 15 2003
next sibling parent reply "Fabian Giesen" <rygNO SPAMgmx.net> writes:
 On the other hand, there is the semantical problem how to deal with
 ambiguities. This problem turns up here, but there is at least one
 other place where I met the same problem (parameter matching).
 The way that D currently chooses is that of complete qualification:
 in case of an ambiguity (and that is handled very strictly) you have
 to exactly say what you want.
 E. g. if you have a
    sqrt(long x) and sqrt(real x)
 doing
    float f; x=sqrt(f);
 is considered ambiguous and has to be resolved by
    float f; x=sqrt((real)f);
 This philosophical decision will turn up as a PITA in the future.
 Having a sqrt(real) in a distributed library and adding sqrt(long)
 will break the code of hundreds of developers and force them to
 exactly qualify what they now - after the library update - want.

Yeah, but you have *that* problem with overload resolution in e.g. C++, too. Just because C++ compilers make somewhat more ambitious attempts at deducing which overload is the best alternative it doesn't mean that kind of problem doesn't exist - quite on the con- trary, actually. C++ has rules that disambiguate such cases, but this can break code in very nonobvious ways: assume that there is already a double sqrt(double) and at some point later in time someone adds a int sqrt(int) routine. Every code that previously called sqrt with an int parameter will now use the version that returns an integer - even in fp expressions. C++ will silently do that and not even issue a warning, because the over- load resolution is completely unambiguous. Of course this will totally break any code assuming that you get a double return value. Bottom line: Overloads are a very picky thing no matter what you do. The whole point of overloading is to allow some kind of ambiguity to make writing code easier or more intuitive. However, it can *very* easily backfire, in circumstances as illustrated above, and, as you see, in very non-intuitive ways. In this case, I think D's choice to expli- citly force nonambiguous qualification is the right one; especially since you normally CANNOT add new overloads without the risk of breaking tons of existing code anyway. This is a design problem with overloads itself - and there's nothing one can do about it except being very care- ful when using overloads and not adding new overloads later when they're not absolutely necessary (this only goes for overloads with the same number of parameters; a different number is obviously not quite as dangerous). -fg
Jun 15 2003
parent reply Helmut Leitner <helmut.leitner chello.at> writes:
Fabian Giesen wrote:
 
 On the other hand, there is the semantical problem how to deal with
 ambiguities. This problem turns up here, but there is at least one
 other place where I met the same problem (parameter matching).
 The way that D currently chooses is that of complete qualification:
 in case of an ambiguity (and that is handled very strictly) you have
 to exactly say what you want.
 E. g. if you have a
    sqrt(long x) and sqrt(real x)
 doing
    float f; x=sqrt(f);
 is considered ambiguous and has to be resolved by
    float f; x=sqrt((real)f);
 This philosophical decision will turn up as a PITA in the future.
 Having a sqrt(real) in a distributed library and adding sqrt(long)
 will break the code of hundreds of developers and force them to
 exactly qualify what they now - after the library update - want.

Yeah, but you have *that* problem with overload resolution in e.g. C++, too. Just because C++ compilers make somewhat more ambitious attempts at deducing which overload is the best alternative it doesn't mean that kind of problem doesn't exist - quite on the con- trary, actually. C++ has rules that disambiguate such cases, but this can break code in very nonobvious ways: assume that there is already a double sqrt(double) and at some point later in time someone adds a int sqrt(int) routine.

I never liked C++ enough to use it in a project. Changing the strategy because A causes problems doesn't guarantee that "not A" doesn't produce the same amount of problems (or more). Remember MS-Windows going in and of of the "central config repository" idea.
 Every code that previously called sqrt with an int parameter will now
 use the version that returns an integer - even in fp expressions. C++
 will silently do that and not even issue a warning, because the over-
 load resolution is completely unambiguous. Of course this will totally
 break any code assuming that you get a double return value.

My example wasn't well chosen, I just wanted a function that I didn't have to explain. But: sqrt is by definition a floating point function. If overloaded it must return a FP value. Otherwise it changes the semantics and should be names something like SqrtFloor(...). A sqrt(long x) might be some function that uses tables for small values of x to increase performance and fall back to the normal sqrt.
 Bottom line: Overloads are a very picky thing no matter what you do.
 The whole point of overloading is to allow some kind of ambiguity to
 make writing code easier or more intuitive. However, it can *very*
 easily backfire, in circumstances as illustrated above, and, as you see,
 in very non-intuitive ways. In this case, I think D's choice to expli-
 citly force nonambiguous qualification is the right one; especially
 since you normally CANNOT add new overloads without the risk of breaking
 tons of existing code anyway. This is a design problem with overloads
 itself - and there's nothing one can do about it except being very care-
 ful when using overloads and not adding new overloads later when they're
 not absolutely necessary (this only goes for overloads with the same
 number of parameters; a different number is obviously not quite as
 dangerous).

I'm no overloading fan. It seems that OO languages can't live without it. I deliver libraries. I don't want a new library to break any old code. If a language can't gurantee me a way - however complicated - to do that, it is no use for me. I can't avoid to create tons of modules. If these modules will share some namespace with variables, then the module names will have to be pretty unique to reduce the risc of conflict. E. g. one could name them p__c.m__stdio (package _ _ c).(module _ _ stdio) This is so ugly that after some time Walter will feel a need to invent something to avoid it. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
Jun 15 2003
next sibling parent "Fabian Giesen" <rygNO SPAMgmx.net> writes:
 My example wasn't well chosen, I just wanted a function that I didn't
 have to explain.

 But: sqrt is by definition a floating point function. If overloaded
 it must return a FP value. Otherwise it changes the semantics and
 should be names something like SqrtFloor(...). A sqrt(long x) might be
 some function that uses tables for small values of x to increase
 performance and fall back to the normal sqrt.

It is crucial to realize that the problem itself is absolutely independent of function chosen (though the probability of it happening isn't). As soon as you start to allow ambiguities, things do, well, get ambiguous :) Adding a new overloaded function with the same number of parameters and different types always has the potential to break existing code - unless the set of types reachable via implicit conversions by the two is disjoint; for example, overloading f(char) with f(char[]) is always safe, since there's no way any implicit conversion should happen that changes the meaning of existing code. However, there IS an easy solution to get rid of that problem - once you know of that issue, just never do that and rather name the function differently. Problem solved :)
 I'm no overloading fan. It seems that OO languages can't live without
 it.

It's a nice feature, but as always, it comes with a price.
 I deliver libraries. I don't want a new library to break any old code.
 If a language can't gurantee me a way - however complicated - to do
 that, it is no use for me.

 I can't avoid to create tons of modules. If these modules will share
 some namespace with variables, then the module names will have to be
 pretty unique to reduce the risc of conflict. E. g. one could name
 them
    p__c.m__stdio (package _ _ c).(module _ _ stdio)
 This is so ugly that after some time Walter will feel a need to
 invent something to avoid it.

Not all module names need to have different names than variables, only the top-level ones do. The rest is reachable via full qualification in any case and doesn't require additional syntax such as a global scope operator. Besides, prefixing is really the worst method to solve the unique identifier problem - clib.stdio would do just fine IMHO. -fg
Jun 16 2003
prev sibling next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
 I deliver libraries. I don't want a new library to break any old code.
 If a language can't gurantee me a way - however complicated - to do that,
 it is no use for me.

Quite true
Jul 08 2003
prev sibling parent "Walter" <walter digitalmars.com> writes:
"Helmut Leitner" <helmut.leitner chello.at> wrote in message
news:3EED5F39.7760CD6C chello.at...
 I deliver libraries. I don't want a new library to break any old code.
 If a language can't gurantee me a way - however complicated - to do that,
 it is no use for me.

One crucial point - overloading does not happen across modules. It only happens to names at the same scope. Hence, if you add a new module foo with foo.sqrt() in it, that will not overload with math.sqrt(). This is because lookups are done name first, then overload resolution.
Aug 04 2003
prev sibling parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
 Using a different syntax for modules, e. g.
    c:stdio
 the problem would go away. (I do not suggest this solution)

Why not? I've never understood the reason for dropping :: in favour of . in Java/.NET. After all, one can still use . to issue a static call on an instance in C++ if one needs this extra level of flexibility (say in a template). The reverse is not true in D/Java/.NET. If I want to explicitly stipulate that something is a static method/variable (again, say in a template) how to I do it? Is there a reason that D has done away with :: or maybe just : ? I think we should have the ability to specify relative and absolute namespaces, so this would certainly lead to a mess with using . Surely there are plenty of symbols left in the character set that would make this relatively simple.
Jul 08 2003
next sibling parent reply Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <befsfr$17ad$3 digitaldaemon.com>, Matthew Wilson wrote:
 Using a different syntax for modules, e. g.
    c:stdio
 the problem would go away. (I do not suggest this solution)

Why not? I've never understood the reason for dropping :: in favour of . in Java/.NET. After all, one can still use . to issue a static call on an instance in C++ if one needs this extra level of flexibility (say in a template). The reverse is not true in D/Java/.NET. If I want to explicitly stipulate that something is a static method/variable (again, say in a template) how to I do it? Is there a reason that D has done away with :: or maybe just : ?

According to Stroustrup (Design & Evolution of C++), C++ originally had only "." but "::" was introduced because it was common C practice to have a class and an object with the same name. As this is not the case any more, "::" is simply not needed. I can't figure out an example of an situation that would really require it, even in a template -- can you? -Antti
Jul 09 2003
next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
"Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
news:slrnbgp4k9.pdc.jsykari seth.hut.fi...
 In article <befsfr$17ad$3 digitaldaemon.com>, Matthew Wilson wrote:
 Using a different syntax for modules, e. g.
    c:stdio
 the problem would go away. (I do not suggest this solution)

Why not? I've never understood the reason for dropping :: in favour of .


 Java/.NET. After all, one can still use . to issue a static call on an
 instance in C++ if one needs this extra level of flexibility (say in a
 template). The reverse is not true in D/Java/.NET. If I want to


 stipulate that something is a static method/variable (again, say in a
 template) how to I do it?

 Is there a reason that D has done away with :: or maybe just :   ?

According to Stroustrup (Design & Evolution of C++), C++ originally had only "." but "::" was introduced because it was common C practice to have a class and an object with the same name. As this is not the case any more, "::" is simply not needed. I can't figure out an example of an situation that would really require it, even in a template -- can you? -Antti

Jul 09 2003
prev sibling next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
"Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
news:slrnbgp4k9.pdc.jsykari seth.hut.fi...
 In article <befsfr$17ad$3 digitaldaemon.com>, Matthew Wilson wrote:
 Using a different syntax for modules, e. g.
    c:stdio
 the problem would go away. (I do not suggest this solution)

Why not? I've never understood the reason for dropping :: in favour of .


 Java/.NET. After all, one can still use . to issue a static call on an
 instance in C++ if one needs this extra level of flexibility (say in a
 template). The reverse is not true in D/Java/.NET. If I want to


 stipulate that something is a static method/variable (again, say in a
 template) how to I do it?

 Is there a reason that D has done away with :: or maybe just :   ?

According to Stroustrup (Design & Evolution of C++), C++ originally had only "." but "::" was introduced because it was common C practice to have a class and an object with the same name. As this is not the case any more, "::" is simply not needed. I can't figure out an example of an situation that would really require it, even in a template -- can you?

"If I want to explicitly stipulate that something is a static method/variable (again, say in a template) how to I do it?"
 -Antti

Jul 09 2003
prev sibling parent Helmut Leitner <leitner hls.via.at> writes:
Antti Sykäri wrote:
 
 In article <befsfr$17ad$3 digitaldaemon.com>, Matthew Wilson wrote:
 Using a different syntax for modules, e. g.
    c:stdio
 the problem would go away. (I do not suggest this solution)

Why not? I've never understood the reason for dropping :: in favour of . in Java/.NET. After all, one can still use . to issue a static call on an instance in C++ if one needs this extra level of flexibility (say in a template). The reverse is not true in D/Java/.NET. If I want to explicitly stipulate that something is a static method/variable (again, say in a template) how to I do it? Is there a reason that D has done away with :: or maybe just : ?

According to Stroustrup (Design & Evolution of C++), C++ originally had only "." but "::" was introduced because it was common C practice to have a class and an object with the same name. As this is not the case any more, "::" is simply not needed. I can't figure out an example of an situation that would really require it, even in a template -- can you?

You just have to go back to message one of this thread which I started with simple example where I stumbled over the problem: In short: char c; is enough to get into trouble. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
Jul 10 2003
prev sibling parent reply Mark T <Mark_member pathlink.com> writes:
In article <befsfr$17ad$3 digitaldaemon.com>, Matthew Wilson says...
 Using a different syntax for modules, e. g.
    c:stdio
 the problem would go away. (I do not suggest this solution)


Why not? I've never understood the reason for dropping :: in favour of . in
Java/.NET. After all, one can still use . to issue a static call on an
instance in C++ if one needs this extra level of flexibility (say in a
template). The reverse is not true in D/Java/.NET. If I want to explicitly
stipulate that something is a static method/variable (again, say in a
template) how to I do it?

Is there a reason that D has done away with :: or maybe just :   ?

maybe it would be nice to change inheritance declares to class B extends A and interface to class C implements I,J like Java so the ":" symbol would be available for more meaningful uses in statements
Jul 12 2003
parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
I doubt very much that it poses a parsing problem.  The larger conflict is
with local label syntax.

Sean

"Mark T" <Mark_member pathlink.com> wrote in message
news:beov0g$15ln$1 digitaldaemon.com...
 In article <befsfr$17ad$3 digitaldaemon.com>, Matthew Wilson says...
 Using a different syntax for modules, e. g.
    c:stdio
 the problem would go away. (I do not suggest this solution)


Why not? I've never understood the reason for dropping :: in favour of .


Java/.NET. After all, one can still use . to issue a static call on an
instance in C++ if one needs this extra level of flexibility (say in a
template). The reverse is not true in D/Java/.NET. If I want to


stipulate that something is a static method/variable (again, say in a
template) how to I do it?

Is there a reason that D has done away with :: or maybe just :   ?

maybe it would be nice to change inheritance declares to class B extends A and interface to class C implements I,J like Java so the ":" symbol would be available for more meaningful uses in

Jul 12 2003
parent "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:bep4tm$1bbh$1 digitaldaemon.com...
 I doubt very much that it poses a parsing problem.  The larger conflict is
 with local label syntax.

It also causes parsing problems with ?: syntax.
Aug 04 2003
prev sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
"Georg Wrede" <Georg_member pathlink.com> wrote in message
news:bcbt1u$ao3$1 digitaldaemon.com...
It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to



this ??

No.

 I thought the whole idea was to be cleaner than C++.

If there's a better way to resolve that problem, I want to know about it!

I think this should be studied together with the Private Import b.a.A issue. Maybe a lot of folks have reasoned deeply into this, but so far the recent discussion here about this has been shallow, almost like "this looks nice, lets do it this way", when we should really consider the _meaning_ of imports, private imports, indirect inclusion (i.e. the b.a.A issue), visibility, and propagation of visibility, as manifestations of a single concept. Like _what_ is one really attempting to acheve with all these. We ought to get a crystal clear understanding, not least because if this is done wrong now then later there'll be hell to pay.

Strongly agree
 Once we understand this, then the separate answers to these
 "separate" issues, I believe, will become obvious.

Jul 08 2003
prev sibling next sibling parent Mark T <Mark_member pathlink.com> writes:
In the next version, I've added a module scope operator, ., which should
resolve this problem properly, as in:
.c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to avoid

No.
 I thought the whole idea was to be cleaner than C++.

If there's a better way to resolve that problem, I want to know about it!

import c.stdio; .. char c; char buf[256]; c.stdio.fgets(&buf[0],buf.size,c.stdio.stdin); c=buf[0]; won't compile because of an no property 'stdio' for type 'char' =========================== let's get back to basics here: the "c" in c.stdio is a package name, it seems that the compilation system should be able to resolve this name versus the variable name "c" from char c. Since in D this "c" is only a reference on how to locate module "stdio". Shouldn't each of package, module, class, variable, etc have it's own name space (whether through name mangling or other means)? I worked with the Ada language for several years and it was easy to resolve any name conflicts between imports by prepending the package name to the function or variable name (assume 'with' and 'use'). Package_1.Function(x) vs Package_2.Function(x) note: Ada package is a module
Jun 21 2003
prev sibling parent reply Burton Radons <loth users.sourceforge.net> writes:
Walter wrote:
 "Mark T" <Mark_member pathlink.com> wrote in message
 news:bc9r3j$1bpm$1 digitaldaemon.com...
 
In article <bc3343$1dgn$1 digitaldaemon.com>, Walter says...

In the next version, I've added a module scope operator, ., which should
resolve this problem properly, as in:
.c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to avoid

this ?? No.
I thought the whole idea was to be cleaner than C++.

If there's a better way to resolve that problem, I want to know about it!

Yeah, don't use too-short module names, and don't put kludges into a language solving a problem that shouldn't exist if the language were being correctly used. I think there's two mistakes going on here. First, we should be applying package organisation to Phobos and other libraries. Second, we should be using capital letters in module names when appropriate. Intuitively, lowercase feels better. But in practice, it results in ugly names, lots of collisions, and seems to result in more curious acronyms and cut words than capitalised (java.rmi.dgc, for example). One naming scheme could be like this: aaA -> D.Internal.AArray; achar -> D.Internal.AChar; adi -> D.Internal.Array; alloca -> D.Internal.alloca; array -> D.Exception.ArrayBoundsError; arraycast -> D.Internal.ArrayCast; arraycat -> D.Internal.ArrayCat; assert -> D.Exception.AssertError; (It's not even a valid module name for goodness' sake!) cast -> D.Internal.Cast; (Ditto!) cmath -> D.System.ComplexMath; cmath2 -> D.Internal.ComplexArithmetic; com -> D.Phobos.COM; compiler -> D.Phobos.Compiler; conv -> D.Phobos.Conv; crc32 -> D.Phobos.CRC32; ctype -> D.Phobos.CharType; date -> D.Phobos.Date; dateparse -> D.Phobos.DateParse; deh2 -> D.Internal.ExceptionHandling; dmain2 -> D.Internal.Main; file -> D.Phobos.File; gc -> D.Phobos.GC; gcstats (merge with gc) intrinsic -> D.Internal.Intrinsic; (put aliases in D.Phobos.Math) invariant -> D.Internal.Invariant; iunknown -> D.Phobos.IUnknown; linux -> D.CRT.Linux; linuxextern -> D.CRT.LinuxExtern; llmath -> D.Internal.LongArithmetic; math -> D.Phobos.Math; math2 (merge with D.Phobos.Math) memset -> D.Internal.memset; moduleinit -> D.Internal.ModuleInit; obj -> D.Internal.Object; object -> D.Phobos.Object; outbuffer -> D.Phobos.OutBuffer; outofmemory -> D.Error.OutOfMemory; path -> D.Phobos.Path; qsort -> D.Internal.Sort; random -> D.Phobos.Random; regexp -> D.Phobos.RegExp; stdint -> D.Phobos.StandardTypes; stream -> D.Phobos.Stream; string -> D.Phobos.String; switch -> D.Internal.Switch; (again the name!) switcherr -> D.Exception.SwitchError; syserror -> D.Exception.SystemError; system -> D.Phobos.System; thread -> D.Phobos.Thread; time -> D.Phobos.Time; ti_* -> D.Internal.*; uri -> D.Phobos.URI; utf -> D.Phobos.UTF8; windows -> D.CRT.windows; c.stdio -> D.CRT.stdio; c.stdlib -> D.CRT.stdlib; gc.* -> D.Internal.GC.*; dig would be put in the "D.Dig" package. I could use "D.Dig.Main" for what "import dig" does now. Or some other prefix than D. In any case, it's much clearer about what I'm referring to; when I type "string.tolower" it's ambiguous as to whether I'm referring to a module or an object, as I use it for both heavily. XYZ.Phobos.String.tolower is completely unambiguous, and if it gets too much (module "string."'s used 43 times throughout dig, so that can happen) I can alias it to something more manageable. And with full package names, I can alias more selectively - "private alias XYZ.Phobos P;" would allow me to use "P.String.tolower", which can often be enough.
Jun 21 2003
next sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
Windows should go into D.Platform.windows or D.SDK.windows;  it is most
certainly not standard C runtime library material.  Same with Linux.

I don't care if you use capital letters or not.  Personally I like
MixedCase, but it really doesn't matter to me.

I do like the idea of moving all this stuff into the D module umbrella.
Prevents many many clashes, prevents cluttering up the global namespace.  It
gives people a clear idea of whether a module is 1st-party or 3rd-party.
But then why would Dig go under D?  DigitalMars should reserve the entire
D.* module namespace.  Library writers can make their own, such as
BRadons.Dig.  ;)

Why the "Internal" module group?  I'm kinda surprised that there are so many
low-level support libraries;  I'd expect more of this to be built in, or
unnecessary.

What's the difference between complex math and complex arithmetic?  Why are
they separate?  They're not even in the same branch... that's just wierd.

I agree that Intrinsic should have aliases in Math.  I suggest that users
should not have to care whether something is an intrinsic or not;  this is
entirely a choice that should be left up to the compiler, possibly affected
by some kind of speed vs. size switch.  It is an implementation detail and
users shouldn't be forced to deal with it.

Why is there D.Exception.* and D.Internal.Exception?

Rename Conv to Convert.  Saving 3 characters is not worth it.  Or maybe
Conversion.

Sean

"Burton Radons" <loth users.sourceforge.net> wrote in message
news:bd1r3s$1s87$1 digitaldaemon.com...
 Yeah, don't use too-short module names, and don't put kludges into a
 language solving a problem that shouldn't exist if the language were
 being correctly used.

 I think there's two mistakes going on here.  First, we should be
 applying package organisation to Phobos and other libraries.  Second, we
 should be using capital letters in module names when appropriate.
 Intuitively, lowercase feels better.  But in practice, it results in
 ugly names, lots of collisions, and seems to result in more curious
 acronyms and cut words than capitalised (java.rmi.dgc, for example).
 One naming scheme could be like this:

 aaA -> D.Internal.AArray;
 achar -> D.Internal.AChar;
 adi -> D.Internal.Array;
 alloca -> D.Internal.alloca;
 array -> D.Exception.ArrayBoundsError;
 arraycast -> D.Internal.ArrayCast;
 arraycat -> D.Internal.ArrayCat;
 assert -> D.Exception.AssertError; (It's not even a valid module name
 for goodness' sake!)
 cast -> D.Internal.Cast; (Ditto!)
 cmath -> D.System.ComplexMath;
 cmath2 -> D.Internal.ComplexArithmetic;
 com -> D.Phobos.COM;
 compiler -> D.Phobos.Compiler;
 conv -> D.Phobos.Conv;
 crc32 -> D.Phobos.CRC32;
 ctype -> D.Phobos.CharType;
 date -> D.Phobos.Date;
 dateparse -> D.Phobos.DateParse;
 deh2 -> D.Internal.ExceptionHandling;
 dmain2 -> D.Internal.Main;
 file -> D.Phobos.File;
 gc -> D.Phobos.GC;
 gcstats (merge with gc)
 intrinsic -> D.Internal.Intrinsic; (put aliases in D.Phobos.Math)
 invariant -> D.Internal.Invariant;
 iunknown -> D.Phobos.IUnknown;
 linux -> D.CRT.Linux;
 linuxextern -> D.CRT.LinuxExtern;
 llmath -> D.Internal.LongArithmetic;
 math -> D.Phobos.Math;
 math2 (merge with D.Phobos.Math)
 memset -> D.Internal.memset;
 moduleinit -> D.Internal.ModuleInit;
 obj -> D.Internal.Object;
 object -> D.Phobos.Object;
 outbuffer -> D.Phobos.OutBuffer;
 outofmemory -> D.Error.OutOfMemory;
 path -> D.Phobos.Path;
 qsort -> D.Internal.Sort;
 random -> D.Phobos.Random;
 regexp -> D.Phobos.RegExp;
 stdint -> D.Phobos.StandardTypes;
 stream -> D.Phobos.Stream;
 string -> D.Phobos.String;
 switch -> D.Internal.Switch; (again the name!)
 switcherr -> D.Exception.SwitchError;
 syserror -> D.Exception.SystemError;
 system -> D.Phobos.System;
 thread -> D.Phobos.Thread;
 time -> D.Phobos.Time;
 ti_* -> D.Internal.*;
 uri -> D.Phobos.URI;
 utf -> D.Phobos.UTF8;
 windows -> D.CRT.windows;
 c.stdio -> D.CRT.stdio;
 c.stdlib -> D.CRT.stdlib;
 gc.* -> D.Internal.GC.*;

 dig would be put in the "D.Dig" package.  I could use "D.Dig.Main" for
 what "import dig" does now.  Or some other prefix than D.  In any case,
 it's much clearer about what I'm referring to; when I type
 "string.tolower" it's ambiguous as to whether I'm referring to a module
 or an object, as I use it for both heavily.  XYZ.Phobos.String.tolower
 is completely unambiguous, and if it gets too much (module "string."'s
 used 43 times throughout dig, so that can happen) I can alias it to
 something more manageable.  And with full package names, I can alias
 more selectively - "private alias XYZ.Phobos P;" would allow me to use
 "P.String.tolower", which can often be enough.

Jun 22 2003
parent "Matthew Wilson" <matthew stlsoft.org> writes:
Agree with a lot of this.

Can I suggest that there's a panel (perhaps of just one compiler walter)
that exercises control over the namespaces, at least as far as the ones that
go into Phobos, so that we don't get inconsistent, or ridiculously large,
standard libraries.

IMO, one of the strongest features of C/C++ is that they've jealously
guarded the small sizes of their libraries.

If there's a good, succinct, standard library with rigorous procedures to
forefend bloat, and there are good mechanisms for allow robust intermixing
of third-party libraries, then we'll all be happy.


"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:bd4s6r$1jiq$1 digitaldaemon.com...
 Windows should go into D.Platform.windows or D.SDK.windows;  it is most
 certainly not standard C runtime library material.  Same with Linux.

 I don't care if you use capital letters or not.  Personally I like
 MixedCase, but it really doesn't matter to me.

 I do like the idea of moving all this stuff into the D module umbrella.
 Prevents many many clashes, prevents cluttering up the global namespace.

 gives people a clear idea of whether a module is 1st-party or 3rd-party.
 But then why would Dig go under D?  DigitalMars should reserve the entire
 D.* module namespace.  Library writers can make their own, such as
 BRadons.Dig.  ;)

 Why the "Internal" module group?  I'm kinda surprised that there are so

 low-level support libraries;  I'd expect more of this to be built in, or
 unnecessary.

 What's the difference between complex math and complex arithmetic?  Why

 they separate?  They're not even in the same branch... that's just wierd.

 I agree that Intrinsic should have aliases in Math.  I suggest that users
 should not have to care whether something is an intrinsic or not;  this is
 entirely a choice that should be left up to the compiler, possibly

 by some kind of speed vs. size switch.  It is an implementation detail and
 users shouldn't be forced to deal with it.

 Why is there D.Exception.* and D.Internal.Exception?

 Rename Conv to Convert.  Saving 3 characters is not worth it.  Or maybe
 Conversion.

 Sean

 "Burton Radons" <loth users.sourceforge.net> wrote in message
 news:bd1r3s$1s87$1 digitaldaemon.com...
 Yeah, don't use too-short module names, and don't put kludges into a
 language solving a problem that shouldn't exist if the language were
 being correctly used.

 I think there's two mistakes going on here.  First, we should be
 applying package organisation to Phobos and other libraries.  Second, we
 should be using capital letters in module names when appropriate.
 Intuitively, lowercase feels better.  But in practice, it results in
 ugly names, lots of collisions, and seems to result in more curious
 acronyms and cut words than capitalised (java.rmi.dgc, for example).
 One naming scheme could be like this:

 aaA -> D.Internal.AArray;
 achar -> D.Internal.AChar;
 adi -> D.Internal.Array;
 alloca -> D.Internal.alloca;
 array -> D.Exception.ArrayBoundsError;
 arraycast -> D.Internal.ArrayCast;
 arraycat -> D.Internal.ArrayCat;
 assert -> D.Exception.AssertError; (It's not even a valid module name
 for goodness' sake!)
 cast -> D.Internal.Cast; (Ditto!)
 cmath -> D.System.ComplexMath;
 cmath2 -> D.Internal.ComplexArithmetic;
 com -> D.Phobos.COM;
 compiler -> D.Phobos.Compiler;
 conv -> D.Phobos.Conv;
 crc32 -> D.Phobos.CRC32;
 ctype -> D.Phobos.CharType;
 date -> D.Phobos.Date;
 dateparse -> D.Phobos.DateParse;
 deh2 -> D.Internal.ExceptionHandling;
 dmain2 -> D.Internal.Main;
 file -> D.Phobos.File;
 gc -> D.Phobos.GC;
 gcstats (merge with gc)
 intrinsic -> D.Internal.Intrinsic; (put aliases in D.Phobos.Math)
 invariant -> D.Internal.Invariant;
 iunknown -> D.Phobos.IUnknown;
 linux -> D.CRT.Linux;
 linuxextern -> D.CRT.LinuxExtern;
 llmath -> D.Internal.LongArithmetic;
 math -> D.Phobos.Math;
 math2 (merge with D.Phobos.Math)
 memset -> D.Internal.memset;
 moduleinit -> D.Internal.ModuleInit;
 obj -> D.Internal.Object;
 object -> D.Phobos.Object;
 outbuffer -> D.Phobos.OutBuffer;
 outofmemory -> D.Error.OutOfMemory;
 path -> D.Phobos.Path;
 qsort -> D.Internal.Sort;
 random -> D.Phobos.Random;
 regexp -> D.Phobos.RegExp;
 stdint -> D.Phobos.StandardTypes;
 stream -> D.Phobos.Stream;
 string -> D.Phobos.String;
 switch -> D.Internal.Switch; (again the name!)
 switcherr -> D.Exception.SwitchError;
 syserror -> D.Exception.SystemError;
 system -> D.Phobos.System;
 thread -> D.Phobos.Thread;
 time -> D.Phobos.Time;
 ti_* -> D.Internal.*;
 uri -> D.Phobos.URI;
 utf -> D.Phobos.UTF8;
 windows -> D.CRT.windows;
 c.stdio -> D.CRT.stdio;
 c.stdlib -> D.CRT.stdlib;
 gc.* -> D.Internal.GC.*;

 dig would be put in the "D.Dig" package.  I could use "D.Dig.Main" for
 what "import dig" does now.  Or some other prefix than D.  In any case,
 it's much clearer about what I'm referring to; when I type
 "string.tolower" it's ambiguous as to whether I'm referring to a module
 or an object, as I use it for both heavily.  XYZ.Phobos.String.tolower
 is completely unambiguous, and if it gets too much (module "string."'s
 used 43 times throughout dig, so that can happen) I can alias it to
 something more manageable.  And with full package names, I can alias
 more selectively - "private alias XYZ.Phobos P;" would allow me to use
 "P.String.tolower", which can often be enough.


Jul 08 2003
prev sibling next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
 I think there's two mistakes going on here.  First, we should be
 applying package organisation to Phobos and other libraries.  Second, we
 should be using capital letters in module names when appropriate.
 Intuitively, lowercase feels better.

Agree with this ...
 Yeah, don't use too-short module names, and don't put kludges into a
 language solving a problem that shouldn't exist if the language were
 being correctly used.

.. but not with this. For a new language, that purports to address the problems of previous ones, to rely on basic functions (such as name resolution) working only if people use some ephemeral, collegial, custom, is patently absurd. There needs to be a proper solution. Maybe increasing orthogonality in operator use would be a start ...
Jul 08 2003
prev sibling parent "Walter" <walter digitalmars.com> writes:
Yes, something like this should be done. I hope to get to it soon. -Walter

"Burton Radons" <loth users.sourceforge.net> wrote in message
news:bd1r3s$1s87$1 digitaldaemon.com...
 Walter wrote:
 "Mark T" <Mark_member pathlink.com> wrote in message
 news:bc9r3j$1bpm$1 digitaldaemon.com...

In article <bc3343$1dgn$1 digitaldaemon.com>, Walter says...

In the next version, I've added a module scope operator, ., which




resolve this problem properly, as in:
.c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to avoid

this ?? No.
I thought the whole idea was to be cleaner than C++.

If there's a better way to resolve that problem, I want to know about


 Yeah, don't use too-short module names, and don't put kludges into a
 language solving a problem that shouldn't exist if the language were
 being correctly used.

 I think there's two mistakes going on here.  First, we should be
 applying package organisation to Phobos and other libraries.  Second, we
 should be using capital letters in module names when appropriate.
 Intuitively, lowercase feels better.  But in practice, it results in
 ugly names, lots of collisions, and seems to result in more curious
 acronyms and cut words than capitalised (java.rmi.dgc, for example).
 One naming scheme could be like this:

 aaA -> D.Internal.AArray;
 achar -> D.Internal.AChar;
 adi -> D.Internal.Array;
 alloca -> D.Internal.alloca;
 array -> D.Exception.ArrayBoundsError;
 arraycast -> D.Internal.ArrayCast;
 arraycat -> D.Internal.ArrayCat;
 assert -> D.Exception.AssertError; (It's not even a valid module name
 for goodness' sake!)
 cast -> D.Internal.Cast; (Ditto!)
 cmath -> D.System.ComplexMath;
 cmath2 -> D.Internal.ComplexArithmetic;
 com -> D.Phobos.COM;
 compiler -> D.Phobos.Compiler;
 conv -> D.Phobos.Conv;
 crc32 -> D.Phobos.CRC32;
 ctype -> D.Phobos.CharType;
 date -> D.Phobos.Date;
 dateparse -> D.Phobos.DateParse;
 deh2 -> D.Internal.ExceptionHandling;
 dmain2 -> D.Internal.Main;
 file -> D.Phobos.File;
 gc -> D.Phobos.GC;
 gcstats (merge with gc)
 intrinsic -> D.Internal.Intrinsic; (put aliases in D.Phobos.Math)
 invariant -> D.Internal.Invariant;
 iunknown -> D.Phobos.IUnknown;
 linux -> D.CRT.Linux;
 linuxextern -> D.CRT.LinuxExtern;
 llmath -> D.Internal.LongArithmetic;
 math -> D.Phobos.Math;
 math2 (merge with D.Phobos.Math)
 memset -> D.Internal.memset;
 moduleinit -> D.Internal.ModuleInit;
 obj -> D.Internal.Object;
 object -> D.Phobos.Object;
 outbuffer -> D.Phobos.OutBuffer;
 outofmemory -> D.Error.OutOfMemory;
 path -> D.Phobos.Path;
 qsort -> D.Internal.Sort;
 random -> D.Phobos.Random;
 regexp -> D.Phobos.RegExp;
 stdint -> D.Phobos.StandardTypes;
 stream -> D.Phobos.Stream;
 string -> D.Phobos.String;
 switch -> D.Internal.Switch; (again the name!)
 switcherr -> D.Exception.SwitchError;
 syserror -> D.Exception.SystemError;
 system -> D.Phobos.System;
 thread -> D.Phobos.Thread;
 time -> D.Phobos.Time;
 ti_* -> D.Internal.*;
 uri -> D.Phobos.URI;
 utf -> D.Phobos.UTF8;
 windows -> D.CRT.windows;
 c.stdio -> D.CRT.stdio;
 c.stdlib -> D.CRT.stdlib;
 gc.* -> D.Internal.GC.*;

 dig would be put in the "D.Dig" package.  I could use "D.Dig.Main" for
 what "import dig" does now.  Or some other prefix than D.  In any case,
 it's much clearer about what I'm referring to; when I type
 "string.tolower" it's ambiguous as to whether I'm referring to a module
 or an object, as I use it for both heavily.  XYZ.Phobos.String.tolower
 is completely unambiguous, and if it gets too much (module "string."'s
 used 43 times throughout dig, so that can happen) I can alias it to
 something more manageable.  And with full package names, I can alias
 more selectively - "private alias XYZ.Phobos P;" would allow me to use
 "P.String.tolower", which can often be enough.

Aug 05 2003
prev sibling parent C <cc.news gateway.mirlex.com> writes:
Mark T wrote:
 In article <bc3343$1dgn$1 digitaldaemon.com>, Walter says...
 
In the next version, I've added a module scope operator, ., which should
resolve this problem properly, as in:

.c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

It works analogously to the C++ global scope operator ::.

IMHO this looks really ugly, doesn't "import" give enough info to avoid this ?? I thought the whole idea was to be cleaner than C++.

You have a point. How about... module.c.stdio.fgets(&buf[0],buf.size,module.c.stdio.stdin); By reusing the 'module' keyword to resolve the collision you would also make it absolutly clear what is happening. (The module keyword, as it is only used once in a file written under the current D specifications should parse easily in this situation.) Having to resolve a collision would be a fairly rare occurance with well chosen module names so having to type 'module.' before the resolution should not be required often. Comments on this proposal anyone? C 2003/6/13
Jun 13 2003
prev sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
Is there _any_ chance of having a .. module scope operator. One of the
things I've always wanted in C++ is to be able to say "one namespace above".
Hence

int x;

namespace L1
{
    int x;

    namespace L2
    {
          int     x;

        x = 0; // Does (in C++ speak) L1::L2::x
        .x = 0; // Does (in C++ speak) ::x
        ..x = 0; // Does (in C++ speak) L1::x
    }
}


Having looked at that, though, I'd actually like . to mean "this namespace",
so how would we get to the root?

What about

 /x is the x in the global namespace
 ./x is the x in the current namespace
 ../x is the x in the enclosing namespace
 x is whatever is determined as happens now in unadorned C++/D

You may wonder why this would be good. In a word, templates.

You may want an example demonstrating the utility. Alas, I can't think of
one atm, but it's definitely something I've wanted many times in C++


"Walter" <walter digitalmars.com> wrote in message
news:bc3343$1dgn$1 digitaldaemon.com...
 In the next version, I've added a module scope operator, ., which should
 resolve this problem properly, as in:

 .c.stdio.fgets(&buf[0],buf.size,.c.stdio.stdin);

 It works analogously to the C++ global scope operator ::.


 "Helmut Leitner" <helmut.leitner chello.at> wrote in message
 news:3EE2FA45.29B11971 chello.at...
 Currently code like

    import c.stdio;
    ...
    char c;
    char buf[256];
    c.stdio.fgets(&buf[0],buf.size,c.stdio.stdin);
    c=buf[0];

 won't compile because of an

    no property 'stdio' for type 'char'

 error.

 Could this be changed, so that the compiler checks for an
 interpretation that makes sense if there a more than one?
 Otherwise any module in any library is a potential
 candidate for such collisions!

 --
 Helmut Leitner    leitner hls.via.at
 Graz, Austria   www.hls-software.com


Jul 08 2003