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

Dynamic keyword generates stackoverflow with -Xexperimental

8 replies
DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.

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?

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
Re: Dynamic keyword generates stackoverflow with -Xexperimental
no, that's a bug, sorryit's fixed in the virtualizing compiler (https://github.com/adriaanm/scala-dev/tree/virtualized-mostrecent), the fix should percolate to trunk eventually
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:
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?

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
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 -

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
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
DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
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

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
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
DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
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

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
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?

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
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 that
part of the bug as well?
nope, whether to insert an applyDynamic is decided statically

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