Clojure deftype: ¿cómo restringir los tipos de campo?

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?

preguntado el 25 de agosto de 12 a las 15:08

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? -

2 Respuestas

De on deftype y defrecord:

fields can have type hints, and can be primitive

tenga en cuenta que 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

se planea restringir el tipo de campo y el constructor arg

(mi énfasis)

Respondido 25 ago 12, 16:08

So there is no way to constrain the field type? - Frederik

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

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

Respondido 25 ago 12, 15:08

I tested this and it seems that "#^Integer" does exactly the same as "^Integer". - Frederik

Those are the same thing - #^ is the old syntax and ^ is the new syntax. - Alex Miller

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.