               (reify org.apache.spark.api.java.function.FlatMapFunction ; todo: skip api.java.* go to spark
                 (call [_ it] 
                   (compile-cond
-                    (has-method? org.apache.spark.api.java.function.FlatMapFunction [java.util.Iterator "call" [Object]])
+                    (has-method? org.apache.spark.api.java.function.FlatMapFunction '[java.util.Iterator "call" [?]])
                     (.iterator ((df) it))
-                    (has-method? org.apache.spark.api.java.function.FlatMapFunction [Iterable "call" [Object]])
+                    (has-method? org.apache.spark.api.java.function.FlatMapFunction '[Iterable "call" [?]])
                     ((df) it))))
               preserve-partitioning)]
     rdd))

       ([] (rf))
       ([acc] (rf acc))
       ([acc left right] (rf acc left (.or (compile-cond
                                            (has-method? org.apache.spark.api.java.JavaPairRDD
                                                         (partial left-outer-join-optional "org.apache.spark.api.java.Optional"))
                                            ^org.apache.spark.api.java.Optional right
                                            (has-method? org.apache.spark.api.java.JavaPairRDD
                                                         (partial left-outer-join-optional "com.google.common.base.Optional"))
                                            ^com.google.common.base.Optional right)
                                           not-found)))))))

(defn ^org.apache.spark.api.java.JavaRDD join
  "Performs a join between two rdds, each rdd may be followed by ':or default-value'.

        ([] (rf))
        ([acc] (rf acc))
        ([acc left right] (rf acc (.or (compile-cond
                                         (has-method? org.apache.spark.api.java.JavaPairRDD
                                           '[[org.apache.spark.api.java.JavaPairRDD ? [scala.Tuple2 ? org.apache.spark.api.java.Optional]]
                                             "leftOuterJoin" [?]])
                                         ^org.apache.spark.api.java.Optional left
                                         (has-method? org.apache.spark.api.java.JavaPairRDD
                                           '[[org.apache.spark.api.java.JavaPairRDD ? [scala.Tuple2 ? com.google.common.base.Optional]]
                                             "leftOuterJoin" [?]])
                                         ^com.google.common.base.Optional left)
                                    not-found) right))))))

(defn- default-right
  "Returns a stateless transducer on pairs which expects Optionals in value position, unwraps their values or return not-found when no value."
