notes-computer-programming-programmingLanguageDesign-prosAndCons-scala

"Scala was... an attempt to come up with a decent statically typed language that is both functional and object-oriented and that interoperates on standard VMs." -- Martin Odersky, http://www.codecommit.com/blog/scala/is-scala-not-functional-enough#comment-4162

the subtext guy on scala: http://alarmingdevelopment.org/?p=562#more-562

"the rules for inferring semicolons are different inside braces than they are inside parentheses"

" the () vs. {} issue bugs me a lot "

" Yes, Scala does have some rough edges (the () vs. {} issue bugs me a lot). On the other hand, Scala's cleaner than Ruby or Java. "

" It even has a half-baked Actor model trying to mimic Erlang's, albeit without Erlang's elegance. "

" I've been happily coding in Scala for the last 2 years.

Unlike any other language I've used (C, C++, Objective-C, Java, Ruby, etc.), the kind of thinking I have to do as a library consumer and library producer are radically different.

As a library consumer, I rarely concern myself with Scala's type system... or most of the other language complexities. My consumer code looks and feels a lot like my Ruby code did. I've got great DSL support. For the most part, the types that the compiler doesn't infer are the ones I need to document anyway. But, unlike my Ruby code, I only need 50%-60% test coverage (vs. 95% coverage) to have stable, deployable code.

As a library producer (http://liftweb.net), I spend a lot of time reasoning about the types of parameters. This allows the compiler to flag illegal types (e.g., passing an Int into a query against a VARCHAR column). The type system also allows me to reason about my code and how the consumers will use my libraries in a way that I could not do in any other language I've ever used. "

" My biggest annoyance with Scala (and other OO languages) is the lack of support for promoting the return types of certain methods during sub-classing. But, this has been fixed with higher-kinded types, and should be in the language fairly soon. So, I'm optimistic about Scala's future. "

" It's been a year since I started using Scala, so I'm by no means an expert. While Scala's type system is complicated when described, actually using it isn't that bad, once you get used to it. The type system has certainly been put in for a reason.

The worst thing about the language in my experience is that in order to make the code neater and smaller, a lot of things are optionally implicit (types, function invocation, object construction, object coercion). This can make the code harder to read later. "

" johnx123-up 17 hours ago

link

> From what I've seen it's been a one-way street from Java -> Scala.

Those users may be core Java developers who don't use any frameworks. If you ask me, Scooter is quite is easy to port any Ruby code easily than any other Scala frameworks out there. Scala adoption is killing Play community (2 times it got forked due to the difference) and that's why they now market it for both Scala and Play. As someone mentioned in Play forum long time ago, Scala is not suitable for team due to its readability. Heck I myself (and our team) used Scala and moved back to Java Play.

reply

trailfox 16 hours ago

link

Interesting. We find Scala to be more readable than Java. I guess it depends on the type/style of Scala you write. You definitely need be mindful of readability when writing Scala code (code reviews etc. help to ensure readable code). We use Play because it works well with Scala.

reply "

opinions

http://neopythonic.blogspot.com/2008/11/scala.html (complains about complexity, o/w not too interesting)

http://www.codecommit.com/blog/scala/is-scala-not-functional-enough

" tenpoundhammer 1 hour ago

link

I just started using scala on the job and have never been more confused in my life. I wish I was getting stuff done instead.

reply "

" AnonymousAugust? 18, 2013 at 9:32 PM

I am kind of upset that Google is not taking up Scala in a big way. The compiled code is almost always as fast as Java. The type system is much much better than Go and is capable of inferring much more than Go, with very advanced support for generics. Scala code is always much more compact than Go (true for most functional languages). Most features in other languages are simply implemented as a library in Scala. In particular Go channels are available as an Akka actor library in Scala. However Go has nothing comparable to Scala's Futures and Finagle libraries for async I/O support.

If Google were to invest more resources in Scala, it can make developers world wide much more happier.

I understand that Go might be an improvement over C++/Java. But it pales in comparison to all the programming language research over the past 3 decades that has produced languages like Haskell, ML and Scala.

Personally for me, Go might have been a good choice 20 years ago, but right now, I just don't see why I should be using it when Scala can do everything better.

Reply Replies

    Andrew GerrandAugust 18, 2013 at 9:37 PM
    Scala doesn't solve all the problems that Go was designed to solve. And it makes some of the problems worse.
    For background: http://talks.golang.org/2012/splash.article
    AnonymousAugust 18, 2013 at 11:55 PM
    Engineers at Google enjoy compiling and testing their code in less than an afternoon.
    AnonymousAugust 19, 2013 at 8:34 AM
    I have worked as a Scala developer for two years now and must say the slowness of the Scala compiler is a huge downside.
    The pauses when compiling even a few files are long enough to constantly distract you from the problem you are trying to solve. I (subjectively) never felt like I was much more productive in Scala than in Java.
    Matt WelshAugust 19, 2013 at 8:51 AM
    Indeed, one of the most important design considerations for Go is fast compilation. In huge projects (like we have at Google), this matters.
    AnonymousAugust 19, 2013 at 9:17 AM
    I use Scala in the eclipse IDE and it launches projects in less than 3 seconds. This is because of incremental builds. Full builds are slower. The project size is around a couple of thousand lines of Scala+Java code. While this may not seem huge, Scala code is way more compact than Java. The Scala compiler itself is less than 100K lines of code.
    With incremental builds, I have never been bitten by the slow compilation issue.
    Frankly, with Scala I have written 50-100 lines of code, equivalent to maybe 500 lines of Java code and it very often works on the first run! Because the type checker really is that good and catches 90% of your typical bugs, which makes you much more aware of the remaining 10% of the bugs. My code quality in Scala is super high, when compared to code in any other language, except may be Haskell. I have written thousands of lines of Scala code with barely a bug reported by anyone at all.
    If you set up your build to do incremental compiles, I just don't see any reason to switch to something else. I have looked at Go, they only have a limited set of built in generics and a far less sophisticated GC than the JVM, no IDE support(with autocomplete, background compilation etc, errors highlighted as you type) and far weaker ecosystem compared to Scala/Java. I just don't understand what benefit I can derive from using Go.
    AnonymousAugust 19, 2013 at 9:20 AM
    > For background: http://talks.golang.org/2012/splash.article
    I did not find anything specific about scala here
    AnonymousAugust 20, 2013 at 8:31 AM
    So just go on using Scala if you like it. Just to balance your opinion, I'm happy Google is not taking up Scala in a big way."

upvote

neya 10 hours ago

link

Another Scala user here. And I've been using Scala for the last six months. Mostly developing web applications on Scalatra and Play. I love Scala - It still has its goodiness and it's an excellent alternative to Java.

If you notice in all of the Scala books (I've read the one by Martin and the One by David Pollak as well), they all seem to push you towards the functional programming model instead of the much more common imperative model.

But you know, there's a problem with that. Not with the language itself, but with the web development side of Scala. There's only certain ways by which you can program with a particular function that accepts a request and returns a response. So, most of the time, I would find myself wasting time thinking "How can I make this more functional?"

Functional programming is really great when you can actually enforce it - When writing algorithms and so forth, but otherwise, you are forced to fallback to this imperative model which sucks, because you have to constantly keep changing your mindset between these two models.

Another downside of Scala is its HUGE syntax. Processing strings? Here's a ten million ways to do it.. (a bit over-exaggerating). Oh and if you chose this way, then you should use this syntax. No, not that one, THIS one. Oh no, not that one, this variation of that one that looks like this.

I've advocated Scala to many HN members here in the past, you can even check out my comments, for instance. But from my experience, I think Scala is an Academic language. But it's superior in its own ways - I just LOVE the concept of avoiding nulls and passing an Option. It's beautiful. But the downside is its huge academic complex syntax. I want to be able to write code which shouldn't reduce my hair count even if I look at it after 6 long months. I don't want to refer to an 800 page book each time I'm confused about something.

That's why I think Go is beautiful. The syntax is just enough to keep it inside your head forever. I fear that as the language matures, this might also evolve into something as complex as Scala, but let's hope not so.

Go isn't a magic bullet though. It has its own downsides, but nothing w.r.t performance or similar. For the most part, it's awesome.

Once you go Go, you never go back.

P.s - I still love Scala as well ;)

reply

upvote

rybosome 7 hours ago

link

I've historically been pretty pro-Scala 'round these parts, so my response to this should be considered in that light. So, with that disclosure out of the way... =)

