I disagree with this line of reasoning that because procedures are actively harmful, procedure syntax should be removed from the language. My contentions are that that declaring that procedures are actively harmful is incorrect, further making procedures look more like functions is counter-productive, and finally making them harder to write doesn't make them written less often.
A. It has not been demonstrated that all procedures are harmful.
The most common testing framework for Scala is JUnit at least among Intellij developers[1], and the most common way to write tests in JUnit is as far as I can tell with the @test def testSomething {} or def testSomething {}, both of these are procedures. They are good procedures! I don't want to belabor this point because I am not a fan of procedures and I am suspicious of them, I try to zero in on them in code review but I don't feel that forcing `: Unit =` accomplishes anything meaningful in discouraging their use.
B. Making procedures look more like functions is more harmful than allowing them to have their own syntax.
When I am reviewing code, I will immediately try to scan for = versus {, procedures with : Unit = doesn't stand out as much to me as ones written in procedure Syntax. Having read hundreds of thousands of lines of Scala code, I can quickly see the procedures versus the functions. To me making the procedureSyntax go actually makes procedures blend into functions and sends the messages that procedure are just functions that return Unit. Which while true, isn't probably want you want to be thinking when you see a procedure. When you see a procedure, you brain should be switching immediately to an interrogative mode, what side effects is this code upto, should this thing exist? Or if I am reviewing a good programmers code, hmm what made the poor bastard have to write a procedure here, and can I throw him a life line and get his code out of this quicksand.
C. Even if procedures are harmful, that doesn't mean that procedure syntax is harmful.
Procedure syntax is the only safe way to use type-inference when writing a procedure. Well it's not really type-inference, because it's it own syntax, but that's because there isn't a consistent way to know unit is going to be inferred. Forcing the programmer to use 10 extra keystrokes every time they write a procedure accomplishes what exactly? Either they are don't understand that the procedure they are writing is harmful, and now they seem even more like normal functions to that developer, or they do, but their task requires them to use them, and writing : Unit = doesn't accomplish anything.
Thousands of good, working Scala procedures are written every single day and committed to Github. Thousands of terrible ones are also written. And lets not even get started on method local procedures, which often take the form of @tailrec def loop {}, which is, in my experience a much better way to write `while`. To me this whole idea of killing procedureSyntax is akin to removing type inference from var because it's bad practice. Sure using vars are bad practice, but when it's needed why are we punishing the developer that already has to write some bad code? The poor guy already has to write some vars, now were are really going to stick it to him by forcing him to write like it's java and do more typing, because someone deemed vars bad, and therefore they should be harder to write? In Scala we've come to the consensus that we like type inference and we prefer less code to more, I even remember reading an EPFL paper about how because Scala has less LOC it is more readable.
As a counterpoint, to me actively harmful is also breaking most examples of a procedure that already exists on stack overflow. Including good old `def main(args : Array[String]) {}`
Also I believe that if the forced type annotated Unit syntax was superior, developers aren't stupid they would be using it already. It's considered good practice among several developers, (certainly more than who oppose procedure syntax), to always type annotate public methods, should that be required as well? Imho a -Xlanguage:requirePublicAnnotations that can be toggled on / off as desired, what would actually be much more helpful to producing readable APIs and public Scala code.
Having said all that I don't think I am going to convince the anti-procedure-syntax people. This is some serious bike-shedding territory. So can't we all just get along and compromise? You might not agree with my reasons, but hopefully you agree that I didn't just make them up for no reason and that they are pretty strongly held.
If it is the contention that removing procedure syntax is an improvement to the language, there is a process for improving the language that is supposed to be followed: Creating a SIP (Scala Improvement Proposal). And further rather than invalidate a coding style still actively used by a majority of Scala programmers why not follow the lead of -Xlanguage:postFixOps and propose adding a -Xlanguage:noProcedureSyntax to the language. That could be done for 2.12 (or even 2.11.3), and codebases good start improving sooner according the noProcedureSyntax people, and I could start using -Xfuture on my company's codebase again.
People want to write methods, but forget the =. In the worst case, the result is silently swallowed and the bug manifests itself only later at the use-site, not at the point of declaration.
The exact same complaint could be registered about any function that doesn't have an explicit return type, yet there is no move to make that mandatory.
No. If the method has no explicit return type, it is inferred. It's really reducing the usefulness of type inference if a trivial error can flip the switch from "the return type is computed from the last expression of the method body" to "the method body is ignored completely, and () is returned instead".
Apart from that, there is a move to make explicit return types mandatory in some places; for instance when defining implicit conversions or when declaring abstract methods in traits.
And yet, if there is an idiomatic Scala (and the lack of one is a huge problem with the ecosystem) it's that nobody uses function syntax for Unit return types. So in order to get rid of a class of bug that is minuscule compared to others you are going to require hundreds of thousands (millions?) of lines of code to be changed. It's that kind of lack of real world perspective that causes the Scala community to be derided.
The most recent version of the Xlint/future features are useless because of this blind spot making so much noise in the output.
> And yet, if there is an idiomatic Scala (and the lack of one is a huge problem with the ecosystem) it's that nobody uses function syntax for Unit return types. So in order to get rid of a class of bug that is minuscule compared to others you are going to require hundreds of thousands (millions?) of lines of code to be changed.
If there's an automated conversion tool, who cares?
No, you'll have to review the patch yourself. We also don't indemnify you when we introduce a regression. We do have support contracts for those who want the fastest turnaround in fixing those...
How many LOC are you responsible for maintaining? Of all the confusing things in Scala the procedure vs method syntax seems like a trivial one, yet in deployed code bases most people use the procedure syntax. It has become a defacto standard. That the language designers got it wrong is bad, but not worse than the fix (or if they are going to "fix" this they should do it more slowly and not screw up Xlint/future).
I agree it's not the most confusing thing about Scala. It just doesn't help. It doesn't confuse me now (I remember programming languages were the distinction between function and procedure is important), but it makes little sense and I'm glad this syntax is removed for future generations of Scala devs.
Scala is a relatively new language that already has made too many concessions to backwards compatibility with Java, resulting in a less elegant language than it could have been. I'd rather they broke compatibility a few more times and got rid of their earlier mistakes.
This is not very important, though. I'd rather they focused on other, more important improvements first.
It's not a minuscle bug. Some older thread where people discussed this showed that it is a huge issue in practice.
The change to method syntax is both binary and source compatible (forward and backward); and as mentioned in the article no one is expected to do it manually.
Additionally, compiler warnings will become configurable, so that developers can choose which warnings add the most benefit to their workflow.
I've written/read/reviewed lots of Scala code and can't remember seeing it be an issue. Certainly not a huge one. I'd like to see a pointer to that thread if you can find it so that I know what to look out for. Maybe include that as justification in the SIP.
If this was such a `huge` issue, I strongly question how code of such importance would be written without a unit test accompanying it that calls the method at least once. If you are going to write code where having unit inferred is going to be a 'huge issue' what the %$&# are you doing not unit testing that method? Is it reasonable to assert we make the unit test harder to write (unit tests are typically procedures) and make this bug even work to catch in the first place?
If this is done with a -Xlanguage flag or made as opt in warning then that sounds very reasonable. It's going to be a lot worse if the first thing a newbie sees when they copy paste a main method in from an old tutorial is 'Error: Procedure syntax is deprecated'. No matter what the parser is going to have to parse the procedure syntax anyhow, in order recognize that form and give a reasonable error message for new users copy pasting in code. So it's not like we all that parsing code disappears.
>Additionally, compiler warnings will become configurable, so that developers can choose which warnings add the most benefit to their workflow.
My understanding was/is that this is going to become a compiler error. If it is going to just be an opt-in -XLint:procedureSyntax thing, then why isn't it being done for 2.11.3 ??? If the plan is just to make an opt-in warning I can rest easy, because I will simply never turn that linter warning on. I would however suggest to consider making it a -Xlanguage so that like postfix ops it can be disabled/enabled where needed.
The warning is already there: -Xfuture -deprecation.
We decided to delay making it a plain deprecation until we have said tool to do help you stay deprecation-warning-free. You are addressing deprecation warnings in a timely fashion, yes? :-)