UFCS for D

Steven Schveighoffer schveiguy at yahoo.com
Thu Mar 29 21:35:50 PDT 2012


On Friday, 30 March 2012 at 01:55:23 UTC, Nick Sabalausky wrote:
> "Steven Schveighoffer" <schveiguy at yahoo.com> wrote in message
> news:op.wbyg2ywyeav7ka at localhost.localdomain...
>>
>> For builtin types (such as arrays or numbers), there wouldn't 
>> be a module that the type was defined.  However, object.di is 
>> imported by everything, so extensions could be put in there.
>>
>
> Wait, What? Weren't you strongly *opposed* to this last week 
> when I
> suggested it for empty()?

Yes.  My assertion is that you have either the module defining 
the template import the module that defines the UFCS function 
(which in this case, std.range imports std.array), or have the 
module that defines the type import it.  Since range operations 
are not intrinsic to slices, and are a phobos-defined thing, 
including them in object.di I don't think is appropriate.  You 
may think differently.

In the case of .empty, I still contend that as long as we don't 
have a general definition of .empty being "the true way to check 
for zero length/elements/whatever," it doesn't belong as an 
intrinsic for arrays.  std.array defines empty so slices can be 
used in range functions, which would inevitably import 
std.range/std.array.  I think you are using .empty() in a 
generalized non-range fashion, and that is fine.  But we haven't 
defined .empty in that way, only in terms of ranges.  I know this 
may seem nit-picky to you, but I think it is important that we 
*don't* put arbitrary pieces of phobos into druntime because it 
seems convenient.  There should be a good compelling reason.

> I'm not trying to be an ass about it. Just not sure if you 
> changed your
> mind, or I'm missing something, or what.

I understand.  I'm trying to play the role of advocating for 
existing code.  Not because I think it's better, but because I 
think we should have a high bar to cross in order to make deep 
changes like this.  Adding things to object.di should not be a 
trivial matter.

I also happen to think if(array) and if(!array) should be 
directly tied to length instead of pointer (this was a big design 
mistake IMHO).  This would put us in the awkward situation of 
aliasing a very builtin feature of arrays as a property, 
seemingly for no reason in hindsight.

>> One  misleading suggestion from the article however, it's not 
>> very easy to create non-friend non-member functions using 
>> UFCS, considering that every function in a given module is a 
>> friend.  In order to do this, you would need a helper module 
>> for each module that wants to define such non-friend 
>> functions.  Given the above proof, the helper module would 
>> also have to be imported by the main module.
>>
>
> Yea, that occurred to me, too. <wishful musing>I've been 
> starting to think
> more and more that the "everything in a module is a friend" was 
> a mistake,
> and that we should have instead just had a "module" access 
> specifier like we
> have "package".</wishful musing>

I don't think it was a mistake, it makes perfect sense to me.  On 
the other hand, I fully understand why Meyers' prescription is 
useful for humongous code bases.  However, I don't see this 
causing much trouble for code I write.

For instance, you have two classes you may have put into the same 
module because they are categorically related (not necessarily 
friends in C++ terms).  It's highly unlikely that you 
"accidentally" access private information across the classes.  So 
how much time is "wasted" checking the other class for external 
references?  Probably none.

-Steve


More information about the Digitalmars-d-announce mailing list