Re: new DIP47: Outlining member functions of aggregates

2013-09-16 Thread Bruno Medeiros

On 09/09/2013 04:46, Manu wrote:

Missed the action...

Well it's clear this is not a popular proposal.
And even to me personally, it's certainly not of critical importance. If
there was a single thing I'd like to see *DONE* in D, it would be
temporary/r-value->ref args, without question (really, really annoying
to work around).

For the record, I tend to agree with the arguments of many in the
'against' camp *from a purist point of view*, but the problem remains,
and the reason I raised it; this has demonstrated to me and my
colleagues on a number of occasions that it is a consistent productivity
hindrance.
I guess a significant reason my experience seems to differ from
many(/most) on this forum, is that they're not in the business of
banging out quick throw-away commercial code.
The practical reality in my experience in the games industry is this:
  - Some (perhaps small) percentage of code is tech/foundation code. It
is carefully authored, but still typically documented only of the class
outline in the header file isn't already self-explanatory (I'm a big fan
of self-documenting code). It is to be re-used.
  - Much (perhaps most) code is rudimentary logic and glue code, or
'game code' as we call it. This tends to be code that is written by more
inexperienced programmers and written to tight schedules. It is almost
never documented (apart from the occasional inline comments), rarely
conforms to some spec (unless it's implementing from foundational
interface), and usually exists to serve only the life of this one very
specific project, ie, throw-away. It is also almost always
logic-intensive code, riddled with switch/if/else constructs that take
an awful lot of vertical space, which further magnifies the problem of
inline function definitions breaking up the readability of the class
outline.

Now further, from an absolutely practical point of view, the time that
someone unfamiliar with this code has to deal with it in the first place
is very likely at 11pm the night before the publisher is demanding a
build so they can show it to a bunch of arseholes in fancy suits who
will decide if they're going to pay us or not.
In C++ there is a very useful tool for unfamiliar programmers to get a
good brief overview of the code before they go hacking at it, that is
the class outline.
We've lost that. And I have demonstrably missed it.

People make claims like "write better code, split it up better, document
your code better, use the IDE folding", blah blah, but it's simply not
the practical reality. The budget and schedule does not typically allow
for careful consideration, design, and documentation of such throw away
code which glues the project together.
The code is what it is, and whether it's written in C++, or D, or lua,
it's probably not going to change the nature of this huge volume of
crappy code.
Code folding doesn't work in foreign editors, communication tools, diff
windows; code reviews become more time consuming to approve, and I don't
know many programmers that like/use it regardless, even if it may help
in some occasions.
I think it's bat-shit-crazy to rely on a tool to simply make code
readable and easy to understand for a start. I also personally feel code
folding alienates me from the code I'm writing. As an author, you
quickly gain a feel for the layout of your source file; the flow and
shape of the code across the file is kinda picturesque. For me
personally, code folding ruins that relationship with my code, and I
don't like it. It makes it harder for me to sweep through my file and
quickly locate the points of interest that I'm working through. So if
I'm not using it in my own code, but I'm required to use it to
understand someone else's code... there's a bit of a conflict of
interest there.

If I'm one of very few voices in favour of class outlines, I'm going to
suggest letting this argument sleep until other more serious issues are
resolved which people have been waiting on for ages.
I certainly want r-values -> ref args to work much more.

Keep in mind, I raised this debate as a practical account of last
weekend, among a bunch of other issues which were certainly more
significant than this one, but this seemed to capture the most attention.
It's not the first time it's come up and it'll be back again I'm sure :)

I support this DIP, obviously, but I'd suggest perhaps a conservative
restriction that definitions should only be allowed to appear within the
same module as the declaration. This would seem to simplify things like
mangling issues and access rights. In my own use case, I have no reason
to spread definitions across files. I just want to see class outlines
clearly summarised at the top of the file. This saves time, and time is
money.


On 8 September 2013 03:00, Walter Bright mailto:newshou...@digitalmars.com>> wrote:

Outlining of member functions is the practice of placing the
declaration of a member function in the struct/class/union, and
placing the definition of it at 

Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Jesse Phillips
On Monday, 9 September 2013 at 18:23:21 UTC, Joseph Rushton 
Wakeling wrote:

On 09/09/13 20:05, Jesse Phillips wrote:
I think DDOC should be improved to handle this scenario. Being 
able to generate
docs with undocumented members would be great for internal 
development of the
module. I realize that doesn't address all your problems, but 
I think that is

the correct direction.


Better DDoc is always going to be nice, but come on -- that 
doesn't address the issue of looking at code in a diff or a 
copy-paste via chat software, and in the scenarios Manu has 
described, no one's going to have time to write documentation 
comments.


OK, you could have a DDoc setting to at least _list_ all 
elements of class interfaces etc., even if there's no doc 
comment, but that doesn't address the other factors.


I hope you realize you've restated what I said? Include 
undocumented members, won't address all problems.


There can definitely be value for diff; if you're objective is to 
find modifications to public API.


I don't want to have a class pasted in a chat window, with or 
without function definitions (Unavoidable I know). If I need to 
do anything complicated with that information, into a text editor 
it goes (and on linux this would be in /tmp and easy to compile 
docs for; Windows, I just hope I'm not there).


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Dicebot

On Tuesday, 10 September 2013 at 14:15:19 UTC, bearophile wrote:

Craig Dillabaugh:


Apart from functions with say variadic parameter lists, is this
really all that useful?


There are rare situations when you need to add a certain 
argument to the function signature, but you don't need to use 
that argument inside the method/function. This happens for 
example because of code evolution. In such cases not giving a 
name to the argument is good, you avoid introducing a useless 
and unused variable name, making the code simpler, safer, and 
more clear.


Bye,
bearophile


It is never the case in the declaration though. You always want 
parameter names there, to reference them in DDOC comment at the 
very least.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Craig Dillabaugh

On Tuesday, 10 September 2013 at 14:15:19 UTC, bearophile wrote:

Craig Dillabaugh:


Apart from functions with say variadic parameter lists, is this
really all that useful?


There are rare situations when you need to add a certain 
argument to the function signature, but you don't need to use 
that argument inside the method/function. This happens for 
example because of code evolution. In such cases not giving a 
name to the argument is good, you avoid introducing a useless 
and unused variable name, making the code simpler, safer, and 
more clear.


Bye,
bearophile


I think using calling the variable 'dummy' would likely do the
trick in those instances, but this makes sense.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Joseph Rushton Wakeling

On 09/09/13 16:29, Dicebot wrote:

On Monday, 9 September 2013 at 14:22:15 UTC, Joseph Rushton Wakeling wrote:

Then it simply becomes a question of deciding if the manual labour of writing
separate outlines and definitions is worth it.  I guess this is probably
somewhere where a tool really _can_ be useful, to ensure that the definitions
and the outline stay in sync.

Writing D code in this way should probably be disapproved of in the D style
guidelines, but with the proviso that it's there for the circumstances where
it really is useful.


Very well spoken, this is exactly how I see it.


Thank you! :-)



Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread bearophile

Craig Dillabaugh:


Apart from functions with say variadic parameter lists, is this
really all that useful?


There are rare situations when you need to add a certain argument 
to the function signature, but you don't need to use that 
argument inside the method/function. This happens for example 
because of code evolution. In such cases not giving a name to the 
argument is good, you avoid introducing a useless and unused 
variable name, making the code simpler, safer, and more clear.


Bye,
bearophile


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Craig Dillabaugh

On Tuesday, 10 September 2013 at 13:49:21 UTC, bearophile wrote:

Walter Bright:


clip



3. Parameter names need not match.


This seems bad. What's the rationale for this? (One perhaps 
acceptable solution is to put no parameter names in the 
signature inside the class).



I am sure there is a good reason for having no parameter names
in a declaration, but to me this doesn't make much sense.
If people want separate declaration/definition so that they can
get an idea of what a class does, then for non-trivial functions
if the variable names are omitted then your more or less have
to look at the definition anyway.

I must admit whenever I come across such declarations in code I
am reading I always find them kind of irritating.

Apart from functions with say variadic parameter lists, is this
really all that useful?


clip



The D compiler could be modified a bit to generate a bare bones 
documentation even with not even a comment written in the code.


Bye,
bearophile


I agree on this last point.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread bearophile

Walter Bright:

Outlining of member functions is the practice of placing the 
declaration of a member function in the struct/class/union, and 
placing the definition of it at global scope in the module or 
even in another module.


http://wiki.dlang.org/DIP47


I was away and very busy, I have read only part of the answers in 
this thread.


I don't like this DIP. If this DIP passes I am probably not going 
to use this feature in my code.


Go and Python show that it's good to minimize the number of 
trivially different ways to write code in a language. This DIP 
does the opposite.




or even in another module.


This is not a good idea.



"If you rely on tools to make the code _readable_,


In my opinion this DIP makes the code less readable, and makes 
the code less DRY.




3. Parameter names need not match.


This seems bad. What's the rationale for this? (One perhaps 
acceptable solution is to put no parameter names in the signature 
inside the class).


Generally I suggest to fix the biggest module system bugs before 
modifying the design of related features, like the ones discussed 
in DIP47.


-

Daniel Murphy:

Let's solve a documentation issue with documentation 
improvements.


This seems one better solution to the problem.

But I also suggest people here to read and discuss about the post 
written by Andrei that touches deeper issues. The module system 
is currently significantly buggy, and it needs a principled 
design before trying to add DIP47.


-

Manu:


People make claims like "write better code, split it up better,
document your code better,


The D compiler could be modified a bit to generate a bare bones 
documentation even with not even a comment written in the code.


Bye,
bearophile


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Dicebot
On Tuesday, 10 September 2013 at 13:32:14 UTC, Andrej Mitrovic 
wrote:

On 9/10/13, Dicebot  wrote:

Main issue of .di files that make them useless for anything but
providing declarations for blobs is that there is absolutely 
zero

compiler control of .d and .di relation.


Yeah, I think we could attempt to provide an alternative to 
DIP47 by
adding a compiler flag that verifies .d implementations match 
.di

declarations. We don't even have to make the .d files explicitly
import the .di files like Andrei proposed.


Please, no compiler flags. It should be default behavior. We are 
speaking about fundamental binary-level application sanity here.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Andrej Mitrovic
On 9/10/13, Dicebot  wrote:
> Main issue of .di files that make them useless for anything but
> providing declarations for blobs is that there is absolutely zero
> compiler control of .d and .di relation.

Yeah, I think we could attempt to provide an alternative to DIP47 by
adding a compiler flag that verifies .d implementations match .di
declarations. We don't even have to make the .d files explicitly
import the .di files like Andrei proposed.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Andrej Mitrovic
On 9/10/13, Jacob Carlborg  wrote:
> A mixin should not be necessary. RTInfo can be used for that:
>
> https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L575

The mixin was demonstrated for convenience so you don't have to
manually type in the class name (or use typeof(this)).


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Joseph Rushton Wakeling

On 10/09/13 14:12, Jacob Carlborg wrote:

verifyDeclarations would look something like this, in pseudo code:

void* verifyDeclarations (T) ()
{
 static if (is(T == class))
 {
 foreach (member ; methods!(T))
 {
 static if (!hasDefinition!(member))
 static assert (false, "The member '" fullyQualifiedName!(T) ~
"." ~ member.stringof ~ "' doesn't have a definition");
 }
 }

 return null;
}


But the problem that I identified wasn't the possibility of members that are 
declared but not defined.  It was the possibility of members that are defined 
but not included in the top-of-the-class list of separate declarations.  The 
whole point is that both the author and the recipient of the code should be able 
to verify at compile-time that the list of declarations is an accurate summary 
of the class.


I imagine you could define a verifySeparateDeclarations that would indeed 
enforce that (for every declaration a definition, and for every definition a 
separate declaration) but that would have its own issues.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Dicebot
Main issue of .di files that make them useless for anything but 
providing declarations for blobs is that there is absolutely zero 
compiler control of .d and .di relation. Fixing this either 
implies providing good control of how .di is generated via 
compiler flags (and prohibiting manual modifications) or 
implementing good part of DIP47 restricted to .di/.d combo (all 
the signature verifications).


Also it does not seem defined in spec how lookup should happen if 
both .d and .di are present, and, for example, .di has only 
declaration. Will compiler check .d for possible inlining if it 
is present?


I think that .di should always contain only declarations and be 
_always_ auto-generated by compiler with strict 1-to-1 matching 
signatures. Then .d are also queried if implementation is 
needed/considered - but those are not mandatory (aside from 
templates). Blob bindings distributed may then simply have a 
stripped down version of .d file (similar to what is now 
generated by dmd -H).


Key point here is  that .di needs _always_ to be there, with hard 
guarantees that it is in sync with actual code. Add even one more 
extra step of getting those and it becomes considerably less 
convenient than C++-like overview.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Jacob Carlborg

On 2013-09-10 10:49, Joseph Rushton Wakeling wrote:


Can you explain a bit more about how that works?


The "object" module, part of druntime defines a template with the name 
"RTInfo". That template will be instantiated with each user defined type.


Currently RTInfo doesn't do anything:

template RTInfo(T)
{
enum RTInfo = cast(void*)0x12345678;
}

https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L575

If you replace that template with something like:

template RTInfo(T)
{
enum RTInfo = verifyDeclarations!(T);
}

verifyDeclarations would look something like this, in pseudo code:

void* verifyDeclarations (T) ()
{
static if (is(T == class))
{
foreach (member ; methods!(T))
{
static if (!hasDefinition!(member))
static assert (false, "The member '" 
fullyQualifiedName!(T) ~ "." ~ member.stringof ~ "' doesn't have a 
definition");

}
}

return null;
}


As long as it can provide a guarantee that everything declared has a
definition, and everything defined has a declaration -- and that they
match! -- then I think this is probably the solution required.

What I mean is -- it needs to ensure that the issue identified in a
couple of my earlier posts will be flagged and prevented:
http://forum.dlang.org/post/mailman.1104.1378795749.1719.digitalmar...@puremagic.com


However, I'm suspicious of anything that would require the programmer to
be "virtuous" and manually ensure that those checks take place, rather
than the checks simply being a natural part of the compilation process.


The idea is then you build a tool that "compiles" all your files which 
uses druntime with the above implementation of RTInfo.


--
/Jacob Carlborg


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Timon Gehr

On 09/10/2013 06:59 AM, Walter Bright wrote:


The trouble with eschewing private access for member functions is then
arguably the member functions do not belong in the class at all - they
should be UFCS functions.


Functions are placed inside classes for convenient scoping and vtables.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Joseph Rushton Wakeling

On 10/09/13 09:59, Jacob Carlborg wrote:

A mixin should not be necessary. RTInfo can be used for that:

https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L575

The compiler will instantiate RTInfo once for each user defined type. The only
downside is that you need to modify druntime.


Can you explain a bit more about how that works?

As long as it can provide a guarantee that everything declared has a definition, 
and everything defined has a declaration -- and that they match! -- then I think 
this is probably the solution required.


What I mean is -- it needs to ensure that the issue identified in a couple of my 
earlier posts will be flagged and prevented:

http://forum.dlang.org/post/mailman.1104.1378795749.1719.digitalmar...@puremagic.com

However, I'm suspicious of anything that would require the programmer to be 
"virtuous" and manually ensure that those checks take place, rather than the 
checks simply being a natural part of the compilation process.


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Jacob Carlborg

On 2013-09-10 08:49, Joseph Rushton Wakeling wrote:

(My one caveat is that I think solutions based on
programmer virtue, like remembering to insert a line: "mixin
VerifyDeclarations;" into a class, are generally less nice than
solutions where the compiler does your checking for you without you
having to ask.)


That shouldn't be necessary, see my reply to Andrej:

http://forum.dlang.org/thread/l0fm2o$2uat$1...@digitalmars.com?page=14#post-l0mjh4:2418bp:241:40digitalmars.com

--
/Jacob Carlborg


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Jacob Carlborg

On 2013-09-09 22:01, Andrej Mitrovic wrote:


You could use compile-time introspection where the API would look like:

class C
{
 void foo();
 void foo() { }
 void bar() { }  // missing declaration
 mixin VerifyDeclarations;
}

And this would statically assert if there's a missing declaration for
a definition. I think this might even be doable with the current
introspection features, although I'm not sure whether we have a way to
determine if something is a declaration or a definition. Certainly
such a trait could easily be added to the compiler.


A mixin should not be necessary. RTInfo can be used for that:

https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L575

The compiler will instantiate RTInfo once for each user defined type. 
The only downside is that you need to modify druntime.


--
/Jacob Carlborg


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Jacob Carlborg

On 2013-09-09 23:45, Ettienne Gilbert wrote:


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).


Yes, my suggestion would be an alternative to DIP47.

--
/Jacob Carlborg


Re: new DIP47: Outlining member functions of aggregates

2013-09-10 Thread Joseph Rushton Wakeling

On 10/09/13 04:09, Michel Fortin wrote:

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.


Is it possible to manually craft some parts of the .di file, while being able to 
rely on the compiler to automatically add any module contents that aren't 
manually declared?


If so it might be the best solution to everyone's concerns.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 21:35, 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.)


Maybe you'll think I'm being too picky, but I don't think that generated files 
of any kind (whether .di or Ddoc) really help with the situations Manu was 
describing.  If you want to be able to look at the latest diff and see at a 
glance how the class API has changed, a generated file doesn't help (unless you 
store that generated file in the VCS, but I've always understood that to be bad 
practice).


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 23:45, Ettienne Gilbert wrote:

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?


The code that Jacob proposed is currently legit D code and that isn't going to 
change -- and if that solution works for you (or other people), great.  However, 
I don't think it completely address the requirements the DIP is attempting to 
meet.  In my previous email I was simply trying to show that implementing new 
functionality to allow class functions to be defined outside the class 
declaration, wouldn't be incompatible with writing code like Jacob's (although I 
don't see why anyone would mix the approaches in this way).


In terms of where I'm coming from, it's more in line with Dicebot -- I think 
both of us have been focused on the simultaneous usefulness and necessity of 
being able to check declaration against definition for class member functions 
that are declared and defined separately.



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...


 [ ... snip code ...]


...really so much better than this?


 [ ... snip again ...]


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?


The point is about being able to check that your declaration list has a 
one-to-one match with your definition list.  If you just decide to place 
declarations at the top of the class definition, and definitions lower down, you 
run the risk of accidentally missing one of the defined functions out of the 
declaration list:


class Foo
{
// Declarations
void foo();
void bar();

// Definitions
void foo() { ... }
void bar() { ... }
void goo() { ... }  // Whoops!  This is part of the class API but
// we forgot to include it in our declaration
// list ...
}

But Andrej Mitrovic has suggested a means to implement those kind of 
introspective checks at compile-time, so maybe it's not as urgent as I first 
thought.  (My one caveat is that I think solutions based on programmer virtue, 
like remembering to insert a line: "mixin VerifyDeclarations;" into a class, are 
generally less nice than solutions where the compiler does your checking for you 
without you having to ask.)



Of course fixing the current issues with .di generation is important as a
separate issue.


Yes, absolutely.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Walter Bright

On 9/9/2013 9:24 PM, Martin Nowak wrote:

 > 7. Outlined member function return types, parameter types, and function
bodies have private access to the module where the aggregate is declared.

I think this is problematic because it gives up the nice
everything-within-this-file property of private.
Doesn't package access mitigate the need for private access?


The trouble with eschewing private access for member functions is then arguably 
the member functions do not belong in the class at all - they should be UFCS 
functions.




Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Martin Nowak

On 09/07/2013 07:00 PM, Walter Bright wrote:

Outlining of member functions is the practice of placing the declaration
of a member function in the struct/class/union, and placing the
definition of it at global scope in the module or even in another module.

http://wiki.dlang.org/DIP47


I'm really happy to see this discussed.

The DIP misses to mention one of the most important rationale IMO,
hiding of implementation details.

> http://wiki.dlang.org/DIP47#Semantics
> 7. Outlined member function return types, parameter types, and 
function bodies have private access to the module where the aggregate is 
declared.


I think this is problematic because it gives up the nice 
everything-within-this-file property of private.

Doesn't package access mitigate the need for private access?

What about module scope functions?



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Martin Nowak

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.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Walter Bright

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.



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread H. S. Teoh
On Mon, Sep 09, 2013 at 10:09:51PM -0400, Michel Fortin wrote:
> On 2013-09-09 00:03:11 +, Andrei Alexandrescu
>  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.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Michel Fortin
On 2013-09-09 00:03:11 +, Andrei Alexandrescu 
 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.for...@michelf.ca
http://michelf.ca



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread H. S. Teoh
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


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Andrei Alexandrescu

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




Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Andrei Alexandrescu

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



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Walter Bright

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.



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread H. S. Teoh
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.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Ettienne Gilbert
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.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Brian Schott
On Monday, 9 September 2013 at 21:20:34 UTC, 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?

Andrei


Related to this: Is semantic information necessary for .di 
generation, or can it be built from the AST?


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Andrei Alexandrescu

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?

Andrei



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Andrej Mitrovic
On 9/9/13, Joseph Rushton Wakeling  wrote:
> A well-defined rule for separating out declarations and definitions would
> check
> for that and throw a compile error.

You could use compile-time introspection where the API would look like:

class C
{
void foo();
void foo() { }
void bar() { }  // missing declaration
mixin VerifyDeclarations;
}

And this would statically assert if there's a missing declaration for
a definition. I think this might even be doable with the current
introspection features, although I'm not sure whether we have a way to
determine if something is a declaration or a definition. Certainly
such a trait could easily be added to the compiler.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 21:30, Jonathan M Davis wrote:

Walter's proposal would be no different on that count. All that the DIP is
proposing is a way to define a member function outside of a class. That
requires that it already be declared in the class, but it doesn't make it so
that you can't define other functions directly in the class.


Sure.  The thing is that if you can only declare and define within the class, 
this potential problem is unavoidable -- you can _never_ be certain that your 
list of declarations is complete.


If on the other hand you can define outside the class declaration, then you can 
make it a design decision to only declare within the class declaration, and to 
define elsewhere in the module.  In that case it should be possible to guarantee 
a safety check that what's declared is defined and what's defined is declared -- 
and that the two match precisely.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 22:01, Andrej Mitrovic wrote:

You could use compile-time introspection where the API would look like:

class C
{
 void foo();
 void foo() { }
 void bar() { }  // missing declaration
 mixin VerifyDeclarations;
}

And this would statically assert if there's a missing declaration for
a definition. I think this might even be doable with the current
introspection features, although I'm not sure whether we have a way to
determine if something is a declaration or a definition. Certainly
such a trait could easily be added to the compiler.


Fair enough.  In that case I guess my objections don't really hold water.



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Jonathan M Davis
On Monday, September 09, 2013 15:51:11 Joseph Rushton Wakeling wrote:
> On 09/09/13 15:12, Daniel Murphy wrote:
> > "Jacob Carlborg"  wrote in message
> > news:l0jrm7$3199$1...@digitalmars.com...
> > 
> >> So what's wrong with this approach, that's already working today:
> >> 
> >> class Foo
> >> {
> >> 
> >> void foo ();
> >> 
> >> void foo ()
> >> {
> >> 
> >> }
> >> 
> >> }
> >> 
> >> void main ()
> >> {
> >> 
> >> auto foo = new Foo;
> >> foo.foo();
> >> 
> >> }
> >> 
> >> BTW, this feature was implemented because you asked for it.
> >> 
> >> --
> >> /Jacob Carlborg
> > 
> > Whoa, I didn't think of applying that to member functions. This seems
> > like
> > the answer. Put your variables and function prototypes at the top of your
> > class. Done.
> 
> Problem -- what about:
> 
> class Foo
> {
> // Declarations
> void foo();
> int bar(double n);
> 
> // Definitions
> void foo() {  }
> int bar(double n) { }
> 
> // Whoops! Forgot to include this one in the
> // declarations list, but it's still accepted
> // as part of the class
> void goo() { ... }
> }
> 
> A well-defined rule for separating out declarations and definitions would
> check for that and throw a compile error.

Walter's proposal would be no different on that count. All that the DIP is 
proposing is a way to define a member function outside of a class. That 
requires that it already be declared in the class, but it doesn't make it so 
that you can't define other functions directly in the class.

- Jonathan M Davis


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread H. S. Teoh
On Mon, Sep 09, 2013 at 08:23:07PM +0200, Joseph Rushton Wakeling wrote:
> On 09/09/13 20:05, Jesse Phillips wrote:
> >I think DDOC should be improved to handle this scenario. Being able
> >to generate docs with undocumented members would be great for
> >internal development of the module. I realize that doesn't address
> >all your problems, but I think that is the correct direction.
> 
> Better DDoc is always going to be nice, but come on -- that doesn't
> address the issue of looking at code in a diff or a copy-paste via
> chat software, and in the scenarios Manu has described, no one's going
> to have time to write documentation comments.
> 
> OK, you could have a DDoc setting to at least _list_ all elements of
> class interfaces etc., even if there's no doc comment, but that
> doesn't address the other factors.

Auto-generation of .di files solves this problem. (Provided we fix the
mess that is the current implementation of .di generation, of course.)


T

-- 
It said to install Windows 2000 or better, so I installed Linux instead.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Gary Willoughby
On Monday, 9 September 2013 at 18:23:21 UTC, Joseph Rushton 
Wakeling wrote:
Better DDoc is always going to be nice, but come on -- that 
doesn't address the issue of looking at code in a diff or a 
copy-paste via chat software, and in the scenarios Manu has 
described, no one's going to have time to write documentation 
comments.


This is such a poor argument for changing and further 
complicating the language. There are so many ways to get a class 
overview *even* in plain text. I can't honestly believe this is 
the catalyst for this DIP.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 20:30, Gary Willoughby wrote:

This is such a poor argument for changing and further complicating the language.
There are so many ways to get a class overview *even* in plain text. I can't
honestly believe this is the catalyst for this DIP.


I can understand anyone feeling that the costs aren't worth it, but I don't 
think it's ever good to dismiss battle experience of skilled developers, 
especially when it comes from scenarios that you or I may not have personal 
experience of.


I don't mind finding out I'm wrong (actually, I'd quite like to be in this 
case:-), but I'd like to understand how I could get the class overview in the 
plain-text scenarios described in my previous email.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 20:05, Jesse Phillips wrote:

I think DDOC should be improved to handle this scenario. Being able to generate
docs with undocumented members would be great for internal development of the
module. I realize that doesn't address all your problems, but I think that is
the correct direction.


Better DDoc is always going to be nice, but come on -- that doesn't address the 
issue of looking at code in a diff or a copy-paste via chat software, and in the 
scenarios Manu has described, no one's going to have time to write documentation 
comments.


OK, you could have a DDoc setting to at least _list_ all elements of class 
interfaces etc., even if there's no doc comment, but that doesn't address the 
other factors.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Jesse Phillips

On Monday, 9 September 2013 at 03:46:23 UTC, Manu wrote:
People make claims like "write better code, split it up better, 
document
your code better, use the IDE folding", blah blah, but it's 
simply not the
practical reality. The budget and schedule does not typically 
allow for
careful consideration, design, and documentation of such throw 
away code

which glues the project together.


I think DDOC should be improved to handle this scenario. Being 
able to generate docs with undocumented members would be great 
for internal development of the module. I realize that doesn't 
address all your problems, but I think that is the correct 
direction.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Jesse Phillips
On Sunday, 8 September 2013 at 19:47:06 UTC, Andrej Mitrovic 
wrote:

On 9/8/13, Jesse Phillips  wrote:

I realize that we want to make it as painless as possible for
Remedy to switch from C++ to D (along with the rest of the game
developers).


FWIW I don't think this has anything to do with Remedy (afaik 
Manu

doesn't work there anymore).


I did not realize he had left, but I did realize he was speaking 
for himself. I'm mostly just using Remedy as the symbol of large 
C++ code bases/programmers which want to use D because they 
actually are. I could see Manu's position being common for this 
user type, I don't think it is common for most D or other 
language programmers.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

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:-)



AFAIC the cost of implementing this would be way too high for any potential
benefit gained from this. And, since Walter already stated that this would "no
way be mandatory", the implications are that the compiler would need to enforce
it once any one function is declared in the declarations list, but... not
enforce it if no functions are declared in the list!


I am personally inclined to leave it to Walter to decide whether the cost of 
this is too much.  At the very least having this possibility seems to be in line 
with earlier plans.



Also, leaving it flexible as it is now cannot silently break anything. Worse
that can happen is that you may inadvertently try to implement goo() twice
(since you may think the missing declaration imply there is no definition), but
then the compiler will anyway complain about the duplicate definition.

So I agree with Jacob Carlborg - I would also like to know why the above is not
already sufficient...?


Because it allows a situation where you can have an incomplete list of member 
function declarations for a class or struct, and yet not know that it's 
incomplete without manual checking -- which I think fails to satisfy the needs 
Manu has identified.


