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

scala, dependency injection and wicket

20 replies
Haim Ashkenazi
Joined: 2009-05-13,
User offline. Last seen 42 years 45 weeks ago.
Hi

(This email was first sent by mistake to the wicket mailing list so if you're subscribed to it, sorry for the duplication).

I've started a test project on which I use scala, wicket and couchdb (I'm new to all of them, which should make it fun :) ).

Until now I was dealing with the writing sample data access code, and I was reading a lot of articles about DI in scala. I more or less went with what is suggested in the "Programing in scala" book, that is using traits with self type annotations and lazy vals (for calling modules). It's very easy to construct object/classes for testing this way. Now I reached the web part (wicket) and I came to a problem. In wicket the class name has to match the html file (e.g. package/HomePage.html must have a corresponding package.HomePage.class). This makes it (I think) impossible to use the above method for DI.

One solution is to use DI framework like guice (which was also suggested to me by Jan Kriesten in the wicket mailing list), and I'm confortable with this, but I just wanted to make sure I'm not overlooking something.

Thanks in advance
--
Haim

Chris Twiner
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: scala, dependency injection and wicket

Hi Haim,

Sorry if this is obvious (I've not used Wicket), but could you give an
example of why mixing traits and self types stops you having a class
per html file?

What do you need from DI in this context?

I'm generally curious as part of my scala experimentation is a di
system, and its always good to know important edge cases.

cheers,
Chris

On Wed, Oct 7, 2009 at 11:11 PM, Haim Ashkenazi
wrote:
> Hi
>
> (This email was first sent by mistake to the wicket mailing list so if
> you're subscribed to it, sorry for the duplication).
>
> I've started a test project on which I use scala, wicket and couchdb (I'm
> new to all of them, which should make it fun :) ).
>
> Until now I was dealing with the writing sample data access code, and I was
> reading a lot of articles about DI in scala. I more or less went with what
> is suggested in the "Programing in scala" book, that is using traits with
> self type annotations and lazy vals (for calling modules). It's very easy to
> construct object/classes for testing this way. Now I reached the web part
> (wicket) and I came to a problem. In wicket the class name has to match the
> html file (e.g. package/HomePage.html must have a corresponding
> package.HomePage.class). This makes it (I think) impossible to use the above
> method for DI.
>
> One solution is to use DI framework like guice (which was also suggested to
> me by Jan Kriesten in the wicket mailing list), and I'm confortable with
> this, but I just wanted to make sure I'm not overlooking something.
>
> Thanks in advance
> --
> Haim
>
>

geoff
Joined: 2008-08-20,
User offline. Last seen 1 year 25 weeks ago.
Re: scala, dependency injection and wicket

On Wed, Oct 07, 2009 at 11:11:42PM +0200, Haim Ashkenazi said
> Hi
>
> (This email was first sent by mistake to the wicket mailing list so if
> you're subscribed to it, sorry for the duplication).
>
> I've started a test project on which I use scala, wicket and couchdb (I'm
> new to all of them, which should make it fun :) ).
>
> Until now I was dealing with the writing sample data access code, and I was
> reading a lot of articles about DI in scala. I more or less went with what
> is suggested in the "Programing in scala" book, that is using traits with
> self type annotations and lazy vals (for calling modules). It's very easy to
> construct object/classes for testing this way. Now I reached the web part
> (wicket) and I came to a problem. In wicket the class name *has* to match
> the html file (e.g. package/HomePage.html must have a corresponding
> package.HomePage.class). This makes it (I think) impossible to use the above
> method for DI.

Since Wicket supports inheritance of markup from super-classes, I think
you should be able to apply exactly the technique from Programming in
Scala.

Following the pattern in PinS your pages would be analogous to the
Browser abstract class and have any dependencies as abstract vals.

For example:

abstract class Homepage extends WebPage {
val database: Database
}

You'd then have a Homepage.html alongside the Homepage class.

Later you can do:

new HomePage {
val database = someRealDatabase
}

and that page instance will pick up the markup through the markup
inheritance mechanism.

Doing it this way does cause problems with passing around dependencies
when constructing components and linked-to pages, since it's a lot like
constructor injection. You might consider making the vending of
components and pages your dependencies. A possible pattern is:

abstract class ARegistrationPage extends WebPage {
val userdb: UserDatabase
}

abstract class AUserSearch(id: String) extends Panel(id) {
val userdb: UserDatabase
}

trait UserComponents {
val userdb: UserDatabase

def userSearchPanel(id: String) = new AUserSearch(id) {
val userdb = UserComponents.this.userdb
}

def registrationPage = new RegistrationPage {
val userdb = UserComponents.this.userdb
}
}

abstract class Homepage extends WebPage {
val userComponents: UserComponents
}

You may be able to have abstract classes in UserComponents that extend
another class and provide the userdb dependency but leave the rest
abstract and you can do

new userComponents.SomeClass(id) {
def onSubmit() = ...
}

> One solution is to use DI framework like guice (which was also suggested to
> me by Jan Kriesten in the wicket mailing list), and I'm confortable with
> this, but I just wanted to make sure I'm not overlooking something.

I have used the wicket guice integration and it works pretty well.
Wicket will install a ComponentInstantiationListener that will inject
dependencies through setter or field injection. So if you are
comfortable with using setter type injection, this is a reasonable way
to go.

>
> Thanks in advance

Bruno Woltzenlo...
Joined: 2009-10-04,
User offline. Last seen 42 years 45 weeks ago.
Inheritance and Pattern Matching

Hi,

I have a doubt about the way case classes, pattern matching and inheritance
work together... Consider the following (pseudo-)code (this is a
simplification of the actual code that I have):

case class A(x:Any)

case class B(y:Any) extends A(A(y))

def f = B(0) match {
case A(A(0)) => println("ok")
}

def g = A(A(0)) match {
case B(0) => println("ok")
case _ => println("not ok")
}

If we try to compile this code, scala will complain about a type mismatch in
the first match (in the function "f").

It will not complain about the second match, but it fail (it will print "not
ok" if "g" is called).

I find this behavior not so intuitive. I guess I could fix this by
implementing implicit converters, but I would expect the conversion to be
automatic and correct (at least in one direction) in the case of inheritance
between case classes.

Could you anyone explain this behavior?

Best regards,

Bruno

Haim Ashkenazi
Joined: 2009-05-13,
User offline. Last seen 42 years 45 weeks ago.
Re: scala, dependency injection and wicket

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Geoff,

On Oct 8, 2009, at 7:00 PM, Geoff Reedy wrote:

> On Wed, Oct 07, 2009 at 11:11:42PM +0200, Haim Ashkenazi said
>> Hi
>>
>> (This email was first sent by mistake to the wicket mailing list so
>> if
>> you're subscribed to it, sorry for the duplication).
>>
>> I've started a test project on which I use scala, wicket and
>> couchdb (I'm
>> new to all of them, which should make it fun :) ).
>>
>> Until now I was dealing with the writing sample data access code,
>> and I was
>> reading a lot of articles about DI in scala. I more or less went
>> with what
>> is suggested in the "Programing in scala" book, that is using
>> traits with
>> self type annotations and lazy vals (for calling modules). It's
>> very easy to
>> construct object/classes for testing this way. Now I reached the
>> web part
>> (wicket) and I came to a problem. In wicket the class name *has* to
>> match
>> the html file (e.g. package/HomePage.html must have a corresponding
>> package.HomePage.class). This makes it (I think) impossible to use
>> the above
>> method for DI.
>
> Since Wicket supports inheritance of markup from super-classes, I
> think
> you should be able to apply exactly the technique from Programming in
> Scala.
>
> Following the pattern in PinS your pages would be analogous to the
> Browser abstract class and have any dependencies as abstract vals.
>
> For example:
>
> abstract class Homepage extends WebPage {
> val database: Database
> }
>
> You'd then have a Homepage.html alongside the Homepage class.
>
> Later you can do:
>
> new HomePage {
> val database = someRealDatabase
> }
>
> and that page instance will pick up the markup through the markup
> inheritance mechanism.
>
> Doing it this way does cause problems with passing around dependencies
> when constructing components and linked-to pages, since it's a lot
> like
> constructor injection. You might consider making the vending of
> components and pages your dependencies. A possible pattern is:
>
> abstract class ARegistrationPage extends WebPage {
> val userdb: UserDatabase
> }
>
> abstract class AUserSearch(id: String) extends Panel(id) {
> val userdb: UserDatabase
> }
>
> trait UserComponents {
> val userdb: UserDatabase
>
> def userSearchPanel(id: String) = new AUserSearch(id) {
> val userdb = UserComponents.this.userdb
> }
>
> def registrationPage = new RegistrationPage {
> val userdb = UserComponents.this.userdb
> }
> }
>
> abstract class Homepage extends WebPage {
> val userComponents: UserComponents
> }
>
> You may be able to have abstract classes in UserComponents that extend
> another class and provide the userdb dependency but leave the rest
> abstract and you can do
>
> new userComponents.SomeClass(id) {
> def onSubmit() = ...
> }
Thanks, This is an interesting approach and I'm not sure I fully
understand it, but I'll do some tests to see how it works.

>
>> One solution is to use DI framework like guice (which was also
>> suggested to
>> me by Jan Kriesten in the wicket mailing list), and I'm confortable
>> with
>> this, but I just wanted to make sure I'm not overlooking something.
>
> I have used the wicket guice integration and it works pretty well.
> Wicket will install a ComponentInstantiationListener that will inject
> dependencies through setter or field injection. So if you are
> comfortable with using setter type injection, this is a reasonable way
> to go.
Actually, after a day of reading and testing (luckily it's a holiday
here), I think I'll go with the implicit parameters technique. I think
I only need small amount of classes to be injected, so this should be
enough. If my DI needs will grow, I'll consider other options.

Thanks

Bye
- --
Haim
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Darwin)

iEYEARECAAYFAkrOOcQACgkQhwMtGgRKzT1dNwCeOu9FSt4B530q3sUklTDW6cTc
vNQAoJEFMu6Q8RxVuxt+ZyqLA+Ix2C6I
=o7nV
-----END PGP SIGNATURE-----

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Inheritance and Pattern Matching

On Thu, Oct 08, 2009 at 08:11:36PM +0200, Bruno Woltzenlogel Paleo wrote:
> I have a doubt about the way case classes, pattern matching and
> inheritance work together... Consider the following (pseudo-)code
> (this is a simplification of the actual code that I have):
>
> case class A(x:Any)
> case class B(y:Any) extends A(A(y))

Let me fire up trunk with -deprecation and see what I can get out of
those two lines:

scala> case class A(x:Any)
defined class A

scala> case class B(y:Any) extends A(A(y))
:6: warning: case class `class B' has case class ancestor `class A'. This has been deprecated for unduly complicating both usage and implementation. You should instead use extractors for pattern matching on non-leaf nodes.
case class B(y:Any) extends A(A(y))
^

Bruno Woltzenlo...
Joined: 2009-10-04,
User offline. Last seen 42 years 45 weeks ago.
Dynamic Duck Typing

Hello,

I will describe below a simplidied version of my real problem...

Suppose I have the following class:

abstract class TypedLambdaExpression {
def exptype: String
}

Where 'exptype' should return "i" if the "type" of the lambda expression is
the individual type, "o" if it is "boolean", "i -> o" if it is a function
from individuals to booleans, and so on...

I would like to be able to say that a TypedLambdaExpression of 'exptype' "o"
(boolean) is a Formula. I imagine that the least verbose way to do this
would be with a kind of "dynamic duck typing" similar to this:

type Formula = {
def exptype: String
require(exptype == "o") // this line doesn't work!
}

Then I could declare, for example, a function f that accepts only boolean
TypedLambdaExpressions like this:

def f(e: Formula) = { ... }

Instead of declaring it like this:

Def f(e: TypedLambdaExpression) = { if e.exptype == "o" ... else throw
Exception } \\ this pattern is kind of ugly and becomes repetitive if we
have to implement lots of functions with Formula arguments

However, this is not possible, because Scala does not accept this
declaration of Formula as a "duck type", because 'require(exptype == "o")'
can only be checked at runtime... And Scala demands static typing...

An alternative would be to declare Formula not as a duck type but as a
trait, and to have:
1) special concrete subclasses of TypedLambdaExpression mixing the Formula
trait.
2) implicit converters from TypedLambdaExpression to those subclasses.

I think this alternative would work, but it would be much less natural and
much more verbose than I would like it to be.

So, here are a few questions related to this:

1) is it possible to do what I want in a way shorter and more natural than
using traits, subclasses and implicit converters?

2) I am puzzled by the apparent paradox that, on the one hand, Scala is
statically typed (and hence forbids the dynamic duck typing that I want),
while on the other hand, I am somehow able to simulate this dynamic duck
typing by using subclasses, traits and implicit converters as I sketched.
What is going on?

3) Is there any language as nice as Scala (functional object oriented,
well-integrated with Java, with pattern matching, case classes, extractors,
implicit converters, combinatory parsers...), but which also allows the kind
of "dynamic" duck typing that I mentioned above?

Many thanks in advance for any help...

Best regards,

Bruno

Bruno Woltzenlo...
Joined: 2009-10-04,
User offline. Last seen 42 years 45 weeks ago.
Case Classes and Traits

Hi,

Here is another very simple failing experiment with Scala:

case class A()
trait T

def test1 = {
val a = new A() with T
a match {
case A() => true
}
}

When I try to compile, I get an error message similar to this:

found : A
required: A with T
case A() => true
^

So, this means that we basically lose the ability to do pattern matching if
we ever mix a trait in an instance of a case class, right??

I find this very restrictive... Why doesn't Scala allow this?

Thanks in advance!
Best regards,

Bruno Woltzenlogel Paleo

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Case Classes and Traits
scala> case class A(i : Int)
defined class A

scala> trait T
defined trait T

scala> val a : AnyRef = new A(1) with T
a: AnyRef = A(1)

scala> a match { case A(1) => true }
res0: Boolean = true

On Tue, Oct 20, 2009 at 8:55 PM, Bruno Woltzenlogel Paleo <bruno.wp.mailinglist@googlemail.com> wrote:
Hi,

Here is another very simple failing experiment with Scala:


   case class A()
   trait T

   def test1 = {
       val a = new A() with T
       a match {
           case A() => true
       }
   }


When I try to compile, I get an error message similar to this:

found   : A
required: A with T
           case A() => true
                   ^


So, this means that we basically lose the ability to do pattern matching if
we ever mix a trait in an instance of a case class, right??

I find this very restrictive... Why doesn't Scala allow this?

Thanks in advance!
Best regards,

Bruno Woltzenlogel Paleo




--
Viktor Klang

Blog: klangism.blogspot.com
Twttr: viktorklang
Wave: viktor.klang@googlewave.com
Code: github.com/viktorklang

AKKA Committer - akkasource.org
Lift Committer - liftweb.com
Atmosphere Committer - atmosphere.dev.java.net
SoftPub founder: http://groups.google.com/group/softpub
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Case Classes and Traits
Viktor's example highlights the solution nicely: matches are type-aware, so you can't use a more general type inside the match when the compiler already knows the answer is more specific.  Thus, if you want to use a more general match, you first broaden the thing you're matching to:

val a:A = new A(1) with T

