Configuring Meta-Programming

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Configuring Meta-Programming

Mark S
Hello,

I'm looking for advice on how to configure code generated at compile
time.  My current solution reads the configuration values from a file,
but the feedback I received indicates that requiring users to create and
maintain a config file, in order to use this library, will at the very
least, severely limit its usefulness.

Is there another way to introduce configuration values at compile time? 
Is there a library you can point me to, that has resolved the same issue
differently?

Specifically, I created code that generates a module, containing a
custom Cyclic Redundancy Check (CRC) calculation function that utilizes
a CRC look-up table.  Creating the function and the look-up table
requires specifying the bit width, polynomial, initial value, final XOR
value, and whether the input and output values are reflected or not.

To generate the code module, I used Ulf Wiger's parse_trans library. In
particular, ct_expand:term() to generate the look-up table, and
codegen:gen_module() to generate the code and finally calling
merl:compile() to compile the abstract syntax tree, generated by
gen_module().

Thanks,

Mark Sebald
Reply | Threaded
Open this post in threaded view
|

Re: Configuring Meta-Programming

Dieter Schön
Hi Mark,

so instead of each user configures his/her environment, you will have to
build a bespoke

app for each user.

You will have to know the desired configuration for each user, and build
a custom version

for each variant.


The technical part is relatively easy, I think. The parameters can be
implemented as

-define(ParamX, ValueY).

Maybe add some -ifdef, if the configuration is complex.


And, from a CM perspective, I would definitely have everything in
version-controlled files.

No ad-hoc commandline switch-triggered artifacts.

Also, for runtime introspection, add a function which outputs the
configuration parameters

of the module.

 From my experience, in a commercial environment,

you should be most concerned how to be able to reliable and reproducible

build a version. And to be able to track which versions are in use where.


kind regards,

dieter


On 29.01.21 15:25, Mark S wrote:

> Hello,
>
> I'm looking for advice on how to configure code generated at compile
> time.  My current solution reads the configuration values from a file,
> but the feedback I received indicates that requiring users to create
> and maintain a config file, in order to use this library, will at the
> very least, severely limit its usefulness.
>
> Is there another way to introduce configuration values at compile
> time?  Is there a library you can point me to, that has resolved the
> same issue differently?
>
> Specifically, I created code that generates a module, containing a
> custom Cyclic Redundancy Check (CRC) calculation function that
> utilizes a CRC look-up table.  Creating the function and the look-up
> table requires specifying the bit width, polynomial, initial value,
> final XOR value, and whether the input and output values are reflected
> or not.
>
> To generate the code module, I used Ulf Wiger's parse_trans library.
> In particular, ct_expand:term() to generate the look-up table, and
> codegen:gen_module() to generate the code and finally calling
> merl:compile() to compile the abstract syntax tree, generated by
> gen_module().
>
> Thanks,
>
> Mark Sebald
Reply | Threaded
Open this post in threaded view
|

Re: Configuring Meta-Programming

Mark S
In reply to this post by Mark S
Hi Dieter,

A bespoke app for each user is fine, but I want to include the configurable CRC library as just a dependency, and not stored or versioned with the app. So the configuration parameters would live with the app, not the library.

My naive solution was to put the parameters in a custom text file.  I'm thinking that creating an include file (.hrl) containing -define() macros would be more Erlangish, but still a separate file to maintain.  Maybe the configuration belongs in the app's rebar.config file?

My ideal solution would be something in the app code that gets evaluated at compile time, and injects the configuration parameters into the library. I didn't mention this before, but I would like this library to be easily used with Elixir apps also.

Good idea about runtime introspection.  I had not considered that before.

Thanks!
Mark

> Date: Sat, 30 Jan 2021 12:27:10 +0100
> From: Dieter Sch?n <[hidden email]>
>
> Hi Mark,
>
> so instead of each user configures his/her environment, you will have to
> build a bespoke app for each user.
>
> You will have to know the desired configuration for each user, and build
> a custom version for each variant.
>
> The technical part is relatively easy, I think. The parameters can be
> implemented as -define(ParamX, ValueY).
>
> Maybe add some -ifdef, if the configuration is complex.
>
> And, from a CM perspective, I would definitely have everything in
> version-controlled files.
>
> No ad-hoc commandline switch-triggered artifacts.
>
> Also, for runtime introspection, add a function which outputs the
> configuration parameters of the module.
>
>   From my experience, in a commercial environment,
>
> you should be most concerned how to be able to reliable and reproducible
>
> build a version. And to be able to track which versions are in use where.
>
>
> kind regards,
>
> dieter
>
>
> On 29.01.21 15:25, Mark S wrote:
>> Hello,
>>
>> I'm looking for advice on how to configure code generated at compile
>> time.? My current solution reads the configuration values from a file,
>> but the feedback I received indicates that requiring users to create
>> and maintain a config file, in order to use this library, will at the
>> very least, severely limit its usefulness.
>>
>> Is there another way to introduce configuration values at compile
>> time?? Is there a library you can point me to, that has resolved the
>> same issue differently?
>>
>> Specifically, I created code that generates a module, containing a
>> custom Cyclic Redundancy Check (CRC) calculation function that
>> utilizes a CRC look-up table.? Creating the function and the look-up
>> table requires specifying the bit width, polynomial, initial value,
>> final XOR value, and whether the input and output values are reflected
>> or not.
>>
>> To generate the code module, I used Ulf Wiger's parse_trans library.
>> In particular, ct_expand:term() to generate the look-up table, and
>> codegen:gen_module() to generate the code and finally calling
>> merl:compile() to compile the abstract syntax tree, generated by
>> gen_module().
>>
>> Thanks,
>>
>> Mark Sebald
>
Reply | Threaded
Open this post in threaded view
|

