I agree, we are derailing the thread. I only mentioned it because people were talking about solutions for '... == false'. I'll create a new topic and we'll see whether there is any support for this.
Let's bring the discussion back to adding a toggle() function to Bool. I totally support this and 'toggle' as name seems fine to me.
nested inside a Bool extension, but Swift doesn't allow words as operators
Why not?
If that was possible one could define a prefix operator "not" for example, used like so:
if not isHere { ...}
You could use a public function:
public func not(_ b: Bool) -> Bool
{
return !b
}
(assuming here btw that the swift optimizer makes this inline as just b = !b)
then it looks much clearer like so:
var isHere = not(isAway)
if not(isHere)
{
print("He's not here.")
}
Recommended:
I always use the "is" prefix for booleans like
isAway, isIndexLoaded, isAscending etc
I never, never, never use isNotHere, isNotThinking,isNotPlaying,
for obvious reasons.
One might ask why not have keywords for boolean operators?
like "not" "and" "or" "xor"
then it's a lot more readable like so:
if not (isLoading or isWaitingForConnection) and isUserConnected {...}
Ok, forgot about that, it's been some time.
So this operator restriction: (re)defining or language keyword implementing:
using words as operators,
is here, just because the current compiler
isn't smart enough (yet) to handle this.
right?
(it's a pity AND OR and NOT have been available in older languages
like Pascal and Cobol
Fortran uses .and. .or. , .not. (between dots)
I was almost starting a new topic asking to implement operator definition
with words, never mind... :o|
TedvG
Personally I'd prefer not to implement those boolean operators as functions
but as real -or custom defined- operators, but alas, that's not possible...
If using @autoclosure for the sake of performance improvement,
You can just as well omit this for these trivial functions.
I think the performance gain would be neglectable
because I am pretty sure the compiler will replace the complete not(...) function
with an in-line "b = !b", right?
OK, you're right.
I think .toggle() is nice, but one of the virtues of Swift is that one can use extensions, which I'd guess most of us have done already for .toggle() and a myriad of other "language improvements" ?
Regards
I think there may be a larger issue at play here, which manifests itself when toggling Booleans: the inability to concisely refer to the LHS of an assignment on the RHS. If Swift had a keyword like “lhs” or “itself” or something of that nature, then you could write some.reallyLong.expression = !itself. This has the advantage of working in other cases besides toggling a Boolean, such as someNum = itself * itself
It's not a matter of "the current compiler isn’t smart enough (yet) to handle this." You're criticizing before thinking about it.
The compiler could be made to allow operator and identifier characters to overlap. The compiler isn't the isuee. The issue is that the compiler isn't the only program that has to parse Swift code. Text editors, linters, websites' code highlighting, etc. all would need to be built with the ability to parse all dependencies to learn about what operators are available, so as to determine which identifiers are operators, and which are just identifiers. That will never happen.
On the other hand, you could take the Python approach of hard coding a fixed set of reserved words. That makes the tooling support easy, but isn't flexible.
Can we please keep the conversation on topic? We can branch out for other discussions, as they're useful in their own right. Or maybe a moderator can close the topic, as the replies don't seem to focus on the proposal.
I'lll spawn a new "compiler vs. user" topic.
Concerning this topic:
imho these(like toggle()) are just syntactic sugar that can be
implemented using class/struct extension if a user desires it.
but that's me.
After further thought I think there is one area that hasn't been mentioned yet where toggle and toggled would be incredibly useful: optional booleans. Currently, if x is a Bool?, then !x is not allowed. However, x?. toggle[d]() would be allowed. This would allow the following:
var x: Bool? = true
x?.toggle()
if x?.toggled() ?? false {}
Currently you must do the following to allow use of ! with optionals:
var x: Bool? = true
if let y = x { x = !y }
// the next two lines are valid ways to return an inverted copy
if x.map({ !$0 }) ?? false {}
if let y = x, !y {} // Should we really need a whole new variable here?
The first code block is much nicer than the second.
Have you thought about using a non-mutating toggled().
Also, have you thought about returning the toggled() value for more one-lined mutations with the @discardableResult property?