Hacker News new | ask | show | jobs
by lcall 2261 days ago
I wanted Scala to be my "better Java" for a long time, mainly because it seemed to have plentiful headroom as I seek to learn more. The community enthusiasm was also contagious.

But: 1) the ecosystem makes it seems like I need to be a genius enough to learn a new DSL a bit too often, and everything is so...complex, which leads to...

2) It is hard to pitch to an organization because of the learning curve if you assume any project maintainer must learn scala to expert level. I failed (in one attempt on a scala mailing list) to pitch to the scala community the idea of having language levels: a compiler switch or the like that would guarantee that a given project will be maintainable by java programmers with only N (1-2 I hope, for the first level) hours of scala training or study, maybe another level for adding certain features (or listing them in a config file), and full-on expert. So teams can be formed with realistic long-term maintainability in mind. Edit: This may be practical with add-ons I didn't try yet.

3) It was unclear what would be the best reasonable, maintainable way to use sqlite. (Edit: in a multiplatform way to include at least BSD, linux, windows, mac. Maybe call a native code library for each? Sounds like lots of work and maintenance to do it well.)

4) Startup times, future viability of scala native (edit: or equivalent), and whether it helps or adds enough more complexity given all the above, to just learn Rust and (hopefully) simplify life (in some ways).

5) And you have to learn java first (for those who didn't know it already), and know its libraries and idioms to some extent. Will that still likely be true?

Comments welcome. (I enjoyed the article.) Maybe I'm just the type that wants to hit the sweet spot between what C, Java, and Scala do (edit: and Scheme), in a way that is hopefully/eventually at a complexity level that is inviting to other devs, but with plenty of learning headroom for my future growth.

2 comments

Scala dev here. "Having to learn Java" is not true at all, unless you interact with Java dependencies in special ways, or if you maintain a Java API for your Scala code. There are Scala libraries for almost anything, and it's easy to use some Java libs here and there. Creating wrappers is also simple.

One of the coolest things about Scala it that it already contains lots of Java best practices. Case classes, singleton and companion objects, traits, powerful generics... almost every Scala feature is a builtin answer for a Java pattern. Hell, even implicits in all its various forms are elegant solutions to common Java problems. People getting creative with these features is an entirely different issue. It's possible, and desirable, to use Scala to craft simple, elegant, and understandable code. Fancy but unmaintainable code should not ever be accepted: it's the job of the developer to teach the reader what the code does, and while this is true in any language, is more important when coding Scala, because the multiparadigm approach means there are multiple ways to solve things.

What you have to learn, at least in a basic form, is how the JVM works.

Thanks. I used Scala for some years and was always drawing on my java knowledge. Are there now good scala learning materials that don't assume java knowledge?

And the maintainability issue seems similar to perl vs. python in that way: it can be done, but I've found it takes much more work and long-term attention & presence, to enforce things with code reviews than with a project-level config that everyone knows why it is there. Just once when you are not looking and now you have a new (large or small) social and technical headache.

(Edit: in other words, while code reviews are essential I think for many reasons, any time there is a way to enforce something good, before the review, it seems like a win.)

As for learning resources, I always loved the Oreilly "Programming Scala" book: http://shop.oreilly.com/product/0636920033073.do

It's one of the few books that is structured in the same way a Scala developer thinks. Lots of Scala books follow the same order: keywords, usual syntax, features also in Java, features exclusive to Scala. I think this is damaging for any person looking to learn Scala, because it does nothing to lay out the way the features interact together. for instance, the Oreilly book shows pattern matching and implicits before class hierarchies, and that maps well with how Scala devs work, because the former features are encountered daily, while the latter tends to be uncommon.

As for maintainability: you're right. Stricter languages are more maintainable. There's also the issue of powerful languages attracting certain kinds of people. Over the years, I've settled on a simple policy: reject everything that is not documented. This goes for both internal code, and external dependencies.

Another follow-up about my point #2 above: if scala had done this early on (in an armchair hindsight kind of way), I don't know what need there could have been for Kotlin, and we could be learning one language for both purposes (better java and lots of headroom to learn/grow), instead of requiring 2-3 languages or more. Edit: I would appreciate better thoughts to improve my view on that.
I don’t understand your comment about SQLite. Doesn’t the driver manage creating a standard SQLite file? This shouldn’t really be Scala related.

Example connecting: https://github.com/tkawachi/sqlite-scalikejdbc-test/blob/mas...

Right, it's more of a JVM issue which affects scala. I did a search a while (couple years?) ago and maybe just didn't find the right materials, but they all (in my now-vague memory) seemed awkward and/or were not portable across platforms. Does this approach let you do every kind of sqlite operation, as completely as if from the interactive native client or as if calling it from C? Who maintains it and is it kept in sync with the C version? (Maybe I'll go look that up, but if you already know...) Thanks much for the info.

Edit: ps (maybe a note to myself as much as anything in case I go look up this stuff): And does sqlite run in the same process as the app? Can the app process control the db location?

I don't really know the answer to those questions. But I know SQLite is heavily used in almost every ecosystem so I would be really surprised if there were real blockers.

I know Android uses it a lot, so I opened up an Android project at my company and it looks like the android SDK comes with a bunch of SQLite abstractions, and it's not clear what the underlying driver is. But the SQLite official website ships an Android AAR so maybe that is it? (https://www.sqlite.org/2020/sqlite-android-3310100.aar)

This seems to be the main general-purpose JVM lib: https://github.com/xerial/sqlite-jdbc and it seems to be keeping in lockstep with the official SQLite versions (within a couple months).

Edit: Also can you elaborate on the "in a multiplatform way"? Maybe I'm having a brain-fart or memory-hole but shouldn't you not have to worry about that at all?

Edit2: Looks like there is a nice blurb in the docs on that github page:

  Since sqlite-jdbc-3.6.19, the natively compiled SQLite engines will be used for the following operating systems:

  Windows (Windows, x86 architecture, x86_64)
  Mac OS X x86_64 (Support for SnowLeopard (i386) has been deprecated)
  Linux x86, x86_64, arm (v5, v6, v7 and for android), ppc64
  In the other OSs not listed above, the pure-java SQLite is used. (Applies to versions before 3.7.15)

  If you want to use the native library for your OS, [build the source from scratch.
I think I had found that one, but didn't actually try it. By multiplatform way, I meant avoiding native libraries (sounds like more maintenance and debugging over time) and still being able to run on OpenBSD (or any BSD), linux, windows, and mac, at least.

Edit: yes, I think it does not currently run on OpenBSD, etc. One could contribute that library, but in that case, I'm more inclined to learn Rust and not deal with the JVM at all. Then I also get convenient access to things like pledge() and unveil(), and other OS-specific system calls, when I want. :) I will be grateful, however, for further correction & enlightenment... :)

(Edit2: I have been reading "the book" in Rust, but probably should write a test to confirm that it will make calls to sqlite and pledge() as directly as I think, using the tools I found.)