Here's an updated instance of that code -- this time dealing with
subtraction (thanks to Dan Bron).

Note also that perhaps I should instead just define replacement
operators for + - * % but this approach works:

units=:3 :0"0&;:
 assert._1-:nc y ['new unit name must have no other meaning'
 L1=. 'assert.0=#$0+n [''unit exponent must be scalar'''
 L2=. '(;:''',(>y),''');m,&<n'
 (y)=: 2 :(L1;L2)
 i.0 0
)

uni=:1 :0
:
 'xu xv xx'=.x
 'yu yv yx'=.y
 zv=.xv u yv  NB. basic operation
 xb=.xu e.yu  NB. find unit overlap
 select. u`''
   case. +`- do.
       assert. xu -: yu ['units must match'
       assert. xx -: yx ['unit exponents must match'
       zu=. xu
       zx=. xx
   case. *`'' do.
       zu=. ~.xu,yu
       zx=. (xu,yu) +//. xx,yx
   case. %`'' do.
       zu=. ~.xu,yu
       zx=. (xu,yu) -//. xx,yx
   case. do. assert 0['unsuppported operation'
 end.
 (/:~zu);zv ,&< zx/:zu
)

dimensionless=:1 :0
 '';m;i.0
)

raw=: 1 {:: ]

example use:
   units 'm g s' NB. meters grams seconds
   10 m 1 NB. 10 meters
   10 m 1 *uni 10 s _1 NB. meters/second
   10 m 1 *uni 10 s _1 * uni 10 s _1 NB. meters/second^2
   10 m 1 *uni^:3 (1 dimensionless)
   10 m 1 -uni 3 m 1
   raw 10 m 1

I should probably also write a displayform verb, if I knew what
the display should look like.

FYI,

-- 
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to