Re: Specifying C++ symbols in C++ namespaces

2014-04-07 Thread Adam Wilson
On Sat, 05 Apr 2014 13:47:32 -0700, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/2/2014 3:07 PM, Walter Bright wrote:
One downside of this proposal is that if we ever (perish the thought!)  
attempted

to interface to C++ templates, this design would preclude that.


Yes, this seems to be a fatal flaw. Another design that has evolved from  
these discussions and my discussions with Andrei on it:


 extern (C++, namespace = A.B) { void foo(); void bar(); }
 extern (C++, namespace = C) void foo();

 bar();  // works
 A.B.bar(); // works
 foo(); // error: ambiguous
 C.foo();   // works

 alias C.foo foo;
 foo();  // works, calling C.foo()

I really think the namespace semantics should be attached to the  
extern(C++) rather than be a separate pragma. Having the namespace=  
thing means that namespace isn't a keyword, and provides a general  
mechanism where we can add language specific information as necessary.


This seems like a reasonable way to interop with C++ namespace in a D way.  
I also think that it is something that we should do ASAP. I know that for  
Aurora, I will not be able to add complete DirectX support until the C++  
namespace interop problem is solved. Specifically because the highly  
optimized DirectXMath functions are inside a namespace. I do not consider  
pre-mangling a solution, it's a hack for something that is quite common in  
C++, and it's fragile.


--
Adam Wilson
GitHub/IRC: LightBender
Aurora Project Coordinator


Re: Specifying C++ symbols in C++ namespaces

2014-04-07 Thread Ola Fosheim Grøstad

On Monday, 7 April 2014 at 01:35:37 UTC, Michel Fortin wrote:
Modules are already in use on OS X for some system frameworks. 
It can result in slightly improved compile times. It has been 
enabled by default for new Xcode projects for some time.


Thanks for sharing, I wasn't aware of that. That means that clang 
will make this a priority. But I guess clang is a long way from 
not having end users write their own header files still.


Re: Specifying C++ symbols in C++ namespaces

2014-04-07 Thread Paulo Pinto
On Monday, 7 April 2014 at 08:06:11 UTC, Ola Fosheim Grøstad 
wrote:

On Monday, 7 April 2014 at 01:35:37 UTC, Michel Fortin wrote:
Modules are already in use on OS X for some system frameworks. 
It can result in slightly improved compile times. It has been 
enabled by default for new Xcode projects for some time.


Thanks for sharing, I wasn't aware of that. That means that 
clang will make this a priority. But I guess clang is a long 
way from not having end users write their own header files 
still.


clang developers are the ones driving the ISO C++ Modules working 
group, so whatever clang does, it will eventually be the standard.


--
Paulo


Re: Specifying C++ symbols in C++ namespaces

2014-04-07 Thread Dejan Lekic

On Saturday, 5 April 2014 at 20:47:29 UTC, Walter Bright wrote:

On 4/2/2014 3:07 PM, Walter Bright wrote:
One downside of this proposal is that if we ever (perish the 
thought!) attempted

to interface to C++ templates, this design would preclude that.


Yes, this seems to be a fatal flaw. Another design that has 
evolved from these discussions and my discussions with Andrei 
on it:


extern (C++, namespace = A.B) { void foo(); void bar(); }
extern (C++, namespace = C) void foo();

bar();  // works
A.B.bar(); // works
foo(); // error: ambiguous
C.foo();   // works

alias C.foo foo;
foo();  // works, calling C.foo()

I really think the namespace semantics should be attached to 
the extern(C++) rather than be a separate pragma. Having the 
namespace= thing means that namespace isn't a keyword, and 
provides a general mechanism where we can add language specific 
information as necessary.


I actually like this idea the most. It is clean, and easy to 
understand.


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Walter Bright

On 4/6/2014 2:56 AM, Marc Schütz schue...@gmx.net wrote:

And wouldn't it clash with D's std package?


Yes. But D has numerous methods of disambiguation.


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Ola Fosheim Grøstad

On Saturday, 5 April 2014 at 23:26:30 UTC, Walter Bright wrote:

I feel that C++ messed up namespace design because:

1. namespaces are not closed
2. they have no relationship with modules


Namespaces are not as powerful as they could have been, but being 
able to add symbols to an external scope (like classes) is very 
useful if done right (e.g. cross-cutting enhancements, adding 
members to external classes like saveyourself, printyourself).


which has wound up forcing the addition of Yet Another Design 
when imports and modules are added to C++.


Unfortunately that seems to be years into the future? Although 
clang has begun implementing something:


http://clang.llvm.org/docs/Modules.html

I've got at feeling that if clang gets something working it will 
become a de-facto standard due to demand.


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Walter Bright
On 4/6/2014 12:39 PM, Ola Fosheim Grøstad 
ola.fosheim.grostad+dl...@gmail.com wrote:

On Saturday, 5 April 2014 at 23:26:30 UTC, Walter Bright wrote:

I feel that C++ messed up namespace design because:

1. namespaces are not closed
2. they have no relationship with modules


Namespaces are not as powerful as they could have been, but being able to add
symbols to an external scope (like classes) is very useful if done right (e.g.
cross-cutting enhancements, adding members to external classes like
saveyourself, printyourself).


It's seriously wrong to allow such. It makes a larger code base nearly 
impossible to reliably reason about, leading one to rely on conventions like 
don't add stuff to namespaces.


D has closed scopes, and members can be added to external classes just fine, 
using CTFE.


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Ola Fosheim Grøstad

On Sunday, 6 April 2014 at 20:17:09 UTC, Walter Bright wrote:
It's seriously wrong to allow such. It makes a larger code base 
nearly impossible to reliably reason about, leading one to rely 
on conventions like don't add stuff to namespaces.


Depends on how it is done. For BETA, there was a seperate 
fragment system that allowed AST specified extension points. 
This system was used for both extensions and for 
encapsulation/API definition. You basically defined slots in 
the syntax three where code could be injected (following the 
grammar of the slot) and what should be hidden etc. It was 
simplistic elegance IMO:


http://www.cs.au.dk/~beta/Manuals/latest/beta/fragment.html

The weakness was that they didn't allow for dynamic dispatch 
(required static resolution), but that was an implementation 
issue, I think.


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Ola Fosheim Grøstad
Btw, cross-cutting programming is indeed meant to cater for 
programming in the large:


http://en.wikipedia.org/wiki/Aspect-oriented_programming


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread monarch_dodra

On Sunday, 6 April 2014 at 20:17:09 UTC, Walter Bright wrote:
D has closed scopes, and members can be added to external 
classes just fine, using CTFE.


You mean UFCS? As in, for example, front for arrays? It doesn't 
work as well as advertised though. The issue is that the added 
members are only visible if the *called* code knows to import the 
*caller* code. This breaks as soon as you leave your own internal 
ecosystem.


//
import a;

struct S //Some object
{
}

//Extend to make it a range.
bool empty(S);
int front(S);
void popFront(S);

//Try it.
void main()
{
S s;
foreach(e; s) //Error: invalid foreach aggregate s
writeln(s);
s.array(); //Error: template std.range.take cannot...
a.foo(s); //Error: no property 'popFront' for type 'S'
}
//
module a;

void foo(T)(T t)
{
t.popFront();
}
//
Well that horribly fails.

Because when calling a template, you are only importing the 
passed argument, but not his ecosystem with it. The only way in D 
to really extend an existing object, is to wrap it into a new 
object. And even then, the wrapping is limited, because you can't 
orthogonally wrap (eg the wrapping linearly stacks, whereas UCFS 
*could* add two completely independent functionalities). Not to 
mention issues with code bloat...


C++'s namespaces have their flaws, but they *are* scalable in a 
way D's modules aren't, thanks to Koenig Lookup.


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Walter Bright

On 4/6/2014 2:00 PM, monarch_dodra wrote:

On Sunday, 6 April 2014 at 20:17:09 UTC, Walter Bright wrote:

D has closed scopes, and members can be added to external classes just fine,
using CTFE.


You mean UFCS?


Yes, my mistake.



As in, for example, front for arrays? It doesn't work as well
as advertised though. The issue is that the added members are only visible if
the *called* code knows to import the *caller* code.


That's a feature of a modular system, not a bug. D does not have a global name 
space, on purpose.



This breaks as soon as you
leave your own internal ecosystem.

//
import a;

struct S //Some object
{
}

//Extend to make it a range.
bool empty(S);
int front(S);
void popFront(S);

//Try it.
void main()
{
 S s;
 foreach(e; s) //Error: invalid foreach aggregate s
 writeln(s);
 s.array(); //Error: template std.range.take cannot...
 a.foo(s); //Error: no property 'popFront' for type 'S'
}
//
module a;

void foo(T)(T t)
{
 t.popFront();
}
//
Well that horribly fails.


That's based on a misunderstanding of how scoped lookup works in D, and how to 
use it properly. In the particular instance above, there is simply no reason to 
not put front() as a member of S, since they are in the same module.




Because when calling a template, you are only importing the passed argument, but
not his ecosystem with it. The only way in D to really extend an existing
object, is to wrap it into a new object. And even then, the wrapping is limited,
because you can't orthogonally wrap (eg the wrapping linearly stacks, whereas
UCFS *could* add two completely independent functionalities). Not to mention
issues with code bloat...


You're right in that if you try to do things the C++ way in D, things won't work 
out so well. D can do all these things, but they are done in a different way - a 
way that is much more robust.


The fault in the C++ method of extending namespaces is that two independently 
developed modules had better not extend the same namespace with the same names. 
You will not necessarily get a compiler error from violating this - code may 
just wind up calling the wrong overload. I.e. it does not scale.




C++'s namespaces have their flaws, but they *are* scalable in a way D's modules
aren't, thanks to Koenig Lookup.


I've never seen anyone defend Koenig lookup as anything but a hack before :-)


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Jacob Carlborg

On 2014-04-05 22:42, Walter Bright wrote:


2. C++ namespaces are very low hanging fruit, with a significant payoff.
It's worthwhile.


I think it's very low hanging fruit to add support for basic C++ 
namespaces. Support for basically just set the mangled name in a 
somewhat nice way, a pragma for example. If we're talking about adding 
something more advanced  like :: or extern (C++) template which my 
affect the current name look up rules then I don't think that's so low 
hanging fruit anymore.


--
/Jacob Carlborg


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Ola Fosheim Grøstad
I think it's very low hanging fruit to add support for basic 
C++ namespaces. Support for basically just set the mangled name 
in a somewhat nice way, a pragma for example.


I think it is more important to think in term of strategic 
positions than whether it takes 1 or 2 weeks to implement a 
feature.


Assumption:
It is desirable to make the eco system more attractive for 
commercial projects.


Key requirements:
- Long term stability of the dev environment.
- Access to mature libraries with significant backing (basically 
C/C++ libraries).
- Easy integration with existing technology and systems 
(basically C/C++).

- No lock-in (basically C/C++ interop).
- Predictable dev environment that enables precise cost estimates.
- Lowering costs/faster development than the alternatives (more 
convinient than C/C++)


If you cannot assume that you can utilize a C++ library from D or 
if you have to assume that using a C++ library might incur a 
significant interfacing overhead (in terms of programmer's time) 
then D looks like a more risky proposition.


The key difference between a commercial project and a hobby 
project is that the hobby project can fully adapt the 
requirements to the dev environment. A hobbyist game project can 
settle for a less capable physics engine or create a custom one, 
for fun. A commercial project will view that as costs that cut 
into profit margins and  a potential source of failure in the 
market. That's a good reason to go with C++ instead of D.


From a strategic point of view it is important to fully support 
those features you claim to support.


If you can claim that interfacing with C++, except for templates, 
is easy, then you communicate that it is relatively easy to 
assess project costs. If you only claim that it is possible to 
interface with some of C++, but that it is kind of difficult 
under certain  vaguely specified circumstances then I think you 
should wait until you have a better solution.


What you absolutely don't want is to trick people into thinking 
that interfacing with C++ is easy, if it isn't, and have them 
discover that they are better off dumping D and doing it all over 
in C++.


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Tove

On Sunday, 6 April 2014 at 02:33:38 UTC, Walter Bright wrote:

On 4/5/2014 6:26 PM, Michel Fortin wrote:

What if you also have a C++ foo at global scope?


It'll work exactly the same as import does.



module cpptest;

extern (C++) void foo();
extern (C++, namespace = A) void foo();

foo(); // ambiguous
A.foo(); // works
.foo(); // works?


Yes.


cpptest.foo(); // works?


Yes.


Does these two last lines make sense?


Just as much sense as:

module bar;
void foo();
.foo(); // works
bar.foo(); // works

Namespace lookup rules would be exactly the same as for imports 
and mixin templates.


My main reservation against the new suggestion is that one would 
be forced to open a new nested namespace even when it's 
detrimental, because in some cases the namespace structure is 
already reflected in the filesystem(just like for D:s module 
system).


I can't assess how widespread this is globally, but at least some 
high-quality projects already have guidelines to use 
file/namespace mappings.


A random example from boost:
boost::asio::ip::multicast
boost/asio/ip/multicast.hpp

One can of course workaround this issue with an extra alias for 
every imported symbol, or use compile-time reflection to 
auto-generate all alias statements... (or heaven forbid, put 
entire boost in one file ;))


I assume the namespace = xxx syntax is some sort of named 
parameter, would it be possible to add another similar param, 
which only changes mangling and doesn't actually create a new 
scope?


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Marc Schütz

On Saturday, 5 April 2014 at 21:43:03 UTC, Walter Bright wrote:

On 4/5/2014 2:31 PM, Tove wrote:

How could this common pattern look?
std::string
boost::fun(std::string arg)

alias cpp= extern (C++, namespace = std);
alias boost = extern (C++, namespace = boost);

cpp.string
boost.fun(cpp.string arg)

?


extern (C++, namespace = std) {
struct string { ... }
}

extern (C++, namespace = boost) {
void fun(std.string arg);
}


What would std be here from D's point of view? A module? Or a new 
kind of symbol?


And wouldn't it clash with D's std package?


Re: Specifying C++ symbols in C++ namespaces

2014-04-06 Thread Michel Fortin
On 2014-04-06 19:39:31 +, Ola Fosheim Grøstad 
ola.fosheim.grostad+dl...@gmail.com said:


Unfortunately that seems to be years into the future? Although clang 
has begun implementing something:


http://clang.llvm.org/docs/Modules.html

I've got at feeling that if clang gets something working it will become 
a de-facto standard due to demand.


Modules are already in use on OS X for some system frameworks. It can 
result in slightly improved compile times. It has been enabled by 
default for new Xcode projects for some time. With modules enabled, 
clang interpret #includes as module imports for system frameworks 
having a module map. It's so transparent you probably won't notice 
anything has changed.


The only thing that really changes with modules is you don't have 
access to symbols you don't have imported yourself. D already works 
like that. I think D can ignore those modules, just like it ignores 
header files.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Ola Fosheim Grøstad

On Friday, 4 April 2014 at 22:17:45 UTC, Dicebot wrote:
#2 should not compile. D currently does not have any notion of 
namespaces other than modules / aggregates and I am against 
introducing those just for the sake of interfacing with C++.


If you want to interface with C++ you should do it well or not at 
all. In C++ namespace names reside in their own namespace which 
means that you get short names like std, qt etc. Which in 
turn means you have to rename those to CPPstd, CPPqt etc in D 
in order to disambiguate the symbols. Having a dedicated 
namespace operator would be a lot more convenient.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Dicebot
On Saturday, 5 April 2014 at 08:42:27 UTC, Ola Fosheim Grøstad 
wrote:

On Friday, 4 April 2014 at 22:17:45 UTC, Dicebot wrote:
#2 should not compile. D currently does not have any notion of 
namespaces other than modules / aggregates and I am against 
introducing those just for the sake of interfacing with C++.


If you want to interface with C++ you should do it well or not 
at all. In C++ namespace names reside in their own namespace 
which means that you get short names like std, qt etc. 
Which in turn means you have to rename those to CPPstd, 
CPPqt etc in D in order to disambiguate the symbols. Having a 
dedicated namespace operator would be a lot more convenient.


D has own tools to disambugate symbols. Introducing new ones is 
equivalent to admitting D module system does not work by design.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Ola Fosheim Grøstad

On Saturday, 5 April 2014 at 12:07:36 UTC, Dicebot wrote:
D has own tools to disambugate symbols. Introducing new ones is 
equivalent to admitting D module system does not work by design.


I think it is primarily a notation issue. Should the notation 
help you discern what is C++ and what is D, or do you have to 
memorize symbols? How much extra notational work is it acceptable 
to impose on the programmer?


There are advantages and disadvantages to both approaches.

Pro explicit c++ namespaces:

- Easy to discern what is C++ and what is D.

- Less chance of future irreconcilable design conflicts when 
either C++ or D changes (e.g. C++18 and beyond)


- Having a philosophy of native foreign functions rather than 
masquerading as D constructs makes it easier to integrate with 
other languages beyond c/c++ at a later stage.


Con:

- More syntax to understand for newbies

- Requires a little bit more refactoring when moving C++ code to 
D.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Dicebot
On Saturday, 5 April 2014 at 12:30:28 UTC, Ola Fosheim Grøstad 
wrote:
Should the notation help you discern what is C++ and what is D, 
or do you have to memorize symbols? How much extra notational 
work is it acceptable to impose on the programmer?


It shouldn't. The fact how entity is exposed via some external 
binary interface should not have any notable impact on D side of 
things (unless you dwell into ABI realm). This is exactly what 
extern is for - matching symbols from domain of D terms to some 
external alien domain.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Ola Fosheim Grøstad

On Saturday, 5 April 2014 at 12:58:54 UTC, Dicebot wrote:
It shouldn't. The fact how entity is exposed via some external 
binary interface should not have any notable impact on D side 
of things (unless you dwell into ABI realm).


This is a design philosophical issue, you can make it normative 
if you want, but only if it is consistent with the overall design 
philosophy.


Working on making that philosophy explicit is important, D2 is 
showing some signs of having gone through a lot of evolutionary 
design and IMHO signs of a need for notational redesign. Meaning: 
recreate the syntax to fit the desired semantics that the 
language has obtained over time (as in designing it, not 
evolving).


Not distinguishing between C++/D does however have consequences: 
if foreign constructs have the same appearance as the language 
constructs then you should also make sure that all the semantics 
are the same. E.g. C++ exceptions, calls to C++ new etc have to 
be fully harmonized with D equivalents.




Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Timon Gehr

On 04/03/2014 09:55 PM, Andrei Alexandrescu wrote:

...
Anyhow de gustibus.



There's good and bad taste.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Ola Fosheim Grøstad
Not that I ever do this, but I think you need to deal with this 
C++ construct:


namespace exposed_ns {
  using namespace internal_ns_2134zxdssdffrandomblablah;
  using namespace internal_ns_2634zasdsfsdrandomblablah;
  using namespace internal_ns_2993adsfadsfrandomblablah;
}

To do this in D you would have to be able to set up a search 
sequence as an alias somehow.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Dicebot
On Saturday, 5 April 2014 at 13:11:27 UTC, Ola Fosheim Grøstad 
wrote:

On Saturday, 5 April 2014 at 12:58:54 UTC, Dicebot wrote:
It shouldn't. The fact how entity is exposed via some external 
binary interface should not have any notable impact on D side 
of things (unless you dwell into ABI realm).


This is a design philosophical issue, you can make it normative 
if you want, but only if it is consistent with the overall 
design philosophy.


This is very practical thing. By introducing special constructs 
to support some foreign language you open the can of worms. Where 
does one stop? Should we also expect adding some new idioms for 
better JNI support? Or Python? I can't see any reason why C++ has 
to be any special and you can't nicely support them all. We don't 
even truly do this for C and this the only real ABI standard.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Ola Fosheim Grøstad

On Saturday, 5 April 2014 at 15:24:32 UTC, Dicebot wrote:
This is very practical thing. By introducing special constructs 
to support some foreign language you open the can of worms.


Yep, but I believe C++ is increasingly going to replace C as a 
language for writing basic libraries and engines in the next few 
decades. Which isn't great for interop, but a trend still.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Mason McGill

On Saturday, 5 April 2014 at 15:24:32 UTC, Dicebot wrote:
This is very practical thing. By introducing special constructs 
to support some foreign language you open the can of worms. 
Where does one stop? Should we also expect adding some new 
idioms for better JNI support? Or Python? I can't see any 
reason why C++ has to be any special and you can't nicely 
support them all. We don't even truly do this for C and this 
the only real ABI standard.


Another way to put this is that D is its own language, not a C++ 
extension.  IMO, an FFI should make interoperability possible via 
ABI matching, but it should not compromise the language (by 
making its scoping rules more complicated, introducing redundant 
constructs, or introducing a new token (::) that could be used 
for another feature).


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Walter Bright

On 4/5/2014 8:24 AM, Dicebot wrote:

This is very practical thing. By introducing special constructs to support some
foreign language you open the can of worms. Where does one stop? Should we also
expect adding some new idioms for better JNI support? Or Python? I can't see any
reason why C++ has to be any special and you can't nicely support them all. We
don't even truly do this for C and this the only real ABI standard.


A very good question. Some points to consider:

1. D is supposed to be a practical language, and be designed to get s**t done.

2. D has long recognized that C++ exists and tries to be accommodating - with 
extern(C++) and C++ compatible COM classes. extern(C++) already does more than 
just adjust the name mangling.


3. There's significant demand for supporting C++ namespaces among people trying 
to migrate to D. There's more than just the people who post here. Currently, 
this is a barrier to adoption of D, and an unnecessary one.


4. I know I very much appreciate products that don't try and pretend they are 
the shiznit and nothing else exists. For example, Thunderbird Mail was able to 
import my old Outlook Express database perfectly, enabling me to completely 
abandon OE.


5. There's also work underway to better integrate with ObjectiveC.

In the light of that:

1. We cannot nicely support them all. But we don't have to. We can support the 
low hanging fruit.


2. C++ namespaces are very low hanging fruit, with a significant payoff. It's 
worthwhile.


3. C++ is special because a) we can support limited interoperability without 
much effort and b) a lot of people come to D from C++ and want to interoperate.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Walter Bright

On 4/2/2014 3:07 PM, Walter Bright wrote:

One downside of this proposal is that if we ever (perish the thought!) attempted
to interface to C++ templates, this design would preclude that.


Yes, this seems to be a fatal flaw. Another design that has evolved from these 
discussions and my discussions with Andrei on it:


extern (C++, namespace = A.B) { void foo(); void bar(); }
extern (C++, namespace = C) void foo();

bar();  // works
A.B.bar(); // works
foo(); // error: ambiguous
C.foo();   // works

alias C.foo foo;
foo();  // works, calling C.foo()

I really think the namespace semantics should be attached to the extern(C++) 
rather than be a separate pragma. Having the namespace= thing means that 
namespace isn't a keyword, and provides a general mechanism where we can add 
language specific information as necessary.


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Tove

On Saturday, 5 April 2014 at 20:47:29 UTC, Walter Bright wrote:

On 4/2/2014 3:07 PM, Walter Bright wrote:
One downside of this proposal is that if we ever (perish the 
thought!) attempted

to interface to C++ templates, this design would preclude that.


Yes, this seems to be a fatal flaw. Another design that has 
evolved from these discussions and my discussions with Andrei 
on it:


extern (C++, namespace = A.B) { void foo(); void bar(); }
extern (C++, namespace = C) void foo();

bar();  // works
A.B.bar(); // works
foo(); // error: ambiguous
C.foo();   // works

alias C.foo foo;
foo();  // works, calling C.foo()

I really think the namespace semantics should be attached to 
the extern(C++) rather than be a separate pragma. Having the 
namespace= thing means that namespace isn't a keyword, and 
provides a general mechanism where we can add language specific 
information as necessary.


How could this common pattern look?
std::string
boost::fun(std::string arg)

alias cpp= extern (C++, namespace = std);
alias boost = extern (C++, namespace = boost);

cpp.string
boost.fun(cpp.string arg)

?


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Walter Bright

On 4/5/2014 2:31 PM, Tove wrote:

How could this common pattern look?
std::string
boost::fun(std::string arg)

alias cpp= extern (C++, namespace = std);
alias boost = extern (C++, namespace = boost);

cpp.string
boost.fun(cpp.string arg)

?


extern (C++, namespace = std) {
struct string { ... }
}

extern (C++, namespace = boost) {
void fun(std.string arg);
}


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Michel Fortin

On 2014-04-05 20:47:32 +, Walter Bright newshou...@digitalmars.com said:


On 4/2/2014 3:07 PM, Walter Bright wrote:
One downside of this proposal is that if we ever (perish the thought!) 
attempted

to interface to C++ templates, this design would preclude that.


Yes, this seems to be a fatal flaw. Another design that has evolved 
from these discussions and my discussions with Andrei on it:


 extern (C++, namespace = A.B) { void foo(); void bar(); }
 extern (C++, namespace = C) void foo();

 bar();  // works
 A.B.bar(); // works
 foo(); // error: ambiguous
 C.foo();   // works

 alias C.foo foo;
 foo();  // works, calling C.foo()

I really think the namespace semantics should be attached to the 
extern(C++) rather than be a separate pragma. Having the namespace= 
thing means that namespace isn't a keyword, and provides a general 
mechanism where we can add language specific information as necessary.


I like this idea. But... should this potentially useful thing really be 
restricted to extern C++ things? I've seen at least one attempt to 
create a namespace using what D currently offers [1], and frankly 
something like the above would make much more sense than a class no one 
can instantiate.


[1]: http://dlang.org/phobos/std_datetime.html#.Clock

Here's a suggestion:

@namespace A.B { // can create two levels at once, yeah!
void foo();
void bar();
}
@namespace C {
void foo();
}

Make those C++ declarations, it does not look too foreign anymore:

extern (C++) @namespace A.B {
void foo();
void bar();
}
extern (C++) @namespace C {
void foo();
}

--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Walter Bright

On 4/5/2014 2:55 PM, Michel Fortin wrote:

I like this idea. But... should this potentially useful thing really be
restricted to extern C++ things? I've seen at least one attempt to create a
namespace using what D currently offers [1], and frankly something like the
above would make much more sense than a class no one can instantiate.


I can't escape the feeling that if you're trying to do namespaces in D, you're 
doing something worng.


I feel that C++ messed up namespace design because:

1. namespaces are not closed
2. they have no relationship with modules

which has wound up forcing the addition of Yet Another Design when imports and 
modules are added to C++.




Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread bearophile

Michel Fortin:


Here's a suggestion:

@namespace A.B { // can create two levels at once, yeah!
void foo();
void bar();
}
@namespace C {
void foo();
}

Make those C++ declarations, it does not look too foreign 
anymore:


extern (C++) @namespace A.B {
void foo();
void bar();
}
extern (C++) @namespace C {
void foo();
}


I suggest to keep the access to C++ namespaces as a feature for 
interoperability only, and to have no namespaces in D.


Bye,
bearophile


Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Michel Fortin

On 2014-04-05 20:47:32 +, Walter Bright newshou...@digitalmars.com said:

Yes, this seems to be a fatal flaw. Another design that has evolved 
from these discussions and my discussions with Andrei on it:


 extern (C++, namespace = A.B) { void foo(); void bar(); }
 extern (C++, namespace = C) void foo();

 bar();  // works
 A.B.bar(); // works
 foo(); // error: ambiguous
 C.foo();   // works

 alias C.foo foo;
 foo();  // works, calling C.foo()


What if you also have a C++ foo at global scope?

module cpptest;

extern (C++) void foo();
extern (C++, namespace = A) void foo();

foo(); // ambiguous
A.foo(); // works
.foo(); // works?
cpptest.foo(); // works?

Does these two last lines make sense?


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: Specifying C++ symbols in C++ namespaces

2014-04-05 Thread Walter Bright

On 4/5/2014 6:26 PM, Michel Fortin wrote:

What if you also have a C++ foo at global scope?


It'll work exactly the same as import does.



 module cpptest;

 extern (C++) void foo();
 extern (C++, namespace = A) void foo();

 foo(); // ambiguous
 A.foo(); // works
 .foo(); // works?


Yes.


 cpptest.foo(); // works?


Yes.


Does these two last lines make sense?


Just as much sense as:

module bar;
void foo();
.foo(); // works
bar.foo(); // works

Namespace lookup rules would be exactly the same as for imports and mixin 
templates.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Mason McGill
Walter Bright  wrote in message 
news:lhi1lt$269h$1...@digitalmars.com...

Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}

This seems misleading to readers of future code.
- An extern (C++) function lets you use a C++ function.
- An extern (C++) interface lets you use a C++ interface 
(declared as a class, as is always the case in C++).

- An extern (C++) template lets you use a C++... namespace?

On Thursday, 3 April 2014 at 11:19:53 UTC, Daniel Murphy wrote:

Why not just

pragma(cpp_namespace, outer)
{
   pragma(cpp_namespace, inner)
   {
   extern(C++) void func();
   }
}
This really has only one obvious interpretation (the correct 
one), and seems to be a rather harmless addition to the language.


It also fulfills the goal of allowing access to C++ libraries 
without cluttering D with C++ language features.  I don't want to 
have to explain to my students the difference between modules 
D templates and C++ namespace templates (it reminds me of 
old- and new-style classes in Python 2).


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Walter Bright

On 4/3/2014 5:47 PM, deadalnix wrote:

I'm not familiar with usual C++ mangling as much as D. Are
template and namespace mangled the same way ?


No.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Dicebot

Late to the thread, my short opinion:

extern(C++ namespace::path) looks best. It should only affect 
mangling and have no impact on fully qualified name on D side. 
Most KISS solution I have read in the thread.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread David Gileadi

On 4/3/14, 11:59 PM, Mason McGill wrote:

Walter Bright  wrote in message news:lhi1lt$269h$1...@digitalmars.com...

Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}

This seems misleading to readers of future code.
- An extern (C++) function lets you use a C++ function.
- An extern (C++) interface lets you use a C++ interface (declared as
a class, as is always the case in C++).
- An extern (C++) template lets you use a C++... namespace?

On Thursday, 3 April 2014 at 11:19:53 UTC, Daniel Murphy wrote:

Why not just

pragma(cpp_namespace, outer)
{
   pragma(cpp_namespace, inner)
   {
   extern(C++) void func();
   }
}

This really has only one obvious interpretation (the correct one), and
seems to be a rather harmless addition to the language.

It also fulfills the goal of allowing access to C++ libraries without
cluttering D with C++ language features.  I don't want to have to
explain to my students the difference between modules D templates
and C++ namespace templates (it reminds me of old- and new-style
classes in Python 2).


The above well describes my first reaction to the syntax (except the 
part about having students). And my second reaction too, in fact.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Mason McGill

On Friday, 4 April 2014 at 12:34:15 UTC, Dicebot wrote:

Late to the thread, my short opinion:

extern(C++ namespace::path) looks best. It should only affect 
mangling and have no impact on fully qualified name on D side. 
Most KISS solution I have read in the thread.


I actually remember almost trying this syntax before reading this 
thread.  It's definitely intuitive, and it KIS.  Though, may I 
suggest


extern(C++, namespace::path) or
extern(C++, namespace, path)

keeping in line with __traits and pragma?


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Simen Kjærås

On 03.04.2014 00:07, Walter Bright wrote:

Here's Andrei's proposal:

 extern (C++) template nspace() {
 int foo();
 }

It would be accessed in D by:

nspace!().foo();

A possible enhancement would be to allow (for all templates with no parameters):

 nspace.foo();

Note that:

 template nspace() {
 extern (C++) int foo();
 }

would not put foo() in a C++ namespace, although it would still be accessed from
D as:

 nspace.foo();

One downside of this proposal is that if we ever (perish the thought!) attempted
to interface to C++ templates, this design would preclude that.


I have to say I like Robert Clipsham's idea best:

extern(C++) module nspace {
int foo(); // Is this also extern(C++)? I think it should be.
}

extern(C++) module nspace {
module innernspace {
int bar(); // Also extern(C++), if we follow the example above.
}
}

I haven't the foggiest idea how C++ modules are supposed to work, so there might 
be clashes with those somehow?


--
  Simen


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Dicebot

On Friday, 4 April 2014 at 18:51:21 UTC, Simen Kjærås wrote:

I have to say I like Robert Clipsham's idea best:

extern(C++) module nspace {
int foo(); // Is this also extern(C++)? I think it should 
be.

}

extern(C++) module nspace {
module innernspace {
int bar(); // Also extern(C++), if we follow the 
example above.

}
}


All solutions based on binding extern(C++) to some D 
qualification entity are bad because they confuse reader into 
thinking that `bar` is actually `nspace.innerspace.bar` and that 
should never happen.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Simen Kjærås

On 04.04.2014 20:54, Dicebot wrote:

On Friday, 4 April 2014 at 18:51:21 UTC, Simen Kjærås wrote:

I have to say I like Robert Clipsham's idea best:

extern(C++) module nspace {
int foo(); // Is this also extern(C++)? I think it should be.
}

extern(C++) module nspace {
module innernspace {
int bar(); // Also extern(C++), if we follow the example above.
}
}


All solutions based on binding extern(C++) to some D qualification entity are
bad because they confuse reader into thinking that `bar` is actually
`nspace.innerspace.bar` and that should never happen.


I'm not entirely sure I follow you here. Is this what you mean?

