Héllo,

I've done some exploration regarding this topic; I think it might of interest or it's very naive.

It goes like this:

``` scheme

(define (loop-run-forever)
  (while #true
    (call-with-prompt 'loop
      loop-run-once
      (lambda (cc callback) (callback cc)))))

```

`loop-run-once` does the `do-select` thing and call scheduled task. Then we only need to wrap blocking calls inside `abort-to-prompt`, here an example with `read`:

```
(define (read/ sock)
  (abort-to-prompt 'loop (lambda (cc)
(loop-add-reader sock (lambda () (cc (read sock)))))))
```

`loop-add-reader` is procedure that register a callback against `select` to restart the computation where it was left it's equivalent to `port-request-read` machinery.


I attached an example server, the client is vanilla imperative code. Also, it doesn't implement exception propagation.


I don't understand the point of %8sync macro when all blocking calls can be expressed directly in terms of abort-to-prompt.


HTH
(setlocale LC_ALL "")

(define sock (socket PF_INET SOCK_STREAM 0))
(connect sock AF_INET INADDR_LOOPBACK 12345)

(pk sock)
(write "héllo world" sock)
(write "you are free" sock)
(close sock)
(define-module (plain))

(use-modules (srfi srfi-9))  ;; records
(use-modules (srfi srfi-9 gnu))  ;; set-record-type-printer! and set-field

;;;
;;; plain records
;;;
;;
;; macro to quickly define records
;;
;;
;; Usage:
;;
;;   (define-record-type <car> seats wheels)
;;   (define smart (make-abc 2 4))
;;   (car-seats smart) ;; => 2
;;
;; Mutation is not done in place, via set-field or set-fields eg.:
;;
;; (define smart-for-4 (set-field smart (seats) 4))
;; 

(define-syntax define-record-type*
  (lambda (x)
    (define (%id-name name) (string->symbol (string-drop (string-drop-right 
(symbol->string name) 1) 1)))
    (define (id-name ctx name)
      (datum->syntax ctx (%id-name (syntax->datum name))))
    (define (id-append ctx . syms)
      (datum->syntax ctx (apply symbol-append (map syntax->datum syms))))
    (syntax-case x ()
      ((_ rname field ...)
       (and (identifier? #'rname) (and-map identifier? #'(field ...)))
       (with-syntax ((cons (id-append #'rname #'make- (id-name #'rname 
#'rname)))
                     (pred (id-append #'rname (id-name #'rname #'rname) #'?))
                     ((getter ...) (map (lambda (f)
                                          (id-append f (id-name #'rname 
#'rname) #'- f))
                                        #'(field ...))))
         #'(define-record-type rname
             (cons field ...)
             pred
             (field getter)
             ...))))))

(export define-record-type*)
(re-export set-record-type-printer!)
(re-export set-field)
(use-modules (rnrs bytevectors))
(use-modules (ice-9 rdelim))


(define sock (socket PF_INET SOCK_STREAM 0))
(bind sock (make-socket-address AF_INET INADDR_ANY 12345))
(listen sock 128)
(define inbound (accept sock))

(define-public (string->scm string)
  (call-with-input-string string
    (lambda (port)
      (read port))))

(define (read-message port)
  (let next ((char (read-char port))
             (out '()))
    (if (eq? char #\0)
        (list->string (reverse out))
        (next (read-char port) (cons char out)))))

Reply via email to