Open jlapeyre opened 1 year ago
Same problem here. For example, we cannot use Polynomials.jl with symbolic expression coefficients.
What are you proposing ==
do?
If there is a reasonable answer, we can implement it. But a==b
is meant to be a value check in most code, so just returning false
would be wrong.
I can't find a single instance in Julia where a == b does not return Bool. Maybe there is one, but I can't find it.
julia> missing == 2
missing
that would miss my point. Julia is about composability an genericness.
I hope it's also about correctness.
What are you proposing
==
do?
That it does what isequal
do?
The current behavior of ==
is actually used in packages. (MTK for example).
That it does what
isequal
do?
This will result in wrong code as I mentioned.
What are you proposing == do? If there is a reasonable answer, we can implement it. But a==b is meant to be a value check in most code, so just returning false would be wrong.
I mean that ==
always returns a Bool
and everyone expects it. Not returning a Bool
is more wrong. An exception is missing
which is a continual source of headaches and forces everyone to deal with itself.
Because ==
falls back to ===
, you can always call ==
and expect a Bool
. So people rely on it. A lot of people wish it were not this way. I've seen Stefan opine that it was a mistake.
It looks like 1.0 was released a couple of months ago. That's unfortunate. This limits the usability of SymbolicUtils.jl
. I'm not sure how to fix it. Maybe deprecate it's use and use a different symbol, like Symbolics.jl
does.
Here is a related problem shield Base.require from invalidations when loading Symbolics.jl. SymbolicUtils
extends Base.isequal
for no reason to do something it is not documented to do. So far, this has required at least this commit to Julia itself. If there is some way to take this back or fix it in a breaking release, I suggest doing it.
I think this kind of thing is quite common. I have some packages that should be released at v1 and this is a good reminder to vet them for gratuitous extensions, which I know I have made in the past. Like everyone else, I was over-enamored with multiple dispatch. It's probably the relatively recent focus on invalidations that has brought this problem to light.
btw Convex.jl also works this way, where ==
returns a constraint object, and has since ~2014 or so when the package was first developed. I don't have a strong opinion about whether or not it should, but just want to point that out. I think it hasn't caused many issues there because Convex's objects don't really work in generic code so they tend to only be passed into Convex.jl-aware functions.
If there is a strong desire for this, I think one can make a number type which behaves in the way need, just as we have LiteralReal
and SafeReal
.
@syms x::LiteralReal
makes it so that x-x
remains as-is and is not represented as 0. @syms x::SafeReal
makes it so that (x*y)/x
is not simplified but x-x
is.
Having
==
construct an equation might be a good idea if this package were a standalone CAS, like Mathematica. But it's meant to work with the larger Julia ecosystem. The semantics of==
in Julia at large is consistent. The semantics here is completely different, which means you usingSym
in generic code will often do the wrong thing, in fact throw an error.I can't find a single instance in Julia where
a == b
does not returnBool
. Maybe there is one, but I can't find it. This line inBase.jl
is largely responsible:You have...
As a result, this assumption is made everywhere in the Julia ecosystem.
This issue is similar to #15. I did not check this against the version of SymbolicUtils in that issue, but I think the problem there was also that
==
does not return aBool
, not simplification.I noticed this a couple of years ago, and may have posted something somewhere. But I want to state the issue clearly. I can't think of a function in Julia that is more widespread and with more consistent semantics than
Base.==
. And the method defined for::Sym
breaks this consistency for the sake of giving the frontend experience of Mathematica. This makesSymbolicUtils
more like a DSL and less like a library for use in other Julia projects.A response could be "just use
isequal
". But that would miss my point. Julia is about composability an genericness. (Andisequal
has a different, specified, semantics.)(btw. +100 on performance of rules and of load time of
SymbolicUtils
! This makes it easier to argue for Julia.)