Posted: April 7th, 2010 | Author: mars | Filed under: Uncategorized | Comments Off
There’s going to be a conference this summer all about “emerging” languages: talks by the designers of Go, JRuby, Io, and others. It’s going to be in Portland, July 21st and 22nd; sounds pretty interesting.
Posted: March 5th, 2010 | Author: mars | Filed under: Uncategorized | Comments Off
From the Pro Git blog:
As of the release of version 1.6.6 at the end of last year, however, Git can now use the HTTP protocol just about as efficiently as the git or ssh versions. I think this will become the standard Git protocol in the very near future. I believe this because it’s both efficient and can be run either secure and authenticated (https) or open and unauthenticated (http). It also has the huge advantage that most firewalls have those ports (80 and 443) open already and normal users don’t have to deal with ssh-keygen and the like. Once most clients have updated to at least v1.6.6, http will have a big place in the Git world.
I still don’t particularly like git that much, but this change will make it a lot easier to manage multi-person development.
Posted: February 27th, 2010 | Author: mars | Filed under: Reference | Comments Off
Documentation about the DWARF debugging data format.
Posted: February 17th, 2010 | Author: mars | Filed under: Progress | Comments Off
I burned myself out working on binary search trees and object members back in January and have taken the last couple of weeks off from Radian work. I’m starting to feel the inspiration come back, so I’ll probably have more progress to report soon.
In the meantime, here’s an interesting article by Martin Fowler about version control tools:
So this leaves three tools that my contacts are generally happy with. I find it interesting that all three are open-source. Choosing between these tools involves first deciding between a centralized or distributed VCS model and then, if you chose DVCS, choosing between git and mercurial.
Most of the time, the choice between centralized and distributed rests on how skilled and disciplined the development team is. A distributed system opens up lots of flexibility in work-flow, but that flexibility can be dangerous if you don’t have the maturity to use it well. Subversion encourages a simple central repository model, discouraging large scale branching. In an environment that’s using Continuous Integration, which is how most of my friends like to work, that model fits reasonably well. As a result Subversion is a good choice for most environments.
Posted: January 21st, 2010 | Author: mars | Filed under: Uncategorized | 3 Comments »
The ability to host a repository via HTTP is nice, but I’m left swimming any time something unusual happens. I’m sure one of git’s hundreds of sub-commands can tell me why it won’t do what I want, but in absence of a comprehensive knowledge of the system, I’m stuck. Here’s the latest example of its helpfulness:
Morgan:git marssaxman$ git apply 0001-implementation-of-an-intrinsic-function-system-in-th.patch
error: patch failed: source/flowgraph/pool.cpp:355
error: source/flowgraph/pool.cpp: patch does not apply
Morgan:git marssaxman$
There are no changes in the local repository, and the patch comes from a fresh clone of the same master. Why won’t this work? Beats me. I guess it’s time to trash the local repository and clone a new one.
Posted: January 16th, 2010 | Author: mars | Filed under: Progress | Comments Off
I’ve checked in the new member-lookup code for objects and modules. The compiler generates a binary search tree, which the object function captures as one of its slots. Request for an object member becomes a call to the BST lookup function. The lookup code is implemented as a compiler intrinsic. I tried to write it as an actual function, which would live in a “core” library, but implementing modules in terms of a module turned out to be something of a challenge.
The next step will be a function to set a value in the tree. This is not the same as the standard associative-container “insert” operation – you can’t establish a new key-value mapping, but only change the value associated with an existing key. This way I can organize the tree at compile time, and the intrinsic member-lookup and member-set functions don’t need any complex balancing logic.
Posted: January 11th, 2010 | Author: mars | Filed under: Uncategorized | Comments Off
An object contains a group of related things: pieces of data and functions which operate on the data. We can think of an object as a kind of associative container, then, mapping names to members. What is the value of bar, one may ask; or how do I perform the baz operation?
In many object-oriented languages, this mapping is established by a class. Radian objects are simpler; instead of combining instantiation, inheritance, and type identification into one structure, each of these functions is implemented separately. The object itself, once you’ve constructed it, is just a function which returns a value in response to some key, which is the name of the function or variable you want to retrieve.
The dot-syntax for members is therefore a specialized form of function call. If you have an object foo, and you want its member bar, you would write this:
baz = foo.bar
This operation performs two calls. First, you call the object foo, passing in the symbol bar. The object responds with a reference to whichever function it is that can return the value of bar. Then you call that function, passing in the object reference, and it returns the value.
The lookup mechanism and the accessor mechanism are thus separated from one another. Accessors do not need to have any privileged relationship with the object, provided they are capable of doing the job requested of them; any function which returns an appropriate value when presented with the object can work. Further, it doesn’t matter where the data actually comes from; it may live in the object, it may live somewhere else, or it may be computed on demand, but the mechanism for retrieving it is the same in each case.
The object constructor syntax is effectively a dictionary, or map, constructor. The object block itself represents a function which returns some object; the object is an associative mapping of keys, which are member names, to values, which are functions that return some interesting information. Each new item declared in the object block adds such a mapping to the resulting object.
Each function or method defined inside this block gets an implicit parameter, self, representing the object it is expected to work on. This need not be declared explicitly, as in Python; it is a byproduct of the object-constructor context. Variables defined inside an object block also receive special handling: they are marked in the symbol table as self-members, so that the compiler can generate code to look the value up through the “self” object, or to assign a new value by assigning to the “self” object.
Posted: January 6th, 2010 | Author: mars | Filed under: Design, Progress | Comments Off
Radian offers syntax for five types of container data structures: tuple, array, set, map, and object. The tuple is a primitive element, implemented in the compiler backend, but the others must be built up from simpler components. I’ve been thinking a lot about the fundamentals of data organization in Radian lately, therefore, and while I’ve spent a lot of time working on the project, I’ve written little code, all of which I have thrown away.
It’s less the implementation that has been puzzling me – though immutability certainly complicates matters – than the fact that I have to design an API for the whole thing, and API design is hard. Objects, like maps, are associative containers; but how much of the map interface should an object share? How much support should I build in for runtime inspection or mutation of object structure? Should arrays serve double-duty as queues and stacks?
I’m making progress, and I think the next round of code I write may actually stick. I’ve settled on a list of standard containers, interfaces, and method names. Key->value containers like maps and objects will be implemented with red-black trees; ordered containers, like arrays, will be finger trees. Both structures offer O(log n) average performance for lookup, insert, and delete, and both are compatible with immutability.
It’s proving difficult to implement any useful API using only the current set of primitives. I’m thinking of upgrading the red-black tree to become one of the primitives, alongside tuples and closures. Tonight’s project is a persistent implementation in Python, as a prototype for the version I intend to embed in the compiler’s semantics engine.
Posted: December 29th, 2009 | Author: Aaron Ballman | Filed under: Design | Comments Off
Initially, Radian handled numbers as basic integers only. The way floating-point support was implemented was by using the dot operator as a function which would take two integers (the left-hand side and the right-hand side) and return a floating-point value. However, this also meant that it was basically impossible for us to write any backend support for special processing of numerics. Also, it meant that it was possible to write some funky things, like:
var wahoo = 12
var blah = 1.wahoo
if blah = 1.12 then
end if
In theory, that would work fine because the dot operator function would concatenate 1 and wahoo (12) together.
Now Radian has lexical support for more numeric formats than just integers. The support is highly based off of Python, so those of you coming from that language should feel right at home. We now support integers, floating-point values, hexadecimal, octal and binary literals. All of the various literal formats are still considered to be a “number” internally, and there basically is no support for coercion aside from what the backend does via C. Eventually, we’d like to see a numeric tower like Scheme, where each numeric format builds on top of a lower abstraction. However, that project will wait for another day.
Currently, the syntax for numeric literals is:
Integers: [1-9][0-9]* | 0
Floats: [0-9]+.[0-9]+
Hexadecimal: 0[Xx][0-9A-Fa-f]+
Octal: 0[Oo][0-7]+
Binary: 0[Bb][0-1]+
You’ll notice that there is not support for scientific notation with floats, which will likely change in the future. Also, I’m not supporting sign information as part of the numeric literal. When you apply a sign, we treat it as an operator currently. I’m not too keen on that right now because I think it will make constant folding a bit more difficult. Also, I’m still on the fence as to whether I want to support a unary + as well as a unary – in the same way that Python (and JavaScript, etc) does. I can’t think of reasonable use cases that aren’t contrived or too clever.
Posted: December 29th, 2009 | Author: Aaron Ballman | Filed under: Uncategorized | Comments Off
Introductory posts always scare me — I feel like I’m applying for a job. :-P
My name is Aaron Ballman, and I’m one of the contributors to the Radian project (and blog). I started working on compilers with Mars while we were both at REAL Software, and eventually worked my way up to being the lead compiler architect on REALbasic once he moved on to greener pastures at Microsoft. I’m currently employed by 4D, Inc doing compiler-ish type work on several languages, including JavaScript and SQL.
I’ve been involved with Radian in one way or another for a few years now. However, it’s only recently that my involvement has started to ramp up into actual productivity instead of just acting as a sounding board. I’m really looking forward to working with Mars on the language design and implementation work for Radian.
Don’t be too shocked if you see blog posts from me in the future. At least you now know who I am! ;-)