#1228 featurep(false, 'complex)

Harald Geyer

Currently featurep(false, 'complex) returns true.
This is not what I would expect.

After looking at the definition of featurep() it
becomes obvious, that it returns always true for
complex. This test is pointless.

I'm not sure in which cases besides true/false
this test should be negative. I'm not sure in
which cases this test is useful at all.
Perhaps this should just be removed from


  • Robert Dodier
    Robert Dodier

    Logged In: YES
    Originator: NO

    For the record, here is a message I posted to the mailing list:

    On 7/14/07, Harald Geyer <Harald.Geyer@gmx.at> wrote:

    > I have thought about bug 1742275 "featurep(false, 'complex) -> true"
    > a bit and i basically see two possible solutions:

    Well, featurep has evolved toward evaluating predicates of the
    form is(x in S) where S is a set; I think featurep recognizes
    integers, rationals, reals, complex, and pure imaginary, maybe
    some others. That is a useful idea, but at present featurep is not
    a very good implementation of it.

    In that spirit, feature(false, 'complex) should return false
    because false is a Boolean literal and therefore demonstrably
    not an element of set of complex numbers.
    Likewise featurep(true, 'complex) and featurep("foo", 'complex)
    should return false.

    featurep(A, 'complex) where A is a matrix, list, or set should
    return false (or maybe featurep should distribute over aggregate
    objects; dunno if I'm for or against that).

    > a)
    > Just remove the condition ((eq ind '$complex) t) from $featurep.
    > With this we would get
    > declare(z, 'complex); featurep(z, 'complex); -> true
    > because of the generic condition for symbol properties. But
    > featurep(1+%i, 'complex); -> false

    Hmm. I guess I don't like this one.

    > b)
    > Change the condition to
    > ((eq ind '$complex)
    > (let ((ris (trisplit e)))
    > (not (or (zerop1 (car ris)) (zerop1 (cdr ris))))))
    > which is equivalent to realpart(expr) != 0 and imagpart(expr) != 0

    At present featurep seems to embody the notion that
    featurep(X, S) => featurep(X, T) when S is a subset of T.
    That makes sense to me and I don't want to change it at
    the moment. Requiring that realpart and imagpart be nonzero
    makes featurep true isn't consistent with that.
    So I guess I don't like this one either.

    As mentioned by others, featurep has accumulated some baggage
    over the years and probably we're best off separating the
    stuff which has only to do with declared properties of symbols,
    and potentially-inferred properties of symbols or expressions.

    For the moment I think changing featurep(foo, complex) to
    return false when foo is a Boolean or string literal is a step forward.

    In the long run, I would like to see declarations expanded to
    expressions as well as symbols, which would allow stuff like:

    declare (x in Z);
    declare (matrixp (y));
    declare (z in R and z > 0);

    I'd like to merge the declare and assume stuff --- these could
    equally well be assume(x in Z), assume(matrixp(y)), etc.

    For the moment this is just a daydream.


  • Dieter Kaiser
    Dieter Kaiser

    featurep has changed with revixion 1.57 of compar.lisp.
    The example of this bug report is now:

    (%i28) featurep(false,complex);
    (%o28) false

    There are more problems and open bugs with featurep, but this example is fixed.
    Closing this bug report as fixed.
    Dieter Kaiser

  • Dieter Kaiser
    Dieter Kaiser

    • status: open --> closed