My FeedDiscussionsHashnode Enterprise
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more
Matthijs Cox

3 likes

·

760 reads

3 comments

Mark Kittisopikul
Mark Kittisopikul
Jun 25, 2023

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}
1
·
Mason Protter
Mason Protter
Jun 26, 2023

I played around with this a few years ago in github.com/MasonProtter/PatternDispatch.jl

julia> module PatternFruitFactory
       using PatternDispatch

       abstract type Fruit end
       struct Apple <: Fruit end
       struct Orange <: Fruit end

       @pattern fruit("apple") = Apple()
       @pattern fruit("orange") = Orange()
       @pattern fruit(s) = error("unknown fruit $s")
       end

julia> @btime PatternFruitFactory.fruit("orange")
  3.449 ns (0 allocations: 0 bytes)
Main.PatternFruitFactory.Orange()

These are extensible at a later time:

julia> @btime PatternFruitFactory.fruit("banana")
  7.537 ns (0 allocations: 0 bytes)
Main.PatternFruitFactory.Banana()

PatternDispatch.jl does some stuff that's unfriendly to precompilation though so it doesn't fit very well into packages. Very much just a proof of concept.

1
·
·1 reply
Matthijs Cox
Matthijs Cox
Author
·Jun 27, 2023

cool, thanks for yet another suggestion :)

·