scalapuzzlers / scalapuzzlers.github.com

Github Pages behind scalapuzzlers.com
www.scalapuzzlers.com
161 stars 53 forks source link

You Blockhead! init order in ctor vs block #85

Closed som-snytt closed 11 years ago

som-snytt commented 11 years ago

In this case, implicits are in play.

It's kind of nice to know that no matter how shoddy this submission, A.P. wlll improve it and, anyways, it can't possibly break the build.

"You blockhead" is of course a reference to Charlie Brown. I'm not partial to it. Footnote, however, the other day I realized that it really is true that "Happiness is a warm puppy."

demobox commented 11 years ago

Will try to review today - just read the scala-lang thread ;-)

demobox commented 11 years ago

Will try to review today

Well, OK, a bit optimistic there. But time for a next step, at least:

class Markup {
  def apply(normalPrice: Int) = normalPrice * 2
}
class TouristMarkup extends Markup {
  override def apply(normalPrice: Int) = normalPrice * 20
}
def makeLabel(price: Int)(implicit m: Markup) = s"Price: ${m(price)}" 

object OldFashionedMarket {
  def main(args: Array[String]): Unit = {
    implicit val normalMarkup = new Markup
    Console println makeLabel(3)
    implicit val touristMarkup = new TouristMarkup
    Console println makeLabel(5)
  }
}
object ModernMarket extends App { // "modern" because it extends App ;-)
  implicit val normalMarkup = new Markup
  Console println makeLabel(3)
  implicit val touristMarkup = new TouristMarkup
  Console println makeLabel(5)
}
OldFashionedMarket.main(Array())
ModernMarket.main(Array())

This version tries to motivate the variables and implicits a little bit, and attempts to "hide" the block vs. ctor part. I don't like the two main(Array()) calls at the end, though...any suggestions there?

som-snytt commented 11 years ago

Did you see this one from last Friday? It's a shame for some bugs to get fixed.

https://groups.google.com/forum/#!topic/scala-internals/qWjq6V6lbKw

som-snytt commented 11 years ago

In my own quickie code, I write ModernMarket main null.

Yes, Foo Bar Baz gets old after a while.

Shouldn't the modern market values reflect inflation?

Shouldn't the bazaar reflect a haggle factor?

I guess I go overboard on narrative. Mise-en-scene. Ambiance.

som-snytt commented 11 years ago

http://stackoverflow.com/questions/19106699/nested-map-withdefaultvalue-changes-default-value

Why don't people read the puzzlers? There ought to be a ML, or maybe a newsletter.

demobox commented 11 years ago

Why don't people read the puzzlers? There ought to be a ML, or maybe a newsletter.

"Independently discovered puzzlers" like this at least validate our conclusion that the behaviour was indeed puzzling.

demobox commented 11 years ago

Shouldn't the modern market values reflect inflation?

I was thinking about other factors like this and "bargaining skill" too, but didn't want to change the original Markup trait too much. All for more mise-en-scene!

demobox commented 11 years ago

@som-snytt Thoughts on updating this..?

som-snytt commented 11 years ago

We need a "jigsaw puzzle piece" icon to display next to puzzlers that have been independently verified as puzzling.

Your version gets my +1. I can get around to updating in a short while, or you can feel free.

Edit: thanks for taking it over. Your name should be on the page. Like Will Shortz. It would also be nice to have a Simpsons tie-in.

http://en.wikipedia.org/wiki/Homer_and_Lisa_Exchange_Cross_Words

demobox commented 11 years ago

See http://scalapuzzlers.com/#pzzlr-043. Thanks, @som-snytt!

som-snytt commented 8 years ago

I went looking for the useful error message, but then I couldn't trigger it.

       if (best.isFailure) {
          // If there is no winner, and we witnessed and recorded a divergence error,
          // our recovery attempt has failed, so we must now issue it.
          DivergentImplicitRecovery.issueSavedDivergentError()

          if (invalidImplicits.nonEmpty)
            setAddendum(pos, () =>
              s"\n Note: implicit ${invalidImplicits.head} is not applicable here because it comes after the application point and it lacks an explicit result type"
            )
        }

I had to google for it. I guess conversions and vals are different.

http://stackoverflow.com/questions/2731185/why-does-this-explicit-call-of-a-scala-method-allow-it-to-be-implicitly-resolved

scala> :pa
// Entering paste mode (ctrl-D to finish)

class C {
  def f() = "A" ==> "B"
  implicit def string2Wrapper(s: String) = new Wrapper(s)
  class Wrapper(s: String) {
    def ==>(s2: String) {}
  }
}

// Exiting paste mode, now interpreting.

<pastie>:12: error: value ==> is not a member of String
 Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type
       def f() = "A" ==> "B"
                     ^
demobox commented 8 years ago

Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type

Nice! Curious now as to why it seemingly triggers only in some cases. I also like Daniel's comment to Jason's answer in the Stack Overflow questions:

"It is (supposed to be) spec'ed"

Thanks for digging that up!