I could imagine something like it, being used under
some circumstances, but I should maybe have come up
with a better example. I'm just trying to demonstrate
a principle here.
The infix operator seems interesting. Could you show
how it would be used in the example I provided?
Thanks Tino, but I only want to set someInt to 10 if someInt
already has a value. If someInt was initially set to nil, then
someInt will remain nil. Maybe I should have explained this.
If you're not willing to introduce a new variable name at all, then no, it's not currently possible to achieve both goals at the same time.
If you're willing to split the difference, though, and use an anonymous closure parameter name, then as noted a ways up-thread, the operation you're looking for already exists as flatMap(_:):
Although I never encountered this syntax before, it's quite an obscure feature.
I wonder though what exactly is the problem here? As written it is totally fine with me (when it is in other people code, see 1). Introducing prettifiers like "someInt.isNil" or "someInt.isNotNil" or "Bool(someInt)" doesn't buy you much, and if it does – you can create such an extension and use it throughout your code base (1).
(1) I do something along these lines in my code base having custom "a <> b" and "a.not" operators (I just don't like explanation marks and also prefer negation to be postfix)).
I've seen it and forgotten that it was the reason I wrote that operator above, to achieve consistency with the other side of the assignment operators.
var none: Int? = nil
none?=1 // nil
var zero: Int? = 0
zero=?none // 0
You just can't use enclosing spaces (none ?= 1) because ?= is not an operator.
Looking at it this time, I thought at first this was a bug with optional chaining in that maybe an operator that returned Void was required…
someInt? %= 2 // compiles
someInt?.quotientAndRemainder(dividingBy: 2) // compiles
someInt? % 2 // Value of optional type 'Int?' must be unwrapped to a value of type 'Int'
…but no. There's more specific magic at work. You can only recreate the behavior with what's noted in the next post. Return type doesn't matter.
I’ve been thinking a lot about custom operators. When I code, I follow a number of conventions (as do we all) with the goal of producing unsurprising code, I.e. code that does what it appears to do. And, I’m in the crowd that thinks + is a great glyph for concatenation, and strX - strY looks like nonsense.
If a new coder comes to look at your code, new operators really need to be super obvious. This is why I made a custom operator to convert CGFloats to Double, and then removed it and extended Double with a function to give me a cgfloat instead. The operator failed to convey what it did.
One of the worst abuses of obviousness is the use of < and >. Like most everyone, I learned that < means less than, and > is greater than. ‘->’ is a little weird, but the arrow makes sense pretty quickly. cout << “foo” is gross if you see << as meaning left shift.
HTML makes me cross.
Foobar<T> makes me grind my teeth. I thank what deities might approach that Swift avoids the absurd levels of use of that construction that C++ has.
To me the Swifty way to check for a nil optional is
if foo != nil {}
It’s what I’ve been doing since Optionals were introduced. Sure it’s a tiny bit more typing. But it’s blindingly obvious what it does.
Off-topic, but this is making me wish Swift had a built-in null assignment operator (??= in some languages). Far more useful than this obscure non-null assignment, which as you mentioned earlier you're having a hard time imagining a use case for. Is there documentation on this anywhere?
Yeah, I did see that. That was prior to its popularisation in other languages (including C#, Javascript, and PHP), so I'm hopeful it may be reconsidered one day :)
I was wondering if there was documentation on the existing someInt? = 10 feature though?
personally i don't think Swift .map or .flatMap act as kotlin "let". Kotlin "let" doesn't iterate over an array for what i know. If you are looking for something more like kotlin let maybe that fit: