-
Notifications
You must be signed in to change notification settings - Fork 380
VIP12: vmod polymorphism (for type conversions)
VCL has implicit type conversion to STRING, but not for other types. E.g. a REAL or INT do not get converted to DURATION implicitly. Calling explicit type conversion functions is possible, but we have some variations already and would need more, e.g. in vmod_std
-
integer()
(actually string2integer) real2integer()
time2integer()
-
duration2integer()
(does not yet exist)
During a bugwash discussion on 2016-10-05, several options were discussed (including relaxed casting/conversion between types) and it was found that explicit type conversions were still the best option, so it was suggested that these should be made easier and cleaner to use by introducing polymorphism.
- some existing conversions require a de-tour over stringification, which is both computationally and memory inefficient
- implicit conversions would lack the fallback value (which is important e.g. for REAL being InF or NaN)
- implicit conversions would open a new class of problems in vcc
- polymorphism avoids x2y conversion function names and allows for cleaner VCL code
- for polymorphic arguments, STRING always needs to be supported
- for polymorphic arguments, the implementation for non-STRING arguments needs to behave as if a STRING argument was passed, iow
foo(X, FALLBACK) === foo("" + X, FALLBACK)
- vmodtool allows a VCL function/method name to be multiply defined
- the definition contains a C function name suffix for the given argument type combination
- at vcl compile time, vcc finds the best match ** arbitration left->right best match (e.g. stringification of rightmost arguments preferred)
by example of std.int
(to supersede all the above)
VCC definition:
$Function INT int{_BOOL}(BOOL b, INT fallback)
$Function INT int{_BYTES}(BYTES b, INT fallback)
$Function INT int{_DURATION}(DURATION d, INT fallback)
$Function INT int{_REAL}(REAL r, INT fallback)
$Function INT int{_STRING}(STRING s, INT fallback)
$Function INT int{_TIME}(TIME t, INT fallback)
produces vcc_if.h
:
VCL_INT int_BOOL(VRT_CTX, VCL_BOOL, VCL_INT);
VCL_INT int_BYTES(VRT_CTX, VCL_BYTES, VCL_INT);
VCL_INT int_DURATION(VRT_CTX, VCL_DURATION, VCL_INT);
VCL_INT int_REAL(VRT_CTX, VCL_REAL, VCL_INT);
VCL_INT int_STRING(VRT_CTX, VCL_STRING, VCL_INT);
VCL_INT int_TIME(VRT_CTX, VCL_TIME, VCL_INT);
(PHK 2019-02-06)
Having circled back to this one, I think the optional arguments to VMOD functions does most, if not all of this, at very little extra cost and inconvenience, so I propose we retire this VIP after reconsidering the standard conversion functions.
Originally the conversion functions go the prototype-prototype TYPE std.type(STRING input, TYPE default)
in order to not having users forget to handle parsing-errors in VCL.
With optional arguments, we can make the conversion functions much more functional, for instance:
TIME std.time([STRING input], [TIME fallback], [REAL real_input], [INT int_input])
Present calls to std.time will work as they always did, but now you can also:
Leave out the fallback, turning a parsing error into a SLT_VCL_Error failure.
Pass integers or reals, with or without fallbacks (I guess for NaN or negative values ?)
Obviously, if you call this std.time() in a silly way, for intance with no arguments at all, you get a SLT_VCL_Error failure.
(2019-02-11)
Consensus: Yes we should, subject to bikesheds about argument names etc.