Saturday, March 25, 2006

Evolving a language

Over the years I have tried very hard to maintain a simple and backwards compatible syntax with Liberty BASIC. This has worked well for the most part and most people seem to find Liberty BASIC easy to make friends with.

Sometimes in programming languages it is necessary to be willing to break with the past, especially when bad decisions have been made that hurt the programmer. In Liberty BASIC there is probably one decision in particular that I've been meaning to rectify for some time now, and that is the syntax for interacting with GUI widgets.

Originally it seemed like a cool idea to treat windows and widgets like streams, controlling them by printing to them, and getting information by reading out of them. This was fine in theory, but people don't automatically feel comfortable with this. For example:

'set the font to be Arial of size 10
print #myWidget, "font Arial 10"


Several things about this approach are unpalatable. First, printing to a widget is perhaps more of a leap than most people are comfortable with. Instead they might prefer a straight statement, and not put the command in a string.

The other problem with this approach is that it is just too noisy. I came to realize this a few releases ago and implemented a shorthand without the print keyword and comma, like so:

'set the font to be Arial of size 10
#myWidget "font Arial 10"


Well, that is better but still slightly foreign. Behind the scenes it is exanded to the full form.

Okay now here comes the really difficult part. Since we're sending the command as a string, this can get messy if we want to use variables. We need to concatenate a bunch of stuff together.

'set the font to be Arial of size 10
#myWidget "font ";fontName$; " "; fontSize


Can you say ugly?

Okay, so let's fix this. With Liberty BASIC 5 were going to make another evolutionary step that will give us a lot of flexibility. Instead of treating widgets like streams, we'll treat them like the objects they are. So widget commands will be turned into function calls (or method calls in OO parlance):

'set the font to be Arial of size 10
#myWidget font(fontName$, fontSize)


This is much simpler and cleaner. It is also more similar to the conventions that programmers are used to.

There are also commands which return a value. Here is an example in the current syntax that places the contents of an input field into a variable:

'set myVariable to the contents of this input field
#myWidget "!contents? myVariable$"


In our new syntax you will be able to return a value from a function in the familar way, like so:

'set myVariable to the contents of this input field
myVariable$ = #myWidget contents$()


Were still going to support the old syntax for backwards compatibility, but all the examples and documentation will use the new form.

In addition to using this convention to control widgets, we also hope to use this syntax to add some scriptability to the Liberty BASIC IDE. I'll blog about this in more detail in the coming weeks.

4 comments:

Carl Gundel said...

Supporting the old syntax shouldn't slow anything down, especially since LB5 is a lot faster than LB4 in general.

BTW, the new syntax is already part of the language and not a "to be implemented feature." ;-)

Carl Gundel said...

I should also mention that since the syntax is discovered at compile time there is no runtime penalty for supporting the two syntaxes.

Zack Ohlin said...

Great! I think that this will be a very good improvement. I also like that LB will support both syntaxes, just in case.

~Zack (Z) from the forums

Coda said...

I tend to disagree with this idea. I feel there is nothing wrong with the current syntax. I feel this goes against your own philosophy of keeping LB simple! (Also, see your own post on 'overloading'). But...if you must, you must.