Note : I have left this file 'as is'. This was an
intro to 2.1 (between alpha 1 and beta 1). The product later became C4 with many
enhancements over those detailed here
2.1 Overview
Hello and Good Morning. I’m David Bayliss, I have been authoring
the compiler for the last five years and become the team lead for the templates
and base classes last Autumn. I am also the project lead for 2.1 professional so
if you have any positive feedback I would be delighted to hear it. If you have
any negative feedback then I can direct you to the developer in
question.
My aim over the next fifty minutes is to give you a whistle stop
tour of 2.1, I shall be going into language and template aspects more deeply
tomorrow.
Focus for 2.1
For a product to be cohesive rather than just a rag-bag of OK
ideas you need a focus. CW 1.0 was functionality, 1.5 was RAD producing windows
applications, 2.0 was leverage (getting someone else to produce your
applications for you). So what about 2.1
Downsizing
We are repeatedly told that commerical computing is in the era
of downsizing.
As far as I can tell downsizing is the phenomenan whereby
application software gets bigger every year.
We are told that if cars had progressed at the same rate as
computers we would now be able to buy a family saloon that was 5 cm long, did
20,000km to a litre of petrol and cost about 5 pence.
What they don’t tell you is that if car drivers had
expanded at the same rate as computer software, each car driver would turn up on
average a year late, need 70,000 cars to support his weight, and 98% of them
would crash before you got to the end of the road....
Hello World
Many software products, ourselves included, have tried to sell
themselves on the ease with which you can write a Hello World program. I believe
in CW it takes about 10 lines. But there is one very important question which
(fortunately) no-one has ever asked, that is ‘so what’?
The market for Hello World programs world-wide is very small
indeed, the really important thing about developments tools is surely this
:
Brick Walls
There is no advantage to being able to get 95% of the way
somewhere very quickly if you then pile into a brick wall. What you need is a
system that is very rapid early on, can cruise at high speed, but then can keep
on scaling with you as the project increases in scope.
And that is our focus for 2.1. Scaleability.
Micro->Macro
Genuine scaleability is not simply about one part of your system
getting a facelift (sorry Visual Basic V5) but about going through each and
every part of the product eliminating hazards as they arise.
Here is how we have done this
32 bit support
Long file names in IDE
Long file name support, meaningful file names, 32 bit dialogs.
(Optional)
LFN in programs (including 16 bit)
The next thing is to allow long file names in your programs. 16
and 32 bit ones. You don’t have to force your users to support 32 bit
programs.
Graceful degradation
Win 3.1 is still out there, you can write a program utilizing
LFN that still runs under 3.1 (using shortened file names)
ODBC Driver (Abscess)
Import from 32 bit only drivers
Procedure Level
Source Editor
This is the feature sometimes referred to on CIS and
PWEE.
View / Edit all embeds
An embed editor that allows you to see and edit all embeds in a
given procedure at once.
Cut / Paste etc
Jumps to filled embeds
Error Editing
Configurable source view
Procedure size
Now that your embeds are easy to find you will probably want to
make your procedures bigger and flashier. Personally I think the chap with 32
browses scattered over 22 tabs is going too far, but its’ your choice and we
have given you some technology to help.
DATA in routines
Any routine in your procedures may now have its’ own local data,
further two routines may have data with the same labels and they don’t
conflict.
This is particularly nice for template writers as it means you
can use short meaningful labels rather than Myfield1::ByBrowses:
OOP in templates
Without doubt this is the single biggest advance in terms of
man-hours in the system. Most (but not all) of the templates have been
redesigned around a set of OOP base classes. I will be discussing this in detail
tomorrow but put simply
Control template becomes object
Code goes out of line
How much code? Well the equation seems to be that you get 60K of
base classes but then your generated code is between half and one third of its
original size. So a 250K app would be about 33% smaller.
Relation example has a form with 16 browses that used to just
creep under the 64K limit, it is now about 15K.
ISL Errors go, plists, labs etc
Frame procedure
Module Level
Module Restrictions
Unfortunately there are a set of compiler limits that have
nothing to do with procedure size and therefore OOP didn’t help. They are based
upon the size of a module. They are as follows :-
.idn identifier spellings
.id identifiers
.sym symbols
.fld fields
I was asked to detail what each of these was and how to avoid
them, I was going to do that but then I figured, why bother, after
all.
All Gone
So now with radically improved template code remove
per-procedure restrictions, and compiler front-end limits removed about the only
thing that was likely to stop you was the ...
64K code limit
Gone too!
So we took that out too! So the Clarion 2.1 compiler can compile
just about anything you throw at it ,
Compilation speed
eventually. There is not much comfort in knowing the compiler
can compile your whole application if it wont finish until tomorrow morning and
you need to ship today. So we have worked on reducing your development
cycle.
50% Less code
Firstly, and obviously, given we generate much less code the
compiler compiles much less code which helps a lot.
Also, the size shrinkage means you can have more procedures per
module which cuts down the overhead of recompiling the header files.
Library routines compile once
Each of the base classes is a UNIVERSAL or empty member. This
means you only have to compile it once for each application. Better yet, you can
change an empty member module and your application does not
recompile.
Local maps
One of the most frustrating parts of application development is
when you add one tiny little procedure to an application and every single source
module recompiles. And then you add a parameter and it all re-compiles again.
Then you go back and spell the name correctly and off it all goes
again.
At least it did. Under 2.1 the templates can operate a local map
system. Using this mode a member only includes prototypes for those procedures
it calls so adding a new procedure will typically only mean 2 or 3 modules
recompile.
Template development
Notice I said one of the most frustrating things is
adding a procedure. The most frustrating is undoubtedly changing a line
in a template. First the templates re-register, then the changes are merged into
your application, then your application regenerates and then the whole
lot recompiles. And, of course, given you can’t debug templates you have to keep
repeating this until the system finally works.
Until base classes came along. These make the job so much
easier. The template becomes a relatively thin interface, the code actually goes
into one of these universal member modules.
For those of you who are system minded I would suggest you
seriously look at developing your own base classes & templates, it is much
more productive than it was.
Application Level
Data representation
That all covers your day to day working, some of the most
interesting changes are actually in the way you structure your
application.
Additional sort orders
Browses and reports can now specify the sort order by a key and
additional fields.
Suppose you have an order file which is keyed by CustomerId. But
you need a report of outstanding orders grouped by customer Id but then sorted
by date? What do you do? Well in 2.0 you have to go and create a key in the dct,
rebuild every single app that uses that dictionary and then go and convert every
single instance of data files that use that dictionary.
In 2.1 it is easy. On the report you just say, CustomerId is the
key but then sort by date please. And the system does it for you extremely
efficiently and without touching your data format.
This feature alone can radically reduce the complexity of your
file structures and improve the performance of transaction processing
system.
Auto-increment in base class
Another key to good database design is the auto-incrementing
key. It is usually used when normalising data to assign unique ‘system ids’ to a
record. The problem has been that having one in your file meant you could only
add to the file from a form. Not so any more, auto-incrementing is handled in
the base classes so you can add a record from any procedure or even from embed
code.
Business rules in base class
Clarion has always provided validation checks on fields of a
file, but again these have only taken effect in the form. Allowing invalid data
into the system. Worse yet, for user defined restrictions you have had to use
embeds in the form which means you have to type the same thing into every form
you have.
But not any more. Field validation is now performed in the base
classes and is always checked on an Add & change, there is also one embed
-application wide- for all rules / checks for a given field.
So now arbritrarily complex dictionaries can be represented in
your application.
Dynamic restructuring of RI
Even if they change. One of the most far reaching aspects of the
new base classes is that they are all soft-configured, at run-time in code. So
if you need to slice out some portion of your relation tree (because a
server is down for example) you can do so.
BILF
With all this extra data representation power available there is
still a fly in the ointment, or more specifically a BILF. BILF is a technical
term for B. Irritating little files. If you have an application of any size and
have normalized your data you will almost certainly have come across these. They
are hard to define but generally they can be updated with one tab, probably have
one key, often only two fields. Examples are county codes, status categories,
may department names.
The one thing they have in common is that are not central to
your application but you still need to produce browses and update forms for them
nonetheless and your real procedures often get swamped by the
trivia.
A quick straw poll indicates that in a sizeable application up
to 50% of files may be BILFs. I believe heavily in normalization and have one
app with 3 files and 17 BILFs....
So in 2.1 we have gone on a BILF hunt
Edit in Place browses
In one swoop this eliminates the need for update forms for
BILFs. The user can insert / change / delete records directly from the browse.
The EIP system automatically deals with auto-inc keys and if the browse is
restricted then those restrictions are copied into the new record fields
too.
Auto-Fill combo boxes
But sometimes you don’t even need a browse. We have always had
combos but now they are nice to use. As you type the system auto-completes the
combo for you (like Quicken or MS Books). You can also insert to a combo and
auto-increment is now handled for you.
Relate:Customer.Open
Another way we have dealt with BILFs is to make them invisible
at the code level. You can now open a main file and all accompanying BILFs are
dealt with too.
Logout restrictions removed
The final nasty to be removed is the 26 file restriction on a
logout.
Scaling data
So far we have dealt with scaling your applications and data
structure. But what about the data itself. Your problem may not be 300 files but
one file that 100G big. How do we deal with that? Well for files that size you
probably need one of our native SQL drivers, and they have been upgrade for the
following :-
SQL Fat fetches
This is a simple but effective was of reducing network traffic,
the system will now fetch data by the browse-full rather than by the record. Put
another way, you data comes back as fast as it possibly can.
There’s only one way you can spend less time waiting for your
data
SQL Asynchronous read ahead
You don’t. This is simplest to understand for reports although
it also works with browses. Imagine the system fat-fetches 10 records for you.
Before you process those 10 records you send to the server asking for another
10. Instead of waiting for those records you set about processing the first 10,
adding totals whatever. Then when you have finished you go back and collect the
2nd set of 10 records, and order your third set. So basically either
your file I/O or your printing becomes free.
More efficient browse code
This one is much more simple. It turns out the old browse code
was quite sloppy in a few places, we have re-written those parts and browses are
now much faster to load. 2 - 3 times on start up.
Contracting locators
This one is really for SQL people again, it specifies a bottom
and top range limit for a field, this often results in partially filled browses
which again helps network traffic.
Really scaling data
Ok, so now we have the Lan sorted out but what if we want to
transmit data across really large distances. Like, all over the world, to
millions of people in hundreds of different countries. And what if they don’t
have our application already and maybe don’t have a machine that could run our
application. In other words, what do we do if we want our application to be run
from an internet browser?
One click WWW applications
No problem, with CW Internet Connect you can make your standard
Clarion application Webable, at the click of a button.
Dual Windows / Web solutions
Further, you can produce applications that run as normal
applications or run over the net. So you can develop and test locally,
maybe upgrade to a LAN later, and then go WWW.
No additional software (or knowledge)
needed
And our software solution really is a one-stop-shop for you WWW
needs.
Stay tuned
Story so far ...
So with 2.1 you can produce extremely complex, lean, mean and
hungry applications using advanced RAD techniques. There is only one thing now
likely to get in the way of you and eventual success ...
Enterprise
However good you are a project that becomes sufficiently big
will begin to outstrip your personal ability to keep track of what is happening.
As part of our commitment to allowing developers to produce Enterprise wide
software solutions 2.1 will be launched in Professional and Enterprise editions.
In addition to supporting our native SQL drivers enterprise edition will have
the following features (these will be covered by SF in his breakout
session):-
Visualization
Fully graphic entity relationship diagram
A picture is supposed to be worth a thousand words, it can
certainly be worth a thousand fiddly little dialog boxes. So Enterprise comes
with a graphic entity modeller for visualizing the structure of your
dictionary.
Alternative DCT front end
As well as the overview this product has been crafted to produce
a complete alternative front-end for your dictionary.
Field Pools
One of the features.
Dwiz integrated with CW
IOW Don’t blame when it doesn’t work.
Source control
One thing that is invaluble when you are under pressure is
simply being able to find out what has happened and regress if you need to. The
source control product allows this.
Control over APP and procedure level
Keep track of changes to each procedure
Revision control system
Allow you to keep track of different revisions and
version
Multi-user locking
Of course if the project gets big enough you may need help, this
part of the package allows 2 or more developers to work together without
treading on each others toes
Template control
Keep control of tempaltes too.
DCT Synchronizer
Synchronize two Clarion dictionaries
The ability for two people to work together extends to the
dictionary too. With the DCT synchroniser you can simply interweave changes to a
DCT with a master source.
Better yet, the synchronizer can write a program to upgrade all
of your data to the new Dct structure.
Synchronize Clarion to Server
But this is the really clever bit. As well as synchronising DCT
to DCT you can synchronize a Clarion dictionary to an Oracle database, or to a
Btrieve DDF, or SQL server, or AS/400 etc etc.
Bulk import to Clarion
And there are two very special cases of syncing Clarion to
Server. The first is when your Clarion DCT is empty, this package will
bulk-import your entire SQL database into Clarion in one go. Relationships and
all. So you really can march in to an MIS department, suck their whole database
into a DCT, use the AppWizard and then watch the MIS manager hit the
deck.
Your portable DBA
And you can do it the other way around, you can take your DCT
toa site and create an SQL table structure to handle your dictionary.
And just in case you were wondering :-
Aliases automatically handled
User interface
Of course all this power could be a little intimidating. About a
year ago Ilka who wrote this came up to me and said "We are forming a design
panel for the DCT synchronizer would you join it please?". I smiled knowingly
and said "Ilka, I am a compiler writer, I don’t know a dictionary from my elbow.
I havn’t the foggiest idea how to design a dictionary synchronizer". She said "
I know, that’s why we want you on the panel, we figured if you can understand
what we are doing then everyone else will too...." So here it is :
Wizard setup
Most importantly it is very quick to get into. A few wizard
pages go through asking you where the files are and which direction you want the
merge to go.
Drag and Drop
You are then dropped into a couple of tree structures, source
& target. The system will have matched up all the obvious fields and all you
have to do is drag & drop the rest (which are in bright red).
Goal seeking auto-correction
Just in case you can’t spot these bright red lines the system
will automatically take you to them. If resolving one problem could lead to
another then system will warn you and take you there too.
Sometimes if you resolve one problem the system can then take
over and solve some other ones for you, and it does so.
Altogether this is probably one of the most user friendly pieces
of software we have produced.
Session memory
And the piece de resistance is that when you have finished the
system remembers as much as it can about what you did so that next time you
synchronise those two systems it can do even more of the work
automatically.
End
So there we have it, Clarion for Windows 2.1, Clarion at
Large.
Language and Templates
Good day. My aim in this session is to give a brief overview of
the new language features in 2.1 and a conceptual overview of the new base
classes. These subjects will be covered in much greater detail in the day long
seminar given by Roy Hawkes tomorrow.
Incremental Derivation
There are really just two major conceptual jumps in the 2.1
language spec, between them they enable us to produce object oriented code that
is safer and simpler than that available in other OOP languages. The first of
them tackles the need to produce a derived class that is very similar to
a parent class.
Very thin subclasses
Our embed system basically has done this for years, allow you to
take a large standard procedure and add a tiny snippet of code of your own, the
only problem has been the templates have then splurged hundreds of copies of the
parent all over the place.
PARENT keyword
Note that our system is quite a bit cleaner than C++, it that
language you actually have to name the parent you are casting to, that code then
breaks when you add a layer between the two classes, our system is
safe.
Embed system
PROTECTED
To further support object extensibility we have added the
PROTECTED keyword. This is for data and methods that may change from major
release to major release so cannot be made public but that may be useful to
someone writing base-class code.
Polymorphic variables
The other is actually not that new at all. Clarion has had type
polymorphism since CDD 3.002, it is the *? Parameter. The difference now is that
you can have them as data.
Any Keyword
Any is a new data type, and as the name suggests
MyAny = POSITION(blarg)
They can hold any value. Here I am using them to give me
genuinly dynamic length strings. You can also store numbers and whatever data
type you store the collate correctly.
MyAny &= SomeField
But here is the interesting case. An any can store a reference
to any other simple data type, and from then on that any refers to that
variable.
Example
The reason this is powerful is that a Q of them can be used to
refer to any group of fields, such as those projected from a view, in a
completely abstract way. ANYs have allowed us to eliminate over 70% of the
virtuals from a traditional OOP system.
Any other business
Contructors / Destructors & REPLACE
Some people will be delighted to know that Clarion now fully
supports constructors and destructors in exactly the same manner as C++. Those
of you like me that prefer to have at least some idea of what their code is
doing will be delighted to know we have also implemented the REPLACE attribute
which allows you to switch off a parent constructor or destructor.
ELSE in execute
This was a customer suggestion, the only thing we couldn’t work
out was why we hadn’t thought of it ourselves.
DATA in routines
This further enhances the use of routines, data in routines is
local in scope so labels will not clash with those of parents or global
data.
ITEMIZE (enumerated types)
This is a good way of tidying up a series of equates.
Any more
IF Ref &= Variable THEN
One other thing we have done is allow you to turn a reference
assignment into a condition. This means does this reference point to this
variable, it also works if you have an ANY on the l.h.s which can be
useful.
IF Ref &= NULL THEN
A special case that is useful is ‘does this reference point to
anything yet’.
Return from functions by address
This allows you to return structures such as classes from a
function.
CHOOSE any types of parameters and short-circuit
File.field
Nested dimensioned groups
Any more more
OMIT(blarg,undef)
Auto-init of heap data
MyRef &= NUMBER
Allows you to cast references. Extremely low level, extremely
dangerous and occasional extremely useful.
CLEAR(File)
MyGroup[3].MyField[2]
Templates go OOP
The biggest single piece of template news that won’t surprise
anyone is that in 2.1 the generated template code has gone OOP. What might
surprise some people is this.
But in fact, they already were
We have always claimed that templates offered a visual object
paradigm, and it turns out they did. So for 2.1 the template interface has not
had to change one iota. Obviously new features have meant new prompts but the
interface has remained fixed. All that has changed is that the generated code
now reflects the IDE interface.
Control templates
So when you drop a browse engine on your screen a browse object
lands in your procedure. When you set a property on your browse control a
property gets set in your browse object.
Extensions become contained
Extensions & child controls simply become contained objects.
You’ve dropped a locator onto your window? A locator object gets dropped into
your browse object.
Code in procedure becomes your code
Is the code readable, thats up to you, its your code.
File Manager
So now for a quick whistle stop tour of the major base classes
and what they do for you.
Corresponds to one file
The file manager for a given file is really an embodiment not
just of the underlying file but also the various field and record level
contrainsts applied within the dictionary.
Auto increment
Field and record validation
In 2.0 limits were only applied in the form, so they weren’t
really a safeguard. Now they are applied in the base classes, so whereever they
are accessed from, even hand code, the validation applies.
Error handling
The base classes also handle errors, including user interaction
and retries.
Key labels
Also provides information about the file to other classes. For
example in here is a routine to convert a key to an order clause.
Relation manager
The relation manager is one step further up and reflects you
file in the context of all its related files.
Corresponds to a relation tree
Relation manager is a file manager and a list of other files.
One thing to remember is this relation is soft, so you can alter which files are
in a tree at run time.
RI
Handles RI, currently the same RI scheme is used as in 2.00x but
the whole of the RI code is now contained in 4 functions so if you wish to
implement some new RI scheme the problem is tightly defined.
Broadcast opens
One line allows you to open a whole relation tree.
Save / Restore
Allows you to snap-shot a whole relation tree and restore it
later. This can cut down on the need for aliases.
Logout
Allows you to work within a transaction frame
View Manager
File Schematic
The easiest way to see a view manager is as a file schematic,
the picture is not quite true but that is probably why it is easy to visualize.
Multiple Sort Orders
The view manager implements our key + additional fields scheme,
it allows multple of these to be defined and switched between (corresponding to
tabs on a browse) and handles keeping the correct record in different sort
orders
Range Limits
It also handles our standard types of range limit, you just say
what you want done and it looks after all the temporary variables, seeing if
limits have changed etc etc.
Multi-part filters
We have also implemented named multi-part filters. In a complex
browse a number of people will each want to specify part of the filter. Some
will be the range limit, some for a programmer filter, some for a contracting
locator and maybe even a user defined filter. Well now you can have all of these
on the go without them treading on each others toes.
Constructing blank records
The final thing the view manager will do is construct blank
records of the primary file for you. These are not just cleared and
auto-incremented but also if you have a range limit that specifies
‘Country=’France’’ then it will fill in France in your country field.
Particularly useful for edit in place and drop down combos.
Browse Class
Bulk of code gain
This really is where the biggest code gain is. Power Browse has
always claimed to get 50% code reduction over our browse. Because we use ANY
rather than virtuals we get 75%, browses are now very cheap indeed.
page loaded view manager
The essense of a browse is really just a page loaded view
manager, and that is precisely how the browse is implemented. A view manager
with a queue attached.
Container class
But the browse manager is also a container class, that is it
comes with lots of hooks to allow other smaller classes to be hung off it. Here
are the ones that come in the box
Locators
Entry, Step, Incremental. The nice thing was when I came to
implement contracting locators it took just a couple of hours, just slotted
straight in.
Popups
The browse also contains a popup manager to look after the RM
key. The nice thing about this is you can simply tell the popup manager :’Add a
menu item and make it like this button (or menu item)’. And then there is no
more work to do. If the button is disabled so is the popup menu item, when it is
selected your button gets an accepted event.
You can now add whatever you wish to a popup menu with one line
of code.
Step Class
We have a set of classes to handle (among other things) the
thumb down the r.h.s of a browse. The basic issue is you have to guess how far
you have got simply from the data field. We tackle it is a class so that we can
use the same technology to get the progress bar correct on a report.
Edit In Place
One of the new ones is the edit in place class. The one we
provide is quite simple, it implements edit in place as an entry control. You
can create your own to have such things as drop downs and spins as part of your
e.i.p
Others
Process class
This is really just a view manager with some boiler plate to
handle a progress bar and the step class.
Print Preview
Well we re-wrote this in 2.0 and we have re-written it again in
2.1 to make it smaller, faster and more functional. Importantly we have
implemented it cleanly this time so we can expand it over time to bring it up to
a full industrial strength print preview engine.
Ascii Classes
The good old ascii box but now it is page loaded to allow
editing over very large files.
Toolbar Classes
I’m sure you’ve noticed that some people don’t seem to do
anything useful themselves they just spend their whole time bossing others
around. Well that is what the toolbar classes do. They are parasite classes that
latch onto a reltree, update form or browse and enable it to be toolbar
aware.
Translation Classes
All of our base classes can be easily translated into a
non-English language by simply editing our translation header files. We have
also built in a translation class that can walk over a window structure and
translate all the strings and prompts and column headers etc on a
window.
Error Class
We have also provided a completely soft error handler. By
default it works much as 2.0 does but it can easily be extended to allow you to
handle errors yourself.
Visual OOP
Global Class Tab
One final aspect we have focused on is the ability for people to
extend our templates cleanly. So on the global properties there is a class tab
that specifies the default class name, header and implementation files for all
the objects used in our system. So if you produce your own derived versions of
these you can simply drop them into the system once and from then on your
classes are used, not ours.
Complete 3rd party integration
This gives us this. Better yet, provided the third parties stick
to our well documented class structure you will be able to mix-and-match
3rd party base class extensions. A PB browse, a Hanson invoice update
and a Teames report.
Local Class Tab
But we have also focused on the detail. In each procedure you
may program the individual objects that comprise your window. So you can add
data or override methods in your browse object to get specific behaviour you
require. And the nice thing :
Explicit automatic derivation
Is you can do it without even understanding the OOP syntax. The
system will automatically derive and instantiate your classes and just leave you
to fret about the code.
Now what could be easier than that?
Implicit Automatic Derivation
And the answer this! Pressing a button can be a real drag so for
those things you will commonly want to do (such as formating some elements of a
browse) we have simply provided you an embed point, if you put something in
there it sets of a trigger and the system automatically performs all the above
derivations for you.
Conclusion
So there we have it, the move over to OOP is not complete, and
we have only really just begun to exploit the new platform we have created. I do
hope that I have you’ll a taster and the confidense and will to go and have a
look for yourself. I also heartily recommend that as many as can go along to
Roys sessions tomorrow to look at these issues in more
depth.