We can reasonably debate whether those needs are worth addressing at all, and 
whether addressing them comes at too high a cost, but we should be clear on what 
solutions address them properly and what don't.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread jostly
On Monday, 9 September 2013 at 14:22:15 UTC, Joseph Rushton 
Wakeling wrote:
Question: do you have any access to information about similar 
short-deadline programming activity using other languages 
(Java, C# ...) that also forbid the separation of declaration 
and definition, and how devs using those languages cope with 
that?  It might offer an alternative solution that no one here 
has thought of.


As a long-time Java developer, my answer would be that it's dealt 
with via careful code crafting. Keep classes small, follow the 
principle of single responsibility etc. There are tons of good 
advice for writing maintainable, easy-to-understand code. And 
there's certainly nothing stopping us from doing the same in D.


However, if I understood Manu correctly, the issue here is those 
instances where there is not a lot of time, as in 48-hour game 
jams and game industry crunch mode. The cases where it is felt 
that code quality takes second place to getting things out fast.


In those cases, I think Java people would feel the same problem. 
It can be alleviated, in Java, by making sure you write 
interfaces for all public-facing code. The same could be done in 
D, but I am unsure if that would involve a performance hit that 
might actually matter in games programming. So at that point, the 
Java programmer would rely on the IDE to make sense of the 
bigfiles they are producing.


Now, I think an argument could be made that the initial 
productivity loss from performing refactorings to make sure you 
are producing maintainable code will pay off in a short while, 
even in crunchmode, but I realise this is something the games 
industry in general would have to deal with, and it should not be 
a burden put upon the individuals wishing to adopt D for making 
games.


As for the DIP, I would not want to code using that style myself, 
but I wouldn't mind it if the requirement was to keep all parts 
of the same class in the same module. Once we start crossing file 
boundaries, finding out where stuff is is going to be terrible 
unless you have a good IDE support for things like "Go to 
definition".


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Ettienne Gilbert
On Monday, 9 September 2013 at 13:51:20 UTC, Joseph Rushton 
Wakeling wrote:

On 09/09/13 15:12, Daniel Murphy wrote:

[snip]

/


Whoa, I didn't think of applying that to member functions.  
This seems like
the answer.  Put your variables and function prototypes at the 
top of your

class.  Done.


Problem -- what about:

class Foo
{
// Declarations
void foo();
int bar(double n);

// Definitions
void foo() {  }
int bar(double n) { }

// Whoops!  Forgot to include this one in the
// declarations list, but it's still accepted
// as part of the class
void goo() { ... }
}

A well-defined rule for separating out declarations and 
definitions would check for that and throw a compile error.


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.


AFAIC the cost of implementing this would be way too high for any 
potential benefit gained from this. And, since Walter already 
stated that this would "no way be mandatory", the implications 
are that the compiler would need to enforce it once any one 
function is declared in the declarations list, but... not enforce 
it if no functions are declared in the list!


Also, leaving it flexible as it is now cannot silently break 
anything. Worse that can happen is that you may inadvertently try 
to implement goo() twice (since you may think the missing 
declaration imply there is no definition), but then the compiler 
will anyway complain about the duplicate definition.


So I agree with Jacob Carlborg - I would also like to know why 
the above is not already sufficient...?


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Paulo Pinto

Am 09.09.2013 16:36, schrieb H. S. Teoh:

On Mon, Sep 09, 2013 at 03:26:23PM +0200, PauloPinto wrote:

On Monday, 9 September 2013 at 12:28:54 UTC, Dicebot wrote:

On Monday, 9 September 2013 at 00:43:39 UTC, H. S. Teoh wrote:

Therefore, the *real* solution to this problem is to fix the
compiler's .di output to give a proper overview of the class
*automatically*, and nicely pretty-printed.


Yes, that should be superior approach in general though exact
usability is very detail-specific - currently relation between .di
and .d and not really well-defined and pulling this off will
requires its own DIP at the very least.

For example, it is not entirely clear to me, what should happen if
there are both .di and .d files in the file system at the same
time and they have minor difference (remember, it is perfectly
legal to tweak .di manually).


I'd propose to make it such that you *don't* have to tweak the .di
manually. Maybe the use of UDAs could help get rid of the need to edit
.di by hand, by instructing the compiler what kind of output is desired.

Anything that requires hand-tweaking is unreliable and prone to errors
and careless bugs. The best way is to have .di completely automated.



It is likely, that improving .di
tool chain will require similar signature matching verification
anyway. Also I am wondering how to differ purely auto-generated .di
files (should be updated completely upon build) and ones with
manual changes (should be only verified).

It is all about small details.


In languages like Modula-2, it is a compile error if there are
differences.

So I would say D compilers should follow the same behavior, unless
it is requested to generate .di files automatically, which will then
overwrite the corresponding .di files.


I think it is a bug for the .di and .d to have mismatches. For example,
I don't see how the following code could be correct:

---module.di---
int func(int x) pure;

---module.d---
int global;
int func(int x) { return global; }

Any such mismatch should be considered a bug.

In fact, the current lax enforcement of matching makes it possible for
something to be declared pure @safe nothrow in .di, but impure @system
throwing in .d. I think there has been a few bugs like this in druntime
that got fixed.


T




I should have read your earlier post better.

The better approach would then be like the compilers of the Oberon 
language family do, by generating the interface file when compiling the 
packages.


--
Paulo


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Paulo Pinto

Am 09.09.2013 02:03, schrieb Andrei Alexandrescu:

On 9/8/13 5:33 AM, Andrej Mitrovic wrote:

On 9/8/13, Michel Fortin  wrote:

So I'd like to suggest this: allow a .d file to "import" its
corresponding
.di file.


This is actually what Andrei proposed as well.


I have to say I was a lot more in favor of the proposal before this thread.

The problem as I see it has two facets:

1. Code duplication

2. Modularity and logistics

Regarding (1), we currently force duplication of the entire class
layout. My understanding is that this is the way it's done:

// file acme.di

class A {
   int x;
   double y;
   void fun();
}

// file acme.d
// cannot import acme.di
class A {
   int x;
   double y;
   void fun() { ... }
}

The fact that acme.d cannot import acme.di is an unforced error of
embarrassing proportions and consequence. That should be fixed yesterday
no matter how we proceed otherwise.

The problem with acme.d not having access to acme.di is that any error
in duplicating the layout of A (e.g. swapping x and y or adding some
other members etc) will have undefined behavior, and there is no
reasonable way for the compiler to check against that.

Assuming that bug is fixed, the problem of duplication remains - all
state of the class must be duplicated.

(I also suspect constructors might need to be white-boxed (i.e.
available in the .di) for raw/cooked typechecking, but I'm not sure.)

If we go with DIP47, the duplication of state goes away. However we have
a distinct problem - modularity, which segues into (2).

Allowing out-of-module implementations of individual methods poses
additional modularity problems. Consider:

// file acme.di

class A {
   int x;
   double y;
   void fun();
}
private int a;
private void gun();

// file acme.d
// assume we solve the import problem
import acme;
void A.fun() { gun(); a = 42; }

If A.fun() were defined inside acme.di, it would have access to gun()
and a. Defining it outside asks the question - do we allow such access,
or not?

Intuitively the body of a method should not be all too sensitive to
where it's placed, so that argues in favor of visibility.

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.


Andrei



The approach should be like in Modula-2 family, only public stuff is 
allowed in .di files.


--
Paulo


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 16:34, Jacob Carlborg wrote:

Doesn't this already solve what this DIP47 is trying to solve?


See the objection given in my reply to Daniel Murphy.



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread H. S. Teoh
On Mon, Sep 09, 2013 at 03:26:23PM +0200, PauloPinto wrote:
> On Monday, 9 September 2013 at 12:28:54 UTC, Dicebot wrote:
> >On Monday, 9 September 2013 at 00:43:39 UTC, H. S. Teoh wrote:
> >>Therefore, the *real* solution to this problem is to fix the
> >>compiler's .di output to give a proper overview of the class
> >>*automatically*, and nicely pretty-printed.
> >
> >Yes, that should be superior approach in general though exact
> >usability is very detail-specific - currently relation between .di
> >and .d and not really well-defined and pulling this off will
> >requires its own DIP at the very least.
> >
> >For example, it is not entirely clear to me, what should happen if
> >there are both .di and .d files in the file system at the same
> >time and they have minor difference (remember, it is perfectly
> >legal to tweak .di manually).

I'd propose to make it such that you *don't* have to tweak the .di
manually. Maybe the use of UDAs could help get rid of the need to edit
.di by hand, by instructing the compiler what kind of output is desired.

Anything that requires hand-tweaking is unreliable and prone to errors
and careless bugs. The best way is to have .di completely automated.


> > It is likely, that improving .di
> >tool chain will require similar signature matching verification
> >anyway. Also I am wondering how to differ purely auto-generated .di
> >files (should be updated completely upon build) and ones with
> >manual changes (should be only verified).
> >
> >It is all about small details.
> 
> In languages like Modula-2, it is a compile error if there are
> differences.
> 
> So I would say D compilers should follow the same behavior, unless
> it is requested to generate .di files automatically, which will then
> overwrite the corresponding .di files.

I think it is a bug for the .di and .d to have mismatches. For example,
I don't see how the following code could be correct:

---module.di---
int func(int x) pure;

---module.d---
int global;
int func(int x) { return global; }

Any such mismatch should be considered a bug.

In fact, the current lax enforcement of matching makes it possible for
something to be declared pure @safe nothrow in .di, but impure @system
throwing in .d. I think there has been a few bugs like this in druntime
that got fixed.


T

-- 
Microsoft is to operating systems & security ... what McDonalds is to gourmet 
cooking.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Jacob Carlborg

On 2013-09-09 14:36, Manu wrote:


Which is what I requested it for, and use it very extensively.


Doesn't this already solve what this DIP47 is trying to solve?

--
/Jacob Carlborg


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Dicebot
On Monday, 9 September 2013 at 14:22:15 UTC, Joseph Rushton 
Wakeling wrote:
Then it simply becomes a question of deciding if the manual 
labour of writing separate outlines and definitions is worth 
it.  I guess this is probably somewhere where a tool really 
_can_ be useful, to ensure that the definitions and the outline 
stay in sync.


Writing D code in this way should probably be disapproved of in 
the D style guidelines, but with the proviso that it's there 
for the circumstances where it really is useful.


Very well spoken, this is exactly how I see it.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 05:46, Manu wrote:

For the record, I tend to agree with the arguments of many in the 'against' camp
*from a purist point of view*, but the problem remains, and the reason I raised
it; this has demonstrated to me and my colleagues on a number of occasions that
it is a consistent productivity hindrance.


For what it's worth, I think this kind of baptism-by-fire practical experience 
is very valuable, and that it's worth considering carefully even if the final 
decision is not to implement the requested feature.


Question: do you have any access to information about similar short-deadline 
programming activity using other languages (Java, C# ...) that also forbid the 
separation of declaration and definition, and how devs using those languages 
cope with that?  It might offer an alternative solution that no one here has 
thought of.



I support this DIP, obviously, but I'd suggest perhaps a conservative
restriction that definitions should only be allowed to appear within the same
module as the declaration. This would seem to simplify things like mangling
issues and access rights. In my own use case, I have no reason to spread
definitions across files. I just want to see class outlines clearly summarised
at the top of the file. This saves time, and time is money.


I think the conservative approach is probably correct -- the class outline and 
the function definitions should have to be in the same module, and the outline 
and definitions should match precisely.  Any mismatch (including in variable 
names)?  Compile error.  A function in the outline that isn't implemented? 
Compile error.  A function implemented that isn't in the outline?  Compile 
error.  That should greatly reduce the possibility of error caused by code 
duplication.


Then it simply becomes a question of deciding if the manual labour of writing 
separate outlines and definitions is worth it.  I guess this is probably 
somewhere where a tool really _can_ be useful, to ensure that the definitions 
and the outline stay in sync.


Writing D code in this way should probably be disapproved of in the D style 
guidelines, but with the proviso that it's there for the circumstances where it 
really is useful.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On 09/09/13 15:12, Daniel Murphy wrote:

"Jacob Carlborg"  wrote in message
news:l0jrm7$3199$1...@digitalmars.com...


So what's wrong with this approach, that's already working today:

class Foo
{
 void foo ();

 void foo ()
 {

 }
}

void main ()
{
 auto foo = new Foo;
 foo.foo();
}

BTW, this feature was implemented because you asked for it.

--
/Jacob Carlborg


Whoa, I didn't think of applying that to member functions.  This seems like
the answer.  Put your variables and function prototypes at the top of your
class.  Done.


Problem -- what about:

class Foo
{
// Declarations
void foo();
int bar(double n);

// Definitions
void foo() {  }
int bar(double n) { }

// Whoops!  Forgot to include this one in the
// declarations list, but it's still accepted
// as part of the class
void goo() { ... }
}

A well-defined rule for separating out declarations and definitions would check 
for that and throw a compile error.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread PauloPinto

On Monday, 9 September 2013 at 12:28:54 UTC, Dicebot wrote:

On Monday, 9 September 2013 at 00:43:39 UTC, H. S. Teoh wrote:
Therefore, the *real* solution to this problem is to fix the 
compiler's
.di output to give a proper overview of the class 
*automatically*, and

nicely pretty-printed.


Yes, that should be superior approach in general though exact 
usability is very detail-specific - currently relation between 
.di and .d and not really well-defined and pulling this off 
will requires its own DIP at the very least.


For example, it is not entirely clear to me, what should happen 
if there are both .di and .d files in the file system at the 
same time and they have minor difference (remember, it is 
perfectly legal to tweak .di manually). It is likely, that 
improving .di tool chain will require similar signature 
matching verification anyway. Also I am wondering how to differ 
purely auto-generated .di files (should be updated completely 
upon build) and ones with manual changes (should be only 
verified).


It is all about small details.


In languages like Modula-2, it is a compile error if there are 
differences.


So I would say D compilers should follow the same behavior, 
unless it is requested to generate .di files automatically, which 
will then overwrite the corresponding .di files.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Daniel Murphy
"Jacob Carlborg"  wrote in message 
news:l0jrm7$3199$1...@digitalmars.com...
> On 2013-09-09 05:46, Manu wrote:
>> Missed the action...
>>
>> Well it's clear this is not a popular proposal.
>> And even to me personally, it's certainly not of critical importance. If
>> there was a single thing I'd like to see *DONE* in D, it would be
>> temporary/r-value->ref args, without question (really, really annoying
>> to work around).
>
> So what's wrong with this approach, that's already working today:
>
> class Foo
> {
> void foo ();
>
> void foo ()
> {
>
> }
> }
>
> void main ()
> {
> auto foo = new Foo;
> foo.foo();
> }
>
> BTW, this feature was implemented because you asked for it.
>
> -- 
> /Jacob Carlborg

Whoa, I didn't think of applying that to member functions.  This seems like 
the answer.  Put your variables and function prototypes at the top of your 
class.  Done. 




Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Joseph Rushton Wakeling

On Monday, 9 September 2013 at 04:18:29 UTC, deadalnix wrote:
For that second, it has been discussed in the thread to improve 
the di behavior to fit that role. Do think this is a viable 
approach, and that your team of happy devs would have benefited 
from that ?


Correct me if I'm wrong, but isn't the problem of using 
manually-written .di files to separate out class declaration and 
definition, that you consequently also have to manually include 
all the declarations of all the other module content?


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Manu
On 9 September 2013 18:08, deadalnix  wrote:

> On Monday, 9 September 2013 at 07:00:23 UTC, Jacob Carlborg wrote:
>
>> On 2013-09-09 05:46, Manu wrote:
>>
>>> Missed the action...
>>>
>>> Well it's clear this is not a popular proposal.
>>> And even to me personally, it's certainly not of critical importance. If
>>> there was a single thing I'd like to see *DONE* in D, it would be
>>> temporary/r-value->ref args, without question (really, really annoying
>>> to work around).
>>>
>>
>> So what's wrong with this approach, that's already working today:
>>
>> class Foo
>> {
>> void foo ();
>>
>> void foo ()
>> {
>>
>> }
>> }
>>
>> void main ()
>> {
>> auto foo = new Foo;
>> foo.foo();
>> }
>>
>> BTW, this feature was implemented because you asked for it.
>>
>
> This is super useful to generate boilerplate from compile time reflection !
>

Which is what I requested it for, and use it very extensively.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Dicebot

On Monday, 9 September 2013 at 00:43:39 UTC, H. S. Teoh wrote:
Therefore, the *real* solution to this problem is to fix the 
compiler's
.di output to give a proper overview of the class 
*automatically*, and

nicely pretty-printed.


Yes, that should be superior approach in general though exact 
usability is very detail-specific - currently relation between 
.di and .d and not really well-defined and pulling this off will 
requires its own DIP at the very least.


For example, it is not entirely clear to me, what should happen 
if there are both .di and .d files in the file system at the same 
time and they have minor difference (remember, it is perfectly 
legal to tweak .di manually). It is likely, that improving .di 
tool chain will require similar signature matching verification 
anyway. Also I am wondering how to differ purely auto-generated 
.di files (should be updated completely upon build) and ones with 
manual changes (should be only verified).


It is all about small details.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Volcz
On Sunday, 8 September 2013 at 04:47:04 UTC, Jonathan M Davis 
wrote:

On Saturday, September 07, 2013 10:00:05 Walter Bright wrote:
Outlining of member functions is the practice of placing the 
declaration of
a member function in the struct/class/union, and placing the 
definition of

it at global scope in the module or even in another module.

http://wiki.dlang.org/DIP47


I confess that I really don't like this idea. I think that the 
separation of
declarations and definitions is a serious downside of C++ and 
that it
negatively impacts code maintenence. And from the recent 
discussion on this,

it's clear that quite a few people agree with me.

However, at the same time, there are some folks (like Manu) who 
really prefer
to separate the declaration and definitions so that they can 
just see the
signatures for an entire class' functions at once without 
seeing any
definitions. Personally, I don't think that that's a big deal 
and that it's far
better to just use generated documentation for that, but 
clearly there's not a

consensus on that.



- Jonathan M Davis


I completely agree with Jonathan!
This will only produce more code which will lead to more bugs and 
more maintenance.


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread sclytrack
On Saturday, 7 September 2013 at 17:00:08 UTC, Walter Bright 
wrote:
Outlining of member functions is the practice of placing the 
declaration of a member function in the struct/class/union, and 
placing the definition of it at global scope in the module or 
even in another module.


http://wiki.dlang.org/DIP47


---



unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, 
Dialogs, StdCtrls;


type

  { TForm1 }

  TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
  private
{ private declarations }
  public
{ public declarations }
procedure ChangeTitle(x:string);
procedure ChangeOtherTitle(x: string);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  ChangeTitle('test');
end;

procedure TForm1.ChangeTitle(x: string);
begin
   Memo1.Lines.Add(x);
end;

procedure TForm1.ChangeOtherTitle(x: string);
begin
   Memo1.Lines.Add(x);
end;

end.




Here is how it looks like in Lazarus.
In the class definition you type the declaration.

  public
{ public declarations }
procedure ChangeTitle(x:string);

Then you press "control shift c" this will create the empty 
implementation.
Use "control shift up" to cycle between the interface section and 
the implementation section.



There are two keywords "interface" and "implementation" to 
separate the two sections.


Honestly. There is not much typing going on.

If you go want to go the the next procedure in the implementation 
section it is faster to go "control shift up" back to the 
interface section. And then go to the next method and go back 
"control shift up" to the implentation section than to press the 
arrow down button until you are at the next method.



Lazarus does not accept changes in the name of the parameter.



Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread deadalnix

On Monday, 9 September 2013 at 07:00:23 UTC, Jacob Carlborg wrote:

On 2013-09-09 05:46, Manu wrote:

Missed the action...

Well it's clear this is not a popular proposal.
And even to me personally, it's certainly not of critical 
importance. If
there was a single thing I'd like to see *DONE* in D, it would 
be
temporary/r-value->ref args, without question (really, really 
annoying

to work around).


So what's wrong with this approach, that's already working 
today:


class Foo
{
void foo ();

void foo ()
{

}
}

void main ()
{
auto foo = new Foo;
foo.foo();
}

BTW, this feature was implemented because you asked for it.


This is super useful to generate boilerplate from compile time 
reflection !


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Jacob Carlborg

On 2013-09-07 19:00, Walter Bright wrote:

Outlining of member functions is the practice of placing the declaration
of a member function in the struct/class/union, and placing the
definition of it at global scope in the module or even in another module.

http://wiki.dlang.org/DIP47


What's wrong with the code below, that works today:

class Foo
{
void foo ();

void foo ()
{
writeln("Foo.foo");
}
}

void main ()
{
auto foo = new Foo;
foo.foo();
}

--
/Jacob Carlborg


Re: new DIP47: Outlining member functions of aggregates

2013-09-09 Thread Jacob Carlborg

On 2013-09-09 05:46, Manu wrote:

Missed the action...

Well it's clear this is not a popular proposal.
And even to me personally, it's certainly not of critical importance. If
there was a single thing I'd like to see *DONE* in D, it would be
temporary/r-value->ref args, without question (really, really annoying
to work around).


So what's wrong with this approach, that's already working today:

class Foo
{
void foo ();

void foo ()
{

}
}

void main ()
{
auto foo = new Foo;
foo.foo();
}

BTW, this feature was implemented because you asked for it.

--
/Jacob Carlborg


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Paolo Invernizzi

On Monday, 9 September 2013 at 04:00:39 UTC, Manu wrote:


Indeed. These opinions are my own, and I raised it on the merit 
of our
experience last weekend in a 48hour game-dev-jam with a few 
former

colleagues (including one who still works at Remedy).
This discussion has come up at remedy in the past, but I don't 
think this
is of particular significance to the remedy workflow; the 
modules were

small enough to not cause issues, at least not as I left it.

I believe the scenarios I describe are going to be very typical 
though, at
least in the game-dev context, particularly when larger volumes 
of D code
emerge. I've demonstrated this across 2 separate 48 hour 
game-jam's now,
which simulate the environment of a commercial crunch period 
quite

faithfully.


I don't believe that typical. We are working with some very big 
modules, and we have _no_ problems at all regarding that aspect.


I think that this is a swift for the discussion: discussing about 
an issue that it is present _today_ in a commercial user of the 
product, or a discussion about an a _potential_ problem.


The worst part of all this mess it is that the proposal ditches 
one of the *strong* selling point of D: no code duplication, use 
documentation if you want an overview.


I also strongly disagree that this way of coding is not typical: 
here at work we are using it without problems with D, and, again, 
DDocs are the right way.


I would also add that also here we have a lot of time pressures 
for the releases... as in every commercial software company I 
know of... ;-P


- Paolo Invernizzi


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread PauloPinto

On Monday, 9 September 2013 at 04:00:39 UTC, Manu wrote:
On 9 September 2013 05:46, Andrej Mitrovic 
wrote:



On 9/8/13, Jesse Phillips  wrote:
> I realize that we want to make it as painless as possible for
> Remedy to switch from C++ to D (along with the rest of the 
> game

> developers).

FWIW I don't think this has anything to do with Remedy (afaik 
Manu

doesn't work there anymore).



Indeed. These opinions are my own, and I raised it on the merit 
of our
experience last weekend in a 48hour game-dev-jam with a few 
former

colleagues (including one who still works at Remedy).
This discussion has come up at remedy in the past, but I don't 
think this
is of particular significance to the remedy workflow; the 
modules were

small enough to not cause issues, at least not as I left it.

I believe the scenarios I describe are going to be very typical 
though, at
least in the game-dev context, particularly when larger volumes 
of D code
emerge. I've demonstrated this across 2 separate 48 hour 
game-jam's now,
which simulate the environment of a commercial crunch period 
quite

faithfully.


Game developers embracing Erlang, C#, Java and ActionScript don't 
seem to have issues with that, as far as I can tell.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Ramon

Correction (3rd paragraph)

My personal view is that we should *not* make D a mixed pickles 
with

lots of "but C++ has that" and then some more gadgets thrown in
for good measure.

Sorry -R


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Ramon
Manu has pointed to some issue behind the obvious issue that will 
come up again and again unless it's settled once and for all.


Let's call it "To please everyone somewhat (and never really 
enough) - vs - to stick to a clear and well founded concept".


My personal view is that we should make D a mixed pickles with 
lots of "but C++ has that" and then some more gadgets thrown in 
for good measure.


The point that triggered me was "quick and dirty throw away 
code". Frankly, I don't care batshit about that. Don't get me 
wrong, Manus desire is doubtlessly valid and I wish him the best 
of luck to achieve maximum happyness. But I also see that comfort 
for "throw away code" has a strong tendency to run counter 
reliability.


There's a gazillion C++ compilers, pretty printers, analysers and 
other tools out there. And C++ has proven to be useful as a throw 
away code language - just look at mountains of throw away code 
out there (they won't call it that, of course).
And there is C#, $Basic, Perl (a perfect language to create 
trobletickets - or to not even care to), etc, etc.


The issue is not to please crowd A or crowd B. The issue is to 
make up ones mind and to establish a clear definition of what D 
is meant to be - and than to bloody stick to it.


D had "reliability" and "safety" written in quite big letters in 
it's PR. It's a *major* reason for (sure enough not only) me to 
be here. Comfort and some luxury is important, too, when you make 
your living using a tool, sure. But that's no contradiction. One 
can have both.


If I wanted to play a mixture of hide and seek and lottery I'd 
use C++ in the first place (and would have tools thrown at me).


In case I missed it, could someone kindly point me to a more or 
less binding priorities list of what D is meant to be and in what 
order of priorities. Maybe it's my fault and I just didn't see 
that list. But in case #1 on the list was "to please everyone and 
then glue some more gadgets to it" I wouldn't be here.


Thanks -R


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread FrogLegs
 This seems like a waste of time compared to the other complaints 
Manu brought up(bad IDE/debugger support etc.)


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread deadalnix

On Monday, 9 September 2013 at 03:46:23 UTC, Manu wrote:
For the record, I tend to agree with the arguments of many in 
the 'against'
camp *from a purist point of view*, but the problem remains, 
and the reason
I raised it; this has demonstrated to me and my colleagues on a 
number of

occasions that it is a consistent productivity hindrance.


I think that you guys being experienced C++ devs makes it worse. 
As a matter of fact, changing an habit is difficult.


I suspect your experience here was in fact a source f increased 
difficulty. Let me take an actual example. When you put a total 
newbie in front of a linux or OSX, they usually manage pretty 
well (considering they are newbies). Now take the average windows 
user and put it in front of a linux or an OSX, and you'll notice 
that they have tremendous difficulties to use them. Because 
everything they know, every expectation they have, get into their 
way.


Anyway, this outline, first, the need of better IDE support (but 
that isn't big news, I guess we all know that by now). Second 
some need of interface/implementation separation.


For that second, it has been discussed in the thread to improve 
the di behavior to fit that role. Do think this is a viable 
approach, and that your team of happy devs would have benefited 
from that ?


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Manu
On 9 September 2013 05:46, Andrej Mitrovic wrote:

> On 9/8/13, Jesse Phillips  wrote:
> > I realize that we want to make it as painless as possible for
> > Remedy to switch from C++ to D (along with the rest of the game
> > developers).
>
> FWIW I don't think this has anything to do with Remedy (afaik Manu
> doesn't work there anymore).
>

Indeed. These opinions are my own, and I raised it on the merit of our
experience last weekend in a 48hour game-dev-jam with a few former
colleagues (including one who still works at Remedy).
This discussion has come up at remedy in the past, but I don't think this
is of particular significance to the remedy workflow; the modules were
small enough to not cause issues, at least not as I left it.

I believe the scenarios I describe are going to be very typical though, at
least in the game-dev context, particularly when larger volumes of D code
emerge. I've demonstrated this across 2 separate 48 hour game-jam's now,
which simulate the environment of a commercial crunch period quite
faithfully.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Peter Williams

On 08/09/13 16:47, Walter Bright wrote:

On 9/7/2013 11:08 PM, Peter Williams wrote:

In summary, you've gotten rid of the need for this type of duplication
so why
would you introduce it?


I believe that is covered in the "Rationale" section of the dip.


Couldn't see a rational answer to my question in the rationale.

Looked more like a "I want to do this and I think that we should change 
the language syntax to allow it" statement to me.  It doesn't really add 
functionality just makes what's there more complex.


Peter


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Manu
Missed the action...

Well it's clear this is not a popular proposal.
And even to me personally, it's certainly not of critical importance. If
there was a single thing I'd like to see *DONE* in D, it would be
temporary/r-value->ref args, without question (really, really annoying to
work around).

For the record, I tend to agree with the arguments of many in the 'against'
camp *from a purist point of view*, but the problem remains, and the reason
I raised it; this has demonstrated to me and my colleagues on a number of
occasions that it is a consistent productivity hindrance.
I guess a significant reason my experience seems to differ from many(/most)
on this forum, is that they're not in the business of banging out quick
throw-away commercial code.
The practical reality in my experience in the games industry is this:
 - Some (perhaps small) percentage of code is tech/foundation code. It is
carefully authored, but still typically documented only of the class
outline in the header file isn't already self-explanatory (I'm a big fan of
self-documenting code). It is to be re-used.
 - Much (perhaps most) code is rudimentary logic and glue code, or 'game
code' as we call it. This tends to be code that is written by more
inexperienced programmers and written to tight schedules. It is almost
never documented (apart from the occasional inline comments), rarely
conforms to some spec (unless it's implementing from foundational
interface), and usually exists to serve only the life of this one very
specific project, ie, throw-away. It is also almost always logic-intensive
code, riddled with switch/if/else constructs that take an awful lot of
vertical space, which further magnifies the problem of inline function
definitions breaking up the readability of the class outline.

Now further, from an absolutely practical point of view, the time that
someone unfamiliar with this code has to deal with it in the first place is
very likely at 11pm the night before the publisher is demanding a build so
they can show it to a bunch of arseholes in fancy suits who will decide if
they're going to pay us or not.
In C++ there is a very useful tool for unfamiliar programmers to get a good
brief overview of the code before they go hacking at it, that is the class
outline.
We've lost that. And I have demonstrably missed it.

People make claims like "write better code, split it up better, document
your code better, use the IDE folding", blah blah, but it's simply not the
practical reality. The budget and schedule does not typically allow for
careful consideration, design, and documentation of such throw away code
which glues the project together.
The code is what it is, and whether it's written in C++, or D, or lua, it's
probably not going to change the nature of this huge volume of crappy code.
Code folding doesn't work in foreign editors, communication tools, diff
windows; code reviews become more time consuming to approve, and I don't
know many programmers that like/use it regardless, even if it may help in
some occasions.
I think it's bat-shit-crazy to rely on a tool to simply make code readable
and easy to understand for a start. I also personally feel code folding
alienates me from the code I'm writing. As an author, you quickly gain a
feel for the layout of your source file; the flow and shape of the code
across the file is kinda picturesque. For me personally, code folding ruins
that relationship with my code, and I don't like it. It makes it harder for
me to sweep through my file and quickly locate the points of interest that
I'm working through. So if I'm not using it in my own code, but I'm
required to use it to understand someone else's code... there's a bit of a
conflict of interest there.

If I'm one of very few voices in favour of class outlines, I'm going to
suggest letting this argument sleep until other more serious issues are
resolved which people have been waiting on for ages.
I certainly want r-values -> ref args to work much more.

Keep in mind, I raised this debate as a practical account of last weekend,
among a bunch of other issues which were certainly more significant than
this one, but this seemed to capture the most attention.
It's not the first time it's come up and it'll be back again I'm sure :)

I support this DIP, obviously, but I'd suggest perhaps a conservative
restriction that definitions should only be allowed to appear within the
same module as the declaration. This would seem to simplify things like
mangling issues and access rights. In my own use case, I have no reason to
spread definitions across files. I just want to see class outlines clearly
summarised at the top of the file. This saves time, and time is money.


On 8 September 2013 03:00, Walter Bright  wrote:

> Outlining of member functions is the practice of placing the declaration
> of a member function in the struct/class/union, and placing the definition
> of it at global scope in the module or even in another module.
>
> http://wiki.dlang.or

Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Meta

On Sunday, 8 September 2013 at 03:37:35 UTC, Walter Bright wrote:
On the other hand, DRY, and I don't recall anyone ever 
complaining about this in C++ outlined members.


Let me be the first, then, to formally lodge my complaint.

As for the DIP itself, I had enough of this tedium in C++. I 
would strongly prefer that it not be introduced in D. Working 
with Java/C#/D/any language with a decent module system, I've 
realized what a pain this "feature" is.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread H. S. Teoh
On Sun, Sep 08, 2013 at 02:53:10PM +0200, Dicebot wrote:
> On Sunday, 8 September 2013 at 12:46:49 UTC, Gary Willoughby wrote:
[...]
> >Seriously, this goes against everything you learn as a programmer,
> >nothing should ever be typed twice and then to say that the
> >declaration and implementation could be different just boggles my
> >mind?!?! Great more work!
> 
> It is no different from overriding `interface` methods in class.
> From the code structure point of view, declaration is interface.
> Implementation is implementation. Keeping those separate may
> sometimes/often be useful.
[...]

I agree that declaration is interface, and implementation is
implementation, and that it's good to separate them.  What I *don't*
agree with is that the interface should be *manually* maintained.  There
is absolutely no reason, in this day and age, that something so trivial
as extracting the interface *automatically* and *reliably* by the
compiler, can't be done.

Therefore, the *real* solution to this problem is to fix the compiler's
.di output to give a proper overview of the class *automatically*, and
nicely pretty-printed.  Manu has already said that the whole motivation
behind wanting this sort of interface/implementation separation was to
be able to tell what a class does at a glance. Well guess what? If we
clean up the current messy .di generation to produce something decent,
then all you have to do is to run dmd -H, and you have your at-a-glance
version of the class.  No unnecessary complication of the language, no
maintenance nightmare, no code duplication, very little implementation
effort, and 100% reliable because the .di file is generated straight
from the implementation, and therefore by definition is correct.

*This* is the correct solution to Manu's issue, IMO. DIP47 is
approaching it from a completely wrong angle. Please, let's not go back
to the C++ way. We've abandoned that a long time ago, and for good
reason. That bridge should've been burned already.


T

-- 
INTEL = Only half of "intelligence".


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Peter Williams

On 08/09/13 22:46, Gary Willoughby wrote:

On Saturday, 7 September 2013 at 17:00:08 UTC, Walter Bright wrote:

Outlining of member functions is the practice of placing the
declaration of a member function in the struct/class/union, and
placing the definition of it at global scope in the module or even in
another module.

http://wiki.dlang.org/DIP47


I'm absolutely against this DIP.

This proposal is just going back to the hell of header files again. Why
on earth would you emulate C/C++ when D was supposed to be designed
taking into account lessons learned from them. This is unnecessary
complexity added for the sake of a few programmers who can't get out of
C++ mode. I think you need to have a good hard think about *why* header
files were introduced into those early languages and then consider if
that reason is still valid. Personally i don't think it is. Java and C#
do just fine without this.

Seriously, this goes against everything you learn as a programmer,
nothing should ever be typed twice and then to say that the declaration
and implementation could be different just boggles my mind?!?! Great
more work!

If implemented, i will never used this feature and i will never deal
with code that uses it either. I choose D *purely* because it didn't
have this header file nonsense. If i find in future i start seeing more
and more of this style of D code i would just move on to use something
else that doesn't have all this extra baggage and work associated with
it. Just because Manu brings it up randomly you decide to create a DIP?

In reality this is a documentation issue. Which has already been
addressed by DDOC or *.di files. If data exists in one form, and it is
needed in another, that's work a computer should do. Not a human! IDE's
also give you numerous tools to get class overviews and such. If you are
suggesting that you also need these class overviews in code to be viewed
on github etc, just use comments. They are as arbitrary and simpler to
implement.

Honestly this DIP is going backwards, i was under the impression D was
going forwards! I am so disappointed.


Well said.

Peter



Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Andrei Alexandrescu

On 9/8/13 5:33 AM, Andrej Mitrovic wrote:

On 9/8/13, Michel Fortin  wrote:

So I'd like to suggest this: allow a .d file to "import" its corresponding
.di file.


This is actually what Andrei proposed as well.


I have to say I was a lot more in favor of the proposal before this thread.

The problem as I see it has two facets:

1. Code duplication

2. Modularity and logistics

Regarding (1), we currently force duplication of the entire class 
layout. My understanding is that this is the way it's done:


// file acme.di

class A {
  int x;
  double y;
  void fun();
}

// file acme.d
// cannot import acme.di
class A {
  int x;
  double y;
  void fun() { ... }
}

The fact that acme.d cannot import acme.di is an unforced error of 
embarrassing proportions and consequence. That should be fixed yesterday 
no matter how we proceed otherwise.


The problem with acme.d not having access to acme.di is that any error 
in duplicating the layout of A (e.g. swapping x and y or adding some 
other members etc) will have undefined behavior, and there is no 
reasonable way for the compiler to check against that.


Assuming that bug is fixed, the problem of duplication remains - all 
state of the class must be duplicated.


(I also suspect constructors might need to be white-boxed (i.e. 
available in the .di) for raw/cooked typechecking, but I'm not sure.)


If we go with DIP47, the duplication of state goes away. However we have 
a distinct problem - modularity, which segues into (2).


Allowing out-of-module implementations of individual methods poses 
additional modularity problems. Consider:


// file acme.di

class A {
  int x;
  double y;
  void fun();
}
private int a;
private void gun();

// file acme.d
// assume we solve the import problem
import acme;
void A.fun() { gun(); a = 42; }

If A.fun() were defined inside acme.di, it would have access to gun() 
and a. Defining it outside asks the question - do we allow such access, 
or not?


Intuitively the body of a method should not be all too sensitive to 
where it's placed, so that argues in favor of visibility.


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.



Andrei



Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread w0rp

I'm opposed to this DIP. It's aimed solely at aiding readability,
but having two ways to do something usually detracts from
readability. I don't see the point.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Andrej Mitrovic
On 9/8/13, Jesse Phillips  wrote:
> I realize that we want to make it as painless as possible for
> Remedy to switch from C++ to D (along with the rest of the game
> developers).

FWIW I don't think this has anything to do with Remedy (afaik Manu
doesn't work there anymore).


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Jesse Phillips
On Saturday, 7 September 2013 at 17:00:08 UTC, Walter Bright 
wrote:
Outlining of member functions is the practice of placing the 
declaration of a member function in the struct/class/union, and 
placing the definition of it at global scope in the module or 
even in another module.


http://wiki.dlang.org/DIP47


I am against this proposal. The rationale does not convince me we 
would be getting enough value out of solving this problem.


1. Converting C++ to D

This is the strongest argument. Maybe the issue identified here 
is solved with partial classes (see C#).


2. Having an outline of the code

DDOC already provides this! And any such limitations should be 
fixed. This point has several supporting points.


a. An IDE is not always available to fold code

I never do this, I hate code folding.

b. People read their code just as much in github commits, 
merge/diff windows, emails/chat, etc.


And? I could see some value having a summary for signature 
changes/additions when reviewing commits. For merges this 
proposal just adds one more line of conflict to deal with. 
Brining up emails would suggest that you want someone to write 
down their class signature; instead of having them go to that 
much work I'd rather ask them to generate the docs and email them 
to me. Chat, well I think that is a lost cause (I haven't had any 
code sent to me over chat that I had been glad to have received 
over chat)



I believe requiring the programmer to keep function prototypes in 
sync is a mistake. I also don't think having this be optional is 
addressing the issue of those that are for it.


When C/C++ programmers talk of the problems header files, they 
talk of the problems cause by textual replacements and compiled 
header files. When everyone who doesn't program in C/C++ talk of 
the problems of header files, they talk about the troubles of 
writing prototypes twice.


By providing this feature as an optional statement, you'll be 
left with Manu and his team using it, an no one else touching it 
(Sorry Manu, you're the only one I've seen with a strong 
conviction for it, I know others will use it too).


I realize that we want to make it as painless as possible for 
Remedy to switch from C++ to D (along with the rest of the game 
developers). I'm also really glad about the changes which have 
come from their use/insistence. However I think this is mostly a 
superficial change which will result in a divide in the community 
much like @property.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Simen Kjaeraas

On 2013-09-07, 19:00, Walter Bright wrote:

Outlining of member functions is the practice of placing the declaration  
of a member function in the struct/class/union, and placing the  
definition of it at global scope in the module or even in another module.


http://wiki.dlang.org/DIP47


I like the idea, but I feel the DIP is missing some info:

- What happens to UDAs? Do I need to declare them both places?
- Why no nested classes/structs?
- How do outlined ctors/dtors look?
- How does it look in practice? Is this how it works:

// foo.d:
module foo;
class Foo {
   int bar();
}

//foo_impl.d:
module foo;
import foo;
int Foo.bar() {
return 3;
}

- Do the module names have to be the same?
- Do I have to import the 'header' module in the implementation modules?
- If the module names don't have to be the same:
Can I implement the functions in any package? Sub-package? Only
the same package?


Also, I disagree with these points:

- Parameter names should match. I can accept nameless parameters in the
   declaration, but otherwise they should match. Anything else is an
   invitation for things to go out of sync.
- Default parameter values - either disallow them or enforce that they
   are the same in both places.
- Implementation in a module different from the declaration. .di files
   provide all the good stuff here, without sending you on a wild goose
   chase through all your files for that one function your resident
   junior programmer hid away inside the implementation of a completely
   different class.


Lastly, I want more examples - is this the same for structs and classes?
Interfaces? Can I spread the function definitions over several modules?

All in all, I would currently vote against.


As an aside, I do like the idea of having a nice list of member
functions that is statically compared to those actually implemented.
This could however be done in different ways. My favorite would be
something along these lines:

class Foo {
interface {
 float bar(int n) const;
 Foo clone();
 static int qux(); // Compile-time error on this line: declared
   //  function with no implementation.
}
float bar(int n) const {
return 0.0;
}
Foo clone() {
return this;
}
static int baz() { // Compile-time error on this line: undeclared
   //  function with implementation.
return 2;
}
}

For the sake of fueling discussion, I have created a DIP with this  
suggestion:

http://wiki.dlang.org/DIP48

--
  Simen


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Simen Kjaeraas

On 2013-09-08, 12:46, Tove wrote:

Wouldn't this style be an acceptable compromise instead? with both  
declaration and definition 100% identical.


struct S
{
   // member function declarations
   static int mfunc1(int a, int b = 5) pure;
   static int mfunc2(int a, int b = 5) pure;
   static int mfunc3(int a, int b = 5) pure;

   // member function definitions
   static int mfunc1(int a, int b = 5) pure
   {
   }
   static int mfunc2(int a, int b = 5) pure
   {
   }
   static int mfunc3(int a, int b = 5) pure
   {
   }
}


The problem here is the compiler does not enforce that all
definitions are present in the declaration list. Apart from that, I
feel this is the correct solution to the problem.

--
  Simen


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Ettienne Gilbert
On Sunday, 8 September 2013 at 13:00:11 UTC, Dmitry Olshansky 
wrote:

08-Sep-2013 16:02, Michel Fortin пишет:

[Snip]


Example:

// test.di
module test;

class A {
void foo(int a, int b);
}

// test.d
import module test; // import declarations from the .di 
file


void A.foo(int a, int b) {
// member function definition
}



With this suggestion it finally becomes sane.


+1


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Dicebot

On Sunday, 8 September 2013 at 15:14:51 UTC, deadalnix wrote:
On Sunday, 8 September 2013 at 12:34:06 UTC, Andrej Mitrovic 
wrote:

On 9/8/13, Michel Fortin  wrote:
So I'd like to suggest this: allow a .d file to "import" its 
corresponding

.di file.


This is actually what Andrei proposed as well.


+42


That is why I had a feeling I have already seen it somewhere :)


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Dicebot
On Sunday, 8 September 2013 at 15:09:31 UTC, Gary Willoughby 
wrote:
This is a job for the *documentation* and if documentation is 
automatically generated (which it is, see '-D') then this 
argument is moot.


Documentation is tool to help with cross-project learning. I have 
never seen one used internally inside the same project. It simply 
does not work that way, not even close in convenience to matching 
source organization. Takes more time, uses different information 
representation other than plain code, is not applicable in some 
contexts (i.e. git log).


Built-in IDE tools are generally better for that but, as I have 
already said, I am not aware of a single one that does it 
conveniently enough.


Except when dealing with books, tutorials, third party 
libraries, pull requests, etc...


That applies to any other possible feature that may or may not 
exist in D. What I do mean though is that you shouldn't care how 
third-party library is organized - for you it remains same import 
statement and documentation investigation that requires to change 
nothing in your code flow even if third-party library uses this 
feature and you do not.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread deadalnix
On Sunday, 8 September 2013 at 12:34:06 UTC, Andrej Mitrovic 
wrote:

On 9/8/13, Michel Fortin  wrote:
So I'd like to suggest this: allow a .d file to "import" its 
corresponding

.di file.


This is actually what Andrei proposed as well.


+42


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Gary Willoughby
I have never worked on any reasonably large Java/C# code base. 
But it C++ once amount of entities grows large enough clear 
interface overview in header files is basically only way to get 
familiar quickly with sources.


This is a job for the *documentation* and if documentation is 
automatically generated (which it is, see '-D') then this 
argument is moot.


I don't think it will matter at all. As it was mentioned, usage 
of such feature tends to be private business of certain project 
- it won't propagate to yours  if you don't use it.


Except when dealing with books, tutorials, third party libraries, 
pull requests, etc...


I dismay.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread QAston
On Sunday, 8 September 2013 at 12:46:49 UTC, Gary Willoughby 
wrote:

I'm absolutely against this DIP.

This proposal is just going back to the hell of header files 
again. Why on earth would you emulate C/C++ when D was supposed 
to be designed taking into account lessons learned from them. 
This is unnecessary complexity added for the sake of a few 
programmers who can't get out of C++ mode. I think you need to 
have a good hard think about *why* header files were introduced 
into those early languages and then consider if that reason is 
still valid. Personally i don't think it is. Java and C# do 
just fine without this.


Seriously, this goes against everything you learn as a 
programmer, nothing should ever be typed twice and then to say 
that the declaration and implementation could be different just 
boggles my mind?!?! Great more work!


If implemented, i will never used this feature and i will never 
deal with code that uses it either. I choose D *purely* because 
it didn't have this header file nonsense. If i find in future i 
start seeing more and more of this style of D code i would just 
move on to use something else that doesn't have all this extra 
baggage and work associated with it. Just because Manu brings 
it up randomly you decide to create a DIP?


In reality this is a documentation issue. Which has already 
been addressed by DDOC or *.di files. If data exists in one 
form, and it is needed in another, that's work a computer 
should do. Not a human! IDE's also give you numerous tools to 
get class overviews and such. If you are suggesting that you 
also need these class overviews in code to be viewed on github 
etc, just use comments. They are as arbitrary and simpler to 
implement.


Honestly this DIP is going backwards, i was under the 
impression D was going forwards! I am so disappointed.


I totally agree (stating this just in case number of votes 
matters).


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Dicebot
On Sunday, 8 September 2013 at 13:11:01 UTC, Gary Willoughby 
wrote:
That said, I am strongly against permissive rules proposed in 
this DIP. It should be similar to overriding rules - any 
smallest difference between to signatures and program stops 
compiling. Otherwise it is maintenance hell.


Well you've just argued against your first paragraph there. The 
issue is (as you recognise) the extra complexity introduced 
with having a declaration and an implementation both of which 
could be different and/or not clear how they relate.


Not really. Issue is cognitive load of matching definition and 
declaration if they are allowed to be out of sync.


But it goes further than that. If this DIP is implemented and 
you are working with code written like this you now have to 
change the code in two places when you want to update a method. 
Also you now have to find the implementation or declaration 
which is a total pain when not using an IDE.


I consider it a minor inconvenience for a certain structural gain.

This is entirely different to how overloading works because in 
that scenario you are explicitly saying in your code this 
method overrides the parent (or interface) with this one that 
matches that signature exactly. There is no duplication, it's 
explicit overriding which is different.


overloading != overriding. I am speaking about overriding. From 
the maintenance point of view this two snippets are identical:

---
interface A
{
void foo();
}

class A_prim : A
{
void foo() { }
}
---
class A
{
void foo();
}

void A.foo()
{
}
---

Same amount of duplication, same amount of information available 
for compiler verification.


Also could you give me any examples of where keeping the 
declaration separate to the implementation is "sometimes/often 
useful". Because IMHO it only adds work and Java and C# do just 
fine.


I have never worked on any reasonably large Java/C# code base. 
But it C++ once amount of entities grows large enough clear 
interface overview in header files is basically only way to get 
familiar quickly with sources.


As I have already said it is good for same reasons interfaces are 
good - easier to abstract away information you shouldn't be aware 
of when working in large teams.


I don't think Walter realises how much of a plus point it is 
for D to not have this 'feature'. I mean if this was 
implemented and code started appearing written in this style 
(as it will) why would people choose D over C++ to get stuff 
done when they both offer the same headaches now?


I don't think it will matter at all. As it was mentioned, usage 
of such feature tends to be private business of certain project - 
it won't propagate to yours  if you don't use it.


And you really underestimate issues of C++ that force programmers 
to seek other languages. Separation of definition and declaration 
won't probably be even in top 50.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Paulo Pinto

Am 08.09.2013 15:11, schrieb Gary Willoughby:

On Sunday, 8 September 2013 at 12:53:11 UTC, Dicebot wrote:

Seriously, this goes against everything you learn as a programmer,
nothing should ever be typed twice and then to say that the
declaration and implementation could be different just boggles my
mind?!?! Great more work!


It is no different from overriding `interface` methods in class. From
the code structure point of view, declaration is interface.
Implementation is implementation. Keeping those separate may
sometimes/often be useful.

That said, I am strongly against permissive rules proposed in this
DIP. It should be similar to overriding rules - any smallest
difference between to signatures and program stops compiling.
Otherwise it is maintenance hell.


Well you've just argued against your first paragraph there. The issue is
(as you recognise) the extra complexity introduced with having a
declaration and an implementation both of which could be different
and/or not clear how they relate. But it goes further than that. If this
DIP is implemented and you are working with code written like this you
now have to change the code in two places when you want to update a
method. Also you now have to find the implementation or declaration
which is a total pain when not using an IDE. You now have more files.
Longer compilation times. All for what? Not using -D on the command
line? Come on!

This is entirely different to how overloading works because in that
scenario you are explicitly saying in your code this method overrides
the parent (or interface) with this one that matches that signature
exactly. There is no duplication, it's explicit overriding which is
different.

Also could you give me any examples of where keeping the declaration
separate to the implementation is "sometimes/often useful". Because IMHO
it only adds work and Java and C# do just fine.

I don't think Walter realises how much of a plus point it is for D to
not have this 'feature'. I mean if this was implemented and code started
appearing written in this style (as it will) why would people choose D
over C++ to get stuff done when they both offer the same headaches now?


Not only Java and C#, but any other language with module support, even 
the ones that have native compilers by default.


The ones that offer interface definitions, like Delphi, Modula-{2,3}, ML 
family among many others, have a model that D already offers via the .di 
files.


So I also agree this is a step backwards.

--
Paulo


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Gary Willoughby

On Sunday, 8 September 2013 at 12:53:11 UTC, Dicebot wrote:
Seriously, this goes against everything you learn as a 
programmer, nothing should ever be typed twice and then to say 
that the declaration and implementation could be different 
just boggles my mind?!?! Great more work!


It is no different from overriding `interface` methods in 
class. From the code structure point of view, declaration is 
interface. Implementation is implementation. Keeping those 
separate may sometimes/often be useful.


That said, I am strongly against permissive rules proposed in 
this DIP. It should be similar to overriding rules - any 
smallest difference between to signatures and program stops 
compiling. Otherwise it is maintenance hell.


Well you've just argued against your first paragraph there. The 
issue is (as you recognise) the extra complexity introduced with 
having a declaration and an implementation both of which could be 
different and/or not clear how they relate. But it goes further 
than that. If this DIP is implemented and you are working with 
code written like this you now have to change the code in two 
places when you want to update a method. Also you now have to 
find the implementation or declaration which is a total pain when 
not using an IDE. You now have more files. Longer compilation 
times. All for what? Not using -D on the command line? Come on!


This is entirely different to how overloading works because in 
that scenario you are explicitly saying in your code this method 
overrides the parent (or interface) with this one that matches 
that signature exactly. There is no duplication, it's explicit 
overriding which is different.


Also could you give me any examples of where keeping the 
declaration separate to the implementation is "sometimes/often 
useful". Because IMHO it only adds work and Java and C# do just 
fine.


I don't think Walter realises how much of a plus point it is for 
D to not have this 'feature'. I mean if this was implemented and 
code started appearing written in this style (as it will) why 
would people choose D over C++ to get stuff done when they both 
offer the same headaches now?


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Dmitry Olshansky

08-Sep-2013 16:02, Michel Fortin пишет:

On 2013-09-07 17:00:05 +, Walter Bright 
said:


Outlining of member functions is the practice of placing the
declaration of a member function in the struct/class/union, and
placing the definition of it at global scope in the module or even in
another module.

http://wiki.dlang.org/DIP47


About placing the definition in another module, you say that the
definition when outlined in another module would have private access to
the private members of the module of declaration. Does that mean that
the definition has access to the private members of two modules at the
same time, the one it is declared in and the one it is defined in? That
seems strange to me.


Same here. This was the ugliest point.

[snip]


I'd like to make a suggestion. If one goal is effectively to allow the
implementation of a function to live in a separate file from its
declaration, then we already have a mechanism for that: .di files. So
I'd like to suggest this: allow a .d file to "import" its corresponding
.di file. Then the .d file should only contain the missing definitions
for what's declared in the hand-crafted .di file. That'd remove the
dubious semantics of making the definition part of another module and
would also allow outlining of global functions. And it also matches
better the C++ model of header/implementation files.



Also, I'd allow outlining only for this specific case where a .di file
is imported by a .d file. This way you know for sure when you see a
declaration without the definition in a .di file that this declaration
is in the corresponding .d file and not anywhere else, making it easier
to hunt it down.

Example:

 // test.di
 module test;

 class A {
 void foo(int a, int b);
 }

 // test.d
 import module test; // import declarations from the .di file

 void A.foo(int a, int b) {
 // member function definition
 }



With this suggestion it finally becomes sane.

--
Dmitry Olshansky


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Dicebot
P.S. In general I'd love to have feature feature proposed in 
DIP47  but its importance is very, _very_ low, right now it is 
probably the least important DIP in the whole list.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Dicebot
On Sunday, 8 September 2013 at 12:46:49 UTC, Gary Willoughby 
wrote:
This proposal is just going back to the hell of header files 
again.


It has nothing to do with header files. Or real header file 
problems.


Seriously, this goes against everything you learn as a 
programmer, nothing should ever be typed twice and then to say 
that the declaration and implementation could be different just 
boggles my mind?!?! Great more work!


It is no different from overriding `interface` methods in class. 
From the code structure point of view, declaration is interface. 
Implementation is implementation. Keeping those separate may 
sometimes/often be useful.


That said, I am strongly against permissive rules proposed in 
this DIP. It should be similar to overriding rules - any smallest 
difference between to signatures and program stops compiling. 
Otherwise it is maintenance hell.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Gary Willoughby
On Saturday, 7 September 2013 at 17:00:08 UTC, Walter Bright 
wrote:
Outlining of member functions is the practice of placing the 
declaration of a member function in the struct/class/union, and 
placing the definition of it at global scope in the module or 
even in another module.


http://wiki.dlang.org/DIP47


I'm absolutely against this DIP.

This proposal is just going back to the hell of header files 
again. Why on earth would you emulate C/C++ when D was supposed 
to be designed taking into account lessons learned from them. 
This is unnecessary complexity added for the sake of a few 
programmers who can't get out of C++ mode. I think you need to 
have a good hard think about *why* header files were introduced 
into those early languages and then consider if that reason is 
still valid. Personally i don't think it is. Java and C# do just 
fine without this.


Seriously, this goes against everything you learn as a 
programmer, nothing should ever be typed twice and then to say 
that the declaration and implementation could be different just 
boggles my mind?!?! Great more work!


If implemented, i will never used this feature and i will never 
deal with code that uses it either. I choose D *purely* because 
it didn't have this header file nonsense. If i find in future i 
start seeing more and more of this style of D code i would just 
move on to use something else that doesn't have all this extra 
baggage and work associated with it. Just because Manu brings it 
up randomly you decide to create a DIP?


In reality this is a documentation issue. Which has already been 
addressed by DDOC or *.di files. If data exists in one form, and 
it is needed in another, that's work a computer should do. Not a 
human! IDE's also give you numerous tools to get class overviews 
and such. If you are suggesting that you also need these class 
overviews in code to be viewed on github etc, just use comments. 
They are as arbitrary and simpler to implement.


Honestly this DIP is going backwards, i was under the impression 
D was going forwards! I am so disappointed.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Andrej Mitrovic
On 9/8/13, Michel Fortin  wrote:
> So I'd like to suggest this: allow a .d file to "import" its corresponding
> .di file.

This is actually what Andrei proposed as well.


Re: new DIP47: Outlining member functions of aggregates

2013-09-08 Thread Michel Fortin

On 2013-09-07 17:00:05 +, Walter Bright  said:

Outlining of member functions is the practice of placing the 
declaration of a member function in the struct/class/union, and placing 
the definition of it at global scope in the module or even in another 
module.


http://wiki.dlang.org/DIP47


About placing the definition in another module, you say that the 
definition when outlined in another module would have private access to 
the private members of the module of declaration. Does that mean that 
the definition has access to the private members of two modules at the 
same time, the one it is declared in and the one it is defined in? That 
seems strange to me.


I find it strange that pure/const/immutable/shared/nothrow need to 
match, yet static does not. Beside this being the way it works in C++ 
(presumably because static at global scope has another meaning 
inherited from C), I see no reason for this. In C++ I often find myself 
wondering whether a function has access to the member variables and I 
have to find the definition in the header file, which is inconvenient. 
Static being part of the definition seems to only make sense.


About parameter names, I think it'd be better if they were forced to 
match. Mismatches are a code smell to me: if you reverse the meaning of 
two parameters with the same type while refactoring, you must be sure 
the public interface and the implementation still agree. I guess you 
could allow the declaration to omit the parameter names in which case 
the definition could add a name, but don't allow *different* names, 
it's pointless and it can easily hide a bug.


I think it's fine that default values for parameters don't have to be 
repeated, but it'd be nice if they *could* because it enables 
copy-pasting of the declarations. The compiler would of course have to 
check that both expressions are identical.


I'd like to make a suggestion. If one goal is effectively to allow the 
implementation of a function to live in a separate file from its 
declaration, then we already have a mechanism for that: .di files. So 
I'd like to suggest this: allow a .d file to "import" its corresponding 
.di file. Then the .d file should only contain the missing definitions 
for what's declared in the hand-crafted .di file. That'd remove the 
dubious semantics of making the definition part of another module and 
would also allow outlining of global functions. And it also matches 
better the C++ model of header/implementation files.


Also, I'd allow outlining only for this specific case where a .di file 
is imported by a .d file. This way you know for sure when you see a 
declaration without the definition in a .di file that this declaration 
is in the corresponding .d file and not anywhere else, making it easier 
to hunt it down.


Example:

// test.di
module test;

class A {
void foo(int a, int b);
}

// test.d
import module test; // import declarations from the .di file

void A.foo(int a, int b) {
// member function definition
}

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



  1   2   >