Typing manifold.deferred.Deferred

18 views
Skip to first unread message

Atamert Ölçgen

unread,
Jul 31, 2015, 5:40:23 AM7/31/15
to clojure-c...@googlegroups.com
Hi,

I am trying to annotate manifold.deferred/deferred etc.

(t/ann ^:no-check manifold.deferred/deferred [-> manifold.deferred.Deferred])

This works, but I would also like to be able to type the result of Deferred. So I have read all I could find and tried to retrofit higher-kinded variables example:

(t/defalias TDeferred
  (t/TFn [[d :< (t/TFn [[x :variance :covariant]] manifold.deferred.Deferred)]]
         '{:deref (t/All [x]
                         [(d x) -> x])}))

I don't think I actually understand this. My interpreration is:

  • d is a type constructor that takes one parameter and returns a Deferred.
  • Outer TFn wraps this d stating that derefing a (d x) would result in an x for all values of x.

Is this correct? Am going about this the wrong way? Is TFn explained in more detail somewhere else?

BTW, the error I'm getting is:

Type Error (...) Internal Error (...) Invalid variance: :inferred

it points to the (t/defalias ...) line.



--
Kind Regards,
Atamert Ölçgen

◻◼◻
◻◻◼
◼◼◼

www.muhuk.com

Ambrose Bonnaire-Sergeant

unread,
Jul 31, 2015, 5:43:00 AM7/31/15
to core.typed
I think you're on the right track, try annotating the variance of `d` to be :invariant or :covariant.

Thanks,
Ambrose

Atamert Ölçgen

unread,
Jul 31, 2015, 6:06:49 AM7/31/15
to clojure-c...@googlegroups.com

On Fri, Jul 31, 2015 at 1:01 PM, Atamert Ölçgen <mu...@muhuk.com> wrote:
Thanks Ambrose! Adding :variance :invariant worked.

I get an error when I try to use it though:

(t/ann ^:no-check manifold.deferred/deferred (t/All [a] [-> (TDeferred a)]))


(t/defalias TDeferred
  (t/TFn [[d :variance :invariant :< (t/TFn [[x :variance :covariant]] manifold.deferred.Deferred)]]
         '{:deref (t/All [x]
                         [(d x) -> x])}))


(t/ann f [-> (TDeferred t/Num)])

(defn f []
  (deferred/deferred))

The error is:

Type Error (...) Internal Error (...) Invalid operator to type application: (t/Num (B 0))

Shouldn't a in manifold.deferred/deferred's annotation assumed to be t/Num?

Ambrose Bonnaire-Sergeant

unread,
Jul 31, 2015, 6:14:00 AM7/31/15
to core.typed
t/Num is not a TFn, so (TDeferred t/Num) seems wrong. What is the type you want to expand to?

Atamert Ölçgen

unread,
Jul 31, 2015, 6:18:48 AM7/31/15
to clojure-c...@googlegroups.com
I see what I've done wrong (two TFn's).

This passes the check:

(t/defalias TDeferred
  (t/TFn [[x :variance :covariant]]
         (t/I manifold.deferred.Deferred
              '{:deref (t/All [x]
                         [(TDeferred x) -> x])})))

My intention is that it's an instance of m.d.Deferred AND that defer works as such. Does it make sense?

Ambrose Bonnaire-Sergeant

unread,
Jul 31, 2015, 6:21:39 AM7/31/15
to core.typed
Can you enumerate a couple of fully expanded types that you want to abstract over?

Thanks,
Ambrose

Atamert Ölçgen

unread,
Jul 31, 2015, 10:13:46 PM7/31/15
to clojure-c...@googlegroups.com
My current code is a bit broken right now. As deferred is not exactly delay, it can succeed or fail. So I probably need a union or something eventually. But let's assume there's no failure for now.

I would like to denote (TDeferred t/Num) to have a type m.d.Deferred (which is not parametrized) and at the same time calling deref on it should give me a t/Num. Am I wrong assuming the underlying type m.d.Deferred not having parametrized is not a problem here?

I am not exactly sure what you mean by fully expanded types. (TDeferred a) with some value of a is as expanded as I can think of. And a can be t/Any.

As to how it works runtime; (deferred/deferred) returns an m.d.Deferred. Then (deferred/success! a-deferred some-value) sets its value to be some-value and anything that's blocking on a-deferred (just like any other dereffable) would get this value. I was hoping parametrizing (deferred/deferred) as well as (deferred/success!) would do the trick. (Since I have a qualified (TDeferred t/Num) in function's annotation.)

Atamert Ölçgen

unread,
Jul 31, 2015, 10:13:47 PM7/31/15
to clojure-c...@googlegroups.com
Thanks Ambrose! Adding :variance :invariant worked.

I get an error when I try to use it though:

(t/ann ^:no-check manifold.deferred/deferred (t/All [a] [-> (TDeferred a)]))


(t/defalias TDeferred
  (t/TFn [[d :variance :invariant :< (t/TFn [[x :variance :covariant]] manifold.deferred.Deferred)]]
         '{:deref (t/All [x]
                         [(d x) -> x])}))


(t/ann f [-> (TDeferred t/Num)])

(defn f []
  (deferred/deferred))

The error is:

Type Error (...) Internal Error (...) Invalid operator to type application: (t/Num (B 0))

Shouldn't a in manifold.deferred/deferred's annotation assumed to be t/Num?

On Fri, Jul 31, 2015 at 12:42 PM, Ambrose Bonnaire-Sergeant <abonnair...@gmail.com> wrote:

Ambrose Bonnaire-Sergeant

unread,
Jul 31, 2015, 10:28:22 PM7/31/15
to core.typed
On Fri, Jul 31, 2015 at 6:31 PM, Atamert Ölçgen <mu...@muhuk.com> wrote:
My current code is a bit broken right now. As deferred is not exactly delay, it can succeed or fail. So I probably need a union or something eventually. But let's assume there's no failure for now.

I would like to denote (TDeferred t/Num) to have a type m.d.Deferred (which is not parametrized) and at the same time calling deref on it should give me a t/Num. Am I wrong assuming the underlying type m.d.Deferred not having parametrized is not a problem here?

By fully expanded, I mean the above english description, but in core.typed types.

It does sound like Deferred needs to be parameterised. I'm not sure if this is possible yet, how did you annotate Deferred?

Atamert Ölçgen

unread,
Aug 1, 2015, 1:27:29 AM8/1/15
to clojure-c...@googlegroups.com
I am using TDeferred in place of Deferred, like so:

(t/ann f [-> (TDeferred t/Num)])

If I don't parametrise Deferred somehow, I would effectively have a deferred t/Any as the return type. The result is deferred, but it's also something specific.

Actually I kept saying Deferred is like Delay but it's actually more like a Future. So (in scala terms) a return type of Deferred is like a Future[Any].


Reply all
Reply to author
Forward
0 new messages