I have to admit, I don't agree with the assertion that the cognitive dissonance associated with programming in an imperative way versus a functional way is a major problem to Scala. I realize personal preference is a very big part of this, but there are many problems which are just easier to solve in a functional way versus an imperative way. Of course, the opposite holds true as well. This is the beauty of Scala; one can write performance-critical imperative code while exposing a functional interface; or, one can consume a fluent functional interface to produce imperative code.

Frankly, I guess I've become something of a functional zealot, so my problem with Go is that it's so stubbornly imperative. This is why I can't get behind Go, as much as I want to. I feel like it doesn't consider many of the lessons that have been learned about FP making life easier. Set operations (map, filter, reduce) are insanely common, yet doing them imperatively sucks to the point of discouraging them. Excessive mutability is difficult to reason about. Nobody expects the nil/null/none inquisition. We tend to forget about side effects. Without an extensible language, which requires truly first-class functions, you're at the language designer's mercy.

Hell, Scala probably isn't the be-all, end-all answer to all of this. I just don't think that a doggedly-imperative, non-composable, statement-oriented language is the future of programming "in the large", not when the past has shown us that we tend to produce buggy, unmaintainable software this way. I'm pragmatic enough to realize that pure FP isn't a solution, but I feel strongly that sticking to traditional imperative because it's familiar is a costly mistake.

I can't argue with your take on the syntax, though, since that's personal preference. =) If you have any thoughts on why you feel productive in Go, I'd love to hear them; as I've said, I've been really struggling with motivating myself to learn and enjoy it.

reply

upvote

realrocker 7 hours ago

link

Have ever tried programming in Go?

Edit: Functional Programming in Go 1. http://stackoverflow.com/questions/4358031/functional-progra... 2. http://golang.org/doc/codewalk/functions/

reply

upvote

rybosome 6 hours ago

link

I'm currently in a study group at work for Go, and I'm writing a few one-off personal tools with it. This is hardly serious experience, but it's enough to get a flavor for the language.

As the other answer to your question states, adopting a functional style in Go is technically possible, but practically it is so inconvenient as to be unusable.

EDIT: Take a look at this article, which explores developing a library that adds runtime-checked type parametric functions. http://blog.burntsushi.net/type-parametric-functions-golang

Choice quote:

"There’s no such thing as a free lunch. The price one must pay to write type parametric functions in Go is rather large:

Type parametric functions are SLOW. Absolutely zero compile time type safety. Writing type parametric functions is annoying. Unidiomatic Go."

reply

upvote

gnuvince 7 hours ago

link

Go doesn't lend itself to functional programming, in part because of its lack of type parametrization. In a language like Scala or Haskell, using functions like map, fold, and filter is clean an idiomatic. In Go, it is so ugly and convoluted that you immediately reject this approach and use for loops instead.

reply

upvote

eranation 10 hours ago

link

For an academic language (which I assume is factually true as it was developed in a university) it is one of the most developer friendly academic languages out there IMHO, I rather write Scala than Java in terms of complexity, and if I would need to rewrite a Ruby code base, I would give it a shot in Scala before trying Go (feels more natural to me, they have way more similarities than I thought) I have the parts I need from Scala easily fitting in my head, which is perhaps just a subset, but enough for me to be very expressive in it.

I think one of Scala's biggest issues is people being turned off by what sometimes feels as functional zealotry[0]. But people perhaps are not aware that it is also a great imperative language, you get no compiler warnings if you use a var or a mutable collection. I find it very close to Ruby actually and I think Ruby developers will feel at home with it [1]

The other thing that holds it back IMHO is the compile time. (But this is improving from version to version)

[0] https://twitter.com/wycats/status/372107196617592832 [1] https://twitter.com/yukihiro_matz/status/372181477909200896

reply

winter_blue 9 hours ago

link

> The other thing that holds it back IMHO is the compile time.

Now that you mention compile time -- one of the biggest things that the Go designers cared about was compile-time. Go touts it as one of its major pros; and I do agree for personal experience that compile time matters.

You can often cut down compile-time by making "run-time compromises". For instance, with C++ code, dyn-linking rather statically linking everything can speed up things significantly. This is because with massive C++ codebases, when you change a couple of lines, rebuilding the relevant objects only takes a few seconds - but the static linking stage can take forever.

On memory constrained system (4GB) of RAM, I've seen a particular codebase that I've worked with take up to 28 minutes just to link. The same code on a machine with 8 gigs of RAM (just double) took less than 4 minutes to link. Due to the sheer number of objects that need to be linked, your system ends up thrashing (swapping pages out to disk).

That being said, I read somewhere that Go doesn't support incremental compilation. I don't if this is still true, but that's a major problem that needs to be fixed right away.

With interpreted languages, practically everything is done at run-time and you have no compilation stage -- but at a massive performance penalty. Tracing JITs do help though.

reply

upvote

pkinsky 9 hours ago

link

>Another downside of Scala is its HUGE syntax. Processing strings? Here's a ten million ways to do it.. (a bit over-exaggerating). Oh and if you chose this way, then you should use this syntax. No, not that one, THIS one. Oh no, not that one, this variation of that one that looks like this.

On the other hand, Scala lets you deal with collections and Strings using the same enormous set of methods.

    "\"foo\"".drop(1).dropRight(1)

is just

    List('"', 'f', 'o', 'o', '"').drop(1).dropRight(1)

reply

upvote

programminggeek 10 hours ago

link

Go seems to be hitting some kind of tipping point where it's going from being more of a niche thing with a small user base to something with a broader appeal. I don't think that it's because go is changing so much as the kinds of problems people are encountering writing web services that need to scale (or at least have that option).

I've been comparing go to scala lately and what has really got me into go is the development speed. The fast compiles and fast web page auto-reload make it feel every bit as fast to develop in as ruby or python or php, but with type safety, fewer tests, and very clean code.

Scala is a fantastic language, but even with jrebel autoreload you still have 2-3 second page reloads and a 5 second test suite reload. That seems like a small thing, but the faster I see code change results, the more hooked I am to the process. A 5 second wait is probably enough to get me out of the zone.

With go, on just a default simple test of a small thing it is less than a second to compile/run. In revel, pages reload/update as fast/faster than they do in rails/sinatra.

Oh, and with go, each web request will run in a separate goroutine, so you get excellent nonblocking IO performance without dealing with the callback soup of node.js.

It might just be irrational exuberance because I haven't built anything big and messy yet, but so far go is seriously fantastic and solves a lot of real world problems elegantly.

reply

upvote

" Using Java or Groovy from Scala is a breeze. Using Java and Groovy from each other are also a breeze. Using Scala from Java or Groovy pretty much makes me want to drink a pitcher of boiling lava.

I won’t pretend to un­der­stand the design de­ci­sions that went into Scala, but I’m def­i­nitely annoyed at the fact that scala.Lists do not im­ple­ment the java.util.List in­ter­face. It seems to me that Scala could have had the full benefit of using its own lists within the Scala lan­guage while still im­ple­ment­ing that triv­ially-small in­ter­face. Doing so would have made it so much easier to at least pass Scala’s lists to Java or Groovy methods that are ex­pect­ing a java.util.List or a java.util.Collection. I’ve had to import scala.collection.JavaConversions? into more .java and .groovy files than I care to recount.

Of course, this wouldn’t solve the problem of passing Java Lists into Scala, which re­sem­bles this beauty: 1 scala.collection.JavaConversions?.asScalaBuffer(existing).toList()

