September 09, 2013
On Monday, 9 September 2013 at 17:34:23 UTC, Joseph Rushton Wakeling wrote:
> On 09/09/13 18:41, Ettienne Gilbert wrote:
>> I would argue that it is actually better this way (that not all functions need
>> to be in the declarations list) - its way more flexible! This way you can leave
>> out function declarations that you are not really interested to see from a
>> "functional overview perspective" of the class.
>
> AFAICS the request is for separation of declaration and definition, so you'd be able to do things like this:
>
>     class Foo
>     {
>         void foo();
>         int bar(double x);
>         void goo(int n);
>         // ... etc.
>     }
>
> ... and then later in the same file:
>
>     void Foo.foo()
>     {
>         /* ... function body ... */
>     }
>
>     int Foo.bar(double x)
>     {
>         /* ... ditto ... */
>     }
>
>     void Foo.goo(int n)
>     {
>         /* ... and so on ... */
>     }
>
> Now, you'd be at liberty to mix declarations and definitions in the _class_ (or struct) declaration, e.g.:
>
>     class Foo
>     {
>         void foo(); // we define this somewhere else
>
>         int bar(double x)
>         {
>             /* ... but we define this here */
>         }
>
>         // ... etc.
>     }
>
> But supposing that a function is declared but not defined inside the class declaration, it should be obligatory that it _is_ defined somewhere else in the file -- and conversely, if a class function is defined somewhere else in the file, it should be obligatory that it's declared in the class declaration.
>
> And on top of that, it should be obligatory that the declaration and definition match perfectly.  (Note that for any function defined in the class declaration, this is automatically and unavoidably true:-)

Ahh, ok. I see where you are coming from - you were evaluating the implications of what Jacob Carlborg proposed if "mixed" in with Walter's DIP47, right? My points though was specifically on the implications of Jacob Carlborg's proposal "in isolation" i.e. as an acceptable alternative to DIP47. And, AFAICS, Jacob posed the question to Manu this way as well (I think - but maybe Jacob can confirm/deny).

If you mix the 2 I agree with you for the most part. But the real question for me (and I suspect Jacob) is this:

Is this...

>     class Foo
>     {
>         void foo();
>         int bar(double x);
>         void goo(int n);
>         // ... etc.
>     }
>
>     void Foo.foo()
>     {
>         /* ... function body ... */
>     }
>
>     int Foo.bar(double x)
>     {
>         /* ... ditto ... */
>     }
>
>     void Foo.goo(int n)
>     {
>         /* ... and so on ... */
>     }

...really so much better than this?


>     class Foo
>     {
>         void foo();
>         int bar(double x);
>         void goo(int n);
>         // ... etc.
>         void foo()
>         {
>              /* ... function body ... */
>         }
>
>         int bar(double x)
>         {
>              /* ... ditto ... */
>         }
>
>         void goo(int n)
>         {
>              /* ... and so on ... */
>         }
>     }

Granted, this sacrifices some flexibility from DIP47. But these are of such dubious quality/use/potential pitfalls (as discussed in this thread), that I hardly think DIP47 is worth implementing as a result. Especially since, what we currently have (as shown by Carl,) already gives you arguably 90%+ (IMHO) of Manu's request for (I quote) "You don't need to see the function bodies in the class definition, you want to quickly see what a class has and does". Does it really matter that the function definitions are also present inside the class definition, as long as you can also see "what a class has and does" in the declarations list at the top?

Of course fixing the current issues with .di generation is important as a separate issue.
September 09, 2013
On Mon, Sep 09, 2013 at 02:20:34PM -0700, Andrei Alexandrescu wrote:
> On 9/9/13 12:35 PM, H. S. Teoh wrote:
> >Auto-generation of .di files solves this problem. (Provided we fix the mess that is the current implementation of .di generation, of course.)
> 
> OK, so what's the trouble with .di generation today?
[...]

1) It could be pretty-printed (it currently tries to, but it's not very
pretty).

2) Eponymous templates look ugly. I.e., this:

	template MyClass(T) {
		class MyClass {
			...
		}
	}

   instead of:

   	class MyClass(T) {
		...
	}

3) It loses manual formatting, like turning this:

	writeln("This is a very very long string "~
		"broken across multiple lines");

   into:

	writeln("This is a very very long string "~ "broken across multiple lines");

   which detracts from readability when the expression is very long.
   This also applies to signature contraints, which are just
   concatenated onto an already-over-long function signature.

   A related issue concerns reordering of function qualifiers, e.g., if
   your code looks like this:

   	void func(int a) pure @safe nothrow {
		...
	}

   it gets turned into:

   	pure @safe nothrow void func(int a) {
		...
	}

   which is a bit jarring since when reviewing the .di file you may be
   expecting what you wrote, not what the compiler thinks you should
   have written.

4) It includes template function bodies inline, which means it fails to
   serve as a class-at-a-glance format in that case. It could use the
   declare-first, implement-later approach some have suggested, i.e.:

   	class MyTemplateClass(T) {
		void member();

		...

		void member() { /* implementation here */ }
	}

    instead of the current:

    	class MyTemplateClass(T) {
		void member() { /* implementation here */ }
		...
	}

5) Private templates are included along with public ones: to achieve
   Manu's goal of interface-at-a-glance, private members and private
   templates should be put at the end of the file, rather than in the
   midst of the public symbols. Though this is a minor issue; you could
   just reorder code in the source manually.

There may be a few other points I missed. But all in all, it's not *quite* ready to serve as an interface-at-a-glance format yet. I didn't find any inherent limitations, though (except possibly for templated private members, but those can be largely alleviated by suitable reordering), so once these issues are addressed, we should be good to go.


T

-- 
In theory, there is no difference between theory and practice.
September 10, 2013
On 9/8/2013 5:03 PM, Andrei Alexandrescu wrote:
> D's module system has always favored a file-granular approach, e.g. private
> stuff is module-private. This notion of spilling private access outside the file
> into methods defined in various other files works against that nice tenet.
>
> So it looks there's no obvious and obviously good solution. Probably the first
> one is more sensible.

One solution that has been proposed here (by Manu and perhaps others) is that the outlined functions can only appear inside the same module that the declaration is in.

This would resolve the private access problem and the modularity problem.

September 10, 2013
On 9/9/13 4:43 PM, H. S. Teoh wrote:
> On Mon, Sep 09, 2013 at 02:20:34PM -0700, Andrei Alexandrescu wrote:
>> On 9/9/13 12:35 PM, H. S. Teoh wrote:
>>> Auto-generation of .di files solves this problem. (Provided we fix the
>>> mess that is the current implementation of .di generation, of course.)
>>
>> OK, so what's the trouble with .di generation today?
> [...]
>
> 1) It could be pretty-printed (it currently tries to, but it's not very
> pretty).
[more good stuff]

Please paste all of the above into a bug report!

Andrei

September 10, 2013
On 9/9/13 5:12 PM, Walter Bright wrote:
> On 9/8/2013 5:03 PM, Andrei Alexandrescu wrote:
>> D's module system has always favored a file-granular approach, e.g.
>> private
>> stuff is module-private. This notion of spilling private access
>> outside the file
>> into methods defined in various other files works against that nice
>> tenet.
>>
>> So it looks there's no obvious and obviously good solution. Probably
>> the first
>> one is more sensible.
>
> One solution that has been proposed here (by Manu and perhaps others) is
> that the outlined functions can only appear inside the same module that
> the declaration is in.
>
> This would resolve the private access problem and the modularity problem.

It also reduces the motivation for the thing as it becomes a minor convenience.

Andrei


September 10, 2013
On Mon, Sep 09, 2013 at 05:39:06PM -0700, Andrei Alexandrescu wrote:
> On 9/9/13 4:43 PM, H. S. Teoh wrote:
> >On Mon, Sep 09, 2013 at 02:20:34PM -0700, Andrei Alexandrescu wrote:
> >>On 9/9/13 12:35 PM, H. S. Teoh wrote:
> >>>Auto-generation of .di files solves this problem. (Provided we fix the mess that is the current implementation of .di generation, of course.)
> >>
> >>OK, so what's the trouble with .di generation today?
> >[...]
> >
> >1) It could be pretty-printed (it currently tries to, but it's not
> >very pretty).
> [more good stuff]
> 
> Please paste all of the above into a bug report!
[...]

http://d.puremagic.com/issues/show_bug.cgi?id=11003


T

-- 
"I suspect the best way to deal with procrastination is to put off the procrastination itself until later. I've been meaning to try this, but haven't gotten around to it yet. " -- swr
September 10, 2013
On 2013-09-09 00:03:11 +0000, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> D's module system has always favored a file-granular approach, e.g. private stuff is module-private. This notion of spilling private access outside the file into methods defined in various other files works against that nice tenet.

Is the D module system file-granular or module-granular? I always thought the later. Putting the implementation of functions in the .d file while the declarations are in the corresponding .di does not change things much: it's still one module, but it's one module split over two files.

It also helps solve another problem: the problem where you're shipping a library and want to force some things to not be inlined. This is needed if the library is to be swapped for another version without having to recompile all client code. You can do this currently by hand-crafting .di files, but it's a pain to keep it manually in sync with the .d file.

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

September 10, 2013
On Mon, Sep 09, 2013 at 10:09:51PM -0400, Michel Fortin wrote:
> On 2013-09-09 00:03:11 +0000, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
> 
> >D's module system has always favored a file-granular approach, e.g. private stuff is module-private. This notion of spilling private access outside the file into methods defined in various other files works against that nice tenet.
> 
> Is the D module system file-granular or module-granular? I always thought the later. Putting the implementation of functions in the .d file while the declarations are in the corresponding .di does not change things much: it's still one module, but it's one module split over two files.
> 
> It also helps solve another problem: the problem where you're shipping a library and want to force some things to not be inlined. This is needed if the library is to be swapped for another version without having to recompile all client code. You can do this currently by hand-crafting .di files, but it's a pain to keep it manually in sync with the .d file.
[...]

It would be nice if UDAs can somehow be used to mark functions as don't-inline, so that dmd -H produces the correct .di file without requiring manual maintenance.


T

-- 
Mediocrity has been pushed to extremes.
September 10, 2013
On 9/9/2013 5:39 PM, Andrei Alexandrescu wrote:
> On 9/9/13 5:12 PM, Walter Bright wrote:
>> This would resolve the private access problem and the modularity problem.
>
> It also reduces the motivation for the thing as it becomes a minor convenience.

Yup.

September 10, 2013
On 09/08/2013 07:00 AM, Jonathan M Davis wrote:
> Actually, for those who really want this sort of thing, why don't they just
> use .di files?
Because this is a prerequisite to do so.
One important point is being able to verify the definition against the declaration which isn't currently possible.