[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnu-arch-users] Re: ITLA
[Gnu-arch-users] Re: ITLA
Mon, 1 Mar 2004 18:50:23 -0800 (PST)
> From: Andreas Rottmann <address@hidden>
> I also agree here, but IMO, this doesn't speak against using GOOPS as
> a "back end"; i.e. making the declarations create GOOPS instances, but
> not letting that shine thru at the surface.
> Sure, a clean seperation between surface syntax (for declarations) and
> the internal workings is, to say the least, desirable.
I basically agree with all of that but with a caveat. The
distinction between "interface" and "internals" in the command
processor of an extensible systems is bound to be fuzzy. I'm not
saying that the coder of the command processor has to support every
gross hack that anyone ever thinks of --- just that having a really
simple design that promises to be stable and that invites and rewards
"suprising" hacks on top of it is a good thing.
> > One way to avoid such disasters is the "lego approach to lisp
> > programming". [...]
> > Perhaps you are familiar with the famous debate between Jamie
> > Zawinski and RMS about whether events and keymaps should be built up
> > out of simple lisp types (RMS) or should be a special disjoint type
> > (jwz). RMS was, in effect, applying the "lego principle" and I
> > think his was the superior idea.
> Do you have any references to this discussion?
Oh, foo. Google around for Xemacs, and jwz, and rms until you get
bored. The way it's gotten "recorded in history" really obscures the
underlying technical issues and tends to come out as some kind of
clash of personalities. (But there's some funny, albeit ironic,
commentary around it.)
> For instance, I just find that generics are just too damn convienent
> for managing the namespace, so I don't really want to miss them: You
> get away with short names, since generics are mergable (should names
> ever collide) if you just keep prefixes for the classes. A short
> example out out the (itla tla) module is:
> (define-class <tla> ()
> (cwd #:init-thunk getcwd #:accessor working-directory)
> (flags #:init-value '() #:getter flags))
> (define-method (invoke (tla <tla>) (command <string>) (args <list>))
> "Returns the output of the tla command as a list of lines."
> (if (flag-set? tla 'verbose)
> (format #t "invoking tla: ~S ~S\n" command args))
> (let ((check (if (string= command "changes")
> (lambda (val) (<= 0 val 1))
> (lambda (val) (= 0 val)))))
> (if (flag-set? tla 'dry-run)
> (apply command-output/check check "tla" (cons command args)))))
> So you can just:
> (define *tla* (make <tla>))
> (invoke *tla* "get" '("--link" "foo--bar--1.0" "some-dir"))
> Without using GOOPS, this would probably look more like:
> (define *tla* (make-tla))
> (tla-invoke *tla* "get" '("--link" "foo--bar--1.0" "some-dir"))
> The tla- prefix in this case is not that inconvient, so this is a bad
> example, but there are types, for which no suitable
> (i.e. readable/easily recognicable) short prefixes can be found.
> Of course, this is just low-level stuff, and would never shine thru up
> to the "declarative level".
The last paragraph is probably the most important.
Keep in mind, too, that someone might want to write extensions that
crawl over the set of commands -- perhaps to format a help message or
perhaps to make some new kind of menu-driven interface. Keeping all
the relevent data in the simplest format (e.g., s-exps following an
extensible syntax over basic types) makes that easy.
For example, since you have the basic idea of a command processor of
the sort we're discussing, can you:
(a) imagine an implementation
(b) presume the implementation is built, has at least a CLI a
front-end and maybe a GUI front end.
(c) assume that lots of people have written code against this
(d) imagine implementing something like:
in a way that everybody's existing code "just works" with
the new input method?