Groovy Name-and-Value Macro Support Proposal

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

Groovy Name-and-Value Macro Support Proposal

MG
Hi,

I have given Groovy 2.5's new macro support a spin and implemented functionality to support code constructs which I could last use with C++'s macro preprocessor stringify operation (and which I always found very helpful for debugging / creating runtime log output).

Example:
final ageOfTree = 124
final towerHeight = 987.654
final String visitorName = "abc"
final s1 = "DEFGH"
final gs0 = "val0:$ageOfTree"
final GString gs1 = "TheTower($towerHeight)"
final List names = [ "Peter", "Ann", "Raymond" ]

println "single variables: ${NV(ageOfTree)} and ${NV(gs0)} and ${NV(visitorName)} and ${NV(s1)} and ${NV(gs1)} and also ${NV(names)})}"
println "variable list: ${NVL(ageOfTree, gs0, visitorName, s1, towerHeight, gs1, names)}"

which prints:

single variables: ageOfTree=124 and gs0="val0:124" and visitorName="abc" and s1="DEFGH" and gs1="TheTower(987.654)" and also names=[Peter, Ann, Raymond])}
variable list: [ageOfTree=124, gs0="val0:124", visitorName="abc", s1="DEFGH", towerHeight=987.654, gs1="TheTower(987.654)", names=[Peter, Ann, Raymond]]

NV here is a Groovy macro method which, which allows turning the passed variable expression into its name and value in the form of a simple NameAndValue class instance. NVL does the same for multiple variables (returning a list of NameAndValue|s).
(I used a different name for NVL, to allow for NV to take more than one variable expression parameter (and return e.g. a GString that contains a sequence of "name=$val" expressions without the enclosing list brackets), or to allow for NV to take additional parameters).

Such an extension would be useful, because it:
  1. Reduces the amount of boilerplate code one needs to write
  2. Makes the code more concise
  3. Removes errors such as: println "var0=$var0, var1=$var0"

I therefore propose we add this functionality to Groovy 2.5.x .


Apart from the general decision, open questions for me are:
  1. Where do we put macro extensions in the Groovy source code ?
  2. What names should we use for macro methods ?
I lean towards using C/C++ macro naming conventions as a guideline, i.e. using short, abbreviated, uppercase-only names such as NV = named variable, or NVL = named variable list, since:
  1. Macros allow for "magic" and are not really method calls in the classical sense
  2. Java do not have macros, so the hope would be that making them stick out a bit will make them less confusing for developers coming from Java to Groovy
  3. On the other hand C/C++ developers that are used to macros will immediately suspect that they are looking at a macro-like construct
  4. Independent of upper-/lowercase, brevity is important, especially for the proposed two NV/NVL macros, since it would imho be desirable for e.g. "NV(x)" to not take up more space than "x=$x"
In any case macro-method support in Groovy is a fantastic feature, which opens up completely new possibilities for language & framework developers - Go Groovy !-)
Please comment,
Cheers,
mg





Reply | Threaded
Open this post in threaded view
|

Re: Groovy Name-and-Value Macro Support Proposal

paulk_asert
Looks nice.

I'll have to think about conventions on where such contributions should live and naming conventions too.

We already have "macro" which is lowercase. Sometimes I suspect we want to make it obvious that we are dealing with a macro, other times we want to almost hide that fact. I am not sure one single convention is going to work.

My current inclination is to delay making any final decisions on such topics until we see what else emerges. Though I must admit I like your current proposal as is.

Cheers, Paul.


On Thu, Jun 28, 2018 at 5:10 AM MG <[hidden email]> wrote:
Hi,

I have given Groovy 2.5's new macro support a spin and implemented functionality to support code constructs which I could last use with C++'s macro preprocessor stringify operation (and which I always found very helpful for debugging / creating runtime log output).

Example:
final ageOfTree = 124
final towerHeight = 987.654
final String visitorName = "abc"
final s1 = "DEFGH"
final gs0 = "val0:$ageOfTree"
final GString gs1 = "TheTower($towerHeight)"
final List names = [ "Peter", "Ann", "Raymond" ]

println "single variables: ${NV(ageOfTree)} and ${NV(gs0)} and ${NV(visitorName)} and ${NV(s1)} and ${NV(gs1)} and also ${NV(names)})}"
println "variable list: ${NVL(ageOfTree, gs0, visitorName, s1, towerHeight, gs1, names)}"

which prints:

single variables: ageOfTree=124 and gs0="val0:124" and visitorName="abc" and s1="DEFGH" and gs1="TheTower(987.654)" and also names=[Peter, Ann, Raymond])}
variable list: [ageOfTree=124, gs0="val0:124", visitorName="abc", s1="DEFGH", towerHeight=987.654, gs1="TheTower(987.654)", names=[Peter, Ann, Raymond]]

NV here is a Groovy macro method which, which allows turning the passed variable expression into its name and value in the form of a simple NameAndValue class instance. NVL does the same for multiple variables (returning a list of NameAndValue|s).
(I used a different name for NVL, to allow for NV to take more than one variable expression parameter (and return e.g. a GString that contains a sequence of "name=$val" expressions without the enclosing list brackets), or to allow for NV to take additional parameters).

Such an extension would be useful, because it:
  1. Reduces the amount of boilerplate code one needs to write
  2. Makes the code more concise
  3. Removes errors such as: println "var0=$var0, var1=$var0"

