;; Jens Axel S\x{00F8}gaard writes:
;;
;; >> There are several noteworthy solutions, but the
;; >> shortest is from Ben Goetter:
;;
;; (define (shuffle l)
;; (map cdr
;; (sort (lambda (x y) (< (car x) (car y)))
;; (map (lambda (x) (cons (random 1.0) x)) l))))
;; gauche
(use srfi-1)
(define (random _)
(sys-random))
(define (shuffle l)
(map cdr
(sort (map (lambda (x) (cons (random 1.0) x)) l)
(lambda (x y) (< (car x) (car y))))))
(print (shuffle (iota 20)))
;;
;; It's short and sweet and purely functional (modulo the side effect in
;; random). It's also O(n log n) where the usual swapping algorithm is
;; linear time, and it assumes the programmer remembers which way sort
;; wants its arguments, which I didn't. Also, if one kept the playing
;; list in a vector, the usual swapping would not need any extra space.
;;
;; Hm. Petite Chez seems to have its sort that way, and it seems stable,
;; too. Is that portable nowadays?
;;
;; ----
;; This also works on Chicken, with the order of the argument in
;; sort exchanged and a minor variation in random. I would call it a
;; Schwartzian transform or a DSU (decorate-sort-undecorate) pattern. It
;; is not a translation of Python's shuffle, but does the same job, so
;; I will accept it as a solution of my problem ;)
;;
;; --------------------
;; Often let* is used in the situation where a series of
;; assignments are used in an imperative language. Thus heavily use
;; of let* is normally a sign of problems, but the construct is quite
;; handy when it is needed.
;;
;; One difference between let and let* is that you can "update" several
;; variables at a time based on several old values using let where as
;; let* updates shadows the old value.
;;
;; (let ([x 0]
;; [y 0])
;; (let ([x (+ x 1)]
;; [y (+ x 1)])
;; (list x y))
;;
;; => (list 1 1)
;;
;; and
;;
;; (let ([x 0]
;; [y 0])
;; (let* ([x (+ x 1)]
;; [y (+ x 1)])
;; (list x y))
;;
;; => (list 1 2)
;;
;; Perhaps someone more imaginative than me can come up with a
;; real life example.