4 ms·
I really wish Swift closures were more uniform. I remember Alan Kay (or maybe Dan Ingalls) was famed for saying “its ok to cheat, as long as you don’t get caugh
by travisgriggs 8y ago
I really wish Swift closures were more uniform. I remember Alan Kay (or maybe Dan Ingalls) was famed for saying “its ok to cheat, as long as you don’t get caught” (re. Language implementation).
I really like swift, but there are times when I feel I need a magic decoder to figure out which edge cases apply. My biggest frustration is that something like this
for view in self.subviews { view in
...
return something
}
Is very different from the naively similiar
self.subviews.forEach { view in
...
return something
}
I just wish closures were a more first class part of the language like they were in Smalltalk. If language written in 1980 could use closures/lambdas all the way down even for things like if/else, and keep the deception pretty complete, I don’t understand why swift can’t do similiar.
- delinka 8y agoI don't understand your syntax on the for-in. Is there some magic on an array that takes a closure and is nonobvious? Or is there a syntactic issue with the code in your comment?
- Groxx 8y agotho I'm not familiar with swift: my guess here is that the first (for ... in) shares a closure / var, so stuff like this classic JS mistake can happen: for i=0;i<10;i++ { setTimeout(() => console.log(i), 100); } and you get 10 calls logging "9". (most languages I've touched do this, JS just makes it worse since `var x` in the loop will not fix it) The second won't do that, since the "view" var isn't "mutated" between calls.
- aplummer 8y agoA good try from a JS perspective however: 1) view is immutable in both cases 2) GGP is returning in a void block so both sets of code will fail 3) there is really no difference except iteration vs function calls as far as I can tell, you can iterate arrays and use higher order functions built into arrays... which seems normal 4) you can only access the index in (1) by calling .enumerated() I suppose.
- throw_away2 8y agoI think the difference OP is pointing out is that the return behaves differently. In the forEach, the return exits the closure, but in for-in, it returns from the enclosing function.
- travisgriggs 8y agoyes, this
- delinka 8y agoFirst, to make arguments that rely on syntax, one must use correct syntax. If OP’s syntax were valid, that return in the for-in would indeed exit the closure. To address this argument: the fact that a ‘return’ within a loop exits the enclosing function and a return from within a closure exits the closure is not a Swift problem.
- ken 8y agoAs of Swift 4, it's not valid syntax. I don't see any Swift 5 proposals that would make it valid. Maybe it's just a mistake?
- SebastianFrelle 8y agoThe trailing closure syntax [1] seems to be a point of pride with Swift. However, I feel that it’s grown to be a painful aspect of the language. Another example is when a function takes two closure arguments, e.g.: func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) It is perfectly valid to call this function using a trailing closure for the latter argument, i.e. animate(withDuration: 0.5, animations: { ... }) { // handle completion here } rendering the `completion` parameter label obsolete and giving no clear visual indication that the trailing closure is a completion handler. Again, I strongly dislike the visual similarity to control flow statements. [1]: https://www.natashatherobot.com/swift-trailing-closure-syntax/ https://www.natashatherobot.com/swift-trailing-closure-synta...
- HNLogInShit 8y agoLearn to line up your braces vertically, and you’ll be fine.
- slavapestov 8y ago> I just wish closures were a more first class part of the language like they were in Smalltalk. Functions are first class types and values in Swift. Both named functions and anonymous functions can be used as values and can capture values from outer scopes. What’s not first class? > If language written in 1980 could use closures/lambdas all the way down even for things like if/else, and keep the deception pretty complete, I don’t understand why swift can’t do similiar. Smalltalk’s approach of using higher order functions for all control structures is more uniform in some ways but is not inherently superior. Swift has statements that perform non-local control transfer (break, continue, return) and designing those to work with closures (presumably only non-escaping closures) would be tricky. Also Swift ‘if’ and ‘switch’ statements can perform pattern matching and bind variables in various complex ways, so again it’s not clear if completely unifying all this with anonymous closure syntax would produce something that is simpler overall than just special casing conditionals and loops in the statement syntax.