[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44. Future Work Discussion

This chapter includes (mostly) email discussions about particular design issues, edited to include only relevant and useful stuff. Ideally over time these could be condensed down to a single design document to go into the normal Future Work section.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.1 Discussion – Garbage Collection


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.1.1 Discussion – KKCC

KKCC is the tag used for the “new garbage collector algorithms,” which are a refactoring of the garbage collector to make trying new collectors simpler.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.1.2 Discussion – Incremental Collector

The incremental collector is designed to allow better “realtime” performance by not requiring a full mark and sweep pass. This also allows removal of most finalizers, as described in ‘<vpd8x1fomdx.fsf@informatik.uni-tuebingen.de>’ by Marcus Crestani on xemacs-beta:

I was able to nuke many finalizers by transforming separately allocated data structures to Lisp objects. Some of the remaining finalizers are also likely to go away, as soon as I (or someone else) find the time to “lift” the remaining, separately allocated objects to Lisp objects.

Unfortunately, the current Lisp object layout leads to holes in the write barrier: Not all data structures that contain pointers to Lisp objects are allocated on the Lisp heap. Some Lisp objects do not carry all their information in the object itself. External parts are kept in separately allocated memory blocks that are not managed by the new Lisp allocator. Examples for these objects are hash tables and dynamic arrays, two objects that can dynamically grow and shrink. The separate memory blocks are not guaranteed to reside on page boundaries, and thus cannot be watched by the write barrier.

Moreover, the separate parts can contain live pointers to other Lisp objects. These pointers are not covered by the write barrier and modifications by the client during garbage collection do escape. In this case, the client changes the connectivity of the reachability graph behind the collector’s back, which eventually leads to erroneous collection of live objects. To solve this problem, I transformed the separately allocated parts to fully qualified Lisp objects that are managed by the allocator and thus are covered by the write barrier. This also removes a lot of special allocation and removal code for the out-sourced parts. Generally, allocating all data structures that contain pointers to Lisp objects on one heap makes the whole memory layout more consistent.

A large part of the patch converts these data structures to Lisp objects. The conversion of an additionally allocated data structure to an Lisp objects includes:

The initial motivation for this is the write barrier and the consistent format for all objects that may contain Lisp pointers. That we can get rid of finalizers this way follows naturally.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.1.3 Discussion – Pure Space

On Tue, Oct 12, 1999 at 03:36:59AM -0700, Ben Wing wrote:

So what am I missing here?

In response, Olivier Galibert wrote:

Two things:

  1. The purespace is gone

    I mean absolutely, completely and utterly removed. Fpurecopy is a no-op now (and have been for some time). Readonly objects are gone too. Having less checks to do in Fsetcar, Fsetcdr, Faset and some others is probably a good thing, speedwise. I have it removed some time ago because it does not make sense when using a portable dumper to copy data in a special area of the memory at dump time and I wanted to be sure that supressing the copying from Fpurecopy wouldn’t break things.

    Now, we want to get the post-dumping data sharing back, of course. In today systems, it is quite easy: you just have to map the file MAP_PRIVATE and avoid writing to the subset of pages you want to keep shared. Copy-on-write does the job for you. It has the nice side effect of completely avoiding bus errors due to trying to write to readonly memory zones.

    Avoiding writing to the "pure" objects themselves is already done, of course. Would lisp code have written to the purecopied parts of the dumped data that it would have exploded long ago. So there is nothing to do in this area. So the only remaining thing is the markbit. Two possible strategies:

    The second solution is more appealing to me for a bunch of reasons:

  2. Finding all the dumped objects in order to unmark them sucks

    Not having to rebuild a list of all the dumped objects in order to find them all and ensure that all are unmarked simplifies things for me. Errr, ok, now that I really think of it, I can rebuild this list easily, in fact. And I’m probably going to have to manage it, since I feel like the lack of calls to the finalizers for the dumped objects is going to someday turn over and bite me in the face. But anyways, it makes my life easier for now.

    So no, it’s not a _necessity_. But it helps. And the automatic sharing of all objects until you write to them explicitely is, I think, really cool.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.1.4 Discussion – Hashtable-Based Marking and Cleanup

On 10/12/1999 5:49 PM Ben Wing wrote:

OK, I can see the advantages. But:

  1. There will be an inevitable loss of speed using a large hashtable. If it’s large, I say that it’s just not worth it. There are things that are so much more important than futzing around with the garbage collector (e.g. fixing the god damn user interface), things which if not fixed will sooner or later cause XEmacs to die entirely. If we are causing a major slowdown in the name of some not-so-important work that may or may not get done, we shouldn’t do it. (On the other hand, if the slowdown is negligible, I have no problems with this.)
  2. I think you should expand the concept of read-only objects so that any object (especially strings and cons cells) can get marked read-only by the C code if it wants. (Perhaps you could use the now-unused mark bit to hold a read-only flag.) This is important because it allows C code to directly return internal lists (e.g. from the specifiers and various object property lists) without having to do a copy, like is now done (and similarly, potentially to directly accept lists from a Lisp call without copying them for internal use, if the Lisp caller is made aware that the list might become read-only) – if the copy weren’t done and some piece of Lisp code went and modified the list, XEmacs might very well crash. Thus, this read-only flag would be a huge efficiency gain in terms of the garbage collection overhead saved as well as the speed of copying a large list. The extra checks in Fsetcar(), etc. for this that you mention are in fact negligible in their speed overhead – one or two instructions – and these functions are not used all that commonly, either. With the changes I have proposed in Architecting XEmacs, the case of returning an internal list will become more and more common as the power of the user interface would be greatly increased and along with it are lots and lots of lists of info that need to be retrievable from Lisp.

BTW there is a wonderful book all about garbage collection by Jones and Lins. Ever seen it?

 
http://www.amazon.com/exec/obidos/ASIN/0471941484/qid=939775572/sr=1-1/002-3092633-2509405

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.1.5 Discussion – The Anti-Cons

From: "Ben Wing" <ben@666.com> Date: Tue, 14 May 2002 06:48:09 -0700

i was thinking about the proliferating types of weak hash tables – e.g. now we have "key-car-value weak" hash tables due to a need in the glyphs code. i realized there should be a general solution, that lets you control exactly how the weakness of such hash tables work.

and, assuming we implement a simple "reference" type, a simple container whose object is a weak reference and thus gets converted to nil (and a flag set on the reference) when the object is collected, it would be useful for more precisely controlling the reference, too.

it’s called an "anti-cons". it behaves somewhat like a cons in that it boxes two items, but its marking properties are very different – in fact, backwards. normally, a cons, if marked, marks its children. in this case, if the children of an anti-cons are marked, it marks itself! you’d need a few different kinds of anti-cons – probably the following:

 
and [marks itself if both children marked]
or [...]
left [marks itself if left is marked, and then marks the right]
right [...]
not-left
not-right

by putting such an object inside of a weak reference – e.g. in a weak hash table – we can set up a tree of arbitrary complexity which implements any boolean formula of markedness over any number of objects. this would easily handle key-car, and key-cadr, and key-car-or-cdr, and key-((caar or cadr) and cdr) etc. etc.

implementing this in the current xemacs framework is mostly trivial.

michael, would such an object get in the way of your new gc?

From: sperber@informatik.uni-tuebingen.de (Michael Sperber [Mr. Preprocessor]) Date: Tue, 14 May 2002 16:04:01 +0200

You might want to look at

http://research.microsoft.com/Users/simonpj/Papers/weak.htm

for a pretty comprehensive survey of what you could want in terms of weakness. Its weak pointers are very similar to your anti-cons. However, there are some problems in doing the same in a Lisp settings, mainly because of symbols. I intend to elaborate on this next week; this week is full, unfortunately.

Ben> implementing this in the current xemacs framework is mostly Ben> trivial.

Ben> michael, would such an object get in the way of your new gc?

Well, our first commit will be an implementation of vanilla weak boxes (ready within the next few days, I hope), and we’ll then try to replace most other instances of weakness with uses of those. We’ll then try to find a more general solution for the rest. (Richard Reingruber has already done a comprehensive survey of the trouble spot.

Can you wait until next week? I’ll try to come up with a battle plan then.

From: sperber@informatik.uni-tuebingen.de (Michael Sperber [Mr. Preprocessor]) Date: Tue, 28 May 2002 16:14:20 +0200

We’ve now started implementing ephemerons as a building block for the more involved weakness-involving data structures:

The relevant reference is

Barry Hayes. Ephemerons: A New Finalization Mechanism. OOPSLA 1997. 176–183

The idea is this:

an ephemeron consists of a key and a value. Through the ephemeron, the key is not reachable. The value is only reachable if both the ephemeron is reachable and the key is reachable. If the ephemeron is reachable and the key becomes unreachable, the value slot of the ephemeron will be tombstoned, i.e. overwritten with NIL or something.

This allows implementing, AFAICS, the other data structures involving weakness, such as weak hash tables and their various mutants.

We’re also planning to come up with a more comprehensive solution for finalization, but some design snags remain to be worked out.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.2 Discussion – Glyphs

Some comments (not always pretty!) by Ben:

March 20, 2000

Andy, I use the tab widgets but I’ve been having lots of problems.

1] Sometimes clicking on them does nothing.

2] There’s a design flaw: I frequently use M-C-l to switch to the previous buffer. If I use this in conjunction with the tabs, things get all screwed up because selecting a buffer with the tab does not bring it to the front of the buffer list, like it should. It looks like you’re doing this to avoid having the order of the tabs change, but this is wrong: If you don’t reorder the buffer list, everything else gets screwed up. If you want the order of the tabs not to change, you need to decouple this order from the buffer list order.

March 23, 2000

I’m very confused. The SIGIO timer is used only for C-g. It has nothing to do with any other events. (sit-for 0) ought to

(1) cause all pending non-command events to get executed, and (b) do redisplay

However, sit-for gets preempted by input coming in.

What about (sit-for 0.1)?

I suppose a solution along the lines of dispatch-non-command-events might be OK if you’ve tried everything else and it doesn’t work, but i’m leery of introducing new Lisp functions to deal with specific problems. Pretty soon we end up with a whole bevy of such ill-defined functions, like we already have. I think instead, you should introduce the following primitive:

 
(wait-for-event redisplay &rest event-specs)

Waits for one of the event specifications specified to happen. Returns something about what happened.

REDISPLAY controls the behavior of redisplay during waiting. Something like

EVENT-SPECS could be

 
t                     -- drain all non-user events, and then return
any-process           -- wait till input or state change on any process
process               -- wait till input or state change on process
time                  -- wait till such-and-such time has elapsed
'user                 -- wait till user event has happened
'(user predicate)     -- wait till user event matching the predicate has
                         happened
'event                -- wait till any event has happened
'(event predicate)    -- wait till event matching the predicate has happened

The existing functions next-event, next-command-event, accept-process-output, sit-for, sleep-for, etc. could all be written in terms of this new command. You could use this command inside of your glyph code to ensure that the events get processed that need do in order for widget updates to happen.

But you said something about need a magic event to invoke redisplay? Why is that?

April 2, 2000

the internal distinction between "widget" and "layout" is bogus. there exist widgets that do drawing and do layout of their children, e.g. group-box widgets and proper tab widgets. the only sensible distinction is between widgets with children and those without children.

April 5, 2000

andy, i’m not sure i really believe that you need to cycle the event code to get widgets to redisplay, but in any case you should

  1. hide the logic to do this in the c code; the lisp code should do nothing other than call (redisplay widget)
  2. make sure your event-cycling code processes NO events at all. this includes non-user events. queue the events instead.

in other words, dispatch-non-command-events must go, and i am proposing a general function (redisplay OBJECT) to replace the existing ad-hoc functions.

April 6, 2000

the tab widget code should simply be able to create a whole lot of tabs without regard to the size of the gutter, and the surrounding layout widget (please please make layouts be proper widgets!) should automatically map and unmap them as necessary, to fill up the available space. perhaps this already works and what you’re doing is just for optimization? but i get the feeling this is not the case.

April 6, 2000

the function make-gutter-only-dialog-frame is bogus. the use of the gutter here to hold widgets is an implementation detail and should not be exposed in the interface. similarly, make-search-dialog should not have to do all the futzing that it does. creating the frame unmapped, creating an extent and messing with the gutter: all this stuff should be hidden. you should have a simple function make-dialog-frame that takes a dialog specification, and that’s all you need to do.

also, these dialog boxes, and this function make-dialog-frame, should

  1. be in ‘dialog.el’, not gutter-items.el.
  2. when possible, be placed in the interactive spec of standard lisp functions rather than accessed directly from ‘menubar-items.el
  3. wrapped in calls to should-use-dialog-box-p, so the user has control over when dialog boxes appear.

April 7, 2000

hmmm ... in that case, the whitespace absolutely needs to be specified as properties of the layout widget (e.g. :border-width and :border-height), rather than setting an overall size. you have no idea what the correct size should be if the user changes font size or uses translations in a different language.

Your modus operandi should be "hardcoded pixel sizes are always bad."

April 7, 2000

you mean the number of tabs adjusts, or the size of each tab adjusts (by making the font smaller or something)? if the size of a single tab is not related to the total space the tabs can fix into, then it should be possible to simply specify as many tabs as exist for buffers, and have the layout manager decide how many can fit into the available space. this does not mean the layout manager will resize the tabs, because query-geometry on the tabs should find out that the tabs don’t want to be any size other than they are.

the point here is that you should not have to worry about pixel heights and widths anywhere in Lisp-level code. The layout managers should take care of everything for you. The only exceptions may be in some text fields, which will be blank by default and you want to specify a maximum width (which should be done in ’n’ sizes, not in pixels!).

i won’t stop complaining until i see nearly every one of those pixel-width and pixel-height parameters gone, and the remaining ones there for a very, very good reason.

April 7, 2000

Andy Piper wrote:

 
> At 03:51 PM 4/6/00 -0700, Ben Wing wrote:
> >[the function make-gutter-only-dialog-frame is bogus]
>
> The problem is that some of the callbacks and such need access to the
> created frame, so you end up in a catch 22 unless you do what I've done.

[Ben proposes other ways to avoid exposing all the guts, as in make-gutter-only-dialog-frame:]

  1. Instead of passing in the actual glyph spec or glyph, pass in a function of two args (the dialog frame and its parents), which when called, creates and returns the appropriate glyph.
  2. [Better] Provide a way for callbacks to determine where they were invoked at. This is much more general and is what you should really do. For example, have the code that calls the callbacks bind some global variables such as widget-callback-current-glyph and widget-callback-current-channel, which contain the glyph whose callback is being invoked, and the window or frame of the glyph (depending on where the glyph is) where the invocation actually happened. That way, the callbacks can easily figure out the dialog box and its parent, and not have to worry about embedding it in at creation time.

April 15, 2000 I don’t understand when you say "the various types of callback". Are you using the callback for various different purposes?

Your widget callbacks should work just like any other callback: they take two arguments, one indicating the object to which the callback was attached (an image instance, i think), and the event that caused the callback to be invoked.

April 17, 2000

I am completely vetoing widget-callback-current-channel. How about you create a new keyword, :new-callback, that is a function of two args, like i specified before.

btw if you really are calling your callback using call-interactively, why don’t you declare a function (interactive "e") and then call event-channel on the resulting event? that should get you the same result as widget-callback-current-channel.

the problem with this and everything you’ve proposed is that there’s no way, of course, to get at the actual widget that you were invoked from. would you propose adding widget-callback-current-widget?


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.3 Discussion – Dialog Boxes

 
From: 
        Ben Wing <ben@666.com>
                                                      10/7/1999 5:57 PM

 Subject:
        Re: Animated gif patch (2)
     To: 
        Andy Piper <andy@xemacs.org>
    CC: 
        xemacs-review@xemacs.org, xemacs-beta@xemacs.org




The distinction between layouts and widgets makes no sense, so you should combine
the different data required.  Consider a grouping widget.  Is this a layout or a
widget?  It draws, like a widget, but has children, like a layout.  Same for a tab
widget, properly implemented.  It draws, handles input, has children, and makes
choices about how to lay them out.

ben

From: 
        Ben Wing <ben@666.com>
                                                       9/7/1999 8:50 PM

 Subject:
        Re: Layouts done
     To: 
        Andy Piper <andyp@beasys.com>




this sounds great!  where can i see the code?

as for user-defined layouts, you must certainly have some sort of abstraction
layer for layouts, with DEFINE_LAYOUT_TYPE or something similar just like device
types and such.  If not, you should certainly make one ...  it would have methods
such as query-geometry and do-layout.  It should be easy to create a user-defined
layout if you have such an abstraction.

with a user-defined layout, complex built-in layouts such as grid should not be
necessary because it's so easy to write snippets of lisp.

as for the "redisplay too much" problem, perhaps you could put a dirty flag in
each glyph indicating whether it needs to be redisplayed, recalculated, etc.?

Andy Piper wrote:

> You may want to check them out. I haven't done the user-defined layout
> callback - I'm not sure what sort of API this could have.  Keywords I've done:
>
> :orientation - vertical or horizontal
> :justify - left, center or right
> :border - etch-in, etch-out, bevel-in, bevel -out or text (which gives you
> etch-in with a title)
>
> You can embed any glyph type in a layout.
>
> There is probably room for improvements for justify to do grid-type layouts
> as per java.
>
> The only annoying thing is that I've hacked up font-lock support to do a
> progress gauge in the gutter area. I've used a layout to set things out
> correctly. The problem is if you change one of the sub-widgets, the whole
> layout gets redisplayed because it is treated as a single glyph by redisplay.
>
> Oh, and I've done line based scrolling so that glyphs scroll off the page
> in units of the average display line height rather than the whole line at
> once. This could easily be converted to pixel scrolling but would be very
> slow I fear.
>
> andy
> --------------------------------------------------------------
> Dr Andy Piper
> Senior Consultant Architect, BEA Systems Ltd




From: 
        Ben Wing <ben@666.com>
                                                     8/10/1999 11:11 PM

 Subject:
        Re: Widgets
     To: 
        Andy Piper <andy@xemacs.org>




I think you might have misinterpreted what i meant.  I meant to say that XEmacs should
implement the concept of a hierarchy of nested child "widgets" or "gui items" or
whatever we want to call them -- this includes container "widgets" such as grouping
widgets (which draw a border around the children, like in Windows), tab widgets, simple
layout widgets (invisible, but lay out their children appropriately), etc, plus leaf
"widgets" (buttons, sliders, etc., also standard Emacs windows).  The layout calculations
for these widgets would be handled entirely by XEmacs in a window-system-independent way.
There is no need to create a corresponding hierarchy of window-system
widgets/controls/whatever if it's not required, and certainly no need to try to use the
window-system-supplied geometry management routines.  It's absolutely necessary to support
this nesting concept in XEmacs, however, or it's impossible to have easily-designable
dialog boxes.  On the other hand, I think it is required to create much of this
hierarchy within the actual window system, at the very least for non-invisible container
widgets (tab, grouping, etc.), otherwise we will have very bogus, non-native-looking
containers like your current tab-widget implementation.  It's critical for XEmacs to be
able to create dialog boxes in Windows or Motif that look just like those in any other
standard application.  Otherwise people will continue to think that XEmacs is a
backwards-looking, badly implemented piece of software, which in many ways it is,
particularly in regards to its user interface.

Perhaps we should talk on the phone?  This typing is quite hard for me still.  What hours
are you at work?  My hours are approx. 2pm - 2am Pacific time (GMT - 7 hours currently).

ben


From: 
        Ben Wing <ben@666.com>
                                                     7/21/1999 2:44 AM

 Subject:
        Re: Tabs 'n widgets screenshot
     To: 
        Andy Piper <andy@xemacs.org>
    CC: 
        xemacs-beta@xemacs.org, wmperry@aventail.com




This is real cool, but looking at this, it's clear that it doesn't look the
way tab widgets are supposed to work.  In particular, of course, they should
have the proper borders around the stuff displayed.  I've attached a screen
shot of a typical Windows dialog box with a tab widget in it.  The problem
lies with this "expanded gutter" concept.  Tabs are NOT extra graphical junk
placed in the gutters of a buffer but are GUI objects with children inside
of them.  This is the right way to do things, and you would need no extra
gutter functionality at all for this.  You just need to implement the concept
of GUI objects containing other GUI objects within them.  One such GUI object
needs to be a "Emacs-text" GUI object, which is an Emacs window and contains a
buffer within it.  At this level, you need not be concerned with the
complexities of geometry layout.  The only change that needs to be made in the
overall strategy of frames, windows, etc. is that windows need not be exactly
contiguous and tiled, as long as they are contained within a frame.  Or more
specifically: Given that you could always split a window contained inside a
GUI object, we just need to expand things so that each frame has multiple
hierarchies of windows in it, rather than just one.  A hierarchy of windows
can nest inside of another window -- e.g. I put a tab widget or a text widget
inside of a buffer.  This should be easy to implement -- just change things so
there are multiple hierarchies of windows where there are one, each (except
the top-level one) being rooted inside some other window.

Anyone willing to implement this? Andy?


From: 
        Ben Wing <ben@666.com>
                                                      6/30/1999 3:30 PM

 Subject:
        Re: Focus Help!
     To: 
        Andy Piper <andy@xemacs.org>
    CC: 
        Ben Wing <ben@xemacs.org>, martin@xemacs.org, andyp@beasys.com




It sounds like you're doing very good work.  It also sounds like the approach
you have followed is the correct one.  Now, it seems like there isn't really
that much work left to get dialog boxes working.  What you really just need to
do is implement container widgets, that is to say, subwindows that can contain
other subwindows.  For example, the tab widget works this way. (It sounds like
you have already implemented tab widgets, so I don't quite see how you've done
this without the concept of container widgets.) So you might just try adding a
framework for container widgets and then implementing very simple container
widgets.  The basic container widgets are:

1. A vertical-layout widget, which draws nothing itself and lays out its
children one above the next.
2. A horizontal-layout widget, which draws nothing itself and lays out its
children side-to-side.
3. A box (or "grouping") widget, which draws a rectangle around its single child
and optionally draws some text on the top or bottom line of the rectangle.
4. A tab widget, which displays a series of tabs horizontally at the top of its
area, and then below it places one of its children,
corresponding to the selected tab.
5. A user widget, which draws nothing itself and does no layout at all on its
children, except that it has a "layout callback"
property, a Lisp function, so that the programmer can control the layout.

The framework is as follows:

1. Every widget has at least the following properties:
     a) a size, whose value can be "unspecified", which might be implemented
using the value -1.  The default value should be "unspecified".
     b) whether it's mapped, i.e. whether it will be displayed. (Some container
widgets, such as the tab widget, set the mapped
property themselves on their children.  Others, such as the vertical and
horizontal layout widgets, don't change this property but pay attention to it,
and ignore completely all children marked as unmapped.) The default value should
be "true".
     c) whether its size can be changed by another widget's layout routine. The
default value should be "true".
     d) a layout procedure, which (potentially at least) determines the size of
the widget as well as the position, size and mappedness of its child widgets.
The layout procedure is inherent in the widget and is not an external property
of the widget (except in the case of the "user widget"): it is instead more like
the redisplay callback that each widget has.
2. Every container widget contains a property which is a list of child widgets.
3. Every child widget contains the following properties:
     a) a position indicating where the child is located relative to the top
left corner of its parent.  The position's value can be "unspecified", which
might be implemented using the value -1.  The default value should be
"unspecified".
     b) whether its position can be changed by another widget's layout routine.
The default value should be "true".
4. All of the properties just listed (except possibly the layout procedure) can
be modified directly by the programmer, and there are no proscriptions against
doing so.  However, if the programmer wants to resize, reposition, map or unmap
a widget in such a way that the layout of all the other widgets in the tree
changes appropriately, he should use a special function to change the property,
as described below.

The redisplay mechanism pays attention to the position, size, and mappedness
properties and to the hierarchy of widgets, mapping, resizing and repositioning
the corresponding subwindows (the "real representation" of the widgets) as
necessary.  It also pays attention to the hierarchy of the widgets, making sure
that container subwindows get drawn before their child subwindows.  When it
encounters widgets with an unspecified size, it should not draw them, and should
issue a warning.  When it encounters widgets with an unspecified position, it
should draw them at position (0, 0) and should issue a warning.

The above framework should be fairly simple to implement and is basically
universal across all high-level windowing system toolkits.  The stickyness comes
with what procedures you follow for getting the layout done.

Andy, I understand that implementing this may seem like a daunting task.
Therefore, I propose that at first you implement the above framework but don't
implement any of the layout procedures, or any of the functions that call them:
Just make them stubs that do nothing.  This way, the Lisp programmer can still
create any dialog boxes he wants, he just has to set the sizes and positions of
all the widgets explicitly, and then recompute them whenever the widget tree is
resized (once you get around to allowing this).  I have a lot more to write
about exactly how the layout procedures work, but I'll send that to you later
once you're ready.

You should also think about making a way to have widget trees as top-level
windows rather than just glyphs in a buffer.  There's already the concept of
"popup" frames.  You could provide an easy way to create a popup frame with no
menu, toolbars, scrollbars, modeline or minibuffer, and put a single glyph in
the displayed buffer that takes up the whole Emacs window.

Ben




March 20, 2000

You wrote to me awhile ago about this and asked about documentation, and I
dictated a response but never got it sent, so here it is:

I don't think there's any more documentation on how things work under Xt but it
should be clear. The EmacsFrame widget is the widget corresponding to the X
window that Emacs draws into and there is a handler for expose events called
from Xt which arranges for the invalidated areas to get redrawn. I think this
used to happen as part of the handler itself but now it is delayed until the
next call to redisplay.

However, one thing that you absolutely must not do is remove the Xt support.
This would be an incredibly unfriendly thing to do as it would prevent people
from using any widget set other than Qt or GTK. Keep in mind that people run
XEmacs on all sorts of different versions of X in Unix, and Xt is the standard
and the only toolkit that probably exists on all of these systems.

Pardon me if I've misunderstood your intentions w.r.t. this.

As for how you would implement GTK support, it will not be very hard to convert
redisplay to draw into a GTK window instead of an Xt window. In fact redisplay
basically doesn't know about Xt at all, except in the portion that handles
updating menubars and scrollbars and stuff that's directly related to Xt.

What you'd probably want to do is create a new set of event routines to replace
the ones in event-Xt.c. On the display side you could conceivably create a new
device type but you probably wouldn't want to do that because it would be an
externally visible change at the Lisp level. You might simply want to put a
flag on each frame indicating what sort of toolkit the frame was created under
and put conditions in the redisplay code and the code to update toolbars and
menubars and so forth to test this flag and do the appropriate thing.


