[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.1 Discussion – KKCC | ||
44.1.2 Discussion – Incremental Collector | ||
44.1.3 Discussion – Pure Space | ||
44.1.4 Discussion – Hashtable-Based Marking and Cleanup | ||
44.1.5 Discussion – The Anti-Cons |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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:
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:
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] | [ ? ] |
On 10/12/1999 5:49 PM Ben Wing wrote:
OK, I can see the advantages. But:
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] | [ ? ] |
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] | [ ? ] |
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
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
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
:]
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] | [ ? ] |
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 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
Author: Ben Wing
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.
untar; configure; make; make install
just works.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.