So the topic of global functions like min/max came up on the thread about 
adding a standard clamp method, and it got me to thinking whether there was a 
better way to define most global methods.

Currently for example there are two global functions min and max; very useful, 
and don't make much sense as instance methods, but they're not as easily 
discoverable as a static method declared under relevant type(s). We could get 
around this by defining such functions both as a static method, and as a global 
function, but it means duplicate code and by convention only.

An alternative is to remove the need for duplicate methods using a new global 
keyword for a method declaration, telling Swift to define it as both a static 
method and a global function. This allows the function to be grouped logically 
under a type, making it a bit neater, but without losing the benefit of the 
global definition. For example:

        protocol Comparable {
                global func min(_ a:Self, _ b:Self) -> Self { return a < b ? a 
: b }
                global func max(_ a:Self, _ b:Self) -> Self { return a > b ? a 
: b }
        }

With this single definition both of the following are now valid:

        let min = Int.min(1, 3)
        let max = max(5, 10)

In the second case, Swift looks at all global definitions for "max" in order to 
locate the best match, leading it to Int.max.

It's a relatively small change, but helps with neatness. It may also be good 
for consistency if we ever get the ability to define operators within types 
(though I'm not sure where we are with that?), as they could potentially just 
use the same format like-so:

        struct MyType : Equatable {
                global func == (_ a:MyType, _ b:MyType) -> Bool { /* Determine 
equality */ }
        }

I just think it's a neater way to do this than currently requiring separate 
declarations for the static and global versions, especially since one usually 
just calls the other anyway, anyone have any thoughts?

I normally argue against new keywords, but in this case it may be justified, as 
I considered an attribute but it would only end up requiring static anyway, so 
it seemed neater to just have a new category "above" static that is both static 
and global, since a global non-static doesn't make any sense. However, one 
advantage of a @global attribute is that it could potentially take a different 
name for the global function, so I could (but probably wouldn't) define 
something like:

        @global("min") static func smallerOfTwo(_ a:Self, _ b:Self) -> Self { 
return a < b ? a : b }

So here, although the method name is smallerOfTwo, it is exposed globally as 
"min". Though I don't know much need there would be for something like that.
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to