On 6/23/11 Jun 23 -7:05 AM, Boris Smilga wrote:
On Thu, Jun 23, 2011 at 1:04 AM, Robert Goldman rpgoldman@sift.info wrote:
Would it be better to rewrite this from shortest to longest as:
(defun write-json-number (nr stream) "Write the JSON representation of the number NR to STREAM." (typecase nr (integer (format stream "~d" nr)) (real (let ((*read-default-float-format* (etypecase nr (short-float 'short-float) (single-float 'single-float) (double-float 'double-float) (long-float 'long-float)))) (format stream "~f" nr))) (t (unencodable-value-error nr 'write-json-number))))
What about rationals? They too are a subtype of REAL, but your etypecase doesn't take them into account.
Should we check for rationals before we check for reals (i.e., check for integer, rational, real, and then have the error case)? And presumably we should print rationals as if they are floats, correct?
So we would have:
(defun write-json-number (nr stream) "Write the JSON representation of the number NR to STREAM." (typecase nr (integer (format stream "~d" nr)) (rational (format stream "~f" nr)) (real (let ((*read-default-float-format* (etypecase nr (short-float 'short-float) (single-float 'single-float) (double-float 'double-float) (long-float 'long-float)))) (format stream "~f" nr))) (t (unencodable-value-error nr 'write-json-number))))
This still yields warnings on Clozure, because SHORT-FLOAT == SINGLE-FLOAT and DOUBLE-FLOAT == LONG-FLOAT (IIUC), but I think that's implementation-dependent, so we can't do away with the intermediates in general, can we?
Not sure how to muffle these warnings, or even if it's desirable, since the Clozure implementers might split apart single and short and double and long at some point, right?
In principle, yes (although in practive such design choices tend to be very stable, undergoing changes only when radically different hardware architectures become available). If these warnings bother you so much, you might just use #-CCL et al. to exclude the TYPECASE clauses that cause them.
I think in principle we should try to detect the relationship between the different float subtypes. Presumably we can do this using MOST-POSITIVE-SHORT-FLOAT, MOST-POSITIVE-SINGLE-FLOAT, etc.., etc., etc., and that would be portable... If I get a chance, I will try to do that: looks like it will be a little cumbersome.
best, r