It seems to me you have to do a lot of hacky stuff to get around the "ugly" 
API as you call it.

Maybe it'd be better to separate out the ObjectSupport class into two 
separate classes, a HasherSupport class and an EqualsSupport class.

interface HashSupport<T> {
    public static <T> HashSupport<T> of(Lookup lookup, String... fields) {
        var mh = createMh(lookup, fields);
        return (obj) -> {
            mh.invokeExact(obj);
        };
    }
    int hashCode(T obj);
}

and similar for EqualsSupport.

I feel like ObjectSupport is a bit nebulous and open ended and you'd 
inevitably end up needing more support methods such as a toString method.


On Friday, April 26, 2019 at 8:13:17 AM UTC-7, Remi Forax wrote:
>
>
>
> ------------------------------
>
> *De: *"Steven Stewart-Gallus" <[email protected] <javascript:>>
> *À: *"mechanical-sympathy" <[email protected] <javascript:>>
> *Envoyé: *Vendredi 26 Avril 2019 01:51:47
> *Objet: *Re: Exotic classes
>
>
> Hi Steven,
> thanks for spending some time on this,
>
>
> 1. Why 
> publicabstractclassObjectSupport{
> publicabstractboolean equals(Objectself,Object other);
> publicabstractint hashCode();
> publicstaticObjectSupport of(Lookup lookup,String... fields){
> // impl details
> }
> // impl details
> }
>
> and not something like?
> interfaceObjectSupport<T>{
> publicboolean equals(T self, T other);
> publicint hashCode(T obj);
> publicstatic<T, U extendsObjectSupport<T>>T of(Lookup lookup,Class<U> 
> iface,Class<T> obj){
> // impl details
> }
> }
> @Retention(RetentionPolicy.RUNTIME)
> @Target(ElementType.FIELD)
> @interfaceObjectSupportField{
> }
>
>
> There are three questions, why not use an interface, why not use generics 
> to make the API more typesafe and why not use an annotation to mark the 
> fields,
> (1), it should be an interface, yes :
> (2), yes, the API can be more typesafe, i've implemented that. BTW, the 
> correct type of equals() if generified is (T, Object), because you can call 
> equals(Person, String), it should return false.
> (3),the API you propose can be built on top of the existing one, that's 
> why there is an overload of ObjectSupport.of() that takes a function as 
> third parameter
>      see 
> https://github.com/forax/exotic/blob/master/src/test/java/com.github.forax.exotic/com/github/forax/exotic/ObjectSupportTests.java#L310
>
> so i've updated the code according to (1) and (2).
>
> 2. I don't understand why you can't use 
> https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.Lookup.html#defineClass-byte:A-
>  instead 
> of unsafe. If you can use 
> https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html
>  things 
> might be easier to optimise because the VM doesn't trust nonstatic final 
> fields but I don't think you'll need to rely on that.
>
>
> I need a VM anonymous class otherwise the method handles used to implement 
> equals and hashCode are not considered as constant by the JIT. A previous 
> version of the API was using one lambdas for equals and one for hashCode,
> but it makes the API ugly. see 
> https://github.com/forax/exotic/commit/168736c43f32520ef6e280db174bf8a848ee4421#diff-0b01bd4ba5740e6b300bfa38e337dd71R13
>
> 3. The raw class file isn't always available at runtime so you can't 
> necessarily use ObjectSupportImpl as a template.
>
>
> yes, i will inline it (storing it as an array of bytes inside the Java 
> code) once the API is stable enough.
>
> 4. 
> https://github.com/forax/exotic/blob/master/src/main/java/com.github.forax.exotic/com/github/forax/exotic/ObjectSupport.java#L180
>  Pretty 
> sure you want a static final field here. You can do that if you're using 
> ObjectSupportImpl as a raw template. Unfortunately defineClass doesn't 
> accept arguments so you have to use wonky garbage like a hashmap to pass 
> runtime data that can't be embedded in a class file easily.
>
>
> No need for static fields there because ObjectSupportImpl is loaded as a 
> VM anonymous class, so the instance fields are considered as constant if 
> the object itself is a constant (see the answer to your question 2).
>
> There is a JMH test if you want to take a look to the generated assembly 
> code
>
> https://github.com/forax/exotic/blob/master/src/test/java/com.github.forax.exotic/com/github/forax/exotic/perf/ObjectSupportBenchMark.java
>
> regards,
> Rémi
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected] <javascript:>.
> For more options, visit https://groups.google.com/d/optout.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to