Created
April 6, 2012 09:10
-
-
Save clhodapp/2318356 to your computer and use it in GitHub Desktop.
SOC 2012 Proposal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Name: Christopher Hodapp | |
Institution: The University of Alabama | |
Program: Computer Science | |
Graduation: May 2012 | |
Proposal Title: Dynamic Scala | |
Email: [email protected] | |
Phone: +19372199307 | |
About me: I am a 4th (final) year undergraduate Computer Science | |
student at the University of Alabama. I plan to resume my studies at | |
the same university next fall with the goal of eventually getting a | |
Master's degree in Computer Science. I have had courses in | |
Programming Languages, Data Structures, and Algorithms. While I was | |
taking Programming Languages, I created an interpreter for a simple | |
dynamic language of my own design (http://bit.ly/IaBRuR). It's been a | |
very long time since I've done anything with it. I am currently in a | |
Formal Languages Course (Pushdown Automata, Turing Machines, etc.). | |
I'm currently doing independent study work for two professors. In the | |
first independent study work with two professors. First, I'm working | |
with another student to port a source code feature extraction program | |
that is currently written in Python to Java. The code for that project | |
will be put online when it's done, but it's not available now. Second, | |
I'm finishing an automated (Android) App Inventor to Java | |
(libsimpleandroidruntime) porting tool. The project was started by | |
another student, but he left in a very rough (nonfunctional) state. | |
That project is not fully working yet, but you can see its current | |
state at http://bit.ly/I0UMtg. I am also paid to develop Android apps | |
to collect laboratory by another professor. | |
I learned Scala from "Programming In Scala" last year and I thoroughly | |
enjoy the language. | |
I am also familiar with the following langauges: Java, C, C++, Scheme, | |
Python | |
I've done a tiny bit of Ruby and I'm working through Learn You A | |
Haskell. | |
====================================================================== | |
Scala is a language grounded in principles of pragmatism. It allows | |
the developer to write code in many styles and paradigms. It also | |
allows code written in different paradigms to seamlessly interact. The | |
classic example of this is the way that Scala allows the developer to | |
use a blend of functional and object-oriented programming techniques. | |
I propose that I spend this summer working to allow Scala to support a | |
new paradigm: Dynamic typing. | |
The way I envision it, dynamically typed code would look like this: | |
""" | |
import language.Dynamic | |
class Foo { | |
def double(x) = x * 2 | |
} | |
object Main extends App { | |
val a = 3 | |
val b = "abc" | |
val f = new foo | |
println(f.double(a)) | |
println(f.double(b)) | |
} | |
""" | |
This code would print 6 and "abcabc" on lines. | |
As with the example functional/Object Oriented case given earlier, | |
static and dynamic code would need to be able to interact seamlessly. | |
I do have a partial strategy for making this happen. The first phase | |
of my implementation idea builds on top of the Dynamic marker trait | |
described in SIP 17. I want to create a type hierarchy rooted on this | |
trait and prototyped below: | |
""" | |
trait DynamicRef { | |
val referenced: Any = this | |
private[this] val rt = mirror.typeOfInstance(referenced) | |
import DynamicBox._ | |
private[this] def convertVal(sym: mirror.Symbol) = { | |
sym match { | |
case s if s == mirror.classToSymbol(classOf[Int]) => | |
mirror.classToSymbol(classOf[java.lang.Integer]) | |
case s if s == mirror.classToSymbol(classOf[Long]) => | |
mirror.classToSymbol(classOf[java.lang.Long]) | |
case s if s == mirror.classToSymbol(classOf[Byte]) => | |
mirror.classToSymbol(classOf[java.lang.Byte]) | |
case s if s == mirror.classToSymbol(classOf[Char]) => | |
mirror.classToSymbol(classOf[java.lang.Character]) | |
case s if s == mirror.classToSymbol(classOf[Boolean]) => | |
mirror.classToSymbol(classOf[java.lang.Boolean]) | |
case s if s == mirror.classToSymbol(classOf[Short]) => | |
mirror.classToSymbol(classOf[java.lang.Short]) | |
case s if s == mirror.classToSymbol(classOf[Float]) => | |
mirror.classToSymbol(classOf[java.lang.Float]) | |
case s if s == mirror.classToSymbol(classOf[Double]) => | |
mirror.classToSymbol(classOf[java.lang.Double]) | |
case _ => | |
sym | |
} | |
} | |
def applyDynamic(name: String)(args: Any*): DynamicRef = { | |
val argSymbols = args.map(arg => mirror.symbolOfInstance(arg)) | |
val namesMatch = rt.members.filter(_.name == mirror.newTermName(name)) | |
val exactMatch = namesMatch.filter( method => | |
method.typeSignature match { | |
case mirror.MethodType(params, _) => | |
params.map(p => convertVal(p.asType.typeSymbol)).toList == argSymbols.toList | |
case _ => | |
false | |
} | |
) | |
if (exactMatch.size == 1) | |
mirror.invoke(referenced.asInstanceOf[AnyRef], exactMatch.head)(args: _*).toDynamic | |
else | |
// try upcasting arguments | |
// else | |
sys.error("not found") | |
} | |
def is[T](implicit t: ClassManifest[T]) = rt.baseClasses.contains(t.symbol) | |
def as[T] = referenced.asInstanceOf[T] | |
override def toString = referenced.toString | |
} | |
class DynamicBox private(underlying: Any) extends DynamicRef { | |
override val referenced = underlying | |
} | |
object DynamicBox { | |
def apply(underlying: Any) = | |
if (underlying.isInstanceOf[DynamicRef] underlying | |
else new DynamicBox(underlying) | |
implicit def anyRef2boxWithMethod(underlying: AnyRef) = new BoxWithMethod(underlying) | |
} | |
class BoxWithMethod(underlying: AnyRef) { | |
def toDynamic = DynamicBox(underlying) | |
} | |
""" | |
The idea is to have a dynamic reference type with generic | |
implementations of the applyDynamic, applyNamedDynamic, updateDynamic, | |
and selectDynamic (henceforth this list will be called "*Dynamic") | |
methods that use reflection to call through to the | |
properly-named/properly-parametered methods. This allows you to call | |
method on an object of this type even if you only have a reference of | |
type DynamicRef. Alternately, you could say that method binding for | |
references of type DynamicRef is delayed until runtime. There must | |
also be a dynamic box class which can wrap a non-dynamic object and | |
make it dynamic in order to serve as the return type of the *Dynamic | |
methods. Note that the type of a DynamicRef can be checked against a | |
specified static type with the is method and the referenced object can | |
be retrieved as a specified static type with the as method. | |
This prototype actually works for simple cases, but it has some | |
issues: It will not upcast in order to make a call work. It does not | |
support type parameters or multiple parameter lists. Also, it does not | |
support implicits (it should check for implicits defined at the call | |
site and at the definition site of both argument and parameter types). | |
Christopher Vogt, an engineer at EPFL, has create an implementation of | |
DynamicRef at http://bit.ly/HiR1mn that uses the Toolbox reflective | |
compiler and works with implicits in some circumstances (we haven't | |
figured out exactly what rules govern when it does and doesn't work | |
yet). Christopher and I have also discussed DynamicRef Skype. That | |
discussion actually forms the basis of this proposal. At the end of | |
our discussion, we could not figure out how to write *Dynamic methods | |
that accept an unbounded number of type parameters and curried | |
parameter lists. I still have not been able to figure out a way to do | |
this. It is likely that new language features would be necessary if | |
this functionality is deemed necessary. | |
The second part of my implementation plan requires modifications to | |
the compiler and the Scala language specification. The actual features | |
are simple: when the feature flag language.Dynamic is in scope, the | |
compiler silently behaves as if all declared classes mix in and all | |
traits extend the DynamicRef trait. It also behaves as if all vals, | |
var, and method parameters without a programmer-specified type are of | |
type DynamicRef and as if all methods without a programmer-specified | |
return type return DynmaicRef. That is to say, it behaves as if | |
""" | |
class Foo { | |
def double(x) = x * 2 | |
} | |
""" | |
were | |
""" | |
class Foo extends DynamicRef { | |
def double(x: DynamicRef): DynamicRef = x * 2 | |
} | |
""" | |
That's it. Implementing this type hierarchy and these compiler | |
features should be all that is necessary to get to the point where | |
Scala is not just functional and object oriented, it's also static and | |
dynamic. | |
Here is the timeline that I envision for this project: | |
Now - 21 May : Get more familiar with the Scala codebase | |
: Read/post to mailing lists a lot | |
: Figure how to add compiler/lang features I will need | |
21 MAY - 4 JUL : Implement the 1st part of proposal (DynamicRef) | |
4 JUL - 9 JUL : Review methods / find bugs / buffer | |
9 JUL - 11 JUL : Midterm Evaluation | |
11 JUL - 13 AUG : Implement 2nd part of proposal (compiler features) | |
13 Aug - 20 AUG : Buffer / Documentation | |
20 AUG - 24 AUG : Final Evaluation |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment