[erlang-questions] getting type info at runtime

Daniel Luna daniel@REDACTED
Tue Sep 27 17:53:37 CEST 2011

Many years ago I wrote a runtime -spec checker, reading the data from
abstract code (if I remember correctly).

The checker will convert input to any function with a -spec
declaration to a type, and validate that type against the -spec.  This
will then be done recursively for any function call originating from
the checked function call. (As long as all modules in that chain are
compiled with debug_info (since that is the only way to get access to
the types).)

All of this is done loading a spec checked version of the code, and
rewriting all function calls with a magical prefix.  Calls to unknown
modules are then intercepted (by using a replacement error handler),
and loads a modified version of the called module. Etc.

The checking is all done in core erlang, which unfortunately ruins
readability quite a bit.

You can use and copy whatever you want from that project

There are a few caveats:

1. I have not tested this in a long time, and I'm heavily depending on
Dialyzer for the type parsing.  If Dialyzer has been changed, my code
might break.

2. Something changed in core erlang a few years back, so the code is
broken as it stands today.  Should be an easy fix for someone wiling
to learn a bit about core erlang (or wants to do some io:format
programming).  I have marked the place of offending code.

3. Type checking using my current implementation is *slow*.  The
reason for this is that I type convert the full argument even if only
a minor piece is necessary. (e.g. given the type [any()] my code would
still convert a list with a thousand deeply nested elements into its
fully expanded type)  The fix for this is easy, but time consuming.

Anyway.  Even if it turns out that the core erlang parts are hard to
reuse, the code server parts should be straight forward to copy.  If
anyone wants to know more detail just ask and I'll see what I can



ps. Assume that it's under an MIT license, and I'll add the actual
license statement later this week.

On 26 September 2011 18:57, Tim Watson <watson.timothy@REDACTED> wrote:
> Hi Lukas,
> Thanks for this - some very helpful suggestions.
>> Regarding types in .beam files: That information is only part of the
>> abtract code, so dialyzer, hipe and all other tools need the abtract code or
>> the source code to do its magic. The reason why it is stripped out is
>> because the .beam files should be as small as possible by default and also
>> partly because you cannot trust a typespec to be correct.
> Yes I can understand wanting to keep the beam small, but it would be nice to
> have the option of the compiler inserting the type specs and of course just
> because the type spec is in the beam file, doesn't mean it has to be brought
> into memory when loading the beam. :)
> If abstract_code is the only sane way to go then I can simply push out
> warnings for beams that don't have it and exclude those from the
> introspection.
>> Describing where you want to put your instrumentation is harder to figure
>> out though and to date no one really has managed to write a good wrapper to
>> match specs. The best one (imo) is the dbg:fun2ms function Eg:
> Yes I've used this before. As you say though, it's not a great deal clearer
> than the match spec itself.
>> Using the improved -specs that will come in R14B04 it would be possible to
>> write a spec which describes the same thing. Keeping things in Erlang has
>> the advantage of it being easier to build tools around it though.
> I haven't seen these, so I'll have a poke around and see how they work. In
> terms of actually writing the specification, I think you're right that
> having something pure erlang is good. I was pondering the approach I used
> for https://github.com/hyperthunk/hamcrest-erlang of using various functions
> as sugar. Ultimately though, I'd like to be able to put the instrumentation
> config used by the build into a config file (such as rebar.config) so it
> will probably end up either looking like a match spec or being a string that
> gets parsed.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

More information about the erlang-questions mailing list