/* * The Computer Language Shootout * http://shootout.alioth.debian.org/ * * Contributed by: Micky Latowicki * Date: May 7, 2007 */ #pragma indent using System module Coroutines public variant coroutine['a,'b] | End | Ready first: 'b rest: coroutine['a,'b] | Waiting mkRest: 'a->coroutine['a,'b] public class UnexpectedState : System.Exception {} public class ExpectedWaiting : UnexpectedState {} public put(x:'a) : coroutine['a,'b] match (this) | Waiting(mkRest) => mkRest(x) | _ => throw ExpectedWaiting() module CheapConcurrency type co['a,'b] = Coroutines.coroutine['a,'b] Test(n:int) : void def IncrementorThread(mutable next) mutable coro = null coro = co.Waiting((x)=>{ next = next.put(x+1); coro }) coro mutable total = 0 mutable adderThread = null adderThread = co.Waiting((x)=>{ total+=x; adderThread }) def makePipeline(k,last) if (k==0) last else makePipeline(k-1, IncrementorThread(last)) mutable pipeline = makePipeline(500, adderThread) repeat(n) pipeline = pipeline.put(0) Console.WriteLine(total) public Main() : void def args = Environment.GetCommandLineArgs () def n = (if (args.Length<2) 1 else int.Parse(args [1])) Test(n)