More thoughts on type checking

2 views
Skip to first unread message

Edward K. Ream

unread,
Feb 8, 2012, 8:19:42 AM2/8/12
to leo-editor
Leo's present key-handling code is much more solid than before.
However, I regard it as a work in progress.

In particular, the many type-related assertions in leoConfig.py and
leoKeys.py are a bit un-Pythonic. They are ugly, and they are
shouldn't really be necessary. In fact, they make me uneasy. In the
short term, this can't be helped. However, I would like to create a
more elegant solution.

Any such solution would likely involve richer, stronger classes. The
idea is to have the class understand the tricky relationships
involved, leaving the client code blissfully unaware of the
complications.

For example, I plan to move methods such as k.isPlainKey, k.isFKey,
and several other to be methods of the KeyStroke class. This will
hide more picky details of key-handling from the reset of leoKey.py
and leoConfig.py. Note that the recent "Question for European Users"
was intended to allow this migration.

I'll also create two new classes: ModeInfo and ModeController. You can
think of them as wrappers for the dictionaries that represent mode
bindings. Indeed, the *entry-commands* and *command-prompt* keys in
one of the dictionaries are really ivars of the missing ModeInfo
class.

There is an interesting, if indirect, relationship between these
considerations and lint-like type checking. Imo, the main issue in
type checking is computational complexity. My goal is to design
classes in which important deductions can be made quickly.

Indeed, type checking is usually very simple in a *local* context.
The computational problems arise because deductions have to be checked
globally. This is where classes designed for type checking become
important. We want to have classes that hide the internal details
from client code. If we do that, there will be little or no global
deductions to make.

An example might make this clearer. Leo uses the "c" name throughout
to represent a Commander. We want to show that every "c" really is a
commander. We do this by "induction":

1. Every assignment to c is either an argument whose name is c or the
result of the ctor of Commander objects.

2. Every argument whose name is c is a commander, assume point 1
holds.

This is actually a very simple to verify. We can use "c" names in Leo
because we are pretty sure the induction holds, and very sure that
code will quickly fail if it doesn't ;-)

I'd like to make it easier to rely on such "intuition" for the new si
(ShortcutInfo) and ks (KeyStroke) names. (At present, the code uses
stroke instead of ks, but I'll probably use the shorter names soon).

Edward

Edward K. Ream

unread,
Feb 8, 2012, 12:13:25 PM2/8/12
to leo-editor
On Wed, Feb 8, 2012 at 7:19 AM, Edward K. Ream <edre...@gmail.com> wrote:

> In fact, [type assertions] make me uneasy.

[big snip]

> I'll also create two new classes: ModeInfo and ModeController.

The first draft of the ModeController class used a g.TypedDict, but
this is unnecessary. The code makes it clear that the keys of this
dict are whatever aMode.name is, and that clearly doesn't change.

This is an example of what I attempting to convey: creating better
classes clarifies relationships so much that fancy type checking may
not be needed.

I am beginning to regard any "long-lived" dict in Leo as a design
problem. I plan to enfold many of Leo's key-handling dicts into
easier-to-understand classes. Quick: what are the values and keys for
k.masterGuiBindingsDict? Or even, what the heck does this dict do?

Edward

P.S. Creating the ModeInfo class is going to clarify the client code
in leoKeys.py considerably. The client code should not know the
details of modes; at present, it knows *everything* about modes.

P.P.S. It's becoming obvious that the work with leoConfig.py and
especially leoKeys.py is an essential precondition to better support
of vim bindings and commands. The code is already at the "breaking"
point in terms of complexity. It must be dramatically simplified
before any additions are possible.

P.P.P.S. I am beginning to realize just how much mischief is done by
reading settings twice. In particular, the double read greatly
complicates the way-too-complex init code for c and c.k objects.

EKR

Reply all
Reply to author
Forward
0 new messages