Going up One more level of abstraction up from objects and relational data…

This is the thing that I start to build in every programming language… no matter what. I’m not particular about how it gets done. It can be done all in Lisp. It can be written in any language and made to make script files to compile to a Blub. There may even be languages that integrate these sorts of features already. Whatever works.

The first thing I need is to have tables be first class citizens of the language. Following the “simple things should be simple” dictum, the core case of the standard table of data with the first column being the “key” should be easy to write and edit. Non-coders should be able to immediately maintain some of this. For a lot of what I want to do, I don’t care about data types. Having everything in the table cells just be what they are (in the tradition of Perl’s scalar’s) is sufficient for most cases. The tables have to be globally accessible throughout the coding environment. Individual cells should be referenced with some sort of sigil or read macro– if I can do it however I want, I tend to use something like TableName~Key~ColumnName.

As far as syntax goes for defining a table, it takes at least two lines to specify a table: one to name it and one to list the columns. There could be parenthetical asides for each column name with a regular expression for use with validating incoming data. After those two initial lines come separate rows of comma delimited data. You could maybe use a marker on the table name to specify different delimiters or alternate methods of outlining the data if you wanted. One thing I do is (by default) trim off the leading and trailing spaces before loading up the data into the hashtable (or whatever) that will store it. That way the code for the tables can be prettied up for readability purposes.

The next thing I want is a way of defining objects that eliminates much the boiler plate that I tend to have to write when I code them. I want to go up another level of abstraction, organize everything a little better, and synthesize a lot of concepts that I picked up here and there. This isn’t really a more generic way of doing objects… but more of a specialized implementation of them for a particular domain of problems. I’m probably specifying an awful version of something that already exists, but here’s what I’m thinking anyway.

Your primary component of a widget is its Input or Read-Write fields. These can be modified with a regular expression in a similar way to how we specify table columns. Heck, we could even specify a validation message if some input fails to meet the regular expression. We could also optionally tack on some parenthetical modifiers– default values, markers that note the units of measure being used, etc. In order to fulfill the closure property, some of the Read-Write fields might be other widgets or collections of widgets.

A secondary component of the widget is a set of derived fields. These are specified as an expression that references other fields in the widget and/or tables in the environment. One crazy idea I had was to be so dynamic that some of these fields disappear altogether given certain combinations of Input fields. Properties and methods come, go, and change depending on the values of the input fields. Next there are warnings and errors that are triggered by certain combinations of Input fields. Finally, there should be a suite of events that can be filled in with custom code like you see in typical GUI frameworks (and maybe even CLOS, I think.)

Where I’m going with this is I want to be able to make an interface (both command-line/scriptable and GUI) that can consume these widgets, present the options to the users, and interactively display the results of fiddling with the different values. This way, complex things can be configured by the user… and the programmer can maintain the “model” definitions without having to touch any user-interface code.

I have a domain in mind for applying this framework, but I don’t think I can both develop the framework and apply it given the limitations on time, knowledge and resources that I have. I do have time to develop test cases for a hypothetical system and hone the overall design concept with real feedback from a concrete application. (I estimate that it would take me years to work out a mediocre way to do this… when there’s people out there that could crunch through the core architecture in a weekend or two. And then there are the mondo-evil problems that I haven’t anticipated yet that would likely derail me from ever finishing anyway. So… I’m just tossing this out there to get feedback from wiser, more experienced developers before I waste months of time chasing a dead end.)

(And as with sed one-liners and other kewl Unix tricks, the point of this is not so much the particular domain or example that I have in mind. The point is… someone that can do this and understand how to deal with these issues could code really good maintainable solutions to all kinds of things. It’s this kind of problem that motivates me to study Lisp and other “hard” problems.  There’s no immediate business value to it, though solving this may put you within “5 minutes” of getting something done that is valuable.)

Here’s a “back of the napkin” type example script:

Table Stuff:

Widget Foobar:
Read-Write Fields:
	Level [Option A|Option B|Option C]
	Weird /GRIBFOO[\d][A|B|C]/ "This is a validation message."
	Stuff [A|B]
	Number [1-72] (in pounds, default to 42)
	MyFoos (Collection of Foos)
	MyBars (Collection of Bars)
	MyBaz (Widget Baz)
Read Fields:
	TableLookUp --- Stuff~{Stuff}~Description
	ExpressionExample (If {Stuff} = "A") --- {Number} * 3 + 1
	ExpressionExample (If {Stuff} = "B") --- {Number} + 100
	TotalOfChildFooThingies --- Sum({MyFoos~FieldName})
	{Level} == "Option A" --- "This might not work."
	{Level} == "Option B" --- "You really hate this!"
	{Stuff} == "A" and {Level} == "Option C" --- "Bad {Stuff} for {Level}."
	print "You just changed the number field.\n";

6 Responses to “Going up One more level of abstraction up from objects and relational data…”

  1. Mark Miller Says:

    Regarding your wish that someone write a language that handles widgets at a higher level of abstraction, I know of a package that’s been around for a while for Squeak called Magritte. You didn’t mention a particular language/platform, so I figure this is germane. It does what you describe WRT widgets. It’s a meta-language. It allows you to specify form fields simply, what they will accept, how they will be displayed (and you can set conditions). I just went by the site for it and it says that you can modify the meta-language because “Magritte is written in itself”.

    I know OO is not your cup of tea, but you can use it as a model if you want. The source code is all there.

  2. Vilson Vieira Says:

    It remember me Weblocks: http://common-lisp.net/project/cl-weblocks/ with it’s widgets and scaffold mechanism.

  3. Chui Tey Says:

    You have to take a look at the Andromeda Project. Ken has extracted a lot of patterns into his meta-spec.

  4. using the sphincter-sigil to abuse Perl « Learning Lisp Says:

    […] is bogus and brain dead. But but by marrying this to our table parsing code, we can create our own Frankenstein style scripting language. We already can create specialized data structures can initialize them with data parsed from a […]

  5. 4GL Patterns #7 - Data Dictionaries | Chui’s counterpoint Says:

    […] abstracting relational data, […]

  6. Perl source filters: evil or not? « Learning Lisp Says:

    […] also brings me back to my original ‘dream’ project. I could create my own shorthand for a certain class of objects. I could create a set of source […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: