Swift 5.0 and Swift 5.1, 112 bytes
func f(_ x:Any)->Double{let y=x as!Double
return y*y}
func f<T>(_ x:T)->Double{return(x as!Double).squareRoot()}
SwiftFiddle link
Swift 5.1 changed overload resolution for functions with unlabelled arguments, so f(_:)
resolves as the square function in Swift 5.0 and as the square root in Swift 5.1. The permissive argument types are required for this to work; if you don't pass it a double, this will compile but crash at runtime.
The lack of argument labels is required: if you remove the underscores to make this f(x:)
, it will print the square root in both versions.
Swift 4 and Swift 5, 125 113 bytes
import Foundation
func s(x:Double)->Double{return pow(x,Double("\(try?{()throws->Int?in 0}())".count)*0.15-1.15)}
SwiftFiddle link
The function s(x:)
computes the square in Swift 4 and the square root in Swift 5.
The original answer had the throwing function on its own line, rather than being an inline IIFE.
This was harder than I expected.
The try?
operator is one of three legal prefixes for a call to a throwing function -- the others being try
and try!
. try
requires a catch
, try!
promotes errors to fatal errors, and try?
ignores errors and returns nil
instead. For example, consider the following code snippet:
func foo() throws -> Int {
// ...
}
let bar = try? foo()
The type of bar
is now Optional<Int>
, since it might be nil
.
What if foo()
already returns Optional<Int>
? In Swift 5, the optionals are flattened, and bar
is still Optional<Int>
. In Swift 4, this is not the case, and bar
is now Optional<Optional<Int>>
.
When you convert an optional value to a string, it wraps it in "Optional("...")"
. So, the following code:
func foo() throws -> Int? {
return 0
}
print("\(try? foo())")
Prints Optional(0)
in Swift 5 and Optional(Optional(0))
in Swift 4. (If you don't wrap it in the string interpolation, it fails to compile. I have no idea why.)
From there, I use .count
to get the length of the string, and do some simple arithmetic to get 2.0
in Swift 4 and 0.5
in Swift 5.
Swift 4 and Swift 5, cheating, 85 bytes
func s(x:Double)->Double{#if swift(>=5)
return x.squareRoot()#else
return x*x#endif
}
I shouldn't have to explain this.