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

Companion object implicitly imported?

6 replies
Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Hello guys,

I'm toying a bit with a good concise way of defining type constraints for properties.


Now, the "problem" is:

        class Address
        {
            import Address._ //Have to import manually... not so cool...
            val city = City() //
            val street = Street()
            val zipcode = Zipcode()
        }

So, I guess I wanted to know the rationale for not implicitly importing the contents of the Companion Object...
Or am I just stupid?

FULL CODE BELOW

---BEGIN CODE---

object Foobar
{
        /**
         * SubsetOf is a box-type for a value of type T where T conforms to predicate p
         */
        sealed class SubsetOf[T](p : (T) => boolean)
        {
            protected var value : Option[T] = None

            def validate(t : T) : boolean = p(t)
            def apply() : Option[T] = value
            def update(t:T) : Unit = if ( validate(t) ) value = Some(t)
        }

        /**
         * SubsetBuilder is responsible for constructing instances of SubsetOf:s given the predicate p
         */
        abstract class SubsetBuilder[T](p : (T) => boolean)
        {
            def apply() : SubsetOf[T] = new SubsetOf[T](p)
            def as_:(t:T) : Option[T] = if( p(t) ) Some(t) else None
        }

        /**
         * some is a DSL class to improve syntax for constructing SubsetOfs
         */
        abstract class some[T](okf : (T) => boolean) extends SubsetBuilder[T](okf)


        /**
         * Address is just a POC and demo
         */
        class Address
        {
            import Address._
            val city = City()
            val street = Street()
            val zipcode = Zipcode()
        }

        object Address
        {
            object City extends some[String](_.length > 0)
            object Street extends some[String](!_.isEmpty)
            object Zipcode extends some[String](_.matches("^\\d{5}$"))
        }

        def main(a : Array[String]) : Unit = {
            val a = new Address
            for(b <- "foobar" as_: Address.Street ) a.street() = b
            println(a.street())
        }
    }

---END CODE---

--
Viktor Klang
Scala Loudmouth
Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Companion object implicitly imported?

This has puzzled me in the past, too. Particularly given the sentence
in Programming in Scala in section 4.3 - "A class and its companion
object can access each other's private members."

If we don't want to share members with our companions automatically,
isn't that what private[this] is for?

Kris

On Thu, Jul 2, 2009 at 2:22 PM, Viktor Klang wrote:
> Hello guys,
>
> I'm toying a bit with a good concise way of defining type constraints for
> properties.
>
>
> Now, the "problem" is:
>
>         class Address
>         {
>             import Address._ //Have to import manually... not so cool...
>             val city = City() //
>             val street = Street()
>             val zipcode = Zipcode()
>         }
>
> So, I guess I wanted to know the rationale for not implicitly importing the
> contents of the Companion Object...
> Or am I just stupid?
>
> FULL CODE BELOW
>
> ---BEGIN CODE---
>
> object Foobar
> {
>         /**
>          * SubsetOf is a box-type for a value of type T where T conforms to
> predicate p
>          */
>         sealed class SubsetOf[T](p : (T) => boolean)
>         {
>             protected var value : Option[T] = None
>
>             def validate(t : T) : boolean = p(t)
>             def apply() : Option[T] = value
>             def update(t:T) : Unit = if ( validate(t) ) value = Some(t)
>         }
>
>         /**
>          * SubsetBuilder is responsible for constructing instances of
> SubsetOf:s given the predicate p
>          */
>         abstract class SubsetBuilder[T](p : (T) => boolean)
>         {
>             def apply() : SubsetOf[T] = new SubsetOf[T](p)
>             def as_:(t:T) : Option[T] = if( p(t) ) Some(t) else None
>         }
>
>         /**
>          * some is a DSL class to improve syntax for constructing SubsetOfs
>          */
>         abstract class some[T](okf : (T) => boolean) extends
> SubsetBuilder[T](okf)
>
>
>         /**
>          * Address is just a POC and demo
>          */
>         class Address
>         {
>             import Address._
>             val city = City()
>             val street = Street()
>             val zipcode = Zipcode()
>         }
>
>         object Address
>         {
>             object City extends some[String](_.length > 0)
>             object Street extends some[String](!_.isEmpty)
>             object Zipcode extends some[String](_.matches("^\\d{5}$"))
>         }
>
>         def main(a : Array[String]) : Unit = {
>             val a = new Address
>             for(b <- "foobar" as_: Address.Street ) a.street() = b
>             println(a.street())
>         }
>     }
>
> ---END CODE---
>
> --
> Viktor Klang
> Scala Loudmouth
>

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Companion object implicitly imported?
That's different. You can access the object/class private members through full path or import. But a subclass, for instance, can't access it's superclass private members, import or not.

On Thu, Jul 2, 2009 at 6:06 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
This has puzzled me in the past, too. Particularly given the sentence
in Programming in Scala in section 4.3 - "A class and its companion
object can access each other's private members."

If we don't want to share members with our companions automatically,
isn't that what private[this] is for?

Kris

On Thu, Jul 2, 2009 at 2:22 PM, Viktor Klang<viktor.klang@gmail.com> wrote:
> Hello guys,
>
> I'm toying a bit with a good concise way of defining type constraints for
> properties.
>
>
> Now, the "problem" is:
>
>         class Address
>         {
>             import Address._ //Have to import manually... not so cool...
>             val city = City() //
>             val street = Street()
>             val zipcode = Zipcode()
>         }
>
> So, I guess I wanted to know the rationale for not implicitly importing the
> contents of the Companion Object...
> Or am I just stupid?
>
> FULL CODE BELOW
>
> ---BEGIN CODE---
>
> object Foobar
> {
>         /**
>          * SubsetOf is a box-type for a value of type T where T conforms to
> predicate p
>          */
>         sealed class SubsetOf[T](p : (T) => boolean)
>         {
>             protected var value : Option[T] = None
>
>             def validate(t : T) : boolean = p(t)
>             def apply() : Option[T] = value
>             def update(t:T) : Unit = if ( validate(t) ) value = Some(t)
>         }
>
>         /**
>          * SubsetBuilder is responsible for constructing instances of
> SubsetOf:s given the predicate p
>          */
>         abstract class SubsetBuilder[T](p : (T) => boolean)
>         {
>             def apply() : SubsetOf[T] = new SubsetOf[T](p)
>             def as_:(t:T) : Option[T] = if( p(t) ) Some(t) else None
>         }
>
>         /**
>          * some is a DSL class to improve syntax for constructing SubsetOfs
>          */
>         abstract class some[T](okf : (T) => boolean) extends
> SubsetBuilder[T](okf)
>
>
>         /**
>          * Address is just a POC and demo
>          */
>         class Address
>         {
>             import Address._
>             val city = City()
>             val street = Street()
>             val zipcode = Zipcode()
>         }
>
>         object Address
>         {
>             object City extends some[String](_.length > 0)
>             object Street extends some[String](!_.isEmpty)
>             object Zipcode extends some[String](_.matches("^\\d{5}$"))
>         }
>
>         def main(a : Array[String]) : Unit = {
>             val a = new Address
>             for(b <- "foobar" as_: Address.Street ) a.street() = b
>             println(a.street())
>         }
>     }
>
> ---END CODE---
>
> --
> Viktor Klang
> Scala Loudmouth
>



--
Daniel C. Sobral

Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Companion object implicitly imported?

Sure, but that's kind of irrelevant to the question at hand. If
companion class members were implicitly imported it would eliminate
some boilerplate but would not limit our ability to restrict access to
member variables or methods (since making such a member private[this]
would prevent it from being accessed from the companion.)

Since a class and its companion object must be defined within the same
source file, what would be the downside of such automatic imports?

