Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 23 |
Nodes: | 6 (0 / 6) |
Uptime: | 49:51:06 |
Calls: | 583 |
Files: | 1,138 |
Messages: | 111,303 |
Don't know J, but my experience with APL (from the 1970s,
a few years before I started programming in Lisp)
is that it is perfectly readable in the long run.
you are right. You have to learn the meaning of all the single or two
char commands first, but the language itself is much easier than Perl.
Looks like J has a powerful set of commands. Perhaps it could be
translated to Lisp? Of course, this should be done the Lisp-way, which
means using verbose names:
(defun sum (list)
(reduce #'+ list))
(defun seq-eql (element list)
(map 'list #'(lambda (x) (if (eql element x) 1 0)) list))
(defun make-seq (last)
(loop for i from 0 below last collect i))
The translation of this J expression: +/'5'=":i.100 :
(sum (list-eql #\5 (princ-to-string (make-seq 100))))
But it could be done nearly as short as in J:
(defun +/ (list)
(reduce #'+ list))
(defun j= (element list)
(map 'list #'(lambda (x) (if (eql element x) 1 0)) list))
(defun i. (last)
(loop for i from 0 below last collect i))
(defun \"\: (object)
(princ-to-string object))
(sum (list-eql #\5 (princ-to-string (make-seq 100))))
(+/ (j= #\5 (\"\: (i. 100))))
But using \"\: is not very readable. What about writing some macros (and perhaps reader-macros) for embedding J into Lisp? I don't have enough
time now to do it, but looks promising.
[ Earlier in the thread, this was written:
Recently a question was posed in TV about the number of "5"
characters occuring within all integral decimal numerals
between 0 and 100.
]
Frank Buss wrote:
Don't know J, but my experience with APL (from the 1970s,
a few years before I started programming in Lisp)
is that it is perfectly readable in the long run.
you are right. You have to learn the meaning of all the single or two
char commands first, but the language itself is much easier than Perl.
Looks like J has a powerful set of commands. Perhaps it could be
translated to Lisp? Of course, this should be done the Lisp-way, which means using verbose names:
(defun sum (list)
(reduce #'+ list))
(defun seq-eql (element list)
(map 'list #'(lambda (x) (if (eql element x) 1 0)) list))
(defun make-seq (last)
(loop for i from 0 below last collect i))
The translation of this J expression: +/'5'=":i.100 :
I've noticed in the past that moronic users of J
don't have sense enough to separate the tokens
with spaces. Even with spaces the code is ultra
concise. Why try to make it less comprehensible
by removing the spaces?
+/ '5' = ": i. 100
Or is it:
+ / '5' = ": i. 100
(sum (list-eql #\5 (princ-to-string (make-seq 100))))
But it could be done nearly as short as in J:
(defun +/ (list)
(reduce #'+ list))
(defun j= (element list)
(map 'list #'(lambda (x) (if (eql element x) 1 0)) list))
(defun i. (last)
(loop for i from 0 below last collect i))
(defun \"\: (object)
(princ-to-string object))
(sum (list-eql #\5 (princ-to-string (make-seq 100))))
(+/ (j= #\5 (\"\: (i. 100))))
But using \"\: is not very readable. What about writing some macros (and perhaps reader-macros) for embedding J into Lisp? I don't have enough
time now to do it, but looks promising.
Interesting.
Testing:
* (i. 9)
(0 1 2 3 4 5 6 7 8)
* (\"\: (i. 9))
"(0 1 2 3 4 5 6 7 8)"
* (j= #\5 (\"\: (i. 9)))
(0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0)
[ There's a 0 or 1 for each character in the string. ]
* (+/ (j= #\5 (\"\: (i. 9))))
1
* (+/ (j= #\5 (\"\: (i. 100))))
20
Gauche Scheme
(use gauche.sequence) ; So we can map over a string.
(define i. iota)
(define q: x->string)
(define (== obj seq) (map (lambda(x) (if (equal? obj x) 1 0)) seq))
(define (// func seq) (reduce func #f seq))
(// + (== #\5 (q: (i. 100))))
===>
20
(define (J . args)
(let ((args (reverse args)))
(let go ((xs (cdr args)) (result (car args)))
(if (null? xs)
result
(let ((func (car xs)))
(if (equal? 2 (arity func))
(go (cddr xs) (func (cadr xs) result))
(go (cdr xs) (func result))))))))
(J + // #\5 == q: i. 100)
===>
20
100 iota x->string (== #\5) (// +))