ADD More presentation, js example
M .builds/alpine.yml +2 -2
@@ 21,12 21,12 @@ tasks:
   - build: |
       eval $(opam env)
       cd byocm/code
-      time gmake -j4
+      time make -j4
   - test: |
       eval $(opam env)
       cd byocm/code
       set +e
-      time env OCAMLRUNPARAM=b gmake -j4 -k test
+      time env OCAMLRUNPARAM=b make -j4 -k test
       test_ret=$?
       set -x
       find . -name '*.tap' -exec cat '{}' \;

          
A => byocm_js_example.html +11 -0
@@ 0,0 1,11 @@ 
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8">
+    <title>Byocm js example</title>
+    <script type="text/javascript" src="code/build/release/byocm_js_example/byocm_js_example.js"></script>
+  </head>
+  <body onload="javascript:byocmJsRun()">
+    <div id="changeme"></div>
+  </body>
+</html>

          
M code/pds.conf +22 -0
@@ 26,6 26,28 @@ install = false
 install = false
 deps = [ "byocm_fut" ]
 
+[src.byocm_slow_print]
+type = "exec"
+install = false
+deps = [ "byocm_fut", "byocm_sched" ]
+
+[src.byocm_js_example]
+type = "exec"
+install = false
+deps = [ "byocm_fut", "js_of_ocaml", "js_of_ocaml.ppx" ]
+extra_makefile_lines = [ "OCAMLC_LINK_OPTS=",
+                         "OCAMLOPT_LINK_OPTS=",
+                         "all: $(SRC_DIR)/byocm_js_example.js",
+                         "$(SRC_DIR)/byocm_js_example.js: $(BYTE_TARGET)",
+                         "\tjs_of_ocaml $(BYTE_TARGET)" ]
+
+debug = { extra_makefile_lines = [ "OCAMLC_LINK_OPTS=",
+                                   "OCAMLOPT_LINK_OPTS=",
+                                   "all: $(SRC_DIR)/byocm_js_example.js",
+                                   "$(SRC_DIR)/byocm_js_example.js: $(BYTE_TARGET)",
+                                   "\tjs_of_ocaml $(BYTE_TARGET)"  ]}
+
+
 [tests.byocm_fut]
 deps = [ "byocm_fut" ]
 

          
A => code/src/byocm_js_example/byocm_js_example.ml +33 -0
@@ 0,0 1,33 @@ 
+open Js_of_ocaml
+
+let sleep msecs =
+  let p = Byocm_fut.Promise.create () in
+  let f () = Byocm_fut.Promise.set p () in
+  ignore
+    (Dom_html.window##setTimeout
+       (Js.wrap_callback f)
+       msecs);
+  Byocm_fut.Promise.future p
+
+let rec run' elm = function
+  | 0 ->
+    elm##.innerHTML := Js.string "All done";
+    Byocm_fut.return ()
+  | n ->
+    let open Byocm_fut.Infix_monad in
+    elm##.innerHTML := Js.string (string_of_int n);
+    sleep 1000.0
+    >>= fun () ->
+    run' elm (n - 1)
+
+let run n =
+  let elm = Js.Opt.to_option (Dom_html.(CoerceTo.element (getElementById "changeme"))) in
+  match elm with
+    | Some elm -> run' elm n
+    | None -> Js.Unsafe.(fun_call (js_expr "alert") [| inject (Js.string "Could not find element") |])
+
+let _ =
+  Js.export_all
+    (object%js
+      method byocmJsRun = run 10
+    end)

          
A => code/src/byocm_slow_print/byocm_slow_print.ml +12 -0
@@ 0,0 1,12 @@ 
+let () =
+  let open Byocm_fut.Infix_monad in
+  let rec f = function
+    | 0 ->
+      Byocm_fut.return ()
+    | n ->
+      print_endline "Hi";
+      Byocm_sched.sleep 1.0
+      >>= fun () ->
+      f (n - 1)
+  in
+  Byocm_sched.run (fun () -> f 10)

          
M presentation/byocm.tex +69 -7
@@ 64,12 64,10 @@ 
   \item Handle multiple connections in a single thread.
   \item Use OS APIs to get a list of events, process them, ask again (fewer
     context switches).
-  \item Event Loop.
+  \item Scheduler (Event loop).
   \item Basic model the same across OS's but specific API calls change.
   \item Go, Erlang, Mozart/Oz do this for you.  Async/Await in Rust, C\#, and
     JavaScript do a similar thing.
-  \item In Ocaml we can do this as a library, no need to spend 3 years in
-    language standards meetings!
   \end{itemize}
 \end{frame}
 

          
@@ 78,9 76,8 @@ 
   \item The game is to turn kernel calls that can wait an unbounded amount of
     time into two calls: One where you tell the kernel to do something and
     another when it tells you when it's done.
-  \item Start the event loop with some initial work.
-  \item Perform a bit of user-space work then give control back to the event
-    loop.
+  \item Start the scheduler with some initial work.
+  \item Perform a bit of user-space work then give control back to the scheduler.
   \end{itemize}
 \end{frame}
 

          
@@ 180,7 177,7 @@ 
   \begin{itemize}
   \item \textbf{Promises} - Define a graph of things-that-are-not-done and
     things-that-want-to-know-when-they-are-done.
-  \item \textbf{Event loop/Scheduler} - Handle waiting for events and telling
+  \item \textbf{Scheduler} - Handle waiting for events and telling
     kernel about new events and fulfilling promises.
   \end{itemize}
 \end{frame}

          
@@ 209,5 206,70 @@ 
   \hlstd{}\hlkwa{end}\hspace*{\fill}\\
 \end{frame}
 
+\begin{frame}{Scheduler}
+  \noindent
+  \ttfamily
+  \hlstd{}\hlkwa{val\ }\hlstd{sleep\ }\hlopt{:\ }\hlstd{}\hlkwb{float\ }\hlstd{}\hlopt{{-}$>$\ }\hlstd{}\hlkwb{unit\ }\hlstd{}\hlkwc{Byocm\textunderscore fut}\hlstd{}\hlopt{.}\hlstd{t}\hspace*{\fill}\\
+  \hlstd{}\hspace*{\fill}\\
+  \hlstd{}\hlkwa{val\ }\hlstd{run\ }\hlopt{:\ (}\hlstd{}\hlkwb{unit\ }\hlstd{}\hlopt{{-}$>$\ }\hlstd{'a\ }\hlkwc{Byocm\textunderscore fut}\hlstd{}\hlopt{.}\hlstd{t}\hlopt{)\ {-}$>$\ }\hlstd{'a}\hspace*{\fill}\\
+  \mbox{}
+\end{frame}
+
+\begin{frame}{Scheduler Example}
+  \noindent
+  \ttfamily
+  \hlstd{}\hlkwa{let\ }\hlstd{}\hlkwd{f\ }\hlstd{}\hlopt{()\ =\ }\hlstd{}\hlkwc{Byocm\textunderscore sched}\hlstd{}\hlopt{.}\hlstd{sleep\ }\hlnum{1.0\ }\hlstd{}\hlkwa{in}\hspace*{\fill}\\
+  \hlstd{}\hlkwa{let\ }\hlstd{}\hlkwd{v\ }\hlstd{}\hlopt{=\ }\hlstd{}\hlkwc{Byocm\textunderscore sched}\hlstd{}\hlopt{.}\hlstd{run\ }\hlkwd{f\ }\hlstd{}\hlkwa{in}\hspace*{\fill}\\
+  \hlstd{}\hlkwa{assert\ }\hlstd{}\hlopt{(}\hlstd{}\hlkwd{v\ }\hlstd{}\hlopt{=\ ())}\hlstd{}\hspace*{\fill}\\
+  \mbox{}
+\end{frame}
+
+\begin{frame}{Exercises For The Reader}
+  \begin{itemize}
+  \item Add some Unix APIs (send/recv/connect/accept).
+  \item Switch to something other than \texttt{Unix.select}.
+  \item Support canceling operations.
+  \end{itemize}
+\end{frame}
+
+\begin{frame}{Extra Wild: Byocm\_fut + js\_of\_ocaml}
+  \begin{itemize}
+  \item Byocm\_fut is pure Ocaml, can compile to JS just fine.
+  \item Don't need Byocm\_sched, JS engine comes with one
+  \item Let's make a little page that updates a value every second.
+  \end{itemize}
+\end{frame}
+
+\begin{frame}{sleep}
+  \noindent
+  \ttfamily
+  \hlstd{}\hlkwa{let\ }\hlstd{}\hlkwd{sleep\ }\hlstd{msecs\ }\hlopt{=}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ }\hlstd{}\hlkwa{let\ }\hlstd{}\hlkwd{p\ }\hlstd{}\hlopt{=\ }\hlstd{}\hlkwc{Byocm\textunderscore fut}\hlstd{}\hlopt{.}\hlstd{}\hlkwc{Promise}\hlstd{}\hlopt{.}\hlstd{create\ }\hlopt{()\ }\hlstd{}\hlkwa{in}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ }\hlstd{}\hlkwa{let\ }\hlstd{}\hlkwd{f\ }\hlstd{}\hlopt{()\ =\ }\hlstd{}\hlkwc{Byocm\textunderscore fut}\hlstd{}\hlopt{.}\hlstd{}\hlkwc{Promise}\hlstd{}\hlopt{.}\hlstd{set\ }\hlkwd{p\ }\hlstd{}\hlopt{()\ }\hlstd{}\hlkwa{in}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ }\hlstd{ignore}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{}\hlopt{(}\hlstd{}\hlkwc{Dom\textunderscore html}\hlstd{}\hlopt{.}\hlstd{window\#\#setTimeout}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ \ \ \ }\hlstd{}\hlopt{(}\hlstd{}\hlkwc{Js}\hlstd{}\hlopt{.}\hlstd{wrap\textunderscore callback\ }\hlkwd{f}\hlstd{}\hlopt{)}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ \ \ \ }\hlstd{msecs}\hlopt{);}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ }\hlstd{}\hlkwc{Byocm\textunderscore fut}\hlstd{}\hlopt{.}\hlstd{}\hlkwc{Promise}\hlstd{}\hlopt{.}\hlstd{future\ }\hlkwd{p}\hlstd{}\hspace*{\fill}\\
+  \mbox{}
+\end{frame}
+
+\begin{frame}{Final Countdown}
+  \noindent
+  \ttfamily
+  \hlstd{}\hlkwa{let\ rec\ }\hlstd{}\hlkwd{run}\hlstd{'\ elm\ }\hlopt{=\ }\hlstd{}\hlkwa{function}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ }\hlstd{}\hlopt{\textbar \ }\hlstd{}\hlnum{0\ }\hlstd{}\hlopt{{-}$>$}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{elm\#\#}\hlopt{.}\hlstd{innerHTML\ }\hlopt{:=\ }\hlstd{}\hlkwc{Js}\hlstd{}\hlopt{.}\hlstd{}\hlkwb{string\ }\hlstd{}\hlstr{"All\ done"}\hlstd{}\hlopt{;}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{}\hlkwc{Byocm\textunderscore fut}\hlstd{}\hlopt{.}\hlstd{return\ }\hlopt{()}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ }\hlstd{}\hlopt{\textbar \ }\hlstd{n\ }\hlopt{{-}$>$}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{}\hlkwa{let\ open\ }\hlstd{}\hlkwc{Byocm\textunderscore fut}\hlstd{}\hlopt{.}\hlstd{Infix\textunderscore monad\ }\hlkwa{in}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{elm\#\#}\hlopt{.}\hlstd{innerHTML\ }\hlopt{:=\ }\hlstd{}\hlkwc{Js}\hlstd{}\hlopt{.}\hlstd{}\hlkwb{string\ }\hlstd{}\hlopt{(}\hlstd{string\textunderscore of\textunderscore int\ n}\hlopt{);}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{sleep\ }\hlnum{1000.0}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{}\hlopt{$>$$>$=\ }\hlstd{}\hlkwa{fun\ }\hlstd{}\hlopt{()\ {-}$>$}\hspace*{\fill}\\
+  \hlstd{}\hlstd{\ \ \ \ }\hlstd{}\hlkwd{run}\hlstd{'\ elm\ }\hlopt{(}\hlstd{n\ }\hlopt{{-}\ }\hlstd{}\hlnum{1}\hlstd{}\hlopt{)}\hlstd{}\hspace*{\fill}\\
+\mbox{}
+
+\end{frame}
+
 \end{document}
 

          
A => presentation_code/js_loop.ml +10 -0
@@ 0,0 1,10 @@ 
+let rec run' elm = function
+  | 0 ->
+    elm##.innerHTML := Js.string "All done";
+    Byocm_fut.return ()
+  | n ->
+    let open Byocm_fut.Infix_monad in
+    elm##.innerHTML := Js.string (string_of_int n);
+    sleep 1000.0
+    >>= fun () ->
+    run' elm (n - 1)

          
A => presentation_code/js_sleep.ml +8 -0
@@ 0,0 1,8 @@ 
+let sleep msecs =
+  let p = Byocm_fut.Promise.create () in
+  let f () = Byocm_fut.Promise.set p () in
+  ignore
+    (Dom_html.window##setTimeout
+       (Js.wrap_callback f)
+       msecs);
+  Byocm_fut.Promise.future p