I've been using Gradle for my current project and I really like it, but I've been getting grumpy about the build times. Would switching to a build tool that supports keeping the compiler warm and Zinc 1.0's incremental compilation help much? Since I'm looking for something that's production-ready, I think the options for that would be SBT, Maven, and Pants.

I'm a bit nervous about switching to SBT: I have bad memories of the last time I used it, about 5 years ago. And I don't really remember how it works. I've read that people just use templates for their builds. I'm not really comfortable with templates and not knowing how my build tool works. But I'm willing to put in some reading if this is really the best solution.

I actually don't know Maven that well either. I think I last wrote a simple project even further back, but I remember it being somewhat tedious, but well-documented and straightforward. I probably won't go for Maven, but I'd like a second opinion.

Pants seems promising, but I'm not sure the monorepo approach makes sense for a small team with only a couple projects.

tl;dr: My compiles are slow. Would a new build tool help? How are the various build tools?

Note that one of the points of SBT alternatives such are Mill or CBT is to provide users with a way to structure their builds using semantics that users are already familiar with. A class is something that most developers with a little bit of OO experience can easily understand.

SBT's most minimal build might be a selling point for you, but when you start having multi-modules / scope and you need to structure things a bit better, SBT's model is a major pain in the ass, whereas this OO "boilerplate" makes sense to me (and probably to a lot other devs)

2003 - A drunken Martin Odersky sees a Reese's Peanut Butter Cup ad featuring somebody's peanut butter getting on somebody else's chocolate and has an idea. He creates Scala, a language that unifies constructs from both object oriented and functional languages. This pisses off both groups and each promptly declares jihad.

If you are interested in helping write code to build a new Scala build tool, I'd love your help. We have a vision, a plan, and most importantly working code that can already build several (small) open-source repositories. IntelliJ support, watch-&-re-evaluate (for both project files and build files), incremental re-builds (both inter-compilation-unit and intra-compilation-unit using Zinc), a build console & plugin system (using Ammonite), sonatype publishing support, uber-jaring, etc. all work. This isn't a toy experiment that'll disappear tomorrow

If you are looking to use a new Scala build too, you probably should hold off until we announce that it's ready for use

If you are happy with SBT (or Bazel, Gradle, etc.) then you probably should just ignore this project

Alternative interpretation: all the entry-level Scala developers are unemployed and don't turn up in the statistics, whereas there is great demand for entry-level PHP/JS/C# developers who can always find a job

(Not saying that this is the case, just showing how you can really see what you want to see from this statistic)

Commit volume is a poor metric, since a high number of commits might just indicate a poor design that requires a lot of code changes to do anything. (Or might not).

I don't know of anyone using either in production. I don't think iOS is such a big market, particularly among JVM-oriented people who would be the audience - indeed I think fast startup bash-style scripts, while much less glamorous, are probably a bigger market.

Notably, while commit volume isn't a good metric, number of committers is, especially for small numbers. It's a huge jump to go from 1 primary committer to 5, and indicates that the project won't go on hiatus when one guy has a paper to write, or graduates and gets a job doing something else. (Many of my own projects do poorly here; I've been trying to hard to find substitute maintainers, but haven't been totally successful)

I can't answer for alex, but for uTest, the reason I didn't go with REPL methods is because of nesting. I use helper methods very aggressively in my tests to DRY up the logic, which means my tests often end up looking like this:

It effectively gives me many of the benefits of table-driven tests, and let's me smoothly move my tests along the spectrum from "small number of big examples" to "big number of small examples", without needing to jump between two totally separate APIs like you have to do in ScalaTest.

The flip side is that you end up with enough cases in one file that you end up needing nesting to organize it. If I didn't care about nesting, I would have definitely gone with the annotation-def syntax that JUnit does.

Yeah you could, but then you both lose the "call them from the REPL" property, and add a huuuge pile of complexity in the macros required to transform them. So we're back in the same place, just with different syntax

or if you want to be able to call them, nested objects with methods inside them?

Yes I could, but that would lose another property I like: that the different method calls do not share the variables defined in enclosing scopes.

We could potentially solve that by making intermediate wrappers def foo = new { def bar = new {... }}. This is something I've never thought of, and while structural types are gross maybe is worth a serious look regardless

Do you have something specific in mind? I do remove posts that are abusive / insulting / trolling, but many posts arguably fall in a gray zone and I try to give the benefit of the doubt whenever I can.

There is a lot more to moderation than deleting spam. A moderator, just like in an offline forum, can shape the discussion gently towards a form that they want it to be: whether in a 20 minute interview, an hour-long panel, or an online forum.

As many people here have stated, apart from the explicit spam, there a are a lot of pretty toxic posts and toxic posters in this forum. While it may seem strange to actively police tone and other things, giving everyone the benefit of the doubt is just an active a decision: one that drives away good people like /u/alexelcu or /u/tpolecat, and I'm sure many others who would be valuable contributors to discussions here. /r/scala is the most toxic of the programming-language subreddits I browse.

You could conceivably draw the line at "comments must be kind and courteous" like the Rust code of conduct does, rather than "comments must not be obvious trolling". I think the majority would agree that is a reasonable standard to uphold, in which case there are countless comments that cross the line.

More active moderation doesn't mean you need to ban more people or delete more posts: even just gently nudging people when they step over the line (where-ever it is drawn), with the authority that comes with being a moderator, is enough to get people to behave. This is something non-moderators cannot do: the people who will be most vigorous in such discussions are often the most toxic, and the discussion ends when all the reasonable people have left the room and the toxic ones remain.

