Re: [racket-users] Announcing Event-lang

2018-05-23 Thread Eric Griffis
These are in and should be visible in a few hours. I'll keep collecting
more!

Eric


On Tue, May 22, 2018 at 1:48 PM Matthew Butterick  wrote:

> I'm sure I'm not the only one who would like to see these (and other
> examples you have handy) added to your `event-lang` docs.
>
>
> On May 22, 2018, at 7:29 AM, Eric Griffis  wrote:
>
> Here's a variety of small examples.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Announcing Event-lang

2018-05-22 Thread Matthew Butterick
I'm sure I'm not the only one who would like to see these (and other examples 
you have handy) added to your `event-lang` docs.


> On May 22, 2018, at 7:29 AM, Eric Griffis  wrote:
> 
> Here's a variety of small examples.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Announcing Event-lang

2018-05-22 Thread Eric Griffis
On Mon, May 21, 2018 at 11:21 AM Jay McCarthy 
wrote:

> This is very cute! Can you point to a fun example? I looked through
> the repo and it wasn't obvious where some tests and examples were.
>
> Jay
>

Here's a variety of small examples.

Sometimes, I just want to wait until a bunch of stuff is done:

  > (sync
 (async-void*
  (append
   (for/list ([i 10])
 (thread (λ () (channel-put ch i
   (for/list ([_ 10])
 (thread (λ () (write (channel-get ch
  1594302867

Sometimes, I want to do something more than once:

  > (define (channel-dup-evt cs v)
  (async-void* (map (curryr channel-put-evt v) cs)))

With some background getters,

  > (define cs (build-list 5 (λ _ (make-channel
  > (for ([c cs] [i 5])
  (thread (λ () (writeln (cons i (channel-get c))

it's ready for synchronization.

  > (sync (channel-dup-evt cs 'X))
  (1 . X)
  (3 . X)
  (0 . X)
  (2 . X)
  (4 . X)

The natural numbers:

  > (define nats
  (let ([n 0]) (pure (begin0 n (set! n (add1 n))

This event acts like a generator.

  > (sync nats)
  0
  > (sync nats)
  1
  > (sync nats)
  2

nats is handy for generating indices and unique keys in bulk through
repetition.

  > (sync (event-list* (make-list 4 nats)))
  '(3 4 5 6)

It's always fun to implement the fibonacci sequence:

  > (define (naive-fib n)
  (case n
[(0) (pure 0)]
[(1) (pure 1)]
[else (fmap + (naive-fib (- n 1)) (naive-fib (- n 2)))]))

Of course, the naive implementation is very slow.

  > (time (sync (naive-fib 29)))
  cpu time: 5826 real time: 5831 gc time: 1004
  514229

This one:

  > (define fib
  (let ([a 1] [b 0])
(pure (begin0 b (set!-values (a b) (values (+ a b) a))

is much faster.

  > (time (last (sync (event-list* (make-list 30 fib)
  cpu time: 1 real time: 1 gc time: 0
  514229

nats and fib can be combined to build an index:

  > (define fibs (make-hash))
  > (sync
 (async-void*
  (make-list 30 (fmap (curry hash-set! fibs) nats fib
  > (hash-ref fibs 29)
  514229
  > (hash-ref fibs 15)
  610

Promises are pretty easy, too:

  > (define (promise thunk)
  (define result #f)
  (bind (thread (λ ()
  (define vs (call-with-values thunk list))
  (set! result (pure (apply values vs)
(λ _ result)))

The results are memoized so multiple syncs don't replay side effects.

  > (define p (promise (λ () (writeln 123) 4)))
  123
  > (sync p)
  4
  > (sync p)
  4

My personal favorite is more practical than fun:

  > (define (dispatch m ms [default void-mediator])
  (define (dispatch-put m0)
(bind-put
 (make-mediator)
 (λ _ (λ (k . vs) (say* (hash-ref ms k default) vs m0)
  (event-let ([m0 (accept m)]) (offer m0 (dispatch-put m0

Without getting into what mediators are, this one forwards a message from m
 to
an element of hash ms. If the message is a list and the first element is a
key
of ms, the rest of the message is delivered to the keyed element. The
dispatch
event may finish before the message is delivered, but the sender and
receiver
are guaranteed to synchronize on each other. Getting this right was hard.

Most of my work with event-lang is in solving hairy synchronization problems
like this, so I felt I should sneak one in.

Eric

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Announcing Event-lang

2018-05-21 Thread Jay McCarthy
This is very cute! Can you point to a fun example? I looked through
the repo and it wasn't obvious where some tests and examples were.

Jay

On Fri, May 18, 2018 at 4:20 PM, Eric Griffis  wrote:
> Hi everyone,
>
> I would like to announce the initial release of event-lang, an
> experimental Racket library that simplifies the creation of complex
> synchronizable events.
>
> https://pkgd.racket-lang.org/pkgn/package/event-lang
>
> Event-lang provides a primitive expression lifting form,
>
>   > (pure 123)
>   #
>
> some event combinators,
>
>   > (sync (fmap + (pure 1) (pure 2)))
>   3
>   > (sync (app (pure +) (pure 1) (pure 2)))
>   3
>   > (sync (bind (pure 1) (pure 2) (λ xs (pure (apply + xs)
>   3
>
> and a collection of event-friendly alternatives to base Racket forms
> and functions.
>
>   > (sync
>  (event-let
>   ([x (pure 1)]
>[y (pure 2)])
>   (pure (list x y
>   '(1 2)
>
> Composite events make progress by synchronizing constituent events,
> either concurrently or in a predictable sequence. Synchronization
> results can be ordered as specified,
>
>   > (let ([t0 (current-inexact-milliseconds)])
>   (define (now) (- (current-inexact-milliseconds) t0))
>   (sync
>(async-args
> (pure (cons 1 (now)))
> (pure (cons 2 (now)))
> (pure (cons 3 (now))
>   '(1 . 0.200927734375)
>   '(2 . 0.14990234375)
>   '(3 . 0.178955078125)
>
> or as completed.
>
>   > (let ([t0 (current-inexact-milliseconds)])
>   (define (now) (- (current-inexact-milliseconds) t0))
>   (sync
>(async-set
> (pure (cons 1 (now)))
> (pure (cons 2 (now)))
> (pure (cons 3 (now))
>   '(2 . 0.0771484375)
>   '(3 . 0.093017578125)
>   '(1 . 0.123046875)
>
> The project has three outstanding objectives:
>
> 1. Provide a sophisticated lifting form
>
>   to simplify usage of the provided constructs. The event/event module
>   contains a first approximation. Its construction was tedious and
>   error prone, so I commented out the docs.
>
> 2. Provide a full-blown #lang event/racket/base
>
>   for producing whole modules of events and event constructors from
>   ordinary Racket code in a principled manner.
>
> 3. Provide support for static analysis of synchronization behaviors.
>
>   Event programming in Racket is a curious form of meta-programming,
>   and a few simple compile-time checks could reduce cognitive
>   overhead.
>
> This pre-release is a request for feedback in anticipation of a
> production-ready version 1.0. I would like to round out the base
> collection and devise a comprehensive testing plan, with a stretch
> goal of re-introducing the sophisticated lifting form. At the moment,
> I'm using event-lang daily and adding base constructs as needed. Feel
> free to do the same or request your favorites.
>
> Please take a look and let me know what you think.
>
> Eric
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



-- 
-=[ Jay McCarthy   http://jeapostrophe.github.io]=-
-=[ Associate ProfessorPLT @ CS @ UMass Lowell ]=-
-=[ Moses 1:33: And worlds without number have I created; ]=-

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Announcing Event-lang

2018-05-18 Thread Eric Griffis
Hi everyone,

I would like to announce the initial release of event-lang, an
experimental Racket library that simplifies the creation of complex
synchronizable events.

https://pkgd.racket-lang.org/pkgn/package/event-lang

Event-lang provides a primitive expression lifting form,

  > (pure 123)
  #

some event combinators,

  > (sync (fmap + (pure 1) (pure 2)))
  3
  > (sync (app (pure +) (pure 1) (pure 2)))
  3
  > (sync (bind (pure 1) (pure 2) (λ xs (pure (apply + xs)
  3

and a collection of event-friendly alternatives to base Racket forms
and functions.

  > (sync
 (event-let
  ([x (pure 1)]
   [y (pure 2)])
  (pure (list x y
  '(1 2)

Composite events make progress by synchronizing constituent events,
either concurrently or in a predictable sequence. Synchronization
results can be ordered as specified,

  > (let ([t0 (current-inexact-milliseconds)])
  (define (now) (- (current-inexact-milliseconds) t0))
  (sync
   (async-args
(pure (cons 1 (now)))
(pure (cons 2 (now)))
(pure (cons 3 (now))
  '(1 . 0.200927734375)
  '(2 . 0.14990234375)
  '(3 . 0.178955078125)

or as completed.

  > (let ([t0 (current-inexact-milliseconds)])
  (define (now) (- (current-inexact-milliseconds) t0))
  (sync
   (async-set
(pure (cons 1 (now)))
(pure (cons 2 (now)))
(pure (cons 3 (now))
  '(2 . 0.0771484375)
  '(3 . 0.093017578125)
  '(1 . 0.123046875)

The project has three outstanding objectives:

1. Provide a sophisticated lifting form

  to simplify usage of the provided constructs. The event/event module
  contains a first approximation. Its construction was tedious and
  error prone, so I commented out the docs.

2. Provide a full-blown #lang event/racket/base

  for producing whole modules of events and event constructors from
  ordinary Racket code in a principled manner.

3. Provide support for static analysis of synchronization behaviors.

  Event programming in Racket is a curious form of meta-programming,
  and a few simple compile-time checks could reduce cognitive
  overhead.

This pre-release is a request for feedback in anticipation of a
production-ready version 1.0. I would like to round out the base
collection and devise a comprehensive testing plan, with a stretch
goal of re-introducing the sophisticated lifting form. At the moment,
I'm using event-lang daily and adding base constructs as needed. Feel
free to do the same or request your favorites.

Please take a look and let me know what you think.

Eric

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.