extern(C++) module nspace {
int foo();
}

void main() {
foo();// Either this does not work, (#1)
nspace.foo(); // or this does not work. (#2)
}

If so, is that really bad? I'd say the better choice is to make #2 work, as then 
#1 can be made to work with a simple alias:


alias foo = nspace.foo;

If I'm far off into the fields of ignorance now, care to show me the way to a 
better understanding?


--
  Simen


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Walter Bright

On 4/4/2014 5:34 AM, Dicebot wrote:

Late to the thread, my short opinion:

extern(C++ namespace::path) looks best. It should only affect mangling and have
no impact on fully qualified name on D side. Most KISS solution I have read in
the thread.


Fails because:

C++:

namespace S { namespace T {
int foo();
namespace U {
int foo();
}
 } }

D:

  extern (C++, S::T) {
  int foo();
  extern (C++, U) {
int foo();
  }
  }
  foo();  // error, ambiguous, which one?
  S.T.foo(); // S undefined




Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Ola Fosheim Grøstad

On Friday, 4 April 2014 at 19:43:56 UTC, Walter Bright wrote:

  foo();  // error, ambiguous, which one?
  S.T.foo(); // S undefined


I want explicit namespaces S::T::foo().


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Walter Bright
On 4/4/2014 1:00 PM, Ola Fosheim Grøstad 
ola.fosheim.grostad+dl...@gmail.com wrote:

I want explicit namespaces S::T::foo().


We already have a scope operator, '.', don't need another one.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Tove

On Friday, 4 April 2014 at 19:43:56 UTC, Walter Bright wrote:

C++:

namespace S { namespace T {
int foo();
namespace U {
int foo();
}
 } }

D:

  extern (C++, S::T) {
  int foo();
  extern (C++, U) {
int foo();
  }
  }
  foo();  // error, ambiguous, which one?
  S.T.foo(); // S undefined


Why would we need new ways of declaring scopes in D? Overriding 
the external mangling should be sufficient? If there are 
collisions you can use any type of scope you prefer to avoid the 
issue, modules, structs, templates, even functions or blocks...


void fun1() { extern (C++, S::T) int foo();}
void fun2() { extern (C++, S::T::U) int foo();}

extern (C++, S::T::U) int foo();
struct test { extern (C++, S::T) int foo();}


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Ola Fosheim Grøstad

On Friday, 4 April 2014 at 20:06:49 UTC, Walter Bright wrote:

We already have a scope operator, '.', don't need another one.


It is more clear to the reader that it is an external namespace 
and you avoid renaming because then C++ has it's own namespace in 
D reducing the chances of clashes. But it's a minor issue, 
although I think it is important for long term maintainability of 
code to easily discriminate between C++ function calls (which 
tend to be supportive lower level libraries/engines) and D 
function calls (which tend to be higher level code).


When you do contract work on many projects for different small 
businesses, you often get requests for modifications/additions 
1-2 times a year or so. The less chance of code 
misinterpretation, the better.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread bearophile

Tove:

Why would we need new ways of declaring scopes in D? Overriding 
the external mangling should be sufficient? If there are 
collisions you can use any type of scope you prefer to avoid 
the issue, modules, structs, templates, even functions or 
blocks...


void fun1() { extern (C++, S::T) int foo();}
void fun2() { extern (C++, S::T::U) int foo();}

extern (C++, S::T::U) int foo();
struct test { extern (C++, S::T) int foo();}


This seems promising, but this idea needs to become simpler.

Bye,
bearophile


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Dicebot

On Friday, 4 April 2014 at 19:43:56 UTC, Walter Bright wrote:

Fails because:

C++:

namespace S { namespace T {
int foo();
namespace U {
int foo();
}
 } }

D:

  extern (C++, S::T) {
  int foo();
  extern (C++, U) {
int foo();
  }
  }
  foo();  // error, ambiguous, which one?
  S.T.foo(); // S undefined


I don't feel this is a problem. Such foo's should be disambugated 
by D tools, which means using different modules. Exact matching 
between C++ and D sources is impossible anyway, it is not worth 
complicating D qualification system for that.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Dicebot

On Friday, 4 April 2014 at 19:33:34 UTC, Simen Kjærås wrote:

I'm not entirely sure I follow you here. Is this what you mean?

extern(C++) module nspace {
int foo();
}

void main() {
foo();// Either this does not work, (#1)
nspace.foo(); // or this does not work. (#2)
}

If so, is that really bad? I'd say the better choice is to make 
#2 work, as then #1 can be made to work with a simple alias:


alias foo = nspace.foo;

If I'm far off into the fields of ignorance now, care to show 
me the way to a better understanding?


#2 should not compile. D currently does not have any notion of 
namespaces other than modules / aggregates and I am against 
introducing those just for the sake of interfacing with C++.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread Mason McGill

On Friday, 4 April 2014 at 21:39:01 UTC, bearophile wrote:

Tove:

Why would we need new ways of declaring scopes in D? 
Overriding the external mangling should be sufficient? If 
there are collisions you can use any type of scope you prefer 
to avoid the issue, modules, structs, templates, even 
functions or blocks...


void fun1() { extern (C++, S::T) int foo();}
void fun2() { extern (C++, S::T::U) int foo();}

extern (C++, S::T::U) int foo();
struct test { extern (C++, S::T) int foo();}


This seems promising, but this idea needs to become simpler.

Bye,
bearophile


This seems like it would be simple if it came with a recommended 
style for library wrappers, e.g.


// C++
namespace A {
  namespace B {
void f1();
void f2();
  }
  namespace C {
void f3();
void f4();
  }
}

// D
struct A {
  struct B {
  extern(C++, A, B):
static void f1();
static void f2();
  }
  struct C {
  extern(C++, A, C):
static void f3();
static void f4();
  }
}

This can be easily generated by hand or with something like SWIG, 
and keeps the semantics of extern consistent throughout the 
language (it still only affects the ABI).  This also keeps things 
simple for users who just want to call one function.


// D
void callF1() {
  extern(C++, A, B) void f1();
  f1();
}

I used , instead of :: because it avoids adding a new token, 
but that's more of an aesthetic issue.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread deadalnix

On Friday, 4 April 2014 at 07:06:30 UTC, Walter Bright wrote:

On 4/3/2014 5:47 PM, deadalnix wrote:

I'm not familiar with usual C++ mangling as much as D. Are
template and namespace mangled the same way ?


No.


Then that is a bad idea.


Re: Specifying C++ symbols in C++ namespaces

2014-04-04 Thread deadalnix

On Friday, 4 April 2014 at 22:17:45 UTC, Dicebot wrote:

On Friday, 4 April 2014 at 19:33:34 UTC, Simen Kjærås wrote:

I'm not entirely sure I follow you here. Is this what you mean?

extern(C++) module nspace {
   int foo();
}

void main() {
   foo();// Either this does not work, (#1)
   nspace.foo(); // or this does not work. (#2)
}

If so, is that really bad? I'd say the better choice is to 
make #2 work, as then #1 can be made to work with a simple 
alias:


alias foo = nspace.foo;

If I'm far off into the fields of ignorance now, care to show 
me the way to a better understanding?


#2 should not compile. D currently does not have any notion of 
namespaces other than modules / aggregates and I am against 
introducing those just for the sake of interfacing with C++.


templates, function bodies, block statements, ...


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Kagamin

On Wednesday, 2 April 2014 at 22:06:53 UTC, Walter Bright wrote:

Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}


@namespace(nspace)
extern (C++) {
  int foo();
}

One downside of this proposal is that if we ever (perish the 
thought!) attempted to interface to C++ templates, this design 
would preclude that.


If we have partial C++ bindings, why not have partial template 
bindings with a subset of features already existing in D? With 
that you would only need to implement mangling and linking. An 
interesting and simple enough use case is casting:


extern(C++) T my_cast(T,U)(U);
extern(C++) interface A{}
extern(C++) interface B:A{}

A a;
B b = my_cast!B(a);


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Kagamin

On Wednesday, 2 April 2014 at 22:06:53 UTC, Walter Bright wrote:
A possible enhancement would be to allow (for all templates 
with no parameters):


nspace.foo();


std.string - does it refer to phobos module or C++ string?


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Andrej Mitrovic
On 4/3/14, Walter Bright newshou...@digitalmars.com wrote:
 A possible enhancement would be to allow (for all templates with no
 parameters):

  nspace.foo();

My only problem with this is how it will affect existing code. E.g.:

template take(alias templ) { }
template take(T) { }

