Sure. Option A, the one I recommend, is that function types do not have labels. The type of fn removeAll(&mut self, equalTo value: T)
and the type of fn append(&mut self, _ value: T)
are both fn(&mut Self, T)
.
Option B is to keep the labels in the type, giving you fn(&mut Self, equalTo: T)
and fn(&mut Self, T)
. From my perspective, this has a few problems:
-
The labels donāt necessarily make sense without the base name, and when youāre using function pointers (or function traits), youāve got more than one possible value, with no guarantee they have the same labels. Heck, while Iāve never seen functions actually named add(to: Set<T>)
and remove(from: Set<T>)
, surely they should have the same type!
-
If labels are part of the type systemā¦are two different function types compatible? Can removeAll(equalTo:)
be passed to a parameter of type fn(&mut Self, T)
? Probably! But what about fn(&mut Self, value: T)
? Is this a new implicit conversion? Can you change fn(x: f64, y: f64)
to fn(y: f64, x: f64)
?
-
What happens when you put fn(value: isize)
into dyn Any
? Can you get it out as fn(isize)
? As fn(offset: isize)
?
-
Putting the labels in the type undermines the user model of āthese functions have different namesā. (I guess this only matters if you have name-based overloading, which Iām willing to call it. Iāve got some thoughts on Python-style labels without overloading but Iām still working them out.)
Now, there is a downside of Option A too: sometimes function pointers really would benefit from labels. But those labels go with the name of the function pointer argument, not what gets passed to it. We had the idea in Swift that
fn for_each(
&self,
apply process: impl FnMut(key: K, value: V)
) {
// Yes, this is inefficient, donāt worry about it.
for k in self.keys() {
process(key: k, value: self[k])
}
}
would be sugar for something like
fn for_each(
&self,
apply process(key:value:): impl FnMut(K, V)
) {
for k in self.keys() {
process(key: k, value: self[k])
}
}
but never got around to implementing it. (Still could some day, though; we left space for it.) Itās not strictly necessary, and since there are always functions without labels itās not out-of-place or anything.
So yeah, donāt go with Option B.