www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - UFCS with implicit "this" ?

reply cy <dlang verge.info.tm> writes:
I really like UFCS, which is to say, defining functions outside 
the class/struct to operate on it, but you can still say 
object.function(...) and it'll get rewritten into 
function(object,...).

Only sticky point is the convenience of "this". Like I can go

struct A {
	bool a;
	bool b;
	bool c;
	bool d;
	bool foo() {
		return a && b || c && !d;
	}
}

But if I try do do the same thing with "bool bar(A object)" I end 
up with this:

bool bar(A object) {
	return object.a && object.b || object.c && !object.d;
}

My example is a bit contrived, but it occurred to me how neat it 
would be if we could just specify "implicit" objects in our 
current scope. Like I was messing with an RGB and an HSL object, 
and I ended up having things like:

hsl.saturation = (max(rgb.r,rgb.g,rgb.b) - 
min(rgb.r,rgb.g,rgb.b)) / (2 - max(rgb.r,rgb.g,rgb.b) - 
min(rgb.r,rgb.g.rgb.b))

when I wanted something more like this:

saturation = (max(r,g,b) - min(r,g,b)) / (2 - max(r,g,b) - 
min(r,g,b)

Is there any way to do that in D? They don't let you use "alias 
this rgb" for a function scope, only a type's scope, so I guess 
it isn't possible?

I mean, aside from making an inner structure to the function, and 
copying the object by value... that's even more confusing than 
worth the convenience.
Aug 08 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, August 09, 2016 05:13:44 cy via Digitalmars-d-learn wrote:
 I really like UFCS, which is to say, defining functions outside
 the class/struct to operate on it, but you can still say
 object.function(...) and it'll get rewritten into
 function(object,...).

 Only sticky point is the convenience of "this". Like I can go

 struct A {
   bool a;
   bool b;
   bool c;
   bool d;
   bool foo() {
       return a && b || c && !d;
   }
 }

 But if I try do do the same thing with "bool bar(A object)" I end
 up with this:

 bool bar(A object) {
   return object.a && object.b || object.c && !object.d;
 }

 My example is a bit contrived, but it occurred to me how neat it
 would be if we could just specify "implicit" objects in our
 current scope.
Personally, I think that you should just make it a member function if it's not a generic function, but to each their own, I suppose. Regardless, there's already a feature to do what you're looking for - with statements. e.g. bool bar(A object) { with(object) return a && b || c && !d; } https://dlang.org/spec/statement.html#WithStatement - Jonathan M Davis
Aug 08 2016
parent cy <dlang verge.info.tm> writes:
On Tuesday, 9 August 2016 at 05:33:09 UTC, Jonathan M Davis wrote:
 Personally, I think that you should just make it a member 
 function if it's not a generic function, but to each their own,
Well, I use generics for when I have like, optional functionality that isn't inherent to the class itself. Since I avoid using wildcard imports, I won't import any generics I don't specify by name, when I import the class itself. It's good for extending or adding informal things on the side, bells and whistles basically. Sometimes it can be useful for third party structures. Or combinations of existing member functions, in ways that only have limited applicability (like a calculation for graphics, that the database backend won't care about).
     with(object)
         return a && b || c && !d;
And... the feature already exists, I just didn't know about it. Thanks!
Aug 09 2016