diff --git a/README.md b/README.md index 1370dd1..6c478c2 100644 --- a/README.md +++ b/README.md @@ -340,10 +340,9 @@ perhaps unavoidable. Therefore, these approaches are complementary. The EAFP-based strategy is useful for reducing the complexity of library extension interface. -(Implementation details: In Try.jl, each "EAFP-compatible" function is declared -with `Try.@function f` instead of `function f end`. It is defined as an -instance of a subtype of `Tryable <: Function` and not as an instance of a -"direct" subtype of `Function`.) +(Usage notes: An "EAFP-compatible" function can be declared with `Try.@function f` instead +of `function f end`. It automatically defines a catch-all fallback method that returns an +`Err{<:NotImplementedError}`.) #### Side notes on `hasmethod` and `applicable` (and `invoke`) diff --git a/src/Try.jl b/src/Try.jl index 030bbde..1b7d640 100644 --- a/src/Try.jl +++ b/src/Try.jl @@ -44,7 +44,7 @@ function iserr end function enable_errortrace end function disable_errortrace end -abstract type Tryable <: Function end +function istryable end # Core exceptions struct IsOkError <: Exception diff --git a/src/function.jl b/src/function.jl index 7fe6284..454a5af 100644 --- a/src/function.jl +++ b/src/function.jl @@ -1,14 +1,32 @@ +""" + Tryable <: Function + +An *implementation detail* of `Try.@function`. + +This is not exposed as an API because: + +* It may be required for a callable to be in another type hierarchy. Such callables are + incompatible with the code written with `_ isa Tryable`. +* When a Tryable function is part of stack trace, its printing is not great. It may be + better to just use a plain `function` and define `istryable`. +* The tryability many depend on some run-time properties. +""" +abstract type Tryable <: Function end + +Try.istryable(::Any) = false +Try.istryable(::Tryable) = true + const var"@define_function" = var"@function" macro define_function(name::Symbol) typename = gensym("typeof_$name") quote - struct $typename <: $Try.Tryable end + struct $typename <: $Tryable end const $name = $typename() $Base.nameof(::$typename) = $(QuoteNode(name)) end |> esc end -(fn::Try.Tryable)(args...; kwargs...) = Causes.notimplemented(fn, args, kwargs) +(fn::Tryable)(args...; kwargs...) = Causes.notimplemented(fn, args, kwargs) # TODO: show methods