[swift-evolution] [Proposal Draft] Concise Default Values for Containers
Ricardo Parada
rparada at mac.com
Mon Jan 18 12:39:20 CST 2016
I am not sure I would be in favor of additional syntax for something like this. I think that those who want it could write extensions for Array and Dictionary and do the following instead:
let value = array.objectAtIndex(i, default: defaultValue)
let value = dict.objectForKey(key, default: defaultValue)
> On Jan 16, 2016, at 8:28 PM, T.J. Usiyan via swift-evolution <swift-evolution at swift.org> wrote:
>
> I think that both of these are new types or, at the very least, protocols. If you are ok with using something other than subscript to access them, a protocol is actually the best bet, in my opinion. With these additions, Array acts as though it has *infinite* length and Dictionary acts as though it holds all members that inhabit the Dictionary.Key type. That is significant difference in behavior.
> TJ
>
>> On Sat, Jan 16, 2016 at 8:16 PM, Maximilian Hünenberger <swift-evolution at swift.org> wrote:
>> While I like the idea of a default value I don't think that you need one as often.
>>
>>
>> On another thread ("Optional safe subscripting for arrays") something similar is being discussed where
>>
>> array[safe: 6]
>>
>> returns Optionals and your proposal is very similar to
>>
>> array[safe: 6] ?? defaultValue
>> // or probably rewriting this to
>> array[6, default: defaultValue]
>>
>> So these two proposals/threads could be merged.
>>
>>
>> In case of (Python like) slices I'm not sure whether the additional syntax pays off for its use.
>>
>>
>> Do you have any concrete plan how it could be implemented? As additional property/closure/DefaultProtocol?
>> I'm in favor of a closure: () -> Element
>> since it is like a generator where less weird behaviors can occur due to referencing classes. (Value types would work (almost) flawlessly with a stored property)
>>
>>
>> Another note: Could there be a more general way to use "_" as a language feature? So the proposal would be more likely to be accepted.
>>
>>
>> Best regards
>> - Maximilian
>>
>>> Am 17.01.2016 um 00:37 schrieb Paul Ossenbruggen via swift-evolution <swift-evolution at swift.org>:
>>>
>>> This is a preliminary draft, looking for feedback, thanks.
>>>
>>> Introduction
>>>
>>> There are many cases where you don’t want to deal with an out of range lookup in a array or dictionary. There is quite a lot of boilerplate code to check the range and return a value. This proposal addresses that by making a concise way of providing a default value in an array or dictionary. You quickly and safely want to get the value from an array or dictionary but not have to write a bunch of checks.
>>>
>>> Swift-evolution thread: derived from ternary discussion.
>>>
>>> Motivation
>>>
>>> There are many times when you want to map value to another, the range of input values is beyond the array index. Typically you have to write code like this;
>>>
>>> let dayString = [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”]
>>> guard dayIndex > 0 && dayIndex < col..count else {
>>> return “invalid day"
>>> }
>>> dayString[dayIndex]
>>>
>>> Or for a dictionary:
>>>
>>> let chineseNumber = [ “一” : “One”,
>>> “二” : ”Two”,
>>> “三” : ”Three”]
>>>
>>> guard let englishString = englishString else {
>>> return “out of range"
>>> }
>>> return englishString
>>>
>>> Currently dictionaries only produce “nil” if not found so you must handle an optional.
>>>
>>> Proposed solution:
>>>
>>> There approach is to add default to the containers.
>>>
>>> Array:
>>> There is a new syntax which, allows you to choose a default:
>>>
>>> let lookupDayOfWeek = [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday” <> “Invalid Day” ]
>>>
>>> lookupDayOfWeek[1] -> “Monday”
>>> lookupDayOfWeek[9] -> “Invalid Day”
>>>
>>> The <> which is less than greater than. for the else portion, it indicates outside the range of the array as in less than the minimum index and greater than the highest index. It also looks like a diamond when run together so it stands out to clearly show that it is the default case and won’t be confused with the main array. In all other ways the array behaves the same, if you want to get the default value you could do this:
>>>
>>> lookupDayOfWeek[ _ ] -> “Invalid Day”
>>>
>>> Iterating an array with a default would not include the default:
>>>
>>> for day in lookupDayOfWeek {
>>> print(“Day \(day)”)
>>> }
>>>
>>> You would need to do this to get the default (see below for slices):
>>>
>>> for day in lookupDayOfWeek[:_] {
>>> print(“Day \(day)”)
>>> }
>>>
>>> or this would put the default first:
>>>
>>> for day in lookupDayOfWeek[_:] {
>>> print(“Day \(day)”)
>>> }
>>>
>>> Unless there is a better suggestion for this, as this relies on slices.
>>>
>>> Likewise contains() and other operations would not include the default as a result. However, if you were to copy an array with a default it would travel with the array:
>>>
>>> let myOtherArray = lookupDayOfWeek
>>> print(myOtherArray[_]) -> “Invalid Day”
>>>
>>> If we were to adopt slices it would be possible to copy just the main values like this (based upon python slice syntax, speculative because slice syntax is not yet defined. If it is;):
>>>
>>> let myOtherArray = lookupDayOfWeek[:]
>>> print(myOtherArray) -> [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”]
>>>
>>> let myOtherArray = lookupDayOfWeek[:_]
>>> print(myOtherArray -> [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday” <> "Invalid Day”]
>>>
>>> Dictionary:
>>> For a dictionary, we use the _: to indicate none of the above, which is consistent with current dictionary syntax except that it adds the _ case..
>>>
>>> let chineseToEnglishNumber = [ “一" : “One”,
>>> “二": ”Two”,
>>> "三": ”Three”,
>>> _: “Out of Range” ]
>>>
>>> print(chineseToEnglishNumber[ “三”]) -> “Three"
>>> print(chineseToEnglishNumber[“四”]) -> “Out of Range”
>>>
>>> This concisely represents what to do if none of the values are usable. No more if let clauses or guards. Diamond <> could be supported here too, but that is optional for this proposal. The dictionary would be handled pretty much as it is today but the underscore-colon lets you give a default. Similarly, you can access the default value by doing this.
>>>
>>> print(chineseToEnglishNumber[_]) -> “Out of Range”
>>>
>>> print(chineseToEnglishNumber.contains(“None”)) -> would return false.
>>> print(chineseToEnglishNumber) -> ["一": "2", "二": "1", "三": “3” <> “ Out of Range”]
>>>
>>> Copying the dictionary would include the default but iterating it would not include the default:
>>>
>>> for number in chineseToEnglishNumber {
>>>
>>> }
>>>
>>> to include it (this may need work):
>>>
>>> for number in chineseToEnglishNumber[:_] {
>>>
>>> }
>>>
>>> since dictionaries are unordered it will not necessarily be at the end..
>>>
>>> Alternatives considered
>>>
>>> Other operators:
>>> Tried single colon and double colon but did not stand out enough and colon might not work if we adopted slices.
>>>
>>> Sets
>>> Thought about sets but not sure that makes sense because you only test existence of a member usually, the following kind makes sense to a point:
>>>
>>> let set = Set(“A”, “B”, “C” <> “D”)
>>> set.contains(“B”) -> true
>>> set.contains(“D”) -> false
>>> set.contains(“F”) -> false
>>>
>>> print(set) -> [“A”, “B”, “C”]
>>>
>>> but typically you are just checking for existence or getting all values so having it return a default does not make sense.
>>>
>>> Map
>>> This came out of the ternary and switch discussions, this could be done with map defaults. If we don’t want to add it to the container types that might be a better way to go. See that thread for more details.
>>>
>>>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160118/c1b45588/attachment.html>
More information about the swift-evolution
mailing list