Mike_Kluev
(Mike Kluev)
1
Because, ideally, I’d love to be able to do:
infix operator and: LogicalConjunctionPrecedence // or whatever the
precedence is called
func and(lhs: Bool, rhs: Bool) → Bool { return lhs && rhs }
let truthyValue = true and false
+1 (i like your thinking, even if it is unlikely to happen in swift)
(noteworthy, your example used "RIGHTWARDS ARROW" (U+2192) instead of ->,
whether on purpose or not.)
speaking of &&, was it just a copy-paste from C or is there a more
fundamental reason to use that instead of &? in C they had to use two
different operators because of the implicit int <-> bool promotions, but in
swift "true & false" vs "1 & 2" would have been distinguishable.
Mike
···
on Tue, 3 Oct 2017 11:00:33 -0600 Dave DeLong <swift@davedelong.com> wrote:
The difference between the & and && operators isn't to do with the implicit conversions; it's to do with whether both sides of the expression are evaluated or not.
false && system('rm -rf')
You really don't want to do that if both sides are executed ...
Alex
···
On 4 Oct 2017, at 11:42, Mike Kluev via swift-evolution <swift-evolution@swift.org> wrote:
on Tue, 3 Oct 2017 11:00:33 -0600 Dave DeLong <swift@davedelong.com <mailto:swift@davedelong.com>> > wrote:
> Because, ideally, I’d love to be able to do:
>
> infix operator and: LogicalConjunctionPrecedence // or whatever the precedence is called
> func and(lhs: Bool, rhs: Bool) → Bool { return lhs && rhs }
>
> let truthyValue = true and false
+1 (i like your thinking, even if it is unlikely to happen in swift)
(noteworthy, your example used "RIGHTWARDS ARROW" (U+2192) instead of ->, whether on purpose or not.)
speaking of &&, was it just a copy-paste from C or is there a more fundamental reason to use that instead of &? in C they had to use two different operators because of the implicit int <-> bool promotions, but in swift "true & false" vs "1 & 2" would have been distinguishable.
davedelong
(Dave DeLong)
3
> Because, ideally, I’d love to be able to do:
>
> infix operator and: LogicalConjunctionPrecedence // or whatever the precedence is called
> func and(lhs: Bool, rhs: Bool) → Bool { return lhs && rhs }
>
> let truthyValue = true and false
+1 (i like your thinking, even if it is unlikely to happen in swift)
(noteworthy, your example used "RIGHTWARDS ARROW" (U+2192) instead of ->, whether on purpose or not.)
Heh, right. That was unintentional. I have system text replacements set up to turn ->, =>, <->, etc in to their Unicode arrow versions: →, ⇒, ↔︎
And using words (and even phrases like “is not”) as operators is totally possible. It would just require the parser to have a known list of all operators, and then greedily match characters as long as there’s an operator that’s prefixed by the current token, and then backtrack when it fails.
I implemented this style of operator definition and parsing in my open source math parsing library: GitHub - davedelong/DDMathParser: String → Number
Dave
···
On Oct 4, 2017, at 6:41 AM, Alex Blewitt via swift-evolution <swift-evolution@swift.org> wrote:
On 4 Oct 2017, at 11:42, Mike Kluev via swift-evolution <swift-evolution@swift.org> wrote:
on Tue, 3 Oct 2017 11:00:33 -0600 Dave DeLong <swift@davedelong.com> >> wrote:
speaking of &&, was it just a copy-paste from C or is there a more fundamental reason to use that instead of &? in C they had to use two different operators because of the implicit int <-> bool promotions, but in swift "true & false" vs "1 & 2" would have been distinguishable.
The difference between the & and && operators isn't to do with the implicit conversions; it's to do with whether both sides of the expression are evaluated or not.
false && system('rm -rf')
You really don't want to do that if both sides are executed ...
Alex
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
Mike_Kluev
(Mike Kluev)
4
true. however what would stop the hypothetical "logical &" operator to not
evaluate the right hand side if the left
side is false similar to how && behaves? yes, it would make it more
different to the "bitwise &" operator, but they are
already a bit different.
(it was always backwards to me even in C: bitwise *single* & is for and-ing
*multiple* bit pairs, whilst a
*multi-character* && is for and-ing a single bool pair.)
Mike
···
On 4 October 2017 at 13:41, Alex Blewitt <alblue@apple.com> wrote:
On 4 Oct 2017, at 11:42, Mike Kluev via swift-evolution < > swift-evolution@swift.org> wrote:
speaking of &&, was it just a copy-paste from C or is there a more
fundamental reason to use that instead of &? in C they had to use two
different operators because of the implicit int <-> bool promotions, but in
swift "true & false" vs "1 & 2" would have been distinguishable.
The difference between the & and && operators isn't to do with the
implicit conversions; it's to do with whether both sides of the expression
are evaluated or not.
false && system('rm -rf')
You really don't want to do that if both sides are executed ...
actually, thanks for bringing this up as it leads up to a question:
how in swift do i define my &&& operator (that i may need for whatever
reason, e.g. logging) that will short-circuit
the calculation of right hand side if the left hand side is false?
infix operator &&&: LogicalConjunctionPrecedence
func &&&(left: Bool, right: Bool) -> Bool {
return left && right
}
as written it doesn't short-circuit. is it possible at all in swift?
Mike
···
On 4 October 2017 at 13:41, Alex Blewitt <alblue@apple.com> wrote:
The difference between the & and && operators isn't to do with the
implicit conversions; it's to do with whether both sides of the expression
are evaluated or not.
false && system('rm -rf')
You really don't want to do that if both sides are executed ...
speaking of &&, was it just a copy-paste from C or is there a more fundamental reason to use that instead of &? in C they had to use two different operators because of the implicit int <-> bool promotions, but in swift "true & false" vs "1 & 2" would have been distinguishable.
The difference between the & and && operators isn't to do with the implicit conversions; it's to do with whether both sides of the expression are evaluated or not.
false && system('rm -rf')
You really don't want to do that if both sides are executed ...
true. however what would stop the hypothetical "logical &" operator to not evaluate the right hand side if the left
side is false similar to how && behaves? yes, it would make it more different to the "bitwise &" operator, but they are
already a bit different.
Whether you are dealing with boolean/int types and whether you short-circuit the operators are orthogonal concerns.
(it was always backwards to me even in C: bitwise *single* & is for and-ing *multiple* bit pairs, whilst a
*multi-character* && is for and-ing a single bool pair.)
The && (c.f. ||) is explicitly for short-circuiting and is nothing to do with bit pairs or booleans, by specification.
See e.g. section 6.5.13 and 6.5.14.
Alex
···
On 4 Oct 2017, at 13:55, Mike Kluev <mike.kluev@gmail.com> wrote:
On 4 October 2017 at 13:41, Alex Blewitt <alblue@apple.com <mailto:alblue@apple.com>> wrote:
On 4 Oct 2017, at 11:42, Mike Kluev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
When you call the function, the arguments will be evaluated prior to the function body - so this won't work (as you correctly noted).
However, you can wrap the second argument in an @autoclosure, which means it replaces the body of the expression with a function that evaluates the expression automatically:
infix operator &&&: LogicalConjunctionPrecedence
func &&&(left: Bool, right: @autoclosure () -> Bool) -> Bool {
return left && right()
}
func no() -> Bool {
print("no")
return false
}
func yes() -> Bool {
print("yes")
return true
}
print(no() &&& yes())
no
false
Alex
···
On 4 Oct 2017, at 14:12, Mike Kluev <mike.kluev@gmail.com> wrote:
On 4 October 2017 at 13:41, Alex Blewitt <alblue@apple.com <mailto:alblue@apple.com>> wrote:
The difference between the & and && operators isn't to do with the implicit conversions; it's to do with whether both sides of the expression are evaluated or not.
false && system('rm -rf')
You really don't want to do that if both sides are executed ...
actually, thanks for bringing this up as it leads up to a question:
how in swift do i define my &&& operator (that i may need for whatever reason, e.g. logging) that will short-circuit
the calculation of right hand side if the left hand side is false?
infix operator &&&: LogicalConjunctionPrecedence
func &&&(left: Bool, right: Bool) -> Bool {
return left && right
}
as written it doesn't short-circuit. is it possible at all in swift?
great. as you just shown, the difference of short-circuiting or not is not
inside the operator declaration itself (like it is defined in C)
but in the actual operator implementation, so we can have:
infix operator &&&: LogicalConjunctionPrecedence
func &&&(left: Bool, right: @autoclosure () -> Bool) -> Bool {
return left && right()
}
func &&&(left: Int, right: Int) -> Int {
return left & right
}
where the logical one short-circuits and bit-wise one doesn't.
Mike
···
On 4 October 2017 at 14:24, Alex Blewitt <alblue@apple.com> wrote:
On 4 October 2017 at 13:41, Alex Blewitt <alblue@apple.com> wrote:
The difference between the & and && operators isn't to do with the
implicit conversions; it's to do with whether both sides of the expression
are evaluated or not.
However, you can wrap the second argument in an @autoclosure, which means
it replaces the body of the expression with a function that evaluates the
expression automatically:
infix operator &&&: LogicalConjunctionPrecedence
func &&&(left: Bool, right: @autoclosure () -> Bool) -> Bool {
return left && right()
}
func &&&(left: Bool, right: @autoclosure () -> Bool) -> Bool {
return left && right()
}
FTM, it would be nice to be able to "syntax sugar-ize" it into a better
looking:
func &&& (left: Bool, right: lazy Bool) -> Bool {
return left && right // no parens here
}
Mike
···
On 4 October 2017 at 14:24, Alex Blewitt <alblue@apple.com> wrote: