Again, to answer your specific question (the one in the title):
If we agreed that the particular initializer in question should take an optional argument, ie this:
Int.init?(_ description: String)
should be changed to:
Int.init?(_ description: String?)
Then, by the same logic, and in order to keep things consistent, it would of course follow that the same change should be made to all the corresponding failing initializers for Int8
, Int16
, Int32
, Int64
, UInt8
, UInt16
, UInt32
, UInt64
, Float
, Double
and Float80
.
And also for all failing and/or throwing initializers in the Standard Library, like String(contentsOf: URL)
⇒ String(contentsOf: URL?)
, and I guess something like a hundred others.
This is unreasonable, not only because of the number of APIs involved, but because there's no reason why those API should assume that their arguments are optional rather than non-optional in the common case.
Looking at it from this perspective, you have a specific use case / problem, for which there are existing solutions (like unwrapping earlier, or using Optional.flatMap, etc). The solution you are suggesting / asking about, however, would imply the above (kind of huge) change to the Standard Library's API and design philosophy.
You'd like to be able to write:
let port = Int(Environment.get("DATABASE_PORT")) ?? 3306
You can write this today:
let port = Environment.get("DATABASE_PORT").flatMap(Int.init) ?? 3306
Note that the semantics of this (as well as the one you'd want to be able to write) is such that you'll get for example this:
String? : Environment.get("DATABASE_PORT") | Int : port
----------------------------------------------+---------------------
nil | 3306
"9223372036854775807" | 9223372036854775807
"-9223372036854775808" | -9223372036854775808
"blah" | 3306
Which might or might not be what you want. This is another reason for why optional return values should often be dealt with immediately and thoughtfully rather than just kept and passed around.