Even good people sometimes need a nudge when they cross the line, just as a reminder that a line exists.

If you take a more active role in moderation, there will undoubtably be some initial noise and protest. But I think you are a reasonable enough person that you'd make choices that the silent majority broadly agrees with. If done well could do wonders to improve the level of discourse in this forum and possibly attract and retain many community members who would otherwise be driven off.

If you want people to help moderate, I'm sure there will be volunteers, and you'd be reasonable enough to pick sane ones.

Somehow Reddit hasn't become the place that the Scala community interacts. I don't think that's unusual: different communities somehow end up congregating in different places, for no apparent rhyme or reason. There are people outside of reddit...

Generally I think the Scala community is broad and somewhat fragmented, and the breakdown of how the sub-communities have formed mirrors that. Web-devs using Play framework have little in common with those designing digital circuits with Chisel, data scientists running ETL jobs on Spark have little reason to talk to front-end developers making websites in Scala.js.

In the long term, attracting new contributors to the community is far more important than fixing any particular set of specific issues. It's vital to draw a line and ban people who are unable or unwilling to avoid upsetting others, even if it means missing out on some contributions in the short term. (Indeed I'd say a failure to do so has been a repeated problem with the community, and the biggest thing holding Scala back).

I agree with this post. From what I've observed, most of the respected members of the Scala community are super nice and non-confrontational.

This is generally great, but it means well-meaning people who inadvertently step over the line don't get nudged back, and may not even realize that they are causing general unhappiness. You also sometimes see outright trolls coming in, e.g. to this forum, repeatedly/intentionally being inflammatory over a long period of time before being dealt with.

While I'm all for free-speech, I think a somewhat firmer moderation stance, both here and elsewhere (e.g. gitter) would benefit the community as a whole.

Cake has definitely its place. It's the right abstraction for strongly coupled components that mutually depend on each other. It's true that one generally prefers loose over strong coupling, but sometimes strong coupling is the most natural way to express things.

For instance, in the dotc compiler, the cake pattern is used for parts of a context that each transitively depend on the whole context, but that factor out specific concerns.

Notably, if you avoid circular dependencies, cake traits are no more strongly coupled than any other code: each trait can be instantiated and used independently, you just need to fill in the relevant abstract members. This is no different from passing in arguments to a function or class constructor.

You can achieve this by having the cake traits depend/inherit only on the abstract-members/traits they actually need, rather than having every trait extend/self-type the EntireCake. You can also use the acyclic compiler plugin to force yourself to do so.

After modularizing the cake traits, what’s left of the cake pattern is just a convenient way of automatically wiring up a member needed by one trait with the member defined by another, based on the member’s name. This is not unlike the way point-free function composition automatically wires up different functions’ arguments based on their position, or implicit parameters wire up different functions’ args based on type signature. Whether that is useful or not is debatable, but you can definitely build cakes without creating strong coupling via circular dependencies

It's so common that I managed to convince them to merge an less footgun-y alternative, which uses varargs to require commas.

Notably, uTest uses macros do accomplish the same thing without commas. I don't know if I agree-with/understand your proposed solution, but I agree it sure would be nice to have some better, "standard" way of doing this...

This resolves dependencies between the files of your compilation run; any dependencies, e.g. fully qualified access, and not just imports.

Default instructions are for SBT, and it just checks for dependency cycles. But it can be used anywhere you can use scala compiler plugins (e.g. command line, bazel, gradle, ...), and you can mangle the code to do whatever you want with the dependency graph (dump to JSON, dump to dotfiles, etc) or to restrict the dependencies to just imports if that’s what you wish

acyclic’s dependency-tracking code is copy-pasted from the Zinc incremental compile plugin, at some point in the ancient past.

I personally have a fork of this that dumps my project inter-file dependency graph as a dotfile I can | tred | dot -Tsvg > graph.svg for easy viewing. Only took an hour or two to mangle the existing code to make it do that, so you should be able to do similar things without too much difficulty.

You cannot do this with plain implicits, though Dotty would allow it, as tpolecat has noted.

Depending on how much you desperately want that syntax, you can make it work with a macro. Here's the strategy:

Define writeData to be a static method that takes an implicit Foo, where Foo is the actual thing that keeps track of the dependency

Define a globally available @compileTimeOnly implicit dummyFoo: Foo = ??? in Foo's companion object. You can give the annotation an appropriate error message people will see if they use it outside the desired scope without the proper implicit available

Define withChannel to be a macro. Using the macro, convert the withChannel{expr} into withChannelImpl{c => expr}, and walk the expr to replace any usages of dummyFoo with c

First of all, I was wondering why the bottom types (like Null or Nothing) doesn't have all methods above. Here is the answer.
It says that Subtyping and Inheritance not the same. Subtypes don't inherit all methods above.
So my question is - isn't it dangerous? I can put an instance of subtype without method in supertype with a method. It seems that Subtyping without Inheritance is dangerous.

First of all, I was wondering why the bottom types (like Null or Nothing) doesn't have all methods above.
It seems that Subtyping without Inheritance is dangerous.

Yeah that's about it really. Using nulls or throwing exceptions are dangerous. Still very useful sometimes, or at least unavoidable, but if you use them be careful! Wild Pokemon live in the tall grass!