- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
scala, dependency injection and wicket
Wed, 2009-10-07, 22:11
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
(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
Thu, 2009-10-08, 18:07
#2
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
Thu, 2009-10-08, 19:17
#3
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
Thu, 2009-10-08, 20:17
#4
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-----
Thu, 2009-10-08, 21:07
#5
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))
^
Mon, 2009-10-19, 15:47
#6
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
Tue, 2009-10-20, 20:07
#7
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
Tue, 2009-10-20, 20:17
#8
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:
--
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
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
Tue, 2009-10-20, 20:47
#9
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:
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
Tue, 2009-10-20, 20:47
#10
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 { ... }
Tue, 2009-10-20, 21:37
#11
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
Tue, 2009-10-20, 21:47
#12
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 ... :)
Tue, 2009-10-20, 21:57
#13
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
Tue, 2009-10-20, 22:07
#14
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$.()
Tue, 2009-10-20, 23:27
#15
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:
--
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.
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.
Tue, 2009-10-20, 23:47
#16
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:
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.
Wed, 2009-10-21, 00:17
#17
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:
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
Wed, 2009-10-21, 10:07
#18
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.
>
Tue, 2009-10-27, 12:37
#19
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.
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>
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/ *----------
Tue, 2009-10-27, 14:47
#20
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."
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
>
>