|
View:
New views
18 Messages
—
Rating Filter:
Alert me
|
|
|
override method parameter default value specification must not be allowedHi,
while Scala 2.8 is not yet released, I have an addition to SID 1 (named and default args; simplification): disallow default parameter value specfication in override method. I believe, there are no reasons of specifying default value in override method. I seems to be cool, but is is useless. And also, sometimes it is confusing. === abstract class A { def connect(port: Int = 12345) } class B extends A { override def connect(port: Int = 99999) { println("connecting to " + port); } } val a: A = new B a.connect() === "connects" to 99999. However, I expect port value 12345. Code above should fail to be compiled. In the specification, sentence "The subclass can also override default arguments and add new ones to parameters which don’t have a default in the superclass." should be replaced with "The overriding method cannot specify any default method parameters, default values from the base class method are inherited". This change will make specification simpler. S. |
|
|
Re: override method parameter default value specification must not be allowedOn Sunday 08 November 2009 16:28:27 Stepan Koltsov wrote:
> Hi, > > while Scala 2.8 is not yet released, I have an addition to SID 1 > (named and default args; simplification): disallow default parameter > value specfication in override method. > > I believe, there are no reasons of specifying default value in > override method. I seems to be cool, but is is useless. > > And also, sometimes it is confusing. > > === > abstract class A { > def connect(port: Int = 12345) > } > > class B extends A { > override def connect(port: Int = 99999) { println("connecting to " > + port); } > } > > val a: A = new B > a.connect() > === > > "connects" to 99999. However, I expect port value 12345. > > Code above should fail to be compiled. Hm.. I would expect 99999 as long as new B is creating. Do you say 'new B' contract (the way an instance is created) must depend on left side? And, after all, what is that big difference in comparison with val o def overriding? |
|
|
Re: override method parameter default value specification must not be allowedIMHO it's always better to have a capability and not need it than to
need a capability and not have it. Linas. On Sun, 2009-11-08 at 16:28 +0300, Stepan Koltsov wrote: > Hi, > > while Scala 2.8 is not yet released, I have an addition to SID 1 > (named and default args; simplification): disallow default parameter > value specfication in override method. > > I believe, there are no reasons of specifying default value in > override method. I seems to be cool, but is is useless. > > And also, sometimes it is confusing. > > === > abstract class A { > def connect(port: Int = 12345) > } > > class B extends A { > override def connect(port: Int = 99999) { println("connecting to " > + port); } > } > > val a: A = new B > a.connect() > === > > "connects" to 99999. However, I expect port value 12345. > > Code above should fail to be compiled. > > In the specification, sentence > > "The subclass can also override default arguments and add new ones to > parameters which don’t have a default in the superclass." > > should be replaced with > > "The overriding method cannot specify any default method parameters, > default values from the base class method are inherited". > > This change will make specification simpler. > > S. |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, Nov 8, 2009 at 18:16, Andrew Gaydenko <a@...> wrote:
>> And also, sometimes it is confusing. >> >> === >> abstract class A { >> def connect(port: Int = 12345) >> } >> >> class B extends A { >> override def connect(port: Int = 99999) { println("connecting to " >> + port); } >> } >> >> val a: A = new B >> a.connect() >> === >> >> "connects" to 99999. However, I expect port value 12345. >> >> Code above should fail to be compiled. > > Hm.. I would expect 99999 as long as new B is creating. Do you say 'new B' > contract (the way an instance is created) must depend on left side? Yes, I know it is 99999, because I know that I called B instance (although I had to read spec). However, I meant the case where type of "a" variable is not known to be B at the call site. === val a: A = someFunc() a.connect() === > And, after all, what is that big difference in comparison with val o def > overriding? Method parameter belongs to method of class, val belongs to class. Vals and method parameter defaults are very different things. S. |
|
|
Re: override method parameter default value specification must not be allowedOn 08/11/2009 16:39, Stepan Koltsov wrote:
> On Sun, Nov 8, 2009 at 18:16, Andrew Gaydenko<a@...> wrote: > === > val a: A = someFunc() > a.connect() > === Contrary to what you think, I believe that this is the perfect use case for default parameter value override. With or without default parameter override, you can change the port value, for example: override def connect(port: Int) { //ignore the arg and connect to my default port, because it's my //specifity of being a B println("connecting to " + myDefaultPort) } If you use a B for your A, it means that you want the specialized behaviour that comes with B, and perhaps it has nothing to do with the parent behaviour, but that's nothing new. -- Francois Armand |
|
|
Re: override method parameter default value specification must not be allowedOn Sunday 08 November 2009 18:39:10 Stepan Koltsov wrote:
> Yes, I know it is 99999, because I know that I called B instance > (although I had to read spec). However, I meant the case where type of > "a" variable is not known to be B at the call site. > > === > val a: A = someFunc() > a.connect() > === I think it's matter of taste. To my mind, "someFunc() knows itself" is more expectable. > > > And, after all, what is that big difference in comparison with val o def > > overriding? > > Method parameter belongs to method of class, val belongs to class. > Vals and method parameter defaults are very different things. > > S. > Rephrasing: method parameter belongs to method of class, method belongs to class, i.e. method parameter belongs to class in total :-) |
|
|
Re: override method parameter default value specification must not be allowedThe argument that this kind of overriding is broken trivially
generalises to "subtyping is broken". I might agree with that, but given Scala, a language that supports subtyping, this kind of overriding is no more harmful than any other. 2009/11/8 Andrew Gaydenko <a@...>: > On Sunday 08 November 2009 18:39:10 Stepan Koltsov wrote: >> Yes, I know it is 99999, because I know that I called B instance >> (although I had to read spec). However, I meant the case where type of >> "a" variable is not known to be B at the call site. >> >> === >> val a: A = someFunc() >> a.connect() >> === > > I think it's matter of taste. To my mind, "someFunc() knows itself" is more > expectable. > >> >> > And, after all, what is that big difference in comparison with val o def >> > overriding? >> >> Method parameter belongs to method of class, val belongs to class. >> Vals and method parameter defaults are very different things. >> >> S. >> > > Rephrasing: method parameter belongs to method of class, method belongs to > class, i.e. method parameter belongs to class in total :-) > -- Ricky Clarkson Java and Scala Programmer, AD Holdings +44 1565 770804 Skype: ricky_clarkson Google Talk: ricky.clarkson@... Google Wave: ricky.clarkson@... |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, Nov 8, 2009 at 18:18, Linas <vejobrolis@...> wrote:
> IMHO it's always better to have a capability and not need it than to > need a capability and not have it. First, possibility to override default values makes specification larger. Language must be as small as possible. It cannot (and must not) contain all possible features invented in 50 years of programming. Figuratively speaking, ideal language has 100 pages specification and all the best features that can be specified in that 100 pages. Second, current specification restricts method overloading capabilities: === object A { def f(x: Int = 1) = 1 def f(x: String, z: Int = 2) = 1 } === This is not possible because of JVM bytecode generation scheme (name of default parameter value generator method). Third (I said this earlier), current spec makes larger and slower bytecode. === def connect(host = "localhost", port = 1234) = ... connect() === compiled to: === def connect(Strng, Int) = ... def connect$default$1 = "localhost" def connect$default$2(String) = 1234 obj.connect(obj.connect$default$1, obj.connect$default$2(obj.connect$default$1)). === Size of both classes (caller and callee) increased by size of two string constants"connect$default$1" and "connect$default$2"), caller has two extra method call, calee has extra method, JVM consumes more memory, inlines fewer and so on. Alternative compilation scheme (that was in the first version of specification) compiles "connect" method as: === def connect(String, int) = ... def connect$params(String, int, parametersMask: Int) = { setup parameters; connect(p1, p2); } obj.connect$params(null, 0, 0); === But it does not allow (useless and weird) parameter default value overriding. S. > On Sun, 2009-11-08 at 16:28 +0300, Stepan Koltsov wrote: >> Hi, >> >> while Scala 2.8 is not yet released, I have an addition to SID 1 >> (named and default args; simplification): disallow default parameter >> value specfication in override method. >> >> I believe, there are no reasons of specifying default value in >> override method. I seems to be cool, but is is useless. >> >> And also, sometimes it is confusing. >> >> === >> abstract class A { >> def connect(port: Int = 12345) >> } >> >> class B extends A { >> override def connect(port: Int = 99999) { println("connecting to " >> + port); } >> } >> >> val a: A = new B >> a.connect() >> === >> >> "connects" to 99999. However, I expect port value 12345. >> >> Code above should fail to be compiled. >> >> In the specification, sentence >> >> "The subclass can also override default arguments and add new ones to >> parameters which don’t have a default in the superclass." >> >> should be replaced with >> >> "The overriding method cannot specify any default method parameters, >> default values from the base class method are inherited". >> >> This change will make specification simpler. >> >> S. > > > |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, Nov 8, 2009 at 18:56, Andrew Gaydenko <a@...> wrote:
> On Sunday 08 November 2009 18:39:10 Stepan Koltsov wrote: >> Yes, I know it is 99999, because I know that I called B instance >> (although I had to read spec). However, I meant the case where type of >> "a" variable is not known to be B at the call site. >> >> === >> val a: A = someFunc() >> a.connect() >> === > > I think it's matter of taste. To my mind, "someFunc() knows itself" is more > expectable. Actually, I doubt someone's really going to override parameter default value (as it makes program harder to understand). I have an example, where parameter default value overriding maybe useful (and later I'll show that it is bad use). === trait DbConnector { def conect(host: String, port: Int = 0) // port is database specific } class MysqlConnector { override def connect(host: String, port: Int = 3306) // default port for MySQL } class PostgresqlConnector { override def connect(host: String, port: Int = 5432) // default port for PostgreSQL } === This seems to be a good example of parameter default value overriding. But it is not, because I cannot write a class: === class MagicDbConnectorProxy { // that delegates to vendor-specific override def connect(host: String, port: Int = ???) // what value should I use? } === When parameter default value depends on class type, special marker (for example, zero) should be used to indicate the default value, like this: === trait DbConnector { def conect(host: String, port: Int = 0) // port is database specific } class MysqlConnector { override def connect(host: String, port: Int) { if (port == 0) port = 3306; ... } } === This is how code should be written even if parameter default value can be overriden. IMHO. S. |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, Nov 8, 2009 at 18:56, Andrew Gaydenko <a@...> wrote:
>> > And, after all, what is that big difference in comparison with val o def >> > overriding? >> >> Method parameter belongs to method of class, val belongs to class. >> Vals and method parameter defaults are very different things. > > Rephrasing: method parameter belongs to method of class, method belongs to > class, i.e. method parameter belongs to class in total :-) ... and they both belong to universe. But you've asked what is the difference, and I explained. S. |
|
|
Re: override method parameter default value specification must not be allowed> The argument that this kind of overriding is broken trivially
> generalises to "subtyping is broken". I just wanted to write the same. For the same reason one might argue ``if `a' is declared to be of type `A', then it is not desired to behave like a `B'." If you agree with that, you probably don't like subtyping and polymorphism at all ... I think it is a good thing that default args are overridable. This is perfectly in line with polymorphism. > I might agree with that. As my programming experience grew throught the years, I discovered that I more and more favor composition over inheritance. Complex class hierarchies may be impressive to others---in general, they make me suspicious. :) Nonetheless, I'd be interested to hear the reasons, in a sentence or two, why you are spectical about subtyping as a whole. ---Ph |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, 2009-11-08 at 19:21 +0300, Stepan Koltsov wrote:
> On Sun, Nov 8, 2009 at 18:18, Linas <vejobrolis@...> wrote: > > IMHO it's always better to have a capability and not need it than to > > need a capability and not have it. > > > First, possibility to override default values makes specification larger. > > Language must be as small as possible. It cannot (and must not) > contain all possible features invented in 50 years of programming. > > Figuratively speaking, ideal language has 100 pages specification and > all the best features that can be specified in that 100 pages. Ideally I would replace dedicated XML treatment with a library DSL and objects with java style statics (since static scope is the only thing I use them for). Would take many pages out of specification. But someone found those usefull. > Second, current specification restricts method overloading capabilities: > > === > object A { > def f(x: Int = 1) = 1 > def f(x: String, z: Int = 2) = 1 > } > === > > This is not possible because of JVM bytecode generation scheme (name > of default parameter value generator method). > > Third (I said this earlier), current spec makes larger and slower bytecode. > > === > def connect(host = "localhost", port = 1234) = ... > > connect() > === > > compiled to: > > === > def connect(Strng, Int) = ... > def connect$default$1 = "localhost" > def connect$default$2(String) = 1234 > > obj.connect(obj.connect$default$1, > obj.connect$default$2(obj.connect$default$1)). > === > > Size of both classes (caller and callee) increased by size of two > string constants"connect$default$1" and "connect$default$2"), caller > has two extra method call, calee has extra method, JVM consumes more > memory, inlines fewer and so on. > > > Alternative compilation scheme (that was in the first version of > specification) compiles "connect" method as: > > === > def connect(String, int) = ... > def connect$params(String, int, parametersMask: Int) = > { setup parameters; connect(p1, p2); } > > obj.connect$params(null, 0, 0); > === Using the "object A" above as a source why not simply explode everything into overloaded methods when compiling? def f(x : Int) = ... def f() = { f(1); } def f(x : String, z : Int) = .. def f(x : String) = { f(x, 2); } This allows overloading and default value overriding at the same time. > But it does not allow (useless and weird) parameter default value overriding. > > S. > > > > On Sun, 2009-11-08 at 16:28 +0300, Stepan Koltsov wrote: > >> Hi, > >> > >> while Scala 2.8 is not yet released, I have an addition to SID 1 > >> (named and default args; simplification): disallow default parameter > >> value specfication in override method. > >> > >> I believe, there are no reasons of specifying default value in > >> override method. I seems to be cool, but is is useless. > >> > >> And also, sometimes it is confusing. > >> > >> === > >> abstract class A { > >> def connect(port: Int = 12345) > >> } > >> > >> class B extends A { > >> override def connect(port: Int = 99999) { println("connecting to " > >> + port); } > >> } > >> > >> val a: A = new B > >> a.connect() > >> === > >> > >> "connects" to 99999. However, I expect port value 12345. > >> > >> Code above should fail to be compiled. > >> > >> In the specification, sentence > >> > >> "The subclass can also override default arguments and add new ones to > >> parameters which don’t have a default in the superclass." > >> > >> should be replaced with > >> > >> "The overriding method cannot specify any default method parameters, > >> default values from the base class method are inherited". > >> > >> This change will make specification simpler. > >> > >> S. > > > > > > |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, Nov 8, 2009 at 20:07, Linas <vejobrolis@...> wrote:
> On Sun, 2009-11-08 at 19:21 +0300, Stepan Koltsov wrote: >> On Sun, Nov 8, 2009 at 18:18, Linas <vejobrolis@...> wrote: >> > IMHO it's always better to have a capability and not need it than to >> > need a capability and not have it. >> >> >> First, possibility to override default values makes specification larger. >> >> Language must be as small as possible. It cannot (and must not) >> contain all possible features invented in 50 years of programming. >> >> Figuratively speaking, ideal language has 100 pages specification and >> all the best features that can be specified in that 100 pages. > > Ideally I would replace dedicated XML treatment with a library DSL and > objects with java style statics (since static scope is the only thing I > use them for). Would take many pages out of specification. But someone > found those usefull. I don't like XML in Scala language too (although I use it). I don't understand what are you proposing. AFAIU, Scala language cannot be used as a good DSL for XML: === elem("html") { elem("body", "background" -> "red") { text("hello") } } === You meant this? It is too verbose. >> Second, current specification restricts method overloading capabilities: >> >> === >> object A { >> def f(x: Int = 1) = 1 >> def f(x: String, z: Int = 2) = 1 >> } >> === >> >> This is not possible because of JVM bytecode generation scheme (name >> of default parameter value generator method). >> > > > Using the "object A" above as a source why not simply explode everything > into overloaded methods when compiling? > > def f(x : Int) = ... > def f() = { f(1); } > def f(x : String, z : Int) = .. > def f(x : String) = { f(x, 2); } > > This allows overloading and default value overriding at the same time. Avoiding X is always a workaround of any problem of X (X = parameter default value) S. |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, 2009-11-08 at 20:25 +0300, Stepan Koltsov wrote:
... > >> > >> Figuratively speaking, ideal language has 100 pages specification and > >> all the best features that can be specified in that 100 pages. > > > > Ideally I would replace dedicated XML treatment with a library DSL and > > objects with java style statics (since static scope is the only thing I > > use them for). Would take many pages out of specification. But someone > > found those usefull. > > I don't like XML in Scala language too (although I use it). > > I don't understand what are you proposing. AFAIU, Scala language > cannot be used as a good DSL for XML: > > === > elem("html") { > elem("body", "background" -> "red") { > text("hello") > } > } > === > > You meant this? It is too verbose. I was trying to say, that everyone has different ideas on what should go into language, and what should stay out. Nevermind, not a very important topic. > > >> Second, current specification restricts method overloading capabilities: > >> > >> === > >> object A { > >> def f(x: Int = 1) = 1 > >> def f(x: String, z: Int = 2) = 1 > >> } > >> === > >> > >> This is not possible because of JVM bytecode generation scheme (name > >> of default parameter value generator method). > >> > > > > > > Using the "object A" above as a source why not simply explode everything > > into overloaded methods when compiling? > > > > def f(x : Int) = ... > > def f() = { f(1); } > > def f(x : String, z : Int) = .. > > def f(x : String) = { f(x, 2); } > > > > This allows overloading and default value overriding at the same time. > > Avoiding X is always a workaround of any problem of X (X = parameter > default value) I meant, that compiler should do the explosion. You write code with parameter default values and compiler explodes it into a set of overloaded methods. Anyway, bad idea.. This would work badly with named arguments. For number X of default arguments, number of methods after explosion would be X! . Looking at your previous email another approach may work: === def connect(String, int) = ... def connect$params(String, int, parametersMask: Int) = { setup parameters; connect(p1, p2); } obj.connect$params(null, 0, 0); === "setup parameters" could take default values from a set of generated methods where each would provide a default value for one parameter. This would keep a number of generated methods low, allow named arguments, overloading and overriding (override generated method for overriden parameter). > S. Linas. |
|
|
Re: override method parameter default value specification must not be allowedOn Sun, Nov 8, 2009 at 17:34, Stepan Koltsov <stepan.koltsov@...> wrote:
Right, we don't have abstract defaults right now, but you can do the following, which is also a good example why defaults should be inherited. trait DbConn { private val defaultPort: Int def connect(host: String, port: Int = defaultPort) } class MysqlConn extends DbConn { private val defaultPort = 3306 def connect(host: String, port: Int) { ...} // has the right default } class PostgresqlConn extends DbConn { private val defaultPort = 5432 def connect(host: String, port: Int) { ...} // has the right default } Another example why I think dynamic lookup of defaults is useful: class Phone { def call(to: Number, encrypt: Boolean = false) = { ... } } class CIAPhone extends Phone { def call(to: Number, encrypt: Boolean = true) = super.call(to, encrypt) } def callObama(phone: Phone) { phone.call(obama) } val michelle = new Phone val cia = new CIAPhone callObama(michelle) // not encrypted callObama(cia) // encrypted Lukas
|
|
|
Re: override method parameter default value specification must not be allowedOn Mon, Nov 9, 2009 at 14:12, Lukas Rytz <lukas.rytz@...> wrote:
>> >> Actually, I doubt someone's really going to override parameter default >> value (as it makes program harder to understand). >> >> I have an example, where parameter default value overriding maybe >> useful (and later I'll show that it is bad use). >> >> === >> trait DbConnector { >> def conect(host: String, port: Int = 0) // port is database specific >> } >> >> class MysqlConnector { >> override def connect(host: String, port: Int = 3306) // default port for >> MySQL >> } >> >> class PostgresqlConnector { >> override def connect(host: String, port: Int = 5432) // default port >> for PostgreSQL >> } >> === >> >> This seems to be a good example of parameter default value overriding. >> But it is not, because I cannot write a class: >> >> === >> class MagicDbConnectorProxy { // that delegates to vendor-specific >> override def connect(host: String, port: Int = ???) // what value >> should I use? >> } >> === > > > Right, we don't have abstract defaults right now, but you can do the > following, > which is also a good example why defaults should be inherited. > > trait DbConn { > private val defaultPort: Int > def connect(host: String, port: Int = defaultPort) > } > > class MysqlConn extends DbConn { > private val defaultPort = 3306 > def connect(host: String, port: Int) { ...} // has the right default > } > > class PostgresqlConn extends DbConn { > private val defaultPort = 5432 > def connect(host: String, port: Int) { ...} // has the right default > } This is a good example of _how_ defaults should be overriden if someone really want it. It solves the problem I described: class MagicProxy extends DbConn { def connect(host: String, port: Int) { val proxyTarget = ... val targetPort = if (port == 0) proxyTarget.defaultPort else port proxyTarget.connect(host, targetPort) } } S. |
|
|
Re: override method parameter default value specification must not be allowedOn Mon, Nov 9, 2009 at 5:12 AM, Lukas Rytz <lukas.rytz@...> wrote:
You mean 'protected val', right? |
|
|
Re: override method parameter default value specification must not be allowedOn Mon, Nov 9, 2009 at 16:41, Nils Kilden-Pedersen <nilskp@...> wrote:
yeah :) i didn't compile the example. |
| Free embeddable forum powered by Nabble | Forum Help |