Rust philosophy and OOP

classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Eddy Cizeron
Hello,

I'm new to Rust, and I have some questions concerning some aspects of the
language. From what I understand until now, rust has no dynamic  linkage
for methods as it would be the case in any standard OOP language. This is
surely an intentionaly different philosophy from the current trend among
other recent programming languages. But why not after all. I like the idea.
So I find myself skeptical when I read the chapters of the documentation
about OOP-like concepts like classes or interfaces.

The essence of the "class" concept lies in the possibility to gather a data
structure (a type) and the related processes that can act on the
corresponding instances (methods) in a single bundle. But, tell me if you
disagree, the only interesting purpose of such an operation is the ability
to use inheritance. If no concept of inheritance exists, I hardly see what
is the need of making functions "pets" for data. All we obtain are
classical design issues like "is my 'f(a,b)' function a 'a.f(b)' method or
a 'b.f(a)' method ?" (and I don't think the rust "resource"
concept requires classes, as destructors or destructor-like functions are
not methods). I'm afraid that the answer is merely to offer a supposedly
"attractive" syntax for OOP users. And I think this would be a weak argument

The concept of interface/implementation in rust is surely different than
the usual one, but again to me it looks like it has some limitations due to
the same reason than above: it tries to look OOP. I could have imagined a
very similar interface concept but that does not focus on a *single *type:

iface shape_drawing<Sf, Sh> {
    fn draw(Sf, Sh);
    fn bounding_box(Sh) -> bounding_box;
}

fn draw_twice<Sf, Sh with shape_drawing<Sf, Sh>>(surface: Sf, shape: Sh) {
    draw(surface, shape);
    draw(surface, shape);
}

Of course this example is a simple one. And any consistent system like this
(if it does exist but I'm pretty sure it does) would have been more complex
than the current one. But also more general and then more powerful.

Let me clear about something: I don't expect anybody to change the current
design. I'm nobody and I know it's always easier to criticize than to do
things. I'm just expressing the feeling that while Rust tried to take a
different direction from all the other new
JVM-compliant-OOP-languages-with-functional-features (which I really really
value very much) it seems it has not got rid of some conceptual patterns
that are not, IMHO, necessary anymore. And I wish people could give their
opinion about this.

Thank you

--
Eddy Cizeron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121006/c33d74f4/attachment.html>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Tim Chevalier
Hi, Eddy --

Traits and impls in Rust are based on type classes, which originated
in Haskell. You may find it interesting to read about type classes:
"Type classes: exploring the design space" by Simon Peyton Jones, Mark
Jones, and Erik Meijer, is a good start:

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674

("Interfaces" have been renamed to "traits" in the soon-to-be-released
Rust 0.4 release, by the way; it looks like you may be looking at the
docs from Rust 0.3.)

Cheers,
Tim

--
Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
"Gains in likability have deep costs in personal integrity." -- Kirk Read

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Daniel Patterson
In reply to this post by Eddy Cizeron
I think saying that objects are only useful in so far as inheritance exists is strange. The point of objects, as I've understood them, is to provide some form of encapsulation - to be able to give limited access to certain data so that you can maintain invariants on the data that are not expressible with a type system (if such a system even exists). Objects can exist without inheritance (and are still useful).

Inheritance seems to solve a different problem - how to write code that targets many different types of objects in a simple way. But inheritance isn't really needed there, just a way to deal with objects that behave like a certain thing, or have a certain "interface". Java's interfaces, and rust's traits, seem to solve this in a better way, because a single type can implement many interfaces (and multiple inheritance is?. just bad).

The only thing that inheritance seems to provide that isn't covered by abstract types (i.e., a module exports a type and not its constructor, so you can use it, but only in the way defined by its interface) and interfaces (traits here, or typeclasses in haskell) seems to be code reuse - i.e., you write a foo, and then a specialized foo that reuses a bunch of code from foo. But you can approximate that pretty well with traits as well (or you can have your "superclass" as an attribute in your "subclass") - and I think you are left with a more flexible system in general. Of course, that's just my opinion (and, I am more of a functional programmer than an OO programmer).

destructors are provided (currently as a drop attribute in a struct), and will (very shortly) be provided by implementing a Drop interface. i.e., you define a drop method, and when the type goes out of scope, or is garbage collected, the method is called. Again, I think this is more flexible, as it means that if you don't need to have a destructor, you don't have to, but any type can have one if it needs it.

I think it is better to think of rust as a functional language than an object oriented language. Granted, these are all just words, and approximations at best (as most languages incorporate things from all over the place), but I think it explains some of the philosophy a little more.

As for your example, you can probably define an implementation for pairs, i.e.:

trait ShapeDrawing<(Sf,Sh)> {
  ?
}

Or even abstract it a little more into:

trait Drawable<A> {
  ?
}

and then:
trait ShapeDrawing<~[Drawable]> {
  ...
}

Etc. I might be mixing up the syntax a little, but the basic idea should be correct. It is certainly a different approach, but I think you'll find that it isn't less powerful (and you may find it to be more flexible - but you may not!).

On Oct 6, 2012, at 2:14 PM, Eddy Cizeron wrote:

>
> Hello,
>
> I'm new to Rust, and I have some questions concerning some aspects of the language. From what I understand until now, rust has no dynamic  linkage for methods as it would be the case in any standard OOP language. This is surely an intentionaly different philosophy from the current trend among other recent programming languages. But why not after all. I like the idea. So I find myself skeptical when I read the chapters of the documentation about OOP-like concepts like classes or interfaces.
>
> The essence of the "class" concept lies in the possibility to gather a data structure (a type) and the related processes that can act on the corresponding instances (methods) in a single bundle. But, tell me if you disagree, the only interesting purpose of such an operation is the ability to use inheritance. If no concept of inheritance exists, I hardly see what is the need of making functions "pets" for data. All we obtain are classical design issues like "is my 'f(a,b)' function a 'a.f(b)' method or a 'b.f(a)' method ?" (and I don't think the rust "resource" concept requires classes, as destructors or destructor-like functions are not methods). I'm afraid that the answer is merely to offer a supposedly "attractive" syntax for OOP users. And I think this would be a weak argument
>
> The concept of interface/implementation in rust is surely different than the usual one, but again to me it looks like it has some limitations due to the same reason than above: it tries to look OOP. I could have imagined a very similar interface concept but that does not focus on a single type:
>
> iface shape_drawing<Sf, Sh> {
>     fn draw(Sf, Sh);
>     fn bounding_box(Sh) -> bounding_box;
> }
>
> fn draw_twice<Sf, Sh with shape_drawing<Sf, Sh>>(surface: Sf, shape: Sh) {
>     draw(surface, shape);
>     draw(surface, shape);
> }
>
> Of course this example is a simple one. And any consistent system like this (if it does exist but I'm pretty sure it does) would have been more complex than the current one. But also more general and then more powerful.
>
> Let me clear about something: I don't expect anybody to change the current design. I'm nobody and I know it's always easier to criticize than to do things. I'm just expressing the feeling that while Rust tried to take a different direction from all the other new JVM-compliant-OOP-languages-with-functional-features (which I really really value very much) it seems it has not got rid of some conceptual patterns that are not, IMHO, necessary anymore. And I wish people could give their opinion about this.
>
> Thank you
>
> --
> Eddy Cizeron
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121006/6a545e1c/attachment.html>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Brian Anderson
In reply to this post by Eddy Cizeron
On 10/06/2012 11:14 AM, Eddy Cizeron wrote:

>
> Hello,
>
> I'm new to Rust, and I have some questions concerning some aspects of
> the language. From what I understand until now, rust has no dynamic
>   linkage for methods as it would be the case in any standard OOP
> language. This is surely an intentionaly different philosophy from the
> current trend among other recent programming languages. But why not
> after all. I like the idea. So I find myself skeptical when I read the
> chapters of the documentation about OOP-like concepts like classes or
> interfaces.

Hi!

I can understand how you would have this perception, as most Rust code
favors using traits as Haskell-style type classes, with static dispatch
(it is more efficient). OO-style dynamic dispatch is an important use
case though, and Rust supports it, but the implementation is not as mature.

On Rust's master branch you can do things like this:

     impl @Circle: Drawable { fn draw() { ... } }

     impl @Rectangle: Drawable { fn draw() { ... } }

     let c: @Circle = @new_circle();
     let r: @Rectangle = @new_rectangle();

     // Cast box things that implement Drawable to boxed Drawables
     draw_all(~[c as @Drawable, r as @Drawable]);

This gives you dynamic dispatch on any Drawable through a managed (@)
vtable (fwiw I don't know if this is the recommended syntax - this is
still in development).

I recommend giving the 0.4 tutorial's section on [generics] a read. It
does a much better job than the 0.3 tutorial at explaining how it all
works. I hope that it will relieve some of your concerns.

[generics]: http://dl.rust-lang.org/doc/tutorial.html#generics

Additionally your concern about resources and classes not needing to be
interrelated is spot on, and that issue will be resolved. In 0.4 still
structs are the only type that contain destructors, but the intent is to
make destructors just an implementation of `trait Drop` (or `Finalize`
maybe).

-Brian



Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Nathan
In reply to this post by Tim Chevalier
On Sat, Oct 6, 2012 at 11:16 AM, Tim Chevalier <catamorphism at gmail.com> wrote:

> Hi, Eddy --
>
> Traits and impls in Rust are based on type classes, which originated
> in Haskell. You may find it interesting to read about type classes:
> "Type classes: exploring the design space" by Simon Peyton Jones, Mark
> Jones, and Erik Meijer, is a good start:
>
> http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674
>
> ("Interfaces" have been renamed to "traits" in the soon-to-be-released
> Rust 0.4 release, by the way; it looks like you may be looking at the
> docs from Rust 0.3.)
>
> Cheers,
> Tim
>

I'm about half-way through this paper, which is a great reference.  Thanks!

I'm curious if multi-parameter traits are anywhere on the rust
roadmap.  I'm not certain about which challenges or restrictions they
may require but perhaps by the time I finish this reference I'll have
a better understanding.

I'd recommend reading the paper if only to see motivating examples of
multi-parameter traits.

Regards,
Nathan

> --
> Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
> "Gains in likability have deep costs in personal integrity." -- Kirk Read
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Eddy Cizeron
Hi everyone

2012/10/6 Tim Chevalier <catamorphism at gmail.com>
> Traits and impls in Rust are based on type classes, which originated
> in Haskell. You may find it interesting to read about type classes:
> "Type classes: exploring the design space" by Simon Peyton Jones, Mark
> Jones, and Erik Meijer, is a good start:
> http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674

Thank you for the reference Tim. I'm not really fluent in Haskell but I
think I understand the concepts and apparently multi-parameter type classes
are very close to what I would expect from Rust interfaces/traits.

2012/10/6 Tim Chevalier <catamorphism at gmail.com>
> ("Interfaces" have been renamed to "traits" in the soon-to-be-released
> Rust 0.4 release, by the way; it looks like you may be looking at the
docs from Rust 0.3.)

Right, I was looking at docs 0.3 but I could not find any newer
documentation.

2012/10/6 Sebastian Sylvan <sebastian.sylvan at gmail.com>
> I strongly feel that the focus on inheritance in (recent) OOP is a
> huge mistake. OOP was originally more about the metaphor of messages
> and objects than inheritance. Inheritance leads to so many bugs and
> [...]
> Interfaces (even trees of them) are great, just not inheritance of
> implementation.

2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st>
> Inheritance seems to solve a different problem - how to write code that
> targets many different types of objects in a simple way. But inheritance
> isn't really needed there,
> [...]
> Of course, that's just my opinion (and, I am more of a functional
programmer than an OO programmer).

Sorry I have not made myself clear enough. My point is absolulety not say
that inheritance is a good/bad/required/unnecessary feature. My point is
that if you're not using it (or at least if you're not using dynamic
linkage), I cannot see where or why OOP concepts and syntax are relevant
anymore. (But apparently there are some attempts to use dynamic linkage
with interfaces and I didn't know that).

Your remark about the metaphor is indeed interesting. Actually I cannot
remember where I had read someone complaining about that. This guy said "I
know what is sending messages, and it's certainly not that". His point was
precisely that this metaphor fails because the notion of message implies
asynchrony (I'm not paralyzed when I'm waiting for a response to a mail)
and this is certainly not the intended meaning in OOP. I agree with this
view.

You both focus on the functional inspiration for Rust. This is good news.
It's obvious to me the functional paradigm has deep roots in the math
world. Which is also good news. But in mathematics nobody wonder if
such-and-such a function is owned by one of its argument and which one. Or
to say it a la OOP, if this function is a method of one of its argument.
This bias, when taken to the extreme, has generaly lead some languages to
syntactical "oddities" (some of my neurones would say "monstrosities")
like: "x = (PI / 4).sin;" or "y = 2.'+'(7);" Can anyone explain me why it
makes more sense to think about this addition as a message sent to 2 with
parameter 7? What does this metaphor makes clearer ? One may justifiably
argue that mathematical concepts are different from everyday life ones. But
I don't think 'file.moveTo(directory)' or 'directory.move(file)' carries
better meaning than 'moveTo(directory, file)'. If you want to express more
efficiently the purpose of every argument of a function, named arguments
are a far better idea.

2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st>
> I think saying that objects are only useful in so far as inheritance
> exists is strange. The point of objects, as I've understood them, is to
> provide some form of encapsulation - to be able to give limited access
> to certain data so that you can maintain invariants on the data that are
> not expressible with a type system (if such a system even exists).
> Objects can exist without inheritance (and are still useful).

This is a question of terminology. Unfortunately in computer science and
programming, definitions are generally fuzzy or/and depend on the author. I
keep the word "encapsulation" for the idea of grouping together data and
functions and personally prefer the expression "data hidding" or "data
accessibility" for the feature you're describing. And the fact is this too
concepts are certainly not as strongly linked as you might think. You can
perfectly imagine a system where data accessibility does not apply to the
exterior of a class but to the exterior of other bundles (modules,
packages, etc). This way you can craft more precisely the accessibility of
multiple types in multiple functions. Classes are not needed for this.

2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st>
> As for your example, you can probably define an implementation for pairs,
i.e.:
> trait ShapeDrawing<(Sf,Sh)> {
>  ?
> }
> [...]
> It is certainly a different approach, but I think you'll find that it
isn't less
> powerful (and you may find it to be more flexible - but you may not!).

Well as long as I have not read some document about traits, any criticism
or any conclusion from me about this would be pointless (I've just noticed
Brian's link to new documentation). But after a first glance it does not
seem to remove the limitations I found in the previous concept of
interfaces. And I'm almost sure that interfaces, as they where explained in
the documentation 0.3 are less powerfull. For the same reason the authors
of the article proposed by Tim explain single-parameter type classes in
Haskell are less powerfull than multi-parameter type classes. I'll come
back as soon as my comprehension of Rust traits will be less superficial
(and after a session of self-flagellation if my premonitions/arguments turn
out to be wrong :-))

2012/10/6 Brian Anderson <banderson at mozilla.com>
> Additionally your concern about resources and classes not needing to be
interrelated
> is spot on, and that issue will be resolved. In 0.4 still structs are the
only type
> that contain destructors, but the intent is to make destructors just an
implementation
> of `trait Drop` (or `Finalize` maybe).

Precisely, I'm not sure that the fact destructors are turned into methods
is good news to me.

Thank you for this stimulating discussion and references

--
Eddy Cizeron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121009/e202d62e/attachment.html>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Lindsey Kuper-2
On Mon, Oct 8, 2012 at 6:19 PM, Eddy Cizeron <eddycizeron at gmail.com> wrote:
> 2012/10/6 Tim Chevalier <catamorphism at gmail.com>
>> ("Interfaces" have been renamed to "traits" in the soon-to-be-released
>> Rust 0.4 release, by the way; it looks like you may be looking at the docs
>> from Rust 0.3.)
>
> Right, I was looking at docs 0.3 but I could not find any newer
> documentation.

It looks like Brian already pointed you to the head-of-the-tree
tutorial, but also, all the in-development docs are linked from
https://github.com/mozilla/rust/wiki/Docs .  (0.4 should land any day
now, too.)

> I'll come back as soon
> as my comprehension of Rust traits will be less superficial (and after a
> session of self-flagellation if my premonitions/arguments turn out to be
> wrong :-))

