3 ms·
Used objc a bit; never used swift. Question about this signature: func drop(while predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Self.SubSe
by dilap 10y ago
Used objc a bit; never used swift. Question about this signature:
func drop(while predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Self.SubSequence
I take it the "throws" on the type of predicate means it can 'throw/return' an error. Why would you do this? Why not just require your predicate function to be able to process any element?
Or I am confused?
It seems like the equivalent in Go, for example, would be something like this
func drop(seq []T, while func(T) (bool, error)) ([]T, error)
which, again, seems like madness.
Or am I confused?
- mayoff 10y agoFirst, why not allow your predicate to throw? Maybe your program will be better structured that way. Second, if you pass a predicate that is not declared `throws`, then the compiler treats `drop(while:)` as if it cannot throw either. This is what `rethrows` means: it makes `drop(while:)` covariant (in terms of throws-ness) with `predicate`.
- slavapestov 10y agoWith 'drop' passing a throwing predicate feels a bit esoteric, but consider something like 'map'. Suppose you are mapping over an array of file names and loading each one, which can throw. You would expect the 'map' itself to throw if processing one of the elements throws. You can write higher order functions that only take total functions as arguments and handle errors with an 'Either' type, which is more general but creates boilerplate. Also 'rethrows' is a special keyword that means if you pass in a function that does not throw, the overall operation won't throw either. So mapping over an array of integers to increment each one won't require error handling, since the operation itself cannot fail.
- dilap 10y agoAh, OK, interesting. Thanks for the response.
- Someone 10y ago"So mapping over an array of integers to increment each one won't require error handling, since the operation itself cannot fail." Nitpick: in Swift, "since the operation itself cannot fail" isn't correct. The operation will fail on overflow, but it will terminate your application rather than throw.
- astrange 10y agoThose are called "universal errors" and it's not very useful to reason about them. You could prove your program correct, use a total-function programming language, but it still could fail to complete - the power could go out halfway through execution.
- deleted 10y ago[deleted]
- thought_alarm 10y agoThe key is the `rethrows` keyword, which allows the compiler to conditionally enforce error handling based on the signature of the given closure. The equivalent Go code would then (presumably) be these two methods: func drop(seq []T, while func(T) (bool)) ([]T) func dropWithError(seq []T, while func(T) (bool, error)) ([]T, error) If you pass in a closure that throws (i.e., can return an error) then the compiler will require try/catch error handling at the `drop()` method call site. If you pass in a closure that does not throw then compiler will assume that `drop()` does not throw.
- fauigerzigerk 10y ago>Why not just require your predicate function to be able to process any element? Because the predicate would then have to swallow any exceptions thrown downstream. What would it return in that case? True or false?
- masklinn 10y ago> I take it the "throws" on the type of predicate means it can 'throw/return' an error. Why would you do this? Why not just require your predicate function to be able to process any element? Because otherwise you can't use partial functions as predicates which is an unnecessary an oft annoying limitation, in my experience it's one of the biggest pains in the ass in Java and a major reason why its checked exceptions system was unusable: you couldn't create "transparent" functions (and interfaces) with respect to CE. > It seems like the equivalent in Go, for example, would be something like this `rethrows` is a transitive property, if the predicate is not a throwing function, the HoF isn't one either. So you'd need two functions in Go. And then `drop` works on a more abstract concept than concrete array slices ("Sequence" is what many other languages would call an iterable).