template Empty() { struct Empty { } }

take!Empty;  // which overload of take is instantiated?


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Michel Fortin

On 2014-04-03 03:48:18 +, Walter Bright newshou...@digitalmars.com said:


On 4/2/2014 7:14 PM, Michel Fortin wrote:

That's a contrived example.


Not at all. The whole point of using namespaces in C++ is to introduce 
a scope. And the whole point of scopes is to have the same name in 
different scopes represent different objects.



Perhaps I'm wrong, but I'd assume the general use
case is that all functions in a module will come from the same C++ namespace.


I believe that is an incorrect assumption. C++ namespaces were 
specifically (and wrongly, in my not so humble opinion, but there it 
is) not designed to be closed, nor have any particular relationship 
with modules.



Alternatively you can use another module for the other namespace.


Forcing C++ code that exists in a single file to be split up among 
multiple D files is inflicting unnecessary punishment on the poor guy 
trying to justify migrating to D.


Ok, let's assume that we actually want to reproduce the C++ file 
structure then. Let us have a C++ project, with two files. I'll 
temporarily use the 'namespace' keyword on the D side until we can 
decide on how to best represent a namespace:


 module foo;
 extern (C++):

 namespace S { namespace T {
int foo();
namespace U {
int foo();
}
 } }


 module bar;
 extern (C++):

 namespace S { namespace T {
int bar();
namespace U {
int bar();
}
 } }

Now let's use those:

 module main;
 import foo;
 import bar;

 void main() {
 S.T.foo();
 S.T.U.bar();
 }

But how does the lookup for those functions work? If we use structs or 
templates to represent those namespaces in D then you'll have to 
specify the module name to disambiguate the struct/template itself, and 
the namespace just becomes a nuisance you have to repeat over and over:


 void main() {
 .foo.S.T.foo();
 .bar.S.T.U.bar();
 }

Here I'd argue that having whole-module namespaces in D makes no sense. 
So let's retry by peeling the S.T part of the namespace:


 module foo;
 extern (C++, S.T):

 int foo();
 namespace U {
 int foo();
 }


 module bar;
 extern (C++, S.T):

 int bar();
 namespace U {
 int bar();
 }


 module main;
 import foo;
 import bar;

 void main() {
 foo();
 .bar.U.bar();
 }

Better. Still, if you want C++ namespaces to work nicely, you'll have 
to introduce first class namespace support in D. That means that 
identical namespaces are merged into each other when you import 
modules that contain them. It'd allow you to write this:


 void main() {
 foo();
 U.bar();
 }

Still, I'm not convinced that'd be terribly helpful. Namespaces in D 
would make it easier to declare things 1:1 for sure, but anything that 
depends on Koenig lookup[1] will be broken in D. It could even be 
silently broken as no Koenig lookup means another function not in a 
namespace could be used silently instead of the expected one in a 
namespace (assuming a naive port of some C++ code).


[1]: https://en.wikipedia.org/wiki/Argument-dependent_name_lookup

I'd tend to simply implement extern(C++, namespace.here), which should 
work fine to wrap single-namespace cpp files, and wait to see what are 
the actual friction points before introducing more (people can 
experiment with structs or other modules meanwhile).



--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Daniel Kozák
V Thu, 3 Apr 2014 06:36:54 -0400
Michel Fortin michel.for...@michelf.ca napsáno:

 On 2014-04-03 03:48:18 +, Walter Bright
 newshou...@digitalmars.com said:
 
  On 4/2/2014 7:14 PM, Michel Fortin wrote:
  That's a contrived example.
  
  Not at all. The whole point of using namespaces in C++ is to
  introduce a scope. And the whole point of scopes is to have the
  same name in different scopes represent different objects.
  
  Perhaps I'm wrong, but I'd assume the general use
  case is that all functions in a module will come from the same C++
  namespace.
  
  I believe that is an incorrect assumption. C++ namespaces were 
  specifically (and wrongly, in my not so humble opinion, but there
  it is) not designed to be closed, nor have any particular
  relationship with modules.
  
  Alternatively you can use another module for the other namespace.
  
  Forcing C++ code that exists in a single file to be split up among 
  multiple D files is inflicting unnecessary punishment on the poor
  guy trying to justify migrating to D.
 
 Ok, let's assume that we actually want to reproduce the C++ file 
 structure then. Let us have a C++ project, with two files. I'll 
 temporarily use the 'namespace' keyword on the D side until we can 
 decide on how to best represent a namespace:
 
   module foo;
   extern (C++):
 
   namespace S { namespace T {
  int foo();
  namespace U {
  int foo();
  }
   } }
 
 
   module bar;
   extern (C++):
 
   namespace S { namespace T {
  int bar();
  namespace U {
  int bar();
  }
   } }
 
 Now let's use those:
 
   module main;
   import foo;
   import bar;
 
   void main() {
   S.T.foo();
   S.T.U.bar();
   }
 
 But how does the lookup for those functions work? If we use structs
 or templates to represent those namespaces in D then you'll have to 
 specify the module name to disambiguate the struct/template itself,
 and the namespace just becomes a nuisance you have to repeat over and
 over:
 
   void main() {
   .foo.S.T.foo();
   .bar.S.T.U.bar();
   }
 
 Here I'd argue that having whole-module namespaces in D makes no
 sense. So let's retry by peeling the S.T part of the namespace:
 
   module foo;
   extern (C++, S.T):
 
   int foo();
   namespace U {
   int foo();
   }
 
 
   module bar;
   extern (C++, S.T):
 
   int bar();
   namespace U {
   int bar();
   }
 
 
   module main;
   import foo;
   import bar;
 
   void main() {
   foo();
   .bar.U.bar();
   }
 
 Better. Still, if you want C++ namespaces to work nicely, you'll have 
 to introduce first class namespace support in D. That means that 
 identical namespaces are merged into each other when you import 
 modules that contain them. It'd allow you to write this:
 
   void main() {
   foo();
   U.bar();
   }
 
 Still, I'm not convinced that'd be terribly helpful. Namespaces in D 
 would make it easier to declare things 1:1 for sure, but anything
 that depends on Koenig lookup[1] will be broken in D. It could even
 be silently broken as no Koenig lookup means another function not in
 a namespace could be used silently instead of the expected one in a 
 namespace (assuming a naive port of some C++ code).
 
 [1]: https://en.wikipedia.org/wiki/Argument-dependent_name_lookup
 
 I'd tend to simply implement extern(C++, namespace.here), which
 should work fine to wrap single-namespace cpp files, and wait to see
 what are the actual friction points before introducing more (people
 can experiment with structs or other modules meanwhile).
 
 

I think we should distinguish modules lookup from namespaces lookup.
Something like this:

A.B.foo() // call foo function from module/struct/class A and B
#A.#B.foo // call foo function from namespaces A and B
or
A::B.foo // call foo function from namespaces A and B
or
/A/B.foo // call foo function from namespaces A and B



Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Daniel Murphy

Walter Bright  wrote in message news:lhi1lt$269h$1...@digitalmars.com...


Here's Andrei's proposal:

 extern (C++) template nspace() {
 int foo();
 }


This is really ugly and complicated.

Why not just

pragma(cpp_namespace, outer)
{
   pragma(cpp_namespace, inner)
   {
   extern(C++) void func();
   }
}

which is trivial to implement and doesn't require parser or semantic 
changes?


Adding syntax for actual namespaces to D is a different beast and IMO not 
worthwhile. 



Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Jacob Carlborg

On 03/04/14 00:07, Walter Bright wrote:

Here's Andrei's proposal:

 extern (C++) template nspace() {
 int foo();
 }

It would be accessed in D by:

nspace!().foo();

A possible enhancement would be to allow (for all templates with no
parameters):

 nspace.foo();

Note that:

 template nspace() {
 extern (C++) int foo();
 }

would not put foo() in a C++ namespace, although it would still be
accessed from D as:

 nspace.foo();

One downside of this proposal is that if we ever (perish the thought!)
attempted to interface to C++ templates, this design would preclude that.


I like using a UDA or pragma better:

@namespace(nspace)
{
extern (C++) int foo ();
}

Or

pragma(cpp_namespace, nspace)
{
extern (C++) int foo ();
}

Then it's also possible to use this syntax:

@namespace(nspace):

extern (C++) int foo ();

The only advantage I can see with using template is that templates can 
be mixed in, it would be similar to the using declarative in C++.


