Implementation of Futures

Glenn Takanishi <[email protected]> Thu, 09 Feb 2023 05:18:06 +0000
Newsgroups gmane.lisp.scheme.gauche
Message-ID <[email protected]>
2023-2-8

Hello!

Just curious about how futures is implemented.  A short description 
would suffice with respect to some code I was playing with (it's 
attached to this email just for fun).

The Gauche documentation on futures says that "future" calls code in a 
separate thread (I assume a Posix pthread).  So I get the feeling that a 
"future" is like "pthread_create" in C.  And that "future-get" can be 
likened to "pthread_join".  The structure of the programs between Scheme 
and C look alike.

But the output returns after "future-get" is random.  The output result 
from pthread_join is usally not.  This is not a problem for me.  I'm 
just curious as to why this happens.  The behavior using Guile scheme is 
similar with random output results from "touch".

This question might seem weird to you, and I apologize if so.  I'm just 
curious.  Thanks.

Glenn

_______________________________________________
Gauche-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gauche-devel
btree.scm (text/plain, 1.8 KB)
;; The Computer Language Benchmarks Game
;; http://shootout.alioth.debian.org/
;; contributed by Sven Hartrumpf

;; try: gosh -l btree.scm -- 16

(use scheme.bitwise)
(use control.future)

(define nil '())
(define TAB (integer->char 9))

(define (make item depth)
   (if (zero? depth) (list item)
       (let ((item2 (* item 2)) (d2 (- depth 1)))
          (cons item  (cons  (make (- item2 1) d2) (make item2 d2))))))

(define (check node)
   (let ((data (car node)) (link (cdr node)))
      (if  (null? link) data
           (- (+ data (check (car link))) (check (cdr link))))))

(define (check-trees-of-depth d max-depth min-depth)
	(let ((iterations (arithmetic-shift 1 (+ (- max-depth d) min-depth)))
			(c 0))
		(do ((i 0 (+ i 1))) ((>= i iterations))
			(set! c (+ c (check (make i d)) (check (make (- i) d)))))
		(print (* 2 iterations) TAB " trees of depth " d TAB 
				  " check: " c)))

(define (main depth)
	(let* ((min-depth 4)
			 (max-depth (max (+ min-depth 2) depth))
			 (stretch-depth (+ max-depth 1)))
		(print "stretch tree of depth " stretch-depth TAB " check: "
				  (check (make 0 stretch-depth)))
		(let ((long-lived-tree (make 0 max-depth))
				(que (make-future (lambda (d max-depth min-depth)
                                 check-trees-of-depth))))
			
			(do ((d 4 (+ d 2))) ((> d max-depth))
				(let* ((fid (gensym))
						 (fid (future (check-trees-of-depth d max-depth min-depth))))
					;; (push! fid que)))
					(push! que fid)))

			;; the output results are in random order
			(do ((d 4 (+ d 2))) ((> d max-depth))
				(let ((fid (pop! que)))
					(future-get fid)))
		
			(print "long lived tree of depth " max-depth TAB " check: "
					  (check long-lived-tree)))))
	
(print (command-line))
(define n (string->number (last (command-line))))
(main n)
(exit)