December 30, 2005
"Walter Bright" <newshound@digitalmars.com> wrote in
[snip]
> di files' main advantage is improving build speeds for large projects.

I regularly compile 200+ files on a mediocre desktop. Takes about 3 seconds when using Build (which eats perhaps a third or a half of that time). I would not consider it worthwhile using "di" files until the file count were up in the thousands ... from that perspective, the current value of "di" appears truly nebulous. It will likely remain so for the overwhelming majority of users; for eternity.

While I always applaud your progress with the language and the compiler, don't you think this stands alone as blatant feature-creep? With respect, I think we'd all be better off without -H until an actual need for it arises ~ at that point we might even have some /useful/ requirements for it, since implementation hiding (what we all requested) is apparently not what it's intended for :-)

Respectfully;


December 30, 2005
"Kris" <fu@bar.com> wrote in message news:dp1sn8$12rr$1@digitaldaemon.com...
> You suggest that using Interfaces is the right way to hide implementation detail. I'd agree, but how does one expose the means of accessing an instance? Does one provide an interface factory, and expose a header for that?

That's the classic way of doing it.


December 30, 2005
On Thu, 29 Dec 2005 16:03:22 -0800, Walter Bright wrote:

> "Kris" <fu@bar.com> wrote in message news:dp1sn8$12rr$1@digitaldaemon.com...
>> You suggest that using Interfaces is the right way to hide implementation detail. I'd agree, but how does one expose the means of accessing an instance? Does one provide an interface factory, and expose a header for that?
> 
> That's the classic way of doing it.

Can someone translate this into an example or two?

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"A learning experience is one of those things that says,
 'You know that thing you just did? Don't do that.'" - D.N. Adams
30/12/2005 11:18:52 AM
December 30, 2005
"Walter Bright" <newshound@digitalmars.com> wrote
>
> "Kris" <fu@bar.com> wrote in message news:dp1sn8$12rr$1@digitaldaemon.com...
>> You suggest that using Interfaces is the right way to hide implementation detail. I'd agree, but how does one expose the means of accessing an instance? Does one provide an interface factory, and expose a header for that?
>
> That's the classic way of doing it.

Then, this related "di" would not expose anything private or potentially "sensitive" about the interface-factory itself?

Can you perhaps illustrate with a working example, please? I think that would help a lot :)


December 30, 2005
"James Dunne" <james.jdunne@gmail.com> wrote in message news:dp1t3o$1383$1@digitaldaemon.com...
> Walter Bright wrote:
>> They work a lot like "precompiled headers" do in C++.
> Understood.
> How about a separate interface class generation feature then?
> If it were up to me I would rename the 'import file' feature to
> 'precompiled header', hoping that the term is not copyrighted/trademarked
> by Microsoft. =)  Then again, if they work 'a lot like' precompiled
> headers in C++ then what are the main differences if the two are not
> exactly alike?

The main difference is that precompiled headers are an abominable kludge <g>. Precompiled headers are order dependent, and cannot be included multiple times. Some things cannot be put in headers to be precompiled. Precompiled headers tend to aggregate all the headers together. They are very sensitive to compiler switch settings, meaning they need to be constantly rebuilt.

None of these apply to D interface files.

> For the closed source community, one could also invent a specially formatted D import source file which declares only the non-private methods of classes *and* at which offsets they can be found at in the vtable.  Of course include the public fields and at which offsets they are found at as well.

Because of templates, const initializers, etc., I suspect that although this is doable, it will be of marginal utility.


December 30, 2005
"Walter Bright" <newshound@digitalmars.com> wrote in message news:dp1s4k$12ev$1@digitaldaemon.com...
>
> "Derek Parnell" <derek@psych.ward> wrote in message news:zqfcc85x3d7z$.1n4xv1fmu7njt$.dlg@40tude.net...
>> In other words, let's enhance the language so we can support the needs of
>> developers who want closed-source development *and* the needs of the
>> compiler to generate correctly performing code. This would mean we need
>> to
>> resolve the issue of class member offsets, inlining, and const
>> declarations. These are not impossible to resolve.
>
> There's more than that, there are template bodies. At some point, we have to ask if we've just got the wrong approach to implementation hiding. I suggest that interface classes are the way to get true implementation hiding, not di files. di files' main advantage is improving build speeds for large projects.
>
> They work a lot like "precompiled headers" do in C++.
>

I'm not suggesting that the solution below in worth using but it's a good idea to look into.

Quite some time ago I used to do some work in Modula2 and the way implementation and interface were divided was very intutive, over time I've got used to other methods and eventually felt comfortable with them.

This link gives a short overview http://www.csc.twu.ca/rsbook/Ch6/Ch6.5.html

Oberon2 which came later on removed this concept but it was later on re-introduced.

for eg in Modula2:
DEFINITION MODULE MyRealMath;

CONST
  root2 = 1.414213562;

PROCEDURE log (x : REAL) : REAL;

END MyRealMath.and in another file:IMPLEMENTATION MODULE MyRealMath;  (* note same name *)

FROM RealMath IMPORT
  ln;

PROCEDURE log (x : REAL) : REAL;
(* returns the base 10 logarithm of x *)
BEGIN
  RETURN (ln (x)) / (ln (10.0) )
END log;

END MyRealMath.user file:MODULE Client;

FROM MyRealMath IMPORT
  root2, log;


December 30, 2005
Here's an arbitrary example, Derek ~ for a closed-source SearchEngine. I think Walter is the only one who can explain how -H can help here:

~~~~~~~~~~~~~~~~~~~
module SearchFactory;

// these interfaces would typically live in other modules

// the hidden implementation
interface ISearchEngine
{
        ISearchItem[] lookup (char[] terms);
}

// more hidden implementation
interface ISearchItem
{
        int relevancy();
        char[] retrievalUrl();
        char[] displaySnippet();
}


// import a.bunch.of.proprietary.stuff;


// a factory for hooking up a client to the hidden implementation
ISearchEngine createSearchEngine (char[] someAttributes)
{
        // potentially use a.bunch.of.proprietary.stuff;
}


// do some proprietary setup
static this()
{
        // potentially use a.bunch.of.proprietary.stuff;
}

~~~~~~~~~~~~~~~~~~~~~

unfortunately, this is what I get when using the -H option:
dmd.exe has encountered a problem and needs to close. We are sorry for the
inconvenience.


GPF's aside, I imagine that -H would expose the content of both the createSearchEngine() factory method, and whatever else is in there (such as the static ctor). This means that the all relevant proprietary import modules will also need to be shipped with this module :-)

The idea of an Interface is to cleanly isolate a "contractual obligation" from any and all implementation detail. I could easily be wrong, but I fail to see how this can be achieved with D (even in a trivial example) without rather careful attention to detail.

If I were to create a "di" file by hand, then it might look something like this:

~~~~~~~~~~~~~~~~~~~~~~~
module importSearchEngine;

// expose the interfaces
public import search.ISearchEngine;
public import search.ISearchItem;

ISearchEngine createSearchEngine (char[] someAttributes);
~~~~~~~~~~~~~~~~~~~~~~~~

This should work correctly (note the lack of implementation detail). However, it bears little or no resemblance to the -H option. Thus -H is worthless for such things ~ I think you have to build them by hand instead ...

:-(





"Derek Parnell" <derek@psych.ward> wrote in message news:bm7jarnr2vgq$.ddyfy4fndls1.dlg@40tude.net...
> On Thu, 29 Dec 2005 16:03:22 -0800, Walter Bright wrote:
>
>> "Kris" <fu@bar.com> wrote in message news:dp1sn8$12rr$1@digitaldaemon.com...
>>> You suggest that using Interfaces is the right way to hide
>>> implementation
>>> detail. I'd agree, but how does one expose the means of accessing an
>>> instance? Does one provide an interface factory, and expose a header for
>>> that?
>>
>> That's the classic way of doing it.
>
> Can someone translate this into an example or two?
>
> -- 
> Derek
> (skype: derek.j.parnell)
> Melbourne, Australia
> "A learning experience is one of those things that says,
> 'You know that thing you just did? Don't do that.'" - D.N. Adams
> 30/12/2005 11:18:52 AM


December 30, 2005
"Kris" <fu@bar.com> wrote in message news:dp20nn$15ns$1@digitaldaemon.com...
> Here's an arbitrary example, Derek ~ for a closed-source SearchEngine. I think Walter is the only one who can explain how -H can help here:
>
> ~~~~~~~~~~~~~~~~~~~
> module SearchFactory;
>
> // these interfaces would typically live in other modules
>
> // the hidden implementation
> interface ISearchEngine
> {
>        ISearchItem[] lookup (char[] terms);
> }
>
> // more hidden implementation
> interface ISearchItem
> {
>        int relevancy();
>        char[] retrievalUrl();
>        char[] displaySnippet();
> }
>
>
> // import a.bunch.of.proprietary.stuff;
>
>
> // a factory for hooking up a client to the hidden implementation
> ISearchEngine createSearchEngine (char[] someAttributes)
> {
>        // potentially use a.bunch.of.proprietary.stuff;
> }
>
>
> // do some proprietary setup
> static this()
> {
>        // potentially use a.bunch.of.proprietary.stuff;
> }
>
> ~~~~~~~~~~~~~~~~~~~~~
>
> unfortunately, this is what I get when using the -H option:
> dmd.exe has encountered a problem and needs to close. We are sorry for the
> inconvenience.

I'd like an example of that, so I can fix it.

> GPF's aside, I imagine that -H would expose the content of both the createSearchEngine() factory method, and whatever else is in there (such as the static ctor). This means that the all relevant proprietary import modules will also need to be shipped with this module :-)

No, it won't if the function is too complex to be inlined, which is the usual case.

> The idea of an Interface is to cleanly isolate a "contractual obligation" from any and all implementation detail. I could easily be wrong, but I fail to see how this can be achieved with D (even in a trivial example) without rather careful attention to detail.

A good example of using interfaces is COM programming under Windows. The general idea is:

interface Foo
{
    T method1(args);
    U method2(args);
 }

Foo FooFactory(args);

and you call FooFactory(args) to create an instance of Foo, instead of using new.



December 30, 2005
"Kris" <fu@bar.com> wrote in message news:dp1ufk$142q$1@digitaldaemon.com...
> "Walter Bright" <newshound@digitalmars.com> wrote
>>
>> "Kris" <fu@bar.com> wrote in message news:dp1sn8$12rr$1@digitaldaemon.com...
>>> You suggest that using Interfaces is the right way to hide implementation detail. I'd agree, but how does one expose the means of accessing an instance? Does one provide an interface factory, and expose a header for that?
>>
>> That's the classic way of doing it.
>
> Then, this related "di" would not expose anything private or potentially "sensitive" about the interface-factory itself?
>
> Can you perhaps illustrate with a working example, please? I think that would help a lot :)

.di files aren't necessarilly going to help you here. But in another post in this thread, I gave an example of FooFactory() that is the usual way of generating an instance of an interface.


December 30, 2005
"Kris" <fu@bar.com> wrote in message news:dp1tf9$13ds$1@digitaldaemon.com...
> While I always applaud your progress with the language and the compiler, don't you think this stands alone as blatant feature-creep? With respect, I think we'd all be better off without -H until an actual need for it arises ~ at that point we might even have some /useful/ requirements for it, since implementation hiding (what we all requested) is apparently not what it's intended for :-)

Since Dave had already implemented it, and it would be needed eventually anyway, there was good reason to put it in. Furthermore, most of the work involved improving the pretty-printing capability of the compiler, much of which was stubbed out or kludged and needed to be done properly anyway. The pretty-printing capability is used for things like formatting of error messages and the doc generator.

(For example, now expressions get properly parenthesized when printed, and numerous problems printing numeric and string literals were fixed.)

These fixes weren't necessary for DMD to compile programs successfully, but they do contribute to it looking like a polished, presentable product.