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

Re: Summary(2) - things to drop

7 replies
GatesDA
Joined: 2009-01-08,
User offline. Last seen 3 years 7 weeks ago.

Ricky Clarkson wrote:
> My own thoughts are to follow what Scheme, Python and C# do - without any
> parentheses, a method/procedure/function name is just a reference to that
> method/procedure/function; it should only be invocable with parentheses.
> And then the trailing _ syntax can be dropped, and HOFs will live happily
> ever after. Ahem.

Public fields are safe to use in Scala because you can switch between
val/var and def without breaking client code. For example:

//Old version
class Person {
val fullName: String = . . .
}

//New version
class Person {
val firstName: String = . . .
val lastName: String = . . .
def fullName = firstName + " " + lastName
}

By convention, parentheses are only used when no-argument functions have
side effects, and thus can't be replaced with a field anyway.

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Summary(2) - things to drop
On Thu, Jan 8, 2009 at 4:06 PM, GatesDA <GatesDA [at] gmail [dot] com> wrote:


Ricky Clarkson wrote:
> My own thoughts are to follow what Scheme, Python and C# do - without any
> parentheses, a method/procedure/function name is just a reference to that
> method/procedure/function; it should only be invocable with parentheses.
> And then the trailing _ syntax can be dropped, and HOFs will live happily
> ever after.  Ahem.

Public fields are safe to use in Scala because you can switch between
val/var and def without breaking client code.  For example:

This isn't true. You can switch between val and def while allowing some client code compiled against the old version to continue to run but be subtly broken, and the same code will fail to compile if you try to recompile the source. vals have a special place in Scala's type system as stable identifiers. Replacing a val with a def affects client code.
ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: Summary(2) - things to drop

O/H GatesDA έγραψε:
> Public fields are safe to use in Scala because you can switch between
> val/var and def without breaking client code.
>
>
I guess such a change would at least require recompilation of client
code? Or even that is not necessary?

GatesDA
Joined: 2009-01-08,
User offline. Last seen 3 years 7 weeks ago.
Re: Summary(2) - things to drop

David MacIver wrote:
>
> On Thu, Jan 8, 2009 at 4:06 PM, GatesDA wrote:
>> Public fields are safe to use in Scala because you can switch between
>> val/var and def without breaking client code. For example:
>
> This isn't true. You can switch between val and def while allowing some
> client code compiled against the old version to continue to run but be
> subtly broken, and the same code will fail to compile if you try to
> recompile the source. vals have a special place in Scala's type system as
> stable identifiers. Replacing a val with a def affects client code.

Thanks for pointing that out; I had assumed that an implicitly generated def
would behave the same as an explicit one. Compiling with -print indeed
shows automatically generated accessor defs as . Could
we get a code sample showing the distinction and where this changes client
behavior?

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: Summary(2) - things to drop
Changing it from a val to a def can cause assumptions to break.

scala> class X { val x = 5 }
defined class X

scala> assert new X().x == new X().x
<console>:1: error: ';' expected but 'new' found.
       assert new X().x == new X().x
              ^

scala> assert(new X().x == new X().x)

scala> class X { def x = (Math.random*100).toInt }
defined class X

scala> assert(new X().x == new X().x)
java.lang.AssertionError: assertion failed
        at scala.Predef$.assert(Predef.scala:87)
        at .<init>(<console>:6)
        at .<clinit>(<console>)
        at RequestResult$.<init>(<console>:3)
        at RequestResult$.<clinit>(<console>)
        at RequestResult$result(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.j..

2009/1/8 GatesDA <GatesDA [at] gmail [dot] com>


David MacIver wrote:
>
> On Thu, Jan 8, 2009 at 4:06 PM, GatesDA <GatesDA [at] gmail [dot] com> wrote:
>> Public fields are safe to use in Scala because you can switch between
>> val/var and def without breaking client code.  For example:
>
> This isn't true. You can switch between val and def while allowing some
> client code compiled against the old version to continue to run but be
> subtly broken, and the same code will fail to compile if you try to
> recompile the source. vals have a special place in Scala's type system as
> stable identifiers. Replacing a val with a def affects client code.

Thanks for pointing that out; I had assumed that an implicitly generated def
would behave the same as an explicit one.  Compiling with -print indeed
shows automatically generated accessor defs as <stable> <accessor>.  Could
we get a code sample showing the distinction and where this changes client
behavior?
--
View this message in context: http://www.nabble.com/Summary%282%29---things-to-drop-tp20665104p21360434.html
Sent from the Scala - Debate mailing list archive at Nabble.com.


GatesDA
Joined: 2009-01-08,
User offline. Last seen 3 years 7 weeks ago.
Re: Summary(2) - things to drop

Ricky Clarkson wrote:
>
> Changing it from a val to a def can cause assumptions to break.
>
> scala> class X { val x = 5 }
> defined class X
>
> scala> assert new X().x == new X().x
> :1: error: ';' expected but 'new' found.
> assert new X().x == new X().x
> ^
>
> scala> assert(new X().x == new X().x)
>
> scala> class X { def x = (Math.random*100).toInt }
> defined class X
>
> scala> assert(new X().x == new X().x)
> java.lang.AssertionError: assertion failed
> at scala.Predef$.assert(Predef.scala:87)
> at .(:6)
> at .()
> at RequestResult$.(:3)
> at RequestResult$.()
> at RequestResult$result()
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.j..

The assumptions are broken here not by the change from val to def, but by
the change in behavior. A behavioral change like this ought to break
assumptions and require changing client code, but nothing in this example
would change if the original class X had been "class X { def x = 5 }". I
was looking for an example to show the importance of vals being stable
identifiers.

Tillmann Rendel
Joined: 2009-01-09,
User offline. Last seen 42 years 45 weeks ago.
Re: Summary(2) - things to drop

GatesDA wrote:
> I was looking for an example to show the importance of vals being stable identifiers.

Only stable identifiers can occur in types.

scala> class A { class B }
defined class A

scala> class C { val a : A = new A }
defined class C

scala> class Client(val c : C) { val x : c.a.B = new c.a.B }
defined class Client

scala> class C { def a : A = new A }
defined class C

scala> class Client(val c : C) { val x : c.a.B = new c.a.B }
:6: error: stable identifier required, but Client.this.c.a
found.
class Client(val c : C) { val x : c.a.B = new c.a.B }
^
:6: error: stable identifier required, but Client.this.c.a
found.
class Client(val c : C) { val x : c.a.B = new c.a.B }

^

Note that the path-dependent type "c.a.B" in Client contains the stable
identifiers c and a, so making c unstable is a bad idea.

Tillmann

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Summary(2) - things to drop
On Thu, Jan 8, 2009 at 8:36 PM, GatesDA <GatesDA [at] gmail [dot] com> wrote:


David MacIver wrote:
>
> On Thu, Jan 8, 2009 at 4:06 PM, GatesDA <GatesDA [at] gmail [dot] com> wrote:
>> Public fields are safe to use in Scala because you can switch between
>> val/var and def without breaking client code.  For example:
>
> This isn't true. You can switch between val and def while allowing some
> client code compiled against the old version to continue to run but be
> subtly broken, and the same code will fail to compile if you try to
> recompile the source. vals have a special place in Scala's type system as
> stable identifiers. Replacing a val with a def affects client code.

Thanks for pointing that out; I had assumed that an implicitly generated def
would behave the same as an explicit one.  Compiling with -print indeed
shows automatically generated accessor defs as <stable> <accessor>.  Could
we get a code sample showing the distinction and where this changes client
behavior?

The primary example is with type members.  Suppose we have something like this:

trait Foo{
  type T;
  var t : T;
}

Now we have val foo : Foo = new Foo { type T = String; var t = "foo"; }

it is valid to do

val bar = foo.t
foo.t = bar;

But if we change foo to a var it is not, because we could insert the following:

val bar = foo.t
foo = new Foo { type T = Int; var t = 42; }
foo.t = bar;

So in the third line we'd be assigning a String to something that requires an Int.

This is a bit of a contrived example obviously, but there are plenty of cases where it actually matters.

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