A brief overview of type system metadata in various languages

So given that a class that is nothing more than a data bag. After all, each object is just a bag of dict’s which are pointers to some byte array some place. What can we introspect about the byte array in each language?

The following is my attempt to document my metadata experiments.

Let’s start with .Net, its what I know the best and what I am ultimately comparing everything too.

.Net

public class Loan
{
    public decimal Amount { get; set; }
}

var aLoan = new Loan {Amount=5};
aLoan.GetType();
//an instance of Type filled with data about Loan
for(var prop in aLoan.GetType().GetProperties())
{
    Console.WriteLine(prop.Name);
}
aLoan.GetType().GetProperty("Amount");
//returns an instance of PropertyInfo

Links:

Type: http://msdn.microsoft.com/en-us/library/system.type.aspx
PropertyInfo: http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.aspx

Ruby

class Loan
    attr_accessor :amount
    def initialize(initialAmount)
        @amount = initialAmount
    end
end

aLoan = Loan.new 5
aLoan.class #Loan
aLoan.method(:amount) #a method object

After playing around, I couldn’t find anyway to get the type returned by the ‘amount’ function. This is exactly what I expected, but wanted to confirm. I could get the number of arguments via the ‘arity’ method. That said, I was able to extract a lot more information than I had expected. Special thanks to @jflanagan for the much need schooling in ruby.

Links:

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Accessor_Methods

http://ruby-doc.org/core-1.9.3/Method.html

Python

class Loan(object):
    def __init__(self, initialAmount):
        self._amount = initialAmount

    @property
    def amount(self):
        return self._amount

aLoan = Loan(5)
aLoan.__class__ #Loan
aLoan.amount #nope, this returns 5
dir(aLoan) #return 'all the things'

Links

http://docs.python.org/library/functions.html#property

JavaScript

function Loan(initialAmount) {
    //as recommended by Ryan Rauh
    this.amount = initialAmount;
    return this;
}

var aLoan = new Loan(5);
typeof(aLoan); //object
Object.getPrototypeOf(aLoan).constructor.name; //Loan
for(prop in aLoan) {console.log(prop)}; //prop is a string
typeof(aLoan['amount']); //number
//this is actual a typeof(5)

I was again surprised at how much I could extract. Special thanks to @rauhryan for the JavaScript schooling.

Beyond my reach (for now)

So I wanted to do some other languages outside my comfort zone like lisp, haskell, and erlang. But my brain was exploded by the very different nature of the languages. What I do have is how I would set the structure up roughly in the various languages. I hope to come back overtime and update this as I learn or people share with me. :)

Lisp

('Loan, ('Amount, 20))

Haskell

data Loan = Loan { Amount :: Int }

http://www.cs.auckland.ac.nz/references/haskell/haskell-intro-html/moretypes.html

Erlang

-record(Loan, { Amount })

Links:

http://www.erlang.org/doc/reference_manual/records.html

 

Any feedback on how to do these kinds of things in other languages will be most appreciated.

-d

About Dru Sellers

Sr. Software Engineer at Dovetail Software.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.articleteller.com.au/ Article writer

     Amazing information in typing for a various language in programming. I wanted to thank you for this good read!! I definitely enjoyed every little bit of it. I have got you bookmarked to look at new stuff you post…

  • http://www.exsystems.co.uk/?page_id=1349 Rita Joel2011

    I don’t think methods in ruby do have return types. But there is nothing wrong anywhere else. You did it right. 

  • Anonymous

    You are 100% correct, I am in fact trying to apply as much static typed logic as possible to see WHAT I can extract. I am well aware of why this is bad, but in the end I ended up learning that the dynamic languages provide quite a bit more data than I expected. :) Thanks for stopping by Pete!

  • Pete

    Dru I think you are trying to apply statically typed language logic to a different world of dynamicaly typed languages. In C# you define what a certain method returns while in Python and Ruby you don’t. That is a very fundamental difference. Imagine every method in C# returned System.Object and you wouldn’t be much interrested what the return type is rather what the type of actually returned object is – just like Tim Arnold explains.

  • http://domenicdenicola.com/ Domenic Denicola

    For JavaScript:

    Object.getOwnPropertyDescriptor(aLoan, “amount”)

  • Chris Tavares

    Much like Ruby, Python methods don’t have return types, they return object. You can’t do much more than get the return type for an object that was returned by an invocation.

  • Anonymous

    You may not be able to. Its going to be some kind of reflection lib for python based on my research.

  • Tim Arnold

    well now I understand what you meant, but unfortunately I do not know of a way to get info.

  • Anonymous

    Exactly.

  • Anonymous

    agreed. :)

  • anonymous

    The correct link is: http://rosettacode.org

  • http://chadmyers.lostechies.com Chad Myers


    Methods in ruby do not have return types. Method invocations do.” – And this is because you can’t really know what the method will return unless you actually invoke it, right? Because you can return all sorts of things (including multiple things) from a method invocation, right?

  • anonymous

    This sounds like a task for http://www.rosetta.com which at the moment does not have a task for reflection.

  • Anonymous

    Thank you for the java sample!

  • Anonymous

    Don’t think that wasn’t on purpose. ;)

  • Anonymous

    Thank you for the F# example.

  • Anonymous

    Does that give me the type of the object returned by the method/property ‘amount’? They way I am reading that, aLoan.amount is getting invoked, returning a 5, which is passed into type(5) which is an ‘int’. What I really want is a ‘Method’ or ‘MethodInfo’ type object, returned for the amount method/property. :)

  • Anonymous

    It is not. Your code will return “Method” – which is the class of the object returned by a call to #method. 
    Methods in ruby do not have return types. Method invocations do. The following code works, but it is a little different than what Dru is asking for:aLoan.amount.class

  • Tim Arnold

    maybe I’m not understanding, but in Python, just add
    print type(aLoan.amount) #

  • http://twitter.com/scorintha Mark Nyon

    For your Ruby example, getting the type returned should be as simple as what’s written below. Let me know if that helps.

    aLoan.method(:amount).class

  • http://twitter.com/ntcoding Nick

    Great idea for a post. Well done.

  • twisterjosh

    Let’s not forget about the best language ever: F#!!!

    type Loan(amount) =
        member x.Amount = amount

    let aLoan = new Loan(5.0)
    aLoan.GetType()
    //an instance of Type filled with data about Loan
    [ for x in aLoan.GetType().GetProperties() -> x ] 
        |> Seq.iter (fun i -> printfn “%s” i.Name)
    aLoan.GetType().GetProperty(“Amount”);
    //returns an instance of PropertyInfo

  • Stu Smith

    As a starting point for Haskell, you could try the following:

    {-# LANGUAGE DeriveDataTypeable #-}

    import Data.Typeable

    data Loan = Loan { amount :: Int }  deriving (Typeable)

    Then you can experiment a little:

    typeOf Loan

    typeOf amount

  • Anonymous

    LOL maybe it’s because I recently watched that Louis CK stand up special, but I found this line hilarious.

    > After all, each object is just a bag of dict’s which …

  • http://ankitkhandelwal6.myopenid.com/ Ankit Khandelwal

    Java Reflection provides support for making runtime check on the types.
    Reproducing here code snippet from http://java.sun.com/developer/technicalArticles/ALT/Reflection/index.html#4

    import java.lang.reflect.*;

    public class field1 {
    private double d;
    public static final int i = 37;
    String s = “testing”;

    public static void main(String args[])
    {
    try {
    Class cls = Class.forName(“field1″);

    Field fieldlist[]
    = cls.getDeclaredFields();
    for (int i
    = 0; i < fieldlist.length; i++) {
    Field fld = fieldlist[i];
    System.out.println("name
    = " + fld.getName());
    System.out.println("decl class = " +
    fld.getDeclaringClass());
    System.out.println("type
    = " + fld.getType());
    int mod = fld.getModifiers();
    System.out.println("modifiers = " +
    Modifier.toString(mod));
    System.out.println("—–");
    }
    }
    catch (Throwable e) {
    System.err.println(e);
    }
    }
    }

  • Anonymous

    Yes, I made up attr_float and method_metadata. One throws some data in a hash, the other one pulls it out. Metadata!

  • Anonymous

    And the education continues. :) – ahh, so the bit you added was the ‘attr_float’ bit right? Excellent! Thank you for sharing. 

  • Anonymous

    There is no “type returned by the ‘amount’ function” in Ruby. That is, not until you call it. It could be any type, depending on how you choose to use it. That’s the beauty.

    Now, if you thought it was really important to be able to declare and retrieve information about what you expect a function to return, it would be trivial to add some metadata to get something like this:

    class Loan
    attr_float :amount
    def initialize(initialAmount)
    @amount = initialAmount
    end
    end

    aLoan = Loan.new 5
    aLoan.class #Loan
    aLoan.method_metadata(:amount).return_class # Float