Skip to content

Commit

Permalink
Beginnings of async support.
Browse files Browse the repository at this point in the history
Relates to #22
  • Loading branch information
kjnilsson committed Jul 4, 2017
1 parent dd63391 commit de593e1
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 49 deletions.
42 changes: 42 additions & 0 deletions src/Microsoft.FSharp.Control.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
-module('Microsoft.FSharp.Control').

-export([
'FSharpAsyncBuilder.Delay'/2,
'FSharpAsyncBuilder.Return'/2,
'FSharpAsyncBuilder.Bind'/3,
'FSharpAsyncBuilder.Zero'/1,
'FSharpAsync.Start'/2,
'FSharpAsync.RunSynchronously'/3

]).

% -type async() :: {async, delay | return | bind | zero, term()}.

'FSharpAsyncBuilder.Delay'(_B, Fun) ->
{async, delay, Fun}.

'FSharpAsyncBuilder.Return'(_B, V) ->
{async, return, V}.

'FSharpAsyncBuilder.Bind'(_B, Async, Binder) ->
{async, bind, {Async, Binder}}.

'FSharpAsyncBuilder.Zero'(_B) ->
{async, zero, unit}.

% TODO: can we use token somehow to cancel the async? how would we register?
'FSharpAsync.Start'(Async, _Token) ->
% run async on another process
spawn(fun () -> run(Async) end),
ok.

'FSharpAsync.RunSynchronously'(Async, _Timeout, _Token) ->
run(Async).

run({async, zero, unit}) -> ok;
run({async, delay, Fun}) ->
run(Fun());
run({async, return, V}) ->
V;
run({async, bind, {Async, Binder}}) ->
run(Binder(run(Async))).
12 changes: 10 additions & 2 deletions src/Microsoft.FSharp.Core.ExtraTopLevelOperators.erl
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
-module('Microsoft.FSharp.Core.ExtraTopLevelOperators').
-compile(export_all).
-export([
async/0,
printfn/1,
query/0
]).

% dummy value for async builder
async() -> ok.

printfn(S) ->
io:format(S, []).

query() -> query_builder.
query() -> ok.

17 changes: 17 additions & 0 deletions test/basics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,20 @@ let seq_query =
where (n > 5)
select (n + 1)
} |> Seq.toList


let getAsyncValue =
async {
return "async_value" }

let async_start p =
async {
let! v = getAsyncValue
p <! v }
|> Async.Start

let async_run =
async {
let! v = getAsyncValue
return "run_" + v }
|> Async.RunSynchronously
9 changes: 9 additions & 0 deletions test/basics_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,12 @@ lazy_test() ->
seq_query_test() ->
[7,8,9,10] = basics:seq_query(),
ok.

async_test() ->
"run_async_value" = basics:async_run(),
basics:async_start(self()),
receive
"async_value" -> ok
after 1000 ->
exit(async_test_timeout)
end.
73 changes: 26 additions & 47 deletions test/wip.fs
Original file line number Diff line number Diff line change
@@ -1,61 +1,40 @@
module wip
open Fez.Core

(* type IPrt = *)
(* abstract member Prt: unit -> string *)
[<ModCall("erlang", "put")>]
let put<'a, 'b> (k: 'a) (v: 'b) : 'b option = None

let get_v =
async {
return "value" }

(* let async_start p = *)
(* let cts = new System.Threading.CancellationTokenSource() *)
(* async { *)
(* let! v = get_v *)
(* p <! v } *)
(* |> fun a -> Async.Start(a, cts.Token) *)

let assync =
async {
let! v = get_v
return v}
|> Async.RunSynchronously

(* let rarray() = *)
(* let l = new ResizeArray<_>() *)
(* l.Add 1 *)
(* l *)

(* type Obj = *)
(* | O *)
(* interface System.IDisposable with *)
(* member x.Dispose() = printfn "dispose" *)
(* interface IPrt with *)
(* member x.Prt() = "O" *)

(* let interfaces () = *)
(* use o = O *)
(* (o :> IPrt).Prt() *)

(*
module N =
type NTest2 =
| N
static member talk (t: NTest2) = "ntest2"
member x.barf () = "ntest2b"
let nt () = ""
type Banana () =
member x.eat() = 0
type Test2 =
| Test2
static member prt (t: Test2) = "test2"
member x.print () = "test2b"
let tt() =
let t = Test2
Test2.prt t,
t.print(),
let b = Banana()
b.eat(),
N.NTest2.talk N.N,
N.N.barf (),
N.nt
*)

let rarray() =
let l = new ResizeArray<_>()
l
(* let query1 = *)
(* query { *)
(* for n in seq {0..10} do *)
(* where (n > 5) *)
(* select (n - 1) *)
(* } *)

let bigints () =
bigint 1
(* let bigints () = *)
(* bigint 1 *)


#if FEZ
Expand Down

0 comments on commit de593e1

Please sign in to comment.