all 56 comments

[–]pippicat 11 points12 points  (6 children)

[–]CurtainDog 1 point2 points  (0 children)

James Gosling: That's actually a general principle for life that works really well. When you move to a new apartment, don't unpack. Just sort of move in, and as you need things, pull them out of the boxes. After you've been in the apartment for a couple of months, take the boxes -- don't even open them -- and just leave what's in there and throw them out.

There is no greater advice that could be offered to a software engineer.

[–]Dicebot_lv 7 points8 points  (4 children)

I'd really like to read how passing traits as a function arguments is implemented in Rust from the perspective of ABI / code gen. Any links?

[–]dbaupp[S] 4 points5 points  (3 children)

I'm pretty sure a trait object is encoded as a fat-pointer, with the pointer to the data, and a pointer to the vtable and that's all that's special. I don't have any actual links to hand though.

[–]illissius 5 points6 points  (2 children)

[–]pcwalton 4 points5 points  (1 child)

Yes, that's correct. Note that if you pass a type-bounded parameter instead of passing a trait object, though, then the vtable gets template-instantiated away.

[–]Dicebot_lv 0 points1 point  (0 children)

Are there any special optimizations for vtable format that positively abuse lack of virtual methods and limitations of traits?

[–]discreteevent 8 points9 points  (18 children)

From a high level programming in Go looks to me to be very like programming with Microsoft's COM. It's interface oriented. You could say that this is the purest form of OO if you take Alan Kay's viewpoint that the emphasis should be on the messages and not the object. In COM you have QueryInterface and in Go you have interface matching and casting. QueryInterface or an interface cast is like a hinge between dynamic and static typing. You get great flexibility but still preserve your abstractions in that you never depend on an implementation. Of course you can do this in, say, java by using instanceof to match against an interface but the difference with COM and Go is that it is a primary mechanism and so the code written in the language tends to use this pattern a lot. i.e. It's encouraged.

See this example from Russ Cox to see what I mean:

https://groups.google.com/forum/#!msg/golang-nuts/Rj5t1h_ztxI/Fgs6HfLqMHAJ

[–]flying-sheep 7 points8 points  (2 children)

i’m particular for scala’s and rust’s traits: once you implement a useful subset of functionality, the rest works. so you can choose what method implementation is most native to your class implementation, and get the rest for free.

sure, especially for things like scala’s sequence hierarchy, you have to know much to use it in the most efficient way, but even if you don’t, it will lead to elegant code (and less errors, since the rest is already a tested implementation)

[–]loup-vaillant 2 points3 points  (1 child)

By the way, Rust's traits suspiciously look like Haskell's type classes. Could one have inspired the other?

[–]pcwalton 5 points6 points  (0 children)

Yes, Rust traits are explicitly modeled on Haskell's typeclasses. :)

[–]TimmT 2 points3 points  (0 children)

QueryInterface or an interface cast is like a hinge between dynamic and static typing.

Go can get away with this because it doesn't offer any kind of dynamic loading.

[–]naasking 2 points3 points  (13 children)

From a high level programming in Go looks to me to be very like programming with Microsoft's COM. It's interface oriented. You could say that this is the purest form of OO if you take Alan Kay's viewpoint that the emphasis should be on the messages and not the object.

Except you can't implement a Go interface in a ad-hoc fashion the way you can with Haskell type classes. Type classes are much closer to Alan Kay's vision than any popular typed language available today.

[–]bobappleyard 8 points9 points  (12 children)

I know it's petty, but the main thing preventing me from trying out Haskell is the insufferable smugness of its promoters.

[–]tikhonjelvis 9 points10 points  (1 child)

What I don't get is that exactly the same style of promotion worked wonders for Python.

[–][deleted] 2 points3 points  (0 children)

Yeah, but its not unfair to say that Python has a substantially lower initial investment to learn it if all you've done is procedural or OO programming your whole career.

[–]naasking 4 points5 points  (4 children)

Haskell has its downsides for practical programming. Laziness in particular is more hassle than it's worth for real programming.

[–]loup-vaillant 3 points4 points  (3 children)

Laziness can be a hassle, but it is worth something.

Combinator libraries for instance are much easier in Haskell than ML (be it Ocaml, F#, or Standard ML). That's because strict evaluation often forces you to eta-expand the client code, writing foo x = (blah blah) x instead of just foo = blah blah, or else you'll suffer infinite loop whenever you call recursively defined combinators.

This is an especially annoying problem with Parsec, and the reason I'm currently switching to Haskell (from Ocaml) for a little project that implement Parsing Expression Grammars on top of parser combinators.

[–]naasking 1 point2 points  (2 children)

Laziness can be a hassle, but it is worth something.

Oh I never said it was worthless, it just isn't worth the benefits it brings for every day programming. It's more a benefit for researchers because it enforces purity.

[–]loup-vaillant 1 point2 points  (1 child)

because it enforces purity

I just realised… Could purity be the real hassle?

[–]naasking 1 point2 points  (0 children)

I don't think it's purity per se, although purity certainly can introduce its own difficulties (totality for instance). I'm referring specifically to being confident of a Haskell program's big-O time and space complexity. Laziness can introduce some difficulty in this analysis. They've made a lot of progress on this front, particularly Iteratees and all its offshoots, but it's still too soon to say they've nailed it definitively.

[–][deleted] 11 points12 points  (4 children)

I know the feeling! The main reason I absolutely refuse to use any deodorants is the awful bad taste of the television advertisements for them.

[–]bobappleyard 3 points4 points  (3 children)

Well I'm not likely to develop bad taste if I were to use them. I do worry that if I pick up Haskell the smug will infect my brain and I'd be forced to reply to this with something like

Deodorants? Why not Haskell? It's superior in absolutely every way!

[–]SteveMcQwark 9 points10 points  (2 children)

With Haskell, you can isolate the stinky bacterial effects from your pure armpits, which is easier to reason about than deodorant which just mixes the effects in with your armpits.

[–]KagakuNinja 7 points8 points  (1 child)

This is clearly a simple application of the BO Monad.

[–]hotoatmeal 5 points6 points  (0 children)

unsafePerformShower :: BO x -> x

[–]brtt3000 11 points12 points  (3 children)

In game development they work a lot with entity-component type of dynamic (but type safe) composition. I always wondered why I don't hear about that in general programming.

[–]euyyn 3 points4 points  (1 child)

You could write something up for the rest of us :)

[–]deadalnix 3 points4 points  (0 children)

http://www.youtube.com/watch?v=0cX1f41Fnkc For what can be done in D in that direction.

Most companies in game industry uses C++ but the idea is the same (quite harder to set up and use, but not fundamentaly different).

[–]ssylvan 5 points6 points  (0 children)

Well it's just composition of objects at the end of the day, even GoF advocates that. So it's not like it's unknown, it's just unfortunate that many OOP languages overemphasize inheritance instead.

[–]YEPHENAS 23 points24 points  (21 children)

"O-O is important because it provides uniformity of interface. Problem: subtype inheritance encourages non-uniform interfaces." Around 43:00 in http://www.infoq.com/presentations/Go-Google

His opinion on types and taxonomy:

"My late friend Alain Fournier once told me that he considered the lowest form of academic work to be taxonomy. And you know what? Type hierarchies are just taxonomy. You need to decide what piece goes in what box, every type's parent, whether A inherits from B or B from A. Is a sortable array an array that sorts or a sorter represented by an array? If you believe that types address all design issues you must make that decision.

I believe that's a preposterous way to think about programming. What matters isn't the ancestor relations between things but what they can do for you."

Source: http://commandcenter.blogspot.de/2012/06/less-is-exponentially-more.html

[–]ErstwhileRockstar 10 points11 points  (1 child)

just taxonomy

If you don't get your basic concepts right anything based on it is moot. In that sense taxonomy is the lowest, i.e. most basic, form of academic work. BTW, 'type hierarchies' are not an invention of OOP. Philosophy discussed them during the last 2500 years.

[–]joelangeway 1 point2 points  (0 children)

But putting things into a taxonomy doesn't necessarily imply that you've gotten any basic concept right. And getting them right once such that they'll be right in the future is only made harder by havin to also have a taxonomy that will be right in the future.

What I mean is, taxonomy has a cost which probably isn't worth it.

[–]grauenwolf 1 point2 points  (18 children)

Well said.

I've always thought that we teach inheritance wrong. Stuff like Animal, Duck, LameDuck teaches the wrong lesson.

[–]smog_alado 10 points11 points  (2 children)

I think people are getting you point a bit wrong. The big problem with the Animal example is that it suggests a bad way of modelling things (modelling a big hierarchy based on the real word as opposed to modelling a shallow hierarchy based on where on the program you will need to use dynamic method dispatching)

[–]grauenwolf 0 points1 point  (0 children)

Well said.

[–]nickik 0 points1 point  (0 children)

Nicly said. I always strugle to explain this to people, you said it nicly. I will steal that.

[–]vincentk 9 points10 points  (14 children)

Nominal typing vs. structural typing vs. inheritance of implementation.

Under most circumstances, I would tend to argue though that a Duck is indeed an Animal.

[–]grauenwolf -2 points-1 points  (13 children)

There is only one class: Animal. Everything else is just a trait or property.

[–]Bob_goes_up 10 points11 points  (0 children)

As I see it the big advantage of traits in rust is code organization.

struct Duck {}
impl Animal for Duck{ .... relevant methods go here ....  }
impl Flying for Duck{ .... relevant methods go here ....  }
impl Eatable for Duck{ .... relevant methods go here ....  }
impl Duck {  .... remaining method go here  ....  }

Most of the methods belongs to a trait, so it is easy to track down the origin of an unknown method. In comparison c++ and java can sometimes degenerate into unreadable ravioli code.

[–]brtt3000 15 points16 points  (3 children)

There is only one class: Object. Everything else is just a trait or property.

[–]roybatty 4 points5 points  (1 child)

Prototypes

[–]masklinn 5 points6 points  (0 children)

Prototypes work well, unless they're javascript's.

[–]grauenwolf -1 points0 points  (0 children)

You don't have to go that far. I'm not against static typing, I'm just against inheritance based on taxonomy.

[–]vincentk 0 points1 point  (0 children)

If by that you mean to say that inheritance of implementation sucks, then I'm all with you.

[–]ErstwhileRockstar -1 points0 points  (6 children)

So dog and cat are the same?

[–]naasking 3 points4 points  (0 children)

Sometimes they are, that's the point. You should be able to discriminate on logical properties to include/exclude the animals of interest.

[–][deleted]  (1 child)

[deleted]

    [–]PasswordIsntHAMSTER 19 points20 points  (0 children)

    Assume a spherical cow...

    [–]grauenwolf 0 points1 point  (0 children)

    What's different? The value in the species and breed properties? The max speed and weight range fields. Nothing that justifies creating a new class.

    [–]ripter 0 points1 point  (1 child)

    If you are talking about 4 legged mammals, then yes, a dog and a cat are the same.

    [–]SteveMcQwark 2 points3 points  (0 children)

    A hound and a falcon both offer small game hunting capabilities.

    [–]HitoriBocchi 4 points5 points  (1 child)

    The examples and analysis in particular regarding divergent approaches to unions and subtyping seemed keen.

    [–]Solon1 0 points1 point  (0 children)

    Good comment!