I see. That's fair enough.
> Oh, sorry if I came across as feeling disdain for implicits as a feature. To
> the contrary, implicits are one of the things I love most about Scala. I
> just didn't feel it was appropriate to use implicits in this particular
> case, that's all.
>
> Maybe I'm too used to the logger.warn() pattern... it just looked to me that
> a method call like warn() without any context could mean any number of
> things, including popping up a message dialog in a GUI, whereas
> logger.warn() is pretty self-describing without further ado.
>
> You increase confusion ever so slightly, yet you don't really gain much.
>
>
> On 18.06.2009 10:13, Ricky Clarkson wrote:
>>
>> You seem to consider implicit values as hoops; I do not.
>>
>> I would generally rather write warn("We assumed that x will never be
>> greater than y, and that assumption is incorrect") than
>> logger.warn("We assumed that..."), simply because the logger bit is
>> irrelevant to understanding that code.
>>
>> Scala lets us do that without our code gaining bindings to global
>> variables/state, which is an improvement over other languages. Then
>> you call it jumping through hoops, and start talking about "a time and
>> a place.". It's now, and here.
>>
>> I feel more strongly about your disdain for the feature than I do
>> about actually typing logger.warn(s) though.
>>
>> 2009/6/18 Ivan Todoroski <
grnch_lists@...>:
>>>
>>> The question is why should you go through extra hoops (however minor) to
>>> recognize a logging statement?
>>>
>>> There is a time and place for implicits, and this is not it - the use
>>> case
>>> here seems pretty weak and contrived. There is nothing wrong with typing
>>> logger.warn(...), it clearly documents that it's a logging statement, and
>>> such statements are simply not frequent enough to save much typing by
>>> omitting the "logger" part. I know that implicits are cool, but there is
>>> no
>>> need to abuse them for every little thing.
>>>
>>>
>>> On 18.06.2009 09:03, Ricky Clarkson wrote:
>>>>
>>>> Surely you can find where warn is defined by searching for an import
>>>> containing 'warn'. Or jump to declaration in your IDE.
>>>>
>>>> 2009/6/18 Blair Zajac <
blair@...>:
>>>>>
>>>>> On Jun 17, 2009, at 9:57 PM, Walter Smith wrote:
>>>>>
>>>>>> Hi!
>>>>>>
>>>>>> I think logging should be a part of the core libraries of a
>>>>>> language...
>>>>>> it
>>>>>> is such an unbeloved matter that at least the logging api to use
>>>>>> should
>>>>>> not
>>>>>> be something to discuss about in every project.
>>>>>>
>>>>>> There is one logging framework built into Java, but it is not very
>>>>>> well
>>>>>> received. Especially in the Java enterprise world, log4j is used much
>>>>>> more
>>>>>> often for some good reasons, but you can't deploy multiple
>>>>>> configurations
>>>>>> for the same classes used in different enterprise applications within
>>>>>> one
>>>>>> JVM, if it's part of the parent class loader, i.e. it's used by the
>>>>>> container itself. And there is a third comprehensive logging framework
>>>>>> competing: logback. So it's a good idea for frameworks to be able to
>>>>>> use
>>>>>> a
>>>>>> generic logging api, so that a customer can use *one* framework for
>>>>>> all
>>>>>> the
>>>>>> frameworks in use. And generally Scala is right now in the role of
>>>>>> such
>>>>>> a
>>>>>> framework, isn't it?
>>>>>>
>>>>>> I still see Apache commons logging being used a lot. I think this is
>>>>>> not
>>>>>> much better than using prinln directly! It not only lacks important
>>>>>> features
>>>>>> like formatting messages only when needed, or MDCs; I understand that
>>>>>> it
>>>>>> still causes perm gen memory leaks when hot deploying.
>>>>>>
>>>>>> There is a much better solution, though: SLF4J... IMHO every Java or
>>>>>> Scala
>>>>>> programmer should know it.
>>>>>>
>>>>>> But SLF4J is a Java api, so I tried to wrap it in "the Scala way":
>>>>>> 1. Logging is a trait that defines the logger using the name of the
>>>>>> class
>>>>>> you mix it into; a common and regularly used pattern now easily
>>>>>> provided
>>>>>> by
>>>>>> a library... that's what I love Scala for.
>>>>>> 2. There is a sealed trait LogLevel with objects for error, info, etc.
>>>>>> that
>>>>>> you can pass around, e.g. into a library or to configure instances of
>>>>>> a
>>>>>> class. To actually log at a LogLevel, you simply apply your parameters
>>>>>> to
>>>>>> it; the logger can be passed in as a implicit argument.
>>>>>> 3. The arguments that are used for your format are passed in by name,
>>>>>> so
>>>>>> only get evaluated when the log level is enabled, i.e. it's ok to call
>>>>>> debug("client dns name {}",
>>>>>> java.net.InetAddress.getByAddress(client));
>>>>>> the
>>>>>> lookup will only be made, if the debug log level is enabled... Scala
>>>>>> rules!
>>>>>>
>>>>>> BTW: Is there a simpler way to get an Array[Byte] literal than
>>>>>> Array(192.byteValue,168.byteValue,178.byteValue,1.byteValue)?
>>>>>
>>>>> The point of slf4j's format string, i.e. "The foobar's value is {}", is
>>>>> to
>>>>> avoid interpolation cost if the log message will not be used.
>>>>>
>>>>> The Scala way of dealing with this is to use by-name arguments. So you
>>>>> end
>>>>> up with
>>>>>
>>>>> trait Logger
>>>>> {
>>>>> def warn(msg : => String) : Unit
>>>>> }
>>>>>
>>>>> trait Slf4jLogger extends Logger
>>>>> {
>>>>> private val myRealLogger = Logger.getLogger(this.getClass.getName)
>>>>>
>>>>> private val isWarnEnabled = myRealLogger.isWarnEnabled
>>>>>
>>>>> def warn(msg : => String) : Unit
>>>>> {
>>>>> if (isWarnEnabled) {
>>>>> myRealLogger.warn(msg)
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>> Then call it
>>>>>
>>>>> logger.warn("The foobar's value is " + foobar + ".")
>>>>>
>>>>> the string concatenation here won't be done unless
>>>>> my_real_logger.isWarnEnabled is true.
>>>>>
>>>>> BTW, I'm not a fan of implicits here. I'd much rather see a call
>>>>>
>>>>> logger.warn("It blew up!")
>>>>>
>>>>> than
>>>>>
>>>>> warn("It blew up!")
>>>>>
>>>>> It's clear I'm calling a logger and don't need to wonder where warn()
>>>>> is
>>>>> defined.
>>>>>
>>>>> Check out Lift's logger. It does this nicely and has a slf4j layer.
>>>>>
>>>>>
>>>>>
>>>>>
http://github.com/dpp/liftweb/blob/338119b8d7a76adcb9f45e9aa8a2b946d9c81118/lift-util/src/main/scala/net/liftweb/util/Log.scala>>>>>
>>>>>
>>>>>
http://github.com/dpp/liftweb/blob/338119b8d7a76adcb9f45e9aa8a2b946d9c81118/lift-util/src/main/scala/net/liftweb/util/Slf4jLog.scala>>>>>
>>>>> Regards,
>>>>> Blair
>>>>>
>>>>> --
>>>>> Blair Zajac, Ph.D.
>>>>> CTO, OrcaWare Technologies
>>>>> <
blair@...>
>>>>> Subversion training, consulting and support
>>>>>
http://www.orcaware.com/svn/>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>>
>
>