[swift-evolution] [Pitch] Option parameters (potential resilience advantages)

Félix Cloutier felixcca at yahoo.ca
Mon Dec 28 13:08:27 CST 2015


The current workaround is to add an overload that calls the "main" version:

> class Foo {
> 	// version 1
> 	func foo() {
> 		print(5)
> 	}
> 	
> 	// version 2
> 	func foo() {
> 		foo(5)
> 	}
> 	
> 	func foo(value: Int) {
> 		print(value)
> 	}
> }


How would you say that your solution compares?

Félix

> Le 28 déc. 2015 à 11:11:57, Matthew Johnson via swift-evolution <swift-evolution at swift.org> a écrit :
> 
> I've had an idea floating around in my mind for a couple weeks now and would like to find out what others think about it.
> 
> The basic idea is really simple.  It introduces an `@option` parameter attribute.  Parameters with this attribute would behave like parameters with a default value at the call site, however they would not actually have a default value.  Instead, the argument seen in the body would be an optional of the type of the parameter value.
> 
> func foo(@option value: Int) {
> 	// value has type Int? in the body of the function
> 	let valueToUse = value ?? 42
> }
> 
> At first glance it probably seems like this is of no value.  Why not just declare `value: Int? = nil`.  Obviously it must bring something to the table to be worth considering.
> 
> This idea first occurred to me while thinking about flexible memberwise initialization.  One of the use cases I have had in mind while writing that proposal is a theoretical Swift version of UIKit that exposes all of its appearance properties as memberwise initialization parameters with defaults rather than just initializing the members to a default value.  Obviously this could lead to a very large stack frame that isn't really necessary.  Using the `@option` approach we can avoid the unnecessarily large stack frame.
> 
> Instead of always passing a value for every parameter the compiler would use a single dynamic data structure containing the values of all `@option` arguments provided at the call site.  The layout of the data structure would be an implementation detail of the language and would be part of the ABI.  It would contain a header of some kind indicating which parameters were actually provided with arguments at the call site and any additional information necessary to recover the value.  In the body of the function, references to the parameter value would be replaced with a lookup into the data structure which returned an optional value of the type of the parameter.
> 
> Perhaps the most interesting thing about `@option` is that careful design of the implementation might allow for `@option` parameters to be added or removed from a function without breaking ABI compatibility:
> 
> 1. When new parameters are added, existing callers will simply never provide arguments and the implementation will see a nil optional value.  
> 2. When parameters are removed, existing clients will continue to provide them and the data structure will still be populated with them.  The implmentation will simply never look for the value.  The function will behave as if the parameter was still specified in the signature and simply not used.  The client would receive a compiler warning when compiling agains the newer SDK but everything would continue to work without issue until they did so.
> 
> If this is possible `@option` parameters would enable more robust evolution for functions containing parameters that may be omitted or have default values.
> 
> Another benefit of `@option` is that it provides better encapsulation of default values because they do not appear in function and method signatures.  My understanding of the planned mechanism for default arguments is that any changes to default parameter values will not be visible to clients until they recompile against the new version of the library.  If this is the case `@option` would also provide additional control to library authors who may wish to modify the default behavior of their implementation without breaking ABI.
> 
> Lastly, but potentially useful benefit of `@option` is that default argument values do not allow a function to distinguish between the case when a caller explicitly provides a value that happens to be the same as the default and the case when no argument was provided.  `@option` provides this information to the body of the function.
> 
> Finally, an interesting observation: changing a parameter from having a default value to `@option` or vice versa would break ABI but would be source-compatible.
> 
> I am very interested to hear whether others think this idea is worth pursuing further or not.
> 
> Matthew
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list