Hacker Newsnew | past | comments | ask | show | jobs | submit | modersky's commentslogin


We will check first whether they can be expressed as a macro (the macro roadmap for Scala 3 is still evolving).


There is https://github.com/scala/scala-async, which is already implemented as a macro, though it is a bit limited


It's currently about as fast as Scala 2.12, which means it compiles at roughly 3000 lines/sec. However, it supports more aggressive incremental compilation than Scala 2 so at least in my projects, which are typically 50K to 100K lines, most compiles are under a second, and I rarely see compile times over 5 seconds.

There's ongoing performance work to make both Scala 2 and Scala 3 faster than they are now. A lot of what people perceive as slow compile times are actually other factors (such as inefficient macros or slow build tools).


> However, it supports more aggressive incremental compilation than Scala 2

I'm not sure what you mean here... but Scala 2 and Dotty have the same incremental compiler, and their independent bridges feature overall the same quality (which is high and heavily battle tested, for those interested).


It has to do with what kind of dependencies the incremental compiler wrapper (e.g. zinc) can extract from the baseline compiler (e.g nsc or dotc). The Scala 3 compiler dotc handles that itself, which has the potential to achieve better accuracy. But I am not sure how much it matters in practice. We'll find out.


> which has the potential to achieve better accuracy

The quality of the used names extraction affects accuracy, but not compile speed. I must say, Dotty and Scala are extracting about the same amount of dependencies, with some corner cases being covered better in Dotty (for example, changes in constant values).

I don't see a way Dotty can become a faster incremental compiler that doesn't involve adding the incrementality in the compiler.


I'm not sure if you noticed, but you are replying to the designer of Scala.


I think jvican noticed this. jvican is the engineer from Scala Center which is supported by EPFL.

Edit: typo


Oh, my bad then haha!


The shared library we are talking about is the upcoming 2.13 library, which has the new collections design. We currently link against the 2.12 library but will switch to 2.13 once that comes out.


Just wanted to say- thanks for your great work in making Scala possible. And wanted to add that going through your Scala Functional Programming MOOC was one of the most rewarding experiences.


There can be instances of Tree[Nothing], just like there can be instances of List[Nothing]. It just means that in a scenario like this:

    class Tree[T] { def elem: T }
if t is a Tree[Nothing] then t.elem will not return normally (it might throw an exception instead).


Ok, so there are instances, which throw exceptions, fine, we're in Java land after all, where anything can happen. But why is Tree[Nothing] more useful than Tree[Unit]? Both contain the same amount of information (both Nothing and Unit convey zero bits of information), but one throws an exception while the other is safe at runtime.


Tree[Nothing] is a subtype of all Tree[_] types. This is similar to Nil in scala, which is really a singleton implementation of List[Nothing] or None, which is a singleton implementation of Option[Nothing]. Unit does not have this property, it is just a subtype of AnyVal/Any.

Basically, Tree[Nothing] allows you to indicate that a Tree is empty via the type system while still allowing you to use that same type to build an actual tree from. If Nil was List[Unit] instead of List[Nothing], 1 :: Nil would be a compile time error instead of a List[Int].

Oh, and Unit does have an implementation in scala called "()", so if you had a Tree[Unit] you would not be able to tell if it was actually empty or not. You can see this in scala with () :: Nil. It produces a non-empty List[Unit]. Nothing has no such implementation. As for the exceptions, there's not much you can do wrt that. What should happen if you call head on an empty List? That's a straight-out error. headOption or a match block is the safe way to deal with lists if you don't want to have exceptions ever.


Thank you.


I disagree. Value classes are a great tool in my arsenal, and not just for extension methods.


Different languages have different design tradeoffs. I had many profitable exchanges with Andrey Breslav and other Kotlin designers. We can have a technical discussion about the design choices without getting into a fight about who is more competent.


Have to step in here :-). In fact I bet that Scala has fewer features than Kotlin. In retrospect I now think Scala could have had fewer features, and hope we can get to a state where we can remove some of the redundant ones. But that's because (1) hindsight is always easy and (2) I am at heart a minimalist. Almost all programming languages have too many features to my taste.


Yes, Tree[Top] would have been another way to model this. I wanted Tree[Nothing] to make clear that getting the type of an untyped Tree gives a Nothing, i.e. a run-time error. Getting a Top is not quite the same, but it is almost as good, since only a view things can be done with type Any in Scala.

EDIT: There's one thing I did not stress in the talk and that makes Nothing a more attractive choice than Top: We want to do copy on write on these trees. I.e. if we transform an untyped tree to a typed one using "withType", we want to be able to reuse the untyped tree and just set the type (unless somebody else had already added another type). If the tree is of type Tree[Nothing], we can do that safely, even if there are still shared references to the same node as an untyped Tree. Getting the type of the shared untyped tree will give a Nothing, and nothing can be done with it. But if the type would be a Top, we would be able to apply some operations on it, so the copy on write would be unsafe.


It's much older than that. See

https://en.wikipedia.org/wiki/Futures_and_promises

The distinction between futures and promises in the wikipedia article matches Scala's terminology exactly.


Yes, Wikipedia's terminology exactly matches that of Scala, but that's because Wikipedia references a Scala SIP ;)

It's always bothered me that Baker and Hewitt felt the need to coin the term "future" when they were clearly aware of "promise" and "eventual". Their main distinction seems to be that a future is a 3-tuple (process, cell, queue). One can argue that their future meets the "read-only view" definition because cell is only to be written to by the same tuple's process. But they never explicitly distinguish a future as "a read-only placeholder view of a variable," and E was the first publicly-available language to make that very distinction (please correct me if I'm wrong), only they happened to use "promise" in that regard.

In any case, I trust your judgement on the matter more than my own, just wish everyone had picked a nomenclature and stuck with it.


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

Search: