Dashboard > People > Terence Parr > Browse Space > News from
  Terence Parr Log In | Sign Up   View a printable version of the current page.  
  News from September, 2007
  2007/09/21
Last changed: Sep 21, 2007 13:58 by Terence Parr

Mantra is coming along nicely. Added type annotations, but am not doing anything with them yet.  Without much optimization (and huge amounts of memory allocation), Mantra loop and list append are looking good:

a = [];
1..5000000:{int i | a += i;};

The equivalent python:

a = [];
for i in range(5000000):
        a.append(i);

My unscientific wallclock measurements on my dual cpu mac (powerpc) with Java 1.5 shows Java doing about 3.0s vs 3.9s in python.  I am using way more memory though I think.

When I make use of type info manually converting the += operator to a direct list.add operation rather than general message send, it goes much faster: 2.6s.  I simply converted:

main_locals.a.invoke("+=",new mobject[]{closure1_args.i});

to

((mlist)main_locals.a).add(closure1_args.i);

On the other hand, python's highly optimized file I/O kicks Mantra's butt right now.  Here is my word frequency code:

// for each filename, generate a histogram
wfreq = map();

args:{ string filename |
    f = File(filename);
    f => words() => { string w |
        c=wfreq[w];
        if ( c is null ) wfreq[w]=mutint(1);
        else c++;
    };
};

pairs = wfreq.items(); // return list of 2-tuples (key/value pairs)
pairs.sort({int x, int y | return x[1].compareTo(y[1]);});
pairs.backwards():{list p | print(p[1]); print(" "); println(p[0]);};

Processing a 5M file of text, takes about 3.6s in Mantra, but only 1.1s in Python. Here's the python code:

import sys
import string

freqtable = {}

def processfile(file, ftable):

    infile = open(file, 'r')

    for line in infile:
        words = line.split()
        for w in words:
            try:
                ftable[w] = ftable[w] + 1
            except KeyError:
                ftable[w] = 1

    infile.close()

for f in sys.argv[1:]:
    processfile(f, freqtable)

wordlist = freqtable.items()
wordlist.sort((lambda x, y : cmp(x[1], y[1])))
wordlist.reverse()

for p in wordlist:
    print p[0], p[1]
Posted at 21 Sep @ 1:56 PM by Terence Parr | 3 comments
  2007/09/30
Last changed: Sep 30, 2007 19:58 by Terence Parr

See http://www.linguamantra.org for more information.

Type annotations

Mantra is not a statically typed language like Java, though you'll see types specified in the code. These types are annotations kind of like "executable documentation". For example how many times have you done this in other dynamically typed languages like Ruby and Python:

f(a): ... # a is an int and f returns a list with blah blah

Mantra integrates such informal type information into the code like a statically typed language, but that information does not affect the validity of the statements in Mantra methods in any way. Mantra uses dynamic typing. "string s = 34;" compiles fine in mantra. The type information can be used to generate pre-and post-conditions that validate incoming and outgoing objects, relieving the programmer of that burden. The type information can also be used for optimization.

Delegates

This feature is essentially the same as a Ruby mixin ('cept no fields)

Delegates behave like abstract superclasses except that a class may delegate to more than one delegate (very much like multiple inheritance). Recall that abstract superclasses add functionality to subclasses and may refer to methods that don't have implementations in the abstract superclass. A subclass "includes" all of the methods and fields from the superclass except for those methods overridden in the subclass. A delegate differs only in that you cannot define fields and you do not have to provide abstract method declarations for method you call. References to methods become self.methodName() rather than the usual implied this.methodName().

Philosophically, delegates differ from abstract base classes in an important way: delegates are just code they do not talk about identity whereas the superclass/subclass relationship is normally one of identity ("is a" relationship). For example, a manager "is an" employee and a house cat "is a" feline (well, some people think they are human). In contrast, an input stream is not a kind of StreamSupport object, but it does want to reuse that code. Delegates in mantra provides the ability to share code without polluting the organization of the class hierarchy.

My desire for something like delegates came up when I realized that the exact same code for stream comparison should be included in all input streams. How do you do that without sharing the base class or duplicating code? One way is to can create a separate class containing the comparison code (call it a delegate). This code can be shared by multiple classes (the delegators) as long as they have pointers to an instance of the support (delegate) class. The support code reaches methods in the delegator through the use of a "back pointer". The following code illustrates the necessary infrastructure:

class Delegator {
    Delegate d = new Delegate(this);
    void foo() { bar(); }
    void bar() { d.bar(); } // delegator to other class
}

class Delegate {
    Delegator self;
    public Delegate(Delegator self) { this.self = self; }
    void bar() { System.out.println("bar()"); }
    void duh() { self.bar(); } // invokes bar from Delegator
}

All of that infrastructure is a hassle to do manually, but it works efficiently and clearly. Mantra delegates does all of this automatically.

Posted at 30 Sep @ 7:51 PM by Terence Parr | 0 comments

September 2007
Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            

Sep 30, 2007
Sep 21, 2007

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.1 Build:#806 May 06, 2007) - Bug/feature request - Contact Administrators