An Introduction to Rindolf
What is Rindolf
Rindolf is a Perl 5 derived dialect of Perl that is fully backward-compatible with Perl 5. Rindolf was formed as an anti-thesis to Perl 6. While Perl 6 aims (as far as I understood) to be the tower of Babel of computer languages as of today, Rindolf 5 simply aims to be a Perl 5-like language without all the unnecessary idiosyncrasies of Perl 5.
Rindolf can be thought of as a roadmap of what to do next in Perl 5. So far, most Perl 5 changes were relatively incremental, cosmetic or necessary to keep up with the state of the art (i.e: Unicode). Rindolf aims to be a dialect of Perl that rethinks all the things that are unnecessary in Perl 5 and seems trivial in Python, Ruby and Lisp with influences from other languages.
Philosophy
The Competition
Let's face it - we have competition. Perl, Python, Ruby, PHP and (soon, I hope ) Arc all compete for the same niche of dynamically typed, highly flexible languages. They all allow doing in one line what can be done in other more mainstream languages in 50 lines of code, or with an ugly command filled with lots of overly-object-oriented crap. Furthermore, they all scale much better as far as code vs. effort is concerned. (with the sole exception of Lisp, which loses as far as portability is concerned)
The first thing that has to be done is to admit it. At the moment, we are still the dominant. Some people would not replace Perl for anything. True. But some people are unnecessary having to code in something else, because it gives something that Perl does not give. Moreover, more and more newbies are lead to believe that Python is superior to Perl. This is now entirely unfounded as Python does have some features that are not present in Perl, at least not in a straightforward manner.
When facing a competition, the important thing to admit is that it may be doing something better than you do. But it is also important to realize what isn't your competition. Java isn't. C++ isn't. Haskell and OCaml aren't. Like it or not, but dynamically typed languages are here to stay. And I predict (while given the right to err) they are going to be the general purpose languages of the future.
The Enemy
Our enemy is not the competition. Our Enemy is ourselves. There are millions lines of code of pure Perl 5 code out there. That's milliards of dollars worth of development time. No-one is going to go over the code changing all the "."'s to "_" and "->"'s to "."'s. Seriously. And Perl 5 is fine. Not the best language in all respects, but nice to work with.
Every Apocalypse brings new surprises and new incompatibilities. While Perl 6 would have a Perl 5 emulation mode, it would not answer all the compatibility issues. And in Rindolf Perl 5 emulation is not needed. There are pragmas to replace some of idiosyncratic parts of Perl 5 with something more sensible, but otherwise everything will remain the same. Moreover, without any pragmas it would be possible to use powerful new mechanisms that extend and expand the power of Perl.
Is Backward Compatibility Considered Harmful?
Backward Compatibility is your worst enemy, but it's also your users' best friend. And you have to take the users' into consideration. As much as I respect Larry and Damian, I care too much about the thousands of programmers out there who depend on Perl 5, are used to it and like it. And I also happen to like Perl 5.
Features of Rindolf
Now you are probably interested to hear about its features, so prepare your napkins and let's start:
Classes as First-Order Objects
It would be possible to define a class (or a lightweight namespace) in Rindolf using class MyClass { ... }
. The elements of such classes can be accessed from other namespaces. Furthermore, an anonymous class can be constructed using class { ... }
. Two keywords expand
and extend
will be supplied to manipulate those classes.
expand
will dump the contents of a class onto the current namespace. extend
will add more contents to an existing class. bless
will accept a class reference as its second argument.
Parent and this meta-namespaces
Rindolf will support the Parent
namespace that would bring a namespace to its parent namespace, and this
that would start at the current one.
Example:
class Parent { class Child { sub myfunc { print "myfunc() was called!\n"; } } sub ya_func { theclass::Child::myfunc(); } } this::Parent::ya_func(); # Prints myfunc() was called!
A Basic File Primitive
Rindolf will sport the existence of a basic file primitive, which would be very versatile and powerful. Typeglobs, FileHandle
and other I/O mechanisms would be implemented using it. Note that it is intended for those who are doing extensions and should not be used by mundane people, nor would it be very usable this way.
Modifying the Grammar on the fly
In Rindolf it would be possible to add new operators and to change the precedence of existing ones on the fly to create a slightly modified grammar. Furthermore, it would be possible to define new grammars with dedicated semantics.
Blocks
Rindolf will have blocks as first order objects. such blocks are what is used by map, sort, grep and friends and will allow creating such user defined functions. (accum comes to mind).
Proper-Tail Recursion
The more I think about it, the more I think I should think about it some more.
— Clarissa in Clarissa Explains it All.
In order to make sure Clarissa does not run out of stack space - proper-tail recursion is here. The primitive pt_return
will behave exactly like return
except that it would try to make the routine properly-tail recursive if possible. line_return
would explicitly be non tail recursive.
A pragma use recursion
would be available to toggle the default behaviour and should be very flexible.
Adding New Operators
New operators can be added to the core language and the grammar changed on the fly. I find it a necessity in any language. That way the PDL people can add Matlab-like operators to their hearts' content. And obviously many people would find adding interesting operators useful.
LISP-like features
Re-usable blocks
map
, sort
and friends can be implemented in userland using the block { ... }
construct.
my $myblock = block { $result += $iter; }; my ($result); for my $iter (1 .. 100) { expand($myblock); } print "The sum of numbers from 1 to 100 is $result;\n"
It would be possible to expand blocks in the environment they were defined, or in the environment they are expanded in.
Re-usable Virtual Machine Instances
It would be possible to instantiate the Perl interpreter, and to run several Perl virtual machines at once.
Parsing and Analysing of Rindolf Code
Rindolf will have a generic parsing and analysing class which would be very flexible. This class would be able to analyse Perl code, and thus serve as the basis for better code writing and modifying mechanisms.
Eval on Different Environments
As in some dialects of Scheme, it would be possible to store reference to the current environment using a meta function this_env()
and to pass it to eval ""
.
Better Function Prototypes and Function Return Prototypes
It would be possible to define a function prototype using a regular-expression like construct of the terms:
sub myfunc (ext{{scalar}?{array}{typeglob}?}) { }
Moreover, the meta-function wantwhat()
can be used a definition of what the function is expected to return. Like wantarray
on steroids.
Pragmas to Modify some of Perl 5’s Idiosyncrasies
Rindolf by default will be fully compatible to Perl 5. However, it will have pragmas that can modify some of the things I (or others) consider as idiosyncrasies: atomic key-value pairs, non-ambiguous x
operator, our to be an exact replacement for use vars qw( )
, etc.