Using traits, Scala can give you some­thing re­sem­bling mul­ti­ple in­her­i­tance. This is a pow­er­ful ad­di­tion to the toolbox, but it also makes classes sur­pris­ingly dif­fi­cult to use (and, in par­tic­u­lar, mock) in Java or Groovy. As a result, we tend to use this pow­er­ful ability spar­ingly, which is a shame. "

--

--

" If you want to call Scala from Java and have it look nice your Scala can't rely on Scala-specific language features such as implicit conversions, implicit arguments, default arguments, symbolic method names, by-name parameters, etc. Generics should be kept relatively simple as well. If you're Scala objects are relatively simple then there shouldn't be any problem using them from Java. – Erik Engbrecht May 21 '11 at 13:09' "

--

"

Finally, it would be terrible to find something that resembles this infamous line of Scala in Go's standard lib:

implicit def TraversableBind?[M[X] <: Traversable[X]] = new Bind[M] { def bind[A, B](r: M[A], f: A => M[B])(implicit w: CanBuild?[B, M[B]]): M[B] = r.flatMap(f)(breakOut) } "

--

"

There are also some nags I have about the lan­guage design itself. I hate that XML is treated as a first class type with lots of com­piler support, but regular ex­pres­sions are not. In 2012, it’s dif­fi­cult for me to take an ex­pres­sive lan­guage se­ri­ously if I can’t define a regex without first cre­at­ing a String. It also annoys me that there is an an­no­ta­tion that makes the com­piler check for tail re­cur­sion, but not one that pro­vides au­to­matic func­tion mem­o­iza­tion.

Interop between Java and Scala still seems to suck pretty bad, es­pe­cially around Col­lec­tions. You can do some things to make this problem less severe, but it’s still harder than it needs to be, and I’m not con­vinced there’s a good reason.

My biggest com­plaint is with the Scala ecosys­tem. IDE support is tol­er­a­ble but not ex­cel­lent, but more im­por­tantly the build tools are ter­ri­ble. All of this power and all of the things the com­piler does for you causes com­pi­la­tion to be ex­tremely slow. A large Scala project can take ten minutes just to compile.

The only workaround for this seems to be to use SBT and lever­age its built-in in­cre­men­tal com­pi­la­tion, but SBT happens to be ex­tremely dif­fi­cult to un­der­stand and use. Un­for­tu­nately, SBT seems to be the only game in town for Scala; we tried a Gradle build for our large Scala project and con­verted to SBT after spend­ing a great deal of effort and still failing to make the full build in Gradle take fewer than 40 minutes.

Ba­si­cally, you’re using either Maven or Gradle to build your project but it takes forever, or you’re using SBT and it builds quickly, but mod­i­fy­ing your build takes forever instead. My un­der­stand­ing is that some work is going on in the Twitter/Foursquare land to create a new build system that perhaps lever­ages the in­cre­men­tal com­piler, so I’m excited to see what comes out of that.

All in all, I’m very happy using Scala reg­u­larly now, and I often find myself missing it when I’m using another lan­guage. "

--

scala compile time

http://www.artima.com/articles/compile_time.html http://stackoverflow.com/a/3612212/171761

--

" BTW, I've been a big fan of Scala lately, and I don't see myself using much Haskell precisely because its tools for modularity seem limited. In Scala you can use OOP to build abstract modules, with the much hyped Cake pattern being based on that. Dynamic languages are naturally more modular, however I still prefer static languages. "

--

Blogger Alastair Reid said...

    I think Scala has an interesting approach to defining your own control constructs. It lets you declare a function parameter as call by name and it automatically inserts a lambda round the actual parameter and an application round uses of the formal parameter.
    Just one of Scala's tricks to make it easier to implement EDSLs.
    Tuesday, May 3, 2011 at 9:18:00 AM GMT+1

--

2) Syntax:

This is an example from one of my previous commenters (dxbydt, thank you) on my thread:

    scala> def test1 = println ("hello world")
    scala> def test2(f: =>Unit) = println ("hello world")
    scala> def test3(f:Unit) = println ("hello world")
    scala> test1
    hello world
    scala> test2()
    hello world
    scala> test3()
    hello world
    scala> val t = test2 _
    scala> t apply Unit
    hello world
    scala> t()
    hello world
    scala> t(())
    hello world

It is mostly a personal preference, but I still feel too many ways to do one thing is a recipe for disaster.

With all that said, I know of people writing a Scala program and not touching it for a year or two unless they wanted to update their OS on their servers.

upvote

rybosome 36 days ago

link

Nice example. It combines aliases for the Unit type with the sort of hybrid function/value nature of Unit to produce a truly baffling array of options. =)

I'll agree that this set of cases does not reflect well on Scala; at the very least, it supports your point that the syntax is too large. Still, I don't mind it too much. Although the "multiple ways to skin a cat" nature of Scala means you can get very WTF-y code like above, it also means that you can construct a list by writing `1 :: 2 :: 3 :: Nil`, or send an actor a message with the Erlang-inspired `actor ! Message("hello")`.

I don't want to be an apologist for it, though. You're correct that there are some nasty corner cases. Using Scala for serious work is difficult if people don't agree on a consistent style.

--

upvote

auggierose 28 days ago

link

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. :-)

--

http://twitter.github.io/effectivescala/

--

upvote

auggierose 28 days ago

link

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    
  }

upvote

brandonbloom 28 days ago

link

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...


upvote

auggierose 28 days ago

link

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.


upvote

brandonbloom 28 days ago

link

> 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.


upvote

TylerE? 28 days ago

link

I don't suppose I could talk you into re-writing it into idiomatic clojure? Since someone else already rewrote it in idiomatic scala.


upvote

brandonbloom 28 days ago

link

Just guessing from context, but probably something like this:

    (defn completion-items [items options]
      (->> (for [[item v] items]
             (when-let [nonterminal (expected-symbol item options)]
               (when-let [next-value (gen-next-value v options)]
                 [(update-in item [:dot] inc) next-value])))
           (remove nil?)
           (into {})))

upvote

auggierose 28 days ago

link

By the way:

idiomatic == I am doing what I am told to do without understanding why it sometimes makes sense, and sometimes doesn't, and sometimes just doesn't matter.


upvote

mark242 28 days ago

link

Here's a more functional version of complete_items, if you're interested.

  def complete_items(...) = bin.items.flatMap((item, v) => 
    expectedSymbol(item).map(nonterminal => 
      grammar.nextValue(document, item.origin, bin.binindex, completed_binindex, nonterminal, item.ruleindex, item.dot, v, value)
        .map(nextvalue => (item.inc -> nextvalue)
    )
  )

upvote

auggierose 28 days ago

link

What can I say, I like my loops :-)

http://arxiv.org/abs/1007.3023


upvote

mark242 28 days ago

link

Loops obviously have their place, no question, but you're going to find that assigning a List to a var, and then appending to it / re-assigning it is going to generate a ton of garbage, and in general will just be slow all around. There's a reason that prepending/appending to Lists is "strange" in Scala. This is why map and flatMap are so great, because they take care of a lot of that heavy lifting for you (eg the matcher on None/Some -- this is what map is made for!).


upvote

auggierose 28 days ago

link

There is no performance difference here, map etc. are producing the same garbage. Scala isn't Haskell. Also note that there is a HUGE performance difference between appending and prepeding to a list. :-)


upvote

mark242 28 days ago

link

I don't think that's right.

TraversableLike?, and FilterMonadic? will both size up the resulting return value based upon the length of what's passed to it. You'll get a List of N items, and the call to flatMap will also traverse the list to remove/flatten the Options. Items will then get dropped in the List. You're looking at one or two collectable objects every time you run through that method, as opposed to bin.items.length collectable objects in your original code.

Look at it this way-- what happens if bin.items is a List() of 10M objects? completed_items can be replaced up to 10M times. The .flatMap creates one collection of 10M length, removes the None objects, and returns the resulting List.


upvote

bad_user 28 days ago

link

If you need to append, use a Vector instead.


upvote

GyrosOfWar? 28 days ago

link

> Also note that there is a HUGE performance difference between appending and prepeding to a list. :-)

If you're going to do a lot of appending, might I suggest a ListBuffer? or a Vector?


upvote

stuhood 28 days ago

link

If you like loops, here it is with a for-comprehension:

  def complete_items(completed_binindex: Int, bin: ItemBin, nonterminal: Nonterminal, value: Value): MoreItems = {
    for {
      (item, v) <- bin.items
      _ <- expectedSymbol(item)
      nextValue <- grammar.nextValue(document, item.origin, bin.binindex, completed_binindex,
        nonterminal,item.ruleindex, item.dot, v, value)
    } yield {
      item.inc -> nextvalue
    }

--

auggierose 28 days ago

link

The usual argument for Clojure is that it allows for short and succinct code; but actually, Scala code is about 10% shorter: its type system is good enough so that you can do almost anything with it in a similar elegant and short fashion as in Clojure.

Programming in Clojure I miss the following features from Scala most:

a) Pattern matching

b) Having machine-checked documentation (aka type system), traits.

c) A proper documentation generation tool. The Clojure one doesn't do protocols properly, although protocols are the only real way in Clojure to have something akin' to interfaces and Scala traits.


upvote

brandonbloom 28 days ago

link

Not trying to sell you anything, just trying to help you find some things you've been missing:

a) https://github.com/clojure/core.match

b1) https://github.com/clojure/core.typed

b2) I agree that Clojure's facilities for mixins is under-utilized and that it lacks a proper facility for delegation (ie implicit conversions in Scala), but see (doc extend) for how awesome "traits as data" can be. Here's an example: https://github.com/stuartsierra/clojure.walk2/blob/2250e04c7...

c1) I hate generated documentation, but I understand why it's necessary for Scala. When I did some scala programming, I was so pleased with ScalaDoc?, since it really helps you navigate that complex scala.collections hierarchy. Feels like having a pretty decent substitute to a good IDE. In Clojure, I don't feel the need nearly as much... Also, I quite like reflective documentation with the doc macro.

c2) Already covered interfaces/traits in b2


upvote

bdisraeli 28 days ago

link

For a and b you should check our core.match [1] and core.typed [2]. One of the best parts of using lisps is that things that are features of other languages can be implemented as libraries. Not to say Scala probably isn't great too, but I haven't ever really used it.

[1] https://github.com/clojure/core.match

[2] https://github.com/clojure/core.typed


upvote

narwally 27 days ago

link

IIRC Clojure itself is a library.


--

upvote

smrtinsert 28 days ago

link

robust is debatable, I suppose you mean type safe.


upvote

auggierose 28 days ago

link

I mean type safe, therefore much faster code out of the box, easier refactoring (not trivial refactoring, but changing interfaces of libraries and the like), better documentation generator, better build tool, up-to-date tools for google app engine, great Eclipse support, ....

In short: more robust


upvote

benburton 28 days ago

link

You actually mean statically typed. Scala is only limitedly type-safe, and is certainly not type-theoretic type-safe at all:

    $ cat NotTypesafe.scala                                                                    
    object NotTypesafe {
      def main(args: Array[String]) {
        println("5".asInstanceOf[Int])
      }
    }
    $ scalac NotTypesafe.scala
    $ scala NotTypesafe
    java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

http://en.wikipedia.org/wiki/Type_safety

--

upvote

obilgic 28 days ago

link

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


upvote

trailfox 28 days ago

link

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

upvote

Refefer 28 days ago

link

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 ;)

upvote

saosebastiao 28 days ago

link

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 ...".


upvote

asdasf 28 days ago

link

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.


upvote

narwally 27 days ago

link

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!

--

upvote

fnl 28 days ago

link

I had been asking myself the same question over the last few months, maybe even longer. The final selling point for me was lines of code, caused by the feature-richness of Scala. While implementing a few generic data collections and algorithms I need for my project, I realized that in Go this resulted in much more code than in Scala, or I would have had to sacrifice type safety by declaring everything an interface{} (sort of Go's version of a "void pointer" for C guys). I now have solved this by using Go as my favorite "scripting-like" language because it is so easy to bootstrap something there, and it is nice to quickly build efficient binaries and even wrap a C library. But to manage huge code bases and projects, for me the choice in the end became rather obvious. Particularly, with respect to all the magnificent capabilities starting from generics (~ C++ Templates), to higher kinds, the coming macros, etc. that help to create succinct DSLs and the general benefit "FP && OO", over "FP

OO", in the end made this decision obvious to me. And I have not even touched the issue of the gigantic collection of Java libraries and frameworks you automatically get by choosing Scala...

upvote

MrBuddyCasino? 28 days ago

link

Well, if you already use the JVM, its Scala of course.

But ask yourself this: do you work in a team or alone? One of the first sentences is:

"While highly effective, Scala is also a large language, and our experiences have taught us to practice great care in its application."

And thats the biggest issue - Scala is a bit like the JVMs C++, you need capable programmers in order to not fuck it up, because it contains every paradigm ever invented.

Go on the other hand is much simpler, and I like it for that - there is great value in simplicity.


upvote

bad_user 28 days ago

link

I've been working with Scala for the last 2 years, and I also worked with C++. People claiming that Scala resembles in any way with C++ haven't worked with neither of them.

Also, when speaking of simplicity, I like languages with conceptual elegance. Scheme is simple too and that's a rather interesting example. You see, Scheme is homoiconic and has macros and continuations, a combination so powerful that you can easily build on top and efficiently use any pattern or paradigm under the sun. Also, being a Lisp, most builtins can be reimplemented in Scheme.

Now that's simple. What you're describing is actually easyness which is a very different notion. The main difference is that easiness is relative and depends on someone's own biases or limitations. The problem of course is that easy can overnight turn into hard.

Ever tried doing FP in Go? Ever thought about implementing your own data-structures? Try it.


upvote

yohanatan 27 days ago

link

"Haven't worked with neither" is a double negative. Also, 'resembles with' is redundant--'resembles' is sufficient.

I have written both Scala and C++ at my day jobs and I would say that Scala certainly does generally remind me of C++ and specifically in its proliferation of language features. I also know of several others with similar experience and opinion on this matter.


upvote

ericssmith 27 days ago

link

I've worked with C++ going back to the mid 90s, and program Scala full-time in addition to managing a team of programmers. Such a comparison has never occurred to me. Scala is arguably a simple language in its core design. It enables quite feature-rich libraries, and you could argue those make the language seem complex in practice. But to me, it just shows the language is powerful.


upvote

pivo 27 days ago

link

I really do like Scala, however I also find it to be similar to C++ in the sense that lots of the Scala code I've read seems to be written by people who trade simplicity of implementation for being able to use every single feature of the language all at once. In other words, people unable to resist the urge to be too clever.

Sometimes the result is Scala source files that almost appear to be written in different languages, or lots of little libraries each with their own wacky DSLs that require a major investment of time to comprehend just to accomplish something that should be trivial.

These sorts of abuses you really don't see in Clojure even though it's just as possible in that language. Of course this is all based just on my experience, YMMV.


upvote

ericssmith 27 days ago

link

I think DSLs, heavy use of operators, and Unicode characters as identifiers isn't abuse. It's unfamiliar. In Haskell, for instance, syntax is taken much more seriously than in other languages, which tend to just copy previous languages in the name of familiarity. And it takes a while to become use to the basic syntax of Haskell, let alone the various libraries that extend on its ideas. But the syntax choices are not arbitrary.

But even Clojure is syntactically heavy compared to Racket or CL. But with good reason.

A powerful and expressive language takes effort, possibly even years, to become expert in. I'm not sure that making trivial things trivial is part of the plan. There are more appropriate languages for that.


upvote

narwally 27 days ago

link

I really appreciate Clojure's syntactic heaviness when compared to other LISPs. Just by using braces for associative data structures, and brackets for array's makes scanning through Clojure code much nicer because of the added visual cues.


upvote

yohanatan 26 days ago

link

You don't need proliferation of features to achieve expressiveness though (see Scheme or lambda calculus).

Most of the cruft in Scala is due to its support of O-O and its attempt to modernize it. Similarly, C++ is a superset of C rather than a complete break from it (and often, in the field, you find people using it as if it were 'C with classes').

Also, the O-O side of Scheme is certainly more powerful than F#'s O-O side; however, overall F# is at least as powerful of a language (and yet it's also much cleaner/internally consistent).

[Also, it takes only one counter-example to disprove 'all those who say that Scala resembles C++ have never worked with either' (which was my original intent here)].


upvote

ericssmith 27 days ago

link

"you need capable programmers in order to not fuck it up, because it contains every paradigm ever invented."

My team has just the opposite experience. Scala offers a lot of structure and discipline that you can take advantage of without being an expert, and it is a short time to ramp up to idiomatic usage relative to other languages. In fact, this is one of its benefits. By following some fairly simple guidelines, you can avoid making a mess. This has not been my observation with imperative programmers picking up a new imperative language.

Because of the easy-to-achieve discipline, Scala is ideal for teams in my opinion.

--

upvote

candybar 28 days ago

link

For people with zero knowledge of either, I think the following analogy is somewhat (but obviously not completely) apt:

Scala is to Ruby what Go is to Python.


upvote

SkyMarshal? 28 days ago

link

Interesting, but might want to elaborate a bit more. It's not completely clear what you mean. For example, another that comes to mind regarding prototyping vs production:

Python:C++::Go:Scala


upvote

candybar 28 days ago

link

Ruby and Scala are both feature-rich languages that give programmers every chance to abstract away any common logic that they can find anywhere, while remaining elegant at core. Python and Go are both minimalistic languages that provide basic abstraction facilities, but are designed to keep the programming language and source code simple and readable, even it comes at the expense of expressive power. Scala differentiates from Ruby with static typing, faster performance and better support for concurrency. Go differentiates from Python with static typing, faster performance and better support for concurrency.


--

Scala inner classes enclosing class, outer object, #

--

Scala nullary methods can be postfix (did they mean prefix? )

--

Scala

Overrides keyword

--

scala tour comprehensions example is verbose because comprehensions are verbose, pair constructor is verbose, no repr. Why Jasper additions.

--

scala unapply does pattern matching with inverses

--

http://overwatering.org/blog/2013/12/scala-1-star-would-not-program-again/ :

" Scala — 1★ Would Not Program Again gga

  1. 2013-12-01
    With Scala you feel smart having just got something to work in a beautiful way but when you look around the room to tell your clojure colleague how clever you are, you notice he left 3 hours ago and there is a post-it saying use a Map. Daniel Worthington-Bodart
    I consider it an “inhumane” language. That is, one that I’m surprised humans created and intended for other humans. Clinton Begin

I first encountered Scala about six years ago when I was forced to use an in-house build system written in Scala, that also used Scala as the language for build scripts. ... Our build scripts took three minutes to compile when changed — before actually starting the build.

    The syntax for the build scripts was really opaque. Sometimes it was def, sometimes it was a val. Sometimes there was a =, sometimes braces. On the whole, it looked like someone had wandered through my build script dropping random pieces of punctuation.

... In the last two weeks I’ve been building a simple RESTful API for a complex data set using Scala. I don’t ever want to touch Scala again. ...

Compile Times

...It is essentially impossible to practice TDD in Scala simply due to the time it takes to compile. Though we were using Gradle in daemon mode, test runs on a tiny code base could still take a minute 20 seconds. ....

Libraries and the Community

...the npm team decide that they’ve had enough and actually build the best dependency management system we’ve got so far. Sure, they’ve learnt from Bundler, who learnt from Ivy, but that’s how progress happens. ... The Scala community, however, is operating at peak CADT (note: CADT is the phenomenon where you just close bug reports because you're releasing a new version). Documentation is terrible or non-existent. Libraries move from milestone to release candidate to snapshot to milestone to replacement.

Partially, this is understandable. Someone has decided that Scala’s flexible syntax and method invocation syntax mean it’s a great language for creating DSLs. Every library has selected it’s own set of operators and composition philosophy. This leads to ridiculous decisions such as using ~ to glue handlers together in the flexible DSL offered by spray — chosen because it’s a visually lightweight character. Or the attempt at a Gherkin syntax that you can see in specs2. ... But mostly, I wish the language community would start to rate stability as a valid goal.

Magic Syntax

Over the years I’ve found that the easiest programming languages to get started with are those with the ‘simplest’ syntax. Simplicity is a hard thing to define, but in this case it is not the same as flexible. It’s actually closer to regular, or limited with extension options. I’ve found Lisp, Ruby and HyperTalk? to be great examples. I’ve found AppleScript? and Perl to be terrible.

Scala is easily the worst I’ve seen. That punctuation-strewn build system I was forced to use was just taking advantage of Scala’s ridiculously flexible syntax. The goal appears to be to allow concise expression of your program: arbitrary operators, infix method calls, flexible anonymous function definition, and something weird with attaching anonymous functions to method calls.

The problem is that when you’re staring at a chunk of Scala code, you’re only seeing about 60% of the code.

...

Everything is a Type

Scala programmers really like types. This has lead to some surprising decisions. The oddest we encountered was the plethora of types blossoming around the HTTP request/response cycle. Instead of two simple maps with keys for status, headers and body there were types. Types galore! There was a request context, a request, a response, a large number of directives and even types for every ‘known’ HTTP header. ....

‘Local’ Type Inference

...In my mind, Hindley-Milner was always the promise and the pay-off for Scala. And now I’ve discovered it’s not really there. I know this is the fault of the JVM’s use of type erasure.

... And while I’m on the topic, thanks for making me care about the difference between long and int, again.

...

Other Issues

There are other things I could talk about. The confused array of build tools. The hopeless confusion of even the most powerful of IDEs. The enormous array of types of types. The horrible repetition required by case classes. ... "

---

NickPollard? 1 day ago

link

I started learning Scala almost a year ago at my latest job - we use it for production systems at a large multinational investment bank.

Coming to Scala from experience including C, Java and Haskell, I intially found Scala quite difficult. It is true that there are some things in Scala that are not obvious to newcomers, and that are difficult to discover for yourself - such as the use of Implicits, and the strange precedence and binding rules for operator syntax.

That said, it doesn't take long to learn, and once you do, it all makes sense. There are other great languages out there (I'd say Haskell is one), but compared to for example Java, or one of the dynamically typed languages, Scala is superb.

Types, whilst not having the full H-M inference, are brilliant. That the author complains about having types rather than a simple map for keys shows a misunderstanding of what they are there for - the idea is to allow the compiler to prove at run-time what is valid code and what isn't. He comments that tests run too slowly in Scala (they don't - for our production systems building in SBT, a typical test run is significantly less than 10 seconds) but a lot of the time I don't even need to go that far - my IDE already highlights errors in the code as I type, where I have passed in incorrect or insufficient data.

Also, the author makes a strange comment that H-M 'enabled' Monads, and the comment is written in a way that implies that Scala does not have Monads. This is incorrect. Scala has monads, and the Scalaz library has huge support for Monadic programming. We use Monads and Applicative Functors (a close relative) daily to build high level abstractions, and we couldn't live without them. In Scala we say flatMap rather than bind (or >>=), but we mean the same thing. Although thanks to the same flexible method naming that the author complains about, you can in fact say >>= if you wish.

---

Scala is on my "will not work with" list of languages/technologies -- which is generally limited to old languages/tools that I have experience with (like Progress 4GL, Mumps, etc), but don't want to touch. It is a maintainability blackhole and generally horrible (to me) to work with, despite being fairly comfortable with the core (1400 or so hours billed).

reply

rdtsc 1 day ago

link

> Scala is on my "will not work with" list of languages/technologies

Just curious, what are the some languages/platforms you like or enjoy using? (Mine are Python, Erlang and Go for ex).

reply

MetaCosm? 1 day ago

link

Hobby wise: Haskell, Rust, Nimrod, Haxe

Shipping code: Go, Erlang, C++11 (avoiding legacy), F# (with Xamarin)

I program in many more, but those are probably my top 8 right now.

reply

tinco 1 day ago

link

You never work with scripting languages? (i.e., why is there no Python, Ruby or Javascript in your lists? or maybe I do'nt know Haxe, does that replace them?)

reply

MetaCosm? 1 day ago

link

Most of the stuff I work on is highly concurrent. GILs are the devil. Almost all the joy and ease you from GIL languages is lost as you try to go concurrent and have to use (in python for example) multiprocess and gevent ... then you start getting caught on the rough edges and poor ideas in those tools... and everything falls apart.

reply

---

k__ 1 day ago

link

When I read about Scala the first time I felt it was awesome! I bought some books and tried to get into it.

But when I read production code it was aweful because of all the DSLs.

Scala does much to reduce code to whats necessary, like python, but there is so much more that it does, which confuses the code readability later :\

The DSLs also lead to bad API design.

The devs are always like "uhuuu if you don't like the DSL just use the normal functions" and write the horrible DSL stuff without the DSL.

(asd ~! fdd %%% sdasd) gets to asd.doSomethingRatherComplicated( with( fdd ) ).alsoGetSomeStrange( sdasd.compile() )

It looks like they are using the ability to build "easy" DSLs as excuse for bad API-design.

reply

mcv 4 hours ago

link

When I finally picked up a book on Scala, I rejoiced when I read the chapter on parallelization with Actors and especially how they passed case classes around and automatically extracted data from them in their built-in switch statements. That stuff was fantastic!, concise, expressive and beautiful! Hallelujah!

The next chapter delved deeper into the typing system, and I recoiled in horror.

I still want to do Scala some day just to use their actor messaging, but there really is a very strict limit to how far a sane person can look into Scala. At some point, the Abyss looks into you, and if you're not careful, you'll also start building crazy DSLs with incomprehensible operators based on Type Declarations Man Was Not Meant To Know, just to maintain rigid type safety in some situation nobody really cares about.

reply

--

kazagistar 1 day ago

link

Languages like Ruby and Python allow for expressive, high-level customization, metaprogramming, and DSL creation. However, especially in the latter, the potential chaos is curbed by a strong culture and encouragement of self restraint, readability, and simplicity. From the sound of it, this is not so true for Scala.

reply

bad_user 1 day ago

link

I'm really curious of what "sound" you're talking about.

I've been working with Scala full-time for the past 2 years. Prior to that I worked with Perl, Python and Ruby and I still work with these languages for quick scripting or if the codebase demands it.

Scala code-bases tend to be based to a higher degree on good engineering practices. Scala itself is a much more static language than a language like Java, hence it gives you plenty of compile-time safety, with its static type system being one that helps you, instead of staying in your way. Even a tricky feature (now market as experimental SIP-18 and so they have to be explicitly enabled), like implicit conversions, is far more safer than the monkey patching that goes on in Ruby/Python, as it's lexically scoped, doesn't modify anything and the compiler throws errors if there are conflicts.

reply

--

lmm 1 day ago

link

Scala is pulling out of that phase. Scalaz 7 removes a lot of the less-readable operators (e.g. you now have to write "Kleisli" rather than "☆"). The Requests HTTP library, long mocked for its periodic table of operators, has fallen out of favour (I'm not sure it's even maintained any more).

I can't speak for SBT because I don't use it, but Spray is probably the nicest library for defining HTTP APIs I've ever used, in any language. As for type inference, yes it's imperfect, and maybe disappointing for someone used to Haskell, but coming from Python I found the set of type annotations I needed to add to make my Scala compile was a subset of the ones I wanted to document anyway.

reply

runn1ng 1 day ago

link

Wait.

Scala has unicode operators?

Wow.

reply

lmm 1 day ago

link

Scala doesn't make a distinction between operators and methods, and Java has always supported unicode in method names, so they have to be possible for compatibility if nothing else. I think if used carefully, with discipline, they can make code more readable and ultimately more maintainable - e.g. for doing set algebra it's nice to be able to have ∪ and ∩ methods. But yes, if you want to shoot yourself in the foot with them it's very easy.

reply

joeygibson 1 day ago

link

I showed an example of using Unicode operators in a presentation I gave to the Atlanta group back in 2010. It doesn't say it in the slide, but when I gave the talk, I explained that while it sounds like a neat idea, you should probably avoid doing this. You can see the slide here, where I used a Delta as an operator slideshare.net/slideshow/embed_code/2923973?startSlide=9

reply

draegtun 1 day ago

link

Perl6 also has unicode operators - https://news.ycombinator.com/item?id=4942377

reply

--

gfodor 1 day ago

link

Several years ago I picked up Odersky's book. I got a few hundred pages in, considered the types of problems I had encountered in my career so far, and decided life is too short to be spending my time learning some hyper-complex programming language that seemed, like C++, to seem unable to say "no" to introducing complexity where it would provide minimal upside in Getting Shit Done.

Instead, I learned Clojure. I use Ruby, the epitome of comfortable languages, for most things, and when the hard problems come up, I use clojure. My next major scientific computing problem, rare as they are, will be in Julia instead of Matlab for prototyping and java for production. Scala seems to be the hard language for easy problems. No thanks.

reply

voyou 1 day ago

link

Scala reminds me of C++ too, but it's impressive that, in a mere 10 years, Scala has achieved all the multi-paradigm incoherence it took C++ 30 years and tortuous backwards compatibility constraints to attain.

Actually, I spent some time over the weekend trying to get familiar with Scala by using it to solve some Project Euler problems, and it was pretty entertaining. Still, the language's bias towards there being more than one way to do anything does worry me; it does seem that the kind of mutually incomprehensible code bases the OP talks about are likely. I would assume that, like C++, you need a strong style guide for a Scala project laying down which parts of the language you are going to use. Does anyone have any recommendations for guides on writing comprehensible, maintainable Scala?

reply

pkolaczk 1 day ago

link

Multi-paradigm incoherence? There is a huge difference between throwing multiple features/paradigms into one language (as C++ does) and integrating them so that they are orthogonal and don't get into your way (as Scala does). The integration part is the hardest thing and Scala designers did the great job there, assuming the constraints that were given.

Scala does have some rough edges but they are not the kind of C++ ones, and even the complexity of the most powerful features (implicits) is very controllable.

Seriously - which features would you like to remove from Scala? I'm really curious because I don't find any redundant ones. All are pretty complementary and very useful.

reply

kasey_junk 1 day ago

link

I'm not sure I'd remove any, but there is a huge incoherence in what is and is not "idiomatic" scala.

The most obvious example that comes to mind is whether you should use mix in traits or type classes for api design. Another one is the "magic-ness" of map/flatmap/filter for for comprehensions but no way to extend that for Functor/Monad/Monoid type classes.

Finally, the Scala community is a huge advocate of Algebraic Data Types yet don't support Disjoint types making any sufficiently complex system cumbersome to model as an ADT.

reply

gclaramunt 1 day ago

link

http://docs.scala-lang.org/style/

reply

voyou 1 day ago

link

Thanks, that's really useful. It answers a lot of the irritating little questions that Scala's flexible syntax gives you, like whether or not to use dots for method invocation. I see that Twitter has a document on the best ways to write Scala, which looks interesting: http://twitter.github.io/effectivescala/

reply

kvtrew76557 1 day ago

link

Unlike you I finished reading the Odersky book and am very easily "Getting Shit Done" much faster than I ever did in Ruby. It did take effort to learn the language, but it was worth it. Having apps running an order of magnitude faster with better response times is just icing on the cake. Perhaps consider getting a gentler introduction to the language, the Odersky book is rather long and goes into excessive detail about obscure corners of the language you will seldom ever see in a production system.

reply

gfodor 1 day ago

link

I've been in enough code reviews of Scala that did simple things like string processing that inevitably got sidetracked into a navel gazing discussion about type theory, pattern matching, and functional programming to not go near the language again anytime soon. You simply couldn't understand the code without understanding tons of incidental complexity about the language.

The Clojure community has its navel gazing of course, but every time I've been exposed to some crazy idea in that community it was always through the lens of providing real leverage for real problems. Most of the time when I've dealt with people trying to explain concepts to me for Scala code, I've walked away wondering what the point of it all was (beyond the fun Computer Science.)

reply

pkolaczk 1 day ago

link

Maybe you should first learn the language? It would save your time, really. You must know the language to understand programs in that language. Simple as that.

If you don't want to learn FP or you don't value type-safety, Scala is simply not for you.

reply

geoka9 23 hours ago

link

> Maybe you should first learn the language?

Is it actually possible? I've been using Scala for over a year and still have to spend more time learning about the language than writing code in it.

reply

-- " If you don't like Scala, thanks for sharing, but I don't see how it affects me, I will still continue using it as my go to language until I find something better (there are contenders, Kotlin, Ceylon, Dart, TypeScript?, and my favorite now - Nimrod, but there is still a big gap for me to fully switch)

So for someone like me who wants a statically typed language (there goes Ruby, Python JavaScript?, Clojure), who thinks Haskell is too academic to be really productive (I have to think too much to get things done with it) and who don't get what is all the rage about Go (perhaps because I'm not a system programmer, in any case I still don't get it, sorry) This leaves me with no other options (except C#, which I would probably use if it was really portable) "

--

Ygg2 1 day ago

link

What is my biggest gripe theoretical gripe about Scala is that Trait order is important! Because traits can override common function. A class that is e.g. Ball with traits Shiny and Red is NOT the same as e.g. Ball with traits Red and Shiny. Why? Why complicate testing to a point where you need not only test traits for correct behavior, and not just composing of Traits, but even the order in which they are composed? Why?! Why complicate it so much?

Note: It's been a while since I've seen traits, this might have changed for better.

To me Scala is essentially if Java, Haskell and C++ went to a wizard to have a child. The result is a magical mess. I seriously think that Scala has at least twice as many concepts as C++ and same if not greater number of really weird edge cases. I don't want to keep Scala in my mind, no more than I want to keep Necromicon.

reply

pkolaczk 1 day ago

link

As long as your traits are independent, the order does not matter. Anyway, how do you imagine this could be done better? For order to not matter, the linearization could not be possible and we'd end up with something much more complex and ugly like multiple inheritance in C++ with all the diamond inheritance problems, etc.

reply

epsylon 1 day ago

link

Actually, there's a very elegant solution to the diamond problem. Eiffel does this with a renaming mechanism. Martin Odersky certainly knew about Eiffel's solution when he designed Scala, but my guess is that, he chose the simpler solution of traits, just like most languages, because general multiple inheritance just isn't too useful.

Still, it's a shame that most people interested in programming languages have never heard about Eiffel, or ever read the superb book "Object-Oriented Software Construction" by Eiffel's creator, Bertrand Meyer. Eiffel has many flaws (the most proeminent being the complete lack of support for functional idioms), but it has very good ideas as well. (Perhaps the most popular influence Eiffel had on other languages is Design by Contract and the uniform access principle, which you see in most "modern" languages.)

reply

Ygg2 1 day ago

link

Don't have an answer right this minute, but I think eschewing/forbidding variables in trait would prevent the most obvious such collisions.

If you can't override variables, you can't silently change the structure to depend on trait order. You'd have to explicitly state order.

PS. Of course if you have several same signature methods that call super, which is generated depending on order, same problem persist. So, forbidding variables and calling super elements should deal with most "magical" interactions.

reply

pkolaczk 1 day ago

link

If you can't call super nor use variables then this takes quite a lot of power from traits. IMHO being able to stack many traits one on another is a nice pattern.

reply

Ygg2 1 day ago

link

Yeah, you trade power for easier testing and unforseen side-effects for determinism. IMO it's worth it.

reply

---

Ygg2 1 day ago

link

Yeah, you trade power for easier testing and unforseen side-effects for determinism. IMO it's worth it.

reply

JulianMorrison? 1 day ago

link

Problem: author is pining for Go, and doesn't know it.

Solution: author should abandon the JVM ecosystem and use Go.

reply

danieldk 1 day ago

link

If you hadn't mentioned Go, you could have described Java with these bullet points (with the exception of the last). Why throw away all the proven libraries, extremely good garbage collector, IDEs, intrumentation? Java is a perfectly fine language and if you think it is too verbose, there are good other options such as Kotlin, Groovy (which offers static typing nowadays), Ceylon etc.

reply

vorg 23 hours ago

link

> Groovy (which offers static typing nowadays

Groovy's static typing is quite recent, written by one person only, and not actually used in many codebases. Neither Grails nor Gradle uses it.

There's only really 2 or 3 use cases for Groovy:

If you want static typing on the JVM, best use a language designed from the ground up to be staticly typed, e.g. Java, Scala, Kotlin, Ceylon.

reply

---

[–]edwardkmett 63 points 1 month ago*

Off the top of my head:

    If you take any two of the random extensions that have been thrown into scala and try to use them together, they typically don't play nice. e.g. Implicits and subtyping don't play nice together.
    Type inference works right up until you write anything that needs it. If you go to write any sort of tricky recursive function, you know, where inference would be useful, then it stops working.
    Due to type erasure, its easy to refine a type in a case expression / pattern match to get something that is a lie.
    Free theorems aren't.
    Since you can pass any dictionary anywhere to any implicit you can't rely on the canonicity of anything. If you make a Map or Set using an ordering, you can't be sure you'll get the same ordering back when you come to do a lookup later. This means you can't safely do hedge unions/merges in their containers. It also means that much of scalaz is lying to itself and hoping you'll pass back the same dictionary every time.
    The container types they do have have weird ad hoc overloadings. e.g. Map is treated as an iterable container of pairs, but this means you can't write code that is parametric in the Traversable container type that can do anything sensible. It is one of those solutions that seems like it might be a nice idea unless you've had experience programming with more principled classes like Foldable/Traversable.
    You wind up with code that looks like myMap.map(...).toMap all over the place due to CanBuildFrom inference woes.
    Monads have to pay for an extra map at the end of any comprehension, because of the way the for { } sugar works.
    You have type lambdas. Yay, right? But now you can't just talk about Functor (StateT s IO). Its Functor[({type F[X] = StateT[S,IO,X]})#F], and you have to hand plumb it to something like return, because it basically can't infer any of that, once you start dealing with transformers ever. The instance isn't directly in scope. 12.pure[({type F[X] = StateT[S,IO,X]})#F] isn't terribly concise. It can't figure out it should use the inference rule to define the implicit for StateT[S,M,_] from the one for M[_] because of the increased flexibility that nobody uses.
    In this mindset and in the same vein as the CanBuildFrom issue, things like Either don't have the biased flatMap you'd expect, somehow encouraging you to use other tools, just in case you wanted to bind on the Left. So you don't write generic monadic code over the Either monad, but rather are constantly chaining foo.right.flatMap(... .right.flatMap(....)) ensuring you can't use the sugar without turning to something like scalaz to fill it in. Basically almost the entire original motivation for all the type lambda craziness came down to being able to write classes like Functor have have several instances for different arguments, but because they are so hard to use nobody does it, making the feature hardly pay its way, as it makes things like unification, and path dependent type checking harder and sometimes impossible, but the language specification requires them to do it!
    You don't have any notion of a kind system and can only talk about fully saturated types, monad transformers are hell to write. It is easier for me to use the fact that every Comonad gives rise to a monad transformer to intuitively describe how to manually plumb a semimonoidal Comonad through my parser to carry extra state than to work with a monad transformer!
    I've been able to get the compiler to build classes that it thinks are fully instantiated, but which still have abstract methods in them.
    Tail-call optimization is only performed for self-tail calls, where you do not do polymorphic recursion.
    Monads are toys due to the aforementioned restriction. (>>=) is called flatMap. Any chain of monadic binds is going to be a series of non-self tailcalls. A function calls flatMap which calls a function, which calls flatMap... This means that non-trivial operations in even the identity monad, like using a Haskell style traverse for a monad over an arbitrary container blows the stack after a few thousand entries.
    We can fix this, and have in scalaz by adapting apfelmus' operational monad to get a trampoline that moves us off the stack to the heap, hiding the problem, but at a 50x slowdown, as the JIT no longer knows how to help.
    We can also fix it by passing imperative state around, and maybe getting scala to pass the state for me using implicits and hoping I don't accidentally use a lazy val. Guess which one is the only viable solution I know at scale? The code winds up less than 1/2 the size and 3x faster than the identity monad version. If scala was the only language I had to think in, I'd think functional programming was a bad idea that didn't scale, too.
    for yield sugar is a very simple expansion, but that means it has all sorts of rules about what you can't define locally inside of it, e.g. you can't stop and def a function, lazy val, etc. without nesting another for yield block.
    You wind up with issues like SI-3295 where out of a desire to not "confuse the computation model", it was decided that it was better to you know, just crash when someone folded a reasonably large list than fix the issue.. until it finally affected scalac itself. I've been told this has been relatively recently fixed.
    No first-class universal quantification means that quantifier tricks like ST s, or automatic differentiation without infinitesimal confusion are basically impossible.
    def test = diff(new FF[Id,Id,Double] { 
       def apply[S[_]](x: AD[S, Double])(implicit mode: Mode[S, Double]): AD[S, Double]
          = cos(x) 
    })
    is a poor substitute for
    test = diff cos

... but it runs on the JVM.

-- http://www.reddit.com/r/haskell/comments/1pjjy5/odersky_the_trouble_with_types_strange_loop_2013/cd3bgcu

--

http://www.infoq.com/presentations/data-types-issues

--

http://www.infoq.com/presentations/data-types-issues

slide 27

Abstractions

Two fundamental forms – Parameters (positional, functional) – Abstract Members (name-based, modular)

Types in Scala

Functional:

scala.collection.BitSet? Named Type Channel with Logged Compound Type Channel { def close(): Unit } Refined Type

Modular: List[String] Parameterized List[T] forSome { type T } Existential Type List Higher-Kinded

Orthogonal Design

crossproduct of modular and functional, where:

Modular:

Named T { ... } T with U

Functional:

T[U] T[_] Exists T

Dot and Dotty DOT: Calculus for Dependent Object Types Dotty: A Scala-Like Language with DOT as its core

paper: "dependent object types" http://www.cs.uwm.edu/~boyland/fool2012/papers/fool2012_submission_3.pdf " Abstract We propose a new type-theoretic foundation of Scala and languages like it: the Dependent Object Types (DOT) calculus. DOT models Scala’s path-dependent types, abstract type members and its mix- ture of nominal and structural typing through the use of refinement types. The core formalism makes no attempt to model inheritance and mixin composition. DOT normalizes Scala’s type system by unifying the constructs for type members and by providing clas- sical intersection and union types which simplify greatest lower bound and least upper bound computations. In this paper, we present the DOT calculus, both formally and informally. We also discuss our work-in-progress to prove type- safety of the calculus "

Types in Dotty scala.collection.BitSet? Channel & Logged Named Type Intersection Type Channel { def close(): Unit } Refined Type ( List[String] Parameterized )

removed: List[T] forSome { tpe T } Existential Type List Higher-Kinded

Modelling Generics class Set[T] { ... }  class Set { type $T }  Set { type $T = String } Set[String] class List[+T] { ... }  class List { type $T }List[String]  List { type $T <: String } Parameters  Abstract members Arguments  Refinements

Making Parameters Public class Set[type Elem] {...} class Set { type Elem ...} Set[String] Set { type Elem = String } class List[type +Elem] {...} class List { type Elem ...}List[String] List { type Elem <: String } Analogous to “val” parameters: class C(val fld: Int) class C { val fld: Int }

Expressing Existentials What is the type of Lists with arbitrary element type? Previously: List[_] List[T] forSome { type T } Now: List (Types can have abstract members)

Expressing Higher-Kinded • What is the type of List constructors? • Previously: List • Now: List • Can always instantiate later: type X = List X { type T = String } X[String]

In a Nutshell In this system, Existential = Higher-kinded In fact, both are just types with abstract members. We do not distinguish between types and type constructors.

Native Meets and Joins • The horrible type error message came from a computed join of two types. • Problem: In Scala, the least upper bound of two types can be infinitely large. • Adding native & and

types fixes that.

DOT expr.member Type = path.TypeName?

Def = val x: Type = Expr >:
Type { Defs }
...
def f(y: Type): Type = Expr
type T <: Type

extends

Subtyping Fundamental relation: T1 <: T2 T1 is a subtype of T2. Comes in many guises: Implementation matches Interface Type class extension Signature ascription

---

http://www.scala-lang.org/old/node/8610

---

jamii 1 day ago

link

I think that's the real strength of clojure - not the language itself but that the community around it is focused on radically reducing complexity.

Every project I have ever worked on that struggled or failed did so because the complexity outgrew the developers ability to manage it. It kind of scares me that scala is growing so quickly - from my experience working on a large scala project it seems to breed complexity like nothing else I've ever worked with (haskell, python, ocaml, erlang, clojure).

reply

---

my friend p.r. chose scala b/c it's static, jvm, and functional

---

http://docs.scala-lang.org/overviews/macros/overview.html

---

http://lambda-the-ultimate.org/node/5034

---

Zélus : A Synchronous Language with ODEs

Zélus : A Synchronous Language with ODEs Timothy Bourke, Marc Pouzet 2013

    Zélus is a new programming language for modeling systems that mix discrete logical time and continuous time behaviors. From a user's perspective, its main originality is to extend an existing Lustre-like synchronous language with Ordinary Differential Equations (ODEs). The extension is conservative: any synchronous program expressed as data-flow equations and hierarchical automata can be composed arbitrarily with ODEs in the same source code.
    A dedicated type system and causality analysis ensure that all discrete changes are aligned with zero-crossing events so that no side effects or discontinuities occur during integration. Programs are statically scheduled and translated into sequential code that, by construction, runs in bounded time and space. Compilation is effected by source-to-source translation into a small synchronous subset which is processed by a standard synchronous compiler architecture. The resultant code is paired with an off-the-shelf numeric solver.
    We show that it is possible to build a modeler for explicit hybrid systems à la Simulink/Stateflow on top of an existing synchronous language, using it both as a semantic basis and as a target for code generation.

Synchronous programming languages (à la Lucid Synchrone) are language designs for reactive systems with discrete time. Zélus extends them gracefully to hybrid discrete/continuous systems, to interact with the physical world, or simulate it -- while preserving their strong semantic qualities.

The paper is short (6 pages) and centered around examples rather than the theory -- I enjoyed it. Not being familiar with the domain, I was unsure what the "zero-crossings" mentioned in the introductions are, but there is a good explanation further down in the paper:

    The standard way to detect events in a numeric solver is via zero-crossings where a solver monitors expressions for changes in sign and then, if they are detected, searches for a more precise instant of crossing.

The Zélus website has a 'publications' page with more advanced material, and an 'examples' page with case studies. By gasche at 2014-11-22 18:31

General login or register to post comments other blogs 249 reads

---

i've heard that: akka is baked into scala deeply but debugging it is too hard

---