Re: array processing in Lisp
 From: Bruno Daniel <bruno.daniel@xxxxxxx>
 Date: Tue, 11 Dec 2007 14:33:12 +0100 (CET)
Yes, J improved on the APL syntax issue of using that nonASCII
character set. However, J is still a difficult read for most
programmers for a few reasons:
* ambiguous use of symbols
* use of symbols instead of english for functions
* use of symbols which look very similar, thus forcing a lot of visual
parsing... for instance * versus *. versus *:
Most J fans would prefer symbols to english names for the same reason that
mathematicians and physicists prefer symbols to operators in their formulas:
They can understand an expression at a single glance. Think of Maxwell's
equations or the Schroedinger equation using English words instead of symbols
and you'll see what I mean.
On the other hand I don't think that J really accomplishes this. In order to
be able to read a formula fast, the symbols have to be quite distinct from
each other, avoiding ambiguity at all costs. It is especially problematic that
on fast reading you cannot immediately see whether a verb is used monadically
or dyadically because this depends on its position in a verb train and whether
the whole train is a hook or a fork; the matter is further complicated by
adverbs and conjunctions. Only after knowing for each verb the valence in the
expression (i.e. its being monadic or dyadic) you can understand a J
expression. For a long tacit expression you would have to write the valences
down first and this is not what I consider reading at a single glance.
This can be fixed by learning a lesson from Lisp: If you require the
programmer to separate atoms by spaces from each other (you cannot write (+3a)
in Lisp but you'll have to use (+ 3 a) or (nfx 3 + a) in the infix package
http://www.cliki.net/infix ) , you are free to introduce combinations of
multiple symbols and alphanumeric characters as function names (or verbs,
adverbs and conjunctions in J lingo) names. That's why I propse the following
changes for a future version of J:
* Require the programmer to separate atoms by spaces (of course not after
or before opening and closing parentheses, like in (3 + a) * 4).
* Allow all combinations of printable ASCII characters as symbols, e.g.
2* (for monadic +:), ^2 (for monadic *:), %2 (for monadic :), ++ (for
monadic >:),  (for monadic <:).
* Use these combinations for disambiguating most monads from dyads, e.g.
## for copy and # for tally, ~ for passive, ~~ for reflex, / for insert,
// for table, & for bond, oo for compose,  (for monadic , meaning abs),
 for (dyadic , meaning residue),
and for introducing abbreviations, e.g. int1 for monadic 1 & + @: i.,
** for +/ . *, ^T for monadic transpose,
and common idioms that constitute a notion in themselves, like /\ for
/ \, +/ for + /
* Introduce as a convention that userdefined adverbs carry a dot in the end
of the name and conjunctions in the beginning. Then Emacs and other editors
will be able to display them in different colors (maybe even making the
dot invisible, the same could be done for cap) and it will be easy to read
even very complicated tacit verbs.
* I also don't like using [, {, ", ( unpaired, but that is just a matter of
taste.
Here are some examples:
;; An adverb for a table of the Chebyshev coefficients
;; in standard J (see
;; http://www.jsoftware.com/help/jforc/a_first_look_at_j_programs.htm#_Toc141157970)
;; chebft =: adverb define :
;; f =. u 0.5 * (+/y)  (/y) * 2 o. o. (0.5 + i. x) % x
;; (2 % x) * +/ f * 2 o. o. (0.5 + i. x) *"0 1 (i. x) % x
;; )
;; proposal:
chebftable. .= (f > n ab >
(fvals .= f %2 (+/ ab)  (/ ab) * cos pi* (int.5 n) % n)
((2 % n) * +/ fvals * cos pi* (int.5 n) * '01 (int n) % n))
;; Histogram
;; standard J, see
;; http://www.jsoftware.com/help/jforc/forks_hooks_and_compound_adv.htm#_Toc141158229
;; histogram =: ~. ,. #/.~
;; proposal
histogram =. distinct ,. # onkeys. ~~
;; wordcount, (same page)
;; WS =: ' ',TAB,LF
;; wc3 =: (# , (*. .@(.!.0))@(e.&WS) , +/@(LF&=))@ReadFile
;; proposal:
whitespace .= " \t\n"
wordcount =. (# , (and not o (shift :with 0)) o (in & whitespace) ,
+/ o ("\n" & =)) o readfile
;; Hamming code
;; standard J:
;; ham=: 3 : 'y{.(2 3 5&([: /:~@~.@, ] , */))^:((+:y)>:#)^:_] 1'
;; proposal:
hamming .=. (y > y take
(2 3 5 & (cp sortup o distinct o flatten y_ , *//))
.while ((2* y) >= #) 1)
;; Quicksort
;; Standard J:
;; quicksort=: (($:@(<#[) , (=#[) , $:@(>#[)) ({~ ?@#)) ^: (1<#)
;; proposal:
quicksort .=. ((self o (< ## x_) , (= ## x_) , self o (> ## y_))
(@~ roll o #))
.if (1 < #)
;; Display the Mandelbrot set in ascii characters:
;; standard J:
;; {&'#.' @ (2:<) @ ((+*:)^:400 0:) (18 %~ i:_20) j.~/ 28 %~ _59+i.75
;; proposal:
(c > @ "#." 2 <  (z > c + ^2 z) .^ 400 (0))
(18 %~ int 20) <j ~ // 28 %~ 59 + int 75
;; GramSchmidt in standard J, see
;; http://www.nabble.com/reducefoldinJasanadverborconjuctionto13844580s24193.html#a13844580
;; mp=:+/.*
;; norm=:%%:@mp~
;; orth=:]+/@(mp*[)
;; GS1=:,:@norm@{.([,norm@orth)R.}.
;; GramSchmidt:
renorm =. 1% sqrt o **~~
orth =. y_  +/ o (** * x_) ;; x = vectors so far, y = new vector
gramschmidt .=. ,: o renorm o head (x_ , renorm o orth) reduce. behead
piapprox .= 6 * (2 ^ 8) * (sqrt (%2 1 sqrt (1 ^2 x))) .^ 8 (0.5)
mean .=. +/ % #
dev .=. ( mean) '1
sumsqrdev .=. +/ o ^2 o dev
variance .=. (sumsqrdev %  o #) '1
stddev .=. sqrt o variance
sumcrossprods .=. (** ~ ^T) o dev
covariance .=. sumcrossprods %  o #
correlation .=. covariance % */ o stddev
harmonicmean .=. mean .u. 1%
geometricmean .=. mean .u. ln
geometricmean .=. */ root ~ #
weightedsum .=. * % +/ o. y_
.... and so on.
Best regards
Bruno Daniel
.
 References:
 array processing in Lisp
 From: metaperl.com
 array processing in Lisp
 Prev by Date: Re: CLOS constructors
 Next by Date: Re: CLOS constructors
 Previous by thread: Re: array processing in Lisp
 Next by thread: Solving quantitative problems in LISP
 Index(es):
Relevant Pages
