
Effective Scala - auggierose
http://twitter.github.io/effectivescala/
======
auggierose
Scala is becoming my programming language of choice, especially since I tried
out Scala.js which really works well.

I am currently porting a Clojure library of mine to Scala, and it is about 10%
less code, and obviously more robust because of static type checking.

Scala.js: [https://github.com/lampepfl/scala-
js](https://github.com/lampepfl/scala-js)

~~~
TylerE
Can you compare and contrast Scala with Clojure? I've dabbled in both... I in
theory prefer Scala, but I found it just has sooo many moving parts I can't
keep it in my head.

~~~
auggierose
I can show you two code samples of mine, one in Clojure, the other one doing
something very similar in Scala:

    
    
      (defn completion-items [grammar doc items-bin-index completed-bin-index items nonterminal value]
      (loop [items items
             completed '()]
        (if-let [[^Item item previous-value] (first items)]
          (let [alpha (expected-symbol grammar item)
                dot (.dot item)]
            (if (and alpha (= nonterminal alpha))
              (let [rule-nonterminal (.nonterminal item)
                    ruleindex (.ruleindex item)
                    origin (.origin item)
                    value' (gen-nextvalue grammar doc origin items-bin-index completed-bin-index
                                          rule-nonterminal ruleindex dot
                                          previous-value value)]
                (if (nil? value')
                  (recur (next items) completed)
                  (let [item' (->Item rule-nonterminal ruleindex (+ dot 1) origin)]
                    (recur (next items) (cons-item-value completed item' value')))))
              (recur (next items) completed)))
          (apply hash-map completed))))
    
      --------------------------------------------------------
    
      def complete_items(completed_binindex : Int, bin : ItemBin, nonterminal : Nonterminal, value : Value) : MoreItems = {
        var completed_items : List[(Item, IntermediateValue)] = List()
        for ((item, v) <- bin.items) {
          val s = expectedSymbol(item)
          if (s == Some (nonterminal)) {
            grammar.nextValue(document, item.origin, bin.binindex, completed_binindex, nonterminal, 
              item.ruleindex, item.dot, v, value) match 
            {
              case None => 
              case Some(nextvalue) =>
                completed_items = (item.inc -> nextvalue) :: 
                  completed_items
            }
          }
        }
        completed_items    
      }

~~~
brandonbloom
That's quite non-idiomatic Clojure...

1) Unnecessary type hint

2) No use of destructuring or field lookup by keyword

3) Alteration of record objects with positional constructors instead of
update-in

4) Explicit loop with previous item instead of reduce over (partition 2 1
items)

5) Way too many parameters

6) Apply hash-map instead of into

7) (+ ... 1) instead of inc

8) Weird gen-nextvalue auxiliary function instead of a lazy sequence

I could keep going...

~~~
auggierose
The thing is: In order to have performance, you need type hinting (a lot of
it). I DO need performance, as the algorithm above is already part of
something O(n^3). There also clojure.core.type does not help. And that is the
problem with a language feature which is not a compiler feature as well.

By the way, gen-nextvalue is a protocol function.

~~~
brandonbloom
> In order to have performance, you need type hinting (a lot of it).

No, not really. That has only been my experience when interoperating with Java
libraries. Protocol dispatch has inline call caches, which are almost as fast
as normal java interface dispatch.

> that is the problem with a language feature which is not a compiler feature
> as well

You could also say "that is the problem with type system features which are
not virtual machine features as well". There is lots of erased information in
the Scala type system that could be used for optimizations, but the VM can't
make much use of that.

Scala's type system does 3 things:

1) Enable type-related optimizations

2) Ensure internal consistency (ie prevent errors)

3) Enhance expressivity through logic solver search

Clojure's type hints provide just enough type system to trigger host
optimizations, where as core.typed is for finding and preventing bugs. I
consider the implicitness of #3 to be an anti-feature.

------
netcraft
just a suggestion if the author is here - maybe be more consistent when
showing bad vs good - sometimes you show the good then the bad and sometimes
vice versa. Try to stick to one or the other - or alternatively change the
background color of the examples to red and green to clearly show bad
examples.

~~~
ape4
Effective Effective Documents.

------
auggierose
The description about comments is somewhat wrong. The Scaladoc standard is not

    
    
        /** My comment
         *  Next Line
         */
    

which is pretty ugly, but it is

    
    
        /** My comment
          * Next Line
          */
    

which looks much better. :-)

------
obilgic
The question i have been struggling to answer for few months now: Scala or Go?

~~~
trailfox
Pick Scala if:

    
    
      -You think a fusion of OO and functional programming is the way of the future
      -Runtime tooling and advanced instrumentation support matter to you
      -You like having first-class IDE support
      -You want to work for the likes of Twitter/Foursquare/LinkedIn/Amazon
      -Having tons of mature Java libraries available matters to you.
      -You don't mind investing time to learn the language
    

Pick Go if:

    
    
      -Memory footprint matter to you (and you don't want to pick C)
      -Startup time matters to you (and you don't want to pick C)
      -You don't want to spend much time learning the language
      -You like C-style error handling and aren't expecting something as expressive as a python or a ruby.
      -You don't mind limited IDE support
      -You want every post of yours to be voted up on HN regardless of content

~~~
Refefer
I would add a few more:

Pick Scala if:

    
    
        -You find value in strong static assurances.
        -You find value in generics.
        -You want to learn functional programming, not 'functional' programming (and you should).
        -You value succinctness.
    

Pick Go if:

    
    
        -Compile times matter (of course it does).
        -You find value in easier deployments (at the cost of potentially more deployments).
        -You don't want to learn D ;)

~~~
saosebastiao
Ha...love the last line. If I were in the market for something that solves the
problems that Go attempts to solve, I would learn D. I just wish DMD was fully
open source...it is awesome when you go to try a new language and all you have
to do is "sudo apt-get ...".

~~~
asdasf
I believe that very small sounding issue has played a huge role in D being as
uncommonly used as it is. It seems like a trivial thing, but the ability to
just pkg_add languageX is incredibly important for adoption.

~~~
narwally
I don't think this is a small issue at all. I love reading through an
interesting tutorial, and being able to apt-get install the language or
libraries I need to work along with it. But if you make me jump through a
bunch of hoops just to work through a tutorial, forgetaboutit!

------
benmccann
I really wish they'd work on compilation speed. It probably takes me 20
minutes to do a clean compile of the Play Framework.

~~~
gtani
They _are_ working on that specific sbt /play combo, tho this doesn't look
like huge numbers

[https://gist.github.com/jroper/6374383](https://gist.github.com/jroper/6374383)

If you dig thru the internals list, there are a number of fronts they're
working on to produce fewer short lived intermediate objects, parallelize
builds etc

[https://groups.google.com/forum/?_escaped_fragment_=forum/sc...](https://groups.google.com/forum/?_escaped_fragment_=forum/scala-
internals#!forum/scala-internals)

------
pnathan
Can someone knowledgeable in both comment on Scala vs. Rust in terms of the
languages themselves (as opposed to the runtimes)?

------
chii
i take it this is modeled after the "effective java" book? sounds interesting
as a future reference to read.

~~~
mdup
Effective Java and Effective C++ have a good format for listing best
practices, and nowadays more and more languages seem to adopt their own
"Effective" book or web page... I like how useful they are to see real-world
problems before you decide picking up a language.

