September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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? |
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Nowak | 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.
|
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ettienne Gilbert | 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. |
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
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).
|
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | 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.
|
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ettienne Gilbert | 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 |
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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 |
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Rushton Wakeling | 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 |
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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.digitalmars-d@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. |
September 10, 2013 Re: new DIP47: Outlining member functions of aggregates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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.
|
Copyright © 1999-2021 by the D Language Foundation