Discussion:
Translating circular Haskell code to lisp
Add Reply
B. Pym
2024-08-30 17:09:35 UTC
Reply
Permalink
I don't need a general purpose transformation, just some guidelines to
follow when I see code like this.
General guideline: Look for a solution that uses LOOP. ;)
(defun diff3 (list)
(let ((avg (loop for element in list
sum element into sum
count t into length
finally (return (/ sum length)))))
(loop for element in list
collect (- element avg))))
Gauche Scheme

(define (diff3 lst)
(let ((len 0) (sum 0))
(dolist (x lst) (inc! len) (inc! sum x))
(map (cute - <> (/ sum len)) lst)))

(diff3 '(1 2 3 4 5))
===>
(-2 -1 0 1 2)
Kaz Kylheku
2024-08-30 17:32:35 UTC
Reply
Permalink
Post by B. Pym
I don't need a general purpose transformation, just some guidelines to
follow when I see code like this.
General guideline: Look for a solution that uses LOOP. ;)
(defun diff3 (list)
(let ((avg (loop for element in list
sum element into sum
count t into length
finally (return (/ sum length)))))
(loop for element in list
collect (- element avg))))
Gauche Scheme
(define (diff3 lst)
(let ((len 0) (sum 0))
(dolist (x lst) (inc! len) (inc! sum x))
(map (cute - <> (/ sum len)) lst)))
The loop algorithm contains no explicitly visible side effects
whereas yours has ugly variable stepping.

Point-free one-liner:

This is the TXR Lisp interactive listener of TXR 296.
Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
TXR kind of supports IEEE 754.00000000000003 floating-point.
1> [[callf mapcar [chain [callf / sum len] (do op - @@1)] identity] '(1
2 3 4 5)]
(2.0 1.0 0.0 -1.0 -2.0)
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
B. Pym
2024-08-31 20:32:15 UTC
Reply
Permalink
Post by B. Pym
I don't need a general purpose transformation, just some guidelines to
follow when I see code like this.
General guideline: Look for a solution that uses LOOP. ;)
(defun diff3 (list)
(let ((avg (loop for element in list
sum element into sum
count t into length
finally (return (/ sum length)))))
(loop for element in list
collect (- element avg))))
Gauche Scheme
(define (diff3 lst)
(let ((len 0) (sum 0))
(dolist (x lst) (inc! len) (inc! sum x))
(map (cute - <> (/ sum len)) lst)))
(diff3 '(1 2 3 4 5))
===>
(-2 -1 0 1 2)
Since it's "cute" instead of "cut", (/ sum len) is done only once.

"Cute is a variation of cut that evaluates expr-or-slots before
creating the procedure."

Loading...