Create `ImmutableDict` with values of differenrt types

Simple MWE:

d1 = Dict(:a => 1.0, :b => "Hello world") # Works
d2 = Base.ImmutableDict(:a => 1.0, :b => "Hello world") # Fails

How do I create an ImmutableDict where keys can have arbitrary values?

There might be some room for interface improvement here. But the following works:

d = Base.ImmutableDict(Base.ImmutableDict{Symbol, Any}(),
  :a => 1.0, :b => "Hello strange world")

This workaround (which necessitated looking at the code) is because the underlying linked list has to have the same key-value types, and is initialized by the first pair. The empty Dict in the example above fixes the value type to be Any.

A little less verbose:

d = Base.ImmutableDict(Pair{Symbol,Any}(:a, 1.0), :b => "Hi strange world")

Another version:

d = Base.ImmutableDict(Base.ImmutableDict{Symbol,Any}(:a, 1.0), :b => "Hi")
1 Like

As Dan said, ImmutableDict is based on a linked list.

This is a very niche datastructure for very specialized use-cases. It is not an appropriate general purpose datastructure for an “immutable dictionary”.

If you need to ask, you should probably not use ImmutableDict. The entire thing should probably have been julia-internal only.

(ImmutableDict is good for cases where you must use an API that insists on an AbstractDict, and you have 0-5 key-value pairs, and you possibly get to share the tails of the linked list between multiple ImmutableDicts)

1 Like

Got it, thanks for the input.

I am implementing metadata for an (internal) structure within Catalyst.jl. Since it is based on ModelingToolkit.jl, which uses ImmutableDict for its metadata, I decided to also go with it. This is the reason for using an internal Julia type.