April 12, 2000

This is way cool, buuuuutttttttt .............

what we really need is the GUI interface on top of it.  I've taken a shot at
it with generic-print-buffer
(print-buffer is taken by lpr, which is such a total mess that it needs to be
trashed; or at least, the generic
stuff in this package needs to be taken out and properly genericized).  For
the moment, generic-print-buffer
just does something like what Kirill's been posting if we're running windows,
and uses lpr otherwards.  However, what we absofuckinglutely need is a Lisp
interface onto EnumPrinters() so that we can get the
list of printers and have a nice menu listing the available printers, and you
can check the one you want.  People in the Windows world don't normally even
know the names of their local printers!

Kirill, given what I've done in ‘simple.el’ and ‘menubar-items.el’, do you think
you could add the EnumPrinters()
support and fix up the GUI?  If you don't feel comfortable with the GUI, at
least do the EnumPrinters().

But ...  Kirill, I tried your formula for printing and nothing happened.
Perhaps I didn't call redisplay-frame or something?  You need to fix this up
and make it work for multi-page documents. (Again, this is in
generic-print-buffer.)  Nothing special, it just needs to fucking work!  There
are zillions and zillions of postings every day on xemacs-nt about how to get
printing working, and none seem to refer to the built-in support.

ben


April 19, 2000

Kirill 'Big K' Katsnelson wrote:

> Some time ago, Ben Wing wrote...
> >kirill, the interface i created is more general, like this:
>
> [snip]
>
> >Unfortunately I haven't implemented much of this; just some of the file
> >dialog box.  but i think
> >this is better than creating new mswindows-specific primitives.  if you
> >are interested in working on
> >this, i'll send you the code i have.
>
> Sure. Can you just commit it for my starting point?
>
> >also, the dialogs shouldn't have anything directly to do with the printer
> >device.  all they should
> >do is return a set of values.  it's the caller's responsibility to
> >interpret them and set device
> >properties accordingly.  this way, there's a complete separation between
> >the underlying
> >functionality and the gui.
>
> Unfortunately. I thought about doing it this way, but we then lose a lot of
> printer-specific setup in this case. The DEVMODE structure contains two
> parts: printer independent, as defined by SDK typedef DEVMODE, and
> some trailing bytes, of unknown structure, used by a driver. The driver
> only returns the extra length it wants. Such options as PCL ReT resolution
> enhancement options or PostScript negative output are not available
> through the standard part of the devmode structure, and stored in the
> driver part (printer dialogs are driver-specific).
>
> So we have total of three options:
> - Not to implement options beyond standard DEVMODE
> - Make DEVMODE a Lisp object.
> - Hide DEVMODE inside the device object.
>
> First case looks cheesy. Letting DEVMODE fall off the printer is no good
> either, since one needs both the device and the devmode to edit the
> devmode, and they must match. I am still convinced that the devmode and
> the printer should not be separated.

hmm, i see ...  this completely breaks abstraction though.  it fails in various
scenarios, e.g. a program wants to initialize the dialog box with certain
non-driver-specific properties, without caring about the particular printer.

i think you should create a new print-properties object that encapsulates all
printer properties (which can be changed using get/put), including the printer
name, and contains a DEVMODE in it.  if the printer name gets changed, the
DEVMODE might change too, but the print-properties object itself stays the
same.  you pass this object as a parameter to the dialog box, and it gets
changed accordingly.  you can call something like set-device-print-properties to
stick everything in this structure into the device. (you could imagine a case
where someone wanted to keep multiple print configurations around ...)

>
>
> Big K

--
Ben


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.4 Discussion – Multilingual Issues

 
                                                     4/10/2000 4:13 AM

BTW I am planning on adding some more powerful font-mapping capabilities to
XEmacs (i.e. how do we map particular characters to the proper fonts that can
display them, and how do we map the character's codes to the indices into the
font).  These will replace to hackish charset-registry/charset-ccl-program stuff
we currently have, and be [a] much more powerful, [b] designed in a
window-system-independent way, [c] works with specifiers so you can control the
mapping of individual buffers, and [d] works on a character rather than charset
level, to correctly handle Unicode.  One possible usage would be to declare that
all latin1 in a particular buffer to be displayed with latin2 fonts; I bet
Hrvoje would really appreciate that

---------------------------------------------------------------------------

April 10, 2000

[info from "creation of generic macros for accessing internally formatted data"]

Hmm, so there I just wrote a detailed design for the macros.  I would be
THRILLED and overjoyed if you went ahead and implemented this mechanism, or
parts of it.

I've just finished arranging for a new transcriptionist, and soon I should be
able to send off and get back my dictation of my (a) exposing streams to lisp,
and (b) allowing for proper lisp-created coding systems, which define their
reading, writing, and detecting methods in lisp.


BTW How's it going wrt your Unicode and decode-priority stuff?

And ...  you sent me mail asking what it was you had promised me, and listed
only one thing, which was
profiling of vm and certain other operations you found showed tremendous
slowdown with Japanese characters.  The other main thing I want from you is

-- Your priorities, as an actual Japanese user and XEmacs developer,
concerning what MULE work should be done, how it should be done, in what
order, etc.

I'm sure there's something else, but it's been awhile since I took my sleeping
dose and my brain can barely function anymore.  Just let me know how you're
going to proceed with the above macro changes.

BTW there's some nice Perl scripts written by Martin and fixed by me to make
global-search-and-replace
much, much easier.  I've attached them.  The first one is a shell script that
works like

gr foo bar *.[ch]

and replaces foo with bar in all of the files.  For each modified file, a
backup is created in the backup/ directory, which is created as necessary.
This shell script is a fairly trivial front end onto global-replace2, which is
a perl script that takes one argument (a Perl expression such as s/foo/bar/g)
and a list of files obtained by reading the stdin, and does the same global
replacement.  This means that the regexp syntax used here has to be perl-style
rather than standard emacs/grep style.

ben

---------------------------------------------------------------------


