Roger Hui <[EMAIL PROTECTED]> wrote: > _ 0 0 as the result of 0 100 100#:_ is hard to justify, > as is x|_ giving 0 for nonzero x .
J defines _ as an integer (since _ = <._). In fact, it is defined to evenly divide all integers, since _%d is _ (and hence an integer) for all finite integers d. Thus, conceptually, _ = */i._ So, for consistency, x|_ should always give 0 for any integer x. Similarly, for rationals _%(p%q) is (q*_)%p which is also _, so x|_ should be 0 for rationals as well. The case for irrationals is not as clear-cut, but J treats _%d as _ for all finite d (and besides, irrational reals are just approximated by rationals p*2^q for integer p and q). Also, multiplying _ by irrationals doesn't change its "integerness" (_p1 and _x1 are both _). (Curiously though, 1p_ and 1x_ are 0 even though (o.1)^_ and ^_ are both _) Thus, x|_ should yield 0 for all finite x. (since _|y is y for all finite y, it is unclear what _|_ should be). > Using _ as a date or day number forces the entire > argument or result array from integer to floating point. > Some consequences: > - doubles the space consumption > - comparisons take longer > - important computations such as i. and e. take longer The nice thing about using _ or _. in data is that those values are "sticky" - any calculations you perform on them that doesn't totally eradicate them (like 0*_) preserves them. So, an array that has _ as a date, when used in calculations will always preserve the _ conspicuously in the result. In contrast, using large numbers makes them vulnerable to calculations. Granted, a date of 2e9 is less likely to run into a Y2K problem as 99, it's a lot easier to hide such values (for example, with >.10^.(date-today) to get "order of magnitude of how long we have to wait", would return 9, something much less likely to look like "undefined" J also doesn't seem to have any problem using _ in other integer contexts such as verb rank, take-entire-axis, or even using (complex) gaussian integers for Copy and print precision. (Granted, such values are usually atoms or lists, so the performance impact would be lower). Still, I imagine the performance penalty of passing (floating) _ to #: would be much lower than using integers, but making #: rank-0 and using adverse on every atom. The same kind of performance hit occurs anywhere else where user code has to work around unwanted interpreter defaults, like value-safe arithmetic: vsp1 =: + :: (_."_)"0 vsp2 =: +`(_."_)@.(+.&isnan)"0 vst2 =: *`(_."_)@.(+.&isnan)`0:@.(+.&(0&=))"0 NB. Since 0 = _.*0 = 0*_. vsd2 =: %`(_."_)@.(+.&isnan)`0:@.((0=[)+._=|])"0 NB. Since 0 = _.%_ = 0%_. I wonder how much pre-6.02 code will have to be changed use such workarounds to deal with the new NaN behavior (or worse, how long it will take to find all the places where NaN errors might conceivably cause previously-working code to break, but only on rare occasions)? -- Mark D. Niemiec <[EMAIL PROTECTED]> ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
