Cross-language library loading on Parrot

| 6 Comments | 1 TrackBack

On Saturday, I wrote up a possible API for Parrot compilers to support loading libraries written in other languages and discussed some of the details with Jonathan++ and Allison++. It’s not perfect, and is missing a few parts, but should be extensible enough to support whatever else we need in the future. I still need to formalize it a bit and add it to the Parrot docs and the example language shell.

On Sunday, I implemented it on Rakudo (Perl 6) and Cardinal (Ruby; very incomplete).

This morning, after confirming the spec with pmicahud++, I merged the changes into Rakudo trunk.

The syntax for specifying the source language for Perl 6 is:

use Foo:lang<cardinal>;

I couldn’t quite figure out what an appropriate way to do this in Ruby would be, so I just added a function to cardinal:

foreign_load('perl6','Foo/Bar')

If you have a better suggestion for what it should look like in Ruby, please let me know! I don’t actually know much Ruby at all, so my Ruby compiler is fairly limited.

I’ll be adding support for this to pynie (Python) soon, and other languages after that.

Here’s a simple example of using a Perl library from Ruby:

[sweeks@kweh ~]$ cat Foo.pm
module Foo {
    sub greet($name) is export {
        say "Hello, $name!"
    }
}
[sweeks@kweh ~]$ cat perl6.rb
foreign_load 'perl6', 'Foo'
['Ruby', 'Perl', 'World'].each { |name| greet name }
[sweeks@kweh ~]$ cardinal perl6.rb
Hello, Ruby!
Hello, Perl!
Hello, World!

Here’s a similar example of using a Ruby library from Perl:

[sweeks@kweh ~]$ cat Foo.rb
module Foo
    def greet(name)
        puts "hello, " + name
    end
    def apply_people(cb)
        people = ['Dave', 'Bryan', 'Stuart', 'Dax']
        people.each { |name| cb(name) }
    end
end
[sweeks@kweh ~]$ cat ruby.pl
use Foo:lang<cardinal>;
greet("person $_") for 1..5;
apply_people( { say "hello from perl, $^name" } )
[sweeks@kweh ~]$ perl6 ruby.pl
hello, person 1
hello, person 2
hello, person 3
hello, person 4
hello, person 5
hello from perl, Dave
hello from perl, Bryan
hello from perl, Stuart
hello from perl, Dax

Thanks go to my employer (Guru Labs) for their support in my work on Rakudo and Parrot.

1 TrackBack

TrackBack URL: http://blogs.gurulabs.com/cgi-bin/mt-tb.cgi/126

mz2guild의 생각 from mz2guild's me2DAY on May 20, 2009 6:24 PM

Cross-language library loading on Parrot - Stephen Weeks Read More

6 Comments

Now actually that is brilliant.

No matter if people dislike perl - this feature is a killer feature.

You simply toss a scripting language to it, and it works!

This kinda unifies the scripting language and in fact shows that they are MUCH closer together than i.e. Java or C.

It would be interesting to finally see something like a unified CPAN - for _all_ scripting languages to use.

Then you could cherry pick what you want - text parsing via perl, control structures with python, ruby for the object relations and php for the end user stuff (like phpbb)

Regarding the appropriate methods for loading, Ruby normally uses "require" and "load" (see http://www.ruby-doc.org/core/classes/Kernel.html). These methods try to determine the type of file by file extension (if provided) or by whatever works.

The idiomatic way of doing this in ruby is to overload the require function.


Ganked from polyglot.rb:

module Kernel
alias polyglot_original_require require

def require(*a, &b)
polyglot_original_require(*a, &b)
rescue LoadError => load_error
begin
Polyglot.load(*a, &b)
rescue
# Raise the original exception, possibly a MissingSourceFile with a path
raise load_error
end
end
end

This is the moment I've been waiting for since Parrot was first announced.

I too have been waiting for this moment since the first announcement! Tene++ (and then some)

One suggestion for more idiomatic ruby:

Foo.pm:

module Foo {
sub greet($name) is export {
say "Hello, $name!"
}
}
sub great is export { say "that is correct"}

irb:
% foreign_load 'perl6', 'Foo'
=> nil
% greet "me"
=> NoMethodError, 'greet' not found
% great
=> "that is correct"
% include Foo
=> nil
% greet "me"
=> "Hello, me!"

This functionality is the heart of the mixin in Ruby.

Awesome work man!


Really nice, indeed!

For an occasional Parrot follower like me, could you please give slightly more verbose instructions? I didn't really get it to run, especially did not know from which directory to call and always only had one compiler available, either cardinal or perl6, not both ("load_language" couldn't find a compiler module for the language 'perl6'). Maybe it's an FAQ, anyway, I could need some idiot proof instructions.

Thanks.

Leave a comment

About this Entry

This page contains a single entry by Stephen Weeks published on May 18, 2009 10:52 AM.

New Toys in Perl 6: custom ops. was the previous entry in this blog.

Useful Utilities - rlwrap is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.25