--
/Jacob Carlborg


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Ola Fosheim Grøstad
I am not sure what is the best option, but it should be readable 
and obvious. So I might prefer to just have :: if possible. 
Somewhat annoying and verbose, so I am not sure about this, but 
the advantage is that it is easy to see what is C++ and what is D 
function calls.


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Robert Clipsham

On Thursday, 3 April 2014 at 03:48:08 UTC, Walter Bright wrote:
Alternatively you can use another module for the other 
namespace.


Forcing C++ code that exists in a single file to be split up 
among multiple D files is inflicting unnecessary punishment on 
the poor guy trying to justify migrating to D.


A solution could be to allow this:


module foo {
module bar {
// equivalent to foo/bar.d
}
}
extern(C++) module bar {
// Equivalent to namespace bar {} in C++
}


Note that Rust does something similar to this to allow multiple 
modules to be defined in a single file (though Rust also doesn't 
have the correspondence between filesystem location and module 
like D does - perhaps this is acceptable with the introduction of 
package.d?)


Robert


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Walter Bright

On 4/3/2014 4:06 AM, Daniel Kozák wrote:

I think we should distinguish modules lookup from namespaces lookup.
Something like this:

A.B.foo() // call foo function from module/struct/class A and B
#A.#B.foo // call foo function from namespaces A and B
or
A::B.foo // call foo function from namespaces A and B
or
/A/B.foo // call foo function from namespaces A and B



Please, no!


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Walter Bright

On 4/3/2014 3:36 AM, Michel Fortin wrote:

I'd tend to simply implement extern(C++, namespace.here), which should work fine
to wrap single-namespace cpp files, and wait to see what are the actual friction
points before introducing more (people can experiment with structs or other
modules meanwhile).


You have a good point in that to go all the way with namespaces, we'd have to 
implement Koenig lookup and support insertion of names into previous namespaces.


I can't see this happening in D.

But I don't see that as much of an argument to not do simple scoping with 
namespace lookup.




Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Daniel Kozak

On Thursday, 3 April 2014 at 19:44:02 UTC, Walter Bright wrote:

On 4/3/2014 4:06 AM, Daniel Kozák wrote:
I think we should distinguish modules lookup from namespaces 
lookup.

Something like this:

A.B.foo() // call foo function from module/struct/class A and B
#A.#B.foo // call foo function from namespaces A and B
or
A::B.foo // call foo function from namespaces A and B
or
/A/B.foo // call foo function from namespaces A and B



Please, no!


Ok, just an idea :)


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Andrei Alexandrescu

On 4/3/14, 4:19 AM, Daniel Murphy wrote:

Walter Bright  wrote in message news:lhi1lt$269h$1...@digitalmars.com...


Here's Andrei's proposal:

 extern (C++) template nspace() {
 int foo();
 }


This is really ugly and complicated.

Why not just

pragma(cpp_namespace, outer)
{
pragma(cpp_namespace, inner)
{
extern(C++) void func();
}
}

which is trivial to implement and doesn't require parser or semantic
changes?


I don't quite see how one is ugly and complicated and the other is... 
pretty and simple? Anyhow de gustibus.



Adding syntax for actual namespaces to D is a different beast and IMO
not worthwhile.


Agreed.


Andrei



Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Michel Fortin

On 2014-04-03 19:43:23 +, Walter Bright newshou...@digitalmars.com said:


On 4/3/2014 3:36 AM, Michel Fortin wrote:
I'd tend to simply implement extern(C++, namespace.here), which should 
work fine
to wrap single-namespace cpp files, and wait to see what are the actual 
friction

points before introducing more (people can experiment with structs or other
modules meanwhile).


You have a good point in that to go all the way with namespaces, we'd 
have to implement Koenig lookup and support insertion of names into 
previous namespaces.


I can't see this happening in D.


Me neither.

But I don't see that as much of an argument to not do simple scoping 
with namespace lookup.


What I'm saying is that it should be optional to create a new scope to 
declare a C++ function from a namespace. In other words you need to be 
able to put the function at module scope in D.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Théo.Bueno

On Thursday, 3 April 2014 at 11:19:53 UTC, Daniel Murphy wrote:
Walter Bright  wrote in message 
news:lhi1lt$269h$1...@digitalmars.com...



Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}


This is really ugly and complicated.

Why not just

pragma(cpp_namespace, outer)
{
   pragma(cpp_namespace, inner)
   {
   extern(C++) void func();
   }
}

which is trivial to implement and doesn't require parser or 
semantic changes?


Adding syntax for actual namespaces to D is a different beast 
and IMO not worthwhile.



IMO I don't think pragmas are meant to this kind of uses, 
extern(C++) already exists and makes more sense.


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread H. S. Teoh
On Thu, Apr 03, 2014 at 12:43:59PM -0700, Walter Bright wrote:
 On 4/3/2014 4:06 AM, Daniel Kozák wrote:
 I think we should distinguish modules lookup from namespaces lookup.
 Something like this:
 
 A.B.foo() // call foo function from module/struct/class A and B
 #A.#B.foo // call foo function from namespaces A and B
 or
 A::B.foo // call foo function from namespaces A and B
 or
 /A/B.foo // call foo function from namespaces A and B
 
 
 Please, no!

The current situation where module/scope qualifiers clash with UFCS sux,
though.

static import std.algorithm;
...
auto myRange = ...;
//myRange.std.algorithm.find(...);  // NG :-(

alias find = std.algorithm.find;
myRange.find(...);  // OK

But this is kinda tangential to this topic. :P


T

-- 
My program has no bugs! Only undocumented features...


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread deadalnix

On Wednesday, 2 April 2014 at 22:06:53 UTC, Walter Bright wrote:

Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}

It would be accessed in D by:

   nspace!().foo();

A possible enhancement would be to allow (for all templates 
with no parameters):


nspace.foo();

Note that:

template nspace() {
extern (C++) int foo();
}

would not put foo() in a C++ namespace, although it would still 
be accessed from D as:


nspace.foo();

One downside of this proposal is that if we ever (perish the 
thought!) attempted to interface to C++ templates, this design 
would preclude that.


I'm not familiar with usual C++ mangling as much as D. Are
template and namespace mangled the same way ?


Re: Specifying C++ symbols in C++ namespaces

2014-04-03 Thread Daniel Murphy
Andrei Alexandrescu  wrote in message 
news:lhkebg$1i1p$1...@digitalmars.com...




 extern (C++) template nspace() {
 int foo();
 }


This is really ugly and complicated.



I don't quite see how one is ugly and complicated and the other is... 
pretty and simple? Anyhow de gustibus.


Stuff inside the template will only be instantiated when used.  That's fine 
when it's just a prototype of a C++ function to be called from D, but much 
less useful when the implementation is in D and the use is from C++.


It can conflict with the eponymous template syntax - D would not be able to 
tell the difference between a templated function and a function inside a 
namespace with the same name.


It forces this organisation for all symbols that use C++ namespaces.

If you define functions in the same namespace in different modules the 
template symbols will conflict and you will have to use fully-qualified 
names.


On the other side, in D modules are used for symbol organisation.  It's 
powerful enough that you can get namespace::function to match 
library.module.function (and I expect you can force use of the namespace 
through clever use of static renamed imports).


The missing part is getting the mangling right, and a pragma is the least 
intrusive way I can imagine to do that. 



Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Walter Bright

Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}

It would be accessed in D by:

   nspace!().foo();

A possible enhancement would be to allow (for all templates with no parameters):

nspace.foo();

Note that:

template nspace() {
extern (C++) int foo();
}

would not put foo() in a C++ namespace, although it would still be accessed from 
D as:


nspace.foo();

One downside of this proposal is that if we ever (perish the thought!) attempted 
to interface to C++ templates, this design would preclude that.


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread w0rp
Seems alright. The only downside I can think of is that the 
namespace wouldn't be semantically analysed until you first try 
to use it, as it's a template.


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread bearophile

Walter Bright:


Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}


I suggest to brainstorm the syntax some more time, because 
someone could be able to invent a better syntax.


Some seeds:

extern (C++(nspace)) {
int foo();
}

extern (C++) struct nspace {
int foo();
}

extern (C++)(nspace) {
int foo();
}

extern (C++ nspace) {
int foo();
}

Bye,
bearophile


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread monnoroch
And what about something like static struct? It seems more 
natural and less hacky to me.


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Xiaoxi

On Wednesday, 2 April 2014 at 22:33:21 UTC, bearophile wrote:

Walter Bright:


Here's Andrei's proposal:

   extern (C++) template nspace() {
   int foo();
   }


