Re: small selector syntax addition

Ian Hickson wrote:
> 
> Ok, in that case I am very confused. Your comment ("in the syntax I
> describe that would match exactly nothing") doesn't seem relevant,
> since I didn't say that my old :matches() was equivalent to your
> :matches(), I said the opposite (your :matches() was equivalent to my
> old :matches() after some algorithmic changes).

Equivalency works both ways, and my comment about matching nothing is
very relevant because it demonstrates how the two differ in the manner
they treat their arguments. But this is getting ridiculous, so onwards...

> > I don't like the use of # because it normally indicates the start
> > of an ID selector. It complicates parsing, both for the computer
> > and the person. I know you don't want to use up more symbols, but
> > I think in this case the benefit outweighs the advantage.
> 
> It doesn't complicate parsing that much. If your sequence of simple
> selectors consists of exactly '#' then you have the special symbol,
> otherwise '#' will mean the start of an ID. Considering how trivial
> that is, I don't think it's worth using a whole other symbol.

That may take care of the computer, but you missed the person. A fluently
literate person doesn't read by scanning each character one by one, like
a computer, but picks up visual patterns in a not-strictly-linear
fashion. # stands out, but it's already associated with IDs. To assign a
completely different significance to the symbol /if/ it's not followed by
a non-combinator would impair human scanning.

  # -> surrounded by space?
        - yes -> subject indicator
        - no -> followed by a-z? 
                 - yes -> ID selector
                 - no -> surrounded by ~, +, or >?
                          - yes -> subject indicator
                          - no -> invalid

vs.

  # -> followed by a-z?
        - yes -> ID selector
        - no -> invalid

  [other symbol] -> subject indicator

Using different symbols is much less complicated and allows one to
pick up either one faster and more easily. If they both referred to
descriptors, it wouldn't be a big deal, but the subject indicator
is pivotal in determining the structure of the selector and thus in
understanding the expression.

> Also, the '#' symbol makes more sense to me... it's like an anonymous
> ID, if you see what I mean. It conveys to me that this is something
> important.

I don't see how an anonymous ID concept would be relevant here. However,
it is true that # stands out from the text around it, since there's so
much black within the character space.

> The '$' symbol doesn't really convey anything to me, except maybe
> something to do with sections (BCPL used $(...$) as section markers,
> and I've been looking at BCPL recently...).

You've done some scripting with Perl, haven't you? Perl uses $ to
indicate the start of a variable name. A variable is very much a
placeholder, is it not? And if you don't like $, then you can use
%, which indicates a variable in many variants of Basic. It does
not matter to me. I picked $ originally because it looked like an
S ([S]ubject). *shrug*

> I just noticed that the '#' character also looks like a placeholder
> more than a '$' character -- compare:
> 
>     A:matches(B + # + C)
> 
>     A:matches(B + $ + C)

It does not look that way to me. This is a very subjective means of
judgement, however.

> >>     If the # form appears anywhere except the end of an argument, then
> >>     the document must be walked looking for matching elements.
> >
> > This sentence is unnecessary.
> 
> Where else does it say how to handle a '#' somewhere other than at the end?

It's implied. Either way, you must walk the document--whether its up or
down the tree or both--so I don't see why having # any place other than
at the end of the argument needs a special explanation.

> >>     The :has() pseudo-class is an alias for :matches(), as follows:
> >>
> >>        :has(FOO1, FOO2, ..., FOOn)
> >>
> >>     ...is exactly equivalent to
> >>
> >>        :matches(# FOO1, # FOO2, ..., # FOOn)
> >>
> >>     ...in terms of interpretation as a selector. Note that the FOOs
> >>     can start with a combinator, if they don't then the descendant
> >>     combinator is assumed. This is the same as the way we have 'odd'
> >>     and 'even' as equivalents to '2n+1' and '2n' for the :nth-child()
> >>     pseudo-classes. It makes the simple case simple.
> >
> > I suggest you get rid of this :has(). It's redundant,
> 
> Selectors have lots of redundancy, that's not a big problem. For example,
> '2n+1' and 'odd' mean the same thing, and ':first-child' is the same as
> ':nth-child(1)'. This is a feature, not a bug. It means that the simplest
> cases are the simplest to write.

So, you're simplifying the syntax by eliminating one character in an
expression, thus rendering it incomplete, but nevermind that because it's
"simpler"? All the other examples you give translate a more abstract,
mathematical expression into English. I fail to see how ~implying~ '#' at
the beginning of a selector makes it simpler or easier to understand.

>  > and starting an argument with a hanging combinator is, to me, far worse
>  > than using a subject indicator in the main selector. A:has( + B) looks
>  > to me very awkward -- it's incomplete -- and reading it doesn't make
>  > much sense, either.
>
> I think it looks better than A:matches(# + B).

I think that how something "looks" is irrelevant to its superiority as
a syntax. If you analyze your sentence there and explain -why- it looks
better, then you'd have an argument.

My reasoning for why it looks -bad- is as follows:
In every programming language I have ever encountered (which, of course,
is not so very many), the argument to a function is always a -complete-
expression--one which evaluates to an actual value, be it a number, or a
string, or an aggregate of data, or a pointer to a memory location. Here,
you are proposing a function which takes an incomplete selector expression
as an argument, and this goes against the grain of my conception of
functional notation.

Now, you can argue that the '#' is implied. Very well. If you are so keen
on implying this vital piece of the expression, why should it not be
implied at the beginning of any :matches() argument that begins with a
combinator instead?

> Also, the most common case of looking for descendant doesn't appear to
> have a hanging combinator:
> 
>     p:has(strong)

Which encourages people to use that instead of p:has(>strong) even when
the child selector would be more appropriate.

Received on Thursday, 16 May 2002 23:39:34 UTC