Hi Michal,<div><br></div><div>I did look at ennotation, it was one of those places I found inspiration! :)</div><div><br></div><div>One of the things I wanted to do was move away from macros towards module attributes instead. These are discoverable at runtime (using Mod:module_info/1) which makes them available for other tools to use as well. I also find reading a module annotation a bit easier on the eye than a macro, although obviously that's just a personal preference. I also preserve the original code (by renaming and re-exporting the function), which means that during tracing, debugging, logging, etc - the module in which the originating code lives (i.e., the annotation callback module vs the annotated production code) is preserved, which I find preferable.</div>
<div><br></div><div>Another thing I wanted to do (which I mentioned in the previous post) is provide match specification based mappings between annotations and code, and to provide an API for runtime code instrumentation as well as the option of doing it at compile time with a parse transform.</div>
<div><br></div><div>As you've built a conceptually very similar framework (which is much more mature than my effort) I would be very keen to hear your thoughts about whether declarative weaving/advising might be useful!</div>
<div><br></div><div>Cheers,</div><div><br></div><div>Tim</div><div><br><div class="gmail_quote">On 5 December 2011 11:08, Michał Ptaszek <span dir="ltr"><<a href="mailto:michal.ptaszek@erlang-solutions.com">michal.ptaszek@erlang-solutions.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi Tim,<br>
<br>
you might want to take a look at ennotation: it's<br>
something I've derived from erlang-web, but which has<br>
been reimplemented from scratch.<br>
<br>
<a href="https://github.com/paulgray/ennotation" target="_blank">https://github.com/paulgray/ennotation</a><br>
<br>
Best regards,<br>
Michal Ptaszek<br>
<div><div class="h5"><br>
<br>
----- Original Message -----<br>
> There have been a few conversations about instrumentation libraries<br>
> on the<br>
> list, and I've been experimenting with the features Ulf recently<br>
> added to<br>
> parse_trans. I've worked up a simple annotations library, that let's<br>
> you<br>
> put attributes/annotations on specific functions and attach behaviour<br>
> to<br>
> them in the form of an implementation module. The current framework<br>
> is very<br>
> crude and relies on a compile time parse transform, though obviously<br>
> it'll<br>
> be relatively trivial to implement runtime code changes as well.<br>
><br>
> The purpose of this prototyping was to play around with some of the<br>
> ideas<br>
> in Aspect Oriented Programming, and the library allows you to write<br>
> code<br>
> that executes before, after or around an annotated function. This is<br>
> done<br>
> without macros, which feels a bit neater to me than the approach used<br>
> in<br>
> erlang-web. In addition to the library, I've made a small reference<br>
> project<br>
> which implements a simple function memoization annotation using ets<br>
> as a<br>
> cache. The implementation of the annotation itself is very simple:<br>
><br>
> -module(memoize).<br>
> -annotation('function').  %% scoped to functions<br>
> -export([init/1]).<br>
> -export([around_advice/4]).<br>
><br>
> init(Module) -><br>
>     ets:new(Module, [ordered_set, public, named_table,<br>
>                      {write_concurrency,true},<br>
>                      {read_concurrency,true}, compressed]),<br>
>     ok.<br>
><br>
> around_advice(_A, M, F, Inputs) -><br>
>     case ets:lookup(M, {F, Inputs}) of<br>
>         [] -><br>
>             Result = annotation:call_advised(M, F, Inputs),<br>
>             true = ets:insert_new(M, {{F, Inputs}, Result}),<br>
>             Result;<br>
>         [{_, Memoized}] -><br>
>             Memoized<br>
>     end.<br>
><br>
> And the usage of the annotation is very simple too:<br>
><br>
> -module(fib_mem).<br>
> -export([start_memoize/0, fib/1]).<br>
> -include_lib("annotations/include/annotations.hrl").<br>
><br>
> start_memoize() -><br>
>     memoize:init(?MODULE).<br>
><br>
> -memoize(ets).<br>
> fib(0) -> 0;<br>
> fib(1) -> 1;<br>
> fib(N) -> fib(N - 1) + fib(N - 2).<br>
><br>
> --------------------<br>
><br>
> As I said, the implementation is very crude but I hope that the<br>
> concepts<br>
> will trigger some discussion about whether this is a useful<br>
> contribution<br>
> and in what directions it ought to go.<br>
><br>
> Code is here: <a href="https://github.com/hyperthunk/annotations" target="_blank">https://github.com/hyperthunk/annotations</a><br>
> Memoize is here: <a href="https://github.com/nebularis/memoize" target="_blank">https://github.com/nebularis/memoize</a><br>
><br>
</div></div>> _______________________________________________<br>
> erlang-questions mailing list<br>
> <a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
> <a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
><br>
</blockquote></div><br></div>