From 7ad88b6ef8687b43e6a8ab9fc56befd1766afcd3 Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 09:52:48 -0700 Subject: [PATCH 01/12] syntax change, type, abstract type ... --- src/belief.jl | 6 +++--- src/policy.jl | 6 +++--- src/pomdp.jl | 6 +++--- src/requirements_internals.jl | 22 +++++++++++----------- src/simulator.jl | 6 +++--- src/solver.jl | 4 ++-- test/test_generative.jl | 4 ++-- test/test_inferrence.jl | 6 +++--- test/test_requirements.jl | 2 +- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/belief.jl b/src/belief.jl index b3c69417..429d4101 100644 --- a/src/belief.jl +++ b/src/belief.jl @@ -11,9 +11,9 @@ Abstract type for an object that defines how the belief should be updated A belief is a general construct that represents the knowledge an agent has about the state of the system. This can be a probability distribution, an -action observation history or a more general representation. +action observation history or a more general representation. """ -abstract Updater{B} +abstract type Updater{B} end # TODO(max): should this be moved to pomdp.jl? """ @@ -31,7 +31,7 @@ Returns a new instance of an updated belief given `belief_old` and the latest ac function update end """ - initialize_belief{B}(updater::Updater{B}, + initialize_belief{B}(updater::Updater{B}, state_distribution::Any) initialize_belief{B}(updater::Updater{B}, belief::Any) diff --git a/src/policy.jl b/src/policy.jl index 6008907f..c4e2da7b 100644 --- a/src/policy.jl +++ b/src/policy.jl @@ -1,6 +1,6 @@ ################################################################# # The policy is a mapping from a belief to an action in a POMDP, -# and it maps states to actions in an MDP. +# and it maps states to actions in an MDP. # The policy is extracted through calls to the action() function. ################################################################# @@ -9,14 +9,14 @@ Base type for a policy (a map from every possible belief, or more abstract polic B: a belief (or policy state) that represents the knowledge an agent has about the state of the system """ -abstract Policy{B} +abstract type Policy{B} end """ action{B}(policy::Policy, x::B) Fills and returns action based on the current state or belief, given the policy. `B` is a generalized information state - can be a state in an MDP, a distribution in POMDP, -or any other representation needed to make a decision using the given policy. +or any other representation needed to make a decision using the given policy. """ function action end diff --git a/src/pomdp.jl b/src/pomdp.jl index 988730e0..32bfa2a4 100644 --- a/src/pomdp.jl +++ b/src/pomdp.jl @@ -6,7 +6,7 @@ Abstract base type for a partially observable Markov decision process. A: action type O: observation type """ -abstract POMDP{S,A,O} +abstract type POMDP{S,A,O} end """ Abstract base type for a fully observable Markov decision process. @@ -14,7 +14,7 @@ Abstract base type for a fully observable Markov decision process. S: state type A: action type """ -abstract MDP{S,A} +abstract type MDP{S,A} end """ n_states(problem::POMDP) @@ -76,7 +76,7 @@ observation{S,A,O}(problem::POMDP{S,A,O}, a::A, sp::S) = observation(problem, sp Return the observation distribution for the s-a-s' tuple (state, action, and next state) """ -observation{S,A,O}(problem::POMDP{S,A,O}, s::S, a::A, sp::S) = observation(problem, a, sp) +observation{S,A,O}(problem::POMDP{S,A,O}, s::S, a::A, sp::S) = observation(problem, a, sp) @impl_dep {P<:POMDP,S,A} observation(::P,::S,::A,::S) observation(::P,::A,::S) """ diff --git a/src/requirements_internals.jl b/src/requirements_internals.jl index 8da1201f..a51d6764 100644 --- a/src/requirements_internals.jl +++ b/src/requirements_internals.jl @@ -1,16 +1,16 @@ -typealias TupleType Type # should be Tuple{T1,T2,...} -typealias Req Tuple{Function, TupleType} +const TupleType = Type # should be Tuple{T1,T2,...} +const Req = Tuple{Function, TupleType} -abstract AbstractRequirementSet +abstract type AbstractRequirementSet end -type Unspecified <: AbstractRequirementSet +mutable struct Unspecified <: AbstractRequirementSet requirer parent::Nullable{Any} end Unspecified(requirer) = Unspecified(requirer, Nullable{Any}()) -type RequirementSet <: AbstractRequirementSet +mutable struct RequirementSet <: AbstractRequirementSet requirer reqs::Vector{Req} # not actually a set - to preserve intuitive ordering deps::Vector{AbstractRequirementSet} @@ -57,7 +57,7 @@ function pomdp_requirements(name::Union{Expr,String}, block::Expr) return newblock end -typealias CheckedList Vector{Tuple{Bool, Function, TupleType}} +const CheckedList = Vector{Tuple{Bool, Function, TupleType}} """ @@ -83,7 +83,7 @@ function convert_req(ex::Expr) break end end - else + else malformed = true end if malformed # throw error at parse time so solver writers will have to deal with this @@ -133,7 +133,7 @@ function recursively_show(io::IO, show_incomplete(io, r) first_exception = Nullable{RequirementSet}(r) end - + for dep in r.deps depcomplete, depexception = recursively_show(io, dep, analyzed, reported) allthere = allthere && depcomplete @@ -239,7 +239,7 @@ function convert_call(call::Expr) push!(args, a) end end - else + else malformed = true end if malformed # throw error at parse time so solver writers will have to deal with this @@ -262,7 +262,7 @@ Replace any @req calls with `push!(\$reqs_name, )` Returns true if there was a requirement in there and so should not be escaped. """ function handle_reqs!(node::Expr, reqs_name::Symbol) - + if node.head == :macrocall && node.args[1] == Symbol("@req") macro_node = copy(node) node.head = :call @@ -312,7 +312,7 @@ In the example above, `@implemented reward(::P,::S,::A,::S)` will return true if THIS IS ONLY INTENDED FOR USE INSIDE POMDPs AND MAY NOT FUNCTION CORRECTLY ELSEWHERE """ macro impl_dep(curly, signature, dependency) - # this is kinda hacky and fragile with the cell1d - email Zach if it breaks + # this is kinda hacky and fragile with the cell1d - email Zach if it breaks @assert curly.head == :cell1d implemented_curly = :(implemented{$(curly.args...)}) tplex = convert_req(signature) diff --git a/src/simulator.jl b/src/simulator.jl index 13893749..4a8b107f 100644 --- a/src/simulator.jl +++ b/src/simulator.jl @@ -7,11 +7,11 @@ """ Base type for an object defining how simulations should be carried out. """ -abstract Simulator +abstract type Simulator end """ - simulate{S,A,O,B}(simulator::Simulator, problem::POMDP{S,A,O}, policy::Policy{B}, updater::Updater{B}, initial_belief::B) - simulate{S,A}(simulator::Simulator, problem::MDP{S,A}, policy::Policy, initial_state::S) + simulate{S,A,O,B}(simulator::Simulator, problem::POMDP{S,A,O}, policy::Policy{B}, updater::Updater{B}, initial_belief::B) + simulate{S,A}(simulator::Simulator, problem::MDP{S,A}, policy::Policy, initial_state::S) Run a simulation using the specified policy. diff --git a/src/solver.jl b/src/solver.jl index 937e9f85..1190a488 100644 --- a/src/solver.jl +++ b/src/solver.jl @@ -2,11 +2,11 @@ """ Base type for an MDP/POMDP solver """ -abstract Solver +abstract type Solver end """ solve(solver::Solver, problem::POMDP) -Solves the POMDP using method associated with solver, and returns a policy. +Solves the POMDP using method associated with solver, and returns a policy. """ function solve end diff --git a/test/test_generative.jl b/test/test_generative.jl index 16d04896..2385a230 100644 --- a/test/test_generative.jl +++ b/test/test_generative.jl @@ -6,7 +6,7 @@ println("Warning expected:") println("Warning expected:") @test_throws MethodError generate_s(A(), 1, true, Base.GLOBAL_RNG) -type B <: POMDP{Int, Bool, Bool} end +mutable struct B <: POMDP{Int, Bool, Bool} end transition(b::B, s::Int, a::Bool) = Int[s+a] @test implemented(generate_s, Tuple{B, Int, Bool, MersenneTwister}) @@ -28,7 +28,7 @@ initial_state_distribution(b::B) = Int[1,2,3] @test initial_state(B(), Base.GLOBAL_RNG) in initial_state_distribution(B()) -type C <: POMDP{Void, Void, Void} end +mutable struct C <: POMDP{Void, Void, Void} end generate_sr(c::C, s::Void, a::Void, rng::AbstractRNG) = nothing, 0.0 generate_o(c::C, s::Void, a::Void, sp::Void, rng::AbstractRNG) = nothing @test @implemented generate_sor(::C, ::Void, ::Void, ::MersenneTwister) diff --git a/test/test_inferrence.jl b/test/test_inferrence.jl index ef17dfb7..7b8d9634 100644 --- a/test/test_inferrence.jl +++ b/test/test_inferrence.jl @@ -2,9 +2,9 @@ using Base.Test using POMDPs -type X <: POMDP{Float64,Bool,Int} end -abstract Z <: POMDP{Float64,Bool,Int} -type Y <: Z end +mutable struct X <: POMDP{Float64,Bool,Int} end +abstract type Z <: POMDP{Float64,Bool,Int} end +mutable struct Y <: Z end @test_throws ErrorException state_type(Int) @test_throws ErrorException action_type(Int) diff --git a/test/test_requirements.jl b/test/test_requirements.jl index 53d2234e..7be6c08b 100644 --- a/test/test_requirements.jl +++ b/test/test_requirements.jl @@ -71,7 +71,7 @@ end)) @test_throws MethodError solve(CoolSolver(), SimplePOMDP()) POMDPs.states(::SimplePOMDP) = [1.4, 3.2, 5.8] -immutable SimpleDistribution +struct SimpleDistribution ss::Vector{Float64} b::Vector{Float64} end From 5a53bdb4cd51d65145c35b13e8c8528646f1e307 Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 09:58:54 -0700 Subject: [PATCH 02/12] syntax changes in test --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 141c434b..fd81bdb9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,7 @@ using Base.Test using POMDPs -type A <: POMDP{Int,Bool,Bool} end +mutable struct A <: POMDP{Int,Bool,Bool} end @test_throws MethodError n_states(A()) @test_throws MethodError state_index(A(), 1) @@ -18,7 +18,7 @@ POMDPs.observation(::A,::Bool,::Int) = [true, false] @test @implemented observation(::A,::Int,::Bool,::Int) @test @implemented observation(::A,::Bool,::Int) -type D end +mutable struct D end POMDPs.sampletype(::Type{D}) = Int @test @implemented sampletype(::D) @test sampletype(D()) == Int From 1d1ffe5909cf37541067caebf591b94010229ab5 Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 10:11:04 -0700 Subject: [PATCH 03/12] fixed typos --- src/requirements_interface.jl | 8 ++++---- test/test_requirements.jl | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/requirements_interface.jl b/src/requirements_interface.jl index 9f39d636..42a29327 100644 --- a/src/requirements_interface.jl +++ b/src/requirements_interface.jl @@ -55,7 +55,7 @@ macro POMDP_require(typedcall, block) tconstr = Expr[:($(Symbol(:T,i))<:$(esc(C))) for (i,C) in enumerate(types)] # oh snap ts = Symbol[Symbol(:T,i) for i in 1:length(types)] req_spec = :(($fname, Tuple{$(types...)})) - fimpl = quote + fimpl = quote function get_requirements{$(tconstr...)}(f::typeof($(esc(fname))), # dang args::Tuple{$(ts...)}) ($([esc(a) for a in args]...),) = args # whoah @@ -114,7 +114,7 @@ end """ @requirements_info ASolver() [YourPOMDP()] -Print information about the requirements for a solver. +Print information about the requirements for a solver. """ macro requirements_info(exprs...) quote @@ -155,7 +155,7 @@ end """ @subreq f(arg1, arg2) -In a `@POMDP_requirements` or `@POMDP_require` block, include the requirements for `f(arg1, arg2) as a child argument set. +In a `@POMDP_requirements` or `@POMDP_require` block, include the requirements for `f(arg1, arg2)` as a child argument set. """ macro subreq(ex) return quote @@ -196,7 +196,7 @@ function show_requirements(r::AbstractRequirementSet) println("Note: Missing methods are often due to incorrect importing. Consider using `importall POMDPs`.") println() end - + if !isnull(first_exception) print("Throwing the first exception (from processing ") print_with_color(:blue, handle_method(get(first_exception).requirer)) diff --git a/test/test_requirements.jl b/test/test_requirements.jl index 7be6c08b..cf7011c6 100644 --- a/test/test_requirements.jl +++ b/test/test_requirements.jl @@ -11,10 +11,10 @@ end module MyModule using POMDPs - + export CoolSolver, solve - type CoolSolver <: Solver end + mutable struct CoolSolver <: Solver end p = nothing # to test hygeine @POMDP_require solve(s::CoolSolver, p::POMDP) begin @@ -41,7 +41,7 @@ module MyModule util1(x) = abs(x) - util2(p::POMDP) = observations(p) + util2(p::POMDP) = observations(p) @POMDP_require util2(p::POMDP) begin P = typeof(p) @req observations(::P) @@ -51,7 +51,7 @@ end using POMDPs using MyModule -type SimplePOMDP <: POMDP{Float64, Bool, Int} end +mutable struct SimplePOMDP <: POMDP{Float64, Bool, Int} end POMDPs.actions(SimplePOMDP) = [true, false] POMDPs.discount(::SimplePOMDP) = 0.9 From 8c1249bce8259b935b0e44ae63411a3c6258f05e Mon Sep 17 00:00:00 2001 From: Zachary Sunberg Date: Tue, 11 Jul 2017 10:20:05 -0700 Subject: [PATCH 04/12] fixed first requirements testing problem --- src/requirements_interface.jl | 8 ++++---- test/test_requirements.jl | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/requirements_interface.jl b/src/requirements_interface.jl index 42a29327..f47fa359 100644 --- a/src/requirements_interface.jl +++ b/src/requirements_interface.jl @@ -56,7 +56,7 @@ macro POMDP_require(typedcall, block) ts = Symbol[Symbol(:T,i) for i in 1:length(types)] req_spec = :(($fname, Tuple{$(types...)})) fimpl = quote - function get_requirements{$(tconstr...)}(f::typeof($(esc(fname))), # dang + function POMDPs.get_requirements{$(tconstr...)}(f::typeof($(esc(fname))), # dang args::Tuple{$(ts...)}) ($([esc(a) for a in args]...),) = args # whoah return $(pomdp_requirements(req_spec, block)) @@ -114,7 +114,7 @@ end """ @requirements_info ASolver() [YourPOMDP()] -Print information about the requirements for a solver. +Print information about the requirements for a solver. """ macro requirements_info(exprs...) quote @@ -155,7 +155,7 @@ end """ @subreq f(arg1, arg2) -In a `@POMDP_requirements` or `@POMDP_require` block, include the requirements for `f(arg1, arg2)` as a child argument set. +In a `@POMDP_requirements` or `@POMDP_require` block, include the requirements for `f(arg1, arg2) as a child argument set. """ macro subreq(ex) return quote @@ -196,7 +196,7 @@ function show_requirements(r::AbstractRequirementSet) println("Note: Missing methods are often due to incorrect importing. Consider using `importall POMDPs`.") println() end - + if !isnull(first_exception) print("Throwing the first exception (from processing ") print_with_color(:blue, handle_method(get(first_exception).requirer)) diff --git a/test/test_requirements.jl b/test/test_requirements.jl index cf7011c6..64cd33fe 100644 --- a/test/test_requirements.jl +++ b/test/test_requirements.jl @@ -68,7 +68,8 @@ end end)) # solve(CoolSolver(), SimplePOMDP()) -@test_throws MethodError solve(CoolSolver(), SimplePOMDP()) +# @test_throws MethodError solve(CoolSolver(), SimplePOMDP()) +solve(CoolSolver(), SimplePOMDP()) POMDPs.states(::SimplePOMDP) = [1.4, 3.2, 5.8] struct SimpleDistribution From 2a25cc7dbbf78821ed04932a5785691725e93979 Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 10:40:30 -0700 Subject: [PATCH 05/12] typo --- src/requirements_interface.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/requirements_interface.jl b/src/requirements_interface.jl index f47fa359..f8d84161 100644 --- a/src/requirements_interface.jl +++ b/src/requirements_interface.jl @@ -114,7 +114,7 @@ end """ @requirements_info ASolver() [YourPOMDP()] -Print information about the requirements for a solver. +Print information about the requirements for a solver. """ macro requirements_info(exprs...) quote @@ -155,7 +155,7 @@ end """ @subreq f(arg1, arg2) -In a `@POMDP_requirements` or `@POMDP_require` block, include the requirements for `f(arg1, arg2) as a child argument set. +In a `@POMDP_requirements` or `@POMDP_require` block, include the requirements for `f(arg1, arg2)` as a child argument set. """ macro subreq(ex) return quote @@ -196,7 +196,7 @@ function show_requirements(r::AbstractRequirementSet) println("Note: Missing methods are often due to incorrect importing. Consider using `importall POMDPs`.") println() end - + if !isnull(first_exception) print("Throwing the first exception (from processing ") print_with_color(:blue, handle_method(get(first_exception).requirer)) From 564ff53fa058ad3e8f9e3d3f53263f576e5ad6e2 Mon Sep 17 00:00:00 2001 From: Zachary Sunberg Date: Tue, 11 Jul 2017 10:43:20 -0700 Subject: [PATCH 06/12] tests pass --- REQUIRE | 2 +- src/requirements_interface.jl | 2 +- src/requirements_printing.jl | 2 ++ test/test_requirements.jl | 3 +-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/REQUIRE b/REQUIRE index 61d9938b..b49cf826 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,2 +1,2 @@ -julia 0.5 +julia 0.6 Distributions diff --git a/src/requirements_interface.jl b/src/requirements_interface.jl index f47fa359..62813fb1 100644 --- a/src/requirements_interface.jl +++ b/src/requirements_interface.jl @@ -190,7 +190,7 @@ function show_requirements(r::AbstractRequirementSet) # all printing to the screen happens here at once println() - print(takebuf_string(buf)) + print(String(take!(buf))) println() if !allthere println("Note: Missing methods are often due to incorrect importing. Consider using `importall POMDPs`.") diff --git a/src/requirements_printing.jl b/src/requirements_printing.jl index 4a562270..2ed6d2b5 100644 --- a/src/requirements_printing.jl +++ b/src/requirements_printing.jl @@ -52,6 +52,8 @@ function format_method(f::Function, argtypes::TupleType; module_names=false) str = string(str, tt.name.name, i Date: Tue, 11 Jul 2017 10:59:15 -0700 Subject: [PATCH 07/12] changed travis to use julia 0.6 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7cca6b96..8a548756 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ os: - linux - osx julia: - - 0.5 + - 0.6 notifications: email: false before_script: From 76c13a08b5fca0717f924e61d648336603579449 Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 11:11:20 -0700 Subject: [PATCH 08/12] get rid of the parameter in the Policy type --- src/policy.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/policy.jl b/src/policy.jl index c4e2da7b..eb39b19c 100644 --- a/src/policy.jl +++ b/src/policy.jl @@ -6,10 +6,8 @@ """ Base type for a policy (a map from every possible belief, or more abstract policy state, to an optimal or suboptimal action) - - B: a belief (or policy state) that represents the knowledge an agent has about the state of the system """ -abstract type Policy{B} end +abstract type Policy end """ action{B}(policy::Policy, x::B) From 0eb8dd20633267e7853e7d1df51b847f0445284e Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 11:33:14 -0700 Subject: [PATCH 09/12] remove belief parameter to updater type --- src/belief.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/belief.jl b/src/belief.jl index 429d4101..37d0db30 100644 --- a/src/belief.jl +++ b/src/belief.jl @@ -7,13 +7,11 @@ """ Abstract type for an object that defines how the belief should be updated - B: belief type that parametrizes the updater - A belief is a general construct that represents the knowledge an agent has about the state of the system. This can be a probability distribution, an action observation history or a more general representation. """ -abstract type Updater{B} end +abstract type Updater end # TODO(max): should this be moved to pomdp.jl? """ From 88903b3c4b82681987e31d077ec415c3ce9b1886 Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 11:37:14 -0700 Subject: [PATCH 10/12] remove parameter in updater --- src/belief.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/belief.jl b/src/belief.jl index 37d0db30..70d9cdf1 100644 --- a/src/belief.jl +++ b/src/belief.jl @@ -43,4 +43,4 @@ correct type: `initialize_belief{B}(updater::Updater{B}, belief::B) = belief` function initialize_belief end # default implementation if the input is the same type as the output -initialize_belief{B}(updater::Updater{B}, belief::B) = belief +initialize_belief{B}(updater::Updater, belief::B) = belief From 4bc4111bd02d866d403ca1313fd68f2826a689ad Mon Sep 17 00:00:00 2001 From: Zachary Sunberg Date: Tue, 11 Jul 2017 11:56:01 -0700 Subject: [PATCH 11/12] made states and actions declarations less specific --- src/space.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/space.jl b/src/space.jl index 8f086397..8ea628a4 100644 --- a/src/space.jl +++ b/src/space.jl @@ -23,7 +23,7 @@ function states end Returns a subset of the state space reachable from `state`. """ -states{S,A}(problem::Union{POMDP{S,A},MDP{S,A}}, s::S) = states(problem) +states(problem::Union{POMDP,MDP}, s) = states(problem) @impl_dep {P<:Union{POMDP,MDP},S} states(::P,::S) states(::P) """ @@ -40,7 +40,7 @@ function actions end Return the action space accessible from the given state. """ -actions{S,A}(problem::Union{MDP{S,A},POMDP{S,A}}, state::S) = actions(problem) +actions(problem::Union{MDP,POMDP}, state) = actions(problem) @impl_dep {P<:Union{POMDP,MDP},S} actions(::P,::S) actions(::P) """ @@ -62,5 +62,5 @@ function observations end Return the observation space accessible from the given state and returns it. """ -observations{S,A,O}(problem::POMDP{S,A,O}, state::S) = observations(problem) +observations(problem::POMDP, state) = observations(problem) @impl_dep {P<:POMDP,S} observations(::P,::S) observations(::P) From bd34d24f0fb6388183d2a3885568b28064d14a99 Mon Sep 17 00:00:00 2001 From: MaximeBouton Date: Tue, 11 Jul 2017 19:57:10 -0700 Subject: [PATCH 12/12] fix Union printing in format_method --- src/requirements_printing.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/requirements_printing.jl b/src/requirements_printing.jl index 2ed6d2b5..e369dd09 100644 --- a/src/requirements_printing.jl +++ b/src/requirements_printing.jl @@ -44,12 +44,18 @@ function format_method(f::Function, argtypes::TupleType; module_names=false) if !module_names # begin fname = typeof(f).name.mt.name - mless_typenames = [] + mless_typenames = [] for t in argtypes.parameters + # if isa(t, Union) + # str = "Union{" + # for (i, tt) in enumerate(t.types) + # str = string(str, tt.name.name, i