I therefore propose we add this functionality to Groovy 2.5.x .


Apart from the general decision, open questions for me are:
  1. Where do we put macro extensions in the Groovy source code ?
  2. What names should we use for macro methods ?
I lean towards using C/C++ macro naming conventions as a guideline, i.e. using short, abbreviated, uppercase-only names such as NV = named variable, or NVL = named variable list, since:
  1. Macros allow for "magic" and are not really method calls in the classical sense
  2. Java do not have macros, so the hope would be that making them stick out a bit will make them less confusing for developers coming from Java to Groovy
  3. On the other hand C/C++ developers that are used to macros will immediately suspect that they are looking at a macro-like construct
  4. Independent of upper-/lowercase, brevity is important, especially for the proposed two NV/NVL macros, since it would imho be desirable for e.g. "NV(x)" to not take up more space than "x=$x"
In any case macro-method support in Groovy is a fantastic feature, which opens up completely new possibilities for language & framework developers - Go Groovy !-)
Please comment,
Cheers,
mg





MG
Reply | Threaded
Open this post in threaded view
|

Re: Groovy Name-and-Value Macro Support Proposal

MG
Hi Paul,

glad you like it, and I'm with you on the naming convention. If someone where to introduce a new "while" loop construct as a macro method:

@Macro
static Expression forAWhile(...) { ... }

I would also not suggest he call it 
FORAWHILE
or
FOR_A_WHILE.

It is similar to macro usage in C/C++: Sometimes you want a macro to blend into the language, and sometimes you want it to be explicit. 

Independent of that, the shorter a macro name is (say 1 to 3 letters), the more I tend towards uppercasing it, because otherwise it looks like a variable with a implicit call method call, or an oddly short regular method. I have already given my rationale why "named variable" support would imho benefit from a terse notation.

Cheers,
mg








-------- Urspr√ľngliche Nachricht --------
Von: Paul King <[hidden email]>
Datum: 28.06.18 09:23 (GMT+01:00)
Betreff: Re: Groovy Name-and-Value Macro Support Proposal

Looks nice.

I'll have to think about conventions on where such contributions should live and naming conventions too.

We already have "macro" which is lowercase. Sometimes I suspect we want to make it obvious that we are dealing with a macro, other times we want to almost hide that fact. I am not sure one single convention is going to work.

My current inclination is to delay making any final decisions on such topics until we see what else emerges. Though I must admit I like your current proposal as is.

Cheers, Paul.


On Thu, Jun 28, 2018 at 5:10 AM MG <[hidden email]> wrote:
Hi,

I have given Groovy 2.5's new macro support a spin and implemented functionality to support code constructs which I could last use with C++'s macro preprocessor stringify operation (and which I always found very helpful for debugging / creating runtime log output).

Example:
final ageOfTree = 124
final towerHeight = 987.654
final String visitorName = "abc"
final s1 = "DEFGH"
final gs0 = "val0:$ageOfTree"
final GString gs1 = "TheTower($towerHeight)"
final List names = [ "Peter", "Ann", "Raymond" ]

println "single variables: ${NV(ageOfTree)} and ${NV(gs0)} and ${NV(visitorName)} and ${NV(s1)} and ${NV(gs1)} and also ${NV(names)})}"
println "variable list: ${NVL(ageOfTree, gs0, visitorName, s1, towerHeight, gs1, names)}"

which prints:

single variables: ageOfTree=124 and gs0="val0:124" and visitorName="abc" and s1="DEFGH" and gs1="TheTower(987.654)" and also names=[Peter, Ann, Raymond])}
variable list: [ageOfTree=124, gs0="val0:124", visitorName="abc", s1="DEFGH", towerHeight=987.654, gs1="TheTower(987.654)", names=[Peter, Ann, Raymond]]

NV here is a Groovy macro method which, which allows turning the passed variable expression into its name and value in the form of a simple NameAndValue class instance. NVL does the same for multiple variables (returning a list of NameAndValue|s).
(I used a different name for NVL, to allow for NV to take more than one variable expression parameter (and return e.g. a GString that contains a sequence of "name=$val" expressions without the enclosing list brackets), or to allow for NV to take additional parameters).

Such an extension would be useful, because it:
  1. Reduces the amount of boilerplate code one needs to write
  2. Makes the code more concise
  3. Removes errors such as: println "var0=$var0, var1=$var0"

I therefore propose we add this functionality to Groovy 2.5.x .


Apart from the general decision, open questions for me are:
  1. Where do we put macro extensions in the Groovy source code ?
  2. What names should we use for macro methods ?
I lean towards using C/C++ macro naming conventions as a guideline, i.e. using short, abbreviated, uppercase-only names such as NV = named variable, or NVL = named variable list, since:
  1. Macros allow for "magic" and are not really method calls in the classical sense
  2. Java do not have macros, so the hope would be that making them stick out a bit will make them less confusing for developers coming from Java to Groovy
  3. On the other hand C/C++ developers that are used to macros will immediately suspect that they are looking at a macro-like construct
  4. Independent of upper-/lowercase, brevity is important, especially for the proposed two NV/NVL macros, since it would imho be desirable for e.g. "NV(x)" to not take up more space than "x=$x"
In any case macro-method support in Groovy is a fantastic feature, which opens up completely new possibilities for language & framework developers - Go Groovy !-)
Please comment,
Cheers,
mg