From 5242cfe260b630c226e30693aa819adb11eacd50 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 21 May 2018 15:48:08 +0100 Subject: Runtime types --- posts/runtime-types.mdwn | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 posts/runtime-types.mdwn diff --git a/posts/runtime-types.mdwn b/posts/runtime-types.mdwn new file mode 100644 index 0000000..ddc5da9 --- /dev/null +++ b/posts/runtime-types.mdwn @@ -0,0 +1,76 @@ +[[!meta title="Runtime typing"]] +[[!meta author="Daniel Silverstone"]] +[[!meta date="2018-05-21 15:31:00 BST"]] +[[!tag draft]] + +I have been wrestling with a problem for a little while now and thought I might +send this out [into the ether][1] for others to comment upon. (Or, in other +words, Dear Lazyweb…) + +I am writing system which collects data from embedded computers in my car +(ECUs) over the CAN bus, using the on-board diagnostics port in the vehicle. +This requires me to generate packets on the CAN bus, listen to responses, +including managing flow control, and then interpret the resulting byte arrays. + +I have sorted everything but the last little bit of that particular data +pipeline. I have a prototype which can convert the byte arrays into "raw" +values by interpreting them either as bitfields and producing booleans, or as +anything from an unsigned 8 bit integer to a signed 32 bit integer in either +endianness. Fortunately none of the fields I'd need to interpret are floats. + +This is, however, pretty clunky and nasty. Since I asked around and a majority +of people would prefer that I keep the software configurable at runtime rather +than doing meta-programming to describe these fields, I need to develop a way +to have the data produced by reading these byte arrays (or by processing +results already interpreted out of the arrays) type-checked. + +As an example, one field might be the voltage of the main breaker in the car. +It's represented as a 16 bit big-endian unsigned field, in tenths of a volt. +So the field must be divided by ten and then given the type "volts". Another +field is the current passing through that main breaker. This is a 16 bit +big-endian signed value measured in tenths of an amp, so must be interpreted as +as such, divided by ten, and then given the type "amps". I intend for all +values handled beyond the raw byte arrays themselves to simply be floats, so +there'll be signedness available regardless. + +What I'd like, is to later have a "computed" value, let's call it "power flow", +which is the voltage multiplied by the current. Naturally this would need to +be given the type 'watts'. What I'd dearly love is to build into my program +the understanding that volts times amps equals watts, and then have the reader +of the runtime configuration type-check the function for "power flow". + +I'm working on this in Rust, though for now the language is less important than +the algorithms involved in doing this (unless you know of a Rust library which +will help me along). I'd dearly love it if someone out there could help me to +understand the right way to handle such expression type checking without having +to build up a massively complex type system. + +Currently I am considering things (expressed for now in yaml) along the lines +of: + +[[!format yaml """ +- name: main_voltage + type: volts + expr: u16_be(raw_bmc, 14) / 10 +- name: main_current + type: amps + expr: i16_be(raw_bmc, 12) / 10 +- name: power_flow + type: watts + expr: main_voltage * main_current +"""]] + +What I'd like is for each expression to be type-checked. I'm happy for untyped +scalars to end up auto-labelled (so the `u16_be()` function would return an +untyped number which then ends up marked as volts since 10 is also untyped). +However when `power_flow` is typechecked, it should be able to work out that +the type of the expression is `volts * amps` which should then typecheck +against `watts` and be accepted. Since there's also consideration needed for +times, distances, booleans, etc. this is not a completely trivial thing to +manage. I will know the set of valid types up-front though, so there's that at +least. + +If you have any ideas, ping me on IRC or perhaps blog a response and then +drop me an email to let me know about it. Thanks. + +[1]: https://english.stackexchange.com/questions/107853/what-is-the-meaning-of-in-the-ether#107855 -- cgit v1.2.1