From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tim Cross Newsgroups: gmane.emacs.devel Subject: Re: Eliminating a couple of independent face definitions Date: Mon, 7 Feb 2011 12:08:07 +1100 Message-ID: References: <87oc6vm67v.fsf@stupidchicken.com> <87vd12z77n.fsf@stupidchicken.com> <87ipx289cu.fsf@nzebook.haselwarter.org> <1A6A06363E5F4274B2A00E2CA8A242D1@us.oracle.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=001485ebea3860a771049ba6ddf7 X-Trace: dough.gmane.org 1297041136 13599 80.91.229.12 (7 Feb 2011 01:12:16 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 7 Feb 2011 01:12:16 +0000 (UTC) Cc: emacs-devel@gnu.org, Philipp Haselwarter To: Drew Adams Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Feb 07 02:12:08 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PmFae-0004WG-KD for ged-emacs-devel@m.gmane.org; Mon, 07 Feb 2011 02:12:07 +0100 Original-Received: from localhost ([127.0.0.1]:60293 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmFad-0002UL-0F for ged-emacs-devel@m.gmane.org; Sun, 06 Feb 2011 20:08:27 -0500 Original-Received: from [140.186.70.92] (port=59958 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmFaQ-0002RL-Pt for emacs-devel@gnu.org; Sun, 06 Feb 2011 20:08:20 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PmFaL-0006aT-DH for emacs-devel@gnu.org; Sun, 06 Feb 2011 20:08:14 -0500 Original-Received: from mail-iw0-f169.google.com ([209.85.214.169]:45160) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PmFaL-0006aO-0D for emacs-devel@gnu.org; Sun, 06 Feb 2011 20:08:09 -0500 Original-Received: by iwc10 with SMTP id 10so4689338iwc.0 for ; Sun, 06 Feb 2011 17:08:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=M28Y75hbvLh6bzRmXQW2EUkwcc2E3ww5GQRd9u/NIyY=; b=njtNgED97jzMLAC4gKV/VjqTgCSOCwFbehAAZLI0QC5fH85QcAJ5COvTvcmvSkaN1k Aq6W2GVQsVvGqj2AAljdeiBZpd9A44/hJOMOU2fRKcqQkY21UMeMcdOMzkDwww19Un6w tY2VCb8I4IZyZazKsOf2uHFQbBWbv577QOI7Q= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; b=I34wg6ZaZA0Z4j/wx5Px60QhWR2OiXBMybrKyGwQFTJdknh2rgm06u5Jhj5vHR9/9G 4ouVMtpoa0XUbV29f/PtF2C3uY7Z0vQnuKt8jQcJ8Uz09srnPt0I8pf7YUNT5wYsmzLw lUoqQaFcbY9CincNvIhh86gvec2ftB5HX4ybY= Original-Received: by 10.231.59.149 with SMTP id l21mr16439248ibh.196.1297040887817; Sun, 06 Feb 2011 17:08:07 -0800 (PST) Original-Received: by 10.231.19.67 with HTTP; Sun, 6 Feb 2011 17:08:07 -0800 (PST) In-Reply-To: <1A6A06363E5F4274B2A00E2CA8A242D1@us.oracle.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.214.169 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:135661 Archived-At: --001485ebea3860a771049ba6ddf7 Content-Type: text/plain; charset=ISO-8859-1 On Sun, Feb 6, 2011 at 9:11 AM, Drew Adams wrote: > T> One thing I would recommend doing, if possible, would be to > T> spend some time running emacs with a dark background and on a > T> tty. This would likely reveal how bad some default face > T> definitions are and let you see how tedious it is having to > T> customize lots of individual face definitions just to get ones > T> that work. > > I'm not sure what your disagreements are with what I said. I > agree that poorly defined default face definitions are a real > problem. I even suggested that they are likely _the_ real > problem here. > > I think our point of disagreement is small - it is really a matter of degrees. Your position is one I would characterise as representing a pure or strict view of inheritance and one I see as having a strong ideological and theoretical base. Mine is possibly chracterised as being more pragmatic and less pure or strict, possibly characterised as being more liberal. There are also a number of assumptions and conclusions you ahve made regarding some of my points, which are incorrect. I will try to make my position with these clearer. Given reasonable face defaults that work out of the box on > both dark and light backgrounds, I think many if not most > (perhaps all?) of the problems you cited go away. With faces > that just work by default, regardless of the background, there > is no need to "customize lots of individual face definitions > just to get ones that work". > > Agreed. If all faces were well defined there would be no problem. However, the reality is that frequently they are not. My suggestions are based on the belief that this is because defining good default face settings is not easy, takes more effort than some developers want to expend, is difficult to do right as developers don't necessarily have access to all the environments involved and it may be unreasonable to expect all developers have the necessary knowledge and experience to know/identify a good default face setting. Therefore, my focus is on what we can do to make it easier for developers to do the right thing. One solution which I think would work towards this would be to develop a set of guidelines on how to identify and select appropriate faces to inherit from and pitfalls to avoid combined with requiring that faces are either fully defined or inherit from a core/base face which is fully defined. I'm not arguing that faces with similar appearance should be linked via inheritance and I'm not arguing that existing fully defined faces should be converted to use inheritance. The main point of disagreement concerns determining appropriate faces to inherit from. Your position is that inheritance should only be used to inherit from a face with the same/similar semantics/meaning as the child face. My argument is less restrictive. If a core face exists that has the same semantic meaning as the child face, then of course that is the obvious choice. However, if there are no core faces with the same semantic meaning I would rather have the face inherit from a fully defined face with a different semantic meaning, provided that does not cause confusion within the mode used by the child face, rather than have a face that is not fully defined. I would go further and suggest that while you accept the use of inheritance provided the inheritance chain follows the same semantic meaning, you would prefer in general not to use inheritance even if a good candidate with the same semantic meaning does exist in the core set of fully defined faces. While I would never argue that developers should be forced to use inheritance, I would suggest this is the wrong approach. I believe inheritance should definitely be used when there is clear semantic equivalents within the core set because this will help ensure consistency in representation of semantically related items. For example, I currently have numerous definitions for 'hyperlink' type objects as well as clickable buttons. I would like objects of these types to have the same appearance in all modes. However, I like hyperlinks to be a specific colour, with underlining, bold and italic fonts. To achieve this (possibly unusual) appearance in a consistent manner, I have to customize multiple faces. However, if inheritance was used, I would only have to do this once. If I understand your position regarding inheritance, you disagree with the concept of a child face inheriting from a semantically unrelated face because you feel doing so will lead to confusion and unexpected results because it 'muddies' the semantics of the inheritance and will cause unexpected/unwanted side effects when a core face definition is changed. I don't see it as being that straight-forward. I agree that badly chosen inheritance would cause problems - for example, having something that was not a clickable link inherit from the link face. On the other hand, core packages, such as dired, have been using inheritance from sematically unrelated faces for some time and I'm not aware it has caused problems. The dired-directory face inherits from font-lock-function-name-face. There is no 'semantic' link between these two faces, yet having this inheritance apparently works. Yes, if I change the value of font-lock-function-name-face, it will change the appearance of directory names in dired. However, in practice, this is rarely a problem. In fact, if your changing the face to make it fit better with some theme or to work better in your environment, it is likely that this change would fit with your overall objectives anyway. One of the reasons I think this works is because the choice is unrelated and does not confuse contexts within the mode the face is used in. If dired had a face to represent function names, then using font-lock-function-name-face for directory names would be a bad idea. However, dired does not have such a context and therefore does not cause confusion within that mode. Furthermore, I don't believe it would cause confusion with modes that use font-lock-function-name-face for function names. The two modes are distinct enough that it is clear that a face with X attributes in dired is different to a face with the same attributes in completely unrelated modes, such as emacs-lisp-mode. There are some other benefits to using inheritance in this manner. I think it is reasonable to suggest that all users have some underlying 'theme' they want to achieve with face settings. Some themes may seem unusual or even unpleasant, but there is usually some overriding pattern - faces are not selected randomly (I guess there may be some extreme cases where people might do this, but it isn't the 'norm'). Within any theme there is a finite set of usable faces i.e. faces that can be read, fit with the theme and are aesthetically acceptable. As we increase the number of individual face definitions, we also increase the number of faces with different names/meanings which have the same set of attributes as other unrelated faces. If we assume two basic approaches, your pure inheritance model and my less rigid inheritance approach, we end up with two vary different situations when it comes to the user customizing faces to obtain their desired theme. Under your approach, they will need to customize a larger number of faces to obtain their desired outcome. However, under my approach, which is more likely to make greater use of inheritance because it is not restricted to only using semantically related faces, it is more probable that less faces will need to be defined. Of course, we could probably achieve a better 'middle ground' with a larger, more comprehensive set of core/base faces as this would increase the likelihood that a child face can find a sematically related core/base face definition. I have nothing against this and included it as part of my suggestion on how to improve matters and reduce the number of poorly defined faces. > T> As I see it, we want to achieve four main goals. We want to > T> make it easier for developers to set appropriate defaults, we > T> want to get the best default possible for end users, > T> regardless of platform or light/dark background preferences, > T> we want to make it as easy as possible for end users to > T> customize their environment > > Agree. > > T> and we want to, if possible, avoid a proliferation of > T> different face definitions, especially when the definitions > T> don't really differ in anything other than name as this makes > T> customizing and theme definition more complex than it needs to > T> be. > > Disagree, if by "don't really differ in anything other than > the name" you are referring only to the `defface' default > attribute values. > > I am in favor of there being two faces instead of one, if > their use/meaning is different, even if their definitions > modulo the names are identical. In particular, this > facilitates separate customization. > > I was actually thinking of faces that have the same meaning, different names and different default definitions. This is a growing problem. We end up with inconsistency between modes for faces representing the same type of object. It was not meant to mean faces that happen to have the same attribute sets. For example, I have a number of modes that have the same concept of a clickable 'button'. In some modes they look different to how buttons look in other modes. I want them to all look the same and have to customize them individually. This is what I meant by the proliferation of faces. > It avoids coupling that is not logical and not necessary. > Inheritance (hence coupling) based on physical attributes > (appearance) can perhaps occasionally be appropriate, but in > general it is a no-no. > > Yes, where possible, inheritance should be used to link semantically related faces . However, linking semantically unrelated faces is not as bad in practice as you suggest and could be used to improve the end user expereince without causing the confusion you suggest. Yes, there are dangers, but there are also benefits which I think outweigh the downside of a strict inheritance approach, especially if there are only a few core/base fonts to inherit from. (Names are generally indicative of meaning, but yes, there > could be two faces with different names yet identical meaning. > In that case, yes, the duplication could be eliminated.) > > (There is an orthogonal reason to avoid using too many faces > at the same time: performance. But that is a different story > altogether.) > > T> It was good you pointed out that faces are not just about > T> colour. Sometimes, I think peopoe forget this and only focus > T> on the colour aspect. However, this is understandable as > T> colour is what distinguishes most faces from each other. > T> > T> We need to acknowledge how difficult it is to define good > T> default faces. Many definitions fail to do this. While your > T> suggestion of using colour compliments can help, I'm not > T> convinced it is always that easy. One problem is that > T> different environments have different sets of colours to work > T> with. For example, if you work under the linux console, you > T> don't have compliments for most of the colours available under > T> other environments, such as X or (I presume) Windows/Mac. The > T> problem is further complicated because most developers won't > T> have access to many of these environments, so can't easil test > T> and design appropriate faces even if motivated to do so. > > Agree. I did not mean to raise complementing as any kind of > cure-all - far from it. I was just mentioning that I provided > a quick-and-dirty set of default settings for dark backgrounds > for a particular library by flipping the light-background > defaults to their complements. Obviously, any set of defaults > for either light or dark deserves to be well thought out. And > all of the considerations you mention should be taken into > account. > > The tty thing is a big limitation, in particular. Designing a > set of faces for use on tty only is a different task from > designing a set for use with many colors and other attributes. > > For a library that is intended to work with both tty and > graphic windows, either tradeoffs are called for or > essentially two modes or face schemes are needed: full and > degraded (tty). We have constructs like `(type tty pc)' that > can help with that. > > The tty face values are a little tricky because you have a much smaller set of attributes to work with and the attributes you do have have less options. However, the defface macro has the ability to handle this and while it may be a pain to do, it is doable and should be part of any fully defined face definition. I would suggest there are very few packages which are only designed to run within a GUI environment (e.g. doc-view I guess, can't think of many others). > T> I would not argue that inheritance is an ideal solution to > T> this problem, However, I do think it can be part of the > T> solution. Perhaps something along the lines of > T> > T> * Establish guidelines on how to use inheritance i.e. how to > T> select which face to inherit from > T> * Define a good (not too large) set of base faces. Existing > T> font-lock faces may be sufficient, maybe not. Would need > T> review. > T> * Require all face definitions in core emacs packages to > T> either fully define a face (i.e. definition for dark/light, > T> tty, X mac ms etc) OR inherit from a base face (assuming > T> all base faces are fully defined) > T> * Add a section to the manual encouraging developers to > T> either provide a fully defined face or inherit from a base > T> face, but don't just define a single (usually) light > T> background face > T> > T> The key here is that all faces in core emacs packages would > T> end up with a fully defined face, either explicitly or via > T> inherit. > > Fully-defined, yes - good. The part that I think can be > misguided is basing everything on inheritance from faces that > are not necessarily related in terms of use or meaning. > > Nobody has suggested basing everything on inheritance and it has not been suggested that inheritance should be forced on anyone (though, as outlined above, there could be a strong argument for forcing inheritance for clearly semantically related faces). The suggestion is that if you don't want to fully define a face, then use inheritance RATHER than a partially defined face. > Basing a face on a related face is not bad. Stretching things > to base all faces on some "basic" faces, no matter how > unrelated in terms of meaning or context, is not a great idea. > > Nobody has suggested basing *all* faces on some base set. > Faces, including "basic" faces, are customizable. You don't > want a user who customizes `font-lock-doc-face' to suddenly > find that s?he has also affected a chain of unrelated faces > that inherit from it. Customizing font-lock faces should not > affect Dired or Info or... > > Except they already do! I don't see this as a 'real' problem, but more a theoretical one. Yes, changing face attributes in font-lock-* faces will change the look of dired faces, but does that really matter in practice? Maybe the dired faces should be fully defined and I would not have an issue with that. However, I'm glad they are using inheritance rather than only having partial definitions. . > T> One of the reasons I like the use of inherit for face > T> definitions is mainly from an end user perspective. I would > T> rather have faces that are fully defined via inherit, even if > T> that inheritance seems odd, than have a partially defined face > T> which only works if you have a light background or are running > T> under a full gui environment. > > Those are not the only two alternatives - it's not either-or. > > I am in favor of full face definitions. And I am not against > inheritance. The important thing is for a face to inherit > only from a related face (in terms of use/meaning). > I would argue it is preferable rather than being required. > > The key is whether it will generally make sense for the > inheriting face if the inherited face gets customized. If > not, then inheritance is likely not the best way to go. > > I actually agree, except we would differ on what makes sense. > T> If, when I change the base face definition, it results in > T> unacceptable changes to some face which inherits from it, I > T> can customize it. > > Sure you can, but now you're back to customizing all over the > place - and now across multiple libraries and multiple use > contexts, to boot. The cure is at least as bad as the > disease. > > No, its not as bad. If more faces inherited from fully defined core faces, then the faces I need to customize are only those which I find aesthetically unacceptable and does not include faces that are not fully defined and therefore are not even readable in my environment. Moreover, many of the faces I find aesthetically unacceptable are likely to have the same/similar attributes. I can change the base definition and have my changes propogate through all faces that currently have the unacceptable default. Without the use of inheritance, I have multiple faces to change. When they are not fully defined, many of those changes are needed just to make the face readable i.e. not just an aesthetic change, but a necessary one. Nothing wrong with inheritance. But boiling everything down > to font-lock faces (or similar) is a bad idea. Better for > face inheritance to reflect face usage/meaning: families > (inheritance hierarchies) of related faces, not just > everything inheriting from primordial faces `adam' and `eve'. > > Why do you keep taking the extreme? Nobody has suggested that all faces inherit form some low base. This is not what I've suggested - either fully define or inherit, just don't have partial poorly defined faces that only work in a limited environment, such as a light background. > T> My experience has been that this does sometimes happen, but > T> not that often and it is more preferable to fix up the few > T> faces than to spend much more time configuring lots of > T> individual faces. > > I think you are again thinking of the fact that you are > needing to configure lots of faces because they were defined > incompletely or with poor defaults. Take away that > presupposition and where is the argument? > To take away that presupposition, you need to come up with something that enables developers to do the right thing and not only use partial face definitions as the default. This is the whole point. Yes, theoretically, if all faces were fully defined, most of the problem would go away (though there are then other issues concerning consistency). The reality is that too often, faces are not fully defined. Inheritance would provide a simple way to have a fully defined face when the developer cannot or does not want to fully define the face themselves. > T> In fact, as the number of individual face definitions has > T> increased, I actaully think we have gone the wrong direction. > T> We have too many faces which are mostly the same. > > They are not the same just because they have the same > _appearance_ (by _default_ no less). This is a key element in > the confusion, I think. It sounds like it motivated Yidong's > search for faces to eliminate "duplication" via inheritance. > > I acknowledge that. However, we have instances of faces that do represent the same semantic object, but which have different definitions in different modes i.e. clickable buttons etc. I have three different faces for representing dates (admittedly, these are add-on packages and not core ones), I have different faces for representing links etc. None of these use inheritance and in some cases, have different default values. In these instances, inheritance should be used. I then have the ability to set all like things to the same appearance and if I want, the option to change or augement them per mode. > Faces are not the same as their (attribute) values. Faces > have identity and purpose as well as values. > > Agreed. We may differ on how far that identity reaches. I see dired-directory as having its own identity and its relevance is restricted to within dired mode. It inherits from a font-lock face, but I don't see that as part of its identity as such. You appear to see the face it inherits from as part of its identity as well. I'm not sure this is always so or necessary. This is essentially no different from having multiple user > options (or other variables) that have the same value: 42, > nil, t,... You would not argue that we define a set of > "basic" user options and use inheritance to factor out any > "duplicate" options that have the same default value of 42 or > nil, would you? > > You would not argue that we should have only one primeval user > option with a default value of 42, and inherit from it for > wildly different options with different use cases (meanings), > so that someone who customizes the "basic" option to change > the value 42 to 24 ends up changing lots and lots of > inheriting options. Would you? How are faces different in > this regard? > > Now this is just plain silly and a very poor analogy . Faces have a lot more in common and a much closer relationship than al the user variables. Faces work together to present a theme, they are not independent as you imply. Faces that don't set an attribute inherit the value from the default face. You configure faces based on an overall theme and how they interact with each other and faces all have the same format/attributes. To suggest they are as indpendent from each other as other user variables is nonsense. Ignoring how poor the analogy is, the fact is that NOBODY has suggested that all faces need to inherit form a base set. This was never proposed. T> It seems now that every new package is adding its own face > T> definitions > > Good. That should probably happen more than it does. ;-) > > If reasonable, related faces exist on which to base the new > face definitions, then by all means inheritance might well be > called for. But a new package should _not_ avoid adding its > own face definitions, whether they are defined using > inheritance or not (i.e., pointer or copy). > > Disagree. A package should only define its own face when either there is no existing face which adequately represents the meaining of the face OR there is a strong expectation that the user may want to customize the face independently. There is a definite danger of having too many faces and ending up with a consistency problem. Consider the situation where every programming mode defined its own face to represent comments and did not use inheritance. What benefit does that give us? Very little. What harm - potentially a lot as now you have to configure multiple faces to just get code comments to have a consistent appearance. A mode should NOT create a new face just for the sake of it and if it does create a new face, either fully define the face or inherit from a fully defined face - its that simple. If you want to restrict inheritance to only use faces with the same semantic meaning, fine. I think it is over restrictive, but care less about that than about having a solution that would ensure faces are fully defined and providing a way to achieve this that will facilitate developers doing the right thing. On the contrary. What should be avoided is reusing some face > that makes no sense in the current context. What is the > _practical_ criterion? Whether or not customizing the face > wrt its original context/purpose will have a negative effect > in the new context. If not, then go for it (reuse/inherit). > Agreed - pretty much my position. > > T> and many of them are poorly defined. It now takes much > T> longer for me to establish a consistent set of faces. > > Bad - agreed. But not a necessary consequence of having many > faces. More likely a consequence of poor default definitions > (as you mentioned). > > Yes, but encouraging the addition of new faces without good justification is bad - it is the other extreme. Too often, I use applications that don't have enough faces and I cannot change the appearance of some object that I would like to somehow stand-out. However, the other extreme is a proliferation of unnecessary faces that just make customization and theming more difficult. T> If we required face definitions to either be fully defined or > T> inherited from a base set that are fully defined, we would > T> likely give a much better default experience to end users. > > Full face definitions are good, yes. > That is independent of the question of inheritance. > > Well... indiscrimately imposing inheritance (from fully defined > faces) can ensure full definitions. But it has a cost: it can > also introduce unnecessary and unwanted dependencies with > negative consequences. > > Well, either direction has a cost. There is no avoiding that. My view is to find the point at which we get the best cost/benefit. Inheritance provides a way to reduce the burden on developers to fullly define faces and has the potential to reduce the number of faces that are only partially defined and work only in limited configurations/environments. Whether we have strict or less rigid restrictions on inheritance will affect how easily inheritance can be used in this manner. Strict inheritance will give a consistent semantic meaning in inheritance chains and potentially more predictable resutls when modifying base faces. Less rigid inheritance would allow inheritance to be used instead of fully face definitions in more situations. If badly applied it does have the potential to cause confusion, but this could be mitigated with good guidelines. New faces should only be introduced when there is a demonstrated case and not just as an automatic default action. T> Using inheritance also means that when we find a face > T> definition which is poor for a particular environment, we can > T> refine that base definition rather than having to find all > T> similarly poor definitions and updating them individually. > > Yes and no. "Fixing" it for one environment might do exactly > the wrong thing for another context, e.g. for one of its > descendents. Inheritance needs to be used carefully, based on > intended use/meaning of the faces involved. > > Maybe, though I don't think it is as bad in practice as you assume. Existing modes have been using inheritance in a non-semantic fashion since at least emacs 21 and this doesn't seem to have cause any major issues. T> Using inheritance means that it is easier to make broad > T> changes to face definitions, reducing the time spent in > T> customize and lets you then tweak those specific faces which > T> don't quite work. > T> > T> So, using your example, if someone changed the base face that > T> dired+ uses, either they will find the result in dired+ > T> acceptable or they can then tweak that face further. The > T> alternative is that it would be necessary to customize both > T> faces, even when you are going to set them to the same value. > > Maybe, maybe not. Depends what kind of change you want/need. > > It's true that if you want to change all occurrences of red > foreground to blue then more customization would be involved > without inheritance. Maybe we could find a way to make such > changes easier - I don't have a problem with that. > > Maybe this could be an alternative. Frequently, you do need to change colours 'across the board' - often because the faces are not fully defined and you have a different background to the assumed default and need to make the change to make the face more readable. So, perhaps this would fix the symptom. However, it does not address the basic problem, which is faces that are not fully defined. But we should not be using _inheritance_ for that (in > general). A Dired face should either not inherit or it should > inherit from a related face, not just some face whose _default > appearance_ looks good for Dired. It makes no sense to base a > Dired face on a font-lock face, for instance. > > So you would argue that the existing dired face definitions are wrong. However, they ahve been like that for quite some time and it appears to work. > Just because you might want some Dired face to have a red > foreground by default is no reason to go looking for a face > with a red foreground to inherit from. Look instead for a > face with a related use/meaning. If you find none, then do > not use inheritance here. That's the guideline I'd suggest. > > I emphasize the use/meaning of a given face: what it is for, > what it represents, what it does. I think you are emphasizing > its default appearance - attribute values (color etc.). To > me, a face or a variable `foo' is mainly about its use, not > its value. > > No, I'm not focused on its appearance. The difference is that while I agree you should select the face that has a similar semantic meaning if one exists, I have no issue with using one that does not provided it does not cause confusion within the mode it is used in. I would cite dired as an example where this has been done successfully. > If the opposite were true, then we would name faces and > variables after their default values, not after their uses. > Yes, I've seen some Lisp code with face names like > `underlined-bold-red-foreground-on-gray-background'. > (Mea culpa: I even wrote such code at one point.) > > And there's not necessarily anything wrong with that; for some > contexts it might make sense. But in that case it makes more > sense for the "face" to be a constant, not customizable. It > would be perverse to customize a face named `red-foreground' > to have a green foreground. > (And in general it is more likely for single attributes to be > reuse candidates than it is for combinations of attributes.) > > T> The reality is that there are a limited set of good faces and > T> you will usually end up with the same face definition being > T> used in multiple roles. Frequently, those roles have nothing > T> to do with each other. This doesn't matter as the contexts > T> are completely different. From an end user perspective, it is > T> irrelevant that compiler messages inherit from > T> font-lock-string - all the end user sees is that compiler > T> messages use a default face that is green, which may be > T> exactly the same as strings in their code, but so what. > > I strongly disagree here. > > If the roles/meanings/use are unrelated, then inheritance is > usually inappropriate. It _does_ matter whether a > compiler-messages face inherits from `font-lock-string-face' - > _if_ someone customizes that parent face. > > But does it really matter. I change font-lock-comment-face to orange because that is easier to read or more aesthetic given my default background colour. As a result, compiler-message face also changes to orange. Isn't it just as likely that if pink was not acceptable for comments in code that pink is also unacceptable for messages in compile-mode? Sure, maybe I might decide I'd still like pink for those messages and I can override the inheritance, but in practice, I think in most cases, this would be fine and has been my experience with the mdoes that do use inheritance in such a manner. Of course, if there is a base face with a more closely fitting semantic meaning, it should be used in preference and you would avoid using faces like link or button that have very precise meanings that could cause confusion within the mode - especially if that mode supports links or buttons. If we defined a compiler-messages face to inherit from > `font-lock-string-face' _only_ because we liked the default > foreground choice of `LightSalmon', that would be misguided, > IMO. > > Perhaps, if that was the only motivation. However, if you choose that font-lock face because you want to use inheritance rather than spend time fully defining compiler-message face and if the font-lock face is fully defined, then it may be a valid choice. > If there is no existing face that is related in terms of > use/meaning, then the compiler-messages face should not > inherit; it should just be defined with a default foreground > of `LightSalmon'. That kind of duplication is not a curse but > a blessing. > NO, That would be a partial font definition. If I happen to use a background of LightSalmon, that face is now unreadable. Either fully define the face or inherit. > > Then a user can customize either the compiler-messages face or > `font-lock-string-face' without affecting the other. And that > makes sense because (by hypothesis) the two are unrelated. > > Even if compiler-message face uses inheritance form an unrelated face, you still have the option of customizing it to something different or even removing the inheritance if so desired. Tim --001485ebea3860a771049ba6ddf7 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable

On Sun, Feb 6, 2011 at 9:11 AM, Drew Ada= ms <drew.adam= s@oracle.com> wrote:
T> One thing I would recommend doing, if possible, would be to
T> spend some time running emacs with a dark background and on a
T> tty. =A0This would likely reveal how bad some default face
T> definitions are and let you see how tedious it is having to
T> customize lots of individual face definitions just to get ones
T> that work.

I'm not sure what your disagreements are with what I said. =A0I
agree that poorly defined default face definitions are a real
problem. =A0I even suggested that they are likely _the_ real
problem here.

I think our point of disagreement is small - it is re= ally a matter of degrees. Your position is one I would characterise as repr= esenting a pure or strict view of inheritance and one I see as having a str= ong ideological and theoretical base. Mine is possibly chracterised as bein= g more pragmatic and less pure or strict, possibly characterised as being m= ore liberal.=A0

There are also a number of assumptions and conclusions = you ahve made regarding some of my points, which are incorrect. I will try = to make my position with these clearer.

Given reasonable face defaults that work out of the box on
both dark and light backgrounds, I think many if not most
(perhaps all?) of the problems you cited go away. =A0With faces
that just work by default, regardless of the background, there
is no need to "customize lots of individual face definitions
just to get ones that work".

Agreed. If all faces were well defined there wo= uld be no problem. However, the reality is that frequently they are not. My= suggestions are based on the belief that this is because defining good def= ault face settings is not easy, takes more effort than some developers want= to expend, is difficult to do right as developers don't necessarily ha= ve access to all the environments involved and it may be unreasonable to ex= pect all developers have the necessary knowledge and experience to know/ide= ntify a good default face setting. Therefore, my focus is on what we can do= to make it easier for developers to do the right thing. One solution which= I think would work towards this would be to develop a set of guidelines on= how to identify and select appropriate faces to inherit from and pitfalls = to avoid combined with requiring that faces are either fully defined or inh= erit from a =A0core/base face which is fully defined.

I'm not arguing that faces with similar appearance = should be linked via inheritance and I'm not arguing that existing full= y defined faces should be converted to use inheritance.=A0

The main point of disagreement concerns determining appropriate = faces to inherit from. Your position is that inheritance should only be use= d to inherit from a face with the same/similar semantics/meaning as the chi= ld face. My argument is less restrictive. If a core face exists that has th= e same semantic meaning as the child face, then of course that is the obvio= us choice. However, if there are no core faces with the same semantic meani= ng I would rather have the face inherit from a fully defined face with a di= fferent semantic meaning, provided that does not cause confusion within the= mode used by the child face, rather than have a face that is not fully def= ined.=A0

I would go further and suggest that while you accept th= e use of inheritance provided the inheritance chain follows the same semant= ic meaning, you would prefer in general not to use inheritance even if a go= od candidate with the same semantic meaning does exist in the core set of f= ully defined faces. While I would never argue that developers should be for= ced to use inheritance, I would suggest this is the wrong approach. I belie= ve inheritance should definitely be used when there is clear semantic equiv= alents within the core set because this will help ensure consistency in rep= resentation of semantically related items. For example, I currently have nu= merous definitions for 'hyperlink' type objects as well as clickabl= e buttons. I would like objects of these types to have the same appearance = in all modes. However, I like hyperlinks to be a specific colour, with unde= rlining, bold and italic fonts. To achieve this (possibly unusual) appearan= ce in a consistent manner, I have to customize multiple faces. However, if = inheritance was used, I would only have to do this once.

If I understand your position regarding inheritance, yo= u disagree with the concept of a child face inheriting from a semantically = unrelated face because you feel doing so will lead to confusion and unexpec= ted results because it 'muddies' the semantics of the inheritance a= nd will cause unexpected/unwanted side effects when a core face definition = is changed. I don't see it as being that straight-forward. I agree that= badly chosen inheritance would cause problems - for example, having someth= ing that was not a clickable link inherit from the link face. On the other = hand, core packages, such as dired, have been using inheritance from semati= cally unrelated faces for some time and I'm not aware it has caused pro= blems. The dired-directory face inherits from font-lock-function-name-face.= There is no 'semantic' link between these two faces, yet having th= is inheritance apparently works. Yes, if I change the value of font-lock-fu= nction-name-face, it will change the appearance of directory names in dired= . However, in practice, this is rarely a problem. In fact, if your changing= the face to make it fit better with some theme or to work better in your e= nvironment, it is likely that this change would fit with your overall objec= tives anyway.=A0

One of the reasons I think this works is because the ch= oice is unrelated and does not confuse contexts within the mode the face is= used in. If dired had a face to represent function names, then using font-= lock-function-name-face for directory names would be a bad idea. However, d= ired does not have such a context and therefore does not cause confusion wi= thin that mode. Furthermore, I don't believe it would cause confusion w= ith modes that use font-lock-function-name-face for function names. The two= modes are distinct enough that it is clear that a face with X attributes i= n dired is different to a face with the same attributes in completely unrel= ated modes, such as emacs-lisp-mode.=A0

There are some other benefits to using inheritance in t= his manner. I think it is reasonable to suggest that all users have some un= derlying 'theme' they want to achieve with face settings. Some them= es may seem unusual or even unpleasant, but there is usually some overridin= g pattern - faces are not selected randomly (I guess there may be some extr= eme cases where people might do this, but it isn't the 'norm').= Within any theme there is a finite set of usable faces i.e. faces that can= be read, fit with the theme and are aesthetically acceptable. As we increa= se the number of individual face definitions, we also increase the number o= f faces with different names/meanings which have the same set of attributes= as other unrelated faces.=A0

If we assume two basic approaches, your pure inheritanc= e model and my less rigid inheritance approach, we end up with two vary dif= ferent situations when it comes to the user customizing faces to obtain the= ir desired theme. Under your approach, they will need to customize a larger= number of faces to obtain their desired outcome. =A0However, under my appr= oach, which is more likely to make greater use of inheritance because it is= not restricted to only using semantically related faces, it is more probab= le that less faces will need to be defined.=A0

Of course, we could probably achieve a better 'midd= le ground' with a larger, more comprehensive set of core/base faces as = this would increase the likelihood that a child face can find a sematically= related core/base face definition. I have nothing against this and include= d it as part of my suggestion on how to improve matters and reduce the numb= er of poorly defined faces.=A0
=A0
T> As I see it, we want to achieve four main goals. We want to
T> make it easier for developers to set appropriate defaults, we
T> want to get the best default possible for end users,
T> regardless of platform or light/dark background preferences,
T> we want to make it as easy as possible for end users to
T> customize their environment

Agree.

T> and we want to, if possible, avoid a proliferation of
T> different face definitions, especially when the definitions
T> don't really differ in anything other than name as this makes
T> customizing and theme definition more complex than it needs to
T> be.

Disagree, if by "don't really differ in anything other than
the name" you are referring only to the `defface' default
attribute values.

I am in favor of there being two faces instead of one, if
their use/meaning is different, even if their definitions
modulo the names are identical. =A0In particular, this
facilitates separate customization.

I was actually thinking of faces that have the same m= eaning, different names and different default definitions. This is a growin= g problem. We end up with inconsistency between modes for faces representin= g the same type of object. It was not meant to mean faces that happen to ha= ve the same attribute sets. For example, I have a number of modes that have= the same concept of a clickable 'button'. In some modes they look = different to how buttons look in other modes. I want them to all look the s= ame and have to customize them individually. This is what I meant by the pr= oliferation of faces.

=A0
It avoids coupling that is not logical and not necessary.
Inheritance (hence coupling) based on physical attributes
(appearance) can perhaps occasionally be appropriate, but in
general it is a no-no.

Yes, where possible, inheritance should be used to li= nk semantically related faces . However, linking semantically unrelated fac= es is not as bad in practice as you suggest and could be used to improve th= e end user expereince without causing the confusion you suggest. Yes, there= are dangers, but there are also benefits which I think outweigh the downsi= de of a strict inheritance approach, especially if there are only a few cor= e/base fonts to inherit from.=A0

(Names are generally indicative of meaning, but yes, there
could be two faces with different names yet identical meaning.
In that case, yes, the duplication could be eliminated.)

(There is an orthogonal reason to avoid using too many faces
at the same time: performance. =A0But that is a different story
altogether.)

T> It was good you pointed out that faces are not just about
T> colour. =A0Sometimes, I think peopoe forget this and only focus
T> on the colour aspect. =A0However, this is understandable as
T> colour is what distinguishes most faces from each other.
T>
T> We need to acknowledge how difficult it is to define good
T> default faces. =A0Many definitions fail to do this. =A0While your
T> suggestion of using colour compliments can help, I'm not
T> convinced it is always that easy. =A0One problem is that
T> different environments have different sets of colours to work
T> with. =A0For example, if you work under the linux console, you
T> don't have compliments for most of the colours available under T> other environments, such as X or (I presume) Windows/Mac. =A0The
T> problem is further complicated because most developers won't
T> have access to many of these environments, so can't easil test T> and design appropriate faces even if motivated to do so.

Agree. =A0I did not mean to raise complementing as any kind of
cure-all - far from it. =A0I was just mentioning that I provided
a quick-and-dirty set of default settings for dark backgrounds
for a particular library by flipping the light-background
defaults to their complements. =A0Obviously, any set of defaults
for either light or dark deserves to be well thought out. =A0And
all of the considerations you mention should be taken into
account.

The tty thing is a big limitation, in particular. =A0Designing a
set of faces for use on tty only is a different task from
designing a set for use with many colors and other attributes.

For a library that is intended to work with both tty and
graphic windows, either tradeoffs are called for or
essentially two modes or face schemes are needed: full and
degraded (tty). =A0We have constructs like `(type tty pc)' that
can help with that.

The tty face values are a little tricky because you h= ave a much smaller set of attributes to work with and the attributes you do= have have less options. However, the defface macro has the ability to hand= le this and while it may be a pain to do, it is doable and should be part o= f any fully defined face definition. I would suggest there are very few pac= kages which are only designed to run within a GUI environment (e.g. doc-vie= w I guess, can't think of many others).=A0
=A0
T> I would not argue that inheritance is an ideal solution to
T> this problem, =A0However, I do think it can be part of the
T> solution. =A0Perhaps something along the lines of
T>
T> =A0* Establish guidelines on how to use inheritance i.e. how to
T> =A0 =A0select which face to inherit from
T> =A0* Define a good (not too large) set of base faces. =A0Existing
T> =A0 =A0font-lock faces may be sufficient, maybe not. =A0Would need T> =A0 =A0review.
T> =A0* Require all face definitions in core emacs packages to
T> =A0 =A0either fully define a face (i.e. definition for dark/light, T> =A0 =A0tty, X mac ms etc) OR inherit from a base face (assuming
T> =A0 =A0all base faces are fully defined)
T> =A0* Add a section to the manual encouraging developers to
T> =A0 =A0either provide a fully defined face or inherit from a base
T> =A0 =A0face, but don't just define a single (usually) light
T> =A0 =A0background face
T>
T> The key here is that all faces in core emacs packages would
T> end up with a fully defined face, either explicitly or via
T> inherit.

Fully-defined, yes - good. =A0The part that I think can be
misguided is basing everything on inheritance from faces that
are not necessarily related in terms of use or meaning.

Nobody has suggested basing everything on inheritance= and it has not been suggested that inheritance should be forced on anyone = (though, as outlined above, there could be a strong argument for forcing in= heritance for clearly semantically related faces). The suggestion is that i= f you don't want to fully define a face, then use inheritance RATHER th= an a partially defined face.
=A0
Basing a face on a related face is not bad. =A0Stretching things
to base all faces on some "basic" faces, no matter how
unrelated in terms of meaning or context, is not a great idea.

Nobody has suggested basing *all* faces on some base = set.=A0
=A0
Faces, including "basic" faces, are customizable. =A0You don'= t
want a user who customizes `font-lock-doc-face' to suddenly
find that s?he has also affected a chain of unrelated faces
that inherit from it. =A0Customizing font-lock faces should not
affect Dired or Info or...

Except they already do! I don't see this as a = 9;real' problem, but more a theoretical one. Yes, changing face attribu= tes in font-lock-* faces will change the look of dired faces, but does that= really matter in practice? Maybe the dired faces should be fully defined a= nd I would not have an issue with that. However, I'm glad they are usin= g inheritance rather than only having partial definitions.=A0
. =A0
T> One of the reasons I like the use of inherit for face
T> definitions is mainly from an end user perspective. I would
T> rather have faces that are fully defined via inherit, even if
T> that inheritance seems odd, than have a partially defined face
T> which only works if you have a light background or are running
T> under a full gui environment.

Those are not the only two alternatives - it's not either-or.

I am in favor of full face definitions. =A0And I am not against
inheritance. =A0The important thing is for a face to inherit
only from a related face (in terms of use/meaning).
I would argue it is preferable rather than being required.=A0<= /div>

The key is whether it will generally make sense for the
inheriting face if the inherited face gets customized. =A0If
not, then inheritance is likely not the best way to go.

I actually agree, except we would differ on what make= s sense.
=A0
T> If, when I change the base face definition, it results in
T> unacceptable changes to some face which inherits from it, I
T> can customize it.

Sure you can, but now you're back to customizing all over the
place - and now across multiple libraries and multiple use
contexts, to boot. =A0The cure is at least as bad as the
disease.

No, its not as bad. If more faces inherited from full= y defined core faces, then the faces I need to customize are only those whi= ch I find aesthetically unacceptable and does not include faces that are no= t fully defined and therefore are not even readable in my environment. More= over, many of the faces I find aesthetically unacceptable are likely to hav= e the same/similar attributes. I can change the base definition and have my= changes propogate through all faces that currently have the unacceptable d= efault. Without the use of inheritance, I have multiple faces to change. Wh= en they are not fully defined, many of those changes are needed just to mak= e the face readable i.e. not just an aesthetic change, but a necessary one.= =A0

Nothing wrong with inheritance. =A0But boiling everything down
to font-lock faces (or similar) is a bad idea. =A0Better for
face inheritance to reflect face usage/meaning: families
(inheritance hierarchies) of related faces, not just
everything inheriting from primordial faces `adam' and `eve'.

Why do you keep taking the extreme? Nobody has sugges= ted that all faces inherit form some low base. This is not what I've su= ggested - either fully define or inherit, just don't have partial poorl= y defined faces that only work in a limited environment, such as a light ba= ckground.=A0
=A0
T> My experience has been that this does sometimes happen, but
T> not that often and it is more preferable to fix up the few
T> faces than to spend much more time configuring lots of
T> individual faces.

I think you are again thinking of the fact that you are
needing to configure lots of faces because they were defined
incompletely or with poor defaults. =A0Take away that
presupposition and where is the argument?

To take away that presupposition, you need to come up with something tha= t enables developers to do the right thing and not only use partial face de= finitions as the default. This is the whole point. Yes, theoretically, if a= ll faces were fully defined, most of the problem would go away (though ther= e are then other issues concerning consistency). The reality is that too of= ten, faces are not fully defined. Inheritance would provide a simple way to= have a fully defined face when the developer cannot or does not want to fu= lly define the face themselves.=A0


T> In fact, as the number of individual face definitions has
T> increased, I actaully think we have gone the wrong direction.
T> We have too many faces which are mostly the same.

They are not the same just because they have the same
_appearance_ (by _default_ no less). =A0This is a key element in
the confusion, I think. =A0It sounds like it motivated Yidong's
search for faces to eliminate "duplication" via inheritance.

I acknowledge that. However, we have instances of fac= es that do represent the same semantic object, but which have different def= initions in different modes i.e. clickable buttons etc. I have three differ= ent faces for representing dates (admittedly, these are add-on packages and= not core ones), I have different faces for representing links etc. None of= these use inheritance and in some cases, have different default values. In= these instances, inheritance should be used. I then have the ability to se= t all like things to the same appearance and if I want, the option to chang= e or augement them per mode.=A0
=A0
Faces are not the same as their (attribute) values. =A0Faces
have identity and purpose as well as values.

Agreed. We may differ on how far that identity reache= s. I see dired-directory as having its own identity and its relevance is re= stricted to within dired mode. It inherits from a font-lock face, but I don= 't see that as part of its identity as such. You appear to see the face= it inherits from as part of its identity as well. I'm not sure this is= always so or necessary. =A0

This is essentially no different from having multiple user
options (or other variables) that have the same value: 42,
nil, t,... =A0You would not argue that we define a set of
"basic" user options and use inheritance to factor out any
"duplicate" options that have the same default value of 42 or
nil, would you?

You would not argue that we should have only one primeval user
option with a default value of 42, and inherit from it for
wildly different options with different use cases (meanings),
so that someone who customizes the "basic" option to change
the value 42 to 24 ends up changing lots and lots of
inheriting options. =A0Would you? =A0How are faces different in
this regard?

Now this is just plain silly and a very poor analogy = . Faces have a lot more in common and a much closer relationship than al th= e user variables. Faces work together to present a theme, they are not inde= pendent as you imply. Faces that don't set an attribute inherit the val= ue from the default face. You configure faces based on an overall theme and= how they interact with each other and faces all have the same format/attri= butes. To suggest they are as indpendent from each other as other user vari= ables is nonsense.=A0

Ignoring how poor the analogy is, the fact is that NOBO= DY has suggested that all faces need to inherit form a base set. This was n= ever proposed. =A0

T> It seems now that every new package is adding its own face
T> definitions

Good. =A0That should probably happen more than it does. ;-)

If reasonable, related faces exist on which to base the new
face definitions, then by all means inheritance might well be
called for. =A0But a new package should _not_ avoid adding its
own face definitions, whether they are defined using
inheritance or not (i.e., pointer or copy).

Disagree. A package should only define its own face w= hen either there is no existing face which adequately represents the meaini= ng of the face OR there is a strong expectation that the user may want to c= ustomize the face independently. There is a definite danger of having too m= any faces and ending up with a consistency problem. Consider the situation = where every programming mode defined its own face to represent comments and= did not use inheritance. What benefit does that give us? Very little. What= harm - potentially a lot as now you have to configure multiple faces to ju= st get code comments to have a consistent appearance.=A0

A mode should NOT create a new face just for the sake o= f it and if it does create a new face, either fully define the face or inhe= rit from a fully defined face - its that simple. =A0If you want to restrict= inheritance to only use faces with the same semantic meaning, fine. I thin= k it is over restrictive, but care less about that than about having a solu= tion that would ensure faces are fully defined and providing a way to achie= ve this that will facilitate developers doing the right thing.=A0

On the contrary. =A0What should be avoided is reusing some face
that makes no sense in the current context. =A0What is the
_practical_ criterion? =A0Whether or not customizing the face
wrt its original context/purpose will have a negative effect
in the new context. =A0If not, then go for it (reuse/inherit).

Agreed - pretty much my position. =A0

T> and many of them are poorly defined. =A0It now takes much
T> longer for me to establish a consistent set of faces.

Bad - agreed. =A0But not a necessary consequence of having many
faces. =A0More likely a consequence of poor default definitions
(as you mentioned).

Yes, but encouraging the addition of new faces withou= t good justification is bad - it is the other extreme. Too often, I use app= lications that don't have enough faces and I cannot change the appearan= ce of some object that I would like to somehow stand-out. However, the othe= r extreme is a proliferation of unnecessary faces that just make customizat= ion and theming more difficult.=A0

T> If we required face definitions to either be fully defined or
T> inherited from a base set that are fully defined, we would
T> likely give a much better default experience to end users.

Full face definitions are good, yes.
That is independent of the question of inheritance.

Well... indiscrimately imposing inheritance (from fully defined
faces) can ensure full definitions. =A0But it has a cost: it can
also introduce unnecessary and unwanted dependencies with
negative consequences.

Well, either direction has a cost. There is no avoidi= ng that. My view is to find the point at which we get the best cost/benefit= . Inheritance provides a way to reduce the burden on developers to fullly d= efine faces and has the potential to reduce the number of faces that are on= ly partially defined and work only in limited configurations/environments. = Whether we have strict or less rigid restrictions on inheritance will affec= t how easily inheritance can be used in this manner. Strict inheritance wil= l give a consistent semantic meaning in inheritance chains and potentially = more predictable resutls when modifying base faces. Less rigid inheritance = would allow inheritance to be used instead of fully face definitions in mor= e situations. If badly applied it does have the potential to cause confusio= n, but this could be mitigated with good guidelines. New faces should only = be introduced when there is a demonstrated case and not just as an automati= c default action.=A0

T> Using inheritance also means that when we find a face
T> definition which is poor for a particular environment, we can
T> refine that base definition rather than having to find all
T> similarly poor definitions and updating them individually.

Yes and no. =A0"Fixing" it for one environment might do exactly the wrong thing for another context, e.g. for one of its
descendents. =A0Inheritance needs to be used carefully, based on
intended use/meaning of the faces involved.

Maybe, though I don't think it is as bad in pract= ice as you assume. Existing modes have been using inheritance in a non-sema= ntic fashion since at least emacs 21 and this doesn't seem to have caus= e any major issues.

T> Using inheritance means that it is easier to make broad
T> changes to face definitions, reducing the time spent in
T> customize and lets you then tweak those specific faces which
T> don't quite work.
T>
T> So, using your example, if someone changed the base face that
T> dired+ uses, either they will find the result in dired+
T> acceptable or they can then tweak that face further. =A0The
T> alternative is that it would be necessary to customize both
T> faces, even when you are going to set them to the same value.

Maybe, maybe not. =A0Depends what kind of change you want/need.

It's true that if you want to change all occurrences of red
foreground to blue then more customization would be involved
without inheritance. =A0Maybe we could find a way to make such
changes easier - I don't have a problem with that.

Maybe this could be an alternative. Frequently, you d= o need to change colours 'across the board' - often because the fac= es are not fully defined and you have a different background to the assumed= default and need to make the change to make the face more readable. So, pe= rhaps this would fix the symptom. However, it does not address the basic pr= oblem, which is faces that are not fully defined.

But we should not be using _inheritance_ for that (in
general). =A0A Dired face should either not inherit or it should
inherit from a related face, not just some face whose _default
appearance_ looks good for Dired. =A0It makes no sense to base a
Dired face on a font-lock face, for instance.

So you would argue that the existing dired face defin= itions are wrong. However, they ahve been like that for quite some time and= it appears to work.
=A0
Just because you might want some Dired face to have a red
foreground by default is no reason to go looking for a face
with a red foreground to inherit from. =A0Look instead for a
face with a related use/meaning. =A0If you find none, then do
not use inheritance here. =A0That's the guideline I'd suggest.

I emphasize the use/meaning of a given face: what it is for,
what it represents, what it does. =A0I think you are emphasizing
its default appearance - attribute values (color etc.). =A0To
me, a face or a variable `foo' is mainly about its use, not
its value.

No, I'm not focused on its appearance. The differ= ence is that while I agree you should select the face that has a similar se= mantic meaning if one exists, I have no issue with using one that does not = provided it does not cause confusion within the mode it is used in. I would= cite dired as an example where this has been done successfully.
=A0
If the opposite were true, then we would name faces and
variables after their default values, not after their uses.
Yes, I've seen some Lisp code with face names like
`underlined-bold-red-foreground-on-gray-background'.
(Mea culpa: I even wrote such code at one point.)

And there's not necessarily anything wrong with that; for some
contexts it might make sense. =A0But in that case it makes more
sense for the "face" to be a constant, not customizable. =A0It would be perverse to customize a face named `red-foreground'
to have a green foreground.
=A0
(And in general it is more likely for single attributes to be
reuse candidates than it is for combinations of attributes.)

T> The reality is that there are a limited set of good faces and
T> you will usually end up with the same face definition being
T> used in multiple roles. =A0Frequently, those roles have nothing
T> to do with each other. =A0This doesn't matter as the contexts
T> are completely different. =A0From an end user perspective, it is
T> irrelevant that compiler messages inherit from
T> font-lock-string - all the end user sees is that compiler
T> messages use a default face that is green, which may be
T> exactly the same as strings in their code, but so what.

I strongly disagree here.

If the roles/meanings/use are unrelated, then inheritance is
usually inappropriate. =A0It _does_ matter whether a
compiler-messages face inherits from `font-lock-string-face' -
_if_ someone customizes that parent face.

But does it really matter. I change font-lock-comment= -face to orange because that is easier to read or more aesthetic given my d= efault background colour. As a result, compiler-message face also changes t= o orange. Isn't it just as likely that if pink was not acceptable for c= omments in code that pink is also unacceptable for messages in compile-mode= ? Sure, maybe I might decide I'd still like pink for those messages and= I can override the inheritance, but in practice, I think in most cases, th= is would be fine and has been my experience with the mdoes that do use inhe= ritance in such a manner.

Of course, if there is a base face with a more closely = fitting semantic meaning, it should be used in preference and you would avo= id using faces like link or button that have very precise meanings that cou= ld cause confusion within the mode - especially if that mode supports links= or buttons.=A0

If we defined a compiler-messages face to inherit from
`font-lock-string-face' _only_ because we liked the default
foreground choice of `LightSalmon', that would be misguided,
IMO.

Perhaps, if that was the only motivation. However, if= you choose that font-lock face because you want to use inheritance rather = than spend time fully defining compiler-message face and if the font-lock f= ace is fully defined, then it may be a valid choice.
=A0
If there is no existing face that is related in terms of
use/meaning, then the compiler-messages face should not
inherit; it should just be defined with a default foreground
of `LightSalmon'. =A0That kind of duplication is not a curse but
a blessing.

NO, That would be a partial= font definition. If I happen to use a background of LightSalmon, that face= is now unreadable. Either fully define the face or inherit.=A0

Then a user can customize either the compiler-messages face or
`font-lock-string-face' without affecting the other. =A0And that
makes sense because (by hypothesis) the two are unrelated.

Even if compiler-message face uses inheritance form an u= nrelated face, you still have the option of customizing it to something dif= ferent or even removing the inheritance if so desired.=A0

Tim

--001485ebea3860a771049ba6ddf7--