On Thu, Jul 2, 2009 at 3:43 PM, Daniel Sobral wrote:
> That's different. You can access the object/class private members through
> full path or import. But a subclass, for instance, can't access it's
> superclass private members, import or not.
>
> On Thu, Jul 2, 2009 at 6:06 PM, Kris Nuttycombe
> wrote:
>>
>> This has puzzled me in the past, too. Particularly given the sentence
>> in Programming in Scala in section 4.3 - "A class and its companion
>> object can access each other's private members."
>>
>> If we don't want to share members with our companions automatically,
>> isn't that what private[this] is for?
>>
>> Kris
>>
>> On Thu, Jul 2, 2009 at 2:22 PM, Viktor Klang
>> wrote:
>> > Hello guys,
>> >
>> > I'm toying a bit with a good concise way of defining type constraints
>> > for
>> > properties.
>> >
>> >
>> > Now, the "problem" is:
>> >
>> >         class Address
>> >         {
>> >             import Address._ //Have to import manually... not so cool...
>> >             val city = City() //
>> >             val street = Street()
>> >             val zipcode = Zipcode()
>> >         }
>> >
>> > So, I guess I wanted to know the rationale for not implicitly importing
>> > the
>> > contents of the Companion Object...
>> > Or am I just stupid?
>> >
>> > FULL CODE BELOW
>> >
>> > ---BEGIN CODE---
>> >
>> > object Foobar
>> > {
>> >         /**
>> >          * SubsetOf is a box-type for a value of type T where T conforms
>> > to
>> > predicate p
>> >          */
>> >         sealed class SubsetOf[T](p : (T) => boolean)
>> >         {
>> >             protected var value : Option[T] = None
>> >
>> >             def validate(t : T) : boolean = p(t)
>> >             def apply() : Option[T] = value
>> >             def update(t:T) : Unit = if ( validate(t) ) value = Some(t)
>> >         }
>> >
>> >         /**
>> >          * SubsetBuilder is responsible for constructing instances of
>> > SubsetOf:s given the predicate p
>> >          */
>> >         abstract class SubsetBuilder[T](p : (T) => boolean)
>> >         {
>> >             def apply() : SubsetOf[T] = new SubsetOf[T](p)
>> >             def as_:(t:T) : Option[T] = if( p(t) ) Some(t) else None
>> >         }
>> >
>> >         /**
>> >          * some is a DSL class to improve syntax for constructing
>> > SubsetOfs
>> >          */
>> >         abstract class some[T](okf : (T) => boolean) extends
>> > SubsetBuilder[T](okf)
>> >
>> >
>> >         /**
>> >          * Address is just a POC and demo
>> >          */
>> >         class Address
>> >         {
>> >             import Address._
>> >             val city = City()
>> >             val street = Street()
>> >             val zipcode = Zipcode()
>> >         }
>> >
>> >         object Address
>> >         {
>> >             object City extends some[String](_.length > 0)
>> >             object Street extends some[String](!_.isEmpty)
>> >             object Zipcode extends some[String](_.matches("^\\d{5}$"))
>> >         }
>> >
>> >         def main(a : Array[String]) : Unit = {
>> >             val a = new Address
>> >             for(b <- "foobar" as_: Address.Street ) a.street() = b
>> >             println(a.street())
>> >         }
>> >     }
>> >
>> > ---END CODE---
>> >
>> > --
>> > Viktor Klang
>> > Scala Loudmouth
>> >
>
>
>
> --
> Daniel C. Sobral
>
> Something I learned in academia: there are three kinds of academic reviews:
> review by name, review by reference and review by value.
>

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Companion object implicitly imported?
Sorry for bouncing this!

Mr. Odersky, would you so kindly comment on this thread?

On Fri, Jul 3, 2009 at 5:38 AM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
Sure, but that's kind of irrelevant to the question at hand. If
companion class members were implicitly imported it would eliminate
some boilerplate but would not limit our ability to restrict access to
member variables or methods (since making such a member private[this]
would prevent it from being accessed from the companion.)

Since a class and its companion object must be defined within the same
source file, what would be the downside of such automatic imports?

On Thu, Jul 2, 2009 at 3:43 PM, Daniel Sobral<dcsobral@gmail.com> wrote:
> That's different. You can access the object/class private members through
> full path or import. But a subclass, for instance, can't access it's
> superclass private members, import or not.
>
> On Thu, Jul 2, 2009 at 6:06 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com>
> wrote:
>>
>> This has puzzled me in the past, too. Particularly given the sentence
>> in Programming in Scala in section 4.3 - "A class and its companion
>> object can access each other's private members."
>>
>> If we don't want to share members with our companions automatically,
>> isn't that what private[this] is for?
>>
>> Kris
>>
>> On Thu, Jul 2, 2009 at 2:22 PM, Viktor Klang<viktor.klang@gmail.com>
>> wrote:
>> > Hello guys,
>> >
>> > I'm toying a bit with a good concise way of defining type constraints
>> > for
>> > properties.
>> >
>> >
>> > Now, the "problem" is:
>> >
>> >         class Address
>> >         {
>> >             import Address._ //Have to import manually... not so cool...
>> >             val city = City() //
>> >             val street = Street()
>> >             val zipcode = Zipcode()
>> >         }
>> >
>> > So, I guess I wanted to know the rationale for not implicitly importing
>> > the
>> > contents of the Companion Object...
>> > Or am I just stupid?
>> >
>> > FULL CODE BELOW
>> >
>> > ---BEGIN CODE---
>> >
>> > object Foobar
>> > {
>> >         /**
>> >          * SubsetOf is a box-type for a value of type T where T conforms
>> > to
>> > predicate p
>> >          */
>> >         sealed class SubsetOf[T](p : (T) => boolean)
>> >         {
>> >             protected var value : Option[T] = None
>> >
>> >             def validate(t : T) : boolean = p(t)
>> >             def apply() : Option[T] = value
>> >             def update(t:T) : Unit = if ( validate(t) ) value = Some(t)
>> >         }
>> >
>> >         /**
>> >          * SubsetBuilder is responsible for constructing instances of
>> > SubsetOf:s given the predicate p
>> >          */
>> >         abstract class SubsetBuilder[T](p : (T) => boolean)
>> >         {
>> >             def apply() : SubsetOf[T] = new SubsetOf[T](p)
>> >             def as_:(t:T) : Option[T] = if( p(t) ) Some(t) else None
>> >         }
>> >
>> >         /**
>> >          * some is a DSL class to improve syntax for constructing
>> > SubsetOfs
>> >          */
>> >         abstract class some[T](okf : (T) => boolean) extends
>> > SubsetBuilder[T](okf)
>> >
>> >
>> >         /**
>> >          * Address is just a POC and demo
>> >          */
>> >         class Address
>> >         {
>> >             import Address._
>> >             val city = City()
>> >             val street = Street()
>> >             val zipcode = Zipcode()
>> >         }
>> >
>> >         object Address
>> >         {
>> >             object City extends some[String](_.length > 0)
>> >             object Street extends some[String](!_.isEmpty)
>> >             object Zipcode extends some[String](_.matches("^\\d{5}$"))
>> >         }
>> >
>> >         def main(a : Array[String]) : Unit = {
>> >             val a = new Address
>> >             for(b <- "foobar" as_: Address.Street ) a.street() = b
>> >             println(a.street())
>> >         }
>> >     }
>> >
>> > ---END CODE---
>> >
>> > --
>> > Viktor Klang
>> > Scala Loudmouth
>> >
>
>
>
> --
> Daniel C. Sobral
>
> Something I learned in academia: there are three kinds of academic reviews:
> review by name, review by reference and review by value.
>

Thanks,
--
Viktor Klang
Scala Loudmouth
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Companion object implicitly imported?

On Sun, Jul 05, 2009 at 12:22:38PM +0200, Viktor Klang wrote:
> Sorry for bouncing this!
>
> Mr. Odersky, would you so kindly comment on this thread?

You will usually find that stuff like this has been discussed before.

http://www.nabble.com/Companion-object-visibility-in-Eclipse-plugin-td17...
http://osdir.com/ml/lang.scala.debate/2008-06/msg00089.html

...and neither of those is the thread I was looking for, where opinions
were solicited and plenty of people were against autoimport from the
companion. The thing is, it's a lot easier to import something into
your namespace if you want it than it is to unimport if you don't. And
personally I already have enough problems with shadowing.

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Companion object implicitly imported?


On Sun, Jul 5, 2009 at 12:56 PM, Paul Phillips <paulp@improving.org> wrote:
On Sun, Jul 05, 2009 at 12:22:38PM +0200, Viktor Klang wrote:
> Sorry for bouncing this!
>
> Mr. Odersky, would you so kindly comment on this thread?

You will usually find that stuff like this has been discussed before.

http://www.nabble.com/Companion-object-visibility-in-Eclipse-plugin-td17685573.html
http://osdir.com/ml/lang.scala.debate/2008-06/msg00089.html

...and neither of those is the thread I was looking for, where opinions
were solicited and plenty of people were against autoimport from the
companion.  The thing is, it's a lot easier to import something into
your namespace if you want it than it is to unimport if you don't.  And
personally I already have enough problems with shadowing.

Ah ok, thanks for the linky!
 
Unfortunately this means that I'll have to turn to code generation to avoid boilerplate, which I was trying to avoid :(


--
Paul Phillips      | Those who can make you believe absurdities
Protagonist        | can make you commit atrocities.
Empiricist         |     -- Voltaire
ha! spill, pupil   |----------* http://www.improving.org/paulp/ *----------



--
Viktor Klang
Scala Loudmouth

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