Make lambdas concise using enumerations?
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
migrated from codereview.stackexchange.com 2 hours ago
This question came from our site for peer programmer code reviews.
add a comment |
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
migrated from codereview.stackexchange.com 2 hours ago
This question came from our site for peer programmer code reviews.
that just looks likeline 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.lambda
s 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
add a comment |
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
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
java iterator lambda
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 likeline 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.lambda
s 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
add a comment |
that just looks likeline 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.lambda
s 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. lambda
s 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. lambda
s 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
add a comment |
2 Answers
2
active
oldest
votes
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.
add a comment |
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>
.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered 1 hour ago
Jarrod RobersonJarrod Roberson
19.9k64481
19.9k64481
add a comment |
add a comment |
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>
.
add a comment |
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>
.
add a comment |
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>
.
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>
.
answered 1 hour ago
Karl BielefeldtKarl Bielefeldt
119k29212408
119k29212408
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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.lambda
s 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