Archive for June, 2011

Babel-17 v0.3 is out !

June 30, 2011

Check it out now at ww.babel-17.com.

Automatic Type Conversions

June 29, 2011

Writing unit tests is a great thing. It makes you think even harder than usually about the semantics of your code.

In Babel-17 you have real interval arithmetic; for example, to describe the interval between 4 and 5, you could write [4.0; 5.0]. This notation, [a;b] assumes that a and b are reals, and forms the convex hull that contains both a and b.

Now. Should it be possible to also write [4; 5] for the above interval?

In my current preliminary spec for Babel-17 v0.3 the answer is NO. An integer is not a real; for example you cannot compare them, 2 == 2.0 evaluates to false. This point of view has a lot going for it; it seems pure.

(Un)fortunately, people don’t care so much about purity. I can already see the looks on faces when I try to explain that [4.0; 5.0] is a real interval, but [4; 5] is not even a legal expression.

There is an obvious solution to this dilemma: type conversions. These are already a part of Babel-17 v0.3: for example, 3 :> real converts the integer 3 to the real 3.0 .

Type conversions could be used such that whenever I need in a particular situation a value of a certain type T, I check if my value at hand can be converted into something of type T. If yes, I use the converted value instead, if not, then it’s a DomainError.

For this not to result in total chaos, a necessary condition for a type conversion to succeed should be that the conversion is reversible (at least in principle). Note that this is only a necessary condition, and you should really think twice before providing a type conversion. Often it makes more sense not to provide a type conversion, but just a conversion function which has to be invoked explicitly.

As an example, look at the conversion between integers and reals. It should be possible to convert integers that are not too large to a real; but if the integer is too large to be represented faithfully as a real number, the conversion should fail. Likewise, a real r for which r.round == r holds should be convertible to an integer. But the conversion should fail for those r with not(r.round == r).

This is a big issue, and adding automatic type conversions to Babel-17 changes the whole look and feel of the language. It will make it a lot easier for beginners to get friendly with the language; at the same time it will make it harder for a compiler (but not impossible, especially for a JIT) to generate fast code.

Automatic type conversions will be introduced in the upcoming Babel-17 v0.3, and further developed in Babel-17 v0.3.1.

Feature Complete

June 28, 2011

Babel-17 v0.3 is feature complete! Everything has been implemented, and there is also a new version of the Babel-17 plugin for Netbeans 7.0. The two biggest changes in the plugin are:

  • there are Babel-17 projects now
  • there is support for running unit tests

Tuesday is dedicated to going through the specification and writing unit tests that check the spec. Hopefully only minor fixes will be necessary; if so, then Tuesday night Babel-17 v0.3 will be released!

Implementing This

June 20, 2011

I am currently teaching the interpreter how to handle evaluation of this. While this is an intuitive concept, its correct implementation results in quite some work. The following code snippet,

val r = 
  object
    def outer = this
    def name = "r"
    def u =
      object
        def test = (inner, outer)
        def inner = this
        def name = "u"
      end
  end
val (i, o) = r.u.test
(i.name, o.name)

should evaluate to ("u", "r"). To achieve this, the interpreter converts the above program into something like:

val r = 
  object
    def outer this_a = this_a
    def name = "r"
    def u this_a =
      object
        def test this_b = (inner this_b, outer this_a)
        def inner this_b = this_b
        def name = "u"
      end
  end
val (i, o) = 
  begin
    val u = r.u r
    u.test u
  end
(i.name, o.name)

Off trying to implement this in a not too messy way …

No Wildcard Import

June 11, 2011

I have implemented wildcard import in Babel-17, i.e. you can do something like

import com.coollib._

or even more complicated imports like

import com.coollib.{coolfun => f, -notneeded}

which will import everything from com.coollib except notneeded. The value com.coollib.coolfun is accessible by the local name f.

But now I decided to get rid of wildcard imports again. There are two major points why wildcard imports are not such a good idea:

  1. Wildcard imports can lead to name collisions that you are not aware of. Right now, it is an error if an imported name collides with a local def or val, but it is no error to collide with names defined not in the local, but an outer scope. This rule makes sense for all imports except wildcard imports, where it is dangerous, especially since Babel-17 is dynamically typed.
  2. Wildcard imports are the only thing standing in the way of a complete separate compilation of Babel-17 files. Right now, all modules are scanned in a first phase. In the second phase, this module information is used for wildcard resolution.

The second point is annoying, but obviously I have already worked around it. But the first point really is a deal breaker. Wildcard imports gotta go.