And, in case nobody has pointed them out yet, here are a couple more resources:

  * An introduction to traits on Patrick's blog:
http://pcwalton.github.com/blog/2012/08/08/a-gentle-introduction-to-traits-in-rust
  * A talk I did in August, with a side-by-side Haskell/Rust
comparison: https://air.mozilla.org/rust-typeclasses

Cheers,
Lindsey

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Joe Groff
In reply to this post by Eddy Cizeron
On Mon, Oct 8, 2012 at 3:19 PM, Eddy Cizeron <eddycizeron at gmail.com> wrote:
> Sorry I have not made myself clear enough. My point is absolulety not say
> that inheritance is a good/bad/required/unnecessary feature. My point is
> that if you're not using it (or at least if you're not using dynamic
> linkage), I cannot see where or why OOP concepts and syntax are relevant
> anymore. (But apparently there are some attempts to use dynamic linkage with
> interfaces and I didn't know that).

One minor non-semantic, non-scientific benefit of OOP syntax over
Algol-style function application syntax is that it's syntactically
more composable?compare `a.foo().bar().bas()`, which reads
left-to-right and composes to the right, to `bas(bar(foo(a)))`, which
reads inside-out and requires bracketing on both sides of an inner
experssion to compose calls. (Of course this only works if your APIs
are designed up front in a "fluent" way, and isn't quite as flexible
as what you can do with combinators in ML or Haskell.)

-Joe

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Nathan
In reply to this post by Eddy Cizeron
Hello,


On Mon, Oct 8, 2012 at 3:19 PM, Eddy Cizeron <eddycizeron at gmail.com> wrote:

> Hi everyone
>
> 2012/10/6 Tim Chevalier <catamorphism at gmail.com>
>> Traits and impls in Rust are based on type classes, which originated
>> in Haskell. You may find it interesting to read about type classes:
>> "Type classes: exploring the design space" by Simon Peyton Jones, Mark
>> Jones, and Erik Meijer, is a good start:
>> http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674
>
> Thank you for the reference Tim. I'm not really fluent in Haskell but I
> think I understand the concepts and apparently multi-parameter type classes
> are very close to what I would expect from Rust interfaces/traits.
>
> 2012/10/6 Tim Chevalier <catamorphism at gmail.com>
>> ("Interfaces" have been renamed to "traits" in the soon-to-be-released
>> Rust 0.4 release, by the way; it looks like you may be looking at the docs
>> from Rust 0.3.)
>
> Right, I was looking at docs 0.3 but I could not find any newer
> documentation.
>
> 2012/10/6 Sebastian Sylvan <sebastian.sylvan at gmail.com>
>> I strongly feel that the focus on inheritance in (recent) OOP is a
>> huge mistake. OOP was originally more about the metaphor of messages
>> and objects than inheritance. Inheritance leads to so many bugs and
>> [...]
>> Interfaces (even trees of them) are great, just not inheritance of
>> implementation.
>
> 2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st>
>> Inheritance seems to solve a different problem - how to write code that
>> targets many different types of objects in a simple way. But inheritance
>> isn't really needed there,
>> [...]
>> Of course, that's just my opinion (and, I am more of a functional
>> programmer than an OO programmer).
>
> Sorry I have not made myself clear enough. My point is absolulety not say
> that inheritance is a good/bad/required/unnecessary feature. My point is
> that if you're not using it (or at least if you're not using dynamic
> linkage), I cannot see where or why OOP concepts and syntax are relevant
> anymore. (But apparently there are some attempts to use dynamic linkage with
> interfaces and I didn't know that).
>
> Your remark about the metaphor is indeed interesting. Actually I cannot
> remember where I had read someone complaining about that. This guy said "I
> know what is sending messages, and it's certainly not that". His point was
> precisely that this metaphor fails because the notion of message implies
> asynchrony (I'm not paralyzed when I'm waiting for a response to a mail) and
> this is certainly not the intended meaning in OOP. I agree with this view.
>
> You both focus on the functional inspiration for Rust. This is good news.
> It's obvious to me the functional paradigm has deep roots in the math world.
> Which is also good news. But in mathematics nobody wonder if such-and-such a
> function is owned by one of its argument and which one. Or to say it a la
> OOP, if this function is a method of one of its argument. This bias, when
> taken to the extreme, has generaly lead some languages to syntactical
> "oddities" (some of my neurones would say "monstrosities") like: "x = (PI /
> 4).sin;" or "y = 2.'+'(7);" Can anyone explain me why it makes more sense to
> think about this addition as a message sent to 2 with parameter 7?

It does not make sense.  Think about a general add interface.  It's
type could be like the following (I am still fuzzy on rust's memory
location/lifetime type modifiers, so here I assume T is somehow
copy-by-value):

add( a: T, b: T ) -> T

There's nothing special about a compared to b, and also the return
type is the same type.  If we could generalize this to an interface
called "Addable", then a single implementation would exist for a given
type, and there'd be nothing special about which argument position(s)
have that type.

I seem to recall there was some constraint on rust traits which says
the parameterized type must appear in a particular position.  Is this
still true?  Is this a constraint that will be lifted in the future?

I hope so, because then interfaces can be much more expressive, such
as as "JSON-compatible interface":

to_json( x: T ) -> ~str;
from_json( text: ~str ) -> Option<T>;

This seems like a coherent and useful kind of interface.


> What does
> this metaphor makes clearer ? One may justifiably argue that mathematical
> concepts are different from everyday life ones. But I don't think
> 'file.moveTo(directory)' or 'directory.move(file)' carries better meaning
> than 'moveTo(directory, file)'. If you want to express more efficiently the
> purpose of every argument of a function, named arguments are a far better
> idea.
>
> 2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st>
>> I think saying that objects are only useful in so far as inheritance
>> exists is strange. The point of objects, as I've understood them, is to
>> provide some form of encapsulation - to be able to give limited access
>> to certain data so that you can maintain invariants on the data that are
>> not expressible with a type system (if such a system even exists).
>> Objects can exist without inheritance (and are still useful).
>
> This is a question of terminology. Unfortunately in computer science and
> programming, definitions are generally fuzzy or/and depend on the author. I
> keep the word "encapsulation" for the idea of grouping together data and
> functions and personally prefer the expression "data hidding" or "data
> accessibility" for the feature you're describing. And the fact is this too
> concepts are certainly not as strongly linked as you might think. You can
> perfectly imagine a system where data accessibility does not apply to the
> exterior of a class but to the exterior of other bundles (modules, packages,
> etc). This way you can craft more precisely the accessibility of multiple
> types in multiple functions. Classes are not needed for this.

The common OO idiom you allude to specifically ties interface, data
accessibility, and namespace together.  That's a particular choice.
You are right that these can be decoupled.

I'm personally a fan of "fewer ways to do it; less flexibility", so I
like nailing down a namespace and data accessibility for example.  Or
for another example, I'm a fan of "the namespace must correlate
directly to the file path in some manner" versus having those
decoupled.

But that's just me, and I see more flexibility in rust.  I'm not
certain but I think data accessibility may be tied to namespaces
(which are decoupled from filenames somewhat), as well as types, so
maybe it already has the flexibility you describe?


>
> 2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st>
>> As for your example, you can probably define an implementation for pairs,
>> i.e.:
>> trait ShapeDrawing<(Sf,Sh)> {
>>  ?
>> }
>> [...]
>> It is certainly a different approach, but I think you'll find that it
>> isn't less
>> powerful (and you may find it to be more flexible - but you may not!).
>

This is intriguing, but not as general as multi-parameter type
classes.  Consider an interface for two types, A and B, like this:

insert( elem: A, container: B ) -> void;
peek( container: B ) -> Option<A>;

There's no (A,B) parameter or return type anywhere.  That would fit
into insert(), but it would not make sense for peek, where I have no B
at hand.


> Well as long as I have not read some document about traits, any criticism or
> any conclusion from me about this would be pointless (I've just noticed
> Brian's link to new documentation). But after a first glance it does not
> seem to remove the limitations I found in the previous concept of
> interfaces. And I'm almost sure that interfaces, as they where explained in
> the documentation 0.3 are less powerfull. For the same reason the authors of
> the article proposed by Tim explain single-parameter type classes in Haskell
> are less powerfull than multi-parameter type classes. I'll come back as soon
> as my comprehension of Rust traits will be less superficial (and after a
> session of self-flagellation if my premonitions/arguments turn out to be
> wrong :-))
>

Just to recap, rust traits are constrained to be
single-type-parameter.  I also read somewhere (but can't find the
reference off-hand) that they are also constrained in the position of
the type parameter in all methods.

Relaxing the latter constraint would allow more expressiveness, and
relaxing the former would allow even more.

I am not very clear on how feasible or difficult relaxing either would
be.  I don't see particular design problems with relaxing the
positional constraint, but I may be missing other related aspects of
rust.  There may be some confusing cases or developer confusion around
multi-parameter traits.



> 2012/10/6 Brian Anderson <banderson at mozilla.com>
>> Additionally your concern about resources and classes not needing to be
>> interrelated
>> is spot on, and that issue will be resolved. In 0.4 still structs are the
>> only type
>> that contain destructors, but the intent is to make destructors just an
>> implementation
>> of `trait Drop` (or `Finalize` maybe).
>
> Precisely, I'm not sure that the fact destructors are turned into methods is
> good news to me.
>
> Thank you for this stimulating discussion and references
>
> --
> Eddy Cizeron
>


Regards,
Nathan Wilcox


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

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Ben Kloosterman
Multiple parameter   are very useful eg a collection and a second type ,
 but it gets messy... it works ok provided its in a single compilation unit
but else you get compilation unit dependency loops ,with generics ( which
are similar) you can  auto generate new  libs to handle this not sure about
rust traits..

Ben


Just to recap, rust traits are constrained to be

> single-type-parameter.  I also read somewhere (but can't find the
> reference off-hand) that they are also constrained in the position of
> the type parameter in all methods.
>
> Relaxing the latter constraint would allow more expressiveness, and
> relaxing the former would allow even more.
>
> I am not very clear on how feasible or difficult relaxing either would
> be.  I don't see particular design problems with relaxing the
> positional constraint, but I may be missing other related aspects of
> rust.  There may be some confusing cases or developer confusion around
> multi-parameter traits.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121009/c1cc4718/attachment.html>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Niko Matsakis
In reply to this post by Nathan
There is no requirement that the self type in a trait appear in the
receiver position.

Rust supports traits like the Json trait you propose:

     trait Json {
         fn to_json(&self) -> ~str;
         fn from_json(value: ~str) -> self;
    }

Today, however, we would require the keyword `static` in front of the
second fn.  We are phasing this out in favor of "explicit self".  In the
explicit self system, methods declare the receiver type explicitly,
somewhat like Python.  This lets you declare what kind of pointer to
`self` you like.  So `fn foo(&self)` means a method with a borrowed
receiver, `fn foo(@self)` means a method with a managed receiver, and so
on.  You can also do `fn foo(self)` to mean "by-value" self.


Niko

> Nathan <mailto:nejucomo at gmail.com>
> October 8, 2012 5:55 PM
> Hello,
>
>
> On Mon, Oct 8, 2012 at 3:19 PM, Eddy Cizeron<eddycizeron at gmail.com>  wrote:
>> Hi everyone
>>
>> 2012/10/6 Tim Chevalier<catamorphism at gmail.com>
>>> Traits and impls in Rust are based on type classes, which originated
>>> in Haskell. You may find it interesting to read about type classes:
>>> "Type classes: exploring the design space" by Simon Peyton Jones, Mark
>>> Jones, and Erik Meijer, is a good start:
>>> http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674
>> Thank you for the reference Tim. I'm not really fluent in Haskell but I
>> think I understand the concepts and apparently multi-parameter type classes
>> are very close to what I would expect from Rust interfaces/traits.
>>
>> 2012/10/6 Tim Chevalier<catamorphism at gmail.com>
>>> ("Interfaces" have been renamed to "traits" in the soon-to-be-released
>>> Rust 0.4 release, by the way; it looks like you may be looking at the docs
>>> from Rust 0.3.)
>> Right, I was looking at docs 0.3 but I could not find any newer
>> documentation.
>>
>> 2012/10/6 Sebastian Sylvan<sebastian.sylvan at gmail.com>
>>> I strongly feel that the focus on inheritance in (recent) OOP is a
>>> huge mistake. OOP was originally more about the metaphor of messages
>>> and objects than inheritance. Inheritance leads to so many bugs and
>>> [...]
>>> Interfaces (even trees of them) are great, just not inheritance of
>>> implementation.
>> 2012/10/6 Daniel Patterson<lists.rust at dbp.mm.st>
>>> Inheritance seems to solve a different problem - how to write code that
>>> targets many different types of objects in a simple way. But inheritance
>>> isn't really needed there,
>>> [...]
>>> Of course, that's just my opinion (and, I am more of a functional
>>> programmer than an OO programmer).
>> Sorry I have not made myself clear enough. My point is absolulety not say
>> that inheritance is a good/bad/required/unnecessary feature. My point is
>> that if you're not using it (or at least if you're not using dynamic
>> linkage), I cannot see where or why OOP concepts and syntax are relevant
>> anymore. (But apparently there are some attempts to use dynamic linkage with
>> interfaces and I didn't know that).
>>
>> Your remark about the metaphor is indeed interesting. Actually I cannot
>> remember where I had read someone complaining about that. This guy said "I
>> know what is sending messages, and it's certainly not that". His point was
>> precisely that this metaphor fails because the notion of message implies
>> asynchrony (I'm not paralyzed when I'm waiting for a response to a mail) and
>> this is certainly not the intended meaning in OOP. I agree with this view.
>>
>> You both focus on the functional inspiration for Rust. This is good news.
>> It's obvious to me the functional paradigm has deep roots in the math world.
>> Which is also good news. But in mathematics nobody wonder if such-and-such a
>> function is owned by one of its argument and which one. Or to say it a la
>> OOP, if this function is a method of one of its argument. This bias, when
>> taken to the extreme, has generaly lead some languages to syntactical
>> "oddities" (some of my neurones would say "monstrosities") like: "x = (PI /
>> 4).sin;" or "y = 2.'+'(7);" Can anyone explain me why it makes more sense to
>> think about this addition as a message sent to 2 with parameter 7?
>
> It does not make sense.  Think about a general add interface.  It's
> type could be like the following (I am still fuzzy on rust's memory
> location/lifetime type modifiers, so here I assume T is somehow
> copy-by-value):
>
> add( a: T, b: T ) ->  T
>
> There's nothing special about a compared to b, and also the return
> type is the same type.  If we could generalize this to an interface
> called "Addable", then a single implementation would exist for a given
> type, and there'd be nothing special about which argument position(s)
> have that type.
>
> I seem to recall there was some constraint on rust traits which says
> the parameterized type must appear in a particular position.  Is this
> still true?  Is this a constraint that will be lifted in the future?
>
> I hope so, because then interfaces can be much more expressive, such
> as as "JSON-compatible interface":
>
> to_json( x: T ) ->  ~str;
> from_json( text: ~str ) ->  Option<T>;
>
> This seems like a coherent and useful kind of interface.
>
>
>> What does
>> this metaphor makes clearer ? One may justifiably argue that mathematical
>> concepts are different from everyday life ones. But I don't think
>> 'file.moveTo(directory)' or 'directory.move(file)' carries better meaning
>> than 'moveTo(directory, file)'. If you want to express more efficiently the
>> purpose of every argument of a function, named arguments are a far better
>> idea.
>>
>> 2012/10/6 Daniel Patterson<lists.rust at dbp.mm.st>
>>> I think saying that objects are only useful in so far as inheritance
>>> exists is strange. The point of objects, as I've understood them, is to
>>> provide some form of encapsulation - to be able to give limited access
>>> to certain data so that you can maintain invariants on the data that are
>>> not expressible with a type system (if such a system even exists).
>>> Objects can exist without inheritance (and are still useful).
>> This is a question of terminology. Unfortunately in computer science and
>> programming, definitions are generally fuzzy or/and depend on the author. I
>> keep the word "encapsulation" for the idea of grouping together data and
>> functions and personally prefer the expression "data hidding" or "data
>> accessibility" for the feature you're describing. And the fact is this too
>> concepts are certainly not as strongly linked as you might think. You can
>> perfectly imagine a system where data accessibility does not apply to the
>> exterior of a class but to the exterior of other bundles (modules, packages,
>> etc). This way you can craft more precisely the accessibility of multiple
>> types in multiple functions. Classes are not needed for this.
>
> The common OO idiom you allude to specifically ties interface, data
> accessibility, and namespace together.  That's a particular choice.
> You are right that these can be decoupled.
>
> I'm personally a fan of "fewer ways to do it; less flexibility", so I
> like nailing down a namespace and data accessibility for example.  Or
> for another example, I'm a fan of "the namespace must correlate
> directly to the file path in some manner" versus having those
> decoupled.
>
> But that's just me, and I see more flexibility in rust.  I'm not
> certain but I think data accessibility may be tied to namespaces
> (which are decoupled from filenames somewhat), as well as types, so
> maybe it already has the flexibility you describe?
>
>
>> 2012/10/6 Daniel Patterson<lists.rust at dbp.mm.st>
>>> As for your example, you can probably define an implementation for pairs,
>>> i.e.:
>>> trait ShapeDrawing<(Sf,Sh)>  {
>>>   ?
>>> }
>>> [...]
>>> It is certainly a different approach, but I think you'll find that it
>>> isn't less
>>> powerful (and you may find it to be more flexible - but you may not!).
>
> This is intriguing, but not as general as multi-parameter type
> classes.  Consider an interface for two types, A and B, like this:
>
> insert( elem: A, container: B ) ->  void;
> peek( container: B ) ->  Option<A>;
>
> There's no (A,B) parameter or return type anywhere.  That would fit
> into insert(), but it would not make sense for peek, where I have no B
> at hand.
>
>
>> Well as long as I have not read some document about traits, any criticism or
>> any conclusion from me about this would be pointless (I've just noticed
>> Brian's link to new documentation). But after a first glance it does not
>> seem to remove the limitations I found in the previous concept of
>> interfaces. And I'm almost sure that interfaces, as they where explained in
>> the documentation 0.3 are less powerfull. For the same reason the authors of
>> the article proposed by Tim explain single-parameter type classes in Haskell
>> are less powerfull than multi-parameter type classes. I'll come back as soon
>> as my comprehension of Rust traits will be less superficial (and after a
>> session of self-flagellation if my premonitions/arguments turn out to be
>> wrong :-))
>>
>
> Just to recap, rust traits are constrained to be
> single-type-parameter.  I also read somewhere (but can't find the
> reference off-hand) that they are also constrained in the position of
> the type parameter in all methods.
>
> Relaxing the latter constraint would allow more expressiveness, and
> relaxing the former would allow even more.
>
> I am not very clear on how feasible or difficult relaxing either would
> be.  I don't see particular design problems with relaxing the
> positional constraint, but I may be missing other related aspects of
> rust.  There may be some confusing cases or developer confusion around
> multi-parameter traits.
>
>
>
>> 2012/10/6 Brian Anderson<banderson at mozilla.com>
>>> Additionally your concern about resources and classes not needing to be
>>> interrelated
>>> is spot on, and that issue will be resolved. In 0.4 still structs are the
>>> only type
>>> that contain destructors, but the intent is to make destructors just an
>>> implementation
>>> of `trait Drop` (or `Finalize` maybe).
>> Precisely, I'm not sure that the fact destructors are turned into methods is
>> good news to me.
>>
>> Thank you for this stimulating discussion and references
>>
>> --
>> Eddy Cizeron
>>
>
>
> Regards,
> Nathan Wilcox
>
>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev at mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
> Eddy Cizeron <mailto:eddycizeron at gmail.com>
> October 8, 2012 3:19 PM
> Hi everyone
>
> 2012/10/6 Tim Chevalier <catamorphism at gmail.com
> <mailto:catamorphism at gmail.com>>
> > Traits and impls in Rust are based on type classes, which originated
> > in Haskell. You may find it interesting to read about type classes:
> > "Type classes: exploring the design space" by Simon Peyton Jones, Mark
> > Jones, and Erik Meijer, is a good start:
> > http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674
>
> Thank you for the reference Tim. I'm not really fluent in Haskell but
> I think I understand the concepts and apparently multi-parameter type
> classes are very close to what I would expect from Rust interfaces/traits.
>
> 2012/10/6 Tim Chevalier <catamorphism at gmail.com
> <mailto:catamorphism at gmail.com>>
> > ("Interfaces" have been renamed to "traits" in the soon-to-be-released
> > Rust 0.4 release, by the way; it looks like you may be looking at
> the docs from Rust 0.3.)
>
> Right, I was looking at docs 0.3 but I could not find any newer
> documentation.
>
> 2012/10/6 Sebastian Sylvan <sebastian.sylvan at gmail.com
> <mailto:sebastian.sylvan at gmail.com>>
> > I strongly feel that the focus on inheritance in (recent) OOP is a
> > huge mistake. OOP was originally more about the metaphor of messages
> > and objects than inheritance. Inheritance leads to so many bugs and
> > [...]
> > Interfaces (even trees of them) are great, just not inheritance of
> > implementation.
>
> 2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st
> <mailto:lists.rust at dbp.mm.st>>
> > Inheritance seems to solve a different problem - how to write code that
> > targets many different types of objects in a simple way. But inheritance
> > isn't really needed there,
> > [...]
> > Of course, that's just my opinion (and, I am more of a functional
> programmer than an OO programmer).
>
> Sorry I have not made myself clear enough. My point is absolulety not
> say that inheritance is a good/bad/required/unnecessary feature. My
> point is that if you're not using it (or at least if you're not using
> dynamic linkage), I cannot see where or why OOP concepts and syntax
> are relevant anymore. (But apparently there are some attempts to use
> dynamic linkage with interfaces and I didn't know that).
>
> Your remark about the metaphor is indeed interesting. Actually I
> cannot remember where I had read someone complaining about that. This
> guy said "I know what is sending messages, and it's certainly not
> that". His point was precisely that this metaphor fails because the
> notion of message implies asynchrony (I'm not paralyzed when I'm
> waiting for a response to a mail) and this is certainly not the
> intended meaning in OOP. I agree with this view.
>
> You both focus on the functional inspiration for Rust. This is good
> news. It's obvious to me the functional paradigm has deep roots in the
> math world. Which is also good news. But in mathematics nobody wonder
> if such-and-such a function is owned by one of its argument and which
> one. Or to say it a la OOP, if this function is a method of one of its
> argument. This bias, when taken to the extreme, has generaly lead some
> languages to syntactical "oddities" (some of my neurones would say
> "monstrosities") like: "x = (PI / 4).sin;" or "y = 2.'+'(7);" Can
> anyone explain me why it makes more sense to think about this addition
> as a message sent to 2 with parameter 7? What does this metaphor makes
> clearer ? One may justifiably argue that mathematical concepts are
> different from everyday life ones. But I don't think
> 'file.moveTo(directory)' or 'directory.move(file)' carries better
> meaning than 'moveTo(directory, file)'. If you want to express more
> efficiently the purpose of every argument of a function, named
> arguments are a far better idea.
>
> 2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st
> <mailto:lists.rust at dbp.mm.st>>
> > I think saying that objects are only useful in so far as inheritance
> > exists is strange. The point of objects, as I've understood them, is to
> > provide some form of encapsulation - to be able to give limited access
> > to certain data so that you can maintain invariants on the data that are
> > not expressible with a type system (if such a system even exists).
> > Objects can exist without inheritance (and are still useful).
>
> This is a question of terminology. Unfortunately in computer science
> and programming, definitions are generally fuzzy or/and depend on the
> author. I keep the word "encapsulation" for the idea of grouping
> together data and functions and personally prefer the expression "data
> hidding" or "data accessibility" for the feature you're describing.
> And the fact is this too concepts are certainly not as strongly linked
> as you might think. You can perfectly imagine a system where data
> accessibility does not apply to the exterior of a class but to the
> exterior of other bundles (modules, packages, etc). This way you can
> craft more precisely the accessibility of multiple types in multiple
> functions. Classes are not needed for this.
>
> 2012/10/6 Daniel Patterson <lists.rust at dbp.mm.st
> <mailto:lists.rust at dbp.mm.st>>
> > As for your example, you can probably define an implementation for
> pairs, i.e.:
> > trait ShapeDrawing<(Sf,Sh)> {
> >  ?
> > }
> > [...]
> > It is certainly a different approach, but I think you'll find that
> it isn't less
> > powerful (and you may find it to be more flexible - but you may not!).
>
> Well as long as I have not read some document about traits, any
> criticism or any conclusion from me about this would be pointless
> (I've just noticed Brian's link to new documentation). But after a
> first glance it does not seem to remove the limitations I found in the
> previous concept of interfaces. And I'm almost sure that interfaces,
> as they where explained in the documentation 0.3 are less powerfull.
> For the same reason the authors of the article proposed by Tim explain
> single-parameter type classes in Haskell are less powerfull than
> multi-parameter type classes. I'll come back as soon as my
> comprehension of Rust traits will be less superficial (and after a
> session of self-flagellation if my premonitions/arguments turn out to
> be wrong :-))
>
> 2012/10/6 Brian Anderson <banderson at mozilla.com
> <mailto:banderson at mozilla.com>>
> > Additionally your concern about resources and classes not needing to
> be interrelated
> > is spot on, and that issue will be resolved. In 0.4 still structs
> are the only type
> > that contain destructors, but the intent is to make destructors just
> an implementation
> > of `trait Drop` (or `Finalize` maybe).
>
> Precisely, I'm not sure that the fact destructors are turned into
> methods is good news to me.
>
> Thank you for this stimulating discussion and references
>
> --
> Eddy Cizeron
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
> Nathan <mailto:nejucomo at gmail.com>
> October 8, 2012 1:05 AM
> On Sat, Oct 6, 2012 at 11:16 AM, Tim Chevalier<catamorphism at gmail.com>  wrote:
>> Hi, Eddy --
>>
>> Traits and impls in Rust are based on type classes, which originated
>> in Haskell. You may find it interesting to read about type classes:
>> "Type classes: exploring the design space" by Simon Peyton Jones, Mark
>> Jones, and Erik Meijer, is a good start:
>>
>> http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674
>>
>> ("Interfaces" have been renamed to "traits" in the soon-to-be-released
>> Rust 0.4 release, by the way; it looks like you may be looking at the
>> docs from Rust 0.3.)
>>
>> Cheers,
>> Tim
>>
>
> I'm about half-way through this paper, which is a great reference.  Thanks!
>
> I'm curious if multi-parameter traits are anywhere on the rust
> roadmap.  I'm not certain about which challenges or restrictions they
> may require but perhaps by the time I finish this reference I'll have
> a better understanding.
>
> I'd recommend reading the paper if only to see motivating examples of
> multi-parameter traits.
>
> Regards,
> Nathan
>
>> --
>> Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
>> "Gains in likability have deep costs in personal integrity." -- Kirk Read
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev at mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
> Tim Chevalier <mailto:catamorphism at gmail.com>
> October 6, 2012 11:16 AM
> Hi, Eddy --
>
> Traits and impls in Rust are based on type classes, which originated
> in Haskell. You may find it interesting to read about type classes:
> "Type classes: exploring the design space" by Simon Peyton Jones, Mark
> Jones, and Erik Meijer, is a good start:
>
> http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.5674
>
> ("Interfaces" have been renamed to "traits" in the soon-to-be-released
> Rust 0.4 release, by the way; it looks like you may be looking at the
> docs from Rust 0.3.)
>
> Cheers,
> Tim
>
> Eddy Cizeron <mailto:eddycizeron at gmail.com>
> October 6, 2012 11:14 AM
>
> Hello,
>
> I'm new to Rust, and I have some questions concerning some aspects of
> the language. From what I understand until now, rust has no dynamic
>  linkage for methods as it would be the case in any standard OOP
> language. This is surely an intentionaly different philosophy from the
> current trend among other recent programming languages. But why not
> after all. I like the idea. So I find myself skeptical when I read the
> chapters of the documentation about OOP-like concepts like classes or
> interfaces.
>
> The essence of the "class" concept lies in the possibility to gather a
> data structure (a type) and the related processes that can act on the
> corresponding instances (methods) in a single bundle. But, tell me if
> you disagree, the only interesting purpose of such an operation is the
> ability to use inheritance. If no concept of inheritance exists, I
> hardly see what is the need of making functions "pets" for data. All
> we obtain are classical design issues like "is my 'f(a,b)' function a
> 'a.f(b)' method or a 'b.f(a)' method ?" (and I don't think the rust
> "resource" concept requires classes, as destructors or destructor-like
> functions are not methods). I'm afraid that the answer is merely to
> offer a supposedly "attractive" syntax for OOP users. And I think this
> would be a weak argument
>
> The concept of interface/implementation in rust is surely different
> than the usual one, but again to me it looks like it has some
> limitations due to the same reason than above: it tries to look OOP. I
> could have imagined a very similar interface concept but that does not
> focus on a *single *type:
>
> iface shape_drawing<Sf, Sh> {
>     fn draw(Sf, Sh);
>     fn bounding_box(Sh) -> bounding_box;
> }
>
> fn draw_twice<Sf, Sh with shape_drawing<Sf, Sh>>(surface: Sf, shape: Sh) {
>     draw(surface, shape);
>     draw(surface, shape);
> }
>
> Of course this example is a simple one. And any consistent system like
> this (if it does exist but I'm pretty sure it does) would have been
> more complex than the current one. But also more general and then more
> powerful.
>
> Let me clear about something: I don't expect anybody to change the
> current design. I'm nobody and I know it's always easier to criticize
> than to do things. I'm just expressing the feeling that while Rust
> tried to take a different direction from all the other new
> JVM-compliant-OOP-languages-with-functional-features (which I really
> really value very much) it seems it has not got rid of some conceptual
> patterns that are not, IMHO, necessary anymore. And I wish people
> could give their opinion about this.
>
> Thank you
>
> --
> Eddy Cizeron
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121008/2e6ac9bc/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: compose-unknown-contact.jpg
Type: image/jpeg
Size: 770 bytes
Desc: not available
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121008/2e6ac9bc/attachment-0002.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: postbox-contact.jpg
Type: image/jpeg
Size: 1270 bytes
Desc: not available
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121008/2e6ac9bc/attachment-0003.jpg>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Sebastian Sylvan
In reply to this post by Joe Groff
On Mon, Oct 8, 2012 at 5:22 PM, Joe Groff <arcata at gmail.com> wrote:

> On Mon, Oct 8, 2012 at 3:19 PM, Eddy Cizeron <eddycizeron at gmail.com> wrote:
>> Sorry I have not made myself clear enough. My point is absolulety not say
>> that inheritance is a good/bad/required/unnecessary feature. My point is
>> that if you're not using it (or at least if you're not using dynamic
>> linkage), I cannot see where or why OOP concepts and syntax are relevant
>> anymore. (But apparently there are some attempts to use dynamic linkage with
>> interfaces and I didn't know that).
>
> One minor non-semantic, non-scientific benefit of OOP syntax over
> Algol-style function application syntax is that it's syntactically
> more composable?compare `a.foo().bar().bas()`, which reads
> left-to-right and composes to the right, to `bas(bar(foo(a)))`, which
> reads inside-out and requires bracketing on both sides of an inner
> experssion to compose calls. (Of course this only works if your APIs
> are designed up front in a "fluent" way, and isn't quite as flexible
> as what you can do with combinators in ML or Haskell.)

I think there are two other benefits. The first is intellisense/code
completion. Type "foo." and get a list of all methods in scope with a
matching self type. This can be a massive productivity boost as it
basically puts all your code and documentation in the IDE in a context
sensitive way. Much harder to do this if you have to remember the name
of the method before you see anything.

Second, and much more subjectively, I think there's a difference
between sort of value oriented programming, and the more low level
mutable programming type where you're dealing with "objects" that have
identity and complicated invariants. Subjective, but tying the methods
to the data type in those cases "feels" okay to me because they kinda
are inseparable in practice, so they might as well be syntactically
tied together as well (with a more functional style you would group
them by modules and visibility, but syntactically it doesn't look like
an indivisible "object" that have a small set hard-wired built in
methods on it as opposed to a value and a random grab bag of
operations that happen to have matching types but could be written by
any old schmuck and not necessarily "part of the object").
--
Sebastian Sylvan

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Eddy Cizeron
In reply to this post by Eddy Cizeron
2012/10/9 Lindsey Kuper <lindsey at rockstargirl.org>
> And, in case nobody has pointed them out yet, here are a couple more
resources:
>  * An introduction to traits on Patrick's blog:
http://pcwalton.github.com/blog/2012/08/08/a-gentle-introduction-to-traits-in-rust
>  * A talk I did in August, with a side-by-side Haskell/Rust
> comparison: https://air.mozilla.org/rust-typeclasses
> Cheers,

Thank you for the references Lindsey.

2012/10/9 Joe Groff <arcata at gmail.com>
> One minor non-semantic, non-scientific benefit of OOP syntax over
> Algol-style function application syntax is that it's syntactically
> more composable?compare `a.foo().bar().bas()`, which reads
> left-to-right and composes to the right, to `bas(bar(foo(a)))`, which
> reads inside-out and requires bracketing on both sides of an inner
> experssion to compose calls. (Of course this only works if your APIs
> are designed up front in a "fluent" way, and isn't quite as flexible
> as what you can do with combinators in ML or Haskell.)

I'm a math guy so to me syntax `bas(bar(foo(a)))` is natural. Besides as
you noticed yourself this only work in certain circumstances. For example
when you have additional parameters, the syntax could sometime be something
like `c.bar(a.foo(b)).bas()` which is less readable in my opinion than
`bas(bar(c, foo(a, b)))`. But all this is very subjective, isn't it ?

2012/10/9 Sebastian Sylvan <sebastian.sylvan at gmail.com>
> I think there are two other benefits. The first is intellisense/code
> completion. Type "foo." and get a list of all methods in scope with a
> matching self type. This can be a massive productivity boost as it
> basically puts all your code and documentation in the IDE in a context
> sensitive way. Much harder to do this if you have to remember the name
> of the method before you see anything.

I agree that it's easier to start from a variable existing in the context
rather than from a namespace or from a function name. But completion does
not necessarily have to insert code after the considered identifier, even
if it is indeed more usual.

> Second, and much more subjectively, I think there's a difference
> between sort of value oriented programming, and the more low level
> mutable programming type where you're dealing with "objects" that have
> identity and complicated invariants. Subjective, but tying the methods
> to the data type in those cases "feels" okay to me because they kinda
> are inseparable in practice, so they might as well be syntactically
> tied together as well (with a more functional style you would group
> them by modules and visibility, but syntactically it doesn't look like
> an indivisible "object" that have a small set hard-wired built in
> methods on it as opposed to a value and a random grab bag of
> operations that happen to have matching types but could be written by
> any old schmuck and not necessarily "part of the object").

This is precisely the subjective feeling I don't agree with. This feeling
only exists because you think of processes/functions/methods as part of a
single object rather than interactions between a group of objects. This is
a very "Aristotelician" view. It sometimes work well (when object can be
seen like "active" autonomous entities) but not in the general case IMHO.

2012/10/9 Nathan <nejucomo at gmail.com>

> It does not make sense.  Think about a general add interface.  It's
> type could be like the following (I am still fuzzy on rust's memory
> location/lifetime type modifiers, so here I assume T is somehow
> copy-by-value):
>
> add( a: T, b: T ) -> T
>
> There's nothing special about a compared to b, and also the return
> type is the same type.  If we could generalize this to an interface
> called "Addable", then a single implementation would exist for a given
> type, and there'd be nothing special about which argument position(s)
> have that type.

Hem ... So this mean we agree right ? My point was precisely that this does
not make sense. The syntax need not to give one of the arguments a specific
role.

> The common OO idiom you allude to specifically ties interface, data
> accessibility, and namespace together.  That's a particular choice.
> You are right that these can be decoupled.
>
> I'm personally a fan of "fewer ways to do it; less flexibility", so I
> like nailing down a namespace and data accessibility for example.  Or
> for another example, I'm a fan of "the namespace must correlate
> directly to the file path in some manner" versus having those
> decoupled.

I may only partly agree. I too prefer Bertrand Meyer's "A programming
language should provide one good way of performing any operation of
interest; it should avoid providing two." to Larry Wall's "There's more
than one way to do it". But this only apply to perfectly equivalent
contructs. If there is several way to do related but distinct things, I
found flexibility better.

> But that's just me, and I see more flexibility in rust.  I'm not
> certain but I think data accessibility may be tied to namespaces
> (which are decoupled from filenames somewhat), as well as types, so
> maybe it already has the flexibility you describe?

In all the docs I've read until now, the word "private" only appeared in
the section for classes, so I guess no.

> This is intriguing, but not as general as multi-parameter type
> classes.  Consider an interface for two types, A and B, like this:
>
> insert( elem: A, container: B ) -> void;
> peek( container: B ) -> Option<A>;
>
> There's no (A,B) parameter or return type anywhere.  That would fit
> into insert(), but it would not make sense for peek, where I have no B
> at hand.

This is definite the kind of interface/trait I would like to be express in
Rust. But apparently it is not possible with the current design.

2012/10/9 Bennie Kloosteman <bklooste at gmail.com>
> Multiple parameter are very useful eg a collection and a second type ,
> but it gets messy... it works ok provided its in a single compilation
> unit but else you get compilation unit dependency loops ,with generics
> ( which are similar) you can  auto generate new  libs to handle this
> not sure about rust traits..

Hi Ben. I'm not sure to understand the link with compilation loop. Any
previous discussion on this topic?

So in conclusion, this means multiple parameter traits are not planned to
be implemented in Rust ? right ?

--
Eddy Cizeron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121011/ff52983c/attachment.html>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Patrick Walton
On 10/10/12 3:49 PM, Eddy Cizeron wrote:
>  > There's no (A,B) parameter or return type anywhere.  That would fit
>  > into insert(), but it would not make sense for peek, where I have no B
>  > at hand.

I do not see why this could not be written with a generic trait.

Patrick


Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Sebastian Sylvan
In reply to this post by Eddy Cizeron
On Wed, Oct 10, 2012 at 3:49 PM, Eddy Cizeron <eddycizeron at gmail.com> wrote:

> 2012/10/9 Sebastian Sylvan <sebastian.sylvan at gmail.com>
>> I think there are two other benefits. The first is intellisense/code
>> completion. Type "foo." and get a list of all methods in scope with a
>> matching self type. This can be a massive productivity boost as it
>> basically puts all your code and documentation in the IDE in a context
>> sensitive way. Much harder to do this if you have to remember the name
>> of the method before you see anything.
>
> I agree that it's easier to start from a variable existing in the context
> rather than from a namespace or from a function name. But completion does
> not necessarily have to insert code after the considered identifier, even if
> it is indeed more usual.

That would indeed be pretty unusual. Worse, it's how you write code
normally. If function applications start with the name of the function
and not the variable, then you have to decide before you even start
that you want to invoke the "code completion feature" on this next
expression, *skip* writing the function name (or put in some kind of
placholder) and instad write the variable you want to act on combined
with some magic incantation to make the IDE let you select and then
pre-inject the function name in front of it. In an OOP style syntax
you just write code like you're used to and the IDE just discretely
flashes up little tool tips and lists of members to gently nudge you
along your way (or allow you to short cut some typing) as you go about
your normal coding. You don't need to do anything special, it's just
constantly there if you need it, and can be ignored if you don't.

I really can't stress enough what a force multipler it is to write
code in an IDE with powerful code completion for someone who has
internalized it into their workflow. I know real men use VIM etc., but
I'm secure enough to admit that I am  more productive in the actual
coding phase using C# with Intellisense in VS than Haskell + Emacs or
whatever, even though I recognize that on language merit alone it
should be the other way around by far. Tooling matters so much these
days. Arguably more than a lot of language semantics, and certainly
more than worrying about slight syntactic redundancy, IMO.

--
Sebastian Sylvan

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Tim Chevalier
On Wed, Oct 10, 2012 at 6:01 PM, Sebastian Sylvan
<sebastian.sylvan at gmail.com> wrote:

>
> I really can't stress enough what a force multipler it is to write
> code in an IDE with powerful code completion for someone who has
> internalized it into their workflow. I know real men use VIM etc., but
> I'm secure enough to admit that I am  more productive in the actual
> coding phase using C# with Intellisense in VS than Haskell + Emacs or
> whatever, even though I recognize that on language merit alone it
> should be the other way around by far. Tooling matters so much these
> days. Arguably more than a lot of language semantics, and certainly
> more than worrying about slight syntactic redundancy, IMO.

Hey folks, two moderation-ish notes:

1. "Real men use VIM etc..." excludes women. We have Rust developers
who aren't men, so please don't assume otherwise. I know it's just a
joke, not intended to be sexist, etc., so there's no need to say that.
Just don't do it again.

2. This discussion is getting a bit far from specifics of how to
improve Rust. Please take it elsewhere. If there is interest, we may
start a rust-cafe list in the vein of haskell-cafe for off-topic-ish
discussions (or, in fact, anybody could, on Google Groups). But for
now, please try to keep discussions on this list narrowly focused.

Cheers,
Tim

--
Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
'Wouldn't you rather be anything other than the kid who runs around
telling stuff what he thinks it is?" -- DavEnd

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Ben Kloosterman
>
>
> 2. This discussion is getting a bit far from specifics of how to
> improve Rust. Please take it elsewhere. If there is interest, we may
> start a rust-cafe list in the vein of haskell-cafe for off-topic-ish
> discussions (or, in fact, anybody could, on Google Groups). But for
> now, please try to keep discussions on this list narrowly focused.
>

I think designing for Intellisense and auto completion is  very important
these days especially when you have huge number of libs or a large runtime
.   This means no short names taking up the namespace etc

In addition the OO to functional story must be resolved and clear. Like it
or not 90% of people are OO coders , which is rammed down your throats at
every university in the world so you need a convincing case..  Personally
most coders dont bother with inheritance anymore  but full polymorphism
through interfaces are important ( including having a typename in a file
and then creating it at runtime) . If you cant provide this form of
polymorphism then the alternatives , impact and reasons with examples need
to be document. Haskell people understand typeclasses  but they may
struggle with Rust objects/traits  while OO people will try to think of it
in terms of generics.,.explaining and having a clear story for this middle
ground is crucial.

Ben
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121011/cf36f733/attachment-0001.html>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Daniel Patterson
On Oct 10, 2012, at 10:26 PM, Bennie Kloosteman wrote:
> I think designing for Intellisense and auto completion is  very important these days especially when you have huge number of libs or a large runtime .   This means no short names taking up the namespace etc

I think there is also some sense in which this is an issue of momentum/resources - certain languages have lots of it, and as a result, grow sophisticated tooling ecosystems. This is often distinct from what the semantics of the languages allow.

For example, in languages with powerful type systems, there is potential for pretty amazing tooling. For instance, there is no reason why an editor / IDE for rust couldn't be doing type checking / inference while you are writing, and could highlight type system (or borrow checking) errors as they occur (this alone would be an amazing productivity booster). Similarly, you could write the name of a variable, and with some sort of completion, get any functions that take its type as the first parameter. Or I could imagine a system where you type the arguments to the function and hit a button and get completion of all functions that match the correct types (figuring out where the last statement ended, and thus the arguments started, is easy). We can also do the more familiar completion on trait implementations (i.e., methods). There are probably also ways in which the tooling could make use of the other special features that rust has (beyond just having a nice type system), but I haven't thought of them yet :)

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Niko Matsakis
In reply to this post by Sebastian Sylvan
For what it's worth, Sebastian, Simon Peyton Jones agrees with you:

     
http://research.microsoft.com/en-us/um/people/simonpj/papers/haskell-retrospective/

(Skip ahead to page 56, he talks specifically about its use in
intellisense, calling it "the power of the dot").

To me, there is another very important point regarding dot notation that
I didn't see mentioned yet: it enables name resolution on a per-type
basis.  In Haskell, if I want to have to have something like
"foo.context()" and "bar.context()" where the context of a foo has one
type and bar has another, it's a big pain and I have to use import
qualified or something crazy like that.  In OOP this is no issue.  And I
find this very natural.

Anyway, I think the design of the trait system is very much going
towards a "best of both worlds" direction.  You can define methods and
you can define standalone functions.  Based on our last meeting, there
seems to be general agreement towards a system that allows methods to be
imported as standalone functions that take the receiver as first
argument as well [1].   Like most modern languages---including Haskell,
Java, and C#---we support both parametric polymorphism (bounded
generics) and ad-hoc polymorphism (trait types).  Both have their place,
after all.

So basically there is no conflict here.  You use the right tool for the job.


Niko

[1] As initially proposed here:
https://mail.mozilla.org/pipermail/rust-dev/2012-August/002255.html

> Sebastian Sylvan <mailto:sebastian.sylvan at gmail.com>
> October 10, 2012 6:01 PM
>
> That would indeed be pretty unusual. Worse, it's how you write code
> normally. If function applications start with the name of the function
> and not the variable, then you have to decide before you even start
> that you want to invoke the "code completion feature" on this next
> expression, *skip* writing the function name (or put in some kind of
> placholder) and instad write the variable you want to act on combined
> with some magic incantation to make the IDE let you select and then
> pre-inject the function name in front of it. In an OOP style syntax
> you just write code like you're used to and the IDE just discretely
> flashes up little tool tips and lists of members to gently nudge you
> along your way (or allow you to short cut some typing) as you go about
> your normal coding. You don't need to do anything special, it's just
> constantly there if you need it, and can be ignored if you don't.
>
> I really can't stress enough what a force multipler it is to write
> code in an IDE with powerful code completion for someone who has
> internalized it into their workflow. I know real men use VIM etc., but
> I'm secure enough to admit that I am more productive in the actual
> coding phase using C# with Intellisense in VS than Haskell + Emacs or
> whatever, even though I recognize that on language merit alone it
> should be the other way around by far. Tooling matters so much these
> days. Arguably more than a lot of language semantics, and certainly
> more than worrying about slight syntactic redundancy, IMO.
>
> Eddy Cizeron <mailto:eddycizeron at gmail.com>
> October 10, 2012 3:49 PM
>
> 2012/10/9 Lindsey Kuper <lindsey at rockstargirl.org
> <mailto:lindsey at rockstargirl.org>>
> > And, in case nobody has pointed them out yet, here are a couple more
> resources:
> >  * An introduction to traits on Patrick's blog:
> http://pcwalton.github.com/blog/2012/08/08/a-gentle-introduction-to-traits-in-rust
> >  * A talk I did in August, with a side-by-side Haskell/Rust
> > comparison: https://air.mozilla.org/rust-typeclasses
> > Cheers,
>
> Thank you for the references Lindsey.
>
> 2012/10/9 Joe Groff <arcata at gmail.com <mailto:arcata at gmail.com>>
> > One minor non-semantic, non-scientific benefit of OOP syntax over
> > Algol-style function application syntax is that it's syntactically
> > more composable---compare `a.foo().bar().bas()`, which reads
> > left-to-right and composes to the right, to `bas(bar(foo(a)))`, which
> > reads inside-out and requires bracketing on both sides of an inner
> > experssion to compose calls. (Of course this only works if your APIs
> > are designed up front in a "fluent" way, and isn't quite as flexible
> > as what you can do with combinators in ML or Haskell.)
>
> I'm a math guy so to me syntax `bas(bar(foo(a)))` is natural. Besides
> as you noticed yourself this only work in certain circumstances. For
> example when you have additional parameters, the syntax could sometime
> be something like `c.bar(a.foo(b)).bas()` which is less readable in my
> opinion than `bas(bar(c, foo(a, b)))`. But all this is very
> subjective, isn't it ?
>
> 2012/10/9 Sebastian Sylvan <sebastian.sylvan at gmail.com
> <mailto:sebastian.sylvan at gmail.com>>
> > I think there are two other benefits. The first is intellisense/code
> > completion. Type "foo." and get a list of all methods in scope with a
> > matching self type. This can be a massive productivity boost as it
> > basically puts all your code and documentation in the IDE in a context
> > sensitive way. Much harder to do this if you have to remember the name
> > of the method before you see anything.
>
> I agree that it's easier to start from a variable existing in the
> context rather than from a namespace or from a function name. But
> completion does not necessarily have to insert code after the
> considered identifier, even if it is indeed more usual.
>
> > Second, and much more subjectively, I think there's a difference
> > between sort of value oriented programming, and the more low level
> > mutable programming type where you're dealing with "objects" that have
> > identity and complicated invariants. Subjective, but tying the methods
> > to the data type in those cases "feels" okay to me because they kinda
> > are inseparable in practice, so they might as well be syntactically
> > tied together as well (with a more functional style you would group
> > them by modules and visibility, but syntactically it doesn't look like
> > an indivisible "object" that have a small set hard-wired built in
> > methods on it as opposed to a value and a random grab bag of
> > operations that happen to have matching types but could be written by
> > any old schmuck and not necessarily "part of the object").
>
> This is precisely the subjective feeling I don't agree with. This
> feeling only exists because you think of processes/functions/methods
> as part of a single object rather than interactions between a group of
> objects. This is a very "Aristotelician" view. It sometimes work well
> (when object can be seen like "active" autonomous entities) but not in
> the general case IMHO.
>
> 2012/10/9 Nathan <nejucomo at gmail.com <mailto:nejucomo at gmail.com>>
> > It does not make sense.  Think about a general add interface.  It's
> > type could be like the following (I am still fuzzy on rust's memory
> > location/lifetime type modifiers, so here I assume T is somehow
> > copy-by-value):
> >
> > add( a: T, b: T ) -> T
> >
> > There's nothing special about a compared to b, and also the return
> > type is the same type.  If we could generalize this to an interface
> > called "Addable", then a single implementation would exist for a given
> > type, and there'd be nothing special about which argument position(s)
> > have that type.
>
> Hem ... So this mean we agree right ? My point was precisely that this
> does not make sense. The syntax need not to give one of the arguments
> a specific role.
>
> > The common OO idiom you allude to specifically ties interface, data
> > accessibility, and namespace together.  That's a particular choice.
> > You are right that these can be decoupled.
> >
> > I'm personally a fan of "fewer ways to do it; less flexibility", so I
> > like nailing down a namespace and data accessibility for example.  Or
> > for another example, I'm a fan of "the namespace must correlate
> > directly to the file path in some manner" versus having those
> > decoupled.
>
> I may only partly agree. I too prefer Bertrand Meyer's "A programming
> language should provide one good way of performing any operation of
> interest; it should avoid providing two." to Larry Wall's "There's
> more than one way to do it". But this only apply to perfectly
> equivalent contructs. If there is several way to do related but
> distinct things, I found flexibility better.
>
> > But that's just me, and I see more flexibility in rust.  I'm not
> > certain but I think data accessibility may be tied to namespaces
> > (which are decoupled from filenames somewhat), as well as types, so
> > maybe it already has the flexibility you describe?
>
> In all the docs I've read until now, the word "private" only appeared
> in the section for classes, so I guess no.
>
> > This is intriguing, but not as general as multi-parameter type
> > classes.  Consider an interface for two types, A and B, like this:
> >
> > insert( elem: A, container: B ) -> void;
> > peek( container: B ) -> Option<A>;
> >
> > There's no (A,B) parameter or return type anywhere.  That would fit
> > into insert(), but it would not make sense for peek, where I have no B
> > at hand.
>
> This is definite the kind of interface/trait I would like to be
> express in Rust. But apparently it is not possible with the current
> design.
>
> 2012/10/9 Bennie Kloosteman <bklooste at gmail.com
> <mailto:bklooste at gmail.com>>
> > Multiple parameter are very useful eg a collection and a second type ,
> > but it gets messy... it works ok provided its in a single compilation
> > unit but else you get compilation unit dependency loops ,with generics
> > ( which are similar) you can  auto generate new  libs to handle this
> > not sure about rust traits..
>
> Hi Ben. I'm not sure to understand the link with compilation loop. Any
> previous discussion on this topic?
>
> So in conclusion, this means multiple parameter traits are not planned
> to be implemented in Rust ? right ?
>
> --
> Eddy Cizeron
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
> Eddy Cizeron <mailto:eddycizeron at gmail.com>
> October 6, 2012 11:14 AM
>
> Hello,
>
> I'm new to Rust, and I have some questions concerning some aspects of
> the language. From what I understand until now, rust has no dynamic
>  linkage for methods as it would be the case in any standard OOP
> language. This is surely an intentionaly different philosophy from the
> current trend among other recent programming languages. But why not
> after all. I like the idea. So I find myself skeptical when I read the
> chapters of the documentation about OOP-like concepts like classes or
> interfaces.
>
> The essence of the "class" concept lies in the possibility to gather a
> data structure (a type) and the related processes that can act on the
> corresponding instances (methods) in a single bundle. But, tell me if
> you disagree, the only interesting purpose of such an operation is the
> ability to use inheritance. If no concept of inheritance exists, I
> hardly see what is the need of making functions "pets" for data. All
> we obtain are classical design issues like "is my 'f(a,b)' function a
> 'a.f(b)' method or a 'b.f(a)' method ?" (and I don't think the rust
> "resource" concept requires classes, as destructors or destructor-like
> functions are not methods). I'm afraid that the answer is merely to
> offer a supposedly "attractive" syntax for OOP users. And I think this
> would be a weak argument
>
> The concept of interface/implementation in rust is surely different
> than the usual one, but again to me it looks like it has some
> limitations due to the same reason than above: it tries to look OOP. I
> could have imagined a very similar interface concept but that does not
> focus on a *single *type:
>
> iface shape_drawing<Sf, Sh> {
>     fn draw(Sf, Sh);
>     fn bounding_box(Sh) -> bounding_box;
> }
>
> fn draw_twice<Sf, Sh with shape_drawing<Sf, Sh>>(surface: Sf, shape: Sh) {
>     draw(surface, shape);
>     draw(surface, shape);
> }
>
> Of course this example is a simple one. And any consistent system like
> this (if it does exist but I'm pretty sure it does) would have been
> more complex than the current one. But also more general and then more
> powerful.
>
> Let me clear about something: I don't expect anybody to change the
> current design. I'm nobody and I know it's always easier to criticize
> than to do things. I'm just expressing the feeling that while Rust
> tried to take a different direction from all the other new
> JVM-compliant-OOP-languages-with-functional-features (which I really
> really value very much) it seems it has not got rid of some conceptual
> patterns that are not, IMHO, necessary anymore. And I wish people
> could give their opinion about this.
>
> Thank you
>
> --
> Eddy Cizeron
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121010/5bed89a2/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: compose-unknown-contact.jpg
Type: image/jpeg
Size: 770 bytes
Desc: not available
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20121010/5bed89a2/attachment-0001.jpg>

Reply | Threaded
Open this post in threaded view
|

Rust philosophy and OOP

Niko Matsakis


Niko Matsakis wrote:
> Based on our last meeting, there seems to be general agreement towards
> a system that allows methods to be imported as standalone functions
> that take the receiver as first argument as well [1].

Actually, it occurs to me that we only discussed these kinds of imports
in the context of static fns.  But in any case I am a fan of permitting
any function defined in an impl to be imported and used as a standalone
function, and I think I am not alone in this. =)


Niko

12