Imho, that's at least one option too many.
The
first option is especially troubling, because we reward people who use
side-effects with special, less verbose syntax, while we claim that the
language nudges people toward a more value-driven style of programming.
Additionally, we make it extremely easy for beginners to mistakenly use procedures instead of methods (by forgetting the =). Because they are still learning the language and often write some
methods down without necessarily wiring them up in the same turn the compiler doesn't create a type error. They
assume that they wrote a method, but in reality they wrote a procedure
instead. Then they run it and keep wondering why they don't get any
values back. Incredibly frustrating. For some, their Scala journey ends
right there.
The question is, why are we causing this huge confusion for basically no tangible benefit? Imho, it would be a lot easier to explain and more consistent if one could say "every member implementation consists of an =, separating the signature to the left and the body to the right" instead of having an additional syntax for procedures.
I spent a lot of time, sat down with those learning the
language and asked them _explicitly_ "from your limited experience,
what part of Scala sucks?" and the procedure-vs.-method thing is one of
the main points where everyone says "yes, one can learn it, but there
seems to be no apparent reason why it is that way, apart from being a
pointless nuisance".
The second option is pretty bad from a different perspective: Those who actually want to return a value, but have forgotten the equals sign fall into this trap. This comes up a lot. (We have at least a warning for that now.)
The third option is explicit and the style I think should be preferred. (Additionally, I recommend that this style is enforced in traits, too. I think it's mind-boggling and invites errors that we even allow writing trait Foo { def foo } instead of trait Foo { def foo: Unit }.
What about
This would improve consistency of the language, remove confusing
variations in style, reduce the amount of special-cases users have to
learn and prevent a lot of beginner mistakes. I think we have a lot of places were we could spend the complexity budget of our language much more effectively than on building error-prone syntactic special-cases.
I think the idea about recommending : Unit = is quite similar to the reason why we started to emit a warning for catching exceptions with case _: we don't prevent people to do potentially dangerous/error-prone stuff, but we tell them to be explicit about their intention, so that future readers don't have to guess whether something is intentional or a bug.
To guarantee a smooth transition, I additionally propose to
Better ideas, opinions, criticism?
SimonSimon --
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Simon --
I agree 100% with your underlying statements, but somehow manage to come to the exact opposite conclusion:(1) Functions and methods are not the same. Methods that return values are not the same as those that do not.It's therefore frustrating that the only difference is the absence of a single character in defining a procedure. An absence that doesn't even trigger a syntax error if left out by mistake. An explicit `: Unit' would be far harder to overlook and near impossible to produce with a mere typo.
(2) The problem caused by this is caught quickly by the compiler due to strong typing. It doesn't impact one's ability to write robust code. (In fact, by reducing the distinction of necessarily side-effecting methods, it may even decrease one's ability to write robust code.)
Missing a character is an easy typo. Typos should be reported as syntax errors if possible, not as a type error which could well be reported far away from the code where the mistake was made. Pinpointing errors quickly will never harm your ability to write robust code.
(3) Your IDE can fix it for you, in principle, if you like to see an extra : Unit =
That's a slippery slope. "It's okay because the IDE can fix it" is a mantra common in discussing Java's syntax, yet it neatly sidesteps the fact that there's something which needs to be fixed in the first place!
(1) Functions and methods are not the same. Methods that return values are not the same as those that do not.It's therefore frustrating that the only difference is the absence of a single character in defining a procedure. An absence that doesn't even trigger a syntax error if left out by mistake. An explicit `: Unit' would be far harder to overlook and near impossible to produce with a mere typo.
--
Was it the only problem encountered by participants?
I'm just curious what was overall failure rate, that is how many attendees managed to produce some working scala code at all at the workshop?
Also, what was the 'failure mode'? Did they just forget to write = ?
Then banning procedure syntax won't help at all - people will still forget about '=' and experience the same failure to define a method.
scala> List().toSet()
res0: Boolean = false
scala> List(()).toSet()
res1: Boolean = true
https://gist.github.com/noahlz/6048606
Rex, I can confirm that my visual parsing system is different from yours. Even knowing what I was looking for, I didn't see the missing equals before the third pass :/. And I get bitten by that syntax even after 7 years of Scala, because well, I just don't see that missing equal.
I did notice the different length in # at first glance, thought, not sure what it tells.
--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Well, what you want is firmly in the "I have infinitely many different kinds of incompatible functions", which I think is a less useful view than the "I have one kind of function" view.
It's very important to allow the empty return to be assigned because otherwise you have to write all your generic code twice: once for handling empty returns, and once for non-empty returns. Ugh! Shall we write it all again if we want to return two things, and yet again for three? No thanks.
This "proc" idea is a total non-starter. I can't think of a single language that uses a different syntactic form depending on whether methods/functions/subroutines return something or not, not even Haskell.
This "proc" idea is a total non-starter. I can't think of a single language that uses a different syntactic form depending on whether methods/functions/subroutines return something or not, not even Haskell.
Scala is all about unifying concepts where applicable, and only has four class level concepts; val, var, def and type. Why on earth would we add another one that is perfectly well addressed by the def form? As Hans pointed out, you want to be able to generalise over functions even if their return type is useless. It's the same concept. Even if you paper over it in the way you suggested, this is more confusing and less simple than the status quo.
On Tue, Aug 20, 2013 at 11:00 PM, Ken Scambler <ken.sc...@gmail.com> wrote:
This "proc" idea is a total non-starter. I can't think of a single language that uses a different syntactic form depending on whether methods/functions/subroutines return something or not, not even Haskell.
Ever heard of Ada?
Scala is all about unifying concepts where applicable, and only has four class level concepts; val, var, def and type. Why on earth would we add another one that is perfectly well addressed by the def form? As Hans pointed out, you want to be able to generalise over functions even if their return type is useless. It's the same concept. Even if you paper over it in the way you suggested, this is more confusing and less simple than the status quo.
According to that line of thinking, we don't need both val and var. var can always be used in place of val.
- its own special syntax for procedures, def foo { println(1) }
- Unit-returning methods with inference, def foo = { println(1) }
- has explicit Unit-returning methods, def foo: Unit = { println(1) }
I am sure, Ceylon will pay tribute to that historical line and have 3 1/2 different keywords to distinguish these "cases". They will probably be called `effectual`, `situation` and `transformation`
Well, you might be interested to know that Ada is the standard higher-order language for avionics. The next time you fly, your life may depend on it.
What I meant is that you can take any working Scala code, replace every occurrence of "val" with "var" and it will work exactly the same if I am not mistaken. So why do we need both again?
No, I'm not suggesting that we get rid of "val." I'm just suggesting that "proc" serves a similar purpose by clearly distinguishing between a function and a procedure. If that distinction is not fundamental, then functional programming is not fundamental.
I like val Unit = (). We certainly call the value "unit" when we are reading the code. The () symbol is noisy syntactically, because parentheses already represent method calls, nesting and tupling. In a signature with lots of ([<: :])(:[[]]): () it becomes hard to stomach.
--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.