would work also (if you don't want to broaden all the way to AnyRef), as would

val a = new A(1) with T
a.asInstanceOf[A] match { ... }

  --Rex


On Tue, Oct 20, 2009 at 3:02 PM, Viktor Klang <viktor.klang@gmail.com> wrote:
scala> case class A(i : Int)
defined class A

scala> trait T
defined trait T

scala> val a : AnyRef = new A(1) with T
a: AnyRef = A(1)

scala> a match { case A(1) => true }
res0: Boolean = true

On Tue, Oct 20, 2009 at 8:55 PM, Bruno Woltzenlogel Paleo <bruno.wp.mailinglist@googlemail.com> wrote:
Hi,

Here is another very simple failing experiment with Scala:


   case class A()
   trait T

   def test1 = {
       val a = new A() with T
       a match {
           case A() => true
       }
   }


When I try to compile, I get an error message similar to this:

found   : A
required: A with T
           case A() => true
                   ^


So, this means that we basically lose the ability to do pattern matching if
we ever mix a trait in an instance of a case class, right??

I find this very restrictive... Why doesn't Scala allow this?

Thanks in advance!
Best regards,

Bruno Woltzenlogel Paleo




--
Viktor Klang

Blog: klangism.blogspot.com
Twttr: viktorklang
Wave: viktor.klang@googlewave.com
Code: github.com/viktorklang

AKKA Committer - akkasource.org
Lift Committer - liftweb.com
Atmosphere Committer - atmosphere.dev.java.net
SoftPub founder: http://groups.google.com/group/softpub

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Case Classes and Traits

On Tue, Oct 20, 2009 at 03:39:05PM -0400, Rex Kerr wrote:
> val a = new A(1) with T
> a.asInstanceOf[A] match { ... }

Oh don't cast, it's made ugly for a reason.

(a: A) match { ... }

Gordon Tyler
Joined: 2009-06-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Case Classes and Traits

Paul Phillips wrote:
> On Tue, Oct 20, 2009 at 03:39:05PM -0400, Rex Kerr wrote:
>> val a = new A(1) with T
>> a.asInstanceOf[A] match { ... }
>
> Oh don't cast, it's made ugly for a reason.
>
> (a: A) match { ... }
>

What exactly does that syntax mean? Is it just a prettier typecast or is
it better than a typecast?

Ciao,
Gordon

phkoester
Joined: 2009-08-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Case Classes and Traits

>> (a: A) match { ... }
>>
>
> What exactly does that syntax mean? Is it just a prettier typecast or is
> it better than a typecast?

It's a pattern match and a decl at the same time, as in:

val (a, b) = p // With `p' being a 2-tuple, a pair

What strikes me is that there is no `val' or `var' in Paul's example,
but I'm ready to believe everything Paul says ... :)

Colin Bullock
Joined: 2009-01-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Case Classes and Traits

What exactly does that syntax mean? Is it just a prettier typecast or is it better than a typecast?

It's simply giving an explicit expected type to an expression (§6.13 of the spec). This is different than a typecast (run-time); if the expression does not conform to the expected type, it will not type-check (compile-time).

scala> trait S
defined trait S

scala> trait T
defined trait T

scala> class A
defined class A

scala> val a = new A with T
a: A with T = $anon$1@fb92dc

scala> (a: S)
<console>:9: error: type mismatch;
 found   : A with T
 required: S
       (a: S)
        ^

scala> a.asInstanceOf[S]
java.lang.ClassCastException: $anon$1
        at .<init>(<console>:9)
        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.java:39)
        at sun.reflect.DelegatingMethodAccesso...
scala>

- Colin

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Case Classes and Traits

On Tue, Oct 20, 2009 at 04:25:04PM -0400, Gordon Tyler wrote:
> What exactly does that syntax mean? Is it just a prettier typecast or
> is it better than a typecast?

Perhaps this will illustrate.

scala> case class A()
defined class A

scala> trait T
defined trait T

scala> val x = new A with T
x: A with T = A()

Excerpts from the mind of scalac in comments.

// "I cannot in good conscience allow you to proceed
// with this madness!"
scala> object o { (x: String) match { case "abc" => true } }
:8: error: type mismatch;
found : A with T
required: String
object o { (x: String) match { case "abc" => true } }
^

// "Hmm, it's a String you say? Sir, yes sir!"
scala> object o { x.asInstanceOf[String] match { case "abc" => true } }
defined module o

// "Sorry sir, I have failed you again. I'm ready to be fed to
// the piranhas under the floor."
scala> o
java.lang.ClassCastException: $anon$1 cannot be cast to java.lang.String
at o$.(:8)
at o$.()

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Case Classes and Traits
What's the flag to turn on Phillipsian error messages? :-)

On Tue, Oct 20, 2009 at 6:53 PM, Paul Phillips <paulp@improving.org> wrote:
On Tue, Oct 20, 2009 at 04:25:04PM -0400, Gordon Tyler wrote:
> What exactly does that syntax mean? Is it just a prettier typecast or
> is it better than a typecast?

Perhaps this will illustrate.

scala> case class A()
defined class A

scala> trait T
defined trait T

scala> val x = new A with T
x: A with T = A()

Excerpts from the mind of scalac in comments.

// "I cannot in good conscience allow you to proceed
//  with this madness!"
scala> object o { (x: String) match { case "abc" => true } }
<console>:8: error: type mismatch;
 found   : A with T
 required: String
      object o { (x: String) match { case "abc" => true } }
                  ^

// "Hmm, it's a String you say? Sir, yes sir!"
scala> object o { x.asInstanceOf[String] match { case "abc" => true } }
defined module o

// "Sorry sir, I have failed you again.  I'm ready to be fed to
//  the piranhas under the floor."
scala> o
java.lang.ClassCastException: $anon$1 cannot be cast to java.lang.String
       at o$.<init>(<console>:8)
       at o$.<clinit>(<console>)

--
Paul Phillips      | It is hard to believe that a man is
Stickler           | telling the truth when you know that you
Empiricist         | would lie if you were in his place.
i pull his palp!   |     -- H. L. Mencken



--
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.
bmaso
Joined: 2009-10-04,
User offline. Last seen 2 years 40 weeks ago.
Re: Case Classes and Traits
scala> wtf ?? => why do[you] (!work)

On Tue, Oct 20, 2009 at 3:18 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
What's the flag to turn on Phillipsian error messages? :-)

On Tue, Oct 20, 2009 at 6:53 PM, Paul Phillips <paulp@improving.org> wrote:
On Tue, Oct 20, 2009 at 04:25:04PM -0400, Gordon Tyler wrote:
> What exactly does that syntax mean? Is it just a prettier typecast or
> is it better than a typecast?

Perhaps this will illustrate.

scala> case class A()
defined class A

scala> trait T
defined trait T

scala> val x = new A with T
x: A with T = A()

Excerpts from the mind of scalac in comments.

// "I cannot in good conscience allow you to proceed
//  with this madness!"
scala> object o { (x: String) match { case "abc" => true } }
<console>:8: error: type mismatch;
 found   : A with T
 required: String
      object o { (x: String) match { case "abc" => true } }
                  ^

// "Hmm, it's a String you say? Sir, yes sir!"
scala> object o { x.asInstanceOf[String] match { case "abc" => true } }
defined module o

// "Sorry sir, I have failed you again.  I'm ready to be fed to
//  the piranhas under the floor."
scala> o
java.lang.ClassCastException: $anon$1 cannot be cast to java.lang.String
       at o$.<init>(<console>:8)
       at o$.<clinit>(<console>)

--
Paul Phillips      | It is hard to believe that a man is
Stickler           | telling the truth when you know that you
Empiricist         | would lie if you were in his place.
i pull his palp!   |     -- H. L. Mencken



--
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.

Donna Malayeri
Joined: 2009-10-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Dynamic Duck Typing
I'm not totally sure I understand the problem, but are you saying that some values of a type should also be classified as some other type?  Why use the phrase "duck typing" (which is not really typing at all)?  Rather, this seems to be a form of what is called predicate dispatch, whereby different methods are called depending on an object's value.

See JPred or Cecil for languages that provide this feature (though neither have the level of Java interop that you want).

Donna

On Mon, Oct 19, 2009 at 4:33 PM, Bruno Woltzenlogel Paleo <bruno.wp.mailinglist@googlemail.com> wrote:
Hello,

I will describe below a simplidied version of my real problem...

Suppose I have the following class:

   abstract class TypedLambdaExpression {
       def exptype: String
   }

Where 'exptype' should return "i" if the "type" of the lambda expression is
the individual type, "o" if it is "boolean", "i -> o" if it is a function
from individuals to booleans, and so on...

I would like to be able to say that a TypedLambdaExpression of 'exptype' "o"
(boolean) is a Formula.  I imagine that the least verbose way to do this
would be with a kind of "dynamic duck typing" similar to this:

type Formula = {
       def exptype: String
       require(exptype == "o")    // this line doesn't work!
}


Then I could declare, for example, a function f that accepts only boolean
TypedLambdaExpressions like this:

def f(e: Formula) = { ... }

Instead of declaring it like this:

Def f(e: TypedLambdaExpression) = { if e.exptype == "o" ... else throw
Exception }   \\ this pattern is kind of ugly and becomes repetitive if we
have to implement lots of functions with Formula arguments


However, this is not possible, because Scala does not accept this
declaration of Formula as a "duck type", because 'require(exptype == "o")'
can only be checked at runtime... And Scala demands static typing...

An alternative would be to declare Formula not as a duck type but as a
trait, and to have:
1) special concrete subclasses of TypedLambdaExpression mixing the Formula
trait.
2) implicit converters from TypedLambdaExpression to those subclasses.

I think this alternative would work, but it would be much less natural and
much more verbose than I would like it to be.

So, here are a few questions related to this:

1) is it possible to do what I want in a way shorter and more natural than
using traits, subclasses and implicit converters?

2) I am puzzled by the apparent paradox that, on the one hand, Scala is
statically typed (and hence forbids the dynamic duck typing that I want),
while on the other hand, I am somehow able to simulate this dynamic duck
typing by using subclasses, traits and implicit converters as I sketched.
What is going on?

3) Is there any language as nice as Scala (functional object oriented,
well-integrated with Java, with pattern matching, case classes, extractors,
implicit converters, combinatory parsers...), but which also allows the kind
of "dynamic" duck typing that I mentioned above?


Many thanks in advance for any help...

Best regards,

Bruno


Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 3 days ago.
Re: Case Classes and Traits

A beer goes to the first person who can implement this as a compiler plugin :)

On Tue, Oct 20, 2009 at 11:18 PM, Daniel Sobral wrote:
> What's the flag to turn on Phillipsian error messages? :-)
>
> On Tue, Oct 20, 2009 at 6:53 PM, Paul Phillips wrote:
>>
>> On Tue, Oct 20, 2009 at 04:25:04PM -0400, Gordon Tyler wrote:
>> > What exactly does that syntax mean? Is it just a prettier typecast or
>> > is it better than a typecast?
>>
>> Perhaps this will illustrate.
>>
>> scala> case class A()
>> defined class A
>>
>> scala> trait T
>> defined trait T
>>
>> scala> val x = new A with T
>> x: A with T = A()
>>
>> Excerpts from the mind of scalac in comments.
>>
>> // "I cannot in good conscience allow you to proceed
>> //  with this madness!"
>> scala> object o { (x: String) match { case "abc" => true } }
>> :8: error: type mismatch;
>>  found   : A with T
>>  required: String
>>       object o { (x: String) match { case "abc" => true } }
>>                   ^
>>
>> // "Hmm, it's a String you say? Sir, yes sir!"
>> scala> object o { x.asInstanceOf[String] match { case "abc" => true } }
>> defined module o
>>
>> // "Sorry sir, I have failed you again.  I'm ready to be fed to
>> //  the piranhas under the floor."
>> scala> o
>> java.lang.ClassCastException: $anon$1 cannot be cast to java.lang.String
>>        at o$.(:8)
>>        at o$.()
>>
>> --
>> Paul Phillips      | It is hard to believe that a man is
>> Stickler           | telling the truth when you know that you
>> Empiricist         | would lie if you were in his place.
>> i pull his palp!   |     -- H. L. Mencken
>
>
>
> --
> 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.
>

Tomer Libal
Joined: 2009-10-06,
User offline. Last seen 2 years 50 weeks ago.
Re: Inheritance and Pattern Matching
I tried to do the same and did not get any deprecation warning. Is it possible this warning is on an older compiler?
Looking on scala changelog there is this line for version 2.7.0:Case classes can now inherit from other case classes.
case class Foo(x: Int)
case class Bar(override val x: Int, y: Int) extends Foo(x)
object test extends Application {
  println(Bar(1, 2).x)
  (Bar(1, 2): Foo) match {
    case Foo(x) => println(x)
  }
}

Taking your solution from the question about traits and pattern matching (type casting) I get:
scala> val x = B(0)x: B = B(0)
scala> def f = (x: A) match {       | case A(A(0)) => true     | }f: Boolean
My apologizes if I misunderstood the problem,Tomer

2009/10/8 Paul Phillips <paulp@improving.org>
On Thu, Oct 08, 2009 at 08:11:36PM +0200, Bruno Woltzenlogel Paleo wrote:
> I have a doubt about the way case classes, pattern matching and
> inheritance work together... Consider the following (pseudo-)code
> (this is a simplification of the actual code that I have):
>
> case class A(x:Any)
> case class B(y:Any) extends A(A(y))

Let me fire up trunk with -deprecation and see what I can get out of
those two lines:

scala> case class A(x:Any)
defined class A

scala> case class B(y:Any) extends A(A(y))
<console>:6: warning: case class `class B' has case class ancestor `class A'.  This has been deprecated for unduly complicating both usage and implementation.  You should instead use extractors for pattern matching on non-leaf nodes.
      case class B(y:Any) extends A(A(y))
                                  ^
--
Paul Phillips      | Adultery is the application of democracy to love.
Vivid              |     -- H. L. Mencken
Empiricist         |
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Inheritance and Pattern Matching

On Tue, Oct 27, 2009 at 12:26:46PM +0100, Tomer Libal wrote:
> I tried to do the same and did not get any deprecation warning. Is it
> possible this warning is on an older compiler?

Right idea, wrong time arrow.

> Looking on scala changelog there is this line for version 2.7.0: Case
> classes can now inherit from other case classes.

...and in 2.8.0 it will say something like "Case classes should no
longer inherit from other case classes."

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