10

I'm trying to write a Clojure library that can be used from Java without users knowing it is written in Clojure. For this, I need my fields to have proper types:

I like that I can do this:

(deftype Point [^double x ^double y])

Which generates a class with proper types for x/y. However, this only seems to work for primitives, not for classes:

(deftype Foo [^String bar])

Generates a:

public final Object bar;

where I would expect a:

public final String bar;

Is there a way to constrain the field types? Is there another option outside of deftype/defrecord?

Frederik
  • 14,156
  • 10
  • 45
  • 53
  • Are you sure it's not easier just to declare your types in java? Presumably, to preserve the 'users don't know it's clojure' you'll want to generate javadocs etc. Defining thin interfaces, value types etc. in java and then extend them as necessary in the clojure domain? – sw1nn Aug 26 '12 at 09:49

2 Answers2

12

From http://clojure.org/datatypes on deftype and defrecord:

fields can have type hints, and can be primitive

note that currently a type hint of a non-primitive type will not be used to constrain the field type nor the constructor arg, but will be used to optimize its use in the class method

constraining the field type and constructor arg is planned

(my emphasis)

Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53
  • So there is no way to constrain the field type? – Frederik Aug 25 '12 at 18:36
  • AFAIK, you can't do that using deftype alone. Your options here are either implement a typed java Interface using proxy/reify (meaning you must use only methods as your public API), or use gen-class if you really need typed, public fields. – Joost Diepenmaat Aug 25 '12 at 19:51
0

Maybe try to do in this way: (deftype Point [#^Integer x #^Integer y])

Adam Sznajder
  • 9,108
  • 4
  • 39
  • 60