Re: [opencog/opencog] Assorted unit-test cleanup. (#2992)

17 views
Skip to first unread message

Linas Vepstas

unread,
Jan 29, 2018, 5:34:46 PM1/29/18
to opencog/opencog, opencog


On Sun, Jan 28, 2018 at 10:05 PM, Amen Belayneh <notifi...@github.com> wrote:

@AmeBel commented on this pull request.


In opencog/openpsi/main.scm:

> @@ -300,6 +300,9 @@
 ; psi rules.  For now, this is OK, but at some point, this will become
 ; a bottleneck, as we will need to evaluate more rules more often.
 ;
+(define psi-run-per-demand-loop-is-going #f) ;;; XXX this should be a
+;;;continuation instead. of a global.

Why should it be a continuation?


I could feel this question in my bones. So let me post on the mailing list as a tutorial that all scheme programmers should know. It is sometimes said that "objects are a poor-man's continuation" but if you've attained Zen enlightenment, then you know that "continutations are a poor-mans object".

Its actually more subtle that that, as there are many kinds of objects, and C++/java only support some of them, not all of them; they do not support "parametric polymorphism"  which is a shame cause its useful in real-world situations. But whatever.  Getting back to scheme...

For the above example, there are two ways of doing this in guile.  The "obvious" one is to use a global variable:

(define n 0)
(define (incr-and-print) (begin (set! n (+ n 1)) (format #t "Hello ~A\n" n)))

The other way is to create an object, cough cough, continuation, and put n inside of it:

(define (make-incr-and-print-object)
   (define n 0)
   (lambda () (set! n (+ n 1)) (format #t "Hello ~A\n" n)))

(define incr-and-print-a (make-incr-and-print-object))
(incr-and-print-a)
(incr-and-print-a)
(incr-and-print-a)
(define incr-and-print-b (make-incr-and-print-object))
(incr-and-print-b)
(incr-and-print-a)

There's also ways to stick multiple methods on that object, e.g. to incr, decr, zero out or print. 

(define (make-counter)
   (define n 0)
   (lambda (message . args)
      (case message
         ((incr)        (set! n (+ n 1)))
         ((decr)        (set! n (- n 1)))
         ((zero)        (set! n 0))
         ((acc)         (apply (lambda (val) (set! n (+ n val))) args))
         ((print)       (format #f "Hello ~A\n" n))
      )))

(define acnt (make-counter))

(acnt 'print)
(acnt 'acc 42)
(acnt 'print)
(acnt 'decr)
(acnt 'print)

So now you see how objects are a poor-mans continuation.  To see the converse, notice that a continuation is an object with one and only one method (which has no name).

I mention this because when I see things like "per demand" and it uses a global it suggests that a per-deman object was wanted, but .. well, I dunno, there's a global for some reason.

--linas



--
cassette tapes - analog TV - film cameras - you
Reply all
Reply to author
Forward
0 new messages