From: 
        Ben Wing <ben@666.com>
                                                    12/23/1999 3:34 AM

 Subject:
        Re: check process state before accessing coding_stream (fix PR#1061)
     To: 
        "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>
    CC: 
        XEmacs Developers <xemacs-beta@xemacs.org>




Thankfully, nearly all of this horridity you bring up is irrelevant.  In
XEmacs, "gettext" does not refer to any standard API, but is merely a stand-in
for a translation routine (presumably written by us).  We may as well call it
something else.  We define our own concept of "current language".  We also
allow for a function that needs a different version for each language, which
handles all cases where simple translation isn't sufficient, e.g. when you
have to pluralize some noun given to you or insert the correct form of the
definite article.  No weird hacks needed.  No interaction problems with other
pieces of software.

What I wrote "awhile ago" is (unfortunately) not anywhere public currently,
but it's on my list to put it on the web site.  "There you go again" is
usually not true; most of what I quote was indeed put out publicly at some
point, but I'll try to be more explicit about this in the future.

ben

"Stephen J. Turnbull" wrote:

> >>>>> "Ben" == Ben Wing <ben@666.com> writes:
>
>     Ben> "Stephen J. Turnbull" wrote:
>
>     >> What I have in mind is not just gettext-izing everything in the
>     >> XEmacs core sources.  I currently believe that to be
>     >> unacceptable
>
>     Ben> I don't quite understand.  Could you elaborate and give some
>     Ben> examples?
>
> Examples?  Hmm.
>
> First, there's the surface of Jan's y-or-n-p example.  You have to
> coordinate the translation of the message string and the response
> prompt.  This is handled by y-or-n-p itself (I see that we already do
> have gettext for Emacs Lisp, that's nice to know).
>
> Except that it's not really handled by y-or-n-p.  There's no reason to
> suppose that somebody writing a Lisp package would necessarily use the
> XEmacs domain (in fact, due to the way gettext binds text domains---if
> I understand that correctly---we don't want that to be the case,
> because it means that every time a Lisp package is updated the whole
> XEmacs catalog must also be updated).  So which domain gets used for
> the message string?
>
> In the current implementation, it is the domain of y-or-n-p.  So
> packages with their own domain won't get y-or-n-p prompts correctly
> translated.  But that means that the package should do its own
> translation.  But now you're applying gettext to the same string
> twice; you just have to pray the that translator upstream doesn't
> collide with an English string that's in the XEmacs domain.  (The
> gettext docs mention the similar problem of English words with
> multiple meanings that must map to different words in the target
> language; this can be disambiguated by various trickeries in forming
> the strings ... but only if you "own" them, which in the multi-domain,
> interated gettext example you do not.)  AFAICT this means that you
> must never pass untranslated strings across public APIs, but this may
> or may not be reasonable, and certainly is inconvenient.
>
> Next, we have to translate the possible answer strings to match the
> language being passed by the user.  This is presumably OK here,
> because it's done by y-or-n-p.  But what if y-or-n-p returned a string
> rather than a boolean?  Then we would need to coordinate the
> presentation of the prompt (done by y-or-n-p) and the translation of
> the possible answer strings (done by the caller).  This can in fact be
> done using dgettext with the XEmacs domain, but you must know that
> y-or-n-p is in the XEmacs domain.  This is not necessarily going to be
> obvious, and it might very well be that sets of related packages might
> have the same domain, so you wouldn't necessarily know which domain is
> appropriate by looking at the requires.
>
> And what happens if one domain does supply translations for a language
> and the other does not?  AFAIK, gettext has no way to find out if this
> is the case.  But you might very will prefer a global fallback to
> English if substantial phrases are drawn from both domains, while you
> might prefer string-by-string fallback if the main text is translated
> and only a few words are left to fallback to English.
>
> Aside from confusing users, this puts a great burden on programmers.
> Programmers need to know about the status of the domains of packages
> they use as well as the XEmacs domain; they need to program
> defensively against the possibility that some package they use will
> become gettext-ized, or the translation projects will be out of synch
> (some teams will do the calling package first, others will do the
> caller package first).
>
> I don't think anybody will use gettext in these circumstances.  At
> least not after they get the first bug report that "XEmacs is stuck in
> an infinite y-or-n-p loop and I can't get out."
>
>     Ben> I wrote this awhile ago:
>
> "There you go again."  Not anywhere I could see it!  (At least, it
> doesn't look familiar and grepping the archives doesn't turn it up.)
>
> OK, you win.  Subscribe me to xemacs-review.  Or whatever seems
> appropriate.
>
> --
> University of Tsukuba                Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
> Institute of Policy and Planning Sciences       Tel/fax: +81 (298) 53-5091
> _________________  _________________  _________________  _________________
> What are those straight lines for?  "XEmacs rules."

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it is not apparent in your message,
please say so.  Thanks for your understanding.



--------------------------------------------------------------------


From: 
        Ben Wing <ben@666.com>
                                                    12/21/1999 2:22 AM

 Subject:
        Re: check process state before accessing coding_stream (fix PR#1061)
     To: 
        "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>
    CC: 
        XEmacs Developers <xemacs-beta@xemacs.org>





"Stephen J. Turnbull" wrote:

> >>>>> "Ben" == Ben Wing <ben@666.com> writes:
>
>     Ben> Implementing message translation is not that hard.
>
> What I have in mind is not just gettext-izing everything in the XEmacs
> core sources.  I currently believe that to be unacceptable (see Jan's
> message for the pitfalls in I18N; it's worse for M17N).  I think
> really solving this problem needs a specifier-like fallback mechanism
> (this would solve Jan's example because you could query the
> text-specifier presenting the question for the affirmative and
> negative responses, and the catalog-building mechanism would have
> checks to make sure they were properly set, perhaps a locale
> (language) argument), and gettext is just not sufficient for that.

I don't quite understand.  Could you elaborate and give some examples?

>
>
> At a minimum, we need to implement gettext for Lisp packages.
> (Currently, gettext is only implemented for C AFAIK.)  But this could
> potentially cuase more trouble than it's worth.
>
>     Ben> A lot depends on priority: How important do you think this
>     Ben> issue is to your average Japanese/Chinese/etc. user?
>
> Which average Japanese (etc) user?  The English-skilled (relatively)
> programmer in the free software movement, or my not-at-all-competent
> undergrad students who I would love to have using an Emacs?  This is a
> really important ease-of-use issue.
>
> Realistically, for Japanese, it's low priority.  The Japanese team in
> the GNU Translation Project is doing very little AFAIK, so even if the
> capability were there, I doubt the message catalog would soon be done.
>
> But I think that many non-English speakers would find it very
> attractive, and for many languages there are well-organized and
> productive translation teams.  I suspect that if the I18N facility
> were well-designed, many Western European languages would have full
> catalogs within a year (granted, they are the ones where it's least
> needed :-( ).
>
> Personally, I think doing it well is hard, and of little benefit to
> _current_ core XEmacs constituency.  I think doing a good job, with
> catalogs, would be very attractive to many non-English-speaking
> _potential_ users.
>
>     Ben> How does it compare to some of the other important Mule
>     Ben> issues that Martin and I are (trying to work) on?
>
> I don't know what you guys are _trying_ to work on.  Everything in the
> I18N section of "Architecting XEmacs" is red-flagged.  OTOH, it's
> clear from your posts that you are overburdened, so I can't read
> priority into the fact that you've responded to specific issues in the
> past.

I wrote this awhile ago:


>
>     Ben> The big question is, would you be willing to help do the
>     Ben> actual implementation, to "be my hands"?
>
> Sure, subject to the usual caveat that I'd need to be convinced it's
> worth doing and a secondary caveat that I am not an experienced coder.

If you'll implement it, I'll design it.  It's more a case of will on your part
than anything else.  I can give you instructions sufficient enough to match
your level of expertise.

ben

>
>
> --
> University of Tsukuba                Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
> Institute of Policy and Planning Sciences       Tel/fax: +81 (298) 53-5091
> _________________  _________________  _________________  _________________
> What are those straight lines for?  "XEmacs rules."

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it is not apparent in your message,
please say so.  Thanks for your understanding.



-----------------------------------------------------------------------------

Dec 20, 1999


Implementing message translation is not that hard.  I've already done a lot of
preliminary work in places such as ‘make-msgfile.lex’ in lib-src/.  Finishing up
the work is not that big a task; I already know exactly how it should be
done.  Perhaps I'll write up detailed design instructions for this, as I'm
doing for other things.  A lot depends on priority: How important do you think
this issue is to your average Japanese/Chinese/etc. user?  How does it compare
to some of the other important Mule issues that Martin and I are (trying to
work) on?  If I did the design document, would you be willing to do the
necessary bit of C hackery to implement the document?  If the design document
is not specific enough for you, I can give you an "implementation document"
which will definitely be specific enough: i.e. I'll show you exactly where the
code needs to be modified, and how.  The big question is, would you be willing
to help do the actual implementation, to "be my hands"?

---------------------------------------------------------------------------

From: 
        Ben Wing <ben@666.com>
                                                    12/14/1999 11:00 PM

 Subject:
        Re: Mule UI disaster: displaying character tables
     To: 
        Hrvoje Niksic <hniksic@iskon.hr>
    CC: 
        XEmacs vs Mule <xemacs-mule@xemacs.org>




What I mean is, please put my name in the header, as well as xemacs-mule.
That way I'll see it in my personal box.

I agree that Mule has problems, but:

Brokenness can be fixed.
Slowness can be fixed.
Limitations can be fixed.

The design limitation you mention below, for example, is not really very
hard to change.

Keep in mind that I pretty much rewrote Mule from scratch, and did it
all in 6-7 months.  In comparison with that, the changes below are
pretty minor, and each could be done by a good (and able-bodied!)
programmer familiar with the Mule code in less than a week -- to the
XEmacs code, at least.  The problem is, everyone who could do this work is
instead spending their time complaining about Mule problems instead of
doing things.

I'll gladly help out anyone who wants to do Mule coding by explaining all
the details; I'll even write a "Mule internals manual", if that will
help.  I can also make international phone calls -- they're cheap here in
the US due to the long distance wars.  But so far no one has asked me for
help or shown any willingness to do any work on Mule.

Perhaps people are daunted by the seeming vastness of the problems.  But I
wager that if I had another 6 months to work on nothing but Mule, it would
be nearly perfect.  The basic design of the XEmacs C code is good;
incremental changes, without over-much concern for compatibility, could
make huge strides in a short amount of time (as was the case the whole
time I worked on it, esp. towards the end -- it didn't even compile for
4 months!).  A "total rewrite" would be an incredible waste of time.

Again, I'm completely willing to provide help, documentation, design
improvement suggestions (ala Architecting XEmacs -- which seems to have
been completely ignored, alas), etc.

ben

Hrvoje Niksic wrote:

> Ben Wing <ben@666.com> writes:
>
> > I'm the one who did most of the Mule work in XEmacs, so if you have
> > any questions about the core, please address them to me directly.  I
> > can probably give you a very clear and detailed answer.
>
> Thanks.  I think it still makes sense to ask here, so that other
> developer have a chance to chime in.
>
> > However, I need some explanation.  What's misdesigned that you're
> > complaining about?  And what's the coding-system disaster?
>
> It's been spoken of a lot.  Basically:
>
> * Unlike XEmacs/no-Mule, XEmacs/Mule doesn't preserve binary files in
>   Latin 2 locales by default.  This is annoying for users who are used
>   to XEmacs/no-Mule.
>
> * XEmacs/Mule is much slower than XEmacs, and not only because of
>   character/byte conversions.  It seems that font lookups etc. are
>   slower.
>
> * The "coding-system disaster" refers to inherent limitations of the
>   coding-system model.  If I understand things correctly,
>   coding-systems convert streams of bytes to streams of Emchars.  It
>   does not appear to be possible to create a "gzip" coding system for
>   handling gzipped file.  Even EOL conversions look kludgish:
>
>     iso-2022-8
>     iso-2022-8-dos
>     iso-2022-8-mac
>     iso-2022-8-unix
>     iso-2022-8bit-ss2
>     iso-2022-8bit-ss2-dos
>     iso-2022-8bit-ss2-mac
>     iso-2022-8bit-ss2-unix
>     iso-2022-int-1
>     iso-2022-int-1-dos
>     iso-2022-int-1-mac
>     iso-2022-int-1-unix
>
>   Ideally, it should be possible to specify a stream of
>   coding-systems, where only the last one converts to actual Emchars.
>
> There are more problems I don't remember right now.  Many many usage
> problems become apparent when I stand and look over the shoulders of
> an XEmacs users who tries to use Mule.

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it is not apparent in your message,
please say so.  Thanks for your understanding.



-----------------------------------------------------------------------




From: 
        Ben Wing <ben@666.com>
                                                   12/14/1999 12:20 AM

 Subject:
        Re: Mule UI disaster: displaying character tables
     To: 
        "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>
    CC: 
        XEmacs vs Mule <xemacs-mule@xemacs.org>




I think you should go ahead with your proposal, and assume it will get
implemented.  I don't think Martin is really suggesting that API changes not
be allowed, but just that they proceed in a somewhat orderly fashion; and in
any case, I imagine I have final say in cases of Mule-related conflicts.

ben

"Stephen J. Turnbull" wrote:

> >>>>> "Hrvoje" == Hrvoje Niksic <hniksic@iskon.hr> writes:
>
>     Hrvoje> So next I tried the "Mule" menu.  That's right, boys and
>     Hrvoje> girls, I've never looked at it before.
>
> For quite a while, it didn't work at all, led to crashes and other
> warm/fuzzy things.  IIRC there used to be a top level menu item
> pointing to information about the current language environment but it
> got removed.
>
>     Hrvoje> Wow.  Seeing shift_jis, iso-2022 variants and (above all
>     Hrvoje> things) big5 makes me really warm and fuzzy.
>
> We've been through this recently---you were there.  We know what to do
> about it, basically (Ben liked my proposal, and it would fix this
> silliness as well as the binary file breakage).  But given that Ben
> and Martin seem to have different ideas about where to go with Mule
> (Ben seemed to be supporting API and implementation revisions, Martin
> evidently wants to keep the current Mule), working on that proposal is
> possibly a waste of time.  I've got other stuff on my plate and I'll
> get back to it one of these days (not tomorrow but sooner than Real
> Soon Now).
>
>     Hrvoje> The items it presents (leading to further submenus) are:
>
>     Hrvoje>     94 character set
>     Hrvoje>     94 x 94 character set
>     Hrvoje>     96 character set
>
> This _is_ bad UI, now that you point it out.  But it is quite natural
> for a coding system lawyer (as all Japanese users have to be), I never
> noticed it before.  Easy enough to fix ("raise my karma").
>
>     Hrvoje> But I do bear some Mule scars, so I happily select "96
>     Hrvoje> character sets", then ISO8859-2.  And I get this:
>
> [Table omitted]
>
>     Hrvoje> So me wonders: what the hell is this?
>
> Huh?  That is the standard table that you see over and over again in
> references.  I'll believe you if you say you've never seen one before,
> but every Japanese users' manual has dozens of pages of those, using
> exactly that format.
>
> The presentation in the range 00--7F is not unreasonable for Latin 2;
> ISO-8859 is a version of ISO-2022, so the high bit should not be
> interpreted as "+ x80" (technically speaking), it should be
> interpreted as a character set shift.
>
> Of course, this doesn't make sense to anybody but a character set
> lawyer, and so should be changed.  Especially since the header refers
> to ISO-8859-2 which everybody these days thinks of as _one, 8-bit_
> character set, not two 7-bit ones.
>
> As for the "Japanese" in the table, that's just a really stupid
> "optimization": those happen to be line-drawing characters available
> in JIS X 0208, to make pretty borders.  Substitute "-", "+", and "|"
> in appropriate places to make ugly but portable borders.
>
>     Hrvoje> Mule is just broken.  Warn your friends.
>
> Hrvoje is on the rampage again.  Warn your friends ;-)
>
> --
> University of Tsukuba                Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
> Institute of Policy and Planning Sciences       Tel/fax: +81 (298) 53-5091
> _________________  _________________  _________________  _________________
> What are those straight lines for?  "XEmacs rules."

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it is not apparent in your message,
please say so.  Thanks for your understanding.



---------------------------------------------------------------------------

From: 
        Ben Wing <ben@666.com>
                                                    12/14/1999 10:28 PM

 Subject:
        Re: Autodetect proposal; specifer questions/suggestions
     To: 
        "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>




I've always thought the specifier API is too complicated (and too
"write-only"), but I went back at one point well after I designed it and I
couldn't figure out an obvious way to simplify it that still kept reasonable
functionality.  Perhaps that's what Custom did, and why it turned out bad.

Inefficiency is a stupid reason not to use them.  They seem efficient enough
for redisplay.  Changing them might be inefficient, but Emacs Lisp is in
general, right?

Can you propose an API or functionality change that will make them more used?



"Stephen J. Turnbull" wrote:

> >>>>> "Ben" == Ben Wing <ben@666.com> writes:
>
>     Ben> I think you should go ahead with your proposal, and assume it
>     Ben> will get implemented.
>
> OK.  "yas baas" ;-)
>
> On something totally different.  I'm really bothered by the fact that
> specifiers are so little used (eg, Custom reimplements them badly),
> and the fact that every package seems to define its own set of faces
> (or whatever), rather than use the specifier mechanism to inherit from
> existing ones, or add new specifications to existing ones.  API problem?
>
> Also, faces (maybe specifiers in general?) should have an autoload
> mechanism, and a ‘<package>-faces.el’ (or ‘<package>-specifiers.el’)
> convention.  There are a number of faces in (eg) Custom that I like to
> use, but I have to load Custom to get them.  And Custom should be able
> to somehow see all the faces in various packages available, even when
> they are not loaded.
>
> I've seen claims that specifiers aren't very efficient.
>
> Opinions?
>
> --
> University of Tsukuba                Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
> Institute of Policy and Planning Sciences       Tel/fax: +81 (298) 53-5091
> _________________  _________________  _________________  _________________
> What are those straight lines for?  "XEmacs rules."

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it is not apparent in your message,
please say so.  Thanks for your understanding.


-----------------------------------------------------------------------------
From: 
        Ben Wing <ben@666.com>
                                                     11/18/1999 9:02 PM

 Subject:
        Re: Char-related crashes (hopefully) fixed
     To: 
        "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>
    CC: 
        XEmacs Beta List <xemacs-beta@xemacs.org>




OK, in summation:

1. C-q is a user-level function and should do whatever makes the most sense.
2. int-char is a low-level primitive and should never depend on high-level
settings like language environment.
3. Everything you can do with int-char can and should be done with make-char
-- representation-independent, much less likelihood of bugs, etc.  Therefore
int-char should be removed.
4. Note that CLTL2 also removes int-char.
5. Your statement

> In one-byte buffers (either Olivier's 1/2/4 extension or `xemacs -font
> *-iso8859-2') it implicitly will have dependence whatever you say.

is confusing internal and external representations.

ben

"Stephen J. Turnbull" wrote:

> Can somebody give a bunch of examples where using integers as
> characters is useful?  For that matter, where they are actually used?
> Ben said "backward compatibility," but I haven't seen this used, and I
> don't really know how to grep for it.  I have grepped for int-char,
> int-to-char, char-int, and char-to-int and they're pretty rare in the
> core and package code (2/3 of it) that I have.
>
> The only one that I ever use is the C-q hack for inserting characters
> by code value at the keyboard, and that could arguably (and in
> Japanese invariably is) delegated to an input method which would know
> about language environment (and return a true character).
>
> For iterating over a character set in "natural" order, only ASCII
> satisfies the requirement of having one, and even that's shaky.  AFAIK
> the Swedes and the Norwegians, or is it the Danes, disagree on
> ordering the _letters_ in ISO-8859-1 character set.  This really
> should be table-driven, and will have to be for everything except
> ASCII and ISO-8859-1 if we go to a Unicode internal representation.
>
> We already have primitives for efficient case conversion and the like.
>
> The only example I can think of offhand where you would really really
> want the facility is to iterate over a code space where you don't know
> which points are legal characters.  Eg, to print out tables of fonts.
> Pretty specialized.  And this can be done through make-char, anyway.
>
> According to CLtL1, the main portable use for char-int is for hashing.
> But that doesn't square with the kind of usage we've been talking
> about (in loops and the like).
>
> What else am I missing?
>
> Ben's desiderata have some problems.
>
> >>>>> "Ben" == Ben Wing <ben@666.com> writes:
>
>     Ben> Either int-char should be the mirror opposite of char-int
>     Ben> (i.e. accept all legal char integers), or it should be
>     Ben> removed entirely.
>
> OK.  I agree with this.
>
>     Ben> int-char should never have any dependence on the language
>     Ben> environment.
>
> In one-byte buffers (either Olivier's 1/2/4 extension or `xemacs -font
> *-iso8859-2') it implicitly will have dependence whatever you say.
> Even without Mule, people can always use external encoders to change
> raw ISO-8859-2 to ISO-2022 (not that anybody sane ever would, OK,
> Hrvoje?).  Then the two files will be interpreted differently in a
> Latin-1 locale Mule; the ISO-8859-2 file will be recognized as
> ISO-8859-1, and the ISO-2022 file will be internally interpreted as
> ISO-8859-2.
>
> The point is that people normally assume that int-char should accept
> their "natural" integer to character map.  For Americans, that's
> ASCII, for Germans, that's ISO-8859-1, for Croatians, that's
> ISO-8859-2.  And it works "correctly" in a no-mule XEmacs with `-font
> *-iso8859-2'!  Japanese usually use ku-ten or JIS, and there's a
> "natural" map from byte-sized integer pairs to shorts, but it's full
> of holes.  So language environments don't agree on what a legal char
> integer is, and where they do (eg, ISO-8859-1 and ISO-8859-2), they
> don't agree on the map.  To satisfy your dictum (with which I agree,
> but I take to mean we should get rid of these functions) we can take
> the intersection where they agree
>
> ==> legal char integers == ASCII
>
> which is what I prefer, or pick something arbitrary and efficient
>
> ==> char-int returns the internal representation
>
> which I really hate, or something else.  Suggestions?
>
>     Ben> I don't think C-q should either.  If Hrvoje wants to insert
>     Ben> Latin-2 characters by number, then make C-u C-q work so that
>     Ben> it also prompts for a character set, with a default chosen
>     Ben> from the language environment.
>
> And restrict this to ASCII?  Or assume Latin-1 in GR if there is no
> prefix argument?
>
> This is a useful feature.  C-q currently inserts Latin-2 characters
> for Hrvoje in no-mule XEmacs (stretching the point only a little); I
> think it should continue to do so in Mule.  This really is an input
> method issue, not a keyboard issue.  In XEmacs, inserting an integer
> into a buffer has no meaning.  Users insert characters.  So this is a
> completely different issue from the programming API, and should not be
> considered analogous.
>
> Maybe we could have C-q insert according to the Unicode standard, and
> treat C-u C-q as part of the input method.  But I think most users
> would prefer to have C-q insert according to their locale-standard
> tables, and select Unicode explicitly using the C-u C-q idiom.  In
> fact (again this points to the input method idea), Japanese users
> would probably like to have the alternatives of using kuten (pairs
> from 1--94 x 1--94) or JIS (pairs from 0x21--0x7E x 0x21--0x7E) as
> options since both indexing systems are common in tables.
>
> --
> University of Tsukuba                Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
> Institute of Policy and Planning Sciences       Tel/fax: +81 (298) 53-5091
> __________________________________________________________________________
> __________________________________________________________________________
> What are those two straight lines for?  "Free software rules."

--
ben

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it's not apparent in your message,
please say so.  Thanks for your understanding.



-----------------------------------------------------------------------------

From: 
        Ben Wing <ben@666.com>
                                                    11/16/1999 11:03 PM

 Subject:
        Re: Char-related crashes (hopefully) fixed
     To: 
        Yoshiki Hayashi <t90553@m.ecc.u-tokyo.ac.jp>
    CC: 
        Hrvoje Niksic <hniksic@iskon.hr>,
        XEmacs Beta List <xemacs-beta@xemacs.org>




Either int-char should be the mirror opposite of char-int (i.e. accept all
legal char integers), or it should be removed entirely.

int-char should never have any dependence on the language environment.

I don't think C-q should either.  If Hrvoje wants to insert Latin-2
characters by number, then make C-u C-q work so that it also prompts for a
character set, with a default chosen from the language environment.

ben

Yoshiki Hayashi wrote:

> Hrvoje Niksic <hniksic@iskon.hr> writes:
>
> > As Ben said, now that we've fixed the actual bugs, we can think about
> > changing the behaviour for int-char conversions for 21.2.
>
> Following are proposed which integers should be accepted
> where characters are expected:
>
> 1) Don't allow anything
> 2) Accept 0-127
> 3) Accept 0-256
> 4) Accept everything
>
> Other things proposed are:
>
> a) When doing C-q, treat 128-256 as Latin-2 in Latin 2
>    language environment.
>
> So far, most of the proposal is intended to apply to every
> int-char conversions, I'd like to make some functions to
> accept.
>
> My plan is:
> Accept only 0-256 in every place except int-to-char.
> int-to-char accepts every valid integers.
> Make new function which does int-to-char conversion
> correctly according to the language environment.
>
> This way, most of the code which does (insert (1+ ?a)) or
> something continues working. Now internal representation is
> changed a little bit, so disabling > 256 characters will
> warn those who are dealing with internal representation
> directly, which is bad. Still, you can do
> (let ((i 1442))
>   (while (i < 2000)
>     (insert (int-to-char i))
>     (setq i (+1 i))))
> to achieve old behaviour.
>
> For C-q, I'm not for changing it's original definition,
> since it might confuse people who are expecting Latin-1 in
> other language environment and typing just 1 integer doesn't
> make sense for multibyte world. It's cleaner to make new
> function, which does make-char according to the charset of
> language-info-alist so that people who use that often can
> bind it to C-q or some other keys.
>
> --
> Yoshiki Hayashi

--
ben

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it's not apparent in your message,
please say so.  Thanks for your understanding.




[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.5 Discussion – Instantiators and Generic Property Accessors

From: Ben Wing <ben@666.com> Date: Sun, 05 May 2002 05:40:07 -0700 Subject: generic functions, new instantiator API

I’ve been reading the C++ manual and getting polymorphism, inheritance, generic functions, etc. in my head.

We have our own "generic function" already in terms of ‘get’, ‘put’, etc. which accept various objects. i’m thinking of extending them so they can accept, as well as objects, lists (either alists or plists) or plist-style vectors, and manipulate their properties. what do people think of this?

Also, i’m designing a new API for "instantiators", which are objects whose main purpose is to hold properties and provide a way of notifying their containing specifiers when they change. Instantiator objects are used when the instantiator gets sufficiently complicated that using lists and vectors gets unwieldy – e.g. when creating widget trees, such as would appear in dialog boxes. you want the ability to programmatically traipse up and down the tree and dynamically modify a part of the tree – e.g. a property on a single widget – as necessary, and have the internal code automatically notice this change and performs any necessary updates. lists and vectors are too low-level for this – no way to get their parent, no way for internal code to be notified when changes occur, can’t always maintain object identity when making property changes, no way to error-check illegal changes, etc.

You could also extend this api to cover toolbars; it would probably make toolbar manipulation significantly easier. but you’d have to think about backward compatibility in such cases.

here is what the api looks like so far – making use of a newly-added facility for keyword args in primitives. comments are welcome.

 
DEFUN ("make-instantiator", Fmake_instantiator, 1, MANY, 0, /*
Create a new instantiator object from TYPE and PROPS.
TYPE should be one of the image instantiator formats described in 
`make-glyph'.
The rest of the arguments should be keyword properties and associated 
values,
as also described in `make-glyph'.

TYPE can also be an old-style vector instantiator.

Instantiator objects can be used as instantiators (see `make-specifier') in
glyphs in place of old-style vector instantiators.  They are especially
used for complicated, nested graphical elements such as widgets (buttons,
text fields, etc.) -- in fact, widget instantiators will automatically be
converted into instantiator objects if they are given in vector format.

Individual properties on instantiators can be manipulated using
`set-instantiator-property'.  If the property's value is a list (for
example, a list of children), you can also use `add-instantiator-item'
to add or insert individual elements in the list.

`delete-instantiator-item' can be used to delete individual items in the 
list;
`get-instantiator-item' to locate individual items in the list; and
`get-instantiator-item-position' to return the position of individual 
items in
the list.

`map-instantiator' can be used to (recursively or not) map over an
instantiator and its children.

`find-instantiator' can be used to (recursively or not) locate an 
instantiator
in a tree composed of an instantiator and its descendants.
*/
       /* (type &rest props) */
       (int nargs, Lisp_Object *args))
{
  /* ^^#### */ return Qnil;
}

DEFUN ("set-instantiator-property", Fset_instantiator_property, 3, 3, 0, /*
Set property PROP to VALUE in INSTANTIATOR.
INSTANTIATOR should have been created with `make-instantiator'.
Valid properties depend on the instantiator type and are described in
`make-glyph'.  For properties that are lists of items, individual items
can be added or deleted using `add-instantiator-item' and
`delete-instantiator-item'.

For compatibility, this also accepts an old-style vector instantiator, and
destructively modifies it; in this case, adding a property requires
creating a new vector, which is returned.  You need to use
`set-glyph-image' on glyphs, or `set-specifier-dirty-flag' on the result of
`glyph-image', to register instantiator changes to vector
instantiators. (New-style instantiators automatically convey property
changes to any glyphs they have been attached to.)
*/
       (instantiator, prop, value))
{
  Lisp_Object *elt;
  int len;

  /* ^^#### */
  CHECK_VECTOR (instantiator);
  if (!KEYWORDP (prop))
    invalid_argument ("instantiator property must be a keyword", prop);

  elt = XVECTOR_DATA (instantiator);
  len = XVECTOR_LENGTH (instantiator);

  for (len -= 2; len >= 1; len -= 2)
    {
      if (EQ (elt[len], prop))
    {
      elt[len + 1] = value;
      break;
    }
    }

  /* Didn't find it so add it. */
  if (len < 1)
  {
    Lisp_Object alist = Qnil, result;
    struct gcpro gcpro1;

    GCPRO1 (alist);
    alist = tagged_vector_to_alist (instantiator);
    alist = Fcons (Fcons (prop, value), alist);
    result = alist_to_tagged_vector (elt[0], alist);
    free_alist (alist);
    RETURN_UNGCPRO (result);
  }

  return instantiator;
}

DEFUN ("instantiator-property", Finstantiator_property, 2, 3, 0, /*
Return the property PROP of INSTANTIATOR, or DEFAULT if PROP has no value.
INSTANTIATOR should have been created with `make-instantiator'.
*/
       (instantiator, prop, default_))
{
  /* ^^#### */ return Qnil;
}

DEFUN ("instantiator-properties", Finstantiator_properties, 1, 1, 0, /*
Return a plist of all defined properties in INSTANTIATOR.
INSTANTIATOR should have been created with `make-instantiator'.
*/
       (instantiator))
{
  /* ^^#### */ return Qnil;
}

DEFUN ("instantiator-type", Finstantiator_type, 1, 1, 0, /*
Return the type of INSTANTIATOR.
INSTANTIATOR should have been created with `make-instantiator'.
Valid types are the instantiator formats described in `make-glyph'.
*/
       (instantiator))
{
  /* ^^#### */ return Qnil;
}

DEFUN ("instantiator-parent", Finstantiator_parent, 1, 1, 0, /*
Return the parent of INSTANTIATOR.
INSTANTIATOR should have been created with `make-instantiator'.
*/
       (instantiator))
{
  /* ^^#### */ return Qnil;
}

DEFUN_WITH_KEYWORDS ("map-instantiator", Fmap_instantiator, 2, 2, 1, 0, 
0, /*
Map FUN recursively over INSTANTIATOR and its descendants.
FUN is called with one argument, the INSTANTIATOR.
If:norecurse is non-nil, don't recurse, just map over the direct
children (not including the instantiator itself). 
*/
             (fun, instantiator),
             (norecurse))
{
  /* ^^#### */ return Qnil;
}

DEFUN_WITH_KEYWORDS ("find-instantiator", Ffind_instantiator, 3, 3,
             1, 0, 0, /*
Find an instantiator by PROP and VALUE in INSTANTIATOR and its descendants.
Returns first item which has PROP set to VALUE.
If:norecurse is non-nil, don't recurse, just look through the direct
children (not including the instantiator itself). 
*/
             (instantiator, prop, value),
             (norecurse))
{
  /* ^^#### */ return Qnil;
}

DEFUN_WITH_KEYWORDS ("add-instantiator-item", Fadd_instantiator_item, 3, 
3, 7,
             0, 0, /*
Add an item to an instantiator property that's a list of items.
\(E.g. the children of an instantiator).  PROP is the property whose list of
items is being modified, and ITEM is the item to add.  To insert somewhere
before the end, use one of the keywords:

--:position specifies a zero-based index of an item, and the new item 
will be
inserted just before the item indicated by the position.  Negative numbers
count from the end -- thus -1 will cause insertion before the last item, -2
before the second-to-last item, etc.

--:before-item and :after-item specify items to insert before or after.
:test (defaults to `eq') can be used to specify the way to compare the given
item with existing items.

--:before-property and :after-property search for an item to insert 
before or
after by looking for an item with the given property.  If :value is 
given, the
property must have that value; otherwise, it simply must exist.  This method
of insertion works if the items in PROP's list are anything that can have or
hold properties.  \("To have and to hold, for ever and ever ...")  This
includes:

-- any object for which `get' works
-- else, if object is a vector, assume it's a plist-style vector
-- else, if object is a cons, and its first element is also a cons,
   assume it's an alist
-- else, if object is a cons, assume it's a plist
*/
             (instantiator, prop, item),
             (position, before_item, after_item, test,
              before_property, after_property, value))
{
  /* ^^#### */ return Qnil;
}

DEFUN_WITH_KEYWORDS ("delete-instantiator-item", Fdelete_instantiator_item,
             2, 2, 5, 0, 0, /*
Delete an item in an instantiator property that's a list of items.

\(E.g. the children of an instantiator).  PROP is the property whose list is
being searched.  One of these keywords should be given:

--:position specifies a zero-based index of an item.  Negative numbers
count from the end -- thus -1 will cause insertion before the last item, -2
before the second-to-last item, etc.

--:item specifies the item to delete. :test (defaults to `eq') can be 
used to
specify the way to compare the given item with existing items.

--:property searches for an item with the given property.  If :value is
given, the property must have that value; otherwise, it simply must exist.
This method of insertion works if the items in PROP's list are anything that
can have or hold properties -- see `add-instantiator-item'.
*/
             (instantiator, prop),
             (item, test, position, property, value))
{
  /* ^^#### */ return Qnil;
}

DEFUN_WITH_KEYWORDS ("get-instantiator-item", Fget_instantiator_item,
             2, 2, 3, 0, 0, /*
Get an item in an instantiator property that's a list of items.

\(E.g. the children of an instantiator).  PROP is the property whose list is
being searched.  One of these keywords should be given:

--:position specifies a zero-based index of an item.  Negative numbers 
count
from the end -- thus -1 will cause insertion before the last item, -2 before
the second-to-last item, etc.

--:property searches for an item with the given property.  If :value is
given, the property must have that value; otherwise, it simply must exist.
This method of insertion works if the items in PROP's list are anything that
can have or hold properties -- see `add-instantiator-item'.
*/
             (instantiator, prop),
             (position, property, value))
{
  /* ^^#### */ return Qnil;
}

DEFUN_WITH_KEYWORDS ("get-instantiator-item-position",
             Fget_instantiator_item_position,
             2, 2, 4, 0, 0, /*
Return an item's position in an instantiator property that's a list of 
items.

\(E.g. the children of an instantiator).  PROP is the property whose list is
being searched.  One of these keywords should be given:

--:item specifies the item to search for. :test (defaults to `eq') can be
used to specify the way to compare the given item with existing items.

--:property searches for an item with the given property.  If :value is
given, the property must have that value; otherwise, it simply must exist.
This method of insertion works if the items in PROP's list are anything that
can have or hold properties -- see `add-instantiator-item'.
*/
             (instantiator, prop),
             (item, test, property, value))
{
  /* ^^#### */ return Qnil;
}

DEFUN ("image-instance-instantiator", Fimage_instance_instantiator, 1, 
1, 0, /*
Return the instantiator from which IMAGE-INSTANCE was created.
*/
       (image_instance))
{
  /* ^^#### */ return Qnil;
}

some other useful stuff:

 
DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /*
Return a new `image-instance' object.

Image-instance objects encapsulate the way a particular glyph (pixmap,
widget, etc.) is displayed on a particular device.  In most circumstances,
you do not need to directly create image instances; instead, you create a
glyph using `make-glyph' and add settings (or "instantiators") onto it
using `set-glyph-image', and XEmacs creates the image instances as
necessary.  However, it may occasionally be useful to explicitly create
image instances, if you want more control over the instantiation process.

For more information on instantiators and instances, see `make-specifier'.

DATA is an image instantiator, which describes the image; see `make-glyph'
for a description of the allowed values.

The most likely circumstance where you need to deal directly with image
instances is in widget callbacks -- e.g. the callback that's executed when
a button is pressed in a dialog box of type `general' (see
`make-dialog-box').  In this case, the widget that was activated is
described by an image instance. (The callback is usually be written as an
interactive function with an interactive spec of (interactive \"e\"), and a
single `event' argument.  The event will be an activate event, describing
the user action that trigged the callback.  The image instance is
retrievable from the event using `event-image-instance'.  Handling the
action may involve setting properties on the image instance or other image
instances in the dialog box in which the widget is usually contained -- or
changing the instantiator that generated the image instance, if you want
permanent changes that will be reflected the next time the dialog box is
popped up.  Properties on an image instance are set using
`set-image-instance-property'.  If the widget is part of a hierarchy of
widgets (as is usually the case in a dialog box, but may not apply if the
widget was inserted by itself in a buffer [by creating a glyph and
attaching it to an extent -- see `make-glyph']), there will be a
corresponding hierarchy of image instances to describe this particular
instance of the dialog box.  You can retrieve other image instances in the
hierarchy using primitives such as `image-instance-parent',
`image-instance-children', and `find-image-instance'.

...

 
(defun image-instance-property (image-instance property &optional default)
  "Return the given property of the given image instance.
Returns DEFAULT if the property or the property method do not exist for
the image instance in the domain."
  (check-argument-type 'image-instance-p image-instance)
  (get image-instance property default))

(defun set-image-instance-property (image-instance prop value)
  "Set the property PROP on IMAGE-INSTANCE to VALUE.
Only certain properties of the image instance can be changed, and they
represent \"temporary\" changes.  If you want to make permanent changes,
you need to change the instantiator that generated the instance --
retrieve the instantiator with `image-instance-instantiator', and change
its properties with `set-instantiator-property'.

This applies mostly to widgets.  For example, you can set a property on
a widget image instance to change the state of a radio or checkbox button,
set the text currently in an edit field, etc.  However, those changes apply
only to the *currently* displayed widgets.  If these widgets are in a dialog
box, and you want to change the way the widgets in the dialog box appear
*each* time the dialog box is displayed, you need to change the 
instantiator.

Make sure you understand the difference between instantiators and
instances.  An \"instantiator\" is a specification, indicating how to
determine the value of a setting whose value can vary in different
circumstances or \"locales\" (buffers, frames, etc.).  An \"instance\" 
is the
resulting value in a particular circumstance.  For more information, see
`make-specifier'."
  (check-argument-type 'image-instance-p image-instance)
  (put image-instance prop value))

From: "Stephen J. Turnbull" <stephen@xemacs.org> Date: 06 May 2002 16:40:46 +0900

>>>>> "Ben" == Ben Wing <ben@666.com> writes:

Ben> We have our own "generic function" already in terms of ‘get’, Ben> ‘put’, etc. which accept various objects.

I proposed extending the class to stuff like charsets about two years ago, and I think you were one of the folks who objected.

Ben> i’m thinking of extending them so they can accept lists Ben> (either alists or plists) or plist-style vectors, and Ben> manipulate their properties. what do people think of this?

I think extending to lists is something we should approach cautiously. For one thing, if "get" is polymorphic, "put" would have to be too. But how does it decide when dealing with "nil"?

Ben> you want the ability to programmatically traipse up and down Ben> the tree and dynamically modify a part of the tree – e.g. a Ben> property on a single widget – as necessary, and have the Ben> internal code automatically notice this change and performs Ben> any necessary updates.

I like this.

From: "Stephen J. Turnbull" <stephen@xemacs.org> Date: 07 May 2002 11:17:05 +0900

>>>>> "Neal" == Neal D Becker <nbecker@hns.com> writes:

Neal> I thought that generic polymorphism was inherent in lisp, as Neal> it is dynamically evaluated. Why would you need anything Neal> special in the way functions are written to support generic Neal> programming?

I think it’s basically a technical matter. We have a number of objects that have property lists besides symbols. Many of them have special functions (coding-system-get, coding-system-property, charset-property are examples I find particularly obnoxious). I would like to make these obsolete by allowing ‘get’ on charsets, coding systems, etc.

And currently we have

(let ((p (symbol-plist symbol))) (plist-get p prop))

Ben would like to allow

(let ((p (symbol-plist symbol))) (get p prop))

with ‘get’ determining whether P is a plist or an alist. And where Michael says "why not use hash tables?", I see ‘(get hash key)’ (probably to Michael’s horror ;-).

This isn’t Lisp any more, though, in some sense. But then we haven’t been that for years. AFAIK all real Lisps restrict ‘get’ to symbols.

From: sperber@informatik.uni-tuebingen.de (Michael Sperber [Mr. Preprocessor]) Date: Tue, 07 May 2002 08:52:53 +0200

Indeed. I’ll just say "goosebumps." But I don’t see why it has to be GET that accesses the plist. You just build more dispatch into GET with no immediate benefit to the API. Ad-hoc genericity gets you something when there’s some place in the code you don’t know what the underlying object is. I don’t see this being the case here. Why do you find them "obnoxious?"

Stephen> This isn’t Lisp any more, though, in some sense. But then we haven’t Stephen> been that for years. AFAIK all real Lisps restrict ‘get’ to symbols.

Actually, Scheme (which admittedly isn’t a real Lisp by many standards) doesn’t have get/put at all. And good riddance, I might add:-)

From: "Stephen J. Turnbull" <stephen@xemacs.org> Date: 07 May 2002 20:04:50 +0900

>>>>> "ms" == Michael Sperber <sperber@informatik.uni-tuebingen.de> writes:

Stephen> special functions (coding-system-get, coding-system-property, Stephen> charset-property are examples I find particularly obnoxious). I would Stephen> like to make these obsolete by allowing ‘get’ on charsets, coding Stephen> systems, etc.

ms> But I don’t see why it has to be GET that accesses the plist. ms> You just build more dispatch into GET with no immediate ms> benefit to the API. Ad-hoc genericity gets you something when ms> there’s some place in the code you don’t know what the ms> underlying object is. I don’t see this being the case here. ms> Why do you find them "obnoxious?"

Their semantics are basically ‘get’. Why not use that name? Of course I agree that it doesn’t have to be ‘get’, but why clutter things up?

But those are particularly obnoxious because of the object/name confusion they have built in. Ie, my real problem with them is more ancient Mule idiom than the *-get or *-property names for the API.

ms> Actually, Scheme (which admittedly isn’t a real Lisp by many ms> standards) doesn’t have get/put at all.

What does it use instead? (And no, you can’t bait _me_ with Lisp definition trolls, I think of XML as "declarative LISP with fat, flavored, fuzzy parentheses.")

From: sperber@informatik.uni-tuebingen.de (Michael Sperber [Mr. Preprocessor]) Date: Tue, 07 May 2002 13:26:13 +0200

Stephen> Their semantics are basically ‘get’. Why not use that name?

Because it doesn’t convey as much information in the source code as it could, and because it provides less type checking than it could.

Stephen> What does it use instead?

What for? I’ve never felt the desire to use them, and it seems to me that in Lisp, properties are usually used for one of two purposes:

- As a poor man’s replacement for hash tables.

- To store data which should really be stored inside the object itself.

In the former case, I use a hash table. In the latter case, I store the data in the object itself.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.6 Discussion – Switching to C++

From: "Ben Wing" <ben@666.com> Date: Fri, 10 May 2002 19:42:53 -0700

i know i’m opening up a bag of worms by suggesting this, but what about moving to C++? I know others advocate this (Jan, Martin), and the more I read Stroustrup’s 3rd edition, the more I realize that *HUGE* armounts of code in XEmacs, and in particular most of the really hairy and hard-to-understand stuff – lots of weird macros, faux object-oriented stuff implemented in multiple places, each differently (Lisp objects; methods on consoles/devices/etc; specifier sub-types; coding-system sub-types; image-instance device methods; image-instance format methds; etc.), all the GCPROS (which could go entirely), dynarrs, eistring, etc. etc. – is simply superseded by stuff already built into C++ or supplied by the standard libraries. Just now, I was going through the redisplay code, and noticing the huge amount of duplication between gtk and X, something that’s hard to fix [except through super ad-hoc ways like using a .c file as a .h file to "generate" lots of similar but slightly different code] in C, but is extremely easy in C++ using inheritance [and/or templates]. for example, instead of having just one layer of device methods, you’d have

 
general -> tty
           -> windowing -> mswindows
                               -> xlike -> x, gtk

which would nicely and naturally encapsulate lots of duplicated [and thus, hard to maintain] code.

even more of a win would be the GCPRO’s. Taking advantage of constructors and destructors, we could simply do away [COMPLETELY!] with explicitly gcproing, and still have everything gcpro’d. [in fact, much more reliably – none of the dreaded "temporary" problem, and every reference is always gcpro’d so we have greater flexibility for GC work – take note, Michael :-) – e.g. we could safely garbage collect when allocating, and we could even implement a relocating garbage collector. in the few places where performance might be an issue [i seriously doubt there’d be many of them], we simply use a separate Lisp_Object_No_GCPRO class (presumably a base class of Lisp_Object), and manually handle the GCPRO’s ourselves. If we needed to distinguish here between static and dynamic objects, or static vs. local vs. heap, we could do so easily with bit flags in the object pointed to – we have space for lots of them.

code reliability and maintainability would likely substantially increase due to the ability to express most things in a natural C++ way instead of lots of weird hackish hard-to-understand C stuff implementing stuff the language wasn’t really designed for. Furthermore, there are even some possibilities for increased speed – many operations that can only reasonably be done now using Lisp objects (and the associated gc overhead and such) could be done using the high-level built-in facilities of C++, which in their ease of use approach Lisp; and C++ has ‘inline’ built-in, so we could easily add various container classes to improve the understandability of the code without loss of performance.

finally, making the "switch" is trivial, since martin did the initial work making XEmacs C++-safe and I’ve been keeping it that way – I regularly build under C++ and fix any problems. All we’d need to do is switch the compiler and start gradually introducing C++ constructs as we feel like it.

for those concerned that dumping might stop working, [a] i don’t think it would, [b] the portable dumper has come of age – i use it almost all the time, and it’s rock-solid and not obviously slower than unexec.

the only major concern that i see is the quality of the C++ implementations out there, in particular G++, which is the most widely available. I know that 6 years ago G++ was a bit rocky – I went to interview for Netscape, and they mentioned having to rely on various vendor implementations of C++, whereas they would have preferred G++ if it was reliable, due to the sameness of environment. But that was *SIX YEARS* ago! Stroustrup 3rd Edition has been out for 5 years now, and it defines, as far as I know, ANSI Standard C++ – so that’s at least 5 years to implement a standard. It’s hard to believe that G++ isn’t completely reliable now; but I do not have as much experience as others.

What do you think? I would *really* like to make this change, as it would immensely facilitate lots of code I’m working on and will be working on, plus of course add all the above benefits once we get around to converting the code.

From: "Stephen J. Turnbull" <stephen@xemacs.org> Date: 11 May 2002 15:34:08 +0900

I don’t have a real problem with it, as long as we’re very conservative about it, ie, using C++ as "clean C with classes", and introducing things slowly. Implement everything ourselves, avoid the standard class libraries.

I’ve been following the Python lists recently, and although the bias is easy to guess, it’s interesting to note that the people who are most anti-C++ are typically the ones who are world-class C++ programmers with big projects under their belts. Many of them actually advocate using C rather than C++.

I do worry that with Martin currently out of the picture we don’t have an active C++ standards bigot and implementation collector to deal with compiler-specific issues. We do OK with C, but C++ is a much more complex, subtle language. Is there anybody else to plausibly take on that role?

From: Hrvoje Niksic <hniksic@arsdigita.com> Date: Sun, 12 May 2002 20:58:50 +0200

I’m strongly opposed to this. Here are some reasons:

* C++ may fix some problems, but it will introduce others, some of which may be much harder to fix. XEmacs is already a large program, hard to understand. C++ will not improve things.

* XEmacs will suddenly become uncompilable and unusable in many environments where it used to build perfectly fine – for example, those that don’t ship with a C++ compiler at all. We could "make GCC 3 a requirement", but I don’t like that idea.

* People without C++ experience will no longer be able to hack XEmacs. I’d be the first one to leave. For example, I know quite a few programmers who don’t care for Qt and KDE simply because it’s C++.

* C is the /lingua franca/ of free software development. If we’re switching languages, it should be for a good reason and to something we agree is an improvement (e.g. Common Lisp).

* C++ is not the be-all end-all to everything. People who undestand it well are usually the first ones to warn against it. It’s possible that they were scarred by using C++ at a bad time, but I’d think twice before discounting their advice or blindly believing that C++ is now all better.

If you were writing a new project, I’d say go for it. But at this point, this seems like a needless tweak. Do we really need *more* internal reorganizations? Shouldn’t we work on user-visible features? Wasn’t that what you yourself advocated when I talked to you?

From: Didier Verna <didier@xemacs.org> Date: Tue, 14 May 2002 11:21:32 +0200

Switching to C++ has been suggested for the first time at the M17n’99 conference in Japan IIRC. Although it was around a table with many empty bottles of beer on it :-), I’ve kept some hope from that time. I’m happy to see Ben in favor of this today. This idea coming from him is likely to have more impact than when it comes from me or Yan of whoever else.

There are several points that make me in favor of this change:

- C++ support is already there thanks to Martin.

- The amount of OO simulation code written in C in XEmacs is *HUGE*. But more important, this code simulates *BASIC* OO features that are not any more a problem for any C++ compiler. I mean, by just using the basic features of C++ in terms of OO and data abstraction (classes, inheritance, methods (with inlining), operators overloading), we’ll win big time in code size, readability, maintainability, and correctness.

- the fact that *basic* OO support is already a major gain is very important to me. You don’t have to go generic programming with templates everywhere to write an OO XEmacs[1]. Switching to C++ can be completely gradual, and we can even stop early in the C++ features we use. That will already be a big gain. That’s also the advantage over the idea of using another more modern language to rewrite the core; something completely unrealistic.

- there is another important aspect on the design issue: many people (including from the industry) have worked on abstracting common problems in an OO philosophy. Some people claim that the concepts that emerged from this kind of work of just C++ specific hackery, and they’re probably right, but anyway that’s obviously not a problem for us. Any C++ writer should have the "Design Patterns" book in hand. It already has good design solutions for many problems that we’re facing in XEmacs (like, supporting more than one widget set), because these problems are so *common*. By using C++ we can directly benefit from the experience of other large applications designers.

Footnotes: [1] We’re working on GP in C++ in our lab here and we trigger bugs in gcc 3. But you should see the code in question, it’s pure template and static programming. Things that XEmacs will never need.

From: Daniel Pittman <daniel@rimspace.net> Date: Sat, 11 May 2002 19:15:04 +1000

I’ve been following the Python lists recently, and although the bias > is easy to guess, it’s interesting to note that the people who are > most anti-C++ are typically the ones who are world-class C++ > programmers with big projects under their belts. Many of them > actually advocate using C rather than C++.

I wouldn’t class myself as "world-class", but I can understand this perspective based on my experiences with large projects that aim for portability to vendor compilers, not just gcc.

The biggest problem, assuming that you are willing to ignore platforms like Sinix-PC[1] and their poor compiler support[2] is that it’s easy to shoot yourself in the foot with C++.

The biggest portability problems are namespaces, the standard C++ library and template support, in about that order, followed by exception handling.

Very few things get namespaces right, even today, with gcc being one of the worst. Tempting as they are, they are best avoided where possible, except in compiler and platform specific code.[3]

The standard C++ library, which supports RTTI and a few other things including the [io]stream tools, is less than totally reliable although it can be used with relative safety most places.

What you really need to watch out for with that is the extensions that every vendor in the universe has added to their collections because there isn’t any standard way of doing common things in most of these areas.

The Standard Template Library isn’t. Aside from a tendency to expose limitations of symbol name lengths[4] the library tends to be unreliable in behavior between compilers and platforms. Not enough to make simple things fail, though, just enough to make it occasionally do odd things or show up obscure bugs in your code...

It’s also not very well designed, I think, as libraries go. That’s a personal opinion, though, and not universal.

C++ exceptions are an interesting issue. They can work extremely well as a mechanism for managing errors and improve the reliability of the system.

They can also become an unending nightmare of epic proportions, causing more pain and suffering than you can imagine. :/

The main difference between the two situations, so far as I can tell, comes from two aspects of design that have ... far reaching implications.

If you try adding exceptions to code that isn’t ready to deal with them, things tend to go very badly wrong. I /think/ that the existing exception mechanisms in XEmacs would be similar enough that this isn’t the case, though.

The other is that you need to base your code very strongly around the "construction acquires, destruction releases" model of resource handling. This, of course, implies using exceptions everywhere because you /can’t/ use that model in C++ without them.[5]

Again, I think that the existing XEmacs model will probably work well with this, but I am hardly an expert at either; my only real-world experience is the one project where I gained these impressions and the knowledge of the suffering they can bring. :)

Oh, and finally, watch out for operator overloading – including casts. These are very easy to abuse into a position where your code is impossible for others to understand.

I would also advocate avoiding multiple inheritance, but that’s because my personal design experience says that it’s almost always a sign of bad design. Views there vary greatly.

> I do worry that with Martin currently out of the picture we don’t have > an active C++ standards bigot and implementation collector to deal > with compiler-specific issues.

You probably have more need of the second than the first. There are not many things you actually need a standards bigot for; just write good C and don’t use too many things other than classes.

> We do OK with C, but C++ is a much more complex, subtle language.

C with classes, or the limited subset of C++ that doesn’t include templates, exceptions or RTTI is not much more complex than standard C.

If you add exceptions to that you will probably not notice anything but a syntax change in the core, given their current standing. Er, they probably don’t work right in signal handlers, though, because they don’t know anything about them.[6]

> Is there anybody else to plausibly take on that role?

I would be happy to look at things that were publicly discussed on the topic but I don’t think I have the experience or the knowledge of the XEmacs development process to do anything more than that.

Not, I imagine, that anyone would ask. :)

Daniel

Footnotes: [1] Archaic Unix ported to i386 from a minicomputer over a decade ago.

[2] The vendor C++ would segfault on anything that had multiple inheritance. :)

[3] I found them invaluable in resolving a few Win9x vn WinNT symbol conflicts, for example, but that’s obviously target-specific.

[4] The current record for STL-generated name length that I have seen is a symbol 892 characters long...

[5] The lack of a return code from a class constructor is the killer issue here.

[6] This, I believe, varies from vendor to vendor. :)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.7 Discussion – Windows External Widget

 
Subject: 
            Re: External Widget Support for Xemacs on nt
       Date: 
            Sat, 08 Jul 2000 01:47:14 -0700
      From: 
            Ben Wing <ben@666.com>
        To: 
            Timothy.Fowler@msdw.com
        CC: 
            xemacs-nt@xemacs.org
 References: 
            1




Nothing is currently done for external widget support under XEmacs but
it should not be too hard to do and would be a great addition to
XEmacs. What you would probably want to do is create an XEmacs control
that has an interface something like the built-in edit control and
which communicates to an existing XEmacs process using DDE. (Basically
you would modify XEmacs so that it registered itself as a DDE server
accepting external widget requests, and then the external edit control
would simply send a DDE request and the result would be a handle of
some sort used for future communication with that particular XEmacs
process.)

There are two basic issues in getting the external widget to work,
which are display and input. Although I am not completely sure, I have
a feeling that it is possible for one process to write into the window
of another process, simply by using that window's HWND handle. If so
it should be extremely easy to get the output working (this is exactly
the approach used under Xt). For input, you would probably again want
to do what is done under Xt, which is that the client widget simply
passes all of the appropriate messages to the XEmacs server process
using whatever communication channel was set up, e.g. DDE, and the
XEmacs server processes them normally. Very few modifications would be
needed to the XEmacs source code and all of the necessary
modifications could be done simply by looking for existing external
widget code in XEmacs.

If you are interested in continuing this, I will certainly give you
any support you need along the way. This would be a great project to
be added to XEmacs.



Timothy Fowler wrote:

> I am looking into external widget support for xemacs nt similar to that
> existing in xemacs for X
> Have any developement efforts been made in this direction in the past?
> Is there any current effort?
> Any insight into the complexity of achieving this?
> Any comments would be greatly appreciated
> Thanks
> Tim Fowler

--
Ben

In order to save my hands, I am cutting back on my mail.  I also write
as succinctly as possible -- please don't be offended.  If you send me
mail, you _will_ get a response, but please be patient, especially for
XEmacs-related mail.  If you need an immediate response and it is not
apparent in your message, please say so.  Thanks for your understanding.

See also http://www.666.com/ben/chronic-pain/


Subject: 
        RE: External Widget Support for Xemacs on nt
   Date: 
        Mon, 10 Jul 2000 12:40:01 +0100
   From: 
        "Alastair J. Houghton" <ajhoughton@lineone.net>
     To: 
        "Ben Wing" <ben@666.com>, <xemacs-nt@xemacs.org>
    CC: 
        <Timothy.Fowler@msdw.com>




> -----Original Message-----
> From: owner-xemacs-nt@xemacs.org [mailto:owner-xemacs-nt@xemacs.org]On
> Behalf Of Ben Wing
> Sent: 08 July 2000 09:47
> To: Timothy.Fowler@msdw.com
> Cc: xemacs-nt@xemacs.org
> Subject: Re: External Widget Support for Xemacs on nt
> 
> Nothing is currently done for external widget support under 
> XEmacs but it should
> not be too hard to do and would be a great addition to XEmacs. 
> What you would
> probably want to do is create an XEmacs control that has an 
> interface something
> like the built-in edit control and which communicates to an 
> existing XEmacs
> process using DDE.

It would be much better to use RPC or COM rather than DDE - and
also it would provide a more useful interface to XEmacs (like the
Microsoft rich text edit control that is used by Wordpad). It
would probably also be easier...

> If you are interested in continuing this, I will certainly give 
> you any support
> you need along the way. This would be a great project to be added 
> to XEmacs.

I agree. This would be a *really useful* thing to do...

Regards,

Alastair.

____________________________________________________________
Alastair Houghton                     ajhoughton@lineone.net 

Subject: 
            Re: External Widget Support for Xemacs on nt
       Date: 
            Mon, 10 Jul 2000 22:56:06 -0700
      From: 
            Ben Wing <ben@666.com>
        To: 
            "Alastair J. Houghton" <ajhoughton@lineone.net>
        CC: 
            xemacs-nt@xemacs.org, Timothy.Fowler@msdw.com
 References: 
            1




sounds good.  i don't know too much about windows ipc methods, so i suggested
dde just as an example.

"Alastair J. Houghton" wrote:

> > -----Original Message-----
> > From: owner-xemacs-nt@xemacs.org [mailto:owner-xemacs-nt@xemacs.org]On
> > Behalf Of Ben Wing
> > Sent: 08 July 2000 09:47
> > To: Timothy.Fowler@msdw.com
> > Cc: xemacs-nt@xemacs.org
> > Subject: Re: External Widget Support for Xemacs on nt
> >
> > Nothing is currently done for external widget support under
> > XEmacs but it should
> > not be too hard to do and would be a great addition to XEmacs.
> > What you would
> > probably want to do is create an XEmacs control that has an
> > interface something
> > like the built-in edit control and which communicates to an
> > existing XEmacs
> > process using DDE.
>
> It would be much better to use RPC or COM rather than DDE - and
> also it would provide a more useful interface to XEmacs (like the
> Microsoft rich text edit control that is used by Wordpad). It
> would probably also be easier...
>
> > If you are interested in continuing this, I will certainly give
> > you any support
> > you need along the way. This would be a great project to be added
> > to XEmacs.
>
> I agree. This would be a *really useful* thing to do...
>
> Regards,
>
> Alastair.
>
> ____________________________________________________________
> Alastair Houghton                     ajhoughton@lineone.net

--
Ben

In order to save my hands, I am cutting back on my mail.  I also write
as succinctly as possible -- please don't be offended.  If you send me
mail, you _will_ get a response, but please be patient, especially for
XEmacs-related mail.  If you need an immediate response and it is not
apparent in your message, please say so.  Thanks for your understanding.

See also http://www.666.com/ben/chronic-pain/


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.8 Discussion – Packages

Author: Ben Wing

Important package-related changes

This file details changes that make the package system no longer an unmitigated disaster. This way, at the very least, people can essentially ignore the package system and not get bitten horribly the way they currently do.

  1. A single tarball containing absolutely everything and named xemacs-21.2.68.tar.gz. This must contain absolutely everything, including all of the packages, and in the proper directory structure, so that the paradigm for

    untar; configure; make; make install

    just works.

  2. Fixed startup slowdown when all packages are installed so that there is absolutely no penalty to having them all installed. This may be hard.
  3. All files on the ftp site should be accessible through http.
  4. Put symlinks into the distribution directory to the appropriate files in the package directory.
  5. Eliminate the confusing SUMO name, choosing a much more obvious name such as all-packages.
  6. There should be no separation of mule and non-mule packages.
  7. Having 2 packages that conflict with each other should be completely disallowed.
  8. Fix vc and ps-print so that there is only ONE version.
  9. Fix up all of the READMEs on the distribution site to make it abundantly clear what needs to be obtained, where to get it, and how to install it, especially with regards to packages.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

44.9 Discussion – Distribution Layout

 
From: 
        Ben Wing <ben@666.com>
                                                     10/15/1999 8:50 PM

 Subject:
        VOTE: Absolutely necessary changes to file naming in releases
     To: 
        SL Baur <steve@xemacs.org>,
        XEmacs Reviews <xemacs-review@xemacs.org>




Everybody except Steve seems to agree that we need to provide a single
tar file containing the entire XEmacs tree whenever we release a new
version of XEmacs (beta or not).  Therefore I propose the following
simple changes, and ask for a vote.  If it is the general will of the
developers, then Steve WILL make these changes.  This is the
definition of cooperative development -- no one, not even the
maintainer, can assert absolute power over anything.

I propose (assuming, for example, release 21.2.20):

1. xemacs-21.2.20.tar.gz -> xemacs-21.2.20-core.tar.gz

2. xemacs-sumo.tar.gz -> xemacs-packages.tar.gz

3. xemacs-mule-sumo.tar.gz -> xemacs-mule-packages.tar.gz

4. Symlinks to the files mentioned in #2 and #3 get created in the SAME
directory as xemacs-21.2.20-*.tar.gz.

5. MOST IMPORTANTLY, a new file xemacs-21.2.20.tar.gz gets created,
which is the combination of the 5 files xemacs-21.2.20-core.tar.gz,
xemacs-21.2.20-elc.tar.gz, xemacs-21.2.20-info.tar.gz,
xemacs-packages.tar.gz, and xemacs-mule-packages.tar.gz.


The directory structure of the new combined file xemacs-21.2.20.tar.gz
would look like this:

xemacs-21.2.20/
xemacs-packages/
xemacs-mule-packages/


I am sorry to shout, but the current situation is just completely
insane.

ben






From: 
        Ben Wing <ben@666.com>
                                                    10/16/1999 3:12 AM

 Subject:
        Re: VOTE: Absolutely necessary changes to file naming in releases
     To: 
        SL Baur <steve@xemacs.org>,
        XEmacs Reviews <xemacs-review@xemacs.org>,
        "Michael Sperber [Mr. Preprocessor]" <sperber@informatik.uni-tuebingen.de>




Something went wrong with my mail program while I was responding, so
Michael's response is not quoted here.

Let me rephrase my proposal, stressing the important points in order of
importance:

1. MOST IMPORTANT: There MUST be a SINGLE tar file containing the complete
XEmacs sources, packages, etc.  The name of this tar file must have a
format like this:

xemacs-21.2.10.tar.gz

The directory layout of the packages within it is not important as long as
it works: The user who downloads the tar file MUST be able to apply the
'configure; make; make install' paradigm at the top-level directory and
have it work properly.

2. All the pieces of XEmacs must be in the same subdirectory on the FTP
site.

3. The names need to be obvious and standard.  Naming the core files
"xemacs-21.2.20.tar.gz" is non-standard because those are only the core
files.  The standard followed by everybody in the world is that a name like
this refers to the entire product, with all ancillary files.  Also, "sumo",
although a nice in-joke, is extremely confusing and needs to go.

Referring to Michael's point about the layout I proposed, I also think that
the package system needs to be modified to accept a layout produced by the
"obvious" way of obtaining and untarring the parts, which leaves you with a
directory consisting of

xemacs-21.2.19/
xemacs-packages/
mule-packages/

All at the same level.  However, this is an independent issue from the vote
at hand.


Consider the current insanity.  The new XEmacs user or beta tester goes to
the FTP site, looks around, finds the file xemacs-21.2.19.tar.gz, and
downloads it, because it looks like the obvious one to get.  But it doesn't
work.  Oops ...  He looks some more and finds the other two -elc and -info
parts, grabs them, and then tries again.  But it still doesn't work.  He
manages to overhear something about packages, so he looks for them, but
doesn't find them immediately (they're not even in the beta tree, though
they obviously contain beta-level code, especially in xemacs-base and
mule-base).  Eventually he discovers the package/ subdirectory, but what
the hell does he do there?  There's no README at all there giving any
clues, so he downloads everything.  Along with this, he gets some files
called "sumo", which he doesn't understand, but he notices that some of
them are extremely large.  "sumo" ... "large" ...  hehe, I get it.  Some
silly developer's joke.  But then he tries again to compile things, and
just can't figure things out.  He still doesn't know:

-- "sumo" is not just some large file, but is a tar file of all the
packages.
-- The packages can't be placed is any subdirectory in any obvious relation
to the XEmacs directory ("straight out of the box" if you manage to grok
the significance of the sumo files, you get a layout like

xemacs-21.2.19/
xemacs-packages/
mule-packages/

which naturally doesn't work!  He needs to put them underneath
xemacs-21.2.19/lib/xemacs/ or something.)

At this point, he gives up, and (if he was a user of a pre-packagized
XEmacs) wonders in despair how things got so messed up, when all older
XEmacs releases, including all the betas, followed the standard "configure;
make; make install" paradigm).



Soooooo .........  PLEASE vote on issues #1-3 above, and add any comments
you feel like adding.

ben

Ben Wing wrote:

> Everybody except Steve seems to agree that we need to provide a single
> tar file containing the entire XEmacs tree whenever we release a new
> version of XEmacs (beta or not).  Therefore I propose the following
> simple changes, and ask for a vote.  If it is the general will of the
> developers, then Steve WILL make these changes.  This is the
> definition of cooperative development -- no one, not even the
> maintainer, can assert absolute power over anything.
>
> I propose (assuming, for example, release 21.2.20):
>
> 1. xemacs-21.2.20.tar.gz -> xemacs-21.2.20-core.tar.gz
>
> 2. xemacs-sumo.tar.gz -> xemacs-packages.tar.gz
>
> 3. xemacs-mule-sumo.tar.gz -> xemacs-mule-packages.tar.gz
>
> 4. Symlinks to the files mentioned in #2 and #3 get created in the SAME
> directory as xemacs-21.2.20-*.tar.gz.
>
> 5. MOST IMPORTANTLY, a new file xemacs-21.2.20.tar.gz gets created,
> which is the combination of the 5 files xemacs-21.2.20-core.tar.gz,
> xemacs-21.2.20-elc.tar.gz, xemacs-21.2.20-info.tar.gz,
> xemacs-packages.tar.gz, and xemacs-mule-packages.tar.gz.
>
> The directory structure of the new combined file xemacs-21.2.20.tar.gz
> would look like this:
>
> xemacs-21.2.20/
> xemacs-packages/
> xemacs-mule-packages/
>
> I am sorry to shout, but the current situation is just completely
> insane.
>
> ben



From: 
        Ben Wing <ben@666.com>
                                                     12/6/1999 4:19 AM

 Subject:
        Re: Please Vote on Proposals
     To: 
        Kyle Jones <kyle_jones@wonderworks.com>
    CC: 
        XEmacs Review <xemacs-review@xemacs.org>




OK Kyle, how about a different proposal:

1. The distribution consists of the following three parts (let's assume
v21.2.25):

-- xemacs-21.2.25-core.tar.gz
   The same as would currently in xemacs-21.2.25.tar.gz.  You can
   run this editor and edit in fundamental mode, but not do anything
else.

-- xemacs-21.2.25-core-packages.tar.gz
   A useful and complete subset of all the possible packages.  Selection
of
   what goes in and what goes out is based partially on consensus,
partially
   on vote, and partially on these criteria:

    -- commonly-used packages go in.
    -- unmaintained or out-of-date packages go out.
    -- buggy, poorly-written packages go out.
    -- really obscure packages that hardly anybody could possibly care
       about go out.
    -- when there are two or three packages implementing basically the
       same functionality, pick only one to go in unless there are two
that
       both are really commonly-used.
    -- if a package can be loaded implicitly as a result of something in
the
       core, it needs to go in, regardless of whether it's been
maintained.
       This applies, for example, to the mode files -- all mode
packages must
       go in (or more properly, every mode must have a corresponding
package
       that's in, although if there are two or more packages implementing
a
       particular mode, e.g. html, we are free to choose just one).

-- xemacs-21.2.25-aux-packages.tar.gz
   All of the packages not in the previous file.  Generally
crappy-quality,
   poorly-maintained code.

Note, we do not make distinctions between Mule and non-Mule in our
packaging scheme -- this is a bug and XEmacs and/or the packages should
be fixed up so that this goes away.

2. The distribution also contains two combination files:

-- xemacs-21.2.25.tar.gz
   This is the "default" file that a naive user ought to retrieve, and
   he'll get a running XEmacs, just like he wants, and comfortable, too,
   because all of the common packages are there.  This file is a
combination
   of xemacs-21.2.25-core.tar.gz and xemacs-21.2.25-core-packages.tar.gz.

-- xemacs-21.2.25-everything.tar.gz
   This file contains absolutely everything, like it advertises --
   including the aux packages and all of their associated crappy-quality,

   unmaintained code.  This file is a combination of
xemacs-21.2.25-core.tar.gz,
   xemacs-21.2.25-core-packages.tar.gz, and
xemacs-21.2.25-aux-packages.tar.gz.


I like this proposal better than the previous one I advocated, because it
follows your good suggestion of separating the wheat from the chaff in
the packages, so to speak.  People will grab xemacs-21.2.25.tar.gz by
default, just like they should,
and they'll get something they're quite happy with, and we're happy
because we can exercise quality control over the packages and exclude the
crappy ones most likely to cause grief later on.


What say y'all?

ben



Kyle Jones wrote:

> Ben Wing writes:
>  > Disagree.  Please let's follow everyone else's convention, and not
>  > introduce yet another randomness.
>
> It is not randomness! I think this is a semantic issue and an
> important one.  The issue is: What do we consider part of XEmacs
> and what is considered external to XEmacs.  If you put all the
> packages in xemacs.tar.gz, then users can reasonably and wrongly
> assume that all this random Lisp code is maintained by us.  We
> are trying to stay away from that model because in the past it has
> left us with piles and piles of orphaned code.  Even if every one
> of us were paid to maintain XEmacs, it is just not practical for
> us to continue to maintain all that code, let alone any new code.
> So I think the naming distinction Jan is making is worth doing.
>
> Also, I don't consider the current situation broken, except
> perhaps the sumo tarball being out of date.  I never, ever,
> though it was a great idea to ship all the stuff that XEacs
> shipped in the old days.  Because this pile of code was always
> around in the distribution, an enormous web of undocumented
> dependencies was constructed.  Eventually, you HAD to install
> everything because if you left something out or removed something
> you never knew when XEmacs would throw an error.  Thus the Cult
> of the Cargo was born.
>
> One of the best things that came out of the package system was
> the month or two we spent running XEmacs without all the assorted
> Lisp installed.  Dependencies were removed or documented, some
> stuff got retired, and for the first time we actually had a full
> accounting of what we were shipping.  I currently run XEmacs with
> 7 packages and I don't miss the other stuff.
>
> Having come this far, I do not think we should go back to
> advocating that everyone just install everything and not
> think about they are doing.  Besides saving space and startup
> time, another reason to not install everything is that you
> won't bloat your XEmacs process nearly as much if you go
> exploring in the Custom menus, because there won't be as much
> Lisp loaded as Custom sets up its groups and whatnot.

--
In order to save my hands, I am cutting back on my responses, especially
to XEmacs-related mail.  You _will_ get a response, but please be patient.
If you need an immediate response and it is not apparent in your message,
please say so.  Thanks for your understanding.

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Aidan Kehoe on December 27, 2016 using texi2html 1.82.