- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Dynamic keyword generates stackoverflow with -Xexperimental
Sat, 2011-11-26, 12:04
I wanted to compile this example(taken from http://pastie.org/1469174)
:
dynamicallytyped.scala
=================
package dynamicallytyped
object Main extends App {
class DynamicImpl(x: AnyRef) extends Dynamic {
def _select_(name: String): DynamicImpl = {
new DynamicImpl(x.getClass.getMethod(name).invoke(x))
}
def _invoke_(name: String)(args: Any*) = {
new DynamicImpl(x.getClass.getMethod(name,
args.map(_.asInstanceOf[AnyRef].getClass) : _*).invoke(x,
args.map(_.asInstanceOf[AnyRef]) : _*))
}
override def typed[T] = x.asInstanceOf[T]
override def toString = "Dynamic(" + x.toString + ")"
}
implicit def toDynamic(x: Any): Dynamic = new
DynamicImpl(x.asInstanceOf[AnyRef])
class Duck {
def quack = "Quack!"
}
class QuackingSwan {
def quack = "Swack!"
}
def makeQuack(d: Dynamic) {
println(d.quack.typed[String])
}
makeQuack(new Duck)
makeQuack(new QuackingSwan)
val s: Dynamic = "Hello, world!"
s.toLowerCase
s.length
s.isEmpty.typed[Boolean]
}
with commandline:
C:\scala-2.9.1.final\examples>scalac -Xexperimental
dynamicallytyped.scala
but I get a stackoverflow error:
dynatype: d.applyDynamic("quack")()
dynatype: d.applyDynamic("applyDynamic")
dynatype: d.applyDynamic("applyDynamic")
dynatype: d.applyDynamic("applyDynamic")
dynatype: d.applyDynamic("applyDynamic")
[..]
dynatype: d.applyDynamic("applyDynamic")
error: java.lang.StackOverflowError
at scala.tools.selectivecps.CPSAnnotationChecker$checker
$.addAnnotations(CPSAnnotationChecker.scala:354)
at scala.tools.nsc.symtab.AnnotationCheckers$$anonfun$addAnnotations
$1.apply(AnnotationCheckers.scala:103)
at scala.tools.nsc.symtab.AnnotationCheckers$$anonfun$addAnnotations
$1.apply(AnnotationCheckers.scala:102)
at scala.collection.LinearSeqOptimized
$class.foldLeft(LinearSeqOptimized.scala:111)
at scala.collection.immutable.List.foldLeft(List.scala:45)
at scala.tools.nsc.symtab.AnnotationCheckers
$class.addAnnotations(AnnotationCheckers.scala:102)
at
scala.tools.nsc.symtab.SymbolTable.addAnnotations(SymbolTable.scala:
13)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4279)
at scala.tools.nsc.typechecker.Typers
$Typer.typedQualifier(Typers.scala:4350)
at scala.tools.nsc.typechecker.Typers
$Typer.typedQualifier(Typers.scala:4356)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4144)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4271)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
$1$1.apply(Typers.scala:3353)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
$1$1.apply(Typers.scala:3353)
at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:624)
at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:
3353)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4104)
at scala.tools.nsc.typechecker.Typers$Typer.typedSelect
$1(Typers.scala:3581)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4165)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4271)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
$1$1.apply(Typers.scala:3353)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
$1$1.apply(Typers.scala:3353)
at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:624)
at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:
3353)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4104)
at scala.tools.nsc.typechecker.Typers$Typer.typedSelect
$1(Typers.scala:3581)
[..]
Am I something missing?
Or is this not working anymore?
Sat, 2011-11-26, 13:47
#2
Re: Dynamic keyword generates stackoverflow with -Xexperimental
>
> solution: implement the applyDynamic method in DynamicImpl
Do you have an example of how to do that?
I tried several thing but they don't work.
>
>
> > dynamicallytyped.scala
> > =================
> > package dynamicallytyped
>
> > object Main extends App {
> > class DynamicImpl(x: AnyRef) extends Dynamic {
> > def _select_(name: String): DynamicImpl = {
> > new DynamicImpl(x.getClass.getMethod(name).invoke(x))
> > }
> > def _invoke_(name: String)(args: Any*) = {
> > new DynamicImpl(x.getClass.getMethod(name,
> > args.map(_.asInstanceOf[AnyRef].getClass) : _*).invoke(x,
> > args.map(_.asInstanceOf[AnyRef]) : _*))
> > }
> > override def typed[T] = x.asInstanceOf[T]
> > override def toString = "Dynamic(" + x.toString + ")"
> > }
> > implicit def toDynamic(x: Any): Dynamic = new
> > DynamicImpl(x.asInstanceOf[AnyRef])
> > class Duck {
> > def quack = "Quack!"
> > }
> > class QuackingSwan {
> > def quack = "Swack!"
> > }
> > def makeQuack(d: Dynamic) {
> > println(d.quack.typed[String])
> > }
> > makeQuack(new Duck)
> > makeQuack(new QuackingSwan)
> > val s: Dynamic = "Hello, world!"
> > s.toLowerCase
> > s.length
> > s.isEmpty.typed[Boolean]
> > }
>
> > with commandline:
> > C:\scala-2.9.1.final\examples>scalac -Xexperimental
> > dynamicallytyped.scala
> > but I get a stackoverflow error:
>
> > dynatype: d.applyDynamic("quack")()
> > dynatype: d.applyDynamic("applyDynamic")
> > dynatype: d.applyDynamic("applyDynamic")
> > dynatype: d.applyDynamic("applyDynamic")
> > dynatype: d.applyDynamic("applyDynamic")
> > [..]
> > dynatype: d.applyDynamic("applyDynamic")
> > error: java.lang.StackOverflowError
> > at scala.tools.selectivecps.CPSAnnotationChecker$checker
> > $.addAnnotations(CPSAnnotationChecker.scala:354)
> > at scala.tools.nsc.symtab.AnnotationCheckers$$anonfun$addAnnotations
> > $1.apply(AnnotationCheckers.scala:103)
> > at scala.tools.nsc.symtab.AnnotationCheckers$$anonfun$addAnnotations
> > $1.apply(AnnotationCheckers.scala:102)
> > at scala.collection.LinearSeqOptimized
> > $class.foldLeft(LinearSeqOptimized.scala:111)
> > at scala.collection.immutable.List.foldLeft(List.scala:45)
> > at scala.tools.nsc.symtab.AnnotationCheckers
> > $class.addAnnotations(AnnotationCheckers.scala:102)
> > at
> > scala.tools.nsc.symtab.SymbolTable.addAnnotations(SymbolTable.scala:
> > 13)
> > at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4279)
> > at scala.tools.nsc.typechecker.Typers
> > $Typer.typedQualifier(Typers.scala:4350)
> > at scala.tools.nsc.typechecker.Typers
> > $Typer.typedQualifier(Typers.scala:4356)
> > at
> > scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4144)
> > at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4271)
> > at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
> > $1$1.apply(Typers.scala:3353)
> > at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
> > $1$1.apply(Typers.scala:3353)
> > at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:624)
> > at
> > scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:
> > 3353)
> > at
> > scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4104)
> > at scala.tools.nsc.typechecker.Typers$Typer.typedSelect
> > $1(Typers.scala:3581)
> > at
> > scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4165)
> > at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4271)
> > at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
> > $1$1.apply(Typers.scala:3353)
> > at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedApply
> > $1$1.apply(Typers.scala:3353)
> > at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:624)
> > at
> > scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:
> > 3353)
> > at
> > scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:4104)
> > at scala.tools.nsc.typechecker.Typers$Typer.typedSelect
> > $1(Typers.scala:3581)
> > [..]
>
> > Am I something missing?
> > Or is this not working anymore?- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -
Sun, 2011-11-27, 13:37
#3
Re: Re: Dynamic keyword generates stackoverflow with -Xexperime
`x.bar(<args>)` becomes `x.applyDynamic("bar")(<args>)` if `x.bar` does not type check and x's type is a subtype of Dynamic
cheersadriaan
cheersadriaan
Mon, 2011-11-28, 14:27
#4
Re: Dynamic keyword generates stackoverflow with -Xexperimental
I get the same infinite recursion and stackoverflow with applyDynamic
Do you have a more explicit example how to do it?
Should I remove something as well?
On 27 nov, 13:30, Adriaan Moors wrote:
> `x.bar()` becomes `x.applyDynamic("bar")()` if `x.bar` does not
> type check and x's type is a subtype of Dynamic
>
> cheers
> adriaan
Mon, 2011-11-28, 15:17
#5
Re: Re: Dynamic keyword generates stackoverflow with -Xexperime
$ scala -Xexperimental
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).Type in expressions to have them evaluated.Type :help for more information.
scala> class DynamicImpl(x: AnyRef) extends Dynamic { | def applyDynamic(name: String)(args: Any*) = { | new DynamicImpl(x.getClass.getMethod(name).invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*)) | } | def typed[T] = x.asInstanceOf[T] | override def toString = "Dynamic(" + x.toString + ")" | }defined class DynamicImpl
scala>
scala> class Duck { | def quack = "Quack!" | }defined class Duck
scala>
scala> class QuackingSwan { | def quack = "Swack!" | }defined class QuackingSwan
scala> implicit def toDynamic(x: Any): DynamicImpl = new DynamicImpl(x.asInstanceOf[AnyRef]) toDynamic: (x: Any)DynamicImpl
scala>
scala> def makeQuack(d: DynamicImpl) { | println(d.quack.typed[String]) | }dynatype: d.applyDynamic("quack")() makeQuack: (d: DynamicImpl)Unit
scala>
scala> makeQuack(new Duck)Quack!
scala> makeQuack(new QuackingSwan)Swack!
hthadriaan
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).Type in expressions to have them evaluated.Type :help for more information.
scala> class DynamicImpl(x: AnyRef) extends Dynamic { | def applyDynamic(name: String)(args: Any*) = { | new DynamicImpl(x.getClass.getMethod(name).invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*)) | } | def typed[T] = x.asInstanceOf[T] | override def toString = "Dynamic(" + x.toString + ")" | }defined class DynamicImpl
scala>
scala> class Duck { | def quack = "Quack!" | }defined class Duck
scala>
scala> class QuackingSwan { | def quack = "Swack!" | }defined class QuackingSwan
scala> implicit def toDynamic(x: Any): DynamicImpl = new DynamicImpl(x.asInstanceOf[AnyRef]) toDynamic: (x: Any)DynamicImpl
scala>
scala> def makeQuack(d: DynamicImpl) { | println(d.quack.typed[String]) | }dynatype: d.applyDynamic("quack")() makeQuack: (d: DynamicImpl)Unit
scala>
scala> makeQuack(new Duck)Quack!
scala> makeQuack(new QuackingSwan)Swack!
hthadriaan
Mon, 2011-11-28, 16:07
#6
Re: Dynamic keyword generates stackoverflow with -Xexperimental
Thanks that works.
I had Dynamic as returntype in toDynamic and val s and
argumenttype in makeQuack instead of DynamicImpl
package dynamicallytyped
object Main extends App {
class DynamicImpl(x: AnyRef) extends Dynamic {
def applyDynamic(name: String)(args: Any*) = {
new DynamicImpl(x.getClass.getMethod(name).invoke(x,
args.map(_.asInstanceOf[AnyRef]) : _*))
}
//def _select_(name: String): DynamicImpl = {
// new DynamicImpl(x.getClass.getMethod(name).invoke(x))
//}
//def _invoke_(name: String)(args: Any*) = {
// new DynamicImpl(x.getClass.getMethod(name,
args.map(_.asInstanceOf[AnyRef].getClass) : _*).invoke(x,
args.map(_.asInstanceOf[AnyRef]) : _*))
//}
def typed[T] = x.asInstanceOf[T]
override def toString = "Dynamic(" + x.toString + ")"
}
implicit def toDynamic(x: Any): DynamicImpl = new
DynamicImpl(x.asInstanceOf[AnyRef])
class Duck {
def quack = "Quack!"
}
class QuackingSwan {
def quack = "Swack!"
}
def makeQuack(d: DynamicImpl) {
println(d.quack.typed[String])
}
makeQuack(new Duck)
makeQuack(new QuackingSwan)
val s: DynamicImpl = "Hello, world!"
println(s.toLowerCase.typed[String])
println(s.length.typed[Int])
println(s.isEmpty.typed[Boolean])
}
C:\scala-2.9.1.final\examples>scalac -Xexperimental
dynamicallytyped.scala
dynatype: d.applyDynamic("quack")()
dynatype: Main.this.s.applyDynamic("toLowerCase")()
dynatype: Main.this.s.applyDynamic("length")()
dynatype: Main.this.s.applyDynamic("isEmpty")()
C:\scala-2.9.1.final\examples>scala dynamicallytyped.Main
Quack!
Swack!
hello, world!
13
false
On 28 nov, 15:07, Adriaan Moors wrote:
> $ scala -Xexperimental
>
> Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM,
> Java 1.6.0_29).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> class DynamicImpl(x: AnyRef) extends Dynamic {
> | def applyDynamic(name: String)(args: Any*) = {
> | new DynamicImpl(x.getClass.getMethod(name).invoke(x,
> args.map(_.asInstanceOf[AnyRef]) : _*))
> | }
> | def typed[T] = x.asInstanceOf[T]
> | override def toString = "Dynamic(" + x.toString + ")"
> | }
> defined class DynamicImpl
>
> scala>
>
> scala> class Duck {
> | def quack = "Quack!"
> | }
> defined class Duck
>
> scala>
>
> scala> class QuackingSwan {
> | def quack = "Swack!"
> | }
> defined class QuackingSwan
>
> scala> implicit def toDynamic(x: Any): *DynamicImpl* = new
> DynamicImpl(x.asInstanceOf[AnyRef])
> toDynamic: (x: Any)DynamicImpl
>
> scala>
>
> scala> def makeQuack(d: DynamicImpl) {
> | println(d.quack.typed[String])
> | }
> dynatype: d.applyDynamic("quack")()
> makeQuack: (d: DynamicImpl)Unit
>
> scala>
>
> scala> makeQuack(new Duck)
> Quack!
>
> scala> makeQuack(new QuackingSwan)
> Swack!
>
> hth
> adriaan
Mon, 2011-11-28, 16:17
#7
Re: Dynamic keyword generates stackoverflow with -Xexperimental
So for Dynamic types subtype polymorphism doesn't work or was that
part of the bug as well?
Mon, 2011-11-28, 16:27
#8
Re: Re: Dynamic keyword generates stackoverflow with -Xexperime
On Mon, Nov 28, 2011 at 4:09 PM, Dave <dave.mahabiersing@hotmail.com> wrote:
So for Dynamic types subtype polymorphism doesn't work or was thatnope, whether to insert an applyDynamic is decided statically
part of the bug as well?
the reason it overflows is that it can't find the applyDynamic method, so it's looking for the applyDynamic method to call the applyDynamic method (I could go on for a while)
solution: implement the applyDynamic method in DynamicImpl
On Sat, Nov 26, 2011 at 12:04 PM, Dave <dave.mahabiersing@hotmail.com> wrote: