* generic * and 0 @ 2006-11-29 17:58 SZAVAI Gyula 2006-12-01 19:56 ` Kevin Ryde 0 siblings, 1 reply; 13+ messages in thread From: SZAVAI Gyula @ 2006-11-29 17:58 UTC (permalink / raw) guile-1.8-20061126 (use-modules (oop goops)) (define-class <c> ()) (define-method (* a (b <c>)) #t) (* 0 (make <c>)) ==> 0 --- orig/libguile/numbers.c 2006-11-29 18:09:22.393764800 +0100 +++ mod/libguile/numbers.c 2006-11-29 18:10:22.319934400 +0100 @@ -4416,12 +4416,6 @@ intbig: xx = SCM_I_INUM (x); - switch (xx) - { - case 0: return x; break; - case 1: return y; break; - } - if (SCM_I_INUMP (y)) { long yy = SCM_I_INUM (y); _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-11-29 17:58 generic * and 0 SZAVAI Gyula @ 2006-12-01 19:56 ` Kevin Ryde 2006-12-01 20:22 ` Mikael Djurfeldt 0 siblings, 1 reply; 13+ messages in thread From: Kevin Ryde @ 2006-12-01 19:56 UTC (permalink / raw) Cc: bug-guile SZAVAI Gyula <szgyg@ludens.elte.hu> writes: > > (use-modules (oop goops)) > (define-class <c> ()) > (define-method (* a (b <c>)) #t) > (* 0 (make <c>)) > ==> 0 Thanks, that's a bug. > - switch (xx) > - { > - case 0: return x; break; > - case 1: return y; break; > - } > - Though that's not the fix (it breaks 0 * bignum, and changes 0 * real and complex). _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-01 19:56 ` Kevin Ryde @ 2006-12-01 20:22 ` Mikael Djurfeldt 2006-12-01 21:52 ` Kevin Ryde 0 siblings, 1 reply; 13+ messages in thread From: Mikael Djurfeldt @ 2006-12-01 20:22 UTC (permalink / raw) Cc: bug-guile 2006/12/1, Kevin Ryde <user42@zip.com.au>: > SZAVAI Gyula <szgyg@ludens.elte.hu> writes: > > > > (use-modules (oop goops)) > > (define-class <c> ()) > > (define-method (* a (b <c>)) #t) > > (* 0 (make <c>)) > > ==> 0 > > Thanks, that's a bug. Are you sure? If you want to use an operator which is common for numbers and <c>:s, why don't you want to use a common zero? If you don't, the behavior of the operator will be inconsistent. If one still don't want 0 as zero (in the abstract sense), maybe one should use another name for the operator, or, tie a different generic to the name "*". M _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-01 20:22 ` Mikael Djurfeldt @ 2006-12-01 21:52 ` Kevin Ryde 2006-12-04 0:26 ` Kevin Ryde 0 siblings, 1 reply; 13+ messages in thread From: Kevin Ryde @ 2006-12-01 21:52 UTC (permalink / raw) Cc: bug-guile "Mikael Djurfeldt" <mikael@djurfeldt.com> writes: > > If you want to use an operator which is common for numbers and <c>:s, > why don't you want to use a common zero? If you don't, the behavior > of the operator will be inconsistent. For multiply by 0, I can sort of think of cases when the return type shouldn't be a fixnum. If you're doing 0 times a certain size matrix, then you probably want a matrix full of zeros to come back. Does that sound right? For multiply by 1, I can't actually think of any time you wouldn't want to get back the object unchanged. But perhaps if a class has a notion of multiply, but not "multiply by scalar" then you'd like it to be overridable so it can be banned. _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-01 21:52 ` Kevin Ryde @ 2006-12-04 0:26 ` Kevin Ryde 2006-12-04 18:26 ` Mikael Djurfeldt 0 siblings, 1 reply; 13+ messages in thread From: Kevin Ryde @ 2006-12-04 0:26 UTC (permalink / raw) [-- Attachment #1: Type: text/plain, Size: 348 bytes --] While nosing around nearby stuff I noticed (* 0 1.0) => 0 (* 0 1+1i) => 0 but (* 1.0 0) => 0.0 (* 1+1i 0) => 0.0 which seems a bit inconsistent. R5RS "Exactness" reads like either exact or inexact is permitted, but I imagine it ought to be the same whichever way around you write the args. I think I'll change the latter two to exact 0. [-- Attachment #2: numbers.c.mul-exact0-16.diff --] [-- Type: text/plain, Size: 854 bytes --] --- numbers.c.~1.135.2.22.~ 2006-03-20 08:48:19.000000000 +1100 +++ numbers.c 2006-12-03 15:59:32.000000000 +1100 @@ -3632,6 +3632,9 @@ } } else if (SCM_REALP (x)) { if (SCM_INUMP (y)) { + /* inexact*exact0 is exact 0, per R5RS "Exactness" section */ + if (SCM_EQ_P (y, SCM_INUM0)) + return y; return scm_make_real (SCM_INUM (y) * SCM_REAL_VALUE (x)); } else if (SCM_BIGP (y)) { return scm_make_real (scm_i_big2dbl (y) * SCM_REAL_VALUE (x)); @@ -3645,6 +3648,9 @@ } } else if (SCM_COMPLEXP (x)) { if (SCM_INUMP (y)) { + /* inexact*exact0 is exact 0, per R5RS "Exactness" section */ + if (SCM_EQ_P (y, SCM_INUM0)) + return y; return scm_make_complex (SCM_INUM (y) * SCM_COMPLEX_REAL (x), SCM_INUM (y) * SCM_COMPLEX_IMAG (x)); } else if (SCM_BIGP (y)) { [-- Attachment #3: numbers.c.mul-exact0-18.diff --] [-- Type: text/plain, Size: 1208 bytes --] --- numbers.c.~1.281.2.7.~ 2006-09-27 11:34:11.000000000 +1000 +++ numbers.c 2006-12-03 16:08:52.000000000 +1100 @@ -4492,7 +4492,12 @@ else if (SCM_REALP (x)) { if (SCM_I_INUMP (y)) - return scm_from_double (SCM_I_INUM (y) * SCM_REAL_VALUE (x)); + { + /* inexact*exact0 is exact 0, per R5RS "Exactness" section */ + if (scm_is_eq (y, SCM_INUM0)) + return y; + return scm_from_double (SCM_I_INUM (y) * SCM_REAL_VALUE (x)); + } else if (SCM_BIGP (y)) { double result = mpz_get_d (SCM_I_BIG_MPZ (y)) * SCM_REAL_VALUE (x); @@ -4512,8 +4517,13 @@ else if (SCM_COMPLEXP (x)) { if (SCM_I_INUMP (y)) - return scm_c_make_rectangular (SCM_I_INUM (y) * SCM_COMPLEX_REAL (x), - SCM_I_INUM (y) * SCM_COMPLEX_IMAG (x)); + { + /* inexact*exact0 is exact 0, per R5RS "Exactness" section */ + if (scm_is_eq (y, SCM_INUM0)) + return y; + return scm_c_make_rectangular (SCM_I_INUM (y) * SCM_COMPLEX_REAL (x), + SCM_I_INUM (y) * SCM_COMPLEX_IMAG (x)); + } else if (SCM_BIGP (y)) { double z = mpz_get_d (SCM_I_BIG_MPZ (y)); [-- Attachment #4: Type: text/plain, Size: 137 bytes --] _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-04 0:26 ` Kevin Ryde @ 2006-12-04 18:26 ` Mikael Djurfeldt 2006-12-05 0:00 ` Kevin Ryde 0 siblings, 1 reply; 13+ messages in thread From: Mikael Djurfeldt @ 2006-12-04 18:26 UTC (permalink / raw) Cc: bug-guile 2006/12/4, Kevin Ryde <user42@zip.com.au>: > While nosing around nearby stuff I noticed > > (* 0 1.0) => 0 > (* 0 1+1i) => 0 > but > (* 1.0 0) => 0.0 > (* 1+1i 0) => 0.0 > > which seems a bit inconsistent. Indeed. > R5RS "Exactness" reads like either > exact or inexact is permitted, but I imagine it ought to be the same > whichever way around you write the args. I think I'll change the > latter two to exact 0. Good idea. Because of paragraph 6.2.2, a program cannot expect to get the result 0.0, and it seems like a strength of the implementation to provide the additional piece of information that the result is indeed *exactly* 0. An added bonus is that it doesn't break the idea to have a common abstract zero for the * operator. (Not entirely sure that the common zero is a good idea, but I tend to think so.) _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-04 18:26 ` Mikael Djurfeldt @ 2006-12-05 0:00 ` Kevin Ryde 2006-12-05 14:07 ` SZAVAI Gyula 2006-12-06 15:52 ` Marius Vollmer 0 siblings, 2 replies; 13+ messages in thread From: Kevin Ryde @ 2006-12-05 0:00 UTC (permalink / raw) "Mikael Djurfeldt" <mikael@djurfeldt.com> writes: > > Good idea. I made the change. > Because of paragraph 6.2.2, a program cannot expect to get > the result 0.0, and it seems like a strength of the implementation to > provide the additional piece of information that the result is indeed > *exactly* 0. If you wanted an argument the other way, returning a flonum zero could give negative zero for say "(* 0 -1.0)". But I'd favour exactness, since the result is certainly exactly zero. > (Not entirely sure that the common zero is a good idea, but I tend > to think so.) I suppose it's a question of whether "*" should do that, or leave it up to the application. The only case I can think of where a common zero may not be good is with matrices, where "(* 0 matrix) => matrix" could preserve the dimensions of the input matrix in the output matrix. Those dimensions could be used later "(* matrix matrix)", to signal an error if the dimensions were incompatible. _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-05 0:00 ` Kevin Ryde @ 2006-12-05 14:07 ` SZAVAI Gyula 2006-12-05 15:33 ` Mikael Djurfeldt 2006-12-06 15:52 ` Marius Vollmer 1 sibling, 1 reply; 13+ messages in thread From: SZAVAI Gyula @ 2006-12-05 14:07 UTC (permalink / raw) Kevin Ryde wrote: > "Mikael Djurfeldt" <mikael@djurfeldt.com> writes: > >> (Not entirely sure that the common zero is a good idea, but I tend >> to think so.) >> > > I suppose it's a question of whether "*" should do that, or leave it > up to the application. > I think there are 3 solution: 1, make * really generic (non-associative, no 0, no 1) 2, make * non-generic 3, document this strange behaviour But present undocumented half-genericity is annoying. Thanks s _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-05 14:07 ` SZAVAI Gyula @ 2006-12-05 15:33 ` Mikael Djurfeldt 2006-12-05 15:51 ` Ludovic Courtès 0 siblings, 1 reply; 13+ messages in thread From: Mikael Djurfeldt @ 2006-12-05 15:33 UTC (permalink / raw) Cc: bug-guile 2006/12/5, SZAVAI Gyula <szgyg@ludens.elte.hu>: > Kevin Ryde wrote: > > "Mikael Djurfeldt" <mikael@djurfeldt.com> writes: > > > >> (Not entirely sure that the common zero is a good idea, but I tend > >> to think so.) > >> > > > > I suppose it's a question of whether "*" should do that, or leave it > > up to the application. > > > > I think there are 3 solution: > 1, make * really generic (non-associative, no 0, no 1) In Guile, this might be tricky to do without large damage to performance. > 2, make * non-generic This would make it impossible to extend the arithmetic system with matrices etc. > 3, document this strange behaviour Absolutely. _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-05 15:33 ` Mikael Djurfeldt @ 2006-12-05 15:51 ` Ludovic Courtès 2006-12-05 19:42 ` Mikael Djurfeldt 0 siblings, 1 reply; 13+ messages in thread From: Ludovic Courtès @ 2006-12-05 15:51 UTC (permalink / raw) Cc: bug-guile Hi, "Mikael Djurfeldt" <mikael@djurfeldt.com> writes: > 2006/12/5, SZAVAI Gyula <szgyg@ludens.elte.hu>: >> Kevin Ryde wrote: >> > "Mikael Djurfeldt" <mikael@djurfeldt.com> writes: >> > >> >> (Not entirely sure that the common zero is a good idea, but I tend >> >> to think so.) >> >> >> > >> > I suppose it's a question of whether "*" should do that, or leave it >> > up to the application. >> > >> >> I think there are 3 solution: >> 1, make * really generic (non-associative, no 0, no 1) > > In Guile, this might be tricky to do without large damage to performance. It would be soooo nice if some day we could have a framework to specialize invocations, especially for arithmetic operators (e.g., like what CMUCL and others have)... :-) Thanks, Ludovic. _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-05 15:51 ` Ludovic Courtès @ 2006-12-05 19:42 ` Mikael Djurfeldt 0 siblings, 0 replies; 13+ messages in thread From: Mikael Djurfeldt @ 2006-12-05 19:42 UTC (permalink / raw) [-- Attachment #1: Type: text/plain, Size: 899 bytes --] 2006/12/5, Ludovic Courtès <ludovic.courtes@laas.fr>: > It would be soooo nice if some day we could have a framework to > specialize invocations, especially for arithmetic operators (e.g., like > what CMUCL and others have)... :-) Well, we do have the things call "primitive generics"---i.e. most procedures can behave as generic functions. What is nice about the system is that hanging methods for new classes on, for example, the Guile arithmetic operators doesn't slow them down. I attach a matrix library to this email as an example. (See README.) It seems to compile also under CVS HEAD. However, of course things could be made much better if we could redesign procedure invocation from bottom up, so that all primitive procedures are true generic functions. If so, most argument checking logic which the C code for all Guile primitives start with could be eliminated. [-- Attachment #2: guile-matrix-1.3.0.tar.gz --] [-- Type: application/x-gzip, Size: 432979 bytes --] [-- Attachment #3: Type: text/plain, Size: 137 bytes --] _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-05 0:00 ` Kevin Ryde 2006-12-05 14:07 ` SZAVAI Gyula @ 2006-12-06 15:52 ` Marius Vollmer 2006-12-07 15:28 ` Mikael Djurfeldt 1 sibling, 1 reply; 13+ messages in thread From: Marius Vollmer @ 2006-12-06 15:52 UTC (permalink / raw) Cc: bug-guile Kevin Ryde <user42@zip.com.au> writes: > The only case I can think of where a common zero may not be good is > with matrices, where "(* 0 matrix) => matrix" could preserve the > dimensions of the input matrix in the output matrix. I would have to dig for the specifics (having forgotton most of my math by now), but 'scaling' matrices and 'multiplying' them are actually two different operations. They are unfortunately notated the same. (* scalar matrix) is scaling, and (* matrix matrix) is multiplying. A special case of this is the more familiar vector scaling versus the vector dot product, I think. Thus, it makes sense to me to let the 'unknown' object in a call to an arithmetic operation decide how to interpret it, and not doing any shortcuts. In general, it is not guaranteed that (* 0 something) is even well-defined, it might be an error. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: generic * and 0 2006-12-06 15:52 ` Marius Vollmer @ 2006-12-07 15:28 ` Mikael Djurfeldt 0 siblings, 0 replies; 13+ messages in thread From: Mikael Djurfeldt @ 2006-12-07 15:28 UTC (permalink / raw) Cc: bug-guile, Kevin Ryde 2006/12/6, Marius Vollmer <mvo@zagadka.de>: > Kevin Ryde <user42@zip.com.au> writes: > > > The only case I can think of where a common zero may not be good is > > with matrices, where "(* 0 matrix) => matrix" could preserve the > > dimensions of the input matrix in the output matrix. > > I would have to dig for the specifics (having forgotton most of my > math by now), but 'scaling' matrices and 'multiplying' them are > actually two different operations. They certainly are different operations: (C complex space, M space of matrices) 1. Scaling: C x M --> M 2. Matrix multiplikation: M x M --> M > They are unfortunately notated the same. That they are notated similarly on paper does not necessarily imply that they should be notated the same way in computer code. > (* scalar matrix) is scaling, and (* matrix matrix) is > multiplying. A special case of this is the more familiar vector > scaling versus the vector dot product, I think. It's actually a third operation: 3. Dot product: V x V --> C (V space of vectors) > Thus, it makes sense to me to let the 'unknown' object in a call to an > arithmetic operation decide how to interpret it, and not doing any > shortcuts. > > In general, it is not guaranteed that (* 0 something) is even > well-defined, it might be an error. Yes. And I think you raise another important point: that one might want to use the same generic function to represent different operators. It is probably Right to make it possible for the primitive generic to dispatch on all arguments (that is skipping the 0 and 1 trick which we have inherited from the original SCM code). However, doing this kind of "improvements" in an incremental manner, given the current structure of the Guile evaluator, makes the thing dog slow. Also, if hanging methods on * implies performance penalty for ordinary arithmetic, it leads to strange practise in structuring code. So I would vote "no" for just "fixing" this, and "yes" for a total restructuring of invocation of primitive procedures so that they would be true generic functions. _______________________________________________ Bug-guile mailing list Bug-guile@gnu.org http://lists.gnu.org/mailman/listinfo/bug-guile ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-12-07 15:28 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-11-29 17:58 generic * and 0 SZAVAI Gyula 2006-12-01 19:56 ` Kevin Ryde 2006-12-01 20:22 ` Mikael Djurfeldt 2006-12-01 21:52 ` Kevin Ryde 2006-12-04 0:26 ` Kevin Ryde 2006-12-04 18:26 ` Mikael Djurfeldt 2006-12-05 0:00 ` Kevin Ryde 2006-12-05 14:07 ` SZAVAI Gyula 2006-12-05 15:33 ` Mikael Djurfeldt 2006-12-05 15:51 ` Ludovic Courtès 2006-12-05 19:42 ` Mikael Djurfeldt 2006-12-06 15:52 ` Marius Vollmer 2006-12-07 15:28 ` Mikael Djurfeldt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).