Re: Configuring Meta-Programming

Dieter Schön
Hi again,

one possible solution would be the split in several rebar3 projects:

The application would live in an app, naturally, and a rebar3 lib  would
be a good fit for the CRC library.

If you want to "inject" the configuration parameters at compile time,

a .hrl with -define's and maybe -record's would be my first choice. just
use an -include in the CRC library.

If you want to keep the configuration file somewhere external from the
library, you can tell the location

to the library with the rebar3 configuration directive

{extra_src_dirs, []}

in rebar.config


At runtime/at the user's site, you need to bundle the app and the
correct library. One way  to do this would be

to use a release (with rebar3 new release) and put app and lib into that.


I have played a bit with erlang libraries in elixir and nerves (also
elixir), and this is absolutely painfree.

Just adapt the calling syntax to the elixir way:

e.g.

get_config() ->
     {config, ?BITWIDTH}.

Erlang/OTP 23 [erts-11.0] [source] [64-bit] [smp:8:8] [ds:8:8:10]
[async-threads:1] [hipe]

Eshell V11.0  (abort with ^G)
1> crc:get_config().
{config,32}

Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :crc.get_config
{:config, 32}


kind regards,

dieter

On 31.01.21 14:26, Mark S wrote:

> Hi Dieter,
>
> A bespoke app for each user is fine, but I want to include the
> configurable CRC library as just a dependency, and not stored or
> versioned with the app. So the configuration parameters would live
> with the app, not the library.
>
> My naive solution was to put the parameters in a custom text file. 
> I'm thinking that creating an include file (.hrl) containing -define()
> macros would be more Erlangish, but still a separate file to
> maintain.  Maybe the configuration belongs in the app's rebar.config
> file?
>
> My ideal solution would be something in the app code that gets
> evaluated at compile time, and injects the configuration parameters
> into the library. I didn't mention this before, but I would like this
> library to be easily used with Elixir apps also.
>
> Good idea about runtime introspection.  I had not considered that before.
>
> Thanks!
> Mark
>
>> Date: Sat, 30 Jan 2021 12:27:10 +0100
>> From: Dieter Sch?n <[hidden email]>
>>
>> Hi Mark,
>>
>> so instead of each user configures his/her environment, you will have to
>> build a bespoke app for each user.
>>
>> You will have to know the desired configuration for each user, and build
>> a custom version for each variant.
>>
>> The technical part is relatively easy, I think. The parameters can be
>> implemented as -define(ParamX, ValueY).
>>
>> Maybe add some -ifdef, if the configuration is complex.
>>
>> And, from a CM perspective, I would definitely have everything in
>> version-controlled files.
>>
>> No ad-hoc commandline switch-triggered artifacts.
>>
>> Also, for runtime introspection, add a function which outputs the
>> configuration parameters of the module.
>>
>>   From my experience, in a commercial environment,
>>
>> you should be most concerned how to be able to reliable and reproducible
>>
>> build a version. And to be able to track which versions are in use
>> where.
>>
>>
>> kind regards,
>>
>> dieter
>>
>>
>> On 29.01.21 15:25, Mark S wrote:
>>> Hello,
>>>
>>> I'm looking for advice on how to configure code generated at compile
>>> time.? My current solution reads the configuration values from a file,
>>> but the feedback I received indicates that requiring users to create
>>> and maintain a config file, in order to use this library, will at the
>>> very least, severely limit its usefulness.
>>>
>>> Is there another way to introduce configuration values at compile
>>> time?? Is there a library you can point me to, that has resolved the
>>> same issue differently?
>>>
>>> Specifically, I created code that generates a module, containing a
>>> custom Cyclic Redundancy Check (CRC) calculation function that
>>> utilizes a CRC look-up table.? Creating the function and the look-up
>>> table requires specifying the bit width, polynomial, initial value,
>>> final XOR value, and whether the input and output values are reflected
>>> or not.
>>>
>>> To generate the code module, I used Ulf Wiger's parse_trans library.
>>> In particular, ct_expand:term() to generate the look-up table, and
>>> codegen:gen_module() to generate the code and finally calling
>>> merl:compile() to compile the abstract syntax tree, generated by
>>> gen_module().
>>>
>>> Thanks,
>>>
>>> Mark Sebald
>>