Style question: defining methods for `tryparse`, `parse`

Existing methods work fine, in fact, I am building on them. But I find it useful to encapsulate parsing information into an object. Eg “this is a date, parse it like this”, or “parse this field with the following strings treated as missing data”. The type system is not rich enough to describe this.

(EDIT) To make things concrete, this is an example I am using for a dataset at the moment:

immutable CustomDate end

macro nullable_catch(expr, catch_errors=:ArgumentError)
    @assert expr.head ≡ :(::) "Use this macro as @nullable_catch value::type."
    (expr_value, expr_type) = map(esc, expr.args)
    quote
        try
            Nullable{$expr_type}($expr_value)
        catch e
            if isa(e, $(esc(catch_errors)))
                Nullable{$expr_type}()
            else
                rethrow()
            end
        end
    end
end

function tryparse(::Type{CustomDate}, string)
    if !isascii(string) || (string == "00000000")
        Nullable{Date}()
    elseif endswith(string, "00")  # day is corrected to 1
        @nullable_catch Date(string[1:end-2], "yyyymm")::Date
    else
        @nullable_catch Date(string, "yyyymmdd")::Date
    end
end

which I call like this:

tryparse(CustomDate, "19800101")
tryparse(CustomDate, "19800100")    # bogus dates in my data
tryparse(CustomDate, "nonsensical") # Nullable{Date}()

The design/style questions are:

  1. whether I should define methods for tryparse anyway, or make a new function,
  2. should I need a function that returns the parsed type for parsing specifications which are not Julia types, eg
parsedtype(::Type{CustomDate}) = Date

with a fallback

parsedtype{T}(::Type{T}) = T

for other types. But maybe that is too general, and I should only define for types which tryparse accepts? Interfaces are hard :slight_smile: