This page is no longer maintained — Please continue to the home page at www.scala-lang.org

On the scalability on functions written in Scala

11 replies
Ryan Schmitt
Joined: 2011-10-26,
User offline. Last seen 42 years 45 weeks ago.

One of the less obvious problems in many programming languages is the extendibility of functions. A classic display of this problem is the clone() function. When a function extends clone(), it usually requires to define an object by calling super.clone() to clone all of the private variables defined by the super class. A problem with this is that some lazy programmers may forget to call super.clone(), therefor preventing those important variables from cloning. Although this problem can be avoided by making sure to emphasis this in the ScalaDoc, this is not a sure fire way to stop this design problem.

                The problem is not limited to clone. If one was to make a very important program designed to manage explosives, one might want to have the ability to defuse all of the explosives at once. A deadly error comes in when the careless designer of “FooBomb” notices that he needs to add functionality to defuse(), but forgets to call super.defuse(). In this hypothetical situation, the bomb goes off.

                A simple way to stop this issue is to add a new key term. If a function uses this turn, any extension of the function must call “super.<function name>” at some point in the new function.  For this example, we’ll use “safe”.  Now, if we define “public safe defuse()”, FooBomb will not be able to run without calling super.defuse at some point in the function. For the example of clone(), we can use “public safe clone()” so the person whom extends our clone method must call super.clone(). Because of this, the extender is forced to use the method at some point. Of course, this still includes some problems. Mister rebellious coder could decide to call super.clone, but instead of defining his Object as super.clone(), he calls it without reference. Although he defeated the system, “safe” key turn would help force the coder to think about what he is doing.

                I appreciate any feedback about this idea, especially if you give me a good reason that this is a dangerous idea to implement or there is a better approach to this problem. Thank you for your time.

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: On the scalability on functions written in Scala


On Wed, Oct 26, 2011 at 7:13 PM, Ryan Schmitt <ryan [dot] l [dot] schmitt [at] gmail [dot] com> wrote:

One of the less obvious problems in many programming languages is the extendibility of functions. A classic display of this problem is the clone() function. When a function extends clone(), it usually requires to define an object by calling super.clone() to clone all of the private variables defined by the super class. A problem with this is that some lazy programmers may forget to call super.clone(), therefor preventing those important variables from cloning. Although this problem can be avoided by making sure to emphasis this in the ScalaDoc, this is not a sure fire way to stop this design problem.

                The problem is not limited to clone. If one was to make a very important program designed to manage explosives, one might want to have the ability to defuse all of the explosives at once. A deadly error comes in when the careless designer of “FooBomb” notices that he needs to add functionality to defuse(), but forgets to call super.defuse(). In this hypothetical situation, the bomb goes off.

                A simple way to stop this issue is to add a new key term. If a function uses this turn, any extension of the function must call “super.<function name>” at some point in the new function.  For this example, we’ll use “safe”.  Now, if we define “public safe defuse()”, FooBomb will not be able to run without calling super.defuse at some point in the function. For the example of clone(), we can use “public safe clone()” so the person whom extends our clone method must call super.clone(). Because of this, the extender is forced to use the method at some point. Of course, this still includes some problems. Mister rebellious coder could decide to call super.clone, but instead of defining his Object as super.clone(), he calls it without reference. Although he defeated the system, “safe” key turn would help force the coder to think about what he is doing.

                I appreciate any feedback about this idea, especially if you give me a good reason that this is a dangerous idea to implement or there is a better approach to this problem. Thank you for your time.


So you'd have the compiler track all method invocations inside the "safe" method to see if any of them calls super.method? What happens if it calls it 1+N times?

--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
Ryan Schmitt
Joined: 2011-10-26,
User offline. Last seen 42 years 45 weeks ago.
Re: On the scalability on functions written in Scala

Well, the way it could work, is to simply check if super has been called at the end of the function, in that calling an exception. At the moment, I have not thought through the full mechanic, but it should be traceable. As for your second question, in this concept, there would be no restrictions for the amount of times the super function can be called. Sorry for the lack of clarity.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: On the scalability on functions written in Scala

On Wed, Oct 26, 2011 at 15:13, Ryan Schmitt wrote:
> One of the less obvious problems in many programming languages is the
> extendibility of functions. A classic display of this problem is the clone()
> function. When a function extends clone(), it usually requires to define an
> object by calling super.clone() to clone all of the private variables
> defined by the super class. A problem with this is that some lazy
> programmers may forget to call super.clone(), therefor preventing those
> important variables from cloning. Although this problem can be avoided by
> making sure to emphasis this in the ScalaDoc, this is not a sure fire way to
> stop this design problem.
>
>                 The problem is not limited to clone. If one was to make a
> very important program designed to manage explosives, one might want to have
> the ability to defuse all of the explosives at once. A deadly error comes in
> when the careless designer of “FooBomb” notices that he needs to add
> functionality to defuse(), but forgets to call super.defuse(). In this
> hypothetical situation, the bomb goes off.
>
>                 A simple way to stop this issue is to add a new key term. If
> a function uses this turn, any extension of the function must call
> “super.” at some point in the new function.  For this
> example, we’ll use “safe”.  Now, if we define “public safe defuse()”,
> FooBomb will not be able to run without calling super.defuse at some point
> in the function. For the example of clone(), we can use “public safe
> clone()” so the person whom extends our clone method must call
> super.clone(). Because of this, the extender is forced to use the method at
> some point. Of course, this still includes some problems. Mister rebellious
> coder could decide to call super.clone, but instead of defining his Object
> as super.clone(), he calls it without reference. Although he defeated the
> system, “safe” key turn would help force the coder to think about what he is
> doing.
>
>                 I appreciate any feedback about this idea, especially if you
> give me a good reason that this is a dangerous idea to implement or there is
> a better approach to this problem. Thank you for your time.

You can always adopt the suggestion of the functional crowd: don't
extend classes, ever.

Though, actually, even Uncle Bob (Clean Code) or Joshua Block
(Effective Java) have more or less the same suggestion: implement
interfaces, extend abstract classes.

Ryan Schmitt
Joined: 2011-10-26,
User offline. Last seen 42 years 45 weeks ago.
Re: On the scalability on functions written in Scala
Although this is currently the best solution, it prevents the flexibility needed for many modern programs. If you write a complex function that is needed for all members of a parent class, allowing it to be overridden may be needed to add features for the newly coded child. One of the major motivations for me is the clone method, which is rarely marked final.
The root reason that so many people pick up concept of marking all functions as either abstract or final is the lack in existence of the previously mentioned feature.
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: On the scalability on functions written in Scala

On Wed, Oct 26, 2011 at 20:24, Ryan Schmitt wrote:
> Although this is currently the best solution, it prevents
> the flexibility needed for many modern programs. If you write a complex

Not at all true.

> function that is needed for all members of a parent class, allowing it to
> be overridden may be needed to add features for the newly coded child. One
> of the major motivations for me is the clone method, which is rarely marked
> final.

> The root reason that so many people pick up concept of marking all functions
> as either abstract or final is the lack in existence of the
> previously mentioned feature.

Baseless and not true. The reason for that is that it makes programs
easier to read, easier to reason about, easier to understand, easier
to change and more robust. Pick up Effective Java and Joshua Boch will
explain it. Go watch the videos on http://www.cleancoders.com/ and
Robert Martin will explain the same thing in a completely different
manner.

Or don't... really, this is something Java experts, Object Oriented
Programming experts *and* Functional Programming experts all agree on.
That shouldn't prevent anyone from disagreeing, but if you are going
to do so, at least do it with some basis.

Ryan Schmitt
Joined: 2011-10-26,
User offline. Last seen 42 years 45 weeks ago.
Re: On the scalability on functions written in Scala
You have yet to provide a feasible replacement when dealing with clone() (which I use as a repeated example for lack of a more known one). I do not know of anyone who recommends marking clone() as final.What I am not saying is that said modifier needed for every situation, but there are defiantly some times where it would help. For example, a class named Human. This hypothetical class contains a function called grow(). Lets say a child class NewHuman contains a couple more body parts than Human. In the current system, one would have to make Human.grow() abstract or empty in order to allow NewHuman.grow() to have full functionality. Along with this, we would have to force all other children of Human to create their own grow function. Not only is this approach inflexible by preventing the growth of Human's private objects, but it also requires each child to rewrite part of their grow method each time Human has a new grow-able object.
In conclusion, I seek a better solution, but I have not found one in my research. I would love for someone to prove me wrong and show me a better way to approach methods.
Ryan Schmitt
Joined: 2011-10-26,
User offline. Last seen 42 years 45 weeks ago.
Re: On the scalability on functions written in Scala

I have rethought through the concept of allowing the child function to call the super function multiple times and determined what it shouldn't be allowed.

runaro
Joined: 2009-11-13,
User offline. Last seen 32 weeks 2 days ago.
Re: On the scalability on functions written in Scala
There is no design problem here:

def clone = this

Q.E.D.

Bernd Johannes
Joined: 2011-01-28,
User offline. Last seen 42 years 45 weeks ago.
Re: On the scalability on functions written in Scala

Hi Ryan,

tracking all the possible execution paths of a given function could get very
complex or even impossible.

While I am indifferent at the idea itself I would opt for a more strict
interpretation: if a function is tagged this way I would have the compiler
produce an implicit super.foo() call as the very first operation and disallow
explicit super.foo() calls in the body itself.
So the sequence of events is strictly defined and cannot be altered. Anything
else seems not "safe" (= predictable enough) to me.

Greetings
Bernd

Am Mittwoch, 26. Oktober 2011, 19:13:47 schrieb Ryan Schmitt:
> One of the less obvious problems in many programming languages is the
> extendibility of functions. A classic display of this problem is the
> clone() function. When a function extends clone(), it usually requires to
> define an object by calling super.clone() to clone all of the private
> variables defined by the super class. A problem with this is that some lazy
> programmers may forget to call super.clone(), therefor preventing those
> important variables from cloning. Although this problem can be avoided by
> making sure to emphasis this in the ScalaDoc, this is not a sure fire way
> to stop this design problem.
>
> The problem is not limited to clone. If one was to make a
> very important program designed to manage explosives, one might want to
> have the ability to defuse all of the explosives at once. A deadly error
> comes in when the careless designer of “FooBomb” notices that he needs to
> add functionality to defuse(), but forgets to call super.defuse(). In this
> hypothetical situation, the bomb goes off.
>
> A simple way to stop this issue is to add a new key term.
> If a function uses this turn, any extension of the function must call
> “super.” at some point in the new function. For this
> example, we’ll use “safe”. Now, if we define “public safe defuse()”,
> FooBomb will not be able to run without calling super.defuse at some point
> in the function. For the example of clone(), we can use “public safe
> clone()” so the person whom extends our clone method must call
> super.clone(). Because of this, the extender is forced to use the method at
> some point. Of course, this still includes some problems. Mister rebellious
> coder could decide to call super.clone, but instead of defining his Object
> as super.clone(), he calls it without reference. Although he defeated the
> system, “safe” key turn would help force the coder to think about what he
> is doing.
>
> I appreciate any feedback about this idea, especially if
> you give me a good reason that this is a dangerous idea to implement or
> there is a better approach to this problem. Thank you for your time.

Ryan Schmitt
Joined: 2011-10-26,
User offline. Last seen 42 years 45 weeks ago.
Re: On the scalability on functions written in Scala

That clone method only works for pure functional programming. This does not return a deep-copy.

Ryan Schmitt
Joined: 2011-10-26,
User offline. Last seen 42 years 45 weeks ago.
Re: On the scalability on functions written in Scala

I actually agree with your opinion, allowing for it to be called at any point during the function is idealistic at best.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland