- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Lazy evaluationg Parameters
Mon, 2009-03-16, 01:35
Hello,
I am pretty new in scala and I was wondering if the following is possible:
I am writing up a custom logging facility for the application I write, and it
would be really great if it was possible to have the parameters of the logging
calls lazily evaluated. Something like:
logger.debug("Something went wrong. Reason: {}", stuff.reason)
now it would be great if stuff.reason was only called when the debuglevel was
set high enough that the message was actually logged.
Thanks in advance
Peter
Mon, 2009-03-16, 01:57
#2
Re: Lazy evaluationg Parameters
On Mon, Mar 16, 2009 at 12:35 AM, Peter <ptriller@soapwars.de> wrote:
Hello,
I am pretty new in scala and I was wondering if the following is possible:
I am writing up a custom logging facility for the application I write, and it
would be really great if it was possible to have the parameters of the logging
calls lazily evaluated. Something like:
logger.debug("Something went wrong. Reason: {}", stuff.reason)
def debug(str: => String, reason: => Any) { if (levelHighEnough) { println(str+": "+reason }}
The => String (and => Any) makes the parameters call-by-name (lazy)
Does that help?
Thanks,
David
now it would be great if stuff.reason was only called when the debuglevel was
set high enough that the message was actually logged.
Thanks in advance
Peter
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Mon, 2009-03-16, 02:27
#3
Re: Lazy evaluationg Parameters
Hello,
thanks for the lightning quick responses, this was exactly what I needed
Peter
Mon, 2009-03-16, 11:07
#4
Re: Lazy evaluationg Parameters
Note that these aren't lazy parameters, the expression is re-evaluated each time, you might want to write
def log(level : LogLevel, message : => String) {
lazy val evaluatedMessage = message
...
and use evaluatedMessage further on
-Carsten
On Mon, Mar 16, 2009 at 2:09 AM, Peter <ptriller@soapwars.de> wrote:
def log(level : LogLevel, message : => String) {
lazy val evaluatedMessage = message
...
and use evaluatedMessage further on
-Carsten
On Mon, Mar 16, 2009 at 2:09 AM, Peter <ptriller@soapwars.de> wrote:
Hello,
thanks for the lightning quick responses, this was exactly what I needed
Peter
Mon, 2009-03-16, 11:27
#5
Re: Lazy evaluationg Parameters
I'd vote for def log(level: LogLevel, lazy message: String)
2009/3/16 Carsten Saager :
> Note that these aren't lazy parameters, the expression is re-evaluated each
> time, you might want to write
>
> def log(level : LogLevel, message : => String) {
> lazy val evaluatedMessage = message
> ...
>
> and use evaluatedMessage further on
>
> -Carsten
>
> On Mon, Mar 16, 2009 at 2:09 AM, Peter wrote:
>>
>> Hello,
>>
>> thanks for the lightning quick responses, this was exactly what I needed
>>
>>
>>
>> Peter
>
>
Mon, 2009-03-16, 14:27
#6
Re: Lazy evaluationg Parameters
+1, as I find the idiom below quite "boilerplatey"
But it needs to be specified what happens for
class Foo {
def bar(lazy msg:String)...
def foo(msg:String)..
def nbar(lazy msg:String)...
def nfoo(msg: =>String)..
}
class Bar extends Foo {
override def bar(msg:String)...
override def foo(lazy msg:String)..
override def nbar(msg: =>String)...
override def nfoo(lazy msg:String)..
}
especially when super.xxx(msg) gets called in the overrides
-Carsten
On Mon, Mar 16, 2009 at 11:21 AM, Ricky Clarkson <ricky.clarkson@gmail.com> wrote:
But it needs to be specified what happens for
class Foo {
def bar(lazy msg:String)...
def foo(msg:String)..
def nbar(lazy msg:String)...
def nfoo(msg: =>String)..
}
class Bar extends Foo {
override def bar(msg:String)...
override def foo(lazy msg:String)..
override def nbar(msg: =>String)...
override def nfoo(lazy msg:String)..
}
especially when super.xxx(msg) gets called in the overrides
-Carsten
On Mon, Mar 16, 2009 at 11:21 AM, Ricky Clarkson <ricky.clarkson@gmail.com> wrote:
I'd vote for def log(level: LogLevel, lazy message: String)
2009/3/16 Carsten Saager <csaager@gmail.com>:
> Note that these aren't lazy parameters, the expression is re-evaluated each
> time, you might want to write
>
> def log(level : LogLevel, message : => String) {
> lazy val evaluatedMessage = message
> ...
>
> and use evaluatedMessage further on
>
> -Carsten
>
> On Mon, Mar 16, 2009 at 2:09 AM, Peter <ptriller@soapwars.de> wrote:
>>
>> Hello,
>>
>> thanks for the lightning quick responses, this was exactly what I needed
>>
>>
>>
>> Peter
>
>
Mon, 2009-03-16, 15:07
#7
Re: Lazy evaluationg Parameters
On Monday March 16 2009, Ricky Clarkson wrote:
> I'd vote for def log(level: LogLevel, lazy message: String)
But if the message is not fixed and requires non-trivial computation to
produce, you don't want to do that unless you know you're going to need
it, and that knowledge resides (should reside) only in the log
function. So the desire for some kind of lazy evaluation is legitimate.
The pattern for that in Scala is using call-by-name and evaluating that
value either zero or one times, depending on the log settings at the
time of the call. (And another anonymous function is born!)
I assume Scala's overload resolution can distinguish "function yielding
String" from String, so the caller can choose which to use to avoid
creating an anonymous function for every call to log(...).
Randall Schulz
> 2009/3/16 Carsten Saager :
> > Note that these aren't lazy parameters, the expression is
> > re-evaluated each time, you might want to write
> >
> > def log(level : LogLevel, message : => String) {
> > lazy val evaluatedMessage = message
> > ...
> >
> > and use evaluatedMessage further on
> >
> > -Carsten
> >
> > On Mon, Mar 16, 2009 at 2:09 AM, Peter wrote:
> >> Hello,
> >>
> >> thanks for the lightning quick responses, this was exactly what I
> >> needed
> >>
> >>
> >>
> >> Peter
Mon, 2009-03-16, 15:17
#8
Re: Lazy evaluationg Parameters
I'm not sure you noticed 'lazy' in my snippet. :)
2009/3/16 Randall R Schulz :
> On Monday March 16 2009, Ricky Clarkson wrote:
>> I'd vote for def log(level: LogLevel, lazy message: String)
>
> But if the message is not fixed and requires non-trivial computation to
> produce, you don't want to do that unless you know you're going to need
> it, and that knowledge resides (should reside) only in the log
> function. So the desire for some kind of lazy evaluation is legitimate.
> The pattern for that in Scala is using call-by-name and evaluating that
> value either zero or one times, depending on the log settings at the
> time of the call. (And another anonymous function is born!)
>
> I assume Scala's overload resolution can distinguish "function yielding
> String" from String, so the caller can choose which to use to avoid
> creating an anonymous function for every call to log(...).
>
>
> Randall Schulz
>
>
>> 2009/3/16 Carsten Saager :
>> > Note that these aren't lazy parameters, the expression is
>> > re-evaluated each time, you might want to write
>> >
>> > def log(level : LogLevel, message : => String) {
>> > lazy val evaluatedMessage = message
>> > ...
>> >
>> > and use evaluatedMessage further on
>> >
>> > -Carsten
>> >
>> > On Mon, Mar 16, 2009 at 2:09 AM, Peter wrote:
>> >> Hello,
>> >>
>> >> thanks for the lightning quick responses, this was exactly what I
>> >> needed
>> >>
>> >>
>> >>
>> >> Peter
>
>
>
Mon, 2009-03-16, 15:27
#9
Re: Lazy evaluationg Parameters
On Monday March 16 2009, Ricky Clarkson wrote:
> I'm not sure you noticed 'lazy' in my snippet. :)
Indeed I did not.
Randall Schulz
trait Logger {
def log(level : LogLevel, message : => String) : Unit
}
The => String is a non-argument function that returns a string. It will be evaluated when used. Remmeber though, that you're passing a closure.
On Sun, Mar 15, 2009 at 8:35 PM, Peter <ptriller@soapwars.de> wrote: