Often I want to use zero-sized structs for dispatch purposes, and it’s kind of annoying to have to make up a name for both the struct and the unique instance of that struct.
In Scala, they have object as a primitive, which creates a class and the unique instance of it in one go. The class is then anonymous, and printed out as Foo.type (or something like that, I can’t remember exactly what).
Would something like this be possible in Julia? It wouldn’t be that hard to do with a macro, using gensym for the name of the struct; but then would it be possible to overload printing out the name of the type to be something more informative than the gensym name?
Already is—because functions are singleton objects (although it’s a bit awkward for this):
julia> function foo end
foo (generic function with 0 methods)
julia> f(x) = x
f(::typeof(foo)) = "Foo!"
f (generic function with 2 methods)
julia> f(foo)
"Foo!"
For with Julia, all things are possible:
julia> macro singleton(s::Symbol) sT=Symbol("#$s"); esc(quote
struct $sT end
Base.show(io::IO, ::$sT) = print(io, $("$s"))
const $s = $sT()
end) end
@singleton (macro with 1 method)
julia> @singleton bar
bar
julia> f(::typeof(bar)) = "Bar?"
f (generic function with 3 methods)
julia> f(bar)
"Bar?"
All that said, I’ve never found a reason not to just follow this:
julia> struct Baz end
julia> f(::Baz) = "Baz 😉"
f (generic function with 4 methods)
julia> f(Baz())
"Baz 😉"
This aligns more closely with how non-function singletons are already used throughout the language—meaning there’s less surprise, so unless there’s a good reason I’d stick with this.
When you see a capitalized name calling something with parentheses, you may assume it’s a constructor, which returns an object. If there are no input arguments, it’s quite likely a singleton (though it could, admittedly, be a non-singleton with default parameters values.)
I don’t believe it’s good practice to have capitalized functions that have observable side effects, if that’s what you are thinking.
But if you do need this, isn’t that very straightforward?