question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

case class default values are non-lazy

See original GitHub issue
import pureconfig._
import pureconfig.generic.auto._

case class SampleConf(foo: String = ???)

ConfigSource.string("{ foo: bar }").load[SampleConf]

the above produces:

scala.NotImplementedError: an implementation is missing
  at scala.Predef$.$qmark$qmark$qmark(Predef.scala:347)
  at SampleConf$.apply$default$1(<console>:1)
  at anon$exportedReader$macro$16$1.inst$macro$1$lzycompute(<console>:1)
  at anon$exportedReader$macro$16$1.inst$macro$1(<console>:1)
  ... 35 elided

I would expect it to produce Right(SampleConf(bar)) since foo is defined. It seems the default values are being invoked even if they’re unneeded. This example is a little egregious (using ???) but the default value might involve a complex operation that we don’t want to be computed if it’s unnecessary.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
ruippeixotogcommented, Feb 25, 2022

Hi @dontgitit, a very late update on this: at the time I investigated the possibility of making default values lazy, but unfortunately it seems to be out of our control. We rely on shapeless’s Default case class for this, which does not provide us enough control to compute defaults only on demand. Getting default implementations seem to be possible only using macros that rely on internal compiler implementation details, so I don’t think we can replicate this on the PureConfig side either…

I guess my only recommendation would be really to use only simple side-effect free fields as defaults. With a bit of extra boilerplate, one can always achieve the same functionality and keep impure logic separate, e.g.:

case class MyConfig(myTag: Option[String]) {
  def myTagValue: String = myTagValue.getOrElse(getFromAWS())
}
1reaction
ruippeixotogcommented, Nov 23, 2021

Hi @dontgitit, thanks for filing this issue. Indeed, it looks like we are instantiating defaults earlier than we need to and that might be a problem (though I wouldn’t recommend setting any kind of heavy logic, particularly stateful logic, in the defaults of config classes).

I’m not sure we can avoid computing all defaults in all cases, but I’ll look into it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Scala: default value in case class constructor doesn't work
I'm creating a case class with default ...
Read more >
Object orientation - The Apache Groovy programming language
Anonymous inner classes help to eliminate verbosity in this case. ... If the argument is not supplied, the method assumes a default value....
Read more >
Function arguments - Manual - PHP
The default value must be a constant expression, not (for example) a variable, a class member or a function call. Note that any...
Read more >
Case classes with default parameters that depend on other ...
Hi there, I am completely new to scala. I am fascinated by the concept of case classes. To my understanding, it allows me...
Read more >
Options — Click Documentation (7.x)
In this case the option is of type INT because the default value is an integer. To show the default values when showing...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found