[ 
https://jira.qos.ch/browse/SLF4J-371?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18767#comment-18767
 ] 

MiNG commented on SLF4J-371:
----------------------------

In the @HermanBovens case, does anyone think about how to define the method 
signature of `debug`, is the above code able to compile?

In Java, function/method is not the first-class type, every lambda expression 
must be converted to a SAM interface in compile time.

So, in the above case, if you want to use like this:
{code:java}
LOG.debug("can mix {} and {} arguments", "normal", () -> "lambda");{code}
you must declare the method with fixed parameters:
{code:java}
void debug(String format, Object arg1, Supplier<?> arg2);{code}

How about the varargs?
In the varargs case the parameter type MUST declare as Object.
{code:java}
void debug(String format, Object... args);{code}
Then, we MUST call it like this:
{code:java}
LOG.debug("can mix {} and {} arguments", "normal", (Supplier<?>)() -> 
"lambda");{code}

Isn't that weird?

So, I think the following method signature is more friendly to users:
{code:java}
// Supply the formatted string to log
debug(Function<MessageFormatter, String> messageSupplier);

// Invoke the log method in the closure lazily
debug(Consumer<Logger> lazyLog);
{code}

call example:
{code:java}
// Supply the formatted string to log
logger.debug(fmt -> "xxx" + Json.serialize(huge));

// Invoke the log method in the closure lazily
logger.debug(log -> log.invoke("xxx {}", Json.serialize(huge)));{code}

> Support the lambda expression in the Logger
> -------------------------------------------
>
>                 Key: SLF4J-371
>                 URL: https://jira.qos.ch/browse/SLF4J-371
>             Project: SLF4J
>          Issue Type: Improvement
>          Components: Core API
>    Affects Versions: 1.7.22
>            Reporter: MiNG
>            Assignee: SLF4J developers list
>
> In some cases, we don't want to calculate the expression for logging eagerly 
> cause the performance reason. Then, we would write the code like the 
> following:
> ```
>     if (LOGGER.isWarnEnabled())
>     {
>        LOGGER.warn("some message: {}", Json.serialize(obj));
>     }
> ```
> Before JDK8, there is no way to encapsulate the above code, because the 
> expression is always calculated before passed as an argument. So, many "if"s 
> appear in the code and smell badly.
> Now, the lambda expression is supported by JDK8, the above could be 
> simplified like following:
> ```
>     LOGGER.warn(formatter -> formatter.format("some message: {}", 
> Json.serialize(obj)));
> ```
> With the default method definition in the org.slf4j.Logger:
> ```
>     public interface Logger
>     {
>       default void warn(Function<MessageFormatter, String> messageSupplier)
>       {
>         if (this.isWarnEnabled())
>         {
>           /* Calculate the expression only if the WARN level logging is 
> enabled. */
>           this.warn(messageSupplier.apply(this.getFormatter()));
>         }
>       }
>     }
> ```



--
This message was sent by Atlassian JIRA
(v7.3.1#73012)
_______________________________________________
slf4j-dev mailing list
[email protected]
http://mailman.qos.ch/mailman/listinfo/slf4j-dev

Reply via email to