Value based dispatch with a string presents some challenges. If you use a Symbol, an interned string, directly, then value based dispatch can be made very efficient due to constant propagation. julia> @btime ValueFruitFactory.fruit(:orange) 1.424 ns (0 allocations: 0 bytes) Main.ValueFruitFactory.Orange() julia> f() = ValueFruitFactory.fruit(:orange) f (generic function with 1 method) julia> @btime f() 1.423 ns (0 allocations: 0 bytes) Main.ValueFruitFactory.Orange() julia> @code_typed f() CodeInfo( 1 ─ return $(QuoteNode(Main.ValueFruitFactory.Orange())) ) => Main.ValueFruitFactory.Orange Compare the typed code with the string version. julia> @code_typed g() CodeInfo( 1 ─ %1 = $(Expr(:foreigncall, :(:jl_string_ptr), Ptr{UInt8}, svec(Any), 0, :(:ccall), "orange"))::Ptr{UInt8} │ %2 = Core.sizeof("orange")::Int64 │ %3 = $(Expr(:foreigncall, :(:jl_symbol_n), Ref{Symbol}, svec(Ptr{UInt8}, Int64), 0, :(:ccall), :(%1), :(%2), "orange"))::Symbol │ %4 = invoke Main.ValueFruitFactory.fruit(%3::Symbol)::Union{Main.ValueFruitFactory.Apple, Main.ValueFruitFactory.Orange} └── return %4 ) => Union{Main.ValueFruitFactory.Apple, Main.ValueFruitFactory.Orange}