Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

To be honest, designing a good programming language is not just collecting random good features from other languages and gluing them together. Particularly, adding new features to an old and mature language like Java or C++ is very hard if not impossible to do right. We have a few examples of this in happened already in Java world: half-broken generics or support for lambdas with no proper map/filter etc. on basic collections (forcing to do a lot of conversions to/from streams). Sure, it is better than no generics or no lambdas at all, but it is Java that really looks like a hack now, not Scala.

There is also stuff that probably can't be taken out from Java without major backwards compatibility issues. E.g. Scala has no distinction for primitive/box types, which makes it much simpler and more elegant for basic imperative/OOP programming than Java.

As for frustration working with Scala - I didn't notice, despite working on a few projects for a few years now. I've known only one programmer in my whole career who complained about introducing Scala into one project because "Scala was too complex" and guess what... he was one of the poorest Java programmers on that team at that time. Java did not save him either. Reading his Java code was probably much more frustrating than waiting 5 minutes for a full Scala build would be. Poor programmers do exist and you should not blame the tool just because someone can't properly learn how to operate it.



> As for frustration working with Scala - I didn't notice, despite working on a few projects for a few years now.

TBH, if you're using Scala as a slightly better Java/C#, then you're probably going to get a lot of mileage out of it. As someone who really would prefer Haskell, the problem I find is that Scala has all these tantalizing features that you really want to use but which turn out to be broken in subtle ways. Anyone who's used scalaz will know what I mean.

The absurdity of "for { ... } yield" notation is one of the first things that springs to mind. (Given that "return" is NOT special or magical in any way in a Monad and can, in fact, meaningfully be repeated in the same function.).

The other major thing is that you can arbitrarily (and subtly!) do side effects while in "monadic" notation. That nullifies most of the advantages of having a do/for-yield notation in the first place.

There's also the stack overflow issues that are rampant if you actually try to use monads seriously in Scala, etc. etc. (This boils down to the JVM not having tail-call elimination.)

Scala is basically a cocktease when it comes to FP features. It promises loads, but doesn't really deliver. These days, I'd actually probably prefer C#/Kotlin/Ceylon over Scala[1] because at least they don't lead you astray in this way. (Obviously, I'd prefer to rewrite everything in Haskell, but we have an actual existing/working system written in Scala to support, so...)

TL;DR: These days we're using Scala as a "better Java" and if that's what you want, then you probably won't be disappointed. If you're looking for FP-as-it-should-be then you will be disappointed.

[1] Assuming we're only talking about language, not the wider ecosystem.


for/yield is fine. Haskell people love to get excited about the one extra flatten but it's really not a big deal.

Side effects in Scala are a little less obvious than unsafePerformIO calls, but not by much. One little unmanaged println isn't going to destroy the universe. The fact that Haskell will invisibly transform your code into lazy thunks, radically altering its performance characteristics, causes a lot more trouble IME.

Stack overflow problems are real, but you can get a lot of value out of the monad functionality without hitting them, particularly these days with a lot of effects being implemented as Free monad + interpreter. I wonder if Scala.js avoids the issue?

I'd probably switch to Ceylon or Idris if either had the ecosystem to match Scala. But for the time being they don't.


(EDIT: sorry, rampant editing. I apologize if you happen to reply to any of my intermediate edits.)

> for/yield is fine. Haskell people love to get excited about the one extra flatten but it's really not a big deal.

No, it's a big deal. It pollutes everything you do in "do" / "for/yield" notation.

Part of why do notation in Haskell is so amazingly beatiful and concise is that it doesn't force this absurd amount of pointless boilerplate on you.

(We can agree that they're technically equivalent, but SYNTAX FUCKING MATTERS, YO)

My thinking here is that Martin Odersky actually understood what was going on at a technical level, but didn't appreciate what was going on at the cognitive level of the programmer... and so just implemented the mechanism.

If you compound this with the semi-recent "cats"/"scalaz" schism over Monad and Functor, thus making us reexperience the monads-tf/monads-fd schism in Haskell-land... making me think that the supremely clever people behind these projects (no sarcasm!) never experienced the pain that comes from split ecosystems. Because if they had, they wouldn't have started "cats" without getting concensus first. My point is that you cannot meaningfully talk about Monad/Functor without that type definition being a core part of the language -- which it isn't in Scala.

Listen, I appreciate that they have a more difficult problem in some sense, because they've accepted subtyping as an actual thing that's useful. But that's their problem. Subtyping generally isn't very useful[1] and they're driven by OOP ideology... which is fine per se, but don't complain when it doesn't work out -- when the problems of subtyping are well-known and have been for the last 20-30 years.

[1] Use lenses and contra-/covariant functors instead when you actually need it.

> One little unmanaged println isn't going to destroy the universe. The fact that Haskell will invisibly transform your code into lazy thunks, radically altering its performance characteristics, causes a lot more trouble IME.

Yes, it will. Because it isn't just a little "println" here and there (in practice). The deal here is: I can mechanically scan all the code for unsafePerformIO and unsafeInterleaveIO, etc. I cannot scan Scala code mechanically for unsafe things because the possibilities are almost literally infinte. It's about "permit evil selectively" vs. "forbid evil when you see it". The latter doesn't work.


    making me think that the supremely clever people behind 
    these projects (no sarcasm!) never experienced the pain 
    that comes from split ecosystems. Because if they had, 
    they wouldn't have started "cats" without getting 
    concensus first.
What consensus? Do you understand why cat needed to be created in the first place?

It was created because it was impossible to work with these terrible, obnoxious (ex-)Haskell people anymore.

The main change from scalaz to cats is not the code, but the community: Friendly people behaving like adults who don't act gravely offended when people discuss potential approaches which don't look like 100% what Haskell came up with.

I think scalaz will fall out of use mid-term, because everyone is sick of their shit behavior.


> What consensus? Do you understand why cat needed to be created in the first place?

Consensus as in: Get the approval of the community or at least lobby for the inclusion of Monad/Functor/etc. in the Scala standard library. My point was that the inclusion in the standard library is key to making Monad/Functor/etc. work. If you don't have that then you end up with the sad sad situation of monad-tf/monad-fd except this time it's not Transformers[1], but the fundamental Monad/Functor/etc.

As for the rest of your comment: ... WHAT?

[1] Which, to be fair, were fairly controversial at the time.


No need to impune Haskell developers thanks. (Even if that wasn't your intention your comment does read that way.)


I'm just stating facts. No idea why these terrible people decided to join Scala in the first place. Maybe the Haskell community ejected them and they just picked their next community to harass?


Oh, fuck off.

You're complaining about "inclusiveness" and you say "terrible people" in the same breath. No. Fuck you, and fuck off.


> You're complaining about "inclusiveness"

Where?

> No. Fuck you, and fuck off.

That's exactly the kind of immature behavior which is not welcome in the community. Please stay in the Haskell land.


Don't imply this behavior is welcome in Haskell land!


lomnakkus, I've never heard of you in the Haskell community, but if you do consider yourself part of our community then act more decently in future. You're giving us a bad name.


I've heard this argument many times and it all boils down to "Scala is not Haskell", which is in fact a true statement. Scala is not Haskell and never meant to be a Haskell replacement, nor a pure FP non-strict language. Complaining effects or monads are broken in Scala is like complaining that nominal subtyping in Haskell is broken or that you can't just introduce state in Haskell whenever you want, like you can with Scala changing a val to a var. Different design choices, different strengths / weaknesses.

Anyway, Scala is probably one of very few languages that combines OOP and FP and at the same time has type system sophisticated enough that it can express directly or indirectly the stuff that Haskell can - maybe more verbose and there are some rough edges like you say, but hello, here is the news: Scala is not Haskell and it had to pay some price for other useful stuff that Haskell doesn't offer.

Also, Scala creators are generally aware of some shortcomings of the current Scala type system and are working hard on improving and simplifying things (DOT calculus). So if you know how to make effects or for yield notation better and fix these subtle problems - I think the community would appreciate your help.


> I've heard this argument many times and it all boils down to "Scala is not Haskell", which is in fact a true statement. Scala is not Haskell and never meant to be a Haskell replacement, nor a pure FP non-strict language.

Yes, but my point is that Scala's unholy combination of OOP/FP has been marketed as some sort of panacea... which it definitely isn't. I think, it's actually worse in both aspects: Erlang (modulo static type checking) beats it in the OOP realm, and Haskell (and Idris, etc.) beat it in the functional.

Try to use scalaz for anything serious, and I think you'll find out what I mean. Don't get me wrong, scalaz (and shapeles, etc.) are marvels of engineering, but they aren't sufficient in practice. Nor are they for any reasonable definition of the term 'usable'. Haskell/GHC is -- and in fact it's simple and easy.

Btw, now we can also enjoy 'cats'! Let's retread the whole "mtl" and "transformers" disaster once again in Scala! Fun! (I was around for the Haskell mtl/transformers/fundeps thing and... it didn't work. Monad &c. need to be part of standard library. For sanity.)

I just think programming languages is a realm where compromise doesn't work. Maybe I'm wrong, but...

> Anyway, Scala is probably one of very few languages that combines OOP and FP

Firstly, "Combine A+B does not necessarily improve anything"[1], but...

Secondly, see, this is the problem... having a few things signify "this cannot be mutated" does not an FP language make. It's far more complicated than that -- it's about culture. The Scheme authors recognized this and named anything that was "dangerous" (side-effecting) with a bang at the end so that it would be offsensive and stand out to any code reviewer. This is what FP is all about... not just paying lip service (which I think Scala is doing currently) to immutability.

EDIT: Look, I realize that I'm being an asshole with the beneift of hindsight, but still... I'm talking about what we should aspire to. Not just accept.

[1] I think the supreme example of this is in the O'Caml object system. It's basically better than any single-dispatch system out there, but nobody[2] actually _uses_ it. Why? Because it's just simpler to do in function style.

[2] Yeah, yeah, qualifiers, formal studies, etc.


There are conventions in scala to talk to the culture as well. Ya I agree that it can be hard to see effects occasionally. I just worked out a bug where some element was cached despite the fact that the function I wrote appeared to be pure. But still, in scala's culture braces at the end of a function are, by convention, representative of an effect.

Eg doSomething is pure and doSomething() has an effect. It's shades of grey. Scala ultimately may not be Haskell, but it's useful and a much better alternative to using Java. To lean on the JVM and be able to sell Scala is better than using Java just because it's what's already there. To transition away from java toward something better is a win. It's definitely a win. I'd love to work on haskell or introduce haskell in places that i work but no way in hell would I ever succeed. Only at a startup with the smartest of smart people. You can take interested ruby developers and chop them into decent scala devs and that's good for the pitch. How the hell do you take a team of mediocre devs and get them to write your next production system in haskell?


> Ya I agree that it can be hard to see effects occasionally.

Nono. The point is that they should be codified and forbidden in places they shouldn't be used. I cannot describe how much this matters to anyone who hasn't "absorbed" the Haskell mindset. (That's not your fault, it's mine. "More research/explanation needed" on my part.)

> ... and a much better alternative to using Java.

Yes, but it only if you use it as a "better Java". It fails _hugely_ if you try to do anything "advanced"... as in actual FP like lenses and things.

> I'd love to work on haskell or introduce haskell in places that i work but no way in hell would I ever succeed.

This is also a cultural problem. Migrate towards microservices and... there you go! Nobody actually cares what it's implemented in. (I think this is a somewhat sneaky/underhanded way to introduce it, but it... works.)

EDIT: If you want to see first-hand what I'm talking about try "monocle" or "shapeless", which -- while both being fantastically named and engineered -- fail on actual usage.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: