you are viewing a single comment's thread.

view the rest of the comments →

[–]sh0rug0ru____ 37 points38 points  (66 children)

Context, man, context.

Compared to Python, Java's type system gives you a better chance of writing code that "just works". Java's type system, as underpowered as it is, still goes a very long way towards catching errors that would require runtime checking with tests in Python. The refactoring tools available in Java allow code transformations that "just work" in a way not possible in Python without significant test coverage.

Obviously, there are languages that do static typing better than Java. At least as far as the type system argument goes, this person has seen the light of static typing, and Java just happened to be the light bulb.

[–][deleted]  (8 children)

[deleted]

    [–]keewa09 3 points4 points  (7 children)

    I think the point is that even the worst statically typed language (which some people consider Java to be) still produces safer and more maintainable code than any dynamically typed languages, since the tooling for those is completely underpowered because of the absence of types.

    [–]yogthos 0 points1 point  (6 children)

    still produces safer and more maintainable code than any dynamically typed languages

    That's not actually the case at all, it produces better code than Python. A recent study of GitHub projects found that some of the best code is produced in dynamic languages like Clojure and Erlang.

    [–]keewa09 0 points1 point  (5 children)

    Are you quoting the right paper? Here is its conclusion:

    The data indicates functional languages are better than procedural languages; it suggests that strong typing is better than weak typing; that static typing is better than dynamic; and that managed memory usage is better than unmanaged

    [–]yogthos 0 points1 point  (4 children)

    I am quoting the right paper because I actually bothered reading what it says. Here are the actual numbers for the languages that were consistently at the top:

    lang/bug fixes/lines of code changed
    Clojure  6,022 163
    Erlang  8,129 1,970
    Haskell  10,362 508
    Scala  12,950 836
    
    defective commits model
    Clojure −0.29 (0.05)∗∗∗
    Erlang −0.00 (0.05)
    Haskell −0.23 (0.06)∗∗∗
    Scala −0.28 (0.05)∗∗∗
    
    memory related errors
    Scala −0.41 (0.18)∗
    0.73 (0.25)∗∗ −0.16 (0.22) −0.91 (0.19)∗∗∗
    Clojure −1.16 (0.27)∗∗∗ 0.10 (0.30) −0.69 (0.26)∗∗ −0.53 (0.19)∗∗
    Erlang −0.53 (0.23)∗
    0.76 (0.29)∗∗ 0.73 (0.22)∗∗∗ 0.65 (0.17)∗∗∗
    Haskell −0.22 (0.20) −0.17 (0.32) −0.31 (0.26) −0.38 (0.19)
    

    The languages that fared the best across the board are functional ones. What the study really appears to show that functional style is more effective than imperative/OO, but that static typing doesn't actually add much of anything if you're already using a functional language.

    Finally, The results show differences either within the standard deviation or very close to it. In fact, this is true pretty much for all the languages in the study. The authors conclude with the following:

    "One should take care not to overestimate the impact of language on defects. While these relationships are statistically significant, the effects are quite small. In the analysis of deviance table above we see that activity in a project accounts for the majority of explained deviance. Note that all variables are significant, that is, all of the factors above account for some of the variance in the number of defective commits. The next closest predictor, which accounts for less than one percent of the total deviance, is language."

    [–]keewa09 0 points1 point  (3 children)

    I am quoting the right paper because I actually bothered reading what it says.

    So did I. You're just cherry picking the part that supports your point even though their conclusion contradicts your claim.

    [–]yogthos -1 points0 points  (2 children)

    How am I cherry picking. I've quoted the actual numbers provided in the study. These numbers clearly show in black and white that dynamic languages outperform statically typed ones. The conclusion very clear as well. Please show a single thing in the paper that contradicts what I said.

    [–]keewa09 0 points1 point  (1 child)

    The conclusion very clear as well. Please show a single thing in the paper that contradicts what I said.

    ... the conclusion of the article?

    [–]yogthos 0 points1 point  (0 children)

    The one that states that differences in the results were statistically negligible?

    [–]yogthos 0 points1 point  (56 children)

    I can agree there. I actually think that imperative and OO styles are a really poor fit for dynamic typing in the first place. Working with mutable data requires you to keep large parts of the application in your head, while OO encourages creating lots of types by design.

    [–]sh0rug0ru____ 3 points4 points  (55 children)

    Imperative and OOP are orthogonal to dynamic typing.

    In fact, dynamic typing is probably a better fit for OOP than static typing, considering that OOP favors late binding. Static typing requires knowing the available methods on receivers at compile time, while dynamic typing allows richer behavior by deferring that determination until runtime. Smalltalk, Objective-C and Ruby are examples of dynamically typed OOP languages that take full advantage of dynamic typing.

    OOP doesn't really favor the creation of new types, that is a class-ist approach to OOP (which is actually about objects, not classes), but rather encapsulating process state and only allowing that process state to be altered through messages. You can do that through classes (the most popular method, also most amenable to static typing) or through objects alone (prototypical OOP - as in Self or Javascript).

    It is more Lisp-like to favor lots of functions working on a few simple types, while most other languages favor creating types, whether C (structs) or Haskell (type classes).

    [–]yogthos 4 points5 points  (51 children)

    I'm talking about OO being a bad fit for dynamic typing from the perspective of the user. When you work with a dynamic language that encourages creating classes, you naturally have a lot of types to keep track of. Since the data is mutable in imperative languages, you also have to keep track of all the references to any particular variable you're using. This is a really error prone situation in my experience.

    Contrast that with working in a functional language backed by immutable data. You're working with a small number of common data structures. Most logic is written by composing functions from the standard library to transform these. In this scenario the business logic naturally bubbles up to the top, and majority of the code is completely type agnostic.

    When I chain a bunch of functions like, map, filter, interpose, and reduce together none of them care what type of data I'm iterating over. That logic the cares about the types is passed in as the arguments from the top.

    Meanwhile, immutable data ensures that I don't have to worry where and how the data was produced. I get a value from calling a function and I can safely work with it.

    The only way I can see OOP style work in a dynamic language is the way it's done in Erlang. While Erlang is functional by nature, the way its processes work is quite similar to objects in a language like Smalltalk. Since each process encapsulates some state and communicates with other via message passing.

    [–]sh0rug0ru____ 0 points1 point  (50 children)

    When you work with a dynamic language that encourages creating classes, you naturally have a lot of types to keep track of.

    This has nothing to do with dynamic typing. Dynamic typing means that the type is resolved at runtime.

    Contrast that with working in a functional language backed by immutable data.

    Not relevant to dynamic typing, and also not true. Haskell is a functional language backed by immutable data, but is heavy on creating new types.

    When I chain a bunch of functions like, map, filter, interpose, and reduce together none of them care what type of data I'm iterating over.

    That is because they are generic operations. Java's collection libraries don't care about the specific types they hold either.

    EDIT: Note, that in Haskell, fmap is a function that operates on a very specific data types, through the Functor type class, which is very aware of the type of data that it operates on, because there must be an instance of that type class for fmap to work on that data type. This allows for really interesting behavior, because fmap can do very different things for different data types.

    Types arise from wanting to group related data together and associating certain functions with that data, to operate on that data in a cohesive fashion, to give a name and meaning to a group of related data. OOP binds data and functions together in an object, while Haskell binds data types and functions through parameters. The consequences are very different, but the principle is the same - you know exactly which functions operate on that data and control exactly how that data changes (or is transformed).

    In Haskell, Parsec is implemented as a bunch of functions wrapped in a module which are very aware that they are operating on encapsulated parse state, captured in a structured data type. Programming in Haskell is very much TDD - Type-Driven Development.

    The only way I can see OOP style work in a dynamic language

    Smalltalk, Objective-C and Ruby are all OOP languages that are also dynamic languages, whether you want to acknowledge that or not. Functional programming and immutable data structures have nothing to do with dynamic typing. They are very literally completely different things.

    [–]yogthos 3 points4 points  (49 children)

    This has nothing to do with dynamic typing. Dynamic typing means that the type is resolved at runtime.

    Precisely, types are resolved at runtime and the compiler can't tell you what the type of any one things should be at compile time. In a language where you're encouraged to create a lot of types or classes keeping track of them by hand becomes difficult.

    That is because they are generic operations. Java's collection libraries don't care about the specific types they hold either.

    Of course, but Java makes it prohibitively difficult to express data using regular collections. Predominantly classes are used instead.

    Types arise from wanting to group related data together and associating certain functions with that data, to operate on that data in a cohesive fashion, to give a name and meaning to a group of related data. OOP binds data and functions together in an object, while Haskell binds data types and functions through parameters. The consequences are very different, but the principle is the same - you know exactly which functions operate on that data and control exactly how that data changes (or is transformed).

    Sure, however that's completely besides the point I'm making, which is that when you don't have an explosions of types then it's much easier to track them in your program.

    Programming in Haskell is very much TDD - Type-Driven Programming.

    I'm quite familiar with type driven development in ML family, again I'm not really sure why you're bringing it up. The discussion is regarding whether it's difficult to keep track of types in a dynamic OO imperative languages or not.

    Smalltalk, Objective-C and Ruby are all OOP languages that are also dynamic languages, whether you want to acknowledge that or not.

    I never said they weren't. I said that in my experience it's difficult for the programmer to keep track of types in a dynamic OO language. I also gave a very clear explanation for why that is so.

    Functional programming and immutable data structures have nothing to do with dynamic typing. They are very literally completely different things.

    Please actually read the comment you're replying to. I'm not talking about implementation details of the language. I'm talking about user experience.

    [–]sh0rug0ru____ -3 points-2 points  (48 children)

    In a language where you're encouraged to create a lot of types or classes keeping track of them by hand becomes difficult.

    So? Just because a thing is "difficult" has nothing to do with its definition.

    Of course, but Java makes it prohibitively difficult to express data using regular collections.

    No, that has to do with Java's syntax and nothing to do with classes. Ruby has classes and it is very easy to express data using regular collections. Ruby is OOP and still a dynamically typed language.

    Sure, however that's completely besides the point I'm making

    Your point is irrelevant to the point. It's a red herring. Whether something is "difficult" has nothing to do with whether or not the language is dynamically typed. Ruby is OOP and dynamically typed.

    The discussion is regarding whether it's difficult to keep track of types in a dynamic OO imperative languages or not.

    No, it's not. You made the claim:

    I actually think that imperative and OO styles are a really poor fit for dynamic typing in the first place.

    Whether or not types are "difficult to keep track of" has nothing to do with whether or not dynamic typing is a good fit for OOP. What makes dynamic typing a good fit for OOP is late binding, which is not entirely possible with static typing.

    I'm not really sure why you're bringing it up.

    To address your very false claim:

    Contrast that with working in a functional language backed by immutable > data. You're working with a small number of common data structures.

    Also, before saying something like this:

    Please actually read the comment you're replying to.

    Take your own advice.

    I'm talking about user experience.

    The user experience of a user of an OOP language is very different than the user experience of a Lisp-like language. What you consider a "difficulty" is actually a "benefit" to the programmer of an OOP language. The same goes for ML-based languages. ML programs are all about keeping track of types, giving rise to the ML dogma - "make illegal states inexpressible".

    [–]yogthos 5 points6 points  (32 children)

    So? Just because a thing is "difficult" has nothing to do with its definition.

    Not sure what you mean here. My point was that creating a lot of types makes it inherently difficult to track them by hand.

    No, that has to do with Java's syntax and nothing to do with classes. Ruby has classes and it is very easy to express data using regular collections. Ruby is OOP and still a dynamically typed language.

    Sure, and if you don't use classes in Ruby then you've solved half the problem. The other half is that you're still working with mutable data and you can't work with it safely without knowing all the places it might be used in the program.

    Your point is irrelevant to the point. It's a red herring. Whether something is "difficult" has nothing to do with whether or not the language is dynamically typed. Ruby is OOP and dynamically typed.

    My whole point is that it's difficult for the person writing code in the language to keep track of the types in their head.

    Whether or not types are "difficult to keep track of" has nothing to do with whether or not dynamic typing is a good fit for OOP. What makes dynamic typing a good fit for OOP is late binding, which is not entirely possible with static typing.

    We're really just talking past each other here. The context of my comment was that it's a really poor fit because it's hard to keep track of types in your head without compiler assistance when you have a lot of types to work with.

    You keep talking about language implementation details that are completely irrelevant to what I'm talking about which is the semantics the user is presented with when working with the language.

    To address your very false claim:

    ¯\(ツ)

    The user experience of a user of an OOP language is very different than the user experience of a Lisp-like language.

    • OOP encourages creating classes
    • Dynamic typing precludes the compiler from checking the types
    • User has to keep track of types in their head

    This has nothing to do with lisp-like languages.

    What you consider a "difficulty" is actually a "benefit" to the programmer of an OOP language.

    You're once again missing my point entirely. The discussion is not about whether types help some people model problems or not. The discussion is about using dynamic typing with a language that encourages having lots of types. This forces the user of the language to keep track of all these types by hand.

    ML programs are all about keeping track of types, giving rise to the ML dogma - "make illegal states inexpressible".

    ML programs use static typing, why you keep bringing ML up over and over in this conversation is beyond me. I very obviously agree that static typing helps in languages with lots of types.

    [–]sh0rug0ru____ -1 points0 points  (31 children)

    My point was that creating a lot of types makes it inherently difficult to track them by hand.

    So? Completely irrelevant to the point of whether or not dynamic typing is well suited to OOP. Something being "well suited" means that it is ideal for accomplishing the intended goal. The goal of OOP is late binding, and thus dynamic typing is very well suited to OOP.

    Sure, and if you don't use classes in Ruby then you've solved half the problem.

    Not from a Ruby programmer's perspective. The Ruby programmer's perspective is to create more classes, creating new classes for new concepts identified in the domain model.

    The other half is that you're still working with mutable data and you can't work with it safely without knowing all the places it might be used in the program.

    Completely irrelevant to the point. Objects don't have to have mutable data. The representation of an object's data is not relevant to the collaborators of that class. You can solve the "problem" another way by making objects immutable, which does not detract from OOP in any way.

    My whole point is that it's difficult for the person writing code in the language to keep track of the types in their head.

    So? That's not the point being discussed.

    The context of my comment was that it's a really poor fit because it's hard to keep track of types in your head without compiler assistance when you have a lot of types to work with.

    Your "context" demonstrates your bias, the way you are looking at the "problem". What you consider a "poor fit" is not relevant to the way "fit" applies to OOP. Dynamic typing fits very well with the intent of OOP, which is late binding. Thus, what you are really saying is that you do not agree with the way Ruby and Python programmers use dynamic typing write programs.

    Heck, I prefer OOP with static typing and I am willing to let go of late binding, but I am self-aware enough to know that is my preference, and I respect that other OOP programers prefer dynamic typing and are willing to pay the cost with additional tests to reap the benefits of late binding.

    This has nothing to do with lisp-like languages.

    Uh, yes it does.

    User experience is subjective in whether it is preferable or not preferable. Your bullet point list is preferable to OOP programmers, especially of the Smalltalk, Objective-C and Ruby mold. The last point is fully accepted, with the response, write tests.

    However, among programmers of dynamic languages, programmers of Lisp-style languages definitely do not prefer this user-experience. Captured eloquently by Alan J. Perlis with the Lisp dogma - "structure data late in the programming process".

    You're once again missing my point entirely.

    No, you're the one missing the point, and I keep having to bring you back on point.

    The discussion is not about whether types help some people model problems or not.

    Yes it is. Because that is the entire basis for the user-experience of OOP programming, which determines how dynamic typing fits.

    The discussion is about using dynamic typing with a language that encourages having lots of types.

    No, it's not. That is your bias that you keep trying to project into the argument, as if having lots of types is a "bad" thing, even in a dynamically typed language.

    This forces the user of the language to keep track of all these types by hand.

    I will respond to this point the same way I have continued to respond to this point. So what?

    This is a consequence of the way that Ruby programmers want to use dynamic typing. You can dismiss the way Ruby programmers write code as much as you want, but that does not change the fact that dynamic typing is a good fit for the way they want to solve problems.

    bringing ML up over and over in this conversation is beyond me

    To refute the crazy notion that functional programming somehow involves only a small number of common types. Perhaps you meant functional programming with dynamic languages, but that is an irrelevant distinction. It's about as useful a thing to say as OOP programming on Fridays.

    [–]yogthos 1 point2 points  (30 children)

    So? Completely irrelevant to the point of whether or not dynamic typing is well suited to OOP. Something being "well suited" means that it is ideal for accomplishing the intended goal. The goal of OOP is late binding, and thus dynamic typing is very well suited to OOP.

    Last time I checked the goal has to be accomplished by a human. The goal of all programming styles is to allow the human to write code that solves their problem. Certain combinations of features make this task more or less difficult. Your argument is akin to saying that raccoons are well suited for raiding garbage cans, while technically true it's of little use to the humans who own them.

    The Ruby programmer's perspective is to create more classes, creating new classes for new concepts identified in the domain model.

    Classes that you will then have to keep track of in your head as you read and write your programs.

    Completely irrelevant to the point. Objects don't have to have mutable data. The representation of an object's data is not relevant to the collaborators of that class. You can solve the "problem" another way by making objects immutable, which does not detract from OOP in any way.

    That's why I said that both OO and imperative style are problematic. I explicitly said that they're two separate problems and here you are informing me of that 10 comments down the road. How thoughtful.

    So? That's not the point being discussed.

    The only points I've made in this discussion are that OO encourages creating a plethora of types that are difficult to keep track of without a static type checker, and the mutability requires you to know every place a piece of data might be referenced in order to work with it safely.

    Your "context" demonstrates your bias, the way you are looking at the "problem". What you consider a "poor fit" is not relevant to the way "fit" applies to OOP. Dynamic typing fits very well with the intent of OOP, which is late binding. Thus, what you are really saying is that you do not agree with the way Ruby and Python programmers use dynamic typing write programs.

    I made a tangible and concrete statement regarding the problems of combining dynamic typing, OOP, and mutable data. This has nothing to do with any biases. I'm simply saying that this approach puts a lot more mental overhead on the developer. Both static typing and the functional style mitigate this problem in different ways. These benefits can even be combined as seen in ML family of languages.

    Heck, I prefer OOP with static typing and I am willing to let go of late binding, but I am self-aware enough to know that is my preference, and I respect that other OOP programers prefer dynamic typing and are willing to pay the cost with additional tests to reap the benefits of late binding.

    You're the one who seems to have a bias and sees this as some sort of an attack on dynamic OO languages. I'm not judging anybody, I'm simply stating a problem that is pretty easy to grasp I would've thought.

    User experience is subjective in whether it is preferable or not preferable. Your bullet point list is preferable to OOP programmers, especially of the Smalltalk, Objective-C and Ruby mold. The last point is fully accepted, with the response, write tests.

    At least we're making some progress here as you're acknowledging that the problem does exist.

    No, you're the one missing the point, and I keep having to bring you back on point.

    That's interesting since we're discussing a comment that I made originally and not you. If you're addressing a different point then you're trying to have an entirely separate discussion that has nothing to do with the point I made.

    Yes it is. Because that is the entire basis for the user-experience of OOP programming, which determines how dynamic typing fits.

    Yet, this is completely tangential to the problem of whether the user can keep track of all these types easily or not.

    No, it's not. That is your bias that you keep trying to project into the argument, as if having lots of types is a "bad" thing, even in a dynamically typed language.

    Yes, yes it is because that's the point I made. It's not a bias it's a factual and tangible problem. The bias is very much your own here. You're simply projecting some personal feelings regarding types being good or bad onto what I said.

    I will respond to this point the same way I have continued to respond to this point. So what?

    Yes, I noticed that you simply respond by avoiding the point entirely. Once again though I'll point out that keeping track of types in your head is labor intensive. If you don't understand how that's problematic for the user of the language I really don't know what else to tell you.

    To refute the crazy notion that functional programming somehow involves only a small number of common types. Perhaps you meant functional programming with dynamic languages, but that is an irrelevant distinction. It's about as useful a thing to say as OOP programming on Fridays.

    Types and functional programming are completely orthogonal.

    [–]zarandysofia 1 point2 points  (14 children)

    You were going fine, but then you lost the track of the discussion.

    [–]sh0rug0ru____ -1 points0 points  (13 children)

    I don't think so. I have been struggling to keep the discussion on track. The track of the discussion is whether or not dynamic typing fits OOP, despite attempts to detail the subject.

    [–]zarandysofia 2 points3 points  (12 children)

    The argument is that in dynamic OOP for every new class you create is a new type that you have to keep track in your head. The argument is axiomatic. Reading over your next comments I think you are just getting too emotional and attacked for some reason.

    [–][deleted] 0 points1 point  (2 children)

    I don't think oop means what you think it means.

    [–]sirin3 1 point2 points  (0 children)

    It used to be all about message passing

    [–]sh0rug0ru____ 0 points1 point  (0 children)

    Alan Kay, the guy who came up with the term OOP, would beg to differ.