Make lambdas concise using enumerations?












0















Generally, we are looking to create a logging framework that can target human readable output as well as various structured data formats. So, a goal is minimizing code duplication in packaging the format functions. We created a library of functions that can be used to format log entries.



The client can then iterate a list of these as it processes each log record, in order to build the output string based on an arbitrary recipe.



for (LogFormatSteps logFormatStep : logFormatList {    

sb = logFormatStep.getRecipeStep().f(sb, record, altContent);
}


In discussions of Lambdas, they seem to be declared each in their own class extending their functional interface. This is a lot of overhead, javadocs notwithstanding. Is it going to be a problem if the lambdas are instead collected into an enumeration, as a way of reducing the number of classes that must ultimately be defined?



import java.util.Date;
import java.util.logging.LogRecord;

@FunctionalInterface
/** Appends stringbuilder with log information. */
interface LogFormatLambda {

/**
* Adds information to log entry text.
*
* @param logFragmentParam starting log fragment
* @param logRecordParam which may be consulted by lambda
* @param altContentParam which may be converted via toString() for use by lambda.
*/
public abstract StringBuilder apply(
StringBuilder logFragmentParam, LogRecord logRecordParam, Object altContentParam);
}

/** Formatter functions, in lambda notation, used by this formatter */
enum LogFormatFunctions {

/** Append urrent date and time. */
DATE((s, r, a) -> s.append(new Date(r.getMillis())).append(" ")),

/** Append log level. */
LEVEL((s, r, a) -> s.append(r.getLevel().getLocalizedName())),

/** Append blank line. */
LINE((s, r, a) -> s.append(System.getProperty("line.separator"))),

/** Append class name, or, lacking that, log name. */
CLASS(
(s, r, a) ->
(r.getSourceClassName() != null)
? s.append(" ").append(r.getSourceClassName())
: (r.getLoggerName() != null) ? s.append(" ").append(r.getLoggerName()) : s),

/** Append name of method generating the log entry. */
METHOD(
(s, r, a) ->
(r.getSourceMethodName() != null)
? s.append(" ").append(r.getSourceMethodName())
: s),

/**
* Append message text for the log entry, adding an indent.
*/
MESSAGE(
(s, r, a) ->
(a != null) ? s.append(" ").append(a.toString().replace("n", "n ")) : s);


/** Lambda field. */
LogFormatLambda f;

/**
* Constructor -loads lambdas.
*
* @param functionParam lambda for this process step
*/
LogFormatFunctions(LogFormatLambda functionParam) {
this.f = functionParam;
}

/**
* Appends log information.
*
* @param stringBuilderParam current log entry fragment
* @param logRecordParam log record (model)
* @param altContentParam object, provides toString() info to process steps
*/
StringBuilder f(
StringBuilder stringBuilderParam, LogRecord logRecordParam, Object altContentParam) {

return f.apply(stringBuilderParam, logRecordParam, altContentParam);
}
}


That said, are there other ways of organizing lambdas, e.g., via naming conventions package organization, etc., to avoid verbosity?



I did see posts about using lambdas to process enumerations, and enumerations to control dynamic linking of lambdas as strategy objects. But so far I haven't seen one that addressed the viability of using an enumeration for purposes of reducing clutter.










share|improve this question













migrated from codereview.stackexchange.com 2 hours ago


This question came from our site for peer programmer code reviews.



















  • that just looks like line noise at first glance, and second glance and third glance whomever is reading it and maintaining it will just rewrite it to be less obfuscated when they do take the time to figure out what it does. lambdas like everything else are easily abused when they are used as a hammer to make everything a nail. *see also: regexes and list comprehensions ( python ) and abusing functional idioms in non-functional languages ( as this is basically doing ).

    – Jarrod Roberson
    2 hours ago


















0















Generally, we are looking to create a logging framework that can target human readable output as well as various structured data formats. So, a goal is minimizing code duplication in packaging the format functions. We created a library of functions that can be used to format log entries.



The client can then iterate a list of these as it processes each log record, in order to build the output string based on an arbitrary recipe.



for (LogFormatSteps logFormatStep : logFormatList {    

sb = logFormatStep.getRecipeStep().f(sb, record, altContent);
}


In discussions of Lambdas, they seem to be declared each in their own class extending their functional interface. This is a lot of overhead, javadocs notwithstanding. Is it going to be a problem if the lambdas are instead collected into an enumeration, as a way of reducing the number of classes that must ultimately be defined?



import java.util.Date;
import java.util.logging.LogRecord;

@FunctionalInterface
/** Appends stringbuilder with log information. */
interface LogFormatLambda {

/**
* Adds information to log entry text.
*
* @param logFragmentParam starting log fragment
* @param logRecordParam which may be consulted by lambda
* @param altContentParam which may be converted via toString() for use by lambda.
*/
public abstract StringBuilder apply(
StringBuilder logFragmentParam, LogRecord logRecordParam, Object altContentParam);
}

/** Formatter functions, in lambda notation, used by this formatter */
enum LogFormatFunctions {

/** Append urrent date and time. */
DATE((s, r, a) -> s.append(new Date(r.getMillis())).append(" ")),

/** Append log level. */
LEVEL((s, r, a) -> s.append(r.getLevel().getLocalizedName())),

/** Append blank line. */
LINE((s, r, a) -> s.append(System.getProperty("line.separator"))),

/** Append class name, or, lacking that, log name. */
CLASS(
(s, r, a) ->
(r.getSourceClassName() != null)
? s.append(" ").append(r.getSourceClassName())
: (r.getLoggerName() != null) ? s.append(" ").append(r.getLoggerName()) : s),

/** Append name of method generating the log entry. */
METHOD(
(s, r, a) ->
(r.getSourceMethodName() != null)
? s.append(" ").append(r.getSourceMethodName())
: s),

/**
* Append message text for the log entry, adding an indent.
*/
MESSAGE(
(s, r, a) ->
(a != null) ? s.append(" ").append(a.toString().replace("n", "n ")) : s);


/** Lambda field. */
LogFormatLambda f;

/**
* Constructor -loads lambdas.
*
* @param functionParam lambda for this process step
*/
LogFormatFunctions(LogFormatLambda functionParam) {
this.f = functionParam;
}

/**
* Appends log information.
*
* @param stringBuilderParam current log entry fragment
* @param logRecordParam log record (model)
* @param altContentParam object, provides toString() info to process steps
*/
StringBuilder f(
StringBuilder stringBuilderParam, LogRecord logRecordParam, Object altContentParam) {

return f.apply(stringBuilderParam, logRecordParam, altContentParam);
}
}


That said, are there other ways of organizing lambdas, e.g., via naming conventions package organization, etc., to avoid verbosity?



I did see posts about using lambdas to process enumerations, and enumerations to control dynamic linking of lambdas as strategy objects. But so far I haven't seen one that addressed the viability of using an enumeration for purposes of reducing clutter.










share|improve this question













migrated from codereview.stackexchange.com 2 hours ago


This question came from our site for peer programmer code reviews.



















  • that just looks like line noise at first glance, and second glance and third glance whomever is reading it and maintaining it will just rewrite it to be less obfuscated when they do take the time to figure out what it does. lambdas like everything else are easily abused when they are used as a hammer to make everything a nail. *see also: regexes and list comprehensions ( python ) and abusing functional idioms in non-functional languages ( as this is basically doing ).

    – Jarrod Roberson
    2 hours ago
















0












0








0








Generally, we are looking to create a logging framework that can target human readable output as well as various structured data formats. So, a goal is minimizing code duplication in packaging the format functions. We created a library of functions that can be used to format log entries.



The client can then iterate a list of these as it processes each log record, in order to build the output string based on an arbitrary recipe.



for (LogFormatSteps logFormatStep : logFormatList {    

sb = logFormatStep.getRecipeStep().f(sb, record, altContent);
}


In discussions of Lambdas, they seem to be declared each in their own class extending their functional interface. This is a lot of overhead, javadocs notwithstanding. Is it going to be a problem if the lambdas are instead collected into an enumeration, as a way of reducing the number of classes that must ultimately be defined?



import java.util.Date;
import java.util.logging.LogRecord;

@FunctionalInterface
/** Appends stringbuilder with log information. */
interface LogFormatLambda {

/**
* Adds information to log entry text.
*
* @param logFragmentParam starting log fragment
* @param logRecordParam which may be consulted by lambda
* @param altContentParam which may be converted via toString() for use by lambda.
*/
public abstract StringBuilder apply(
StringBuilder logFragmentParam, LogRecord logRecordParam, Object altContentParam);
}

/** Formatter functions, in lambda notation, used by this formatter */
enum LogFormatFunctions {

/** Append urrent date and time. */
DATE((s, r, a) -> s.append(new Date(r.getMillis())).append(" ")),

/** Append log level. */
LEVEL((s, r, a) -> s.append(r.getLevel().getLocalizedName())),

/** Append blank line. */
LINE((s, r, a) -> s.append(System.getProperty("line.separator"))),

/** Append class name, or, lacking that, log name. */
CLASS(
(s, r, a) ->
(r.getSourceClassName() != null)
? s.append(" ").append(r.getSourceClassName())
: (r.getLoggerName() != null) ? s.append(" ").append(r.getLoggerName()) : s),

/** Append name of method generating the log entry. */
METHOD(
(s, r, a) ->
(r.getSourceMethodName() != null)
? s.append(" ").append(r.getSourceMethodName())
: s),

/**
* Append message text for the log entry, adding an indent.
*/
MESSAGE(
(s, r, a) ->
(a != null) ? s.append(" ").append(a.toString().replace("n", "n ")) : s);


/** Lambda field. */
LogFormatLambda f;

/**
* Constructor -loads lambdas.
*
* @param functionParam lambda for this process step
*/
LogFormatFunctions(LogFormatLambda functionParam) {
this.f = functionParam;
}

/**
* Appends log information.
*
* @param stringBuilderParam current log entry fragment
* @param logRecordParam log record (model)
* @param altContentParam object, provides toString() info to process steps
*/
StringBuilder f(
StringBuilder stringBuilderParam, LogRecord logRecordParam, Object altContentParam) {

return f.apply(stringBuilderParam, logRecordParam, altContentParam);
}
}


That said, are there other ways of organizing lambdas, e.g., via naming conventions package organization, etc., to avoid verbosity?



I did see posts about using lambdas to process enumerations, and enumerations to control dynamic linking of lambdas as strategy objects. But so far I haven't seen one that addressed the viability of using an enumeration for purposes of reducing clutter.










share|improve this question














Generally, we are looking to create a logging framework that can target human readable output as well as various structured data formats. So, a goal is minimizing code duplication in packaging the format functions. We created a library of functions that can be used to format log entries.



The client can then iterate a list of these as it processes each log record, in order to build the output string based on an arbitrary recipe.



for (LogFormatSteps logFormatStep : logFormatList {    

sb = logFormatStep.getRecipeStep().f(sb, record, altContent);
}


In discussions of Lambdas, they seem to be declared each in their own class extending their functional interface. This is a lot of overhead, javadocs notwithstanding. Is it going to be a problem if the lambdas are instead collected into an enumeration, as a way of reducing the number of classes that must ultimately be defined?



import java.util.Date;
import java.util.logging.LogRecord;

@FunctionalInterface
/** Appends stringbuilder with log information. */
interface LogFormatLambda {

/**
* Adds information to log entry text.
*
* @param logFragmentParam starting log fragment
* @param logRecordParam which may be consulted by lambda
* @param altContentParam which may be converted via toString() for use by lambda.
*/
public abstract StringBuilder apply(
StringBuilder logFragmentParam, LogRecord logRecordParam, Object altContentParam);
}

/** Formatter functions, in lambda notation, used by this formatter */
enum LogFormatFunctions {

/** Append urrent date and time. */
DATE((s, r, a) -> s.append(new Date(r.getMillis())).append(" ")),

/** Append log level. */
LEVEL((s, r, a) -> s.append(r.getLevel().getLocalizedName())),

/** Append blank line. */
LINE((s, r, a) -> s.append(System.getProperty("line.separator"))),

/** Append class name, or, lacking that, log name. */
CLASS(
(s, r, a) ->
(r.getSourceClassName() != null)
? s.append(" ").append(r.getSourceClassName())
: (r.getLoggerName() != null) ? s.append(" ").append(r.getLoggerName()) : s),

/** Append name of method generating the log entry. */
METHOD(
(s, r, a) ->
(r.getSourceMethodName() != null)
? s.append(" ").append(r.getSourceMethodName())
: s),

/**
* Append message text for the log entry, adding an indent.
*/
MESSAGE(
(s, r, a) ->
(a != null) ? s.append(" ").append(a.toString().replace("n", "n ")) : s);


/** Lambda field. */
LogFormatLambda f;

/**
* Constructor -loads lambdas.
*
* @param functionParam lambda for this process step
*/
LogFormatFunctions(LogFormatLambda functionParam) {
this.f = functionParam;
}

/**
* Appends log information.
*
* @param stringBuilderParam current log entry fragment
* @param logRecordParam log record (model)
* @param altContentParam object, provides toString() info to process steps
*/
StringBuilder f(
StringBuilder stringBuilderParam, LogRecord logRecordParam, Object altContentParam) {

return f.apply(stringBuilderParam, logRecordParam, altContentParam);
}
}


That said, are there other ways of organizing lambdas, e.g., via naming conventions package organization, etc., to avoid verbosity?



I did see posts about using lambdas to process enumerations, and enumerations to control dynamic linking of lambdas as strategy objects. But so far I haven't seen one that addressed the viability of using an enumeration for purposes of reducing clutter.







java iterator lambda






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 7 hours ago









John MeyerJohn Meyer

1041




1041




migrated from codereview.stackexchange.com 2 hours ago


This question came from our site for peer programmer code reviews.









migrated from codereview.stackexchange.com 2 hours ago


This question came from our site for peer programmer code reviews.















  • that just looks like line noise at first glance, and second glance and third glance whomever is reading it and maintaining it will just rewrite it to be less obfuscated when they do take the time to figure out what it does. lambdas like everything else are easily abused when they are used as a hammer to make everything a nail. *see also: regexes and list comprehensions ( python ) and abusing functional idioms in non-functional languages ( as this is basically doing ).

    – Jarrod Roberson
    2 hours ago





















  • that just looks like line noise at first glance, and second glance and third glance whomever is reading it and maintaining it will just rewrite it to be less obfuscated when they do take the time to figure out what it does. lambdas like everything else are easily abused when they are used as a hammer to make everything a nail. *see also: regexes and list comprehensions ( python ) and abusing functional idioms in non-functional languages ( as this is basically doing ).

    – Jarrod Roberson
    2 hours ago



















that just looks like line noise at first glance, and second glance and third glance whomever is reading it and maintaining it will just rewrite it to be less obfuscated when they do take the time to figure out what it does. lambdas like everything else are easily abused when they are used as a hammer to make everything a nail. *see also: regexes and list comprehensions ( python ) and abusing functional idioms in non-functional languages ( as this is basically doing ).

– Jarrod Roberson
2 hours ago







that just looks like line noise at first glance, and second glance and third glance whomever is reading it and maintaining it will just rewrite it to be less obfuscated when they do take the time to figure out what it does. lambdas like everything else are easily abused when they are used as a hammer to make everything a nail. *see also: regexes and list comprehensions ( python ) and abusing functional idioms in non-functional languages ( as this is basically doing ).

– Jarrod Roberson
2 hours ago












2 Answers
2






active

oldest

votes


















1














lambdas are just syntactic sugar, they generate the exact same byte code that anonymous inner classes would, as in they each result in a implementation of a class with a single method that compiles to a separate file. This obfuscation you have introduced does nothing to solve the "problem" you are trying to solve. Which is not really a problem.



Do you realize that enum can implement an interface and that would be a better way of doing this from an encapsulation standpoint if nothing else. then you do not even need lambda obfuscation you just implement the method on each new instance directly.






share|improve this answer































    0














    In Java, the idiomatic way to group a bunch of functions is just a plain old class with plain old methods. Then your logFormatList looks something like List.of(LogFormatFunctions::date, LogFormatFunctions::level).



    If you really want something more concise than that, my personal preference would be some sort of format string, like "%d %l: %m" that you then parse to dynamically create your List<LogFormatLambda>.






    share|improve this answer























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "131"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f387160%2fmake-lambdas-concise-using-enumerations%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      lambdas are just syntactic sugar, they generate the exact same byte code that anonymous inner classes would, as in they each result in a implementation of a class with a single method that compiles to a separate file. This obfuscation you have introduced does nothing to solve the "problem" you are trying to solve. Which is not really a problem.



      Do you realize that enum can implement an interface and that would be a better way of doing this from an encapsulation standpoint if nothing else. then you do not even need lambda obfuscation you just implement the method on each new instance directly.






      share|improve this answer




























        1














        lambdas are just syntactic sugar, they generate the exact same byte code that anonymous inner classes would, as in they each result in a implementation of a class with a single method that compiles to a separate file. This obfuscation you have introduced does nothing to solve the "problem" you are trying to solve. Which is not really a problem.



        Do you realize that enum can implement an interface and that would be a better way of doing this from an encapsulation standpoint if nothing else. then you do not even need lambda obfuscation you just implement the method on each new instance directly.






        share|improve this answer


























          1












          1








          1







          lambdas are just syntactic sugar, they generate the exact same byte code that anonymous inner classes would, as in they each result in a implementation of a class with a single method that compiles to a separate file. This obfuscation you have introduced does nothing to solve the "problem" you are trying to solve. Which is not really a problem.



          Do you realize that enum can implement an interface and that would be a better way of doing this from an encapsulation standpoint if nothing else. then you do not even need lambda obfuscation you just implement the method on each new instance directly.






          share|improve this answer













          lambdas are just syntactic sugar, they generate the exact same byte code that anonymous inner classes would, as in they each result in a implementation of a class with a single method that compiles to a separate file. This obfuscation you have introduced does nothing to solve the "problem" you are trying to solve. Which is not really a problem.



          Do you realize that enum can implement an interface and that would be a better way of doing this from an encapsulation standpoint if nothing else. then you do not even need lambda obfuscation you just implement the method on each new instance directly.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 1 hour ago









          Jarrod RobersonJarrod Roberson

          19.9k64481




          19.9k64481

























              0














              In Java, the idiomatic way to group a bunch of functions is just a plain old class with plain old methods. Then your logFormatList looks something like List.of(LogFormatFunctions::date, LogFormatFunctions::level).



              If you really want something more concise than that, my personal preference would be some sort of format string, like "%d %l: %m" that you then parse to dynamically create your List<LogFormatLambda>.






              share|improve this answer




























                0














                In Java, the idiomatic way to group a bunch of functions is just a plain old class with plain old methods. Then your logFormatList looks something like List.of(LogFormatFunctions::date, LogFormatFunctions::level).



                If you really want something more concise than that, my personal preference would be some sort of format string, like "%d %l: %m" that you then parse to dynamically create your List<LogFormatLambda>.






                share|improve this answer


























                  0












                  0








                  0







                  In Java, the idiomatic way to group a bunch of functions is just a plain old class with plain old methods. Then your logFormatList looks something like List.of(LogFormatFunctions::date, LogFormatFunctions::level).



                  If you really want something more concise than that, my personal preference would be some sort of format string, like "%d %l: %m" that you then parse to dynamically create your List<LogFormatLambda>.






                  share|improve this answer













                  In Java, the idiomatic way to group a bunch of functions is just a plain old class with plain old methods. Then your logFormatList looks something like List.of(LogFormatFunctions::date, LogFormatFunctions::level).



                  If you really want something more concise than that, my personal preference would be some sort of format string, like "%d %l: %m" that you then parse to dynamically create your List<LogFormatLambda>.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 1 hour ago









                  Karl BielefeldtKarl Bielefeldt

                  119k29212408




                  119k29212408






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Software Engineering Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f387160%2fmake-lambdas-concise-using-enumerations%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

                      is 'sed' thread safe

                      How to make a Squid Proxy server?