Looking Into Sidef

来源:互联网 时间:2015-12-08

Sidef is a modern, yet experimental, dynamic, object-oriented programming language with an expressive grammar, embracing a newprogramming style, taking the best from languages like Ruby, Go, Perl 6 and JavaScript. Version 2.11 was recently released.

Not much is known about this experimental language, so for more information we turned to one of its creators, Daniel Șuteu and asked him to explain how it came about and its relationship to Perl.

NV:Tell us a bit about yourself, you seem to be a multi-linguist?

DS:I'm Daniel Șuteu, a Romanian self-taught computer programmer. I started learning Perl 5 as my first programming language and it quickly became my favorite one. I use Perl on a daily basis and I find it to be the most natural programming language currently in use.

I'm a little bit of a multi-linguist too. I enjoy experimenting with many programming languages, especially with some new ones, including Julia, Perl 6 and Go. Some of these languages became the main inspiration for Sidef.

NV:So why Sidef? What is the idea and motivation behind it?

DS: Sidef sprung as an idea back in 2013 when a good friend of mine, Ioana Fălcușan, and I came up with a design for a very basic programming language. The original idea was to make everything in the language an object and to implement the functionality inside methods. In the first early days, we pushed this idea to its limits: even conditional constructs were available as objects in the language. Later we found out that this is not such a great idea in practice, as the language became extremely slow.

We actually had a working version of Sidef in which the if and while statements were implemented as objects and could be stored inside variables and be passed to functions and methods as parameters. This was indeed quite exciting and very flexible, as we could generate partial expressions and complete the evaluation at a later time. For example:

var cond = if(false); cond.do { ... }.elsif(expr).do { ... }.else { ... }

Unfortunately, in the latest versions of Sidef this is no longer true due to a major design change in version 2.10, but their implementation can be found in version 0.01, I believe.

The main motivation of Sidef was the exploration of new territories in programming language design and, also, as a learning exercise.

NV:So Sidef's philosophy is that everything is an object? It certainly look like it by observing Sidef employing Ruby-like notation such as string.length or [123].length. That aside, is a regular expression considered an object too?

DS:That is correct. Everything in Sidef is an object, including numbers and regular expressions. The regular expressions are the same as in Perl 5, but they are encapsulated inside an object which accepts methods like .match , returning a Match object.

The notation is exactly as in Ruby, but we also have the tiny-arrow (->) as method separator, which works a bit differently from the dot (.).

For example, let's consider the following statements:

1 + 25.sqrt # means: 1 + sqrt(25) 1 + 25->sqrt # means: sqrt(1+25)

In the first statement, the dot binds the `sqrt` method to the object which precedes the dot, while in the second statement, the method is applied on the left-most expression. This simplifies somewhat the writing of code, as we don't have to enclose the expression in parenthesis when we want to invoke a method on it.

A surprising philosophy of Sidef, is the lack of operator precedence. All operators have exactly the same precedence, which is controlled by the lack of whitespace between the operands. For example:

1+2 * 3+4 # means: (1+2) * (3+4) ??# just as the lack of whitespace implies it

This makes the code much readable, without requiring any extra knowledge about the precedence of each operator.

NV: So given the examples so far, does Sidef diverge from Perl's principles (easy to learn,get things done quickly,there's more than one way to do it) or expands on them?

DS:Sidef follows many principles of Perl: it favours freedom in writing code and, in many cases, it provides more than one way to achieve the same thing. It goes so far in this direction, that it even provides two or more aliases for common methods, allowing the programmer to choose whatever name feels more natural. In addition, it also favours simplicity, elegance and readability of code.

NV:What do you think its key features are,what is different from Perl,or what is its advantage over Perl?

DS: The key features of Sidef lie in the syntax: it borrows many concepts from different languages, trying to make common things easier to write. We have the `gather/take` construct from Perl 6, as well as the hyper and meta operators (such as: »+», ~X+ and ~Z+). We also borrowed many things from Ruby, as you can tell from the very first time you look at its syntax. An interesting feature borrowed from Ruby and extended, it's the possibility of adding an exclamation mark (`!`) at the end of any method. Doing this, the variable on which the method was invoked, will take the value returned by that method. For example:

var str = "foo" str.uc! # makes the string upper case and # replaces `str` with the returned value say str #prints: "FOO"

Sidef is different from Perl in its way of representing any kind of data inside an object. This allows us to work with built-in types in the same way we would work with user-defined types and we also have the possibility of extending built-in types by adding more methods.Example:

class String { # opens the built-in String class method foo { # defines a new method inside # the String class "foo" + self # adds the string `foo` in front

# of the self object

} } "abc".foo; # the `foo` method will be # avaiable for all string objects

The advantage of Sidef over Perl is mainly in the design of the object-oriented system.

NV:An interesting feature is the definition of methods at run-time. Is that akin to Ruby's monkey patching and what is the advantage of it ?

DS:The definition of methods at run-time is particularly helpful for metaprogramming .It is indeed related to Ruby's mokey patching, as it allows us to re-open any class (including built-in classes), and add or replace some methods. Example:

class Array { method square_roots { self.map { .sqrt } } } say [1,4,9,16].square_root # prints: [1, 2, 3, 4]

NV:Was there once Multiple method dispatch but removed in the process , as it says "unsupported in 2.10". W hat would it offer and why was it removed ?

DS: As Sidef supports optional types annotations (in the same way as Perl 6 does it), multiple dispatch was an obvious feature to the language and it was available in several versions before 2.10.

The main idea of multiple method dispatch was borrowed from Julia and it, basically, checks the types of the parameters of a method, and if we have more than one method with the same name, but with different types of parameters, it decides which methods to invoke. For example:

func foo(String s) { ... } func foo(Number n) { ... } foo("abc") # calls the first function foo(123) # calls the second function

The checking was also done on the number of parameters, which didn't required any type annotations when there is no ambiguity. It worked nicely, but the implementation was not very robust and we decided to remove it for now, but it will become available again in the next releases.

Version 2.10 represents a major change in the design of the language and also in the implementation. Before 2.10, the language was interpreted in the traditional way, which was by walking the AST and executing expressions as they are encountered. Not surprisingly, this was very slow, therefore we decided to move towards code generation instead.

Sidef now includes a Perl code generator, as a backend, which generates an equivalent Perl program from the AST of a Sidef program.

NV:Something very intriguing is that you can freeze the AST to disk and then deparse or translate it to Sidef or Perl code. What does this mean for portability, and since it can be used to generate valid Perl 5 code, does it open the possibility of using the AST to compile a Sidef program into multiple backends? For example, feed it into Perlito which subsequently would compile it into JavaScript, Python, Ruby or Go ?

DS: Absolutely. This opens the possibility of generating code in other languages as well. I considered at some point of adding two more backends: one for Perl 6 and the other for Julia, which may happen sometime in the future.

The Perl 5 code that is currently generated by Sidef, it's not 100% compatible with Perlito, so we can't compile it (yet) to Perl 6 or JavaScript, but, in principle, this is definitely possible.

However, having the language implemented in Perl 5, it comes with some interesting benefits: we can load and use in Sidef, virtually, any module from CPAN, including the Tk and Gtk2 libraries, allowing us to create graphical applications in Sidef in a very trivial way.

We have the `require` keyword, which loads a given Perl module and returns an OO-caller. Alternatively, there is the `frequire` keywords which returns a functional-caller:

var lwp = require('LWP::UserAgent') var ua = lwp.new(); var resp = ua.get('http://example.com') if (resp.is_success) { say resp.decoded_content.length }

Any Perl data returned by a module, is automatically converted into a Sidef object. This makes the usage of Perl modules extremely natural and transparent.

NV:Have you hand-rolled a parser yourself through the use of a generator like Marpa or is the parsing done in Perl? if that is so , the saying goes 'only Perl can parse Perl'. Does it hold true for Sidef as well,in that you need to invoke the interpreter as part of the compilation process?

DS:The parser is written in Perl and it uses the power of regular expressions to parse the language. It was entirely written by hand and majorly improved several times. In the early days, some bits of the language were interpreted soon after they were parsed. In the latest versions of Sidef, however, the interpreter is no longer invoked by the parser, which would allow us in principle, to use a generated parser as well.

NV:Sidef borrows features from Perl6 as well,so what's your view on Perl 6 and the current developments?

DS:Perl 6 is the big brother of Sidef, from which it learned many new things. I like Perl 6 very much and I consider it a truly amazing language, extremely well designed and with many new concepts prepared for the future. This is, probably, why Sidef borrows so many things from it.

NV:Finally what's Sidef's place in the programming world? What niche can it excel at?

DS:For now, Sidef is just an experimental language, used by enthusiasts only. It excels, in particular, at numerical computations, as it represents any number as a `Math::BigFloat` object. This enables a very good precision and accuracy in computing very large or very small values, without having to worry about overflow or underflow again. I don't expect the language to be used in production, nor I recommend to.At least, not in this stage as it is now, but it can be used in some small home-made projects to create some cute applications for fun.

An example of a nice application written in Sidef, can be found at: https://github.com/trizen/smart-units