<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Case Classes Are Cool</title>
	<atom:link href="http://www.codecommit.com/blog/scala/case-classes-are-cool/feed" rel="self" type="application/rss+xml" />
	<link>http://www.codecommit.com/blog/scala/case-classes-are-cool</link>
	<description>(permanently in beta)</description>
	<lastBuildDate>Mon, 09 Jan 2012 20:21:24 -0800</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Dan Yankowsky</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-4790</link>
		<dc:creator>Dan Yankowsky</dc:creator>
		<pubDate>Mon, 16 Mar 2009 13:20:49 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-4790</guid>
		<description>Sorry to come into the discussion so late...

I wonder if the angst about case classes stems simply from the name. It is true that they can be used in case clauses of match expressions. However, to say that case classes are simply classes to be used in case clauses is missing the bigger picture. That&#039;s essentially Daniel&#039;s point.

What if everybody did a global, mental replacement of &quot;case&quot; with &quot;bean&quot;. Now we&#039;re talking about bean classes. Does that make things any better?</description>
		<content:encoded><![CDATA[<p>Sorry to come into the discussion so late&#8230;</p>
<p>I wonder if the angst about case classes stems simply from the name. It is true that they can be used in case clauses of match expressions. However, to say that case classes are simply classes to be used in case clauses is missing the bigger picture. That&#8217;s essentially Daniel&#8217;s point.</p>
<p>What if everybody did a global, mental replacement of &#8220;case&#8221; with &#8220;bean&#8221;. Now we&#8217;re talking about bean classes. Does that make things any better?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Spiewak</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3933</link>
		<dc:creator>Daniel Spiewak</dc:creator>
		<pubDate>Sun, 17 Aug 2008 20:04:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3933</guid>
		<description>@Cedric

Ok, so it looks like my article example is going to have to wait a bit longer (not happening this week).  :-S  I&#039;ll try to summarize what I was thinking:

Pattern matching allows boolean testing *and* extraction of data in a single operation.  It&#039;s like the old-fashioned dynamic_cast in C++, which combines Java&#039;s instanceof and cast operations.  This saves on the amount of typing of course, but it also makes things a little less typo-prone.  For example, consider the example of the immutable List.  In Scala, this is implemented using a case class (::) and a case object (Nil):

def sum(list: List[Int]): Int = list match {
case hd :: tail =&gt; hd + sum(tail)
case Nil =&gt; 0
}

The pattern matching handles two operations in one: it checks to see if the list has any remaining elements and binds the first such element and the remainder of the list to the hd and tail constants (respectively).  If we tried to write this without pattern matching, it would look something like this:

def sum(list: List[Int]): Int = {
if (list.length &gt; 0) {
  list.head + sum(list.tail) 
} else 0
}

The problem here is that our conditional body is not *compile time* constrained to only deal with the list as a head and tail.  All we know about this list is that it has at least one element, so we should only work with the element we know exists (at index 0).  It is possible at compile time to access the list deeply.  While this is of course possible in our first example (by accessing list directly), it is not as easy to do (in terms of typographical or even logical errors).

Pattern matching is inextricably linked to the more compelling uses for case classes, so I suppose that it is true that you cannot deeply consider one without the other.  Neither is a hard necessity, since it is certainly possible in Scala to write code which avoids pattern matching (and case classes) altogether.  The question is: why would you want to?  As language features, they save on code noise, they reduce the potential for subtle logic errors (like selecting the wrong index), in every way I can think of they represent a benefit.  Can the technique be over-used and applied to situations where polymorphism is better suited?  Yes it can, but that would not be a &quot;correct&quot; application of the construct.  It&#039;s just another tool which simplifies some unfortunately common scenarios.</description>
		<content:encoded><![CDATA[<p>@Cedric</p>
<p>Ok, so it looks like my article example is going to have to wait a bit longer (not happening this week).  :-S  I&#8217;ll try to summarize what I was thinking:</p>
<p>Pattern matching allows boolean testing *and* extraction of data in a single operation.  It&#8217;s like the old-fashioned dynamic_cast in C++, which combines Java&#8217;s instanceof and cast operations.  This saves on the amount of typing of course, but it also makes things a little less typo-prone.  For example, consider the example of the immutable List.  In Scala, this is implemented using a case class (::) and a case object (Nil):</p>
<p>def sum(list: List[Int]): Int = list match {<br />
case hd :: tail => hd + sum(tail)<br />
case Nil => 0<br />
}</p>
<p>The pattern matching handles two operations in one: it checks to see if the list has any remaining elements and binds the first such element and the remainder of the list to the hd and tail constants (respectively).  If we tried to write this without pattern matching, it would look something like this:</p>
<p>def sum(list: List[Int]): Int = {<br />
if (list.length > 0) {<br />
  list.head + sum(list.tail)<br />
} else 0<br />
}</p>
<p>The problem here is that our conditional body is not *compile time* constrained to only deal with the list as a head and tail.  All we know about this list is that it has at least one element, so we should only work with the element we know exists (at index 0).  It is possible at compile time to access the list deeply.  While this is of course possible in our first example (by accessing list directly), it is not as easy to do (in terms of typographical or even logical errors).</p>
<p>Pattern matching is inextricably linked to the more compelling uses for case classes, so I suppose that it is true that you cannot deeply consider one without the other.  Neither is a hard necessity, since it is certainly possible in Scala to write code which avoids pattern matching (and case classes) altogether.  The question is: why would you want to?  As language features, they save on code noise, they reduce the potential for subtle logic errors (like selecting the wrong index), in every way I can think of they represent a benefit.  Can the technique be over-used and applied to situations where polymorphism is better suited?  Yes it can, but that would not be a &#8220;correct&#8221; application of the construct.  It&#8217;s just another tool which simplifies some unfortunately common scenarios.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug Clinton</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3926</link>
		<dc:creator>Doug Clinton</dc:creator>
		<pubDate>Tue, 12 Aug 2008 20:22:40 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3926</guid>
		<description>Daniel,

Fair enough. I wasn&#039;t aware that the compiler will supply the necessary bits of the companion object, so that keeps the overhead down and gives the flexibility one might need. I should have known. Scala seems particularly good at just letting you express the things you need and dealing with all the rest automatically.</description>
		<content:encoded><![CDATA[<p>Daniel,</p>
<p>Fair enough. I wasn&#8217;t aware that the compiler will supply the necessary bits of the companion object, so that keeps the overhead down and gives the flexibility one might need. I should have known. Scala seems particularly good at just letting you express the things you need and dealing with all the rest automatically.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Spiewak</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3925</link>
		<dc:creator>Daniel Spiewak</dc:creator>
		<pubDate>Tue, 12 Aug 2008 19:37:09 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3925</guid>
		<description>If you define a companion object for your case class, then the compiler will use that and add to it as necessary to satisfy the case class specification.  For example, if you define your own case class companion object with an apply() method, the compiler will *add* an unapply() method to allow pattern matching with the case class.  It won&#039;t overwrite anything you define, but it will ensure that the necessary signatures are present.

You can override apply() in your companion object to perform caching, and that&#039;s precisely what we&#039;re suggesting you do for immutable objects.  The compiler could certainly perform deep analysis to determine immutability, but as James pointed out, actually implementing a caching mechanism based on that analysis alone would be presumptuous to say the least.  How is the compiler to know what your program should be optimized for (space vs time)?  At least GCC and friends define a -O parameter to hint at this sort of thing, but even that does not control transparent caching or its ilk.

As an extreme example of how such transparent caching could go wrong, let&#039;s assume that you&#039;re working on some sort of data-mining application involving the creation of *billions* of immutable objects, each slightly different from the other.  Each of these objects is used briefly, then goes out of scope.  What happens if the compiler injects caching into this scenario?  Answer: memory usage shoots through the roof, the heap overflows and your application crashes after only a few hundred thousand objects.  Even the smartest analysis can&#039;t be trusted to make the final decision on *what* scenario you want to optimize your application for, it can only make guesses.  Basic optimizations (constant folding, tail-call folding, etc) are almost &quot;no-brainers&quot; that apply in all cases, but something as high-level as an object cache would be very dangerous to try to do automatically.</description>
		<content:encoded><![CDATA[<p>If you define a companion object for your case class, then the compiler will use that and add to it as necessary to satisfy the case class specification.  For example, if you define your own case class companion object with an apply() method, the compiler will *add* an unapply() method to allow pattern matching with the case class.  It won&#8217;t overwrite anything you define, but it will ensure that the necessary signatures are present.</p>
<p>You can override apply() in your companion object to perform caching, and that&#8217;s precisely what we&#8217;re suggesting you do for immutable objects.  The compiler could certainly perform deep analysis to determine immutability, but as James pointed out, actually implementing a caching mechanism based on that analysis alone would be presumptuous to say the least.  How is the compiler to know what your program should be optimized for (space vs time)?  At least GCC and friends define a -O parameter to hint at this sort of thing, but even that does not control transparent caching or its ilk.</p>
<p>As an extreme example of how such transparent caching could go wrong, let&#8217;s assume that you&#8217;re working on some sort of data-mining application involving the creation of *billions* of immutable objects, each slightly different from the other.  Each of these objects is used briefly, then goes out of scope.  What happens if the compiler injects caching into this scenario?  Answer: memory usage shoots through the roof, the heap overflows and your application crashes after only a few hundred thousand objects.  Even the smartest analysis can&#8217;t be trusted to make the final decision on *what* scenario you want to optimize your application for, it can only make guesses.  Basic optimizations (constant folding, tail-call folding, etc) are almost &#8220;no-brainers&#8221; that apply in all cases, but something as high-level as an object cache would be very dangerous to try to do automatically.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug Clinton</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3924</link>
		<dc:creator>Doug Clinton</dc:creator>
		<pubDate>Tue, 12 Aug 2008 19:24:52 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3924</guid>
		<description>James,

Fair enough, but the caching is something which could be handled by the companion object. Having to build your own companion object to do this would seem to me to defeat half the benefit of using case classes in this way. The compiler could probably determine if the case class was deeply immutable (i.e. all it&#039;s instance variable were var and deeply immutable) and provide an option in some way to say to use common instances. I&#039;m thinking of a particular case I&#039;ve dealt with in a java program where I built the cache myself to optimise away the generation of vast numbers of immutable objects with the same values that was causing serious overhead. It just seems a missed opportunity to let the language take care of this automatically in some way.

BTW, if I want to override the auto-generated companion object is it just a matter of defining it and the compiler will use my definition instead?</description>
		<content:encoded><![CDATA[<p>James,</p>
<p>Fair enough, but the caching is something which could be handled by the companion object. Having to build your own companion object to do this would seem to me to defeat half the benefit of using case classes in this way. The compiler could probably determine if the case class was deeply immutable (i.e. all it&#8217;s instance variable were var and deeply immutable) and provide an option in some way to say to use common instances. I&#8217;m thinking of a particular case I&#8217;ve dealt with in a java program where I built the cache myself to optimise away the generation of vast numbers of immutable objects with the same values that was causing serious overhead. It just seems a missed opportunity to let the language take care of this automatically in some way.</p>
<p>BTW, if I want to override the auto-generated companion object is it just a matter of defining it and the compiler will use my definition instead?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Iry</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3922</link>
		<dc:creator>James Iry</dc:creator>
		<pubDate>Tue, 12 Aug 2008 16:04:18 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3922</guid>
		<description>Two different instances.   Scala doesn&#039;t currently know in any deep sense the difference between immutable classes which could share the same instance and mutable classes which can&#039;t.  

Even if it did, there would be practical limitations similar to the way string values can be shared.  For instance, it would probably only be able to share instances that were created from the same literals (or things that the compiler knew how to fold into the same literal like &quot;Do&quot; + &quot;ug&quot;).   Trying to share instances created from variables would require a runtime cache which is normally considered something to be left in the hands of a programmer because it creates important differences in runtime space/time trade-offs.</description>
		<content:encoded><![CDATA[<p>Two different instances.   Scala doesn&#8217;t currently know in any deep sense the difference between immutable classes which could share the same instance and mutable classes which can&#8217;t.  </p>
<p>Even if it did, there would be practical limitations similar to the way string values can be shared.  For instance, it would probably only be able to share instances that were created from the same literals (or things that the compiler knew how to fold into the same literal like &#8220;Do&#8221; + &#8220;ug&#8221;).   Trying to share instances created from variables would require a runtime cache which is normally considered something to be left in the hands of a programmer because it creates important differences in runtime space/time trade-offs.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug Clinton</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3921</link>
		<dc:creator>Doug Clinton</dc:creator>
		<pubDate>Tue, 12 Aug 2008 14:53:15 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3921</guid>
		<description>I&#039;m curious about the runtime characteristics of case classes. In your first example, if I do this:

val me = Person(&quot;Doug&quot;, &quot;Clinton)
val meAgain = Person(&quot;Doug&quot;, &quot;Clinton&quot;)

and assuming that the immutable form of case class is used, will this result in the creation of two objects, or will me and meAgain refer to the same instance of Person?</description>
		<content:encoded><![CDATA[<p>I&#8217;m curious about the runtime characteristics of case classes. In your first example, if I do this:</p>
<p>val me = Person(&#8220;Doug&#8221;, &#8220;Clinton)<br />
val meAgain = Person(&#8220;Doug&#8221;, &#8220;Clinton&#8221;)</p>
<p>and assuming that the immutable form of case class is used, will this result in the creation of two objects, or will me and meAgain refer to the same instance of Person?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Iry</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3919</link>
		<dc:creator>James Iry</dc:creator>
		<pubDate>Tue, 12 Aug 2008 00:12:51 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3919</guid>
		<description>There&#039;s been a good discussion on Lambda the Ultimate about Visitor vs Pattern Matching.  The discussion starts about here: http://lambda-the-ultimate.org/node/2927#comment-43220.</description>
		<content:encoded><![CDATA[<p>There&#8217;s been a good discussion on Lambda the Ultimate about Visitor vs Pattern Matching.  The discussion starts about here: <a href="http://lambda-the-ultimate.org/node/2927#comment-43220" rel="nofollow">http://lambda-the-ultimate.org/node/2927#comment-43220</a>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Spiewak</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3917</link>
		<dc:creator>Daniel Spiewak</dc:creator>
		<pubDate>Mon, 11 Aug 2008 21:16:06 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3917</guid>
		<description>@Jesper

Oh, I see what you mean.  In principle, I agree with you.  Unfortunately, there have been situations where I have needed that time variant property in the object identity.  I can&#039;t remember an exact scenario, but I believe it had something to do with caching and multi-maps.

In general though, mutable containers should use object id-based implementations of equals and hashCode, while containers which require equals/hashCode to be formed based on contents should ensure immutability.  As Doug pointed out, it is the difference between a datatype and an entity.</description>
		<content:encoded><![CDATA[<p>@Jesper</p>
<p>Oh, I see what you mean.  In principle, I agree with you.  Unfortunately, there have been situations where I have needed that time variant property in the object identity.  I can&#8217;t remember an exact scenario, but I believe it had something to do with caching and multi-maps.</p>
<p>In general though, mutable containers should use object id-based implementations of equals and hashCode, while containers which require equals/hashCode to be formed based on contents should ensure immutability.  As Doug pointed out, it is the difference between a datatype and an entity.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jesper Nordenberg</title>
		<link>http://www.codecommit.com/blog/scala/case-classes-are-cool/comment-page-1#comment-3916</link>
		<dc:creator>Jesper Nordenberg</dc:creator>
		<pubDate>Mon, 11 Aug 2008 20:24:26 +0000</pubDate>
		<guid isPermaLink="false">http://www.codecommit.com/blog/scala/case-classes-are-cool#comment-3916</guid>
		<description>Daniel, what I&#039;m trying to say is that equals() and hashCode() should not be time variant functions, so whenever you have mutable fields you shouldn&#039;t override equals() and hashCode(), but rather use the default implementation. That&#039;s why I recommend against using case classes for mutable objects.</description>
		<content:encoded><![CDATA[<p>Daniel, what I&#8217;m trying to say is that equals() and hashCode() should not be time variant functions, so whenever you have mutable fields you shouldn&#8217;t override equals() and hashCode(), but rather use the default implementation. That&#8217;s why I recommend against using case classes for mutable objects.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

