Function subtypes

See these discussion: Shorthand syntax for defining functors - Internals & Design - Julia Programming Language (julialang.org)

I’ve actually have written a macro to do this before:

julia> macro singleton(expr)
           expr = expr::Expr
           @assert Meta.isexpr(expr, :call) && first(expr.args) == :isa "Not an `isa` expression"

           _, name, supertype = expr.args
           typename = gensym(name)

           return quote
               struct $typename <: $(esc(supertype)) end
               const $(esc(name)) = $typename()
               Base.@__doc__($(esc(name)))
           end
       end
@singleton (macro with 1 method)

julia> abstract type MyType <: Function end

julia> begin
           """
           Singleton object `foo` acts as a function with special properties...
           """
           @singleton foo isa MyType
       end
foo

julia> foo() = println("Hello world!")
(::var"##foo#292") (generic function with 1 method)

julia> foo(name) = println("Hello $(name)!")
(::var"##foo#292") (generic function with 2 methods)

julia> foo()
Hello world!

julia> foo("Steve")
Hello Steve!

julia> foo isa MyType
true

julia> foo isa Function
true

help?> foo
search: foo floor pointer_from_objref OverflowError RoundFromZero unsafe_copyto! functionloc StackOverflowError

  Singleton object foo acts as a function with special properties...

Edit:

  • Use isa instead of <:
  • Removed Base.show definition
  • Add support for docstrings with Base.@__doc__
2 Likes