Hmm, apparently all generators must be of the same type or down-cast
to the same type. So

        def masters = for {
            sy <- selectedYear
            sm <- selectedMonth
            m = Master.getMastersWithTags(sy, sm)
        } yield m

        m.get // Do something with the list

does the trick, but it's non-idiomatic.

On Nov 17, 1:39 am, DMB <[email protected]> wrote:
> Darn it, apparently I'm not "getting" the more complex cases of for
> comprehensions at all. Returning a Box[Tag] from that function
> affected several other functions which expected Tag or null. So rather
> than pulling the value out of the box, I decided to modify the
> functions, borrowing heavily from the rewrite provided by David.
>
> Here's a fragment of a function which is supposed to get me a sequence
> of Master objects. Note that getMastersWithTags returns a (possibly
> empty) List[Master]:
>
>         def masters = for {
>             sy <- selectedYear
>             sm <- selectedMonth
>             m <- Master.getMastersWithTags(sy, sm)
>         } yield m
>
> Intuitively, this should produce a (possibly empty) sequence of object
> of type Master, right? First, selectedYear would be unboxed, then (if
> there's a year) the selected month, and then, if both values are
> available, the for loop should in theory iterate over the list
> produced by Master.getMastersWithTags(sy, sm) and produce a sequence
> of objects.
>
> NetBeans says:
>
> type mismatch:
>    found: List[Master]
>    required: net.liftweb.common.Box[?]
>
> and I'm not sure what exactly this means. Could someone clarify?
>
> On Nov 16, 10:51 pm, DMB <[email protected]> wrote:
>
> > Nice! And you're right. I'm trying to program in Scala as if it were
> > C# with a weird implementation of LINQ. And C# it is not.
>
> > But the thread was not really about this. The thread was about a bug
> > in the compiler, which still stands. And you can pry my return
> > statements out of my cold, dead hands. :-)
>
> > On Nov 16, 9:42 pm, David Pollak <[email protected]>
> > wrote:
>
> > > If you see the "return" statement in your program, you are likely doing
> > > something wrong.  It means that it's time to refactor your code so 
> > > there's a
> > > single return point from your method.  Using null is a red flag (use 
> > > Option
> > > or Box) and using vars (rather than vals) is a yellow flag.
>
> > > So, let's go through your code:
>
> > >    def findTagWithName(tags: List[Tag], name: String) : Tag = {
> > >        val t = tags.find(x => x.name == name)
> > >         return t.getOrElse(null)
> > >    }
>
> > > becomes:
>
> > >    def findTagWithName(tags: List[Tag], name: String): Box[Tag] =
> > >         tags.find(x => x.name == name)
>
> > >    def getCookieValue(name: String, default: String) : String = {
> > >        for(cookie <- S.findCookie(name); v <- cookie.value) {
> > >            return v
> > >        }
> > >        return default
> > >    }
>
> > > becomes:
>
> > >    def getCookieValue(name: String, default: String): String =
> > >        (for(cookie <- S.findCookie(name); v <- cookie.value)
> > >            yield v) openOr default
>
> > >    def getParamValue(name: String, default: String) : String = {
> > >        for(v <- S.param(name)) {
> > >            return v
> > >        }
> > >        return default
> > >    }
>
> > > becomes:
>
> > >    def getParamValue(name: String, default: String): String =
> > >       S.param(name) openOr default
> > > - Show quoted text -
>
> > >    def getSelectedTag(tags: List[Tag], cookieName: String, urlParam: 
> > > String)
> > > : Tag = {
> > >        var t : Tag = null
> > >        try {
> > >            if(tags.length == 0) {
> > >                return null
> > >            }
>
> > >            // See if tag name is present in the URL
> > >            val tagName = getParamValue(urlParam, "")
> > >            // If yes, check if a tag with this name is present in tags
> > >            t = findTagWithName(tags, tagName)
> > >            // If it is, write out the right cookie and return
> > >            if(t != null) {
> > >                return t
> > >            }
>
> > >            // if no, check the corresponding cookie
> > >            val cv = getCookieValue(cookieName, "")
> > >            if(cv != null) {
> > >                // and check if the tag with a name stored in cookie is
> > > present in tags
> > >                t = findTagWithName(tags, cv)
> > >                if(t != null) {
> > >                    return t
> > >                }
> > >            }
>
> > >            // otherwise just select the last tag from the list and write 
> > > out
> > > the cookie
> > >            t = tags.last
> > >            return t
> > >        } finally {
> > >            if(t != null) {
> > >                var c = HTTPCookie(cookieName, t.name).setMaxAge(365 * 24 *
> > > 60 * 60)
> > >                S.addCookie(c)
> > >            }
> > >        }
> > >    }
>
> > > becomes:
>
> > >    def getSelectedTag(tags: List[Tag], cookieName: String, urlParam:
> > > String): Box[Tag] = {
> > >             // See if tag name is present in the URL
> > >        def tagForParam =
> > >         for {
> > >           param <- S.param(urlParam)
> > >           tag <- tags.find(_.name == param)
> > >         } yield tag
>
> > >       // check the corresponding cookie
> > >       def tagForCookie =
> > >         for {
> > >           cookie <- S.findCookie(cookieName)
> > >           value <- cookie.value
> > >           tag <- tags.find(_.name == value)
> > >         } yield tag
>
> > >      val tag = tagForParam or tagForCookie or tags.lastOption
>
> > >      tag.foreach( t =>
> > >         S.addCookie(HTTPCookie(cookieName, t.name).setMaxAge(365 * 24 * 
> > > 60 *
> > > 60)))
>
> > >      tag
> > >   }
>
> > > Note how the revised code is cleaner and easier to read.  The logic is
> > > grouped together and the expression of what tag to select is very clear.
>
> > > I hope this helps.
>
> > > Thanks,
>
> > > David
>
> > > On Mon, Nov 16, 2009 at 8:45 PM, DMB <[email protected]> wrote:
> > > > I wonder if anyone else finds this stack trace familiar. As often is
> > > > the case with non-mainstream languages, Google turns up nothing of
> > > > value. The code fragment goes below. If I comment out the code inside
> > > > the finally statement, everything compiles fine. If I keep it, I get
> > > > the stack trace below. I have tried to create a minimal repro, but did
> > > > not have any success. I understand this is not a Lift issue, but this
> > > > group has a sizable chunk of Scala enthusiasts, so hopefully someone
> > > > has encountered something like this
>
> > > > block #9 :
> > > >  CONSTANT (Constant(null))
> > > >  LOAD_LOCAL variable t
> > > >  DUP
> > > >  STORE_LOCAL variable eqEqTemp$2
> > > >  CZJUMP (REFERENCE(java.lang.Object))EQ ? 13 : 15
> > > > Successors:  3 15 13 3
> > > > trying to emit: DROP REFERENCE(scala.Null)
> > > > java.lang.reflect.InvocationTargetException
> > > >        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > > >        at sun.reflect.NativeMethodAccessorImpl.invoke
> > > > (NativeMethodAccessorImpl.java:39)
> > > >        at sun.reflect.DelegatingMethodAccessorImpl.invoke
> > > > (DelegatingMethodAccessorImpl.java:25)
> > > >        at java.lang.reflect.Method.invoke(Method.java:597)
> > > >        at org.scala_tools.maven.executions.MainHelper.runMain
> > > > (MainHelper.java:151)
> > > >        at org.scala_tools.maven.executions.MainWithArgsInFile.main
> > > > (MainWithArgsInFile.java:26)
> > > > Caused by: java.lang.AssertionError: assertion failed: BasicBlock
> > > > closed
> > > >        at scala.Predef$.assert(Predef.scala:92)
> > > >        at scala.tools.nsc.backend.icode.BasicBlocks$BasicBlock.emit
> > > > (BasicBlocks.scala:327)
> > > >        at scala.tools.nsc.backend.icode.BasicBlocks$BasicBlock.emit
> > > > (BasicBlocks.scala:317)
> > > >        at scala.tools.nsc.backend.icode.GenICode$ICodePhase.adapt
> > > > (GenICode.scala:1006)
> > > >        at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala
> > > > $tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:
> > > > 496)
> > > >        at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala
> > > > $tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:
> > > > 447)
> > > >        at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala
> > > > $tools$nsc$backend$icode$GenICode$ICodePhase$$genStat(GenICode.scala:
> > > > 183)
> > > >        at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun
> > > > $genStat$1.apply(GenICode.scala:146)
> > > >        at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun
> > > > $genStat$1.apply(GenICode.scala:145)
> > > > etc, etc...
>
> > > > The code fragment:
>
> > > >    def findTagWithName(tags: List[Tag], name: String) : Tag = {
> > > >        val t = tags.find(x => x.name == name)
> > > >        return t.getOrElse(null)
> > > >    }
>
> > > >    def getCookieValue(name: String, default: String) : String = {
> > > >        for(cookie <- S.findCookie(name); v <- cookie.value) {
> > > >            return v
> > > >        }
> > > >        return default
> > > >    }
>
> > > >    def getParamValue(name: String, default: String) : String = {
> > > >        for(v <- S.param(name)) {
> > > >            return v
> > > >        }
> > > >        return default
> > > >    }
>
> > > >    def getSelectedTag(tags: List[Tag], cookieName: String, urlParam:
> > > > String) : Tag = {
> > > >        var t : Tag = null
> > > >        try {
> > > >            if(tags.length == 0) {
> > > >                return null
> > > >            }
>
> > > >            // See if tag name is present in the URL
> > > >            val tagName = getParamValue(urlParam, "")
> > > >            // If yes, check if a tag with this name is present in
> > > > tags
> > > >            t = findTagWithName(tags, tagName)
> > > >            // If it is, write out the right cookie
>
> ...
>
> read more »

--

You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=.


Reply via email to