{"id":371,"date":"2014-09-15T00:21:10","date_gmt":"2014-09-15T09:21:10","guid":{"rendered":"http:\/\/blog.box.kr\/?p=371"},"modified":"2014-09-15T00:21:10","modified_gmt":"2014-09-15T09:21:10","slug":"clojure-vs-scala","status":"publish","type":"post","link":"https:\/\/blog.box.kr\/?p=371","title":{"rendered":"Clojure vs Scala"},"content":{"rendered":"<address><a href=\"http:\/\/programming-puzzler.blogspot.kr\/2013\/12\/clojure-vs-scala.html\">http:\/\/programming-puzzler.blogspot.kr\/2013\/12\/clojure-vs-scala.html<\/a><\/address>\n<address>\n<div class=\"post hentry uncustomized-post-template\">\n<h3 class=\"post-title entry-title\">Clojure vs Scala<\/h3>\n<div class=\"post-header\">\n<\/div>\n<div id=\"post-body-7822096470812486706\" class=\"post-body entry-content\">Last week, someone posted a question on the Clojure group asking for a comparison between Clojure and Scala. Since my most popular blog post, by far, is my<span class=\"Apple-converted-space\">\u00a0<\/span><a href=\"http:\/\/programming-puzzler.blogspot.com\/2010\/08\/racket-vs-clojure.html\">Racket vs Clojure<\/a><span class=\"Apple-converted-space\">\u00a0<\/span>post from three years ago, I thought it would be good to post my response here.Ten years ago, I would have said that my ideal dream language is one that provides the flexibility to program in any style. I want to be able to choose object-oriented or functional, immutable or mutable, high-level abstractions or low-level speed. With respect to this ideal, Scala clearly wins, supporting more programming styles than Clojure.<\/p>\n<p>I&#8217;ve definitely changed my tune, though, and now I actually prefer the way that Clojure constrains and shapes my thinking. I argue that even though Scala may provide me with more options on how to tackle a given programming problem, Clojure guides me towards a simpler solution. If this intrigues you, read on&#8230;<\/p>\n<p>The following text is only slightly paraphrased from what I posted to the group:<\/p>\n<blockquote><p>All or nearly all of the functional aspects of Clojure have counterparts in Scala. On top of that, Scala provides mutable flavors of everything, so you can pick and choose your approach. So that makes Scala better, right?But the difference between Clojure and Scala is bigger than a feature-to-feature comparison &#8212; they have very different philosophies, and programs developed in Clojure consequently have a very different feel to them than those developed in Scala. I find Clojure programs to be dramatically simpler.<\/p>\n<p>Just as one example, consider modeling a deck of cards. In Clojure, you&#8217;d be more likely to come up with a simple representation for a card, perhaps: [10 :spades]. Depending on the card game, you might choose to represent a face card as [:king :clubs] or [13 :clubs]. A deck would likely be modeled as just a sequence of cards, and all the built-in sequence functions would apply, for example, shuffle, take, drop, etc. Serializing the data (for example, if you want to keep a database tracking all the shuffled decks you&#8217;ve ever used in a given game) comes for free.<\/p>\n<p>On the other hand, in Scala, you&#8217;d be more likely to create a card Class with a rank and suit field. The Suit class would be comprised of four case classes, because the philosophy is to enumerate all the possible suits as separate entities &#8212; there&#8217;s nothing in Scala like Clojure&#8217;s convenient keywords. For the rank, you&#8217;d be steered towards representing all the ranks as integers. The possibility of representing face cards with a name would likely never occur to you, because it would be too complicated to go through the effort of defining the type of a rank to be a &#8220;integer or a class comprised of four case classes &#8212; jack,queen,king,ace&#8221;. For modeling the deck, you probably wouldn&#8217;t say a Deck<span class=\"Apple-converted-space\">\u00a0<\/span><i><em>is-a<\/em><\/i><span class=\"Apple-converted-space\">\u00a0<\/span>sequence, because composition is favored over inheritance. So you&#8217;d probably have a Deck class which would<span class=\"Apple-converted-space\">\u00a0<\/span><i><em>contain<\/em><\/i><span class=\"Apple-converted-space\">\u00a0<\/span>a sequence of cards. This means that you&#8217;d have to reimplement methods like shuffle, take, and drop on your Deck class to turn around and dispatch those methods to the underlying sequence of cards. If you&#8217;re not careful, years of object-oriented training might kick in and before you know it, you&#8217;re representing the deck as a class where methods like shuffle, take, and drop destructively update the underlying sequence &#8212; it feels so natural to do that once you&#8217;ve encapsulated the underlying sequence of cards in a class. If you want to serialize a deck, that&#8217;s more code to write (although general &#8220;pickling&#8221; of a Scala object is an active area of research).<\/p>\n<p>This example pretty much sums up what I prefer about Clojure. I like to tell people that a big part of what makes Clojure special is its philosophy of<span class=\"Apple-converted-space\">\u00a0<\/span><i><em>lightweight data modeling<\/em><\/i>. It leads to delightfully simple systems. Scala remains deeply rooted in the OO philosophy, which all too often leads to an over-engineered muddle.<\/blockquote>\n<h2>Further thoughts<\/h2>\n<p>After posting the above message, a couple people pointed out that Scala doesn&#8217;t force you to build the more complicated model. That&#8217;s absolutely true. But due to its highly detailed static type system, Scala attracts the kind of programmers that like to carefully categorize and enumerate all the possible data structures that will occur in their programs. Sure, you could eschew objects in Scala and mimic Clojure by using generic maps\/vectors\/lists\/sets for all your structured data needs, but that&#8217;s clearly not how Scala is meant to be used, and numerous little details of the language psychologically steer you towards developing a more rigorous type taxonomy.In my post, I mentioned<span class=\"Apple-converted-space\">\u00a0<\/span><i>lightweight data modeling<\/i>. I can&#8217;t stress this term enough. I&#8217;d like to see it become the new catchphrase for Clojure. When I used to give my &#8220;elevator pitch&#8221; for Clojure, I&#8217;d talk about how it was a functional programming language, a dialect of Lisp on the JVM, with some interesting concurrency constructs. I&#8217;d get a lot of blank stares. Most people don&#8217;t know what it means to be functional, and many don&#8217;t know about Lisp. But once I started talking about<span class=\"Apple-converted-space\">\u00a0<\/span><i>lightweight data modeling<\/i>, people&#8217;s interest perked up. People get it, or think they get it, or at least get it enough to be curious to ask for more details.<\/p>\n<p>At that point, I often say something like, &#8220;Do you know JSON?&#8221; After getting acknowledgment, I continue with, &#8220;Well, imagine if you could represent all your data as JSON, rather than a complex hierarchy of objects and methods, and the language was designed around making that kind of data super-easy to work with.&#8221; I find I get a much more positive response from this kind of explanation. It gives a hint of what it feels like to work in Clojure and think in Clojure.<\/p>\n<p>I find it interesting that in Scala&#8217;s early days, Scala had a similar orientation. They proudly boasted that XML manipulation was going to be Scala&#8217;s killer feature. You could drop XML in your code as a data literal; the language was oriented around making XML easy to work with. Now, this has fallen by the wayside. Martin Odersky (the designer of Scala) has been quoted as saying, &#8220;Seemed a great idea at the time, now it sticks out like a sore thumb.&#8221;<\/p>\n<p>I admit, there are times where I&#8217;m envious of Scala&#8217;s versatility versus Clojure: the ease of using a mutable variable, the ease of working with Java primitives and arrays, the speed that comes from static typing, the richness of classes versus Clojure&#8217;s namespaces. (Actually, this last point is probably worthy of its own blog post &#8212; Clojure&#8217;s namespaces are quite limited in ways that frequently cause me pain). Whenever I run up against one of these rough spots in Clojure, I feel like an ascetic monk, suffering because I&#8217;ve chosen to deny myself the additional tools that Scala brings to the table. But overall, I feel happier programming in Clojure because the additional constraints imposed by Clojure guide me more quickly towards a simple design.<\/p>\n<div>\n<\/div>\n<\/div>\n<div class=\"post-footer\">\n<div class=\"post-footer-line post-footer-line-1\"><span class=\"post-author vcard\">Posted by<span class=\"Apple-converted-space\">\u00a0<\/span><span class=\"fn\"><a class=\"g-profile\" title=\"author profile\" href=\"http:\/\/www.blogger.com\/profile\/05992502488191304160\" rel=\"author\" data-gapiattached=\"true\" data-onload=\"true\" data-gapiscan=\"true\">Mark Engelberg<span class=\"Apple-converted-space\">\u00a0<\/span><\/a><\/span><\/span><span class=\"post-timestamp\">at<span class=\"Apple-converted-space\">\u00a0<\/span><a class=\"timestamp-link\" title=\"permanent link\" href=\"http:\/\/programming-puzzler.blogspot.kr\/2013\/12\/clojure-vs-scala.html\" rel=\"bookmark\"><abbr class=\"published\" title=\"2013-12-24T00:34:00-08:00\">12:34 AM<\/abbr><\/a><span class=\"Apple-converted-space\">\u00a0<\/span><\/span><\/p>\n<div class=\"post-share-buttons goog-inline-block\">\n<\/div>\n<\/div>\n<div class=\"post-footer-line post-footer-line-2\">\n<\/div>\n<div class=\"post-footer-line post-footer-line-3\">\n<\/div>\n<\/div>\n<\/div>\n<div id=\"comments\" class=\"comments\"><a name=\"comments\"><\/a><\/p>\n<h4>22 comments:<\/h4>\n<div class=\"comments-content\">\n<div id=\"comment-holder\">\n<div id=\"bc_0_23C\">\n<div id=\"bc_0_23CT\">\n<div id=\"bc_0_22T\" class=\"comment-thread\">\n<ol id=\"bc_0_22TB\">\n<li id=\"bc_0_0B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh5.googleusercontent.com\/-HvHQIeZw9-s\/AAAAAAAAAAI\/AAAAAAAAAEI\/ajoTYmu2e_o\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c5382781020629376853\" class=\"comment-block\">\n<div id=\"bc_0_0M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/05677254765276012626\" rel=\"nofollow\">Paco Garc\u00eda<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387887348148#c5382781020629376853\" rel=\"nofollow\">December 24, 2013 at 4:15 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_0MC\" class=\"comment-content\">Years ago it was called &#8220;symbolic programming&#8221; and it&#8217;s still as useful.<\/p>\n<p><span id=\"bc_0_0MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div id=\"bc_0_0BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_0B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c4823994368052731552\" class=\"comment-block\">\n<div id=\"bc_0_10M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/08897011817693913795\" rel=\"nofollow\">phil<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387888555651#c4823994368052731552\" rel=\"nofollow\">December 24, 2013 at 4:35 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_10MC\" class=\"comment-content\">In Scala I would model a card as an Int and a card type either Face or King, Jack, Queen, Ace. I would use case classes giving pattern matching, Scala picking gives serialisation for free and easy and type checking for the serialisation at compile time.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>trait CardType<br \/>\ncase class FaceCard() extends CardType<br \/>\ncase class QueenCard() extends CardType<span class=\"Apple-converted-space\">\u00a0<\/span><br \/>\ncase class&#8230; the other types continued&#8230; then<br \/>\ncase class Card(cardValue: Int, cardType: CardType)<\/p>\n<p>A deck of cards would be a single class which would contain a collection of cards, a List[Card], operations shuffle, etc, would be defined on the Deck class. Operations such as shuffle would produce a new immutable Card class instance, so there would be no mutable state, rely on the immutable List data structure.<\/p>\n<p>In particular since the Deck class is immutable you could expose the internal list publicly so people could do any of the take drop operations on the internal list and still be assured that the code is safe, pure functional and immutable. There is no need to hide the internal list implementation, so all list operations are available.<\/p>\n<p>I would say the main difference is that Scala doesn&#8217;t have some features baked into the language that Clojure has, however, those features are available if you bring in the right libraries. So the language grows by convention, by the libraries, rather than having those things in at the beginning.<br \/>\nIt would be nice if those things were in at the beginning, but it would be a big job to put all of them in!<\/p>\n<p>A good example is Picking, which is new, but it gives easy and fast serialisation of Scala objects, this is not a part of the language but a library which uses Scala macros to do type safe serialisation, ie, it gets type checked at compile time, and some runtime checks.<\/p>\n<p><span id=\"bc_0_10MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div class=\"comment-replies\">\n<div class=\"comment-thread inline-thread\"><span class=\"thread-toggle thread-expanded\"><span class=\"thread-toggle thread-expanded\"><span id=\"bc_0_1TA\" class=\"thread-arrow\" style=\"background: url('data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAG0lEQVR42mNgwAfKy8v\/48I4FeA0AacVDFQBAP9wJkE\/KhUMAAAAAElFTkSuQmCC') no-repeat 0px 0px; margin: 0.3em; width: 7px; height: 6px; overflow: visible; padding-right: 4px; display: inline-block;\"><\/span><span class=\"thread-count\"><a target=\"_self\">Replies<\/a><\/span><\/span><\/span><\/p>\n<div id=\"bc_0_1TD\" class=\"thread-dropContainer thread-expanded\">\n<\/div>\n<div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<li id=\"bc_0_1B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c339527907571359724\" class=\"comment-block\">\n<div id=\"bc_0_1M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/08897011817693913795\" rel=\"nofollow\">phil<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387888884652#c339527907571359724\" rel=\"nofollow\">December 24, 2013 at 4:41 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_1MC\" class=\"comment-content\">Just to show how you could use a deck, if you wanted to find all queens in a deck.<\/p>\n<p>val queenCardsInDeck = deck.cards.filter(_.cardType == QueenCard)<\/p>\n<p>To find cards with values &lt; 5<\/p>\n<p>val valuesLessThanFive = deck.cards.filter(_.cardValue &lt; 5)<\/p>\n<p>To pattern match.<\/p>\n<p>card match {<br \/>\ncase Card(_,QueenCard) =&gt; { println(&#8220;This is a queen&#8221;) }<br \/>\ncase Card(_,KingCard) =&gt; { println(&#8220;This is a king&#8221;) }<br \/>\n}<\/p>\n<p><span id=\"bc_0_1MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_1BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_1B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_2B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c508225596790041688\" class=\"comment-block\">\n<div id=\"bc_0_2M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/08897011817693913795\" rel=\"nofollow\">phil<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387889024819#c508225596790041688\" rel=\"nofollow\">December 24, 2013 at 4:43 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_2MC\" class=\"comment-content\">Small correction &#8220;s such as shuffle would produce a new immutable Card class instance&#8221; should say &#8220;new immutable Deck class&#8221;<\/p>\n<p><span id=\"bc_0_2MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_2BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_2B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_3B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh3.googleusercontent.com\/-cKCqHJgTO6k\/AAAAAAAAAAI\/AAAAAAAAA40\/ND9TxHUyuNg\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c4158502318489892631\" class=\"comment-block\">\n<div id=\"bc_0_3M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/05851775655646953918\" rel=\"nofollow\">Alexander Zolotko<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387895296852#c4158502318489892631\" rel=\"nofollow\">December 24, 2013 at 6:28 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_3MC\" class=\"comment-content\">Phil, do I need to have Picking on the receiving side to deserialise the data? What if I use another language, are there any Picking-compatible deserialisers around? Are there any APIs that accept Picking-serialised data? Are there any databases that understand Picking serialisation format and can create efficient index to query the data?<\/p>\n<p>I hope you see my point. Type safety is great, but your application is usually a tiny piece of software in the much greater world that doesn&#8217;t give a damn about your cool type system \ud83d\ude42<\/p>\n<p><span id=\"bc_0_3MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_3BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_3B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_4B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c8727844086082314070\" class=\"comment-block\">\n<div id=\"bc_0_4M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/00722138503315213359\" rel=\"nofollow\">Mar<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387897055458#c8727844086082314070\" rel=\"nofollow\">December 24, 2013 at 6:57 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_4MC\" class=\"comment-content\">Scala&#8217;s [currently experimental] Pickling does allow you to change the output format easily, so there is an arbitrary number of &#8220;language-independent pickling-deserializers&#8221; around, depending on what output format the developer choose. (Clojure would of course run into the same kind of challenge when talking with other platforms. The author&#8217;s point, as far as I gather, is that there is no such obfuscation of unfamiliarity *inside* a Clojure-application, when using a map to represent a deck of cards rather than a custom data type.)<\/p>\n<p>That being said, I do think phil&#8217;s post goes some length to prove the points of this blog post. And THAT being said, I do love programming in Scala \ud83d\ude42<\/p>\n<p><span id=\"bc_0_4MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_4BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_4B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_5B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c38499380655416769\" class=\"comment-block\">\n<div id=\"bc_0_5M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/00722138503315213359\" rel=\"nofollow\">Mar<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387897191511#c38499380655416769\" rel=\"nofollow\">December 24, 2013 at 6:59 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_5MC\" class=\"comment-content\">(https:\/\/github.com\/scala\/pickling)<\/p>\n<p><span id=\"bc_0_5MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_5BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_5B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_6B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh3.googleusercontent.com\/-cKCqHJgTO6k\/AAAAAAAAAAI\/AAAAAAAAA40\/ND9TxHUyuNg\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c1523126078272807201\" class=\"comment-block\">\n<div id=\"bc_0_6M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/05851775655646953918\" rel=\"nofollow\">Alexander Zolotko<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387898630992#c1523126078272807201\" rel=\"nofollow\">December 24, 2013 at 7:23 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_6MC\" class=\"comment-content\">JSON test fixtures looks very promising, but there already are several limitations:<\/p>\n<p>1. Everything is wrapped with JSONPickle(&#8230;)<br \/>\n2. Some JSON properties (e.g. &#8220;tpe&#8221;, &#8220;$ref&#8221;, &#8220;elems&#8221;, &#8220;value&#8221;) have special meanings, which means they can&#8217;t be used for anything else.<\/p>\n<p>Although it is technically JSON data, it can&#8217;t be used to talk to any Pickling-unaware API. It seems to be a fundamental limitation: you can&#8217;t preserve all the semantics of Scala without loosing format generality. JSON and similar serialisation formats work as the lowest common denominator which everybody understands. Those who have richer semantics in their languages will be forced to somehow encode them to restore in future.<\/p>\n<p>At the moment Scala application I&#8217;m writing looks like series of type transformations JSON &lt;-&gt; JSON parser types &lt;-&gt; case classes &lt;-&gt; [Some application logic] &lt;-&gt; case classes &lt;-&gt; ORM types &lt;-&gt; DB native type system. App logic is slim compared to dances around types. Maybe it will change in future, but at the moment it looks like waste of time.<\/p>\n<p>Clojure&#8217;s native data types are much closer to JSON and relational tuples, so less transformations are needed.<\/p>\n<p><span id=\"bc_0_6MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_6BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_6B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_7B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c6030008665467547580\" class=\"comment-block\">\n<div id=\"bc_0_7M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/00722138503315213359\" rel=\"nofollow\">Mar<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387902299024#c6030008665467547580\" rel=\"nofollow\">December 24, 2013 at 8:24 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_7MC\" class=\"comment-content\">Yes, pickling is a specialized form of serialization+deserialization which lets you retain concrete instance types. This is the central idea about pickling and what differentiates it from serialization\/deserialization. I agree that if you don&#8217;t need this information, then you are better off using a serializer for your format of choice.<\/p>\n<p>If what you are saying is &#8220;Clojure has native data structures and literals for these, much like JavaScript&#8221; then yes, that&#8217;s hard to disagree with \ud83d\ude42 But I don&#8217;t agree that Clojure&#8217;s data types are more similar to JavaScript&#8217;s than, for example, Scala&#8217;s.<\/p>\n<p>Deserializing JSON to Clojure data types would consist of the same steps as Scala, save for custom type providers which are not necessary\/possible. Platform-specific data types such as Ratio, Vector\/List etc would also be lost in the process, unless a Clojure-specific format (and matching &#8220;pickler&#8221;) was used.<\/p>\n<p><span id=\"bc_0_7MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_7BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_7B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_8B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c1124364057847387333\" class=\"comment-block\">\n<div id=\"bc_0_8M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/08897011817693913795\" rel=\"nofollow\">phil<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387936152804#c1124364057847387333\" rel=\"nofollow\">December 24, 2013 at 5:49 PM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_8MC\" class=\"comment-content\">Alexander Zolotko and Mar &#8211; Picking serializes to JSON or Binary at this moment, currently I use it to serialize to JSON files.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>As the website says &#8220;can be Language-Neutral if you want it to be. Changing the format of your serialized data is as easy as importing the correct implicit pickle format into scope. Out of the box, we currently support a fast Scala binary format, as well as JSON. Support is currently planned for other formats. Or, you can even roll your own custom pickle format!&#8221;.<\/p>\n<p><span id=\"bc_0_8MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_8BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_8B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_9B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c1797755539855683635\" class=\"comment-block\">\n<div id=\"bc_0_9M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/08897011817693913795\" rel=\"nofollow\">phil<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387936272477#c1797755539855683635\" rel=\"nofollow\">December 24, 2013 at 5:51 PM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_9MC\" class=\"comment-content\">Alexander, you can change the format of the JSON serialization very easily!<\/p>\n<p><span id=\"bc_0_9MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_9BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_9B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_10B\" class=\"comment\">\n<div id=\"bc_0_10BR\" class=\"comment-replies\">\n<div id=\"bc_0_1T\" class=\"comment-thread inline-thread\">\n<div>\n<\/div>\n<div id=\"bc_0_1I\" class=\"continue\"><a target=\"_self\">Reply<\/a>\n<\/div>\n<div id=\"bc_0_1T_box\" class=\"comment-replybox-thread\">\n<\/div>\n<\/div>\n<\/div>\n<div id=\"bc_0_10B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_11B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh3.googleusercontent.com\/-cKCqHJgTO6k\/AAAAAAAAAAI\/AAAAAAAAA40\/ND9TxHUyuNg\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c5605371626790237794\" class=\"comment-block\">\n<div id=\"bc_0_11M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/05851775655646953918\" rel=\"nofollow\">Alexander Zolotko<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387895762946#c5605371626790237794\" rel=\"nofollow\">December 24, 2013 at 6:36 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_11MC\" class=\"comment-content\">s\/Picking\/Pickling<\/p>\n<p><span id=\"bc_0_11MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div id=\"bc_0_11BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_11B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_12B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c776165237061121539\" class=\"comment-block\">\n<div id=\"bc_0_12M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/04905590931180096628\" rel=\"nofollow\">Unknown<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387901879007#c776165237061121539\" rel=\"nofollow\">December 24, 2013 at 8:17 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_12MC\" class=\"comment-content\">This is a great write up and echos conversations I have had with other scala and clojure developers. And as I read it I found myself agreeing with you that had I wrote this in scala I would be steered psychologically towards the OO approach. But as a counter example &#8211; what if I didn&#8217;t like the shuffle algorithm provided by clojure sequences? (Disclaimer: I have never used clojure, just read about it here and there). What if I want to do other things when drop or take is called? The OO approach always seems like overkill plumbing if all you are doing is putting a facade over an existing datatype &#8211; but you&#8217;re putting a contextual facade over that datatype &#8211; leaving out methods that don&#8217;t apply to a deck of cards and allowing you to do more than just the underlying data types actions. Are there actions you can do on a sequence in clojure that don&#8217;t apply to a deck of cards or that you wouldn&#8217;t want someone to be able to do? Python has a similar mindset &#8211; don&#8217;t keep the programmer from doing something dumb programmatically &#8211; its up to them to know what they&#8217;re doing. Thats great for rapid development in a team thats all about the same skill level &#8211; but I think there are places where an OO approach is more applicable. What do you think?<\/p>\n<p><span id=\"bc_0_12MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div id=\"bc_0_12BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_12B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_13B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c6181954618034165228\" class=\"comment-block\">\n<div id=\"bc_0_13M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/15174131995195090126\" rel=\"nofollow\">Unknown<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387918855909#c6181954618034165228\" rel=\"nofollow\">December 24, 2013 at 1:00 PM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_13MC\" class=\"comment-content\">&gt; the speed that comes from static typing<\/p>\n<p>Is this really an advantage? I thought the speed advantage Scala programs sometimes exhibit over Clojure programs just comes from the reduced reluctance to use destructive updates.<\/p>\n<p>I haven&#8217;t used static types on the JVM, but from talking to people who use it, they seem to care more about offering correctness guarantees than speed. Static types certainly get a speed boost over Groovy or JRuby programs which usually rely heavily on reflection, but this is rarely true (and easy to avoid) in Clojure programs.<\/p>\n<p><span id=\"bc_0_13MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div id=\"bc_0_13BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_13B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_14B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh5.googleusercontent.com\/-FJ-DhlqLhm8\/AAAAAAAAAAI\/AAAAAAAAAGg\/BlnUi7uESd0\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c3825992070859456864\" class=\"comment-block\">\n<div id=\"bc_0_14M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/11707703831241539347\" rel=\"nofollow\">Tommy McGuire<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387929878164#c3825992070859456864\" rel=\"nofollow\">December 24, 2013 at 4:04 PM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_14MC\" class=\"comment-content\">You&#8217;ve got a very good point there, and to an extent I&#8217;ll agree with you.<\/p>\n<p>But.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>There is at least one pitfall that goes along with what you call &#8220;lightweight data modelling&#8221; (great term, by the way): An excessive fascination with the<span class=\"Apple-converted-space\">\u00a0<\/span><i>representation<\/i><span class=\"Apple-converted-space\">\u00a0<\/span>of data, as opposed to its structure. It hit me hard a while back when I was reading<span class=\"Apple-converted-space\">\u00a0<\/span><a href=\"http:\/\/maniagnosis.crsr.net\/2011\/06\/some-lisp-suggestions.html\" rel=\"nofollow\"><i>Land of Lisp<\/i><\/a><span class=\"Apple-converted-space\">\u00a0<\/span>and found the first function from my blog post. So, I came up with a modified version of the program that uses the second function&#8212;they do exactly the same task.<\/p>\n<p>I realize that the second version is somewhat more verbose and that you don&#8217;t have any context to understand what it&#8217;s doing (which is not helped at all by the fact that I kept the same function names&#8212;they&#8217;re fiddling with game search trees). But I submit that the second might be preferable anyway.<\/p>\n<p>A compulsion to over-model every thing in sight is one of the major sins of object-oriented programming, and I get to struggle with it quite a lot at work lately. And my personal feeling is that Scala&#8217;s syncretism is rapidly heading towards Perl&#8217;s write-only-ness&#8212;it certainly doesn&#8217;t seem to be guiding anyone to the simplest solutions. But going too far the other way isn&#8217;t going to be any better.<\/p>\n<p><span id=\"bc_0_14MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div id=\"bc_0_14BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_14B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh5.googleusercontent.com\/-kT9Yx3TZ8Ds\/AAAAAAAAAAI\/AAAAAAAABMU\/uUkA-jvgmtY\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c4859835396428466110\" class=\"comment-block\">\n<div id=\"bc_0_16M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/07505997833685327219\" rel=\"nofollow\">Daniel Sobral<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387948752368#c4859835396428466110\" rel=\"nofollow\">December 24, 2013 at 9:19 PM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_16MC\" class=\"comment-content\">Actually, there _is_ something in Scala like clojure&#8217;s convenient keywords: symbols. They just don&#8217;t get much use (outside the compiler itself).<\/p>\n<p><span id=\"bc_0_16MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div class=\"comment-replies\">\n<div class=\"comment-thread inline-thread\"><span class=\"thread-toggle thread-expanded\"><span class=\"thread-toggle thread-expanded\"><span id=\"bc_0_15TA\" class=\"thread-arrow\" style=\"background: url('data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAG0lEQVR42mNgwAfKy8v\/48I4FeA0AacVDFQBAP9wJkE\/KhUMAAAAAElFTkSuQmCC') no-repeat 0px 0px; margin: 0.3em; width: 7px; height: 6px; overflow: visible; padding-right: 4px; display: inline-block;\"><\/span><span class=\"thread-count\"><a target=\"_self\">Replies<\/a><\/span><\/span><\/span><\/p>\n<div id=\"bc_0_15TD\" class=\"thread-dropContainer thread-expanded\">\n<\/div>\n<div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<li id=\"bc_0_15B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c3002285075055969943\" class=\"comment-block\">\n<div id=\"bc_0_15M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/12082249437984483148\" rel=\"nofollow\">Paul<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1388530643373#c3002285075055969943\" rel=\"nofollow\">December 31, 2013 at 2:57 PM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_15MC\" class=\"comment-content\">They don&#8217;t get used at all (that I can think of) in the compiler itself. The thing called &#8220;Symbol&#8221; in the compiler has no relationship.<\/p>\n<p><span id=\"bc_0_15MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_15BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_15B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_16B\" class=\"comment\">\n<div id=\"bc_0_16BR\" class=\"comment-replies\">\n<div id=\"bc_0_15T\" class=\"comment-thread inline-thread\">\n<div>\n<\/div>\n<div id=\"bc_0_15I\" class=\"continue\"><a target=\"_self\">Reply<\/a>\n<\/div>\n<div id=\"bc_0_15T_box\" class=\"comment-replybox-thread\">\n<\/div>\n<\/div>\n<\/div>\n<div id=\"bc_0_16B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh4.googleusercontent.com\/-q9_d92NULqg\/AAAAAAAAAAI\/AAAAAAAAAO8\/knPBCHsKzIA\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c2713842258032838745\" class=\"comment-block\">\n<div id=\"bc_0_18M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/01642315545975308056\" rel=\"nofollow\">Rui Gon\u00e7alves<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387975721740#c2713842258032838745\" rel=\"nofollow\">December 25, 2013 at 4:48 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_18MC\" class=\"comment-content\">You don&#8217;t need to create a whole new class for a Deck. I would model it as:<\/p>\n<p>sealed trait Suit<br \/>\ncase object Spades extends Suit<br \/>\ncase object Clubs extends Suit<br \/>\ncase object Hearts extends Suit<br \/>\ncase object Diamonds extends Suit<br \/>\ntype Deck = List[(Int, Suit)]<\/p>\n<p>This construct, acting like a type alias in this case, makes it easy for you to change Deck to a class if needed later. You shouldn&#8217;t need it though, as you can add any extra methods to your Deck through extension methods.<\/p>\n<p><span id=\"bc_0_18MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div class=\"comment-replies\">\n<div class=\"comment-thread inline-thread\"><span class=\"thread-toggle thread-expanded\"><span class=\"thread-toggle thread-expanded\"><span id=\"bc_0_17TA\" class=\"thread-arrow\" style=\"background: url('data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAG0lEQVR42mNgwAfKy8v\/48I4FeA0AacVDFQBAP9wJkE\/KhUMAAAAAElFTkSuQmCC') no-repeat 0px 0px; margin: 0.3em; width: 7px; height: 6px; overflow: visible; padding-right: 4px; display: inline-block;\"><\/span><span class=\"thread-count\"><a target=\"_self\">Replies<\/a><\/span><\/span><\/span><\/p>\n<div id=\"bc_0_17TD\" class=\"thread-dropContainer thread-expanded\">\n<\/div>\n<div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<li id=\"bc_0_17B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c6788213418549381109\" class=\"comment-block\">\n<div id=\"bc_0_17M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/03530457085095712842\" rel=\"nofollow\">ndw<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1388050977999#c6788213418549381109\" rel=\"nofollow\">December 26, 2013 at 1:42 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_17MC\" class=\"comment-content\">Exactly.<\/p>\n<p>And if you google &#8220;scala deck of cards&#8221; and look at what people do, &#8220;over-modeling&#8221; doesn&#8217;t seem to be an issue. (One solution appears to be inspired more by &#8220;C&#8221; than Java, but again, &#8220;over-modeled&#8221; it ain&#8217;t).<\/p>\n<p>The scala community is definitely heterogenous but baroque object models are pretty generally frowned upon in my experience.<\/p>\n<p><span id=\"bc_0_17MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_17BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_17B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_18B\" class=\"comment\">\n<div id=\"bc_0_18BR\" class=\"comment-replies\">\n<div id=\"bc_0_17T\" class=\"comment-thread inline-thread\">\n<div>\n<\/div>\n<div id=\"bc_0_17I\" class=\"continue\"><a target=\"_self\">Reply<\/a>\n<\/div>\n<div id=\"bc_0_17T_box\" class=\"comment-replybox-thread\">\n<\/div>\n<\/div>\n<\/div>\n<div id=\"bc_0_18B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/img2.blogblog.com\/img\/b36-rounded.png?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c2941047153370544233\" class=\"comment-block\">\n<div id=\"bc_0_20M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/04047789008225551019\" rel=\"nofollow\">Unknown<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1387981682600#c2941047153370544233\" rel=\"nofollow\">December 25, 2013 at 6:28 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_20MC\" class=\"comment-content\">The problem is that both approaches have their pros and cons. The &#8220;clojure&#8221; approach is the dynamic approach. What a (good) python\/perl\/&#8230; programmer would do. The &#8220;scala&#8221; approach is the general approach a (good) Java\/C++\/&#8230; programmer would take. And you&#8217;re right, for simple operations the dynamic approach would be best, simply because lots of operations are loosely defined because you&#8217;re using very basic classes.<\/p>\n<p>However when the data becomes more complex, all these functions start to have side effects. There are plenty of lists you can&#8217;t &#8220;take&#8221; from random places, shuffle may not be possible for the datastructure you&#8217;ve implemented. God forbid the list is a list that actually exists in a remote database.<\/p>\n<p>So the problem here is small versus large programs. The dynamic approach you describe is unbeatable for small programs, and a complete disaster for large ones. You implicitly apply a large, very-high-up class to your data and lots of stuff just works.<\/p>\n<p>When your program grows you&#8217;re going to find that it doesn&#8217;t always do the right thing and you need to either:<\/p>\n<p>1) reimplement the semantic equivalents of take, shuffle, and give them some weird name. Then live with the fact that anybody in your team can just call the wrong functions and you&#8217;d never find it.<\/p>\n<p>2) switch to the Scala static approach.<\/p>\n<p><span id=\"bc_0_20MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div class=\"comment-replies\">\n<div class=\"comment-thread inline-thread\"><span class=\"thread-toggle thread-expanded\"><span class=\"thread-toggle thread-expanded\"><span id=\"bc_0_19TA\" class=\"thread-arrow\" style=\"background: url('data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAG0lEQVR42mNgwAfKy8v\/48I4FeA0AacVDFQBAP9wJkE\/KhUMAAAAAElFTkSuQmCC') no-repeat 0px 0px; margin: 0.3em; width: 7px; height: 6px; overflow: visible; padding-right: 4px; display: inline-block;\"><\/span><span class=\"thread-count\"><a target=\"_self\">Replies<\/a><\/span><\/span><\/span><\/p>\n<div id=\"bc_0_19TD\" class=\"thread-dropContainer thread-expanded\">\n<\/div>\n<div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<li id=\"bc_0_19B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/lh4.googleusercontent.com\/-4D5W0t6guXY\/AAAAAAAAAAI\/AAAAAAAAA3I\/q2l7VSUgRxY\/s512-c\/photo.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c4972287046929292541\" class=\"comment-block\">\n<div id=\"bc_0_19M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/06490729138296215124\" rel=\"nofollow\">Alex King<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1389045914663#c4972287046929292541\" rel=\"nofollow\">January 6, 2014 at 2:05 PM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_19MC\" class=\"comment-content\">Large programs almost always end up in complete disaster, compile times and the time tests take to run slowly creep up until maintenance and adding new features becomes a nightmare.<\/p>\n<p>Refactoring should be done at an application level as well to ensure programs stay small, it shouldn&#8217;t matter which language they are written in.<\/p>\n<p>Better to keep programs small, pick the right language for the job, continually refactor, and focus on end to end tests so components can be easily replaced.<\/p>\n<p><span id=\"bc_0_19MN\" class=\"comment-actions secondary-text\"><\/span>\n<\/div>\n<div id=\"bc_0_19BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_19B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_20B\" class=\"comment\">\n<div id=\"bc_0_20BR\" class=\"comment-replies\">\n<div id=\"bc_0_19T\" class=\"comment-thread inline-thread\">\n<div>\n<\/div>\n<div id=\"bc_0_19I\" class=\"continue\"><a target=\"_self\">Reply<\/a>\n<\/div>\n<div id=\"bc_0_19T_box\" class=\"comment-replybox-thread\">\n<\/div>\n<\/div>\n<\/div>\n<div id=\"bc_0_20B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<li id=\"bc_0_21B\" class=\"comment\">\n<div class=\"avatar-image-container\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/3.bp.blogspot.com\/-tpUlwA56lS0\/UZekvWw4WqI\/AAAAAAAAALk\/h2H32g4jDyI\/s45\/51679-005%25252Bgrant_rettke-FINAL.jpg?w=623\" alt=\"\" data-recalc-dims=\"1\" \/>\n<\/div>\n<div id=\"c776995347552308076\" class=\"comment-block\">\n<div id=\"bc_0_21M\" class=\"comment-header\"><cite class=\"user\"><a href=\"http:\/\/www.blogger.com\/profile\/09439997834215273665\" rel=\"nofollow\">grant rettke<\/a><\/cite><span class=\"datetime secondary-text\"><a href=\"http:\/\/programming-puzzler.blogspot.com\/2013\/12\/clojure-vs-scala.html?showComment=1395596115683#c776995347552308076\" rel=\"nofollow\">March 23, 2014 at 10:35 AM<\/a><\/span>\n<\/div>\n<p id=\"bc_0_21MC\" class=\"comment-content\">Integers would be a great starting point and they could represent everything that you need as long as you are OK with codifying the constraints in a function.<\/p>\n<p><span id=\"bc_0_21MN\" class=\"comment-actions secondary-text\"><a target=\"_self\">Reply<\/a><\/span>\n<\/div>\n<div id=\"bc_0_21BR\" class=\"comment-replies\">\n<\/div>\n<div id=\"bc_0_21B_box\" class=\"comment-replybox-single\">\n<\/div>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/address>\n","protected":false},"excerpt":{"rendered":"<p>http:\/\/programming-puzzler.blogspot.kr\/2013\/12\/clojure-vs-scala.html Clojure vs Scala Last week, someone posted a question on the Clojure group asking for a comparison between Clojure and Scala. Since my most popular blog post, by far, is my\u00a0Racket vs Clojure\u00a0post from three years ago, I thought it would be good to post my response here.Ten years ago, I would have said that my ideal dream language is one that provides the flexibility to program in any style. I want to be able to choose object-oriented or functional, immutable or mutable, high-level abstractions or low-level speed. With respect to this ideal, Scala clearly wins, supporting more programming styles than Clojure. I&#8217;ve definitely changed my tune, though, and now I actually prefer the way that Clojure constrains and shapes my thinking. I argue that even though Scala may provide me with more options on how to tackle a given programming problem, Clojure guides me towards a simpler solution. If this intrigues you, read on&#8230; The following text is only slightly paraphrased from what I posted to the group: All or nearly all of the functional aspects of Clojure have counterparts in Scala. On top of that, Scala provides mutable flavors of everything, so you can pick and choose [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"ngg_post_thumbnail":0,"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[7],"tags":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5q9Zn-5Z","jetpack-related-posts":[{"id":369,"url":"https:\/\/blog.box.kr\/?p=369","url_meta":{"origin":371,"position":0},"title":"Scala, Clojure, Groovy \uadf8\ub9ac\uace0 \uac1c\ubc1c\uc790\uc758 \uc5b8\uc5b4","date":"2014-09-15","format":false,"excerpt":"http:\/\/www.okjsp.net\/seq\/216749 \u00a0 \u00a0 Scala, Clojure, Groovy \uadf8\ub9ac\uace0 \uac1c\ubc1c\uc790\uc758 \uc5b8\uc5b4 \uac1c\ubc1c\uc790\ub3c4 \uc138\ucee8\ub4dc \uc5b8\uc5b4 \ud639\uc740 \ud568\uc218\ud615 \uc5b8\uc5b4 \ud558\ub098\ucbe4\uc740 \ud574\uc57c \ud560 \uc2dc\uae30\uac00 \uc628\uac70 \uac19\uc2b5\ub2c8\ub2e4.\u00a0 \ubaa8\ubc14\uc77c\ub85c \uac08\uc544\ud0c0\uc9c0 \uc54a\ub294\ub2e4\uba74, \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd, \uc5d4\ud130\ud504\ub77c\uc774\uc988 \ud658\uacbd\uc5d0\uc11c\ub294 \uc790\ubc14 \uc790\uccb4\ub9cc\uc73c\ub85c\ub294 \ud574\uacb0 \ud560 \uc218 \uc5c6\ub294 \uce21\uba74\ub4e4\uc774 \ub098\uc640\uc11c \uc138\ucee8\ub4dc \uc5b8\uc5b4\uc5d0 \ub300\ud55c \uc218\uc694\uac00 \uc810\uc9c4\uc801\uc73c\ub85c \uc0dd\uaca8\ub098\uc9c0 \uc54a\uc744\uae4c \ud558\ub294 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4dc\ub124\uc694.\u00a0 \ub300\ud45c\uc801\uc73c\ub85c\ub294, \uc678\uad6d \uc0ac\ub840\ub97c\u2026","rel":"","context":"In &quot;\ucc38\uace0\ub97c \uc704\ud55c \uc800\uc7a5\ubb3c&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":367,"url":"https:\/\/blog.box.kr\/?p=367","url_meta":{"origin":371,"position":1},"title":"[\ud38c]Scala \uc2dc\uc791\ud558\uae30","date":"2014-09-15","format":false,"excerpt":"\u00a0 http:\/\/ppassa.wordpress.com\/2012\/02\/19\/getting_started_scala\/ Scala \uc2dc\uc791\ud558\uae30 \uc694\uc998 \ub4e4\uc5b4\uc11c\u00a0Scala\ub97c \uacf5\ubd80\ud558\uace0 \uc788\ub2e4. \uc544\uc9c1 \ub9ce\uc774 \ubd80\uc871\ud558\uc9c0\ub9cc, \uc9c0\uae08\uae4c\uc9c0 \ubc30\uc6b4 \uac83\ub4e4 \uae30\ub85d\ud574\ub450\uace0, \ub610 \ud639\uc2dc \uc870\uae08\uc774\ub77c\ub3c4 \ub3c4\uc6c0\uc774 \ub418\ub294 \ubd84\ub4e4\uc774 \uc788\uc744 \uc9c0 \ubab0\ub77c \uacf5\uc720\ud574\ubcf4\uace0\uc790 \ud55c\ub2e4. 1. \ub4e4\uc5b4\uac00\uba70 \ubb58 \ub610 \ubc30\uc6cc\uc57c \ud55c\ub2e8 \ub9d0\uc778\uac00? \uc774\ubbf8 C++, Java, Python, Ruby, JavaScript \ub4f1 \ub9ce\uc740 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\ub4e4\uc774 \uc788\ub294\ub370, \uc65c \uc790\uafb8 \uc0c8\ub85c\uc6b4 \uc5b8\uc5b4\uac00 \ub098\uc624\uace0 \uc788\ub0d0?\u2026","rel":"","context":"In &quot;\ucc38\uace0\ub97c \uc704\ud55c \uc800\uc7a5\ubb3c&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":242,"url":"https:\/\/blog.box.kr\/?p=242","url_meta":{"origin":371,"position":2},"title":"Intellij\uc5d0\uc11c Scala + akka \uc124\uc815","date":"2014-07-23","format":false,"excerpt":"Intellij 13 \ubc84\uc804 \uae30\uc900 \u00a0 1. Scala \uc124\uce58 2. SBT \uc124\uce58 3. Intellij\uc5d0\uc11c Scala\ub97c \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c\ub294 \ud50c\ub7ec\uadf8\uc778\uc73c\ub85c Scala\uc640 sbt \ub458 \ub2e4 \ubaa8\ub450 \uc124\uce58\ud55c\ub2e4. - \uc124\uce58 \ud6c4 'Setting'\uc5d0\uc11c \uc704\uc5d0 \uc124\uce58\ud55c Scala\uc640 SBT\ub97c \uc124\uc815\ud55c\ub2e4. 4. sbt\ub97c \ud1b5\ud574 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \ub9cc\ub4e4\uae30 \uc704\ud574\uc11c\ub294 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c sbt-module\ub97c \uc120\ud0dd\ud55c \ud6c4 build.sbt\uc5d0 \ud544\uc694\ud55c \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc124\uc815\ud55c\ub2e4. \uc704\uc758 build.sbt\uc758 akka \uc124\uc815\uc740\u2026","rel":"","context":"In &quot;JAVA&quot;","img":{"alt_text":"","src":"http:\/\/cfile27.uf.tistory.com\/image\/2418E83652F07318013FE6","width":350,"height":200},"classes":[]},{"id":244,"url":"https:\/\/blog.box.kr\/?p=244","url_meta":{"origin":371,"position":3},"title":"\ud29c\ud1a0\ub9ac\uc5bc: \uc2a4\uce7c\ub77c(Scala), akka \ub85c scalable \ud558\uace0, fault-tolerant \ud55c \ub124\ud2b8\uc6cc\ud06c \ucc44\ud305 \uc11c\ubc84\uc640 \ud074\ub77c\uc774\uc5b8\ud2b8 \ub9cc\ub4e4\uae30","date":"2014-07-23","format":false,"excerpt":"\ud29c\ud1a0\ub9ac\uc5bc: \uc2a4\uce7c\ub77c(Scala), akka \ub85c scalable \ud558\uace0, fault-tolerant \ud55c \ub124\ud2b8\uc6cc\ud06c \ucc44\ud305 \uc11c\ubc84\uc640 \ud074\ub77c\uc774\uc5b8\ud2b8 \ub9cc\ub4e4\uae30 SW\uac1c\ubc1c \u00a0http:\/\/doc.akka.io\/docs\/akka\/1.3.1\/scala\/tutorial-chat-ser..","rel":"","context":"In &quot;JAVA&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":364,"url":"https:\/\/blog.box.kr\/?p=364","url_meta":{"origin":371,"position":4},"title":"[\ud38c]\uac1d\uccb4\uc9c0\ud5a5+\ud568\uc218\ud615 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 Scala","date":"2014-09-15","format":false,"excerpt":"\uac1d\uccb4\uc9c0\ud5a5+\ud568\uc218\ud615 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 Scala \uc2a4\uce7c\ub77c(Scala)\ub294 \uac1d\uccb4\uc9c0\ud5a5 \uc5b8\uc5b4\uc774\uba74\uc11c \ub3d9\uc2dc\uc5d0 \ud568\uc218 \uc5b8\uc5b4\uc774\ub2e4. \uc2a4\uce7c\ub77c\ub294 \uc790\ubc14\uc640 \ub9c8\ucc2c\uac00\uc9c0\ub85c \uc790\ubc14\uac00\uc0c1\uba38\uc2e0(JVM) \uc704\uc5d0\uc11c \uc2e4\ud589\ub418\uba70 \uae30\uc874 \uc790\ubc14 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \ubc18\ub300\ub85c \uc790\ubc14\ub85c \uc791\uc131\ub41c \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc2a4\uce7c\ub77c\ub85c \uc791\uc131\ub41c \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud560 \uc218\ub3c4 \uc788\ub2e4. \ub2e4\ub978 JVML(JVM \uc5b8\uc5b4)\uc778 JRuby, Jython\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c \uc2a4\uce7c\ub77c\ub294 \uc790\ubc14\uc758 \ud55c\uacc4\ub97c \uadf9\ubcf5\ud558\uae30 \uc704\ud574 \ucd9c\ud604\ud588\ub2e4. \ud2b9\ud788, \uc774\ubbf8 \uc124\uacc4\ub41c \ucef4\ud3ec\ub10c\ud2b8 \ub2e8\uc704\uc758\u2026","rel":"","context":"In &quot;\ucc38\uace0\ub97c \uc704\ud55c \uc800\uc7a5\ubb3c&quot;","img":{"alt_text":"","src":"http:\/\/cfs14.tistory.com\/image\/18\/tistory\/2008\/12\/01\/00\/11\/4932ad2c8146f","width":350,"height":200},"classes":[]},{"id":847,"url":"https:\/\/blog.box.kr\/?p=847","url_meta":{"origin":371,"position":5},"title":"[scrap]Automated Testing of REST Services","date":"2015-05-20","format":false,"excerpt":"http:\/\/java.dzone.com\/articles\/automated-testing-rest?utm_content=buffer084c1&utm_medium=social&utm_source=facebook.com&utm_campaign=buffer \u00a0 Despite the fact that I\u2019m a Java and Scala developer I still passionate about testing software, to be more precise\u2013 web applications. It\u2019s really interesting to develop web app and be confident that the apps are of good quality. When I\u2019ve started a career the most popular web\u2026","rel":"","context":"In &quot;\uae30\uc220&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts\/371"}],"collection":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=371"}],"version-history":[{"count":0,"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts\/371\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=371"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=371"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}