[swift-evolution] [Proposal Draft] Concise Default Values for Containers

T.J. Usiyan griotspeak at gmail.com
Sat Jan 16 19:28:49 CST 2016


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


More information about the swift-evolution mailing list