# 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 non-ASCII

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 user-defined 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 ,. # on-keys. ~~

;; wordcount, (same page)

;; WS =: ' ',TAB,LF

;; wc3 =: (# , (*. -.@(|.!.0))@(e.&WS) , +/@(LF&=))@ReadFile

;; proposal:

whitespace .= " \t\n"

word-count =. (# , (and not o (shift :with 0)) o (in & whitespace) ,

+/ o ("\n" & =)) o read-file

;; Hamming code

;; standard J:

;; ham=: 3 : 'y{.(2 3 5&([: /:~@~.@, ] , */))^:((+:y)>:#)^:_] 1'

;; proposal:

hamming .=. (y -> y take

(2 3 5 & (cp sort-up 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

;; Gram-Schmidt in standard J, see

;; http://www.nabble.com/reduce-fold-in-J-as-an-adverb-or-conjuction-to13844580s24193.html#a13844580

;; mp=:+/.*

;; norm=:%%:@mp~

;; orth=:]-+/@(mp*[)

;; GS1=:,:@norm@{.([,norm@orth)R.}.

;; Gram-Schmidt:

renorm =. 1% sqrt o **~~

orth =. y_ - +/ o (** * x_) ;; x = vectors so far, y = new vector

gram-schmidt .=. ,: o renorm o head (x_ , renorm o orth) reduce. behead

pi-approx .= 6 * (2 ^ 8) * (sqrt (%2 1- sqrt (1- ^2 x))) .^ 8 (0.5)

mean .=. +/ % #

dev .=. (- mean) '1

sum-sqr-dev .=. +/ o ^2 o dev

variance .=. (sum-sqr-dev % -- o #) '1

std-dev .=. sqrt o variance

sum-cross-prods .=. (** ~ ^T) o dev

covariance .=. sum-cross-prods % -- o #

correlation .=. covariance % */ o std-dev

harmonic-mean .=. mean .u. 1%

geometric-mean .=. mean .u. ln

geometric-mean .=. */ root ~ #

weighted-sum .=. * % +/ o. y_

.... and so on.

Best regards

Bruno Daniel

.

**References**:**array processing in Lisp***From:*metaperl.com

- 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):