Does anyone know the status of a fully-featured reflection API for Scala?
I know that you can use Java's reflection API to do simple things but this does not work well with Scala's language features. I found an interesting article describing an experimental Scala Mirroring API but as far as I know this is still experimental. I've also found mention of a ScalaSigParser but this seems to be pretty low level.
This is more of a curiosity than anything else as I am currently just playing around with Scala. I thought that the answer to this question might also be useful to others interested in Scala.
The "immutable replacement for the JavaBean style pattern" can be expressed named parameters and optionally the #BeanProperty annotation:
import reflect._
case class A(#BeanProperty val x: String, #BeanProperty val y : Int)
A(x = "s", y = 3)
A(y = 3, x = "s")
Adding methods (more precise: defining a new interface) makes only sense in a statically typed language if the client knowns about the new methods and can compile against the interface. With structural typing clients can define methods they expect to be present in an object. The Scala compiler will transform the structural type into reflection code which may fail at runtime.
type T = {def go(x : Int): Int }
def y(any : Any) = any.asInstanceOf[T].go(2)
class A{
def go(x : Int) = x + 1
}
y(new A())
y(new {}) //this will fail
You can define new classes or traits with the interpreter on the fly. The Interpret method transforms Scala code to byte code.
You've already mentioned the ScalaSigParser which is not exactly easy to work with.
I think the rest of features you like are not there yet.
Related
I have been trying to understand the type system for Julialang but some design aspects are still confusing me. I was hoping someone could clarify.
So the question here is about Abstract Types and their concrete implementations. From what I understand Julia Abstract types do not enforce any constraints on their concrete implementations. So there is no guarantee that a method that works on the Abstract type will work on a concrete implementation of that type.
I get that Julia does not use classes or follow inheritance. But I just want to avoid generating all sorts of bugs in my code. If there is a different design paradigm, then could someone please answer question 2 below.
So I have 2 questions.
Is this still the way that the language works? Just to confirm nothing has changed since the blog post.
How do users design their software around this seeming vulnerability?
And example of the issue from the linked post:
abstract type AbstractPerson end
abstract type AbstractStudent <: AbstractPerson end
abstract type AbstractTeacher <: AbstractPerson end
struct Person <: AbstractPerson
name::String
end
struct Student <: AbstractStudent
name::String
grade::Int
hobby::String
end
struct MusicStudent <: AbstractStudent
grade::Int
end
Now if I create some methods on the abstract type.
get_name(x::AbstractPerson) = x.name
p1 = Person("elroy")
get_name(p1)
>"elroy"
So even if MusicStudent is a subtype of AbstractPerson, the MusicStudent DOES NOT have a name attribute. That means that to following behavior is observed.
m1 = MusicStudent(10)
get_name(m1)
ERROR: type MusicStudent has no field name
Stacktrace:
[1] getproperty(::Any, ::Symbol) at ./sysimg.jl:18
[2] get_name(::MusicStudent) at ./In[2]:1
[3] top-level scope at In[13]:2
So the problem here is that Julia allows me to instantiate the type variable m1 with essentially an incomplete constructor. And it only gives me an error when I try to run that function.
So that means if I write a function for the Abstract Type, I can't guarantee every concrete implementation of that type has the same interface. That seems like it will make very fragile code as the developer won't know which types implement which attributes and methods.
Isn't this kind of behavior just a bug in the implementation of the Persons? If you really want the behavior to go without exception you can define a default method:
julia> get_name(p::AbstractPerson) = try return p.name catch y return "" end
get_name (generic function with 1 method)
julia> m1 = MusicStudent(10)
MusicStudent(10)
julia> get_name(m1)
""
I think the underlying struggle may be that in Julia you cannot inherit the data field called "name" as part of the object hierarchy. There is a nice discussion of that genuine issue here (see the mention of the #forward macro):
https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231
The basic answer is that in julia the interface of a method is thought of as the methods that are defined to take an element of that type. AbstractArray for example specifies that implementations should implement getIndex and size. The reason to not make fields part of the interface is that not doing so allows for memory efficient code, since each type can define the methods in the most sensible way. For example if I want to make a type called Bob that is a subtype for all people named bob, I don't want to store his name every time. by using methods, Julia allows much more potential for future expansion in unexpected ways.
Technically this approach loses "safety", but the only way it does is if you write code using fields that might not exist, in which case you will get an error. This type of safety isn't that useful since it just gives you a compile error that slows down development.
Support for reflection has been currently added into F#, but it is not working for measure types. Is it possible to use reflection in F# for measure types?
I've read this. It was for 2008, but if you check some code like bellow in ildasm you cannot see anything about Units of Measure.
// Learn more about F# at http://fsharp.net
[<Measure>] type m
[<Measure>] type cm
let CalculateVelocity(length:float<m> ,time:float<cm>) =
length / time
The ildasm output:
.method public static float64 CalculateVelocity(float64 length,
float64 time) cil managed
{
// Code size 5 (0x5)
.maxstack 4
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: div
IL_0004: ret
} // end of method Program::CalculateVelocity
So there are somethings that cannot be reflected in F#. Is it true or not?
see the comment : Units actually don't get seen at all by the CLR ... in the article.
As others already pointed out, when you need to get some information about compiled F# types, you can use standard .NET reflection (System.Reflection) and F# reflection which provides information about discriminated unions, records, etc. (Microsoft.FSharp.Reflection).
Unfortunatelly, information about units of measure cannot be accessed using any of these two APIs, because they are checked only during the compilation and do not actually exist at runtime (they cannot be represented in the CLR in any way). This means that you'll never be able to find out whether e.g. a boxed floating point value has some unit of measure...
You can get some information about units of measure using Metadata namespace from F# PowerPack. For example, the following prints that foo is a unit:
namespace App
open System.Reflection
open Microsoft.FSharp.Metadata
[<Measure>]
type foo
module Main =
let asm = FSharpAssembly.FromAssembly(Assembly.GetExecutingAssembly())
for ent in asm.Entities do
if ent.IsMeasure then
printfn "%s is measure" ent.DisplayName
This reads some binary metadata that the compiler stores in compiled files (so that you can see units when you reference other F# libraries), so you should be able to see informaiton about public API of F# libraries.
Units of Measure is just a compile-time thing, it doesn't exist in the assembly/CLR.
From part one:
Units-of-measure are not just handy
comments-on-constants: they are there
in the types of values, and, what's
more, the F# compiler knows the rules
of units.
You can:
.NET and F# Reflection
The F# library also extends the .NET System.Reflection to give additional information about F# data types
Source
Is there a language, which is:
1) functional
2) has type inference
3) has currying
4) and has types as first-class values
also would like to compile from it to JVM and/or CLR
F# is functional and has type inference, currying and types as first-class values in the sense that you can dissect types at run-time via reflection. It compiles to the CLR and works well on Mono.
EXAMPLE: Taken from my (non-free) article Structural Typing in the F#.NET Journal:
The following createType function creates a new .NET assembly, new module and new public class type of the given name:
> let createType typeName =
let name = System.Reflection.AssemblyName(Name="tmpAssembly")
let run = System.Reflection.Emit.AssemblyBuilderAccess.Run
let builder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(name, run)
let mdl = builder.DefineDynamicModule "tmpModule"
let attrs = TypeAttributes.Public ||| TypeAttributes.Class
mdl.DefineType(typeName, attrs);;
val createType : string -> TypeBuilder
I just started learning it but Coq might work for you.
It's quite possible to have a function which takes in a type (yes a raw type, not an instance of that type) and return another type (again, just the type, not an instance). If you're at all interested in formal verification of programs it's worth a look.
It also has the nice little benefit of being able to convert it's code to Haskell/OCaml/Scheme so that you can use their IO/Libraries since Coq tends lacks them.
It has type inference and currying but the type inference isn't perfect as the language's type system is well beyond (and more expressive than) a standard Milner-Hindley type system.
Take a look at Scala, it works on both JVM and .NET. Here is some features including what you seek - http://www.scala-lang.org/node/104, look at "Scala is functional" section, "Local Type Inference", "Currying" and "Predefined function classOf" articles, also it has top type Any, pattern matching for values and types, reflect package.
First start from wikipedia type interference. Answer for this question seems to be Haskell or OCaml.
Only recently, I discovered that both Java and C# do not support reflection of local variables. For example, you cannot retrieve the names of local variables at runtime.
Although clearly this is an optimisation that makes sense, I'm curious as to whether any current languages support full and complete reflection of all declarations and constructs.
EDIT: I will qualify my "names of local variables" example a bit further.
In C#, you can output the names of parameters to methods using reflection:
foreach(ParameterInfo pi in typeof(AClass).GetMethods()[0].GetParameters())
Trace.WriteLine(pi.Name);
You don't need to know the names of the parameters (or even of the method) - it's all contained in the reflection information. In a fully-reflective language, you would be able to do:
foreach(LocalVariableInfo lvi in typeof(AClass).GetMethods()[0].GetLocals())
Trace.WriteLine(lvi.Name);
The applications may be limited (many applications of reflection are), but nevertheless, I would expect a reflection-complete language to support such a construct.
EDIT: Since two people have now effectively said "there's no point in reflecting local variable names", here's a basic example of why it's useful:
void someMethod()
{
SomeObject x = SomeMethodCall();
// do lots of stuff with x
// sometime later...
if (!x.StateIsValid)
throw new SomeException(String.Format("{0} is not valid.", nameof(x));
}
Sure, I could just hardcode "x" in the string, but correct refactoring support makes that a big no-no. nameof(x) or the ability to reflect all names is a nice feature that is currently missing.
Your introductory statement about the names of local variables drew my interest.
This code will actually retrieve the name of the local var inside the lambda expression:
static void Main(string[] args)
{
int a = 5;
Expression<Func<int>> expr = (() => a);
Console.WriteLine(expr.Compile().Invoke());
Expression ex = expr;
LambdaExpression lex = ex as LambdaExpression;
MemberExpression mex = lex.Body as MemberExpression;
Console.WriteLine(mex.Member.Name);
}
Also have a look at this answer mentioning LocalVariableInfo.
Yes, there are languages where this is (at least kind of) possible. I would say that reflection in both Smalltalk and Python are pretty "complete" for any reasonable definition.
That said, getting the name of a local variable is pretty pointless - by definition to get the name of that variable, you must know its name. I wouldn't consider the lack of an operation to perform that exact task a lacuna in the reflection facility.
Your second example does not "determine the name of a local variable", it retrieves the name of all local variables, which is a different task. The equivalent code in Python would be:
for x in locals().iterkeys(): print x
eh, in order to access a local var you have to be within the stackframe/context/whatever where the local var is valid. Since it is only valid at that point in time, does it matter if it is called 't1' or 'myLittlePony'?
Is their an equivalent to C#'s Expression API in scala?
For example, I would like to have a lambda like this:
(Foo) => Foo.bar
and be able to access "bar" in the function it is passed to.
This is not supported by Scala. ScalaQL: Language-Integrated Database Queries
for Scala describes a LINQ-like functionality in Scala:
While it is possible for Microsoft to
simply extend their language with this
particular feature, lowly application
developers are not so fortunate. For
exam- ple, there is no way for anyone
(outside of Sun Microsystems) to
implement any form of LINQ within Java
because of the language modications
which would be required. We faced a
similar problem attempting to
implement LINQ in Scala.
Fortunately, Scala is actually
powerful enough in and of itself to
implement a form of LINQ even without
adding support for expression trees.
Through a combination of operator
overloading, implicit conversions, and
controlled call- by-name semantics, we
have been able to achieve the same
eect without making any changes to
the language itself.
There is an experimental scala.reflect.Code.lift which might be of interest, but the short answer is no, Scala does not have access to the AST in any form (expression trees are a subset of C#'s AST).
It's not quite clear to me what you want. If you want a function that returns a getter for a field, you can do that quite easily:
class Holder(var s: String) { }
class StringSaver(f: Holder => (() => String), h: Holder) {
val getter = f(h)
def lookAtString = getter()
}
val held = new Holder("Hello")
val ss = new StringSaver((h: Holder) => (h.s _) , held)
println(ss.lookAtString)
held.s = "Bye now"
println(ss.lookAtString)
The key is to turn the getter h.s into a function via (h.s _).
No, to the best of my knowledge.