Saturday, February 21, 2009


Unfortunately, I have lost enthusiasm about Loyc. I just can't bring myself to do the incredibly large amount of work necessary to make a new compiler infrastructure. Besides that, I'm running into severe indecision trying to design the AST. I wish I could completely separate the implementation of the AST from its public interface, so that I could change it later if desired, but that's not entirely possible in C#.

I'm sure that if I had supportive friends and another programmer that shares my vision, I could do it, but I am so very alone in this endeavor. If you are reading this article, please leave a comment, otherwise I'll have to assume that not one damn person read it.

Boo recently added some very cool metaprogramming features in v0.9, the kind of thing that I would have liked to put in Loyc. Also it sounds like eventually boo will move to an extensible (PEG-based) syntax, which will theoretically give it a lot of the power that I wanted to give Loyc (albeit boo will still only be powerful enough to compile boo code, not C#--a key feature of Loyc is supposed to be multi-language support). However, the boo developers are terrible at documenting their language. I wonder how Rodrigo managed to find other developers to work on boo given his reluctance to communicate. Maybe it was that boo manifesto--it certainly won me over.

In the boo google group they recently called for people to write examples to showcase boo's new features, but they were unwilling to tell people how to actually USE the new features!

I asked:
Where is the documentation for the "macro" macro? Where is the documentation for using the AST and those cool [| AST expressions |] with $interpolation [...and...] where is the documentation for the AST classes?
No one responded.

I wrote:
I would like to write a macro in which you could write something
x = 12
y = 7.0
z = "11"
total = 0.0
witheach Var in x, y, z:
total += Convert.ToDouble(Var)

and the macro would expand this to

x = 12
y = 7.0
z = "11"
total = 0.0
total += Convert.ToDouble(x)
total += Convert.ToDouble(y)
total += Convert.ToDouble(z)

But I don't know how to get started.
No one responded.

I asked:

can macros have memory? I think it would be cool to
have a pair of macros, let's call them "define" and "expand". define
would be used something like this:
define PointClass(P, T):
class P:
public constructor(x as T, y as T):
X=x; Y=y
public X as T
public Y as T
static def op_Addition(a as P, b as P):
return P(a.X+b.X, a.Y+b.Y)
static def op_Subtraction(a as P, b as P):
return P(a.X-b.X, a.Y-b.Y)
static def op_Multiply(a as P, b as P):
return a.X*b.X + a.Y*b.Y

and expand would be used like this to define three different kinds of
expand PointClass(PointF, float)
expand PointClass(PointD, double)
expand PointClass(PointI, int)

Is this even possible with the current macro architecture?
No one responded.

A brief history of Loyc

I actually wrote a complete unit-inference engine for boo around two years ago, including small changes to the parser, so that you could write, for example,
_weight as double
def GetAcceleration(force as double`N`) `m/s^2`:
return force/_weight

And the boo compiler would automatically determine that _weight is measured in kilograms. Or, you could specify instead that _weight is `kg` and the engine would automatically infer that GetAcceleration returns `m/s^2`. In fact it was not even necessary to specify any units on the GetAcceleration method; it was sufficient to include units in any call to the method:
_weight as double`kg`
def GetAcceleration(force as double):
return force/_weight
def Foo():
_weight = 3
a = GetAcceleration(2`N`)
x = 3
a2 = GetAcceleration(x)

There are only two unit annotations in this code, but the engine has already inferred that the local variable x has units of `kg m/s^2`, i.e. newtons, while a and a2 have units of `m/s^2`.

If you later wrote code that contradicted the units that had been inferred, the compiler would give you a warning. I was very happy with my work and looked forward to using units in my everyday boo programming. I don't always use many physical units like kilograms and metres in my code, mind you, but I would certainly use a lot of other units like bits, bytes, dwords, records, pixels and percentages.

Unfortunately, as my engine required a parser change, it could not be used with standard boo unless boo's author accepted a parser patch. Unfortunately, when I announced my completed work on the boo group, there seemed to be absolutely no interest in it, and boo's author, Rodrigo B. de Oliveira, never even commented on it.

That's when I earnestly began to work on Loyc. I decided that the set of features a language supports should not be under the control of a single person (boo), corporation (C#), or committee (C++). Instead, I felt, a compiler should exist that allowed anybody to add new features. Soon I came up with a name for this idea: Loyc, or Language of Your Choice, because the my compiler would support multiple languages and it the user could choose what the language would support or prohibit.

But without even a single other person rallying behind my cause, I feel at this point it has been a failure. I would certainly consider working on boo instead, except that boo's developers don't seem interested in nurturing their community by helping people use boo. When boo finally has some half-decent documentation, I may start using it again. Hell, I'd write the documentation myself if I had any clue how to use boo's advanced features, but I don't, so I won't.


leppie said...

Come learn scheme (IronScheme particularly) :)

We have formalized specs for the whole language, and probably more language lawyers than users!

Very easy to get any answer.

Qwertie said...

Sounds intruiging, except that performance is important in almost every project I do... Loyc itself, for instance, needs to be fast so that it can compile large projects. (I learned from using boo that simply ignoring performance gets you a sloooow, memory-hogging compiler like booc.) That IronScheme uses the DLR sounds a little scary to me. But if it interoperates easily with C#, maybe it would be worth learning.

By the way, I've gotten over my slump somewhat... I am working on Loyc again! It'll still be years before you can use it at this rate, but I think it'll produce some useful open-source artifacts in a reasonable amount of time.

teresa said...

Looking at recent activity on SourceForge, you were able to overcome your discouragement and are back working again.

Could you update me?

Best to contact me at


Qwertie said...

Okay, I will cc to your email.

Unfortunately I haven't actually worked on Loyc proper in the past 3 months or so. I've been implementing this wacky trie structure and I just finished a marathon of work on a CodeProject article about it. Thanks for your apparent interest in Loyc - I needed a boot in the pants to get this trie thing out of the way.

Now that it's out of the way, I hope to continue work on a LAIF parser (Loyc AST interchange format) and a parser generator (which will serve as an example of how Loyc enables you to embed DSLs inside C#/boo); and then I plan to use that parser generator to actually parse C#. Bootstrapping the parser generator will involve LAIF...

Of course, I would not expect anyone but me to know what I'm talking about. So, who might you be?

Muhammad Asif said...

Let me know what is the best way to start learning about LOYC. I am interested in learning C#. I saw your article at code project and I was impressed. Followed you and reached here.

Qwertie said...

I haven't worked much on Loyc lately. I am having trouble deciding how the AST should work exactly. The AST is the most important part of Loyc. I have decided it should be immutable, or mostly immutable (the current design in Subversion is an immutable tree with a mutable set of "tags" on each node). It also needs to be extensible, and it must be possible to serialize and deserialize to a simple text form called LAIF (Loyc AST Interchange format). The LAIF parser and rseializer are partially done.

Once I have a finished AST design, the next steps are simple: write a C# parser and a back-end to convert the AST to CIL. Let me know if you would like to help with any of this.