Thanks Chris for your excellent explanation! Personally I like the way we 
separate the world that Scala and Java shares so Java developers don't have to 
think of how to use "Scala" in order to write Java code. I think usability for 
Java users and Scala users is the most important tasks we need to take care of. 
A poor usability on these APIs will make them say "good bye" to a language 
(like the feedback from "Zhihu"). In that case, the Java wrapper design 
significantly hide the "unfriendly" Scala API and create a wall that Scala 
users won't have to use them. So I would +0.5 for Andrews Approach. I also vote 
for plan 2) since the new secret Java Macros do a bunch of changes that makes 
them way different than Scala Macros.

But here I quote some point that Naveen mentioned me offline:
1. Compile time problem: The current build pipeline already takes a long time 
to compile the code base with adding more and more to make Java ready. Although 
we narrow down the scope of development to just Java Inference API. Future 
development will still requires a bunch of Java methods being added. It also 
makes the code base redundant a little bit. It will also introduce a "fat jar" 
for both Scala and Java users.
2. The development and maintenance cost: These code would cost a lot of times 
to develop and maintain than implementing them directly in Scala.

Here are the two biggest shortcomings if we go this way. These need to be 
carefully considered and avoided in the implementation.

--------------------------------------------------- Break line for Code Gen 
demo time ------------------
I am also a developer working on Scala Macros a long time. Here I would like to 
show the usability improvement we have taken to Java users.

In v1.3, we delivered the Type-safe API which allows Scala user to do something 
like:
Symbol.api.FullyConnected(data = Some(data), num_hidden = 128, name = "fc1")
Rather than the old API:
Symbol.FullyConnected("fc1")()(Map("data" -> data, "num_hidden" -> 128))

The scenario for Java user to use this API is:
1. Option is not introduced in Java and the closest Class is Optional however 
introduced in 1.8 (we support MXNet Scala from 1.7)
2. Too many args field to pass. The sacrificed point from Scala to Java is we 
lose all default field. For some operators, Java user may need to fill in 13 
arguments (e.g BatchNorm) even if they are not willing to do so.

In this case, we have carefully re-invented the Java API with 
Function+Classbuilder generated by Scala Macros:
The new Java operator API will looks like:

(Java)NDArray.BatchNorm(<Required 
args>).set<OptionalArg>(<OptionalArg>).invoke()

In this case, all generated operators for Java will create a operatorBuilder 
(BatchNormBuilder in above examples). The builder's setter will direct Java 
users what are the optional field they can pass and the Builder constructor 
clearly identify the required field for the operators. The only shortcoming for 
this api is that user has to call a method "invoke()" to get it run, where the 
invoke method would collect all args and call JNI code.

Thanks,
Qing


On 9/27/18, 8:53 PM, "Chris Olivier" <cjolivie...@apache.org> wrote:

    My $0.02 since I’m working with a lot of java and scala lately, including
    the interaction between the two:
    
    Please keep in mind the more complex dependency issues that will be
    introduced by requiring Java users to now have to pull in a large scala
    dependency base. In addition, a lot is Scala is compiler-dependent  with
    different jars for 2.10,2.12,etc. and so they’re in different places than
    the regular jars and having a Java person suddenly have to deal with this
    is a good way to make him say “no thanks”.  My day job build and runtime
    environment systems, for instance, don’t handle the mixing very well
    without having to hack a bunch of build files and even then it causes
    problems from time to time.  Scala experts won’t have problems but it’s a
    steep learning curve for Java (or C++) folks.
    
    On Thu, Sep 27, 2018 at 6:14 PM YiZhi Liu <eazhi....@gmail.com> wrote:
    
    > I vote for "2.) Leave the existing macro in place and add another
    > which generates a Java friendly version"
    >
    > @Qing @Andrew, could you give some examples, so that people can better
    > understand how it provides "best possible experience" to Java users.
    >
    > I have no strong preference between having JavaShape & JavaContext or not.
    > On Thu, Sep 27, 2018 at 5:56 PM Andrew Ayres <andrew.f.ay...@gmail.com>
    > wrote:
    > >
    > > That's not really the conversation I'm wanting to have. I want a
    > discussion
    > > about the macros with respect to NDArray so that we can get agreement on
    > > our path forward with respect to implementing the NDArray wrapper.
    > >
    > > The design that was put forth and agreed to was for a a Java wrapper
    > around
    > > the Scala API. Adding a bunch of Java friendly methods inside the Scala
    > > code would create a mess for users. Maintenance would be essentially the
    > > same for both because either way you're going to be updating Java 
