The Artima Developer Community
Sponsored Link

Weblogs Forum
What's next for Heron?

18 replies on 2 pages. Most recent reply: Jan 26, 2006 11:54 PM by Terje Slettebø

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 18 replies on 2 pages [ 1 2 | » ]
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

What's next for Heron? (View in Weblogs)
Posted: Jan 25, 2006 11:46 AM
Reply to this message Reply
Summary
Good question. Here is a brief summary of where I'm at and where I'm thinking of going.
Advertisement
So I successfully wrote and compiled a program using Heron which reverses the standard input.

def test() {
  string s;
  char c = getchar();
  {
    while (c != EOF) {
      s += c;
      c = getchar();
    };
    while (!s.is_empty()) {
      putchar(s.top());
      s.pop();
     };
  };
}
On my system this executes in less than 2 seconds. The executable size is just 50k, when compiled using MinGW. The comparable program written in C++ takes 100k and executes in roughly the same amount of time.

What I think is particularly cool is that the string class is exceedingly simple:

class string
{
  fields
  {
    stack[char] f_stack;
  }
  delegates
  {
    Stack[char] : f_stack;
  }
  public
  {
    def _init(cstring x) {
      while (x != NULL) {
        push(*x++);
      };
    }
    def _eq(self& x) : self& {
      clear();
      _plus_eq(x);
      return *this;
    }
    def _plus_eq(self& x) : self& {
      uint i=0;
      while (i < x.count()) {
        push(x[i]);
      };
      return *this;
    }
    def _plus(self& x) : self {
      return *this += x;
    }
  }
}

How's that for compact? What a difference delegations make. I guess to be fair I should include the Stack interface:

interface Stack[type T]
{
  inherits
  {
    Array[T];
  }
  requires
  {
    def push(T x) {
      uint old = count();
      inner;
      post(count() == old + 1);
    }
    def pop() {
      uint old = count();
      pre(!is_empty());
      inner;
      post(count() == old - 1);
    }
    def top() : T& {
      pre(!is_empty());
      inner;
    }
  }
  extension
  {
    def is_empty() : bool {
      return count() == 0;
    }
    def clear() {
      while (!is_empty()) {
        pop();
      };
    }
    def dup() {
      push(top());
    }
    def reverse() {
      if (count() < 1) return;
      int max = count() - 1;
      int n = (count() / 2) - 1;
      int i = 0;
      while (i < n) {
        swap_elements(i, max - i);
      };
    }
    def swap_elements(uint i, uint j) {
      T tmp = _subscript(i);
      _subscript(i) = _subscript(j);
      _subscript(j) = tmp;
    }
    def _plus_eq(T x) {
      push(x);
    }
  }
}

Now if you aren't impressed yet, then you probably aren't familiar with the C++ standard template library. Yes, I know you can do much of this in C#, but try comparing the execution speed and memory usage. That's right, Heron screams like a bat out of hell.

Whenever I reach a mile-stone with Heron, I usually tend to get overwhelmed and somewhat depressed by the list of things to do. It's not straightforward what the best next step is.

So the HeronFront compiler works more or less (at least for me, it'll probably bite your right arm off if you tried it). Obviously there are a lot of bugs, and no documentation. However I don't think now is the right time to start documenting the tool, and providing support to the masses. That would simply require more time and energy than I have. I think I should work on it a bit more, doing some field testing before I release it onto the public.

My current plan is to implement a HeronScript interpreter in Heron. I figure that'll reveal the nastiest bugs, and hopefully demonstrate that Heron is going to be a serious force to be reckoned with in the not-too-distant future.


James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's next for Heron? Posted: Jan 25, 2006 12:24 PM
Reply to this message Reply
> This is not something you
> can do easily with many languages.

Are you joking here?

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: What's next for Heron? Posted: Jan 25, 2006 12:54 PM
Reply to this message Reply
> > This is not something you
> > can do easily with many languages.
>
> Are you joking here?

I meant the performance not the task. I erased the statement anyway to avoid any controversy.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's next for Heron? Posted: Jan 25, 2006 1:05 PM
Reply to this message Reply
This reversed 3.4 MB of data from standard-in in well under a second using a 1.5 JRE on my system.
int c;
StringBuffer s = new StringBuffer();
 
while((c = System.in.read()) >= 0) {
    s.append((char) c);
}
 
System.out.print(s.reverse());

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: What's next for Heron? Posted: Jan 25, 2006 1:28 PM
Reply to this message Reply
> This reversed 3.4 MB of data from standard-in in well
> under a second using a 1.5 JRE on my system.

And on mine it takes 8, but I don't want to get into a discussion about performance. I've removed the contentious claim in the blog post.

If you do want to compare Heron to Java, I think it is more interesting that Heron brings to the table:

- value based objects
- delegations
- contract verification
- interface extensions
- implicit interface implementation
- only one kind of string, instead of three (String, StringBuffer, StringBuilder).

But that is just my opinion. Obviously I'm hugely biased and more than just a little insane ;-)

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's next for Heron? Posted: Jan 25, 2006 1:54 PM
Reply to this message Reply
> If you do want to compare Heron to Java, I think it is
> more interesting that Heron brings to the table:

I am interested in the features that you are including in Heron and I like the C-style syntax (what's with def though, isn't that a little 80's?)

> But that is just my opinion. Obviously I'm hugely biased
> and more than just a little insane ;-)

I'm not a performance hound, I just thought the statement was a little crazy. BTW, What are you running it on? I'm on a 2 GHz P4-M. If found the slowest thing was printing to the console ( > 10 sec.) The < 1 sec. was based on redirecting to a file and I also didn't count the JVM startup time.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: What's next for Heron? Posted: Jan 25, 2006 2:45 PM
Reply to this message Reply
> > If you do want to compare Heron to Java, I think it is
> > more interesting that Heron brings to the table:
>
> I am interested in the features that you are including in
> Heron and I like the C-style syntax (what's with def
> though, isn't that a little 80's?)

Thanks for the encouragement. The def serves as a disambiguator, it makes parsing easier. Heron is designed in part to be easily interpreted line by line. I also find the def syntax more aesthetically pleasing.

> > But that is just my opinion. Obviously I'm hugely
> biased
> > and more than just a little insane ;-)
>
> I'm not a performance hound, I just thought the statement
> was a little crazy.

I agree, I have to be careful about what I say.

> BTW, What are you running it on? I'm
> on a 2 GHz P4-M. If found the slowest thing was printing
> to the console ( > 10 sec.) The < 1 sec. was based on
> redirecting to a file and I also didn't count the JVM
> startup time.

I did count JVM startup time, which is I think a crucial part of the equation. From a language comparison standpoint, it is too easy to hide much of the work in the JVM. For instance, I could write a JVM for Heron which preallocates 50 MB of ram, and then the whole program would have been virtually instantaneous and would apparently use no RAM, but that would have been cheating.

I'm running a 1.6 GHZ celeron with 512 MB of RAM.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's next for Heron? Posted: Jan 25, 2006 3:41 PM
Reply to this message Reply
> I also find
> the def syntax more aesthetically pleasing.

I just joking around. 'Def' is def yo.

> I did count JVM startup time, which is I think a crucial
> part of the equation.

I was having a hard time getting a good OS timing going in Windows but my total time was around 2 or three seconds just from guesstimation and definitely less than 4. I assume that you were using a 1.5 JRE. The start up time is much improved over the previous versions. I'm a little surprised that it took that long for you.

Sean Conner

Posts: 19
Nickname: spc476
Registered: Aug, 2005

Re: What's next for Heron? Posted: Jan 25, 2006 9:12 PM
Reply to this message Reply
Hmmm … that clear() method takes O(n) time.

But anyway, when you compiled Heron with MinGW to get that 50k executable, did you compile the C++ version with MinGW as well? It sounds like the small executable size (my own reverse program compiled down to less than an 8k executable) is more due to the compiler than the langauge.

Another thing, if I have this Heron syntax down.


def reverse()
{
if (count() < 2) return; //fixed from orig. code
int max = count() - 1;
int n = (count()/2) - 1; //fixed from orig.
int i = 0;
while(i < n)
{
_subscript(i) :=: _subscript(max - i); //uhg ... _subscript()?
}
}

def _colon_eq_colon(T a,T b)
{
T tmp = a;
a = b;
b = tmp;
}


Somehow I don't think that'll work. Pitty, I really like the idea of ':=:' being the swap operator.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: What's next for Heron? Posted: Jan 26, 2006 3:16 AM
Reply to this message Reply
@Christopher Diggins

The following isn't a dig at you - I am interested in your response because I am considering deleloping my own language. But how do you demonstrate a new language's worth?

It is hard to demonstrate the value of a language. You gave a string example and said it was elegent, fast, small, and doesn't use a JVM. I will leave the elegent point for a moment. The small, fast, and JVM can be challenged, e.g.:
    // Stuff missed out to keep post short - you will get the idea :)
 
    // Simple file reverser to show straight forward code - code from a previous post in this forum
    private static void simple() throws Exception {
        final FileReader reader = new FileReader( input );
        final FileWriter writer = new FileWriter( outputFile() );
        int c;
        final StringBuilder s = new StringBuilder();
        while( (c = reader.read()) >= 0 ) { s.append( (char)c ); }
        writer.write( s.reverse().toString() );
        reader.close();
        writer.close();
    }
    
    // More complex file reverser that demonstrates speed
    private static void fast() throws Exception {
        final FileInputStream fis = new FileInputStream( input );
	final FileChannel fic = fis.getChannel();
	final int sz = (int)fic.size();
	final MappedByteBuffer bbi = fic.map( READ_ONLY, 0, sz );
	final CharBuffer cbi = decoder.decode( bbi );
        final RandomAccessFile fos = new RandomAccessFile( outputFile(), "rw" );
	final FileChannel foc = fos.getChannel();
	final MappedByteBuffer bbo = foc.map( READ_WRITE, 0, sz );
	final CharBuffer cbo = decoder.decode( bbo );
        final StringBuilder s = new StringBuilder();
        s.append( cbi.array() );
        cbo.append( s.reverse().toString() );
        foc.close();
        fic.close();
    }
    
    public static void main( final String... fileName ) throws Exception {
        input = new File( fileName[ 0 ] );
        time( new Timable() {
            public void time() throws Exception { simple(); }
            public String toString() { return "simple"; }
        } );
        time( new Timable() {
            public void time() throws Exception { fast(); }
            public String toString() { return "fast"; }
        } );
    }
}

Shows two Java methods of doing the same thing. The above example demonstrates that it is possible to write the example simply in Java, see method simple. The resulting runtime output on my machine for a 7.5 MB file is:

Run: 1 method: simple time: 2.7 s
Run: 2 method: simple time: 2.3 s
Run: 3 method: simple time: 2.5 s
Run: 1 method: fast time: 1.0 s
Run: 2 method: fast time: 0.9 s
Run: 3 method: fast time: 0.8 s
BUILD SUCCESSFUL (total time: 11 seconds)

The runtime results show four things:

1. The execution time depends mainly on how you access the files. Method fast maps the files and this halves execution time.

2. An execution time of 0.9 seconds for reversing a 7.5 MB file on my machine (Laptop Intel Pentium M 1.3 GHz) is quite good.

3. The IDE I use gives the total time (last line of output) and the total time bearly differs from the sum of the idividual times (about 0.5 s longer). Therefore the JVM start up overhead in terms of time is negligable for almost any application. 0.5 s startup delay doesn't matter for most things: Word processors, emailers, browsers, etc.

4. You need to do a few runs to get a good idea of time. Note how the second and third run is quicker in both cases. Partially because a JVM is used but also because caches are 'primed' by the first run.

Therefore better execution time is difficult to demonstrate. Most mainstream languages are quite good in this regard.

On the topic of a JVM. The resulting executable (uncompressed jar) is 7 kB and that is for both versions and the timing infrastructure! Therefore a JVM is good at reducing executable size. A JVM allows system independence. But a JVM often uses more memory. So no clear cut case against the JVM.

On the topic of elegance your code is certainly better than C++ template code, but is it that much different than say Java, Scala, C#, or Eiffel code?

So in summary I don't think you have conclusively demonstrated with that particular example the value of the new language. So the question is, how do you demonstrate the value?

As I said at the start I am not having a go at you, I am interested in your response since I might venture down a similar path.

Terje Slettebø

Posts: 205
Nickname: tslettebo
Registered: Jun, 2004

Re: What's next for Heron? Posted: Jan 26, 2006 4:03 AM
Reply to this message Reply
> So in summary I don't think you have conclusively
> demonstrated with that particular example the value of the
> new language. So the question is, how do you demonstrate
> the value?

I think one "obvious" answer to that is probably the same as the motivation for making a new language in the first place: Show something that may be easier and/or more elegantly written in the language, than in other languages currently existing (perhaps especially more mainstream ones).

As for reversing a string, that occurs to me to be a good fit for functional programming, and indeed, one solution in Haskell is:

reverse [] = []
reverse (a:st) = reverse st ++ [a]

How's that for elegant and succinct? :) It's a two-liner, with no need for a stack at all (the function call stack will do :) ). I think it would hard to beat. I haven't timed it, though, but I wouldn't be surprised if a compiled version of this was very fast (particularly if the recursion is transformed to iteration when compiled).

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: What's next for Heron? Posted: Jan 26, 2006 6:34 AM
Reply to this message Reply
> But how do you demonstrate a new language's
> worth?

I think the only way is to write lots and lots of code, for people to use, and evaluate.

> Shows two Java methods of doing the same thing. The above
> example demonstrates that it is possible to write the
> example simply in Java, see method simple. The resulting
> runtime output on my machine for a 7.5 MB file is:

With all due respect, you rewrote the program so it no longer does what the original program does. Reversing standard input, is more challenging than reversing a file, because you can't preassume the size of the input.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: What's next for Heron? Posted: Jan 26, 2006 6:41 AM
Reply to this message Reply
> As for reversing a string, that occurs to me to be a good
> fit for functional programming, and indeed, one solution
> in Haskell is:
>
> reverse [] = []
> reverse (a:st) = reverse st ++ [a]
>
> How's that for elegant and succinct? :) It's a two-liner,
> with no need for a stack at all (the function call stack
> will do :) ).

My point about succintness, was in reference to the string class. One of the main goals of Heron is to make it easy to define new classes.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: What's next for Heron? Posted: Jan 26, 2006 7:05 AM
Reply to this message Reply
> Hmmm … that clear() method takes O(n) time.
>
> But anyway, when you compiled Heron with MinGW to get that
> 50k executable, did you compile the C++ version with MinGW
> as well?

Yes.

> It sounds like the small executable size (my own
> reverse program compiled down to less than an 8k
> executable) is more due to the compiler than the
> langauge.

Yes most definitely you are correct (and the implementation)

> Another thing, if I have this Heron syntax down.
>
>

> def reverse()
> {
> if (count() < 2) return; //fixed from orig. code
> int max = count() - 1;
> int n = (count()/2) - 1; //fixed from orig.
> int i = 0;
> while(i < n)
> {
> _subscript(i) :=: _subscript(max - i); //uhg ...
> ... _subscript()?
> }

Only missing a semicolon here. This is because in later versions of Heron strange statements will be possible like:

fu {} {} {};

Which need to be distinguished.


> }
>
> def _colon_eq_colon(T a,T b)
> {
> T tmp = a;
> a = b;
> b = tmp;
> }
>

>
> Somehow I don't think that'll work. Pitty, I really like
> the idea of ':=:' being the swap operator.

Not yet, but when its ready it'll look like:

def _colon_eq_colon[type T](T& a,T& b) { ... }

Terje Slettebø

Posts: 205
Nickname: tslettebo
Registered: Jun, 2004

Re: What's next for Heron? Posted: Jan 26, 2006 1:35 PM
Reply to this message Reply
> > As for reversing a string, that occurs to me to be a
> good
> > fit for functional programming, and indeed, one
> solution
> > in Haskell is:
> >
> > reverse [] = []
> > reverse (a:st) = reverse st ++ [a]
> >
> > How's that for elegant and succinct? :) It's a
> two-liner,
> > with no need for a stack at all (the function call
> stack
> > will do :) ).
>
> My point about succintness, was in reference to the string
> class. One of the main goals of Heron is to make it easy
> to define new classes.

You wrote you had implemented the program in C++, could you have posted the code for that version, too?

It seems the Heron version uses an Array class/interface, could you have posted the code for that, as well?

Flat View: This topic has 18 replies on 2 pages [ 1  2 | » ]
Topic: Multiple Contexts, Information Reuse, and Backpointers Previous Topic   Next Topic Topic: Desktop Linux Just Died

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use