From 0a839b80aaed89dfd0d84fa3308b72de590171cb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 1 Mar 2017 22:13:50 +0100 Subject: Move depmeth tests back to pending I believe this worked only accidentally because we matched more things with wildcards which turned out to be flawed. The test errors show some funky _#_ types, so not sure whether the tests are still valid or not. Moved back to pending awaiting further resolution. --- .../pos/depmet_implicit_oopsla_session.scala | 63 ++++++++++++++++ .../pos/depmet_implicit_oopsla_session_2.scala | 86 ++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 tests/pending/pos/depmet_implicit_oopsla_session.scala create mode 100644 tests/pending/pos/depmet_implicit_oopsla_session_2.scala (limited to 'tests/pending') diff --git a/tests/pending/pos/depmet_implicit_oopsla_session.scala b/tests/pending/pos/depmet_implicit_oopsla_session.scala new file mode 100644 index 000000000..a9c8e56ce --- /dev/null +++ b/tests/pending/pos/depmet_implicit_oopsla_session.scala @@ -0,0 +1,63 @@ +object Sessions { + trait Session[This] { + type Dual + type HasDual[D] = Session[This]{type Dual=D} + def run(p: This, dp: Dual): Unit + } + + implicit object StopSession extends Session[Stop] { + type Dual = Stop + + def run(p: Stop, dp: Stop): Unit = {} + } + + implicit def InDual[A, B](implicit sessionDIn: Session[B]): Sessions.Session[Sessions.In[A,B]]{type Dual = Sessions.Out[A,sessionDIn.Dual]} = + new Session[In[A, B]] { + type Dual = Out[A, sessionDIn.Dual] + + def run(p: In[A, B], dp: Dual): Unit = + sessionDIn.run(p.func(dp.x), dp.y) + } + + implicit def OutDual[A, B](implicit sessionDOut: Session[B]): Sessions.Session[Sessions.Out[A,B]]{type Dual = Sessions.In[A,sessionDOut.Dual]} = + new Session[Out[A, B]] { + type Dual = In[A, sessionDOut.Dual] + + def run(p: Out[A, B], dp: Dual): Unit = + sessionDOut.run(p.y, dp.func(p.x)) + } + + sealed case class Stop() + sealed case class In[-A, +B](func: A => B) + sealed case class Out[+A, +B](x: A, y: B) + + def addServer = + In{x: Int => + In{y: Int => System.out.println("Thinking") + Out(x + y, + Stop())}} + + def addClient = + Out(3, + Out(4, { System.out.println("Waiting") + In{z: Int => System.out.println(z) + Stop()}})) + + def runSession[S, D: Session[S]#HasDual](p: S, dp: D) = + implicitly[Session[S]#HasDual[D]].run(p, dp) + + // def runSession[S, D](p: S, dp: D)(implicit s: Session[S]#HasDual[D]) = + // s.run(p, dp) + // + // def runSession[S, D](p: S, dp: D)(implicit s: Session[S]{type Dual=D}) = + // s.run(p, dp) + + // TODO: can we relax the ordering restrictions on dependencies so that we can use + // def runSession[S](p: S, dp: s.Dual)(implicit s: Session[S]) = + // s.run(p, dp) + // to emphasise similarity of type parameters and implicit arguments: + // def runSession[S][val s: Session[S]](p: S, dp: s.Dual) = + // s.run(p, dp) + + def myRun = runSession(addServer, addClient) +} diff --git a/tests/pending/pos/depmet_implicit_oopsla_session_2.scala b/tests/pending/pos/depmet_implicit_oopsla_session_2.scala new file mode 100644 index 000000000..fcf18691a --- /dev/null +++ b/tests/pending/pos/depmet_implicit_oopsla_session_2.scala @@ -0,0 +1,86 @@ +object Sessions { + + // session states + sealed case class Stop() + sealed case class In[-Data, +Cont](recv: Data => Cont) + sealed case class Out[+Data, +Cont](data: Data, cont: Cont) + + // the type theory of communicating sessions: + + // an instance of type Session[S]{type Dual=D} is evidence that S and D are duals + // such a value witnesses this fact by describing how to compose an instance of S with an instance of D (through the run method) + trait Session[S] { type Self = S + type Dual + type HasDual[D] = Session[Self]{type Dual=D} + def run(self: Self, dual: Dual): Unit + } + + // friendly interface to the theory + def runSession[S, D: Session[S]#HasDual](session: S, dual: D) = + implicitly[Session[S]#HasDual[D]].run(session, dual) + + // facts in the theory: + + // ------------------------[StopDual] + // Stop is the dual of Stop + implicit object StopDual extends Session[Stop] { + type Dual = Stop + + def run(self: Self, dual: Dual): Unit = {} + } + + // CD is the dual of Cont + // -------------------------------------------[InDual] + // Out[Data, CD] is the dual of In[Data, Cont] + implicit def InDual[Data, Cont](implicit cont: Session[Cont]): Sessions.Session[Sessions.In[Data,Cont]]{type Dual = Sessions.Out[Data,cont.Dual]} = new Session[In[Data, Cont]] { + type Dual = Out[Data, cont.Dual] + + def run(self: Self, dual: Dual): Unit = + cont.run(self.recv(dual.data), dual.cont) + } + + // CD is the dual of Cont + // -------------------------------------------[OutDual] + // In[Data, CD] is the dual of Out[Data, Cont] + implicit def OutDual[Data, Cont](implicit cont: Session[Cont]): Sessions.Session[Sessions.Out[Data,Cont]]{type Dual = Sessions.In[Data,cont.Dual]} = new Session[Out[Data, Cont]] { + type Dual = In[Data, cont.Dual] + + def run(self: Self, dual: Dual): Unit = + cont.run(self.cont, dual.recv(self.data)) + } + + // a concrete session + def addServer = + In{x: Int => + In{y: Int => System.out.println("Thinking") + Out(x + y, + Stop())}} + + def addClient = + Out(3, + Out(4, { System.out.println("Waiting") + In{z: Int => System.out.println(z) + Stop()}})) + + def myRun = runSession(addServer, addClient) +} + +/* future improvements: + + + // def runSession[S, D](p: S, dp: D)(implicit s: Session[S]#HasDual[D]) = + // s.run(p, dp) + // + // def runSession[S, D](p: S, dp: D)(implicit s: Session[S]{type Dual=D}) = + // s.run(p, dp) + + // TODO: can we relax the ordering restrictions on dependencies so that we can write + // one possibility: graph of dependencies between arguments must be acyclic + // def runSession[S](p: S, dp: s.Dual)(implicit s: Session[S]) = + // s.run(p, dp) + // to emphasise similarity of type parameters and implicit arguments: + // def runSession[S][val s: Session[S]](p: S, dp: s.Dual) = + // s.run(p, dp) + + +*/ -- cgit v1.2.3