Dermot and I have been planning Sapphire for several years. In fact, our intention to create this language determined the name of our development company, SapphireSteel Software. We created the Steel IDE for Visual Studio which, in its present incarnation, provides editing, debugging and design tools for the Ruby language (and its variants, JRuby and IronRuby). That product is called Ruby In Steel and, from the very earliest stages of its development, it was our plan to release, at a later stage, a different product called Sapphire In Steel. The development cycle that will culminate in that product is just beginning. As the Sapphire language does not currently exist (except in our minds), we have to create it!
Designing and implementing a programming language is a seductively appealing project. But there are already countless programming languages so, in order to justify a new one, there had better be a good reason!
In the case of Sapphire, our reason is Ruby. The Ruby language is great fun to use and has many powerful capabilities. It has a nice un-C-like syntax, a decent implementation of object orientation and, moreover, it has ‘dynamic’ capabilities which allow you to create and modify objects without all the rigmarole of typings and coercions which you may be familiar with from other languages. It also lets you modify programs at runtime - doing anything from creating new objects to defining new classes! All wonderful stuff and used to tremendous effect in web frameworks such as the well-known Rails (and some less well-known ones such as Merb, Waves and Ramaze).
But the consequence of this power is complexity and, potentially, problems of long-term maintainability. A common question posed by programmers coming to Ruby from some other language such as Java or C# is: but how can I check that the types my code is expecting are the types it actually gets? This is a serious question to which there is no real answer. Explaining that Ruby ‘duck types’ variables (it infers what they are at any given time) is not a satisfactory answer to the question. Running test suites to verify the program after it is written is useful but could be seen as ‘disaster recovery’ rather than ‘disaster avoidance’. This issue (Ruby’s free and easy approach to typing) is, I suspect, one reason why so many people dip into Ruby then move rapidly on to some other ‘safer’, more predictable, programming language.
It would, of course, be possible to create a version of Ruby with strictly enforced type declarations. But that would be so far from the spirit of Ruby - it would sacrifice so much of the power of the language - that you might just as well create yet another C or Pascal-like language and have done with it.
In Sapphire we decided to take a different approach. We felt we wanted to keep the essence of Ruby but pare down on its complexities. Where Ruby provides many alternative ways of doing the same thing, Sapphire provides one way. When Ruby introduces the possibility of confusion, say due to the differing precedence of nameless functions (‘blocks’) according to their delimiters, Sapphire removes the source of that confusion (in fact, it has just one set of block delimiters). And we are introducing ’type assertions’ which state the expected types and (optionally) warn if different types are found without enforcing those types.
I won’t go into all the other design decisions at this point. If you are interested, you will be able to read more on the SapphireSteel Software Developer’s Blog.
At any rate, whether or not you are interested in the Ruby and Sapphire languages, if you have ever wondered how you can create and implement your own language, Dermot’s series will show you how.
And to look on the pessimistic side, even if nobody (apart from you and us, that is) actually uses your (and our) language, well, by heck! it’ll be fun creating it anyhow... and that, frankly, is as good a reason as any for doing so.