I suggest to brainstorm the syntax some more time, because 
someone could be able to invent a better syntax.


Some seeds:

extern (C++(nspace)) {
int foo();
}

extern (C++) struct nspace {
int foo();
}

extern (C++)(nspace) {
int foo();
}

extern (C++ nspace) {
int foo();
}

Bye,
bearophile


extern (C++) module nspace;



Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread bearophile

Xiaoxi:


extern (C++) module nspace;


They plan to add some kind of modules to C++ in few years :-( So 
this risks semantic clashes.


Bye,
bearophile


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Mike

On Wednesday, 2 April 2014 at 22:06:53 UTC, Walter Bright wrote:

Here's Andrei's proposal:

extern (C++) template nspace() {
int foo();
}

It would be accessed in D by:

   nspace!().foo();

A possible enhancement would be to allow (for all templates 
with no parameters):


nspace.foo();

Note that:

template nspace() {
extern (C++) int foo();
}

would not put foo() in a C++ namespace, although it would still 
be accessed from D as:


nspace.foo();

One downside of this proposal is that if we ever (perish the 
thought!) attempted to interface to C++ templates, this design 
would preclude that.


Walter, some on this list have not been around long enough to 
understand the motivation for this.  Could you please summarize 
the problem and how this addresses it? Is this for interfacing D 
to C++, or a way to bring namespace semantics to D?


Mike


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Rikki Cattermole

On Wednesday, 2 April 2014 at 22:33:21 UTC, bearophile wrote:

Walter Bright:


Here's Andrei's proposal:

   extern (C++) template nspace() {
   int foo();
   }


I suggest to brainstorm the syntax some more time, because 
someone could be able to invent a better syntax.


Some seeds:


...

extern (C++)(nspace) {
int foo();
}

extern (C++ nspace) {
int foo();
}

Bye,
bearophile


I definitely like the last two. Small and to the point. But where 
nspace is a wrapper 'static struct' essentially.

So:

nspace.foo()


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Mike

On Wednesday, 2 April 2014 at 23:04:58 UTC, Mike wrote:

On Wednesday, 2 April 2014 at 22:06:53 UTC, Walter Bright wrote:

Here's Andrei's proposal:

   extern (C++) template nspace() {
   int foo();
   }

Is this for interfacing D to C++, or a way to bring namespace 
semantics to D?




Well, I'm assuming this is specifically for interfacing D with 
C++ given the 'extern (C++)' attribution.  In that case, I think 
the proposal abuses the 'template' keyword for something that's 
not really a template.


In that case, I find the syntax proposed by bearophile to be far 
better...


extern (C++ nspace) {
int foo();
}

...although I would even prefer it be even more explicit...

extern (C++ namespace nspace) {
int foo();
}

I'd also be interested in hearing the arguments against the UDAs 
and pragmas proposed in the following two links:

* https://d.puremagic.com/issues/show_bug.cgi?id=7961
* https://github.com/D-Programming-Language/dmd/pull/2767

The pragma is especially nice since this isn't really a D thing, 
although bearophile's proposed syntax is hard to argue against.


Mike


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Walter Bright

On 4/2/2014 3:33 PM, bearophile wrote:

I suggest to brainstorm the syntax some more time, because someone could be able
to invent a better syntax.

Some seeds:

extern (C++(nspace)) {
 int foo();
}


I considered that, but it fails because:

C++:

namespace S { namespace T {
int foo();
namespace U {
int foo();
}
 } }

D:

  extern (C++, S.T) {
  int foo();
  extern (C++, U) {
int foo();
  }
  }
  foo();  // error, ambiguous, which one?
  S.T.foo(); // S undefined


 extern (C++) struct nspace {
  int foo();
 }

Fails because a struct as struct and struct as namespace are not 
distinguishable.



Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Walter Bright

On 4/2/2014 3:30 PM, monnoroch wrote:

And what about something like static struct? It seems more natural and less
hacky to me.


Because C++ mangles static member functions of structs differently from members 
of namespaces.


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Walter Bright

On 4/2/2014 4:04 PM, Mike wrote:

Walter, some on this list have not been around long enough to understand the
motivation for this.  Could you please summarize the problem and how this
addresses it? Is this for interfacing D to C++, or a way to bring namespace
semantics to D?



See the earlier thread entitled: C++ interface. started yesterday.



Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread bearophile

Walter Bright:


I considered that, but it fails because:

C++:

namespace S { namespace T {
int foo();
namespace U {
int foo();
}
 } }

D:

  extern (C++, S.T) {
  int foo();
  extern (C++, U) {
int foo();
  }
  }
  foo();  // error, ambiguous, which one?
  S.T.foo(); // S undefined


Then is the idea of extern(C++) module by Xiaoxi usable in some 
way?


Bye,
bearophile


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread monnoroch

On Thursday, 3 April 2014 at 01:06:25 UTC, Walter Bright wrote:
Because C++ mangles static member functions of structs 
differently from members of namespaces.


What i meant is not static functions and members of a struct, but 
a static struct as a concept of a struct, whith can only contain 
a static stuff. C++ has no such concept, but essentually static 
struct === namespace.

Consider this:

extern(C++) static struct A {
static struct B {
struct X {}
int foo(X);
}
}

A.B.foo(A.B.X());


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread monnoroch
Also, D already has scope classes, so why not create full 
featured class bindings?


Suppose, i have this:

class A {
private:
int x;

public:
A(int x_) : x(x_) {}
A(const A v) : x(v.x) {}
~A() {}
};

Why not interfase those as:

extern (C++) {
struct A {
int x;
this(int x_); // call c++ A::A(int)
this(this);   // call c++ A::A(const A)
~this();  // call c++ A::~A()
}
}


I mean, methods in c++ are just like functions in namespaces with 
first T* argument, so this is also just mangling problem; and all 
those constructors and destructors are not something special 
either.


What stops to do that?
If value semantics isn't appropriate, user, who writes D 
interface can just do it in scope class.

Maby discussing that would also do some good.


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread monnoroch

Or even the simplier way. Just do:

extern(C++) struct A {
int x;
A A(int x_);
A A(ref const(A) v);
void ~A(A*);
}

And call those methods manually:

A obj = A.A(1);
A obj1 = A.A(obj);
A.~A(obj);
A.~A(obj1);

The problem here it to distinguish real static methods from fake 
ones. But we can actually make user mark real static methods as 
static.


Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Michel Fortin

On 2014-04-03 01:09:43 +, Walter Bright newshou...@digitalmars.com said:


I considered that, but it fails because:

C++:

 namespace S { namespace T {
 int foo();
 namespace U {
 int foo();
 }
  } }

D:

   extern (C++, S.T) {
   int foo();
   extern (C++, U) {
 int foo();
   }
   }
   foo();  // error, ambiguous, which one?
   S.T.foo(); // S undefined


That's a contrived example. Perhaps I'm wrong, but I'd assume the 
general use case is that all functions in a module will come from the 
same C++ namespace. For the contrived example above, I think it's fair 
you have to use a contrived solution:


module s.t;
extern (C++, S.T):

int foo();

struct U {
static extern (C++, S.T.U):

int foo();
}

Alternatively you can use another module for the other namespace.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: Specifying C++ symbols in C++ namespaces

2014-04-02 Thread Walter Bright

On 4/2/2014 7:14 PM, Michel Fortin wrote:

On 2014-04-03 01:09:43 +, Walter Bright newshou...@digitalmars.com said:

I considered that, but it fails because:

C++:

 namespace S { namespace T {
 int foo();
 namespace U {
 int foo();
 }
  } }

D:

   extern (C++, S.T) {
   int foo();
   extern (C++, U) {
 int foo();
   }
   }
   foo();  // error, ambiguous, which one?
   S.T.foo(); // S undefined


That's a contrived example.


Not at all. The whole point of using namespaces in C++ is to introduce a scope. 
And the whole point of scopes is to have the same name in different scopes 
represent different objects.



Perhaps I'm wrong, but I'd assume the general use
case is that all functions in a module will come from the same C++ namespace.


I believe that is an incorrect assumption. C++ namespaces were specifically (and 
wrongly, in my not so humble opinion, but there it is) not designed to be 
closed, nor have any particular relationship with modules.



For the contrived example above, I think it's fair you have to use a contrived
solution:


I don't believe that punishing C++ users who dare to try D is the path to 
success for D :-)



Alternatively you can use another module for the other namespace.


Forcing C++ code that exists in a single file to be split up among multiple D 
files is inflicting unnecessary punishment on the poor guy trying to justify 
migrating to D.