Congratulations on extempore v10.1

44 views
Skip to first unread message

George

unread,
Jun 29, 2026, 2:17:39 AMJun 29
to Extempore
Congratulations Ben and Minoru
I have been on the sidelines since v0.9.3 watching the ‘duelling banjos’  as you worked through changes to extempore define-macro  and other code.

I have just successfully started v0.10.1 and pleased to find that code like:
(random (cons 0.2  'node1) (cons 0.3  'node2) (cons 0.5  'node3))
seems to work as before.
I note your detailed record of changes you have made in the updated Changelog.md:
https://github.com/digego/extempore/blob/eaf6f9afc6cc8a01636f0cc76ffa5be7dc253954/CHANGELOG.md
I see that I will have to go through some of my own to change:
imp_rand* to xtc_rand*

Understanding all your changes is a bit beyond me but it is obvious you have put in many hours of expert  work.
It seems to me that by your extraordinary efforts you have rescued extempore from a limited future confined to older operating systems.

I’m sure I am not the only one thanking you for it.

Best wishes, thanks and regards
George

Ben Swift

unread,
Jun 29, 2026, 8:05:47 PMJun 29
to 'George' via Extempore
Thanks George - Claude deserves a bit of credit as well :)

Ben

On Sun, 28 Jun 2026 at 11:17 PM +1000, 'George' via Extempore wrote:
>Congratulations Ben and Minoru
>I have been on the sidelines since v0.9.3 watching the ‘duelling banjos’
> as you worked through changes to extempore define-macro and other code.
>
>I have just successfully started v0.10.1 and pleased to find that code like:
>*(random (cons 0.2 'node1) (cons 0.3 'node2) (cons 0.5 'node3))*
>seems to work as before.
>I note your detailed record of changes you have made in the updated
>Changelog.md:
>*https://github.com/digego/extempore/blob/eaf6f9afc6cc8a01636f0cc76ffa5be7dc253954/CHANGELOG.md*
>I see that I will have to go through some of my own to change:
>imp_rand* to xtc_rand*
>
>Understanding all your changes is a bit beyond me but it is obvious you
>have put in many hours of expert work.
>It seems to me that by your extraordinary efforts you have rescued
>extempore from a limited future confined to older operating systems.
>
>I’m sure I am not the only one thanking you for it.
>
>Best wishes, thanks and regards
>George
>
>--
>You received this message because you are subscribed to the Google Groups "Extempore" group.
>To unsubscribe from this group and stop receiving emails from it, send an email to extemporelan...@googlegroups.com.
>To view this discussion visit https://groups.google.com/d/msgid/extemporelang/e9f76965-94a2-40e9-89fe-97df71df3cc6n%40googlegroups.com.


--

Cheers,
Ben

Minoru

unread,
Jun 29, 2026, 10:37:03 PMJun 29
to Extempore

Hi George,

Thanks !
You wrote what I was thinking !
I'm always amazed at Ben's so quick and correct answer/help and work, too !

2026年6月30日火曜日 9:05:47 UTC+9 ben:

Minoru

unread,
Jun 30, 2026, 2:26:34 AMJun 30
to Extempore

Hi George,

By the way, you seem to need weighted randomization func, and I have one of it, it's very easy to weight each value.
I wrote this code by my self though I forgot where I found this underlying argorythm, I made it in 2017.
This function doesn't require the sum of probability values to be 100 or 1.0 !
It is very intuitive to use, especially, it's very conveinient and prctical in live coding music.

(define w-rnd
  (lambda (lis)
    (let ((sum-w (apply + (map (lambda (x) (cadr x))
                               lis))))
      (let loop ((a-lis lis)
                 (rd (random sum-w))) ; rd is from 0 to (sum-w - 1), this is point !
        (if (< rd (cadar a-lis))      ; (cadar a-lis) is weight number of target
            (caar a-lis)              ; (caar a-lis) is target that has above weighted number
            (loop (cdr a-lis) (- rd (cadar a-lis)))))))) ; random number minus weighted number


(w-rnd '((a 5)(b 1) )) ; -> a, a, b, a, a, a, a, b,  ....

;; test function for doing w-rnd many times
(define my-test
  (lambda (arg1 n-times)
    (let ((ans '()))
      (dotimes (i n-times)
        (set! ans (cons (eval arg1) ans)))
      (cl:sort (my-count ans '() '())
               (lambda (x y) (string<? (atom->string (car x)) (atom->string (car y)))))))  )

;; my-test calls my-count
(define my-count
  (lambda (lis anslis sub)
    (cond ((null? lis) anslis)
          ((set! sub (assoc (car lis) anslis))
           (my-count (cdr lis)
                     (cons (list (car sub) (+ (cadr sub) 1))
                           (remove sub anslis))
                     '()))
          (else (my-count (cdr lis)
                          (cons (list (car lis) 1) anslis)
                          '())))))

(my-count '(a a b a b c) '() '())
;; -> ((c 1) (b 2) (a 3))


;; w-rnd tests
(my-test '(w-rnd '((a 10) (b 100) (c 2) (d 1) ))  1000) ;1000times, use 5000 if you want.
;; ((a 76) (b 906) (c 10) (d 8)),  ((a 80) (b 890) (c 20) (d 10)), ....

(my-test '(w-rnd '((a 10) (b 20) (c 70) ))  1000)
;; ((a 103) (b 198) (c 699)),  ((a 105) (b 197) (c 698))

;; random tests
(my-test  '(random '(.1 . a) '(.2 .  b) '(.7 . c))  1000)
;; ((a 101) (b 204) (c 695)), ((a 106) (b 172) (c 722)) ....


(my-test '(w-rnd '((a 10) (b 20) (c 70) (d 20)))  1000)
;; ((a 85) (b 188) (c 556) (d 171)), ((a 96) (b 165) (c 582) (d 157)) ...

(my-test  '(random '(.1 . a) '(.2 .  b) '(.7 . c) '(.2 . d))  1000)
;; ((a 107) (b 205) (c 688)), ((a 111) (b 200) (c 689))
;; there is no 'd', maybe due to over 1.0


(my-test  '(random '(.6 . a) '(.4 .  b) '(.7 . c) '(.2 . d))  1000)
;; ((a 602) (b 398))
;; there is no 'c' nor 'd',  maybe due to over 1.0

(my-test '(w-rnd '((a 6) (b 4) (c 7) (d 2)))  1000)
;; ((a 294) (b 222) (c 364) (d 120))

(my-test  '(random '(.1 . a) '(.2 .  b) '(.3 . c) )  1000)
;; error
(random '(.1 . a) '(.2 .  b) '(.3 . c) )
;; c, b, a or error, maybe due to under 1.0

(my-test '(w-rnd '((a 1) (b 2) (c 3) ))  1000)
;; ((a 148) (b 351) (c 501)), ((a 170) (b 333) (c 497))

;; random calls weighted-selection, so do it, too ...
(my-test '(weighted-selection '(.1 . a) '(.2 . b) '(.7 . c)) 1000)
;; ((a 110) (b 192) (c 698))

(my-test '(weighted-selection '(.1 . a) '(.2 . b) '(.3 . c)) 1000)
;; error
(my-test '(weighted-selection '(.1 . a) '(.2 . b) '(.3 . c)) 1)
;; ((c 1)), ((a 1)), ((b 1)) or error

(weighted-selection '(.1 . a) '(.2 . b) '(.3 . c))
;; c, a, b or error

(my-test '(weighted-selection '(.6 . a) '(.5 .  b) '(.7 . c) '(.2 . d))  1000)
;; ((a 592) (b 408)), ((a 595) (b 405)), ((a 620) (b 380))
;;   looks like 6:4 of probability, not 6:5, maybe due to over 1.0  ....
;; no c nor d

(my-test '(w-rnd '((a 6) (b 5) (c 7) (d 2)))  1000)
;; ((a 266) (b 260) (c 374) (d 100)), ((a 295) (b 248) (c 362) (d 95))


I think this w-rnd is good enough for my purposes ...
Please feel free to use this w-rnd if you like.


2026年6月30日火曜日 11:37:03 UTC+9 Minoru:

George

unread,
Jun 30, 2026, 7:45:46 PMJun 30
to Extempore
Thanks for that Minoru
Your w-rmd looks interesting ... but something wrong with my copy of my-test ... maybe misplaced parenthesis which I couldn't figure.

By the way about a year ago I had a question on Stackoverflow about extempore's random and received an excellent answer.
Check it out:
Keep well
George

Minoru

unread,
Jun 30, 2026, 10:43:48 PMJun 30
to Extempore
Hi George,

Thanks for your trial.

I copied all of my posting functions and examples from the google group page, then all worked well without any troubles.

Hope it goes well for you too !

2026年7月1日水曜日 8:45:46 UTC+9 George:

George

unread,
Jul 4, 2026, 6:42:41 PMJul 4
to Extempore
It works now Minoru
A simple copy & paste is ok for for all your code except for the 'my-test' !
After fiddling with the final two parentheses it was fine.

I notice that you have to be careful about sum-of-probabilities == 1.0 in examples like:
(my-test '(random '(.1 . a) '(.2 . b) '(.3 . c) ) 1000)

which is much like the 'be-careful' with the extempore version I mentioned above:
(random (cons 0.2  'node1) (cons 0.3  'node2) (cons 0.5  'node3))

Regards
George

Minoru

unread,
Jul 4, 2026, 11:01:29 PMJul 4
to Extempore
Hi Geoge,


> I notice that you have to be careful about sum-of-probabilities == 1.0 in examples like:
> (my-test  '(random '(.1 . a) '(.2 .  b) '(.3 . c) )  1000)

Yes I know it,

(random '(.1 . a) '(.2 .  b) '(.3 . c)) ; should be
(random '(1/6 . a) '(2/6 .  b) '(3/6 . c))

a:b:c=1:2:3===> should be 1/6:2/6:3/6, because the sum should be 1.0

(my-test '(random '(1/6 . a) '(2/6 .  b) '(3/6 . c)) 1000)
;; -> ((a 163) (b 333) (c 504))

if we want to change like a:b:c = 1:3:8 then 1/12:3/12:8/12,
when adding d, a:b:c:d = 1:3:8:5 then 1/17:3/17:8/17:5/17,  and so on .....

So I use w-rnd instead of random(with paired-list-notation arg) as weighted-random-selection function.  While playing live coding music, w-rnd saves the calculation for sum-of-probabilities == 1.0, w-rnd uses just probability values in free style or order without any sum of any .... , just intuitive !

And I sometimes use like this style in live coding, too
(random '(a b b c c c)) ; a:b:c=1:2:3, very easy way !

besides
(w-rnd '((a 1) (b 2) (c 3))) ;a:b:c=1:2:3

And this is ok, too, in w-rnd
(w-rnd '((a 1) (b 0) (c 3))) ; a:b:c=1:0:3 -> returns a or c without b,
                             ; it is easy to restore the data to its previous state.


;; test

(my-test '(random '(a b b c c c))  1000)
;; -> ((a 160) (b 347) (c 493))


(my-test '(w-rnd '((a 1) (b 2) (c 3))) 1000)
;; -> ((a 158) (b 343) (c 499))

(my-test '(w-rnd '((a 1) (b 0) (c 3))) 1000)
;; -> ((a 262) (c 738))

(my-test '(random '(a c c c))  1000)
;; -> ((a 266) (c 734))


These can save some bothering calculations, that's important especially while playing live coding music !

2026年7月5日日曜日 7:42:41 UTC+9 George:
Reply all
Reply to author
Forward
0 new messages