Open RaulDurand opened 10 months ago
allow multiple dispatch on && and || operators
Does this make sense? They are not (math) operators, unlike e.g. (bitwise) & and |, that are defined by functions, and they can sometimes be used as substitutions for working (faster even) on Bools (and support multiple dispatch?.
They are Boolean short-circuting operators, or operations... not defined by functions.
I admit I didn't read carefully what you proposed, you want some extension. Those are the only short-circuting operations, i.e. control flow. I.e. none of normal operators are.
To me the benefit also remains unclear. Perhaps a concrete example or two would help illustrate what usecases you have in mind?
As an alternative, you might consider using macros to rewrite expressions containing &&
or ||
, substituting those with suitable code (e.g. a && b
could be transformed into myand(a, ()->b)
).
Backward Compatibility: The proposed change is backward compatible as it preserves the existing behavior for standard Boolean types.
Short-circuiting is what people expect, and if that doesn't apply to what you propose (it doesn't for functions/other operators), then that would be surprising. Are you asking for that in the extension? I'm not sure it's easily doable.
With a macro you can do anything, as proposed, then then people may not expect it, but might also be surprising to miss it.
Does this make sense? They are not (math) operators, unlike e.g. (bitwise) & and |, that are defined by functions, and they can sometimes be used as substitutions for working (faster even) on Bools (and support multiple dispatch?.
They are Boolean short-circuting operators, or operations... not defined by functions.
Well, && and || are logical operators. Although in Julia they are not defined by functions.
I admit I didn't read carefully what you proposed, you want some extension. Those are the only short-circuting operations, i.e. control flow. I.e. none of normal operators are.
The idea is to extend && and || to be used as operators. In the past, other operators (such as the dot operator) were exposed for multiple dispatch.
To me the benefit also remains unclear. Perhaps a concrete example or two would help illustrate what usecases you have in mind?
The use case is more common in symbolic calculus, equations and boolean expressions. Take as an example the definition of a piecewise function using SymPy (from Python). In that case, this package uses the & operator, but additional parentheses are required due to the higher precedence of &.
from sympy import symbols, Piecewise
x = symbols('x')
# Define the piecewise function
f = Piecewise(
(x**2, x <= 0), # x^2 for x <= 0
(x + 1, (x > 0) & (x < 2)), # x + 1 for 0 < x < 2
(3, x >= 2) # 3 for x >= 2
)
There are some Julia packages that use a similar approach.
As an alternative, you might consider using macros to rewrite expressions containing
&&
or||
, substituting those with suitable code (e.g.a && b
could be transformed intomyand(a, ()->b)
).
Yes, macros can help but when used frequently within the same expression they can compromise readability.
Quite related is https://github.com/JuliaLang/julia/issues/39104. That's more specifically about 0 < x < 2
, but that lowers to the short-circuiting 0 < x && x < 2
, just like you have written here.
Short-circuiting is what people expect, and if that doesn't apply to what you propose (it doesn't for functions/other operators), then that would be surprising. Are you asking for that in the extension? I'm not sure it's easily doable.
In my proposal, short-circuit will still work as expected provided that the first argument is a boolean. For other types, such as symbolic expressions, it is reasonable to expect the outcome to be a corresponding symbolic expression.
Quite related is #39104. That's more specifically about
0 < x < 2
, but that lowers to the short-circuiting0 < x && x < 2
, just like you have written here.
Thus, the proposed feature could prove useful in extending the functionality of chained inequalities.
I am currently working with custom mathematical expressions in Julia. One limitation I've encountered is the inability to use multiple dispatch with the short-circuit logical operators && and ||. While alternatives such as defining functions like and() and or() or using Unicode operators are viable, they don't quite offer the intuitive and natural usage that && and || provide for most users.
Proposal:
I propose extending Julia's functionality to allow multiple dispatch on && and || operators while preserving their short-circuit behavior. This enhancement would not only maintain the intuitive use of these operators but also add flexibility for custom types and expressions.
Implementation Concept:
The core idea is to encapsulate the right-hand side (rhs) of the operator into an anonymous function at compile time (or any other stage). This encapsulation allows the short-circuit logic to be preserved. For example:
This approach maintains the current behavior when dealing with Boolean values. For custom types, such as CustomExpr, the operator can be redefined to suit specific needs:
Benefits:
Intuitive Syntax: Users can continue using && and || in a manner they are familiar with. Customizability: This feature opens up avenues for more flexible and powerful expressions in custom mathematical and symbolic computation. Backward Compatibility: The proposed change is backward compatible as it preserves the existing behavior for standard Boolean types.
I believe this feature would be a valuable addition to Julia, enhancing its capabilities in symbolic mathematics and potentially other domains where custom types benefit from logical operations. I am hopeful that this feature aligns with the interests and needs of most Julia programmers. Thank you for considering this proposal