|
View:
New views
11 Messages
—
Rating Filter:
Alert me
|
|
|
[scala] Recursive knot tying and case class extensionDear Scalarazzi,
i'm pretty much in favor of not being able to extend case classes. i noticed that decision forces certain idioms for recursive knot-tying. The following is no longer a "modern" option. scala> case class Response[Request]( magic : Int, more : String, deeper : Option[Request] ) defined class Response scala> case class Request[Response]( magic : Int, more : String, deeper : Option[Response] ) defined class Request scala> case class JustifiedRequest( m : Int, p : String, d : Option[Response[JustifiedRequest]] ) extends Request[Response[JustifiedRequest]]( m, p, d ) warning: there were deprecation warnings; re-run with -deprecation for details defined class JustifiedRequest scala> case class JustifiedResponse( m : Int, p : String, d : Option[Request[JustifiedResponse]] ) extends Response[Request[JustifiedResponse]]( m, p, d ) warning: there were deprecation warnings; re-run with -deprecation for details defined class JustifiedResponse scala> Best wishes, --greg -- L.G. Meredith Managing Partner Biosimilarity LLC 1219 NW 83rd St Seattle, WA 98117 +1 206.650.3740 http://biosimilarity.blogspot.com |
|
|
Re: [scala] Recursive knot tying and case class extensionOn Thu, Oct 15, 2009 at 7:57 PM, Meredith Gregory
<lgreg.meredith@...> wrote: > i'm pretty much in favor of not being able to extend case classes. i noticed > that decision forces certain idioms for recursive knot-tying. The following > is no longer a "modern" option. Make Request and Response plain abstract classes ... Cheers, Miles -- Miles Sabin tel: +44 (0)7813 944 528 skype: milessabin http://www.chuusai.com/ http://twitter.com/milessabin |
|
|
Re: [scala] Recursive knot tying and case class extensionIt's a bit more boiler-plate if you need to pattern match on Request and Response, but the extractors are fairly straightforward to add if need. Easy trade off in my books for being rid of the trouble of case class inheritance. :)
- Colin |
|
|
Re: [scala] Recursive knot tying and case class extensionDear Miles, Colin,
scala> Request[Int]( 0, "zero", None ) match { case Request( _, msg, _ ) => msg } res0: String = zero scala> class ARequest[Response]( magic : Int, more : String, deeper : Option[Response] ) defined class ARequest scala> new ARequest[Int]( 0, "zero", None ) match { case ARequest( _, msg, _ ) => msg } <console>:8: error: not found: value ARequest new ARequest[Int]( 0, "zero", None ) match { case ARequest( _, msg, _ ) => msg } ^ <console>:8: error: not found: value msg new ARequest[Int]( 0, "zero", None ) match { case ARequest( _, msg, _ ) => msg } ^ scala> Best wishes, --greg On Thu, Oct 15, 2009 at 12:09 PM, Colin Bullock <cmbullock@...> wrote: It's a bit more boiler-plate if you need to pattern match on Request and Response, but the extractors are fairly straightforward to add if need. Easy trade off in my books for being rid of the trouble of case class inheritance. :) -- L.G. Meredith Managing Partner Biosimilarity LLC 1219 NW 83rd St Seattle, WA 98117 +1 206.650.3740 http://biosimilarity.blogspot.com |
|
|
Re: [scala] Recursive knot tying and case class extensionJust need an extractor in the companion:
scala> object Wrapper { | class ARequest[Response](val magic: Int, val more: String, val deeper: Option[Response]) | object ARequest { | def unapply[Response](ar: ARequest[Response]) = Some((ar.magic, ar.more, ar.deeper)) | }} defined module Wrapper scala> import Wrapper._ import Wrapper._ scala> new ARequest[Int](0, "zero", None) match { case ARequest(_, msg, _) => msg } res1: String = zero Note, the Wrapper object is just to keep the class and it's companion object together for the interpreter. - Colin |
|
|
Re: [scala] Recursive knot tying and case class extensionDear Colin,
Thanks! Yes, i got the pattern before i posted. The point is that the original simple design pattern has now been eliminated in favor of something much more heavy-weight (by comparison). i see that there is a trade-off. i just hadn't noticed how much the trade-off affected my style of coding ;-) -- which includes lots of recursive knot-tying. Best wishes, --greg On Thu, Oct 15, 2009 at 12:36 PM, Colin Bullock <cmbullock@...> wrote: Just need an extractor in the companion: -- L.G. Meredith Managing Partner Biosimilarity LLC 1219 NW 83rd St Seattle, WA 98117 +1 206.650.3740 http://biosimilarity.blogspot.com |
|
|
Re: [scala] Recursive knot tying and case class extensionOn Thu, Oct 15, 2009 at 8:51 PM, Meredith Gregory
<lgreg.meredith@...> wrote: > Dear Colin, > > Thanks! Yes, i got the pattern before i posted. The point is that the > original simple design pattern has now been eliminated in favor of something > much more heavy-weight (by comparison). i see that there is a trade-off. i > just hadn't noticed how much the trade-off affected my style of coding ;-) > -- which includes lots of recursive knot-tying. I don't quite understand why you can't have your leaves be case classes and keep everything else abstract, Welcome to Scala version 2.8.0.r18324-b20091014231244 (Java HotSpot(TM) Server VM, Java 1.6.0_14). Type in expressions to have them evaluated. Type :help for more information. scala> abstract class Response[Request]( magic : Int, more : String, deeper : Option[Request] ) defined class Response scala> abstract class Request[Response]( magic : Int, more : String, deeper : Option[Response] ) defined class Request scala> case class ARequest[Response]( magic : Int, more : String, deeper : Option[Response] ) defined class ARequest scala> ARequest( 0, "zero", None ) match { case ARequest( _, msg, _ ) => msg } res0: String = zero Cheers, Miles -- Miles Sabin tel: +44 (0)7813 944 528 skype: milessabin http://www.chuusai.com/ http://twitter.com/milessabin |
|
|
Re: [scala] Recursive knot tying and case class extensionIn my experience, I agree with Miles on this one. I've rarely run into the need to deconstruct the parent classes of some hierarchy through pattern-matching (perhaps matching on some parent trait/class as a simple type annotation occasionally); I almost always find that it's the concrete subclasses I need to match against in practice. Of course, to each their own, your mileage may vary, etc.
Having said that, a hypothetical example springs to mind where matching on a superclass could be helpful: class NamedThing(val name: String) case class Person(override val name: String, age: Int) extends NamedThing(name) case class Pet(override val name: String, species: String) extends NamedThing(name) Pet("Fido", "Dog") match { case NamedThing(name) => name } However, in cases such as (but hopefully more complex than) this, the missing extractor is generally a trivial one-liner to add. object NamedThing { def unapply(nt: NamedThing) = Some(nt.name) } - Colin |
|
|
Re: [scala] Recursive knot tying and case class extensionOn Thu, Oct 15, 2009 at 1:21 PM, Colin Bullock <cmbullock@...> wrote: In my experience, I agree with Miles on this one. I've rarely run into the need to deconstruct the parent classes of some hierarchy through pattern-matching (perhaps matching on some parent trait/class as a simple type annotation occasionally); I almost always find that it's the concrete subclasses I need to match against in practice. Of course, to each their own, your mileage may vary, etc. I do almost the same thing, except: trait NamedThing{def name: String} It makes: case class Person(name: String, age: Int) extends NamedThing
cleaner However, in cases such as (but hopefully more complex than) this, the missing extractor is generally a trivial one-liner to add. -- Lift, the simply functional web framework http://liftweb.net Beginning Scala http://www.apress.com/book/view/1430219890 Follow me: http://twitter.com/dpp Surf the harmonics |
|
|
Re: [scala] Recursive knot tying and case class extension
Indeed, much nicer. All the 'override val's were bothering me just writing the email. :) - Colin |
|
|
Re: [scala] Recursive knot tying and case class extensionDear Colin, Miles, et al,
i confess: in production code i do the trait pattern DPP mentioned. In general, i don't think it's a big deal. You just can't factor certain pattern-matching behavior up above the concrete instances. scala> trait Adjuster[T <: ((Int,Int) => Int)] { def checkJustification( adjustmentFormula : T ) ( req : Request[Response[_]], resp : Response[Request[_]] ) : Int = { req match { case Request( qm, _, _ ) => resp match { case Response( sm, _, _ ) => adjustmentFormula( qm, sm ) } } } } defined trait Adjuster scala> The use case is one where you know that the parametric case class is really part of a big knot. Then you can safely factor pattern-matching as high up as scope will allow. The version Miles suggests will cause this behavior to have to use abstract accessors and forgo pattern-matching. Best wishes, --greg On Thu, Oct 15, 2009 at 1:45 PM, Colin Bullock <cmbullock@...> wrote:
-- L.G. Meredith Managing Partner Biosimilarity LLC 1219 NW 83rd St Seattle, WA 98117 +1 206.650.3740 http://biosimilarity.blogspot.com |
| Free embeddable forum powered by Nabble | Forum Help |