methods
    > > when you make Scala changes.
    > >
    > > Let's please stick with the issue in the original email.
    > >
    > > Thanks,
    > > Andrew
    > >
    > > On Thu, Sep 27, 2018 at 5:22 PM Qing Lan <lanking...@live.com> wrote:
    > >
    > > > I would like to loop this back a layer. Current, there is a discussion
    > in
    > > > the MXNet Scala community on the ways to implement the Java APIs.
    > Currently
    > > > there are two thoughts:
    > > >
    > > > 1. Make Scala Java Friendly (Create Java compatible methods in the
    > Scala
    > > > Class. such as NDArray with Java compatible constructor)
    > > > 2. Make Java friendly wrappers in Scala (Andrew's explanation below)
    > > >
    > > > The first approach require minimum input from our side to implement
    > > > however bring user a bunch of useless api they may not want to use. It
    > also
    > > > makes Scala package heavier. The good thing is these two packages
    > require
    > > > minimum maintenance cost. As a tradeoff, if any time in the future we
    > want
    > > > to make Java big (make Java as the primary language supported by
    > MXNet),
    > > > then the migration from Scala to Java will be harmful. Spark consider
    > this
    > > > carefully and decide not to change much on their Scala code base to
    > make it
    > > > more Java.
    > > >
    > > > The second approach will make unique NDArray, Shape, Context and more.
    > The
    > > > good thing about this is we can always holds a version control on 
Java.
    > > > Some breaking changes on Scala may not influence much on Java. It did
    > the
    > > > best way to decouple the module and good for us to build unique
    > pipeline
    > > > for Java. The bad thing with this design is the maintenance cost as we
    > need
    > > > to keep two code bases, but it also make Java side easy to change to
    > make
    > > > it better compatible with users.
    > > >
    > > > Thanks,
    > > > Qing
    > > >
    > > > On 9/27/18, 3:25 PM, "Andrew Ayres" <andrew.f.ay...@gmail.com> wrote:
    > > >
    > > >     Hi,
    > > >
    > > >     Currently, we're working to implement a new Java API and would 
like
    > > > some
    > > >     feedback from the community on an implementation detail. In short,
    > the
    > > > new
    > > >     Java API will use the existing Scala API (in a manner similar to
    > how
    > > > the
    > > >     current Clojure API works). This basically means that we're making
    > Java
    > > >     friendly wrappers to call the existing Scala API.
    > > >
    > > >     The feedback we're looking for is on the implementation of 
NDArray.
    > > > Scala's
    > > >     NDArray has a significant amount of code which is generated via
    > macros
    > > > and
    > > >     we've got two viable paths to move forward:
    > > >
    > > >     1.) Change the macro to generate Java friendly methods  - To do
    > this
    > > > we'll
    > > >     modify the macro so that the generated methods won't have
    > > > default/optional
    > > >     arguments. There may also have to be some changes to parameter
    > types to
    > > >     make them Java friendly. The big advantage here is that ongoing
    > > > maintenance
    > > >     will easier. The disadvantages are that we'll be changing the
    > existing
    > > >     Scala NDArray Infer API (it's marked experimental) and Scala users
    > will
    > > >     lose the ability to use the default and optional arguments.
    > > >
    > > >     2.) Leave the existing macro in place and add another which
    > generates a
    > > >     Java friendly version - The biggest issue here is that we'll be
    > > > doubling
    > > >     the number of macros that we've got to maintain. It'll become even
    > more
    > > >     overhead once we start expanding the Java API with more classes
    > that
    > > > use
    > > >     generated code like this. The advantages are that the existing
    > Scala
    > > >     NDArray Infer API would remain unchanged for Scala users and that
    > the
    > > > new
    > > >     macro could be optimized to give the best possible experience to
    > the
    > > > Java
    > > >     API.
    > > >
    > > >     Thanks,
    > > >     Andrew
    > > >
    > > >
    > > >
    >
    >
    >
    > --
    > Yizhi Liu
    > DMLC member
    > Amazon Web Services
    > Vancouver, Canada
    >
    

Reply via email to