robert-strandh / SICL

A fresh implementation of Common Lisp
Other
1.07k stars 79 forks source link

Add char/= and char-not-equal #222

Closed yitzchak closed 3 years ago

yitzchak commented 3 years ago

Please let me know if there is a better way to do this.

Bike commented 3 years ago

Turning the single-argument case into characterp is probably not correct? Giving char/= a non-character doesn't return false, it's undefined behavior, and in SICL should probably be an error. You could have it expand into (the character ,(car arguments)), maybe, if SICL will treat declarations as assertions.

The compiler macro might be a bad idea in general just because it's a quadratic expansion in code size. But how bad that is depends on how optimization in the rest of SICL works.

yitzchak commented 3 years ago

I copied the characterp from char= and char-equal. Presumably it is supposed to be undefined there also? Don't see any mention in CLHS about what to do for a single argument.

moon-chilled commented 3 years ago

quadratic expansion in code size

Take a look at what I did for the arithmetic version of this: there is a cutoff, past which additional code will not be generated and the task will be punted to the function form. Probably something similar is appropriate here. (It also occurs to me that in the case when the argument list is very large, it would be better to construct a hash table to avoid quadratic work; but.)

Presumably it is supposed to be undefined there also?

Yes.

Don't see any mention in CLHS about what to do for a single argument.

It says:

char/= returns true if all characters are different

'For all'-type statements can be reinterpreted as 'there exists'-type statements when it is convenient to do so. So an alternate reading is as follows:

char/= returns false if any [two distinct] characters are the same

Since there is no possibility of having more than one distinct character in the degenerate case, the false condition can never occur, so the function must return true.