module Rationality
abstract SymbolicMathematics export SymbolicRational import Base: STDOUT, string, show, Rational type SymbolicRational <: SymbolicMathematics num::Int128 den::Int128 SymbolicRational{I<:Signed}(num::I, den::I) = new(Int128(num), Int128(den)) SymbolicRational{I<:Signed}(q::Rational{I}) = SymbolicRational(q.num, q.den) end function string(x::SymbolicRational) return string(x.num, "/", x.den) end function string{I}(x::Rational{I}) return string(x.num, "//", x.den) end function show(io::IO, x::SymbolicRational) s = string(x) print(io, s) end show(x::SymbolicRational) = show(STDOUT, x) function show{I}(io::IO, x::Rational{I}) s = string(x) print(io, s) end show{I}(x::Rational{I}) = show(STDOUT, x) end # module Rationality using Rationality p = 3//5 q = SymbolicRational(p) pstr = string(p); qstr = string(q); p_q = string(pstr, " ", qstr) println(p_q) show([p, q]) On Friday, October 14, 2016 at 9:52:51 AM UTC-4, lapeyre....@gmail.com wrote: > > I'm thinking of symbolic mathematics (Symata.jl). Another example is > `SymPy.jl`, which prints rationals the same way I want to, like this: > "2/3". But in SymPy.jl, rationals are not `Rational`'s, but rather wrapped > python objects, so the problem with printing does not arise. If I wrapped > `Rational`'s it would introduce a lot of complexity. > > So far, walking expression trees to wrap objects of certain types just > before printing seems to be working well. > > On Friday, October 14, 2016 at 4:23:27 AM UTC+2, Jeffrey Sarnoff wrote: >> >> I assume you meant x::T in type A{T}. Why do you want to do this: >> >>> Every time a Rational or Symbol or Bool is encountered on any level, I >>> want it to print differently than Base.show does it. >>> >> Do you want to adorn it (like "3//5" -> "{3//5}") or alter it (like >> "3//5" -> "2//5")? >> >> Also, I think you are approaching solving your problem in way more suited >> to another language. But I really have no idea what your motivation is. >> >> On Tuesday, October 11, 2016 at 7:21:35 PM UTC-4, lapeyre....@gmail.com >> wrote: >>> >>> To make it concrete, I have >>> >>> type A{T} >>> x >>> a::Array{Any,1} >>> end >>> >>> The elements of the array a are numbers, Symbols, strings, etc., as well >>> as more instances of type A{T}. They >>> may be nested to arbitrary depth. If I call show on an instance of A{T}, >>> then show will be called recursively >>> on all parts of the tree. Every time a Rational or Symbol or Bool is >>> encountered on any level, I want it to print differently than Base.show >>> does it. >>> >>> >>> On Tuesday, October 11, 2016 at 11:48:46 PM UTC+2, Jeffrey Sarnoff wrote: >>>> >>>> Are you saying a and b and c and d? >>>> >>>> (a) that you have a outer type which has a Rational field and has >>>> another field of a type that has a field which is typed Rational or is >>>> typed e.g. Vector{Rational} >>>> >>>> (b) and displaying a value of the outer type includes displaying the >>>> Rationals from withiin the field of the inner type >>>> >>>> (c) and when displaying that value, you want to present the outer >>>> type's Rational field a special way >>>> >>>> (d) and when displaying that value, you want to present the Rational >>>> fields of the inner type in the usual way >>>> >>>> >>>> On Tuesday, October 11, 2016 at 1:23:37 PM UTC-4, lapeyre....@gmail.com >>>> wrote: >>>>> >>>>> I think I understand what you are saying (not sure). A problem that >>>>> arises is that if I call show or print on an object, then show or print >>>>> may >>>>> be called many times on fields and fields of fields, etc., including from >>>>> within Base code before the call returns. I don't know how to tell the >>>>> builtin julia code my preference for printing rationals. The only way I >>>>> know to get a redefinition of show eg M.show to work in all situations, >>>>> is >>>>> to copy all the code that might be called. Maybe I'm missing something, >>>>> but >>>>> I can't see a way around this. >>>>> >>>>> I'm not familiar with the idea of a fencing module. >>>>> >>>>> On Monday, October 10, 2016 at 11:30:18 PM UTC+2, Jeffrey Sarnoff >>>>> wrote: >>>>>> >>>>>> You could wrap your redefinitions in a module M without exporting >>>>>> show explicitly. >>>>>> `using M` and accessing the your variation as `M.show` may give the >>>>>> localization you want. >>>>>> Should it not, then doing that within some outer working context, a >>>>>> fencing module, may add enough flexibility. >>>>>> >>>>>> >>>>>> On Monday, October 10, 2016 at 4:18:52 PM UTC-4, >>>>>> lapeyre....@gmail.com wrote: >>>>>>> >>>>>>> For the record, a workable solution, at least for this particular >>>>>>> code: I pass all output through wrapout() at the outermost output call. >>>>>>> The >>>>>>> object to be printed is traversed recursively. All types fall through >>>>>>> except for the handful that I want to change. Each of these is each >>>>>>> wrapped >>>>>>> in a new type. I extend Base.show for each of these wrapper types. This >>>>>>> seems pretty economical and robust and works across versions. The >>>>>>> wrapper >>>>>>> types are only introduced upon output, the rest of the code never sees >>>>>>> them. >>>>>>> >>>>>>> This works because the code uses a customization of the REPL, and >>>>>>> several instances of print, warn, string, etc. I make a new top-level >>>>>>> output function for the REPL that uses `wrapout`. I also generate >>>>>>> wrappers >>>>>>> for each of print, etc. that map `wrapout` over all arguments. A >>>>>>> developer >>>>>>> is expected to use the interface provided rather than `print` etc. >>>>>>> directly. The user doesn't even have a choice. There are very few >>>>>>> types in >>>>>>> the package, but a lot of nested instances. So there is very little >>>>>>> code >>>>>>> needed to traverse these instances. This might be more difficult in a >>>>>>> different situation if many methods for wrapout() were required. >>>>>>> >>>>>>> On Monday, October 10, 2016 at 12:20:50 AM UTC+2, >>>>>>> lapeyre....@gmail.com wrote: >>>>>>>> >>>>>>>> I want to change show for Symbol, Rational, and Bool. Till now, I >>>>>>>> simply overwrote the existing methods. This works great. I get what I >>>>>>>> want, >>>>>>>> even in warn and error and string interpolation, etc. It works >>>>>>>> flawlessly >>>>>>>> on v0.4, v0.5, and v0.6. But, this changes the behavior for everyone. >>>>>>>> So, I >>>>>>>> want to get the same effect through different means that do not affect >>>>>>>> other code. Any idea about how to do this ? >>>>>>>> >>>>>>>> One solution is to copy a large amount of base code that uses >>>>>>>> print, write, show, etc. renaming these functions. Other than changing >>>>>>>> 15 >>>>>>>> or 20 lines for Symbol, etc., the code is unchanged. This is works >>>>>>>> more or >>>>>>>> less, but is obviously a fragile, bad solution. >>>>>>>> >>>>>>>> Another idea is to make a subtype of IO that wraps subtypes of IO. >>>>>>>> I am allowed to write methods for show for this new type. This is >>>>>>>> turning >>>>>>>> out to be complicated and unworkable. >>>>>>>> >>>>>>>> Another vague idea is to make a new mime type. Another is to copy >>>>>>>> IOStream as another type, so that I only have to write methods for >>>>>>>> Symbol, >>>>>>>> Rational and Bool again. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>