[swift-evolution] [Discussion] Static methods as global functions

Haravikk swift-evolution at haravikk.me
Fri Mar 10 05:18:25 CST 2017

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170310/f153ec91/attachment.html>

More information about the swift-evolution mailing list