Live data from Hacker News

Making the move from Scala to Go

movio.co

161–170 of 378 posts

Re: Making the move from Scala to Go

#161
post #118
post #23

Looking through the really abstract scala code they linked brings up a problem that really frustrates me in haskell. Why doesn't anybody document their really abstract code? You know it's going to be confusing, so why not help out? If I have a type like def foreignKey[P, PU, TT It's not sufficient to document the function's arguments. You also need to document the type variables! Likewise in haskell with code like f…

I mostly agree with you, but I also think a bit part of what Haskell-like FP shows is how often your code is invariant to so many things that the variables no longer have any sense to them whatsoever. That doesn't really excuse badly named variables when that doesn't hold. It's more that it's something sort of novel to a lot of Haskell-like programmers and so we all get excited about it and probably overdo it somewha…

> At least with a function `a -> b` might be named `in -> out`, but with a Profunctor there isn't even that intuition.

What about:

  dimap :: (newIn -> in) -> (out -> newOut) -> p in out -> p newIn newOut

Re: Making the move from Scala to Go

#162

Earlier quoted context omitted.

>And honestly, sometimes I don't know if code is too "clever" or the reader is just too "dumb". IMO, the answer is people vastly underestimate the cognitive cost of reading code. "Code" rarely exists in a vacuum, the reader has a universe of inputs, outputs, problems, solutions, failures and goals. The cognitive cost of trying to read someone's code is something that must be paid multiple times per day and at one poi…

I'll keep repeating myself: the cognitive cost of "code" is dwarfed by the cost of understanding an application . If a couple esoteric languagn features take an extra few hours to learn but reduce LOC tenfold, it's a price I'd pay every time. Not everyone feels this way, the investment to learn these features may not pay off right away, and if you come from a "move fast and break things" language (python/php/js) it c…

> If a couple esoteric languagn features take an extra few hours to learn but reduce LOC tenfold, it's a price I'd pay every time.

Issue is that a beginner pre-conditioned long enough on "verboser, imperativer" models/languages, when reading/comprehending such a codebase, has to literally mentally expand every 1 line into 10 upon reading, for quite a while .. some weeks, some months, as more intuitive grasp sets in slowly over time. Probably what happened at OP's quoted company and with the different speeds in comprehending what "clever" (compact) code some of their coders came up with, what they flippantly called "code that was harder to understand by others"..

Re: Making the move from Scala to Go

#163

As it turned out, more flexibility led to devs writing code that others actually struggled to understand. This is what happens in almost every language. Niftyness and the prospect of impressing your coworkers distorts the cost-benefit calculation. This is in addition to the true costs appearing months or years after the code is written, involving the interaction of complex factors, like increased cost of debugging. "…

yep... making 'understandable' is really important.

But given that discipline, scala would outshine go since scala has much better typechecking than go - e.g. http://getquill.io/ can typecheck against a running DB schema, etc.

Re: Making the move from Scala to Go

#164

As it turned out, more flexibility led to devs writing code that others actually struggled to understand. This is what happens in almost every language. Niftyness and the prospect of impressing your coworkers distorts the cost-benefit calculation. This is in addition to the true costs appearing months or years after the code is written, involving the interaction of complex factors, like increased cost of debugging. "…

I'd much rather deal with concise, clever code that has a sane interface and works, rather than sprawling long winded code where everything is void and the same low level constructs are used everywhere. And honestly, sometimes I don't know if code is too "clever" or the reader is just too "dumb".

Welcome to Haskell ... where clever people write frameworks that even dumb people can't break ;-)

e.g. https://code.facebook.com/posts/302060973291128/open-sourcin...

Re: Making the move from Scala to Go

#165
post #112
post #108

Earlier quoted context omitted.

They only missed these features for 2 weeks? Good for them! Their problem domain is likely so simple and neat that it fits the Go's limited built-in types well, and does not lead to frequent copy-paste programming. If so, Scala has been an overkill.

As simple as a distributed, horizontally scalable SQL database, perhaps? ( https://github.com/cockroachdb/cockroach ). Those dumb Go programmers and their toy programs ( https://quicknotes.io/n/1XB0 ).

I program since the mid-80's, many of the features in modern languages weren't always available outside research institute walls, and yet we managed to deliver any sort of software with the tools we had at our disposal.

However, now that those features are part of the majority of mainstream languages, I surely don't want to go back to how I used to write software in the first two decades of my career.

Re: Making the move from Scala to Go

#166

Earlier quoted context omitted.

In all honesty, I prefer having rules that have no special-case 'unless' issues. It's too much effort/trouble to remember all the cases where things don't work. I'm a good engineer but a terrible compiler. I believe part of learning a new library/framework/language is to limit yourself to a certain subset of the API offered. After working with Ruby (the language) and Javascript (the ecosystem), I feel like that's the…

> the rule would be no ternary operators Why not "no nested ternary operators"? > You don't need to wrap if conditions unless you have a multi-line body Why not "keep unwrapped if conditions on a single line"? > Early returns simplify short circuiting logic unless your function becomes too long Why not "keep functions short"? > Using a variable as a conditional in javascript to test against undefined works well unles…

It's because it's too easy to lose some of these nuances during refactoring/development blindness. I'd go so far as to say it's inevitable.

If you come into a 3 year old codebase and during the first 2 weeks you need to add extra functionality to a 30-line function with an early return, are you going to refactor the early return? Or are you going to extend it into a 32-line function? What about the new hire after you?

Alternatively, your team has decided to embrace the "only use conditionals on boolean values" philosophy. You're working with a section of code that reads `if (myVar)`. It's been 3 hours, and you don't understand why the code's not working. Suddenly, you realize that at some point `myVar` was refactored from a non-nullable boolean to a nullable number, and someone missed changing this.

And the biggest offender yet - code that is grouped within a file into 'logical sections'. I've never seen this work out. What is a logical grouping for you is a confusing pairing for me. Or maybe it's that I can't immediately grok all 2000 lines of a file I've never seen before, and know where to place the method. This madness around code location is one of the quickest ways to code rot.

---

The perplexing thing to me is that these situations are completely preventable.

If you don't use early returns, scenario 1 won't happen.

Scenario 2 won't happen if you use real comparisons e.g. `if (person.age !== undefined)` (Similarly, `if (person.age != null)` breaks when null and undefined start meaning different things...)

And lastly, a canonical alphabetical/visibility ordering for methods in a file of any length is unambiguous. I don't care what the order is, as long as there is a canonical order.

---

I understand that other teams have their own rules. It's no trouble at all to adjust to things that are purely syntactic differences. But when the rules that are chosen hide lurking semantic pitfalls...I don't know why you'd risk shooting yourself in the foot.

A lot of my strong feelings on code style come from the book Code Complete. I highly recommend that to everyone who hasn't read it. It's filled with examples of confusing/broken code you might inherit, and teaches you how to avoid creating it yourself.

Edit: looks like we hit the HN thread depth limit. Happy to continue this over Twitter, check my profile.

Re: Making the move from Scala to Go

#167
post #52

I have a simple question. In the article they mentioned they had a concurrency issue with a timed buffer that they later neatly solved with go channels and goroutines. They said that they solved the problem in Scala by moving to the actor model, but that required importing Akka into their project and training everyone how to use Akka. My simple question is: couldn't they have achieved the heart and soul of the actor…

Actors should be in a process no? If it's in a thread then it'll take the main process down with it. Erlang's BEAM VM every actor is in it's own process. So if something goes bad then it can be restarted via supervisor. Scala is on JVM and JVM isn't built with concurrency in mind and I think Erlang's BEAM is too good at this. Akka is gimped too, you have to write actor a certain way iirc other wise it takes over the…

The JVM has tons of concurrency tools, it's absolutely designed with concurrency in mind. You can write code in the channels style if you want too.

Re: Making the move from Scala to Go

#168

[Scala team lead at Lightbend here] I'm always eager to learn how we can improve Scala, especially as we kick of the Scala 2.13 cycle (hard at work on compiler performance and standard library improvements). Email is 'adriaan.at("lightbend.com") Regarding Scala's growth, I will leave you with https://www.indeed.com/jobtrends/q-scala.html .

For completeness:

https://www.indeed.com/jobtrends/q-scala-q-golang.html

Re: Making the move from Scala to Go

#169

Earlier quoted context omitted.

Agreed, but they also complained about map() and flatMap(). I have to think that eventually every developer can understand the more straightforward monads, functors, and Either - which, along with type aliases, IMO, can make code a lot more readable. I think the more esoteric features should be reserved for complex code, especially if it's possible that those features can prove runtime correctness at compile time and…

A for-each loop is only slightly longer, more familiar (just about every language has it), and more flexible - it covers map, flatMap, and reduce. So why have three or more specialized constructs when one will do? There are cases when the restrictions of map() and reduce() are necessary, most famously for a map-reduce in distributed programming, but that's not really relevant for implementing a simple function.

> So why have three or more specialized constructs when one will do?

Because having three specialized functions for three specialized operations makes it easier to see what a given piece of code is doing. One function per function.

Re: Making the move from Scala to Go

#170
post #156

Earlier quoted context omitted.

If you run `~` before any command, sbt watches the directory for any source changes, and on detecting source changes, redoes the command. So `sbt ~compile` will re-compile any new sources as soon as they are saved.

Wait, how does that help build time exactly ? It may help with the perceived build time, but your CI builds are still taking the same (long) time.

CI, sure, but on dev machines this means you're not throwing away the JVM and restarting it, reloading all the classes etc. on every build
Post reply on HN