I have been using procedure syntax to (in my mind) good effect for many years in my work with children using Kojo (www.kojo.in). Commands (defined via procedure syntax) vs functions (with an = sign and an optional return type) is a big deal in the Kojo world.
Kids in grade three don’t get to functions for a couple of years. They start using commands like:
forward(100)
right(90)
hop(100)
In due course, they get to make their own commands:
The : Unit is not necessary, you could just use =. You need the type annotation only for recursive commands. But I would imagine that would quite a bit later in your teaching.
Right, but even if I drop the : Unit, the = will still be there, and currently that’s used only for functions (the function call is explained as being equal to (i.e substitutable with) the value of the function result).
With the change, explaining what the = means for a side-effect (i.e. an ‘action’ in Kojo terminology) will get tricky. So it’ll probably be preferable to leave the : Unit in there as a marker for a side-effect.
I don’t find this syntax particularly confusing, even though I don’t use it very often (mostly because I try to avoid procedural style in Scala). Presumably the compiler is quickly going to tell you something isn’t quite right when you try calling some methods on the result of this method, and it should be rather trivial to figure out and fix.
I also think this is a minor change and that the people in charge of the language specification should try their best not to waste energy on a debate for small things like that. If it was for me, I would not make the change because it’s small, isn’t the most difficult thing about Scala for beginners at all, and some people like it enough to post about it.
To be honest, I think it’s the opposite. From the beginning of learning scala, I thought of procedure syntax as “Cool, but useless”. From what I read and learned from, it was discouraged against and deprecated (this is from IntelliJ’s deprecated transformation to convert : Unit = to procedure syntax but I thought this whole time it was univesally agreed upon and “a simple thing”) since quite some time. I saw the people writing about wanting to keep it as something I’d have never expected, to be honest. I use : Unit = without problem, but I didn’t yet work on anything large-scale so I didn’t weigh in my opinion about the amount of it in real world code.
I had been using Scala for a while, happily writing :Unit = {, before I even learned that procedural syntax existed, and I felt it was unnecessary and ugly, because it was breaking the symmetry.
Every definition returns a value and even something that doesn’t return Unit can have side-effects.
Yes, of course.
Essentially, we have an effect system by convention in the Kojo world. Procedural syntax without the = for commands (that carry out actions with side-effects ), and function definitions with an = for pure computations.
In any case, I don’t want to carry on and on about this. I just wanted to share my ‘use case’ with my initial post on the subject.
I am pretty sure guys behind Scala are against side-effects expressed as types in a language itself. If you want this feature you could check Haskell (or if you want JVM then Eta which works, but still very immature, plus is it has quite easy to install IntelliJ IDEA plugin [unlike the Haskell one which is a real pain to setup and keep it working]) or in Scala libraries like ScalaZ/Cats. But I heard a lot of FP guys are leaving Scala, not sure how this plays out for FP libraries/community.
Thing is, procedure syntax isn’t even really that helpful for effects. It “helps” only with the most basic type of synchronous no-value effect. As soon as you return a value with that (i.e. read from stdin) or change from sync to async code (i.e. Task[Unit]/Future[Unit] and similar), procedure syntax does not help you anymore.
And btw. Effects are, for dotty, at the “Considered” stage of a feature. The chances are probably not high enough to bet on, but still, they are willing to invest time into looking at it.
Oh, didn’t know that. I was convinced that somebody high (I though Mr. Odersky) was against it, but maybe I am wrong, or it was reconsidered.
I tried searching, but I didn’t find anything. If you know a link, could you please share? I am quite curious how IO-like type from Haskell would work in OOP, or how they are approaching this.
If you are talking about major people leaving FP Scala scene, I heard it here → https://www.youtube.com/watch?v=v8IQ-X2HkGE @ 0:25. I don’t watch Scala community much, so the info in the video might be wrong and I wouldn’t really know. I was inclined to believe it, because many points in the video are valid issues with Scala and I hope Scala guys are aware of them.
@quiray yeah, I wouldn’t take the exit of three community members of the scalaz community during the past three years as “fp people are leaving Scala”. The reality is that more people join than those that leave. However let’s not hijack this thread with this discussion and let’s get focused please. Any comment with regards to this topic will from now on be marked as off-topic.
To be frank, I only found out about that cause it’s listed as “Considered” (unlinked as there is no PR for it yet, I presume) on the Dotty EPFL page. I think for details, you are probably better suited asking Odersky or another maintainer directly.
I think making = manditory is pretty good - one less source of confusion. Return type is still optional so it doesn’t add any verbosity as far as I can see.
Erics-MBP:scala-native eric$ dotr
Starting dotty REPL...
scala> val x = println("x")
x
scala> def x = println("x")
def x: Unit
scala> x
x
scala> lazy val x = println("x")
val x: Unit = <lazy>
scala> x
x
scala> def x() { println("x") }
1 |def x() { println("x") }
| ^
| '=' expected, but '{' found
1 |def x() { println("x") }
| ^
| illegal start of simple expression
scala>
I don’t have any strong opinions here either way, but this statement, which I’ve seen pop up multiple times is not really true. The return type is not “still” optional. A ) { procedure always has an explicit, non-inferred, return type. It’s not optional, it is expressed with an alternative syntax.
The problem with the existing procedure syntax is that it is easy to end up with a bug if you forget the “=” character. The code may compile fine but not do what you expect at all.
One alternative (perhaps this has already been discussed) is to use a different (but explicit opt-in) syntax for procedure syntax (e.g. possibly “=>” or “->”). This would be somewhat analogous to explicitly having to choose between val and var.
So
def procedure() { // returns unit)
could become
def procedure() => { // returns unit }
Of course the existing Scala 2 syntax for procedures would be removed.