Live data from Hacker News

Why we love Scala at Coursera

tech.coursera.org

151–160 of 184 posts

Re: Why we love Scala at Coursera

#151
post #79

Earlier quoted context omitted.

"Combining for-comprehensions with composable futures makes asynchronous concurrency look like straightforward synchronous code." I would really enjoy seeing this in Java.

I'd like to see the Scala code too. I've played with both and in the end, both codes are pretty complex, just complex in different ways. It's a complex problem with a lot of edge cases and tricky error cases that need to be handled properly, which is where the elegance of the language or the programming paradigm usually goes down the drain. I'd like to see a fully functional snippet of code that gracefully handles er…

OK. Something like:

  val fNotifications: Future[List[Notification]] = // get notifications from the database
  val fPosts: Future[List[Post]] = // get posts from a different database
  
  // If getting notifications fail, log the error and pretend there are no notifications
  val safeNotifications = fNotifications rescue { t: Throwable => log.error(t); Future(Nil) }

  // If getting posts fails, log the error and try retrieving stale posts from the cached post server
  val safePosts = fPosts rescue { t: Throwable => 
    log.error(t)
    // If the cached post server fails too, just pretend there are no posts
    cachedPostsDatabase.getForCurrentUser rescue { t: Throwable => log.error(t); Future(Nil) }
  }

  val facebookPage: Future[Page] = for {
    notifications: List[Notification] 
is a thumbnail sketch of how you'd implement the facebook timeline in Scala if you were doing so. There are even better abstractions that I've started using (functional reactive programming specifically) but none of them come with the standard library, so I thought that was a bit unfair.

Re: Why we love Scala at Coursera

#152

My favorite quote from the article: "Python probably takes the cake for being regular. PHP gets cake in the face… Scala is somewhere in-between."

If you have complete control over your programmatic infrastructure and you are getting PHP 'cake in the face' you shouldn't blame PHP. You're just a shitty programmer.

Yeah, for example: PHP's accidental broken support for octal numbers is definitely the fault of all the people who use PHP, not a problem with the language.

Re: Why we love Scala at Coursera

#153

Earlier quoted context omitted.

An example I use a lot because it is terse: From MapLike.scala def apply(key: A): B = get(key) match { case None => default(key) case Some(value) => value } From HashMap.scala def get(key: A): Option[B] = { val e = findEntry(key) if (e eq null) None else Some(e.value) } That is to say that the default behaviour of a Scala hash map is to create a new object for every access (notice I say access, not for every insert)…

Doing an extra object allocation (which will likely be elided by escape analysis in the JVM) is hardly "weird and terrifying behaviour". It is an implementation detail which has absolutely no bearing on the behaviour or functionality of the map.

In my use cases escape analysis does not elide these accesses out (and I was unable to reason about why not). Further, I had an immutable map that had ~hundreds of items in it that was generating hundreds of millions of objects. I found that weird and terrifying especially given that I was specifically asking it not to give me Options back.

I frequently hear that memory/performance are "implementation" details and don't have bearing on functionality. For my use cases that isn't true.

Even if it was, the surprising upside down nature of that API (de reference the option, instead of wrap the reference) is of itself weird.

This is just the most terse example of oddities in the library I've encountered. Other's include streams being created (and not GC'd) when they weren't necessary, collections losing performance characteristics due to the monadic calls (IndexedSeq's passed into functions as Seq's use LinkedLists for builders instead of Vectors), etc.

Finally, I fundamentally disagree with the idea that eager evaluation should be the default in the collection library. Views mitigated this somewhat, but after working with more sane libraries, have to remember that every time is tedious (though I'll grant that is a debatable point).

If your software is not performance critical, or you aren't implementing your own collections libraries, maybe you don't encounter these problems. But for the standard library, it is a problem.

Re: Why we love Scala at Coursera

#154

Earlier quoted context omitted.

Actually Haskell is quite nice and does a better job. Practical too.

I am a great fan of Haskell. But the tooling and libraries of the JVM is a significant real-world practical benefit. Scala can get away with a lot of nasties for that. (In fairness Scala is very well designed, nastiness is normally all to do with Java compatibility) Plus it allows Java programmers to start writing code almost immediately.

And yet the whole first part of his talk was problems with scala that are not problems in haskell. And many of those problems exist precisely because of java compatibility, which he acknowledges and says is not a good enough reason to do things poorly. By his own measure it seems like he should be using haskell.

Re: Why we love Scala at Coursera

#155

Earlier quoted context omitted.

Doing an extra object allocation (which will likely be elided by escape analysis in the JVM) is hardly "weird and terrifying behaviour". It is an implementation detail which has absolutely no bearing on the behaviour or functionality of the map.

In my use cases escape analysis does not elide these accesses out (and I was unable to reason about why not). Further, I had an immutable map that had ~hundreds of items in it that was generating hundreds of millions of objects. I found that weird and terrifying especially given that I was specifically asking it not to give me Options back. I frequently hear that memory/performance are "implementation" details and do…

So to summarize the collections library has "weird and terrifying behaviour" because there are cases where the performance is not quite as good you expected?

You might be interested in the AnyRefMap work being done here: https://groups.google.com/forum/#!topic/scala-internals/R4fT... Perhaps you could add your voice to the discussion if you have concerns around performance.

Re: Why we love Scala at Coursera

#156

Earlier quoted context omitted.

I think the Paul Philips stuff is both overblown by people outside of the Scala community and dismissed too freely by those inside of it. Paul has a very pessimistic world view, a very high standard of perfection and he's spent tons of time in the guts of an extremely complicated system. Listening to some of his talks it is easy to make the assumption that he thinks Scala should be nuked from orbit. On the other hand…

> It doesn't take a whole lot of doing to push the Scala collections library into weird and terrifying behaviour I'm genuinely curious to see examples you've seen in production code. I've used the collections for years coding full-time and haven't encountered anything like that.

I encountered them on a daily basis when I was doing Scala, and you see these Scala collections WTFs pretty much on every other line when you are prototyping in the REPL. I've come to the conclusion that the only way the Scala collections library will give me confidence is when my head can reason more than 100 types at the same time while having distinct types for every value in the universe.

Scala's problems are real and structural. There's very little you can do about it now that all these innocent newcomers buying into the lies of the vested interests.

Speaking of lies, besides those Paul Phillips points out, you hear these nonsense about how great Scala's explicit type declarations are, that they make your function's signature clearer and etc. These are all lies, the truth is the type inference algorithm can't unify a type because of all these type variance, type bounds and type views. All these funny emoticon symbols are actually hints to tell the type inferencer to go up or down or sideways when looking for the most generic type that satisfies a type signature.

Another lie is that Odersky will keep showing you kiddy pictures and extolling how small Scala's grammar is while sweeping under the rug that Scala's many features are orthogonal, or halfway in-betweens GCDs or have surfaces of interaction with other features that are too large.

To list a few, these are my favorites:

1. implicits. Explicitness in function decl is good but when you call them it's better to hide all these unknown implicit params/type conversion from you so you can't reason your code.

2. _. There are 12 different ways you can use them. They are not shortcuts, they are conflation of concepts.

3. The interplay between classes, case classes and traits. It's very hard for me to put this one in word, there are just so many corner cases.

4. Java/Scala interop. There's no interop. There's only 1 way op from Scala to Java.

5. case classes are just ADTs. Nope, not letting me have a param-less case class or subclass a case class doesn't make them ADTs.

6. Companion objects are sold as singleton replacements. They are only singleton replacement as a side effect of having no other suitable place to put your implicit kludges.

7. Type safety. You can't guarantee type safety if you allow mutability. Period.

8. Java compat is simultaneously sold as an advantage and blamed when problems arise. Why can't Scala just use the damn bytecodes and avoid the entire Java standard lib?

Re: Why we love Scala at Coursera

#157

Earlier quoted context omitted.

> The biggest thing that contributes to refactorability has nothing to do with type safety. Instead unit test coverage, by a mile, is the thing that makes code easy to refactor Type Safety is Unit Test Coverage. Typing is a statically checked test of correctness of your program. Languages like C give static typing a bad name. Types are not things like 'float', 'int', 'double'. Types are 'degrees', or 'radians'. Types…

> Types guarantee that your code executes as you expect, and prevent you from writing incorrect code in the first place. If you write a Rational class and implement it's + method as def +(other: Rational):Rational = new Rational(0) then no amount of static typing will save you. At least without dependent types. Static typing gives you a knowledge about what kind of object you're dealing with without the need to run t…

> then no amount of static typing will save you. At least without dependent types.

Sure. Static typing also doesn't help with misunderstanding requirements, or a faulty test in a recursive function. But strong typing, especially in languages where there is no such thing as a NullPointerException, does eliminate entire class of problems. On the other hand, with dynamic languages, you are often a typo away from a runtime error.

Re: Why we love Scala at Coursera

#158

Earlier quoted context omitted.

In my use cases escape analysis does not elide these accesses out (and I was unable to reason about why not). Further, I had an immutable map that had ~hundreds of items in it that was generating hundreds of millions of objects. I found that weird and terrifying especially given that I was specifically asking it not to give me Options back. I frequently hear that memory/performance are "implementation" details and do…

So to summarize the collections library has "weird and terrifying behaviour" because there are cases where the performance is not quite as good you expected? You might be interested in the AnyRefMap work being done here: https://groups.google.com/forum/#!topic/scala-internals/R4fT... Perhaps you could add your voice to the discussion if you have concerns around performance.

Another way to summarize might be to say, "If you discount the many examples of incorrect behaviour that paulp mentions, and you don't care about performance, and you are comfortable enough looking through the extremely deep collections hierarchy code to diagnose the reasons for these problems, then the standard scala collections library is almost as good as collection libraries available in other languages".

The AnyRefMap may be a good solution to many of my issues with the default map implementation once it is widely available. It won't help with the more general lack of cohesion in the library though.

Re: Why we love Scala at Coursera

#159

Earlier quoted context omitted.

Look at it the other way. In fact, you can do a blind test. Try writing in a strongly, (well[0]) statically-typed language for a while, and count the number of times your code fails to compile due to a type error. Each of those would likely have been a runtime error in a language like Python. Just earlier today, I had to write a short Python script (I normally write Go), and I was bitten by this. I'm used to the comp…

Look at it the other way. In fact, you can do a blind test. Try writing in a strongly, (well[0]) dynamically-typed language for a while, and count the number of times your code fails at the REPL due to a type error. Each of those would likely have been a compile time error in a language like Haskell. Just earlier today, I was writing some C++ (I normally write Clojure) and I was bitten by this. I'm used to evaluating…

> Each of those would likely have been a compile time error in a language like Haskell.

Why do you consider this a hindrance? Haskell has a lot of issues, but that's really not one of them. You can write a Haskell program and be relatively confident that it's going to work right in a way you simply won't be with, eg, Java. And you don't have to wait until compiling. With ghc-mod and vim/emacs configured, you'll be notified upon saving if you blew up something in the current file. You don't need to run your code in a REPL to find out about it, although GHCi is pretty good. You spend a lot less time figuring out what goes wrong at runtime, although I'll grand you that the tooling is poor enough that you have a bad time doing when it happens.

> I qualify this to rule out Python, which has weak typing

Excuse me? You rule out Python due to weak typing and mutability but disqualify Javascript due to its REPL? This must be sarcasm. I have no comment about Javascript's REPL (which one? node's?), but Python is most certainly not weakly typed, not in the way "weak typing" is commonly understood. As for mutability, they are comparable (except that Python has at least the good grace to throw an exception at runtime if you attempt to access an attribute which does not exist).

Re: Why we love Scala at Coursera

#160
post #114
post #8

What is the point of articles like this? I'm not trying to be snarky; I really am trying to understand why a company would go out of its way to advertise the technology its using. Sometimes we see blog posts from devs at companies (often pretty senior) who write things like "We went with Clojure, and we've been really happy." That's clearly a geek-to-geek thing. But what is this? I mean, it's also geek-to-geek, but i…

When I first approached writing this article, I had a hard time. We have learned a lot from other companies sharing their experiences and we wanted to give back. We are doing this now because we think we have enough content to regularly write posts that will be interesting to other developers. Although we are very interested in open source projects and giving back, open source projects require significant amounts of…

>> As for your warfare speculation, I am happy to say it is just that. We have not had any warfare here at Coursera. This is not true. I have it from multiple independent sources within the company that it was largely an acrimonious coup, led by a couple of engineers. It's one thing to defend your position. It's a wholly different matter to willfully lie.
Post reply on HN