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?