See for example
http://jscience.org/api/org/jscience/mathematics/structure/Field.html
and
http://jscience.org/api/org/jscience/mathematics/number/Float64.html.
Now you cannot just use Double as to use
http://jscience.org/api/org/jscience/mathematics/function/Polynomial.html you 
need to have a type that implements Ring. Then you needed to perform a few 
operations on polynomial and feed it to different library which had it own 
interfaces for float. You cannot just add static method as you're not an user 
of it - the other component is so using interface to abstract numeric 
operations, so function is not a viable workaround (BTW - I don't remember if 
jscience is one of libraries which I've used - they just appeared as one of 
first in Google).

And sure, in ideal world all packages would have one interface but it
wasn't something I controlled or anyone remotely connected with project.
And I wasn't somehow inclined to rewrite 2 libraries.

Another example would be interface which could be implemented in terms
of another. So interface A is subset of B. You could make A a
subinterface of B but it isn't and it is not something you control (for
example first project don't want to depend on second, or does not know
of its existence, or the work is in progress but it hasn't been done
yet).

If you happen to have control over whole system you're in much easier
situation as you can make a single sane hierarchy. If you don't and you
try to pull a few external libraries to work together as a small
component of a larger project it's much more of a problem.

Best regards

On Tue, 2014-03-11 at 15:00 -0500, Evan G wrote:
> I still don't a hundred percent understand... what interface could
> there be that doesn't require the object to store the state necessary
> to implement it? I mean, anything else is really just a function,
> instead of 60.days_after(date) use days_after(60, date).
> 
> 
> On Tue, Mar 11, 2014 at 2:51 PM, Maciej Piechotka
> <uzytkown...@gmail.com> wrote:
>         On Tue, 2014-03-11 at 14:37 -0500, Evan G wrote:
>         > ... Why didn't they just extend Number? (Or, at worst, that
>         was a bad
>         > design decision on Oracle's part, by choosing to make the
>         Float class
>         > final)
>         >
>         > Either way, I don't see how that's a fault of the language.
>         >
>         >
>         
>         
>         I don't remember - maybe they had, but it wouldn't solved the
>         problem.
>         And Float is final - and even if it hadn't been it wouldn't
>         solve the
>         problem at all. Assume that Float is not final and they did
>         extended
>         Number.
>         
>          - Platform P provides interface PI and object PO (say Number
>         and Float)
>          - Component A provided and required interface AI and object
>         AO
>         extending PO and implementing AI and PI
>          - Component B provided and required interface BI and object
>         AO
>         extending PO and implementing BI and PI
>         
>         Now you cannot pass object AO to component B as it requires
>         BI. You need
>         either:
>          - Provide adapter from AI to BI (or other way round) which
>         implements
>         AI, BI and PI
>          - Each time convert from AO to BO when you transfer between
>         interfaces
>         In proposed interface there would be only second option due to
>         single
>         inheritance.
>         
>         On the other hand with traits:
>          - Platform P provides interface PI and object PO
>          - Component A provides and requires interface AI and
>         implements AI for
>         PO (there is no need for adding AI as PO is 'open' for trait
>         implementation)
>          - Component B provides and requires interface BI and
>         implements BI for
>         PO (there is no need for adding BI as PO is 'open' for trait
>         implementation)
>         The user needs to do:
>          - Nothing. Everything works out of the box
>         
>         And before you ask - component A and B were 2 different
>         libraries for
>         which the Oracle interfaces were insufficient.
>         
>         Best regards
>         
>         >
>         > On Tue, Mar 11, 2014 at 2:35 PM, Maciej Piechotka
>         > <uzytkown...@gmail.com> wrote:
>         >         On Tue, 2014-03-11 at 19:09 +0000, Bill Myers wrote:
>         >         > I see a proposal to add "virtual struct" and
>         "virtual fn" in
>         >         the workweek meeting notes, which appears to add an
>         exact copy
>         >         of Java's OO system to Rust.
>         >         >
>         >         > I think however that this should be carefully
>         considered,
>         >         and preferably not added at all (or failing that,
>         feature
>         >         gated and discouraged).
>         >         >
>         >         > The core problem of "virtual functions" (shared by
>         Java's
>         >         classes, etc.) is that rather than exposing a single
>         public
>         >         API, they expose two: the API formed by public
>         functions, and
>         >         the API formed by virtual functions to be overridden
>         by
>         >         subclasses, and the second API is exposed in an
>         inflexible and
>         >         unclean way.
>         >         >
>         >         > A much better way of allowing to override part of
>         a struct's
>         >         behavior is by defining a trait with the overridable
>         >         functionality, and allowing to pass in an
>         implementation of
>         >         the trait to the base class, while also providing a
>         default
>         >         implementation if desired.
>         >         >
>         >         > Another way is to have the "subclass" implement
>         all the
>         >         traits that the "base class" implements, include a
>         field of
>         >         the "base class" type, and then direct all
>         non-overridden
>         >         functionality to the "base class" (here syntax sugar
>         can be
>         >         easily added to eliminate the boilerplate, by
>         automatically
>         >         implementing all non-implemented trait functions by
>         calling
>         >         the same function on the base class field).
>         >         >
>         >         > These approaches can be combined, as the first
>         approach
>         >         allows to change the "inside" behavior of the base
>         class,
>         >         while the second one allows to put extra behavior
>         "around" the
>         >         base class code.
>         >         >
>         >         > The fact that OO using virtual functions (as
>         opposed to
>         >         traits) is a bad design is one of the crucial steps
>         forward of
>         >         the design of languages like Go and current Rust
>         compared to
>         >         earlier OO languages, and Rust should not go
>         backwards on
>         >         this.
>         >         >
>         >         > Here is a list of issues with virtual functions:
>         >         >
>         >         > 1. Incentive for bad documentation
>         >         >
>         >         > Usually there is no documentation for how virtual
>         functions
>         >         are supposed to be overridden, and it as awkward to
>         add it
>         >         since it needs to be mixed with the documentation on
>         how to
>         >         use the struct
>         >         >
>         >         > 2. Mishmashing multiple unrelated APIs
>         >         >
>         >         > With traits, you could pass in multiple objects to
>         implement
>         >         separate sets of overridable functionality; with
>         virtual
>         >         structs you need to mishmash all those interfaces
>         into a
>         >         single set of virtual functions, all sharing data
>         even when
>         >         not appropriate.
>         >         >
>         >         > 3. No encapsulation
>         >         >
>         >         > Private data for virtual function implementations
>         is
>         >         accessible to all other functions in the struct.
>         >         >
>         >         > This means for instance that if you have a virtual
>         function
>         >         called "compute_foo()" that is implemented by
>         default by
>         >         reading a "foo" field in the base class, then all
>         other parts
>         >         of the base class can access "foo" too.
>         >         >
>         >         > If anything else accesses mistakenly "foo"
>         directly, which
>         >         it can, then overriding "compute_foo()" will not
>         work as
>         >         expected.
>         >         >
>         >         > If compute_foo() were provided by an external
>         trait
>         >         implementation, then "foo" would be private and
>         inaccessible,
>         >         eliminating the problem.
>         >         >
>         >         > 4. Data for overridden implementations left there
>         in a
>         >         "zombie" state.
>         >         >
>         >         > In the above example, if you override
>         "compute_foo()", the
>         >         foo variable in the base class will no longer be
>         used, yet it
>         >         will still be present in the type and allocated in
>         memory.
>         >         >
>         >         > 5. Inability to statically dispatch
>         >         >
>         >         > With a trait implementation, you can pass the
>         concrete type
>         >         as a generic parameter, allowing static dispatch.
>         >         >
>         >         > If you instead call an overridable virtual
>         function, then
>         >         you can't dispatch that statically at all (unless
>         you add
>         >         cumbersome syntax for that).
>         >         >
>         >         > 6. Adds a ton of unnecessary complexity to the
>         language
>         >         >
>         >
>         >
>         >         7. Harder interoperability. For example I've
>         encountered at
>         >         least 2
>         >         Float interfaces for Java from 2 different libraries
>         (both
>         >         trying to
>         >         abstract over Float) which I need to use in one of
>         my projects
>         >         (long
>         >         story) - either one needed to have an adapter or
>         there was a
>         >         need to
>         >         convert float to float. In total there were 3 32-bit
>         floats
>         >         representation in single function counting also the
>         float.
>         >         With traits
>         >         they would just add implementation to Java's float.
>         >
>         >         Best regards
>         >
>         >         _______________________________________________
>         >         Rust-dev mailing list
>         >         Rust-dev@mozilla.org
>         >         https://mail.mozilla.org/listinfo/rust-dev
>         >
>         >
>         >
>         >
>         
> 
> 
> 

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to