Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base.zero, Base.one, Base.inv missing #168

Open
ghost opened this issue Apr 15, 2019 · 4 comments
Open

Base.zero, Base.one, Base.inv missing #168

ghost opened this issue Apr 15, 2019 · 4 comments

Comments

@ghost
Copy link

ghost commented Apr 15, 2019

I'm trying to use Symata symbols in Julia code which relies on methods such as Base.zero, Base.one, and Base.inv. These are not implemented for the symbols one gets from the julia code @sym x.

I have tried to implement them as follows, but that does not seem to be correct (or at least not complete) since it leads to MethodError: no method matching zero(::Symata.Mxpr{:Times}) which presumably means this code will have to handle objects of type Symata.Mxpr as well:

using Symata
import Base
Base.one(::Symbol) = 1
Base.zero(::Symbol) = 0
Base.inv(s::Symbol) = one(s) / s

What would a proper implementation look like and can one be added to this great package?

@ghost
Copy link
Author

ghost commented Apr 15, 2019

MWE, continuing from the code above:

x = @sym x
inv(im*x)

# outut

ERROR: MethodError: no method matching inv(::Mxpr{:Times})
Closest candidates are:
  inv(::Complex{Float64}) at complex.jl:431
  inv(::BigFloat) at mpfr.jl:471
  inv(::Integer) at int.jl:56

@ghost
Copy link
Author

ghost commented Apr 15, 2019

symatamath() from https://github.com/jlapeyre/Symata.jl/blob/master/TutorialNotebooks/Interface%20with%20Julia.ipynb does not seem to help (although it perhaps shifts the problem).

It is also at least not sufficient to change my original attempt to

Base.one(::Symbol) = @symExpr 1
Base.zero(::Symbol) = @symExpr 0
Base.inv(s::Symbol) = @symExpr 1 / s

@jlapeyre
Copy link
Owner

Thanks very much for the report. There are a few issues.
x = @sym x binds x to the Julia Symbol :x. So, you can also try

julia> im * :x
im*:x
julia> typeof(im * :x)
Mxpr{:Times}

But this is "type piracy" because this defines Base.:* for the base Julia types of im and :x. It should be disabled by default in Symata. But, it is not. This is a bug. I don't recall why I left it enabled. symatamath is intended to enable several such definitions.

You can define a method for inv like this

julia> Base.inv(m::Mxpr) = mxpr(:Power, m, -1)

julia> inv(:a + :b)
(:a + :b)^(-1)

The definition for inv is not type piracy because Mxpr is not a base type. But, the :a + :b ought not to be defined by default.

A well-thought-out plan for methods like inv has not been done for lack of time. The file julia_level.jl is a sketch providing some methods to be used from Julia. For myself, I thought of this as a secondary use case for Symata. I don't have statistics, but it seems people are more interested in using Symata this way.

This

using Symata
import Base
Base.one(::Symbol) = 1
Base.zero(::Symbol) = 0
Base.inv(s::Symbol) = one(s) / s

could be made to work, but again only using type piracy. Some people think this should never be allowed and they have very good arguments. Supporting opt-in type piracy is also dangerous in general. If many people come to rely on piracy in one package and then Julia core devs decide later they want to use the methods for something else, it will start a contest.

@ghost
Copy link
Author

ghost commented Apr 16, 2019

Thank you very much for the quick and detailed response. The following seems to go a long way:

using Symata
import Base
symatamath()
Base.one(::Mxpr) = @symExpr 1
Base.zero(::Mxpr) = @symExpr 0
Base.inv(m::Mxpr) = mxpr(:Power, m, -1)
Base.sqrt(m::Mxpr) = mxpr(:Power, m, 1//2)
Base.complex(x::Mxpr, y::Mxpr) = x + im*y

Perhaps it should be incorporated into Symata.jl? On the other hand, it's not quite production-ready yet because this requires replacing @sym x with e.g. 1.0 * @sym x to turn the symbol x into an Mxpr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant