Conversation started Oct 16, 2013 at 13:35.
Oct 16, 2013 13:35
@JimmyHoffa - Thanks for the compliments on the Whiteboard earlier. I enjoy constructive debate and greatly appreciate a clear, direct refutation of my statements. Your replies are DH5 or DH6 - it doesn't get any better than that. paulgraham.com/disagree.html
user41796
To the OP I can only suggest: Learn Haskell. If you truly want to learn FP, all the tutorials and nonsense in the world often leads you around the water to show you where the lake is, but that doesn't help you learn to swim. Learning Haskell is how everyone should disembark on their FP journey, it's akin to learning to swim by tossing you in the middle of the Atlantic, the only difference is for all your failures on the path, you'll never drown. So hang on tight and start paddling, with Haskell at your side you'll come to understand FP style better than any other softer language can teach. — Jimmy Hoffa 13 hours ago
user41796
^^^^ Who didn't see that one coming a mile away? @JimmyHoffa
@JimmyHoffa - I added a PS to my answer in response to this statement "If a function is inside an object, it must be there to act on that object; and if it acts on that object it must be changing it's internals." I agree that your accusation is typical of the practice of OOP (and of virtually every other kind of popular programming until maybe 3 years ago), but it is not an inherent aspect of OOP.
user41796
@GlenPeterson - Jimmy's known as our local Haskell evangelist in the chat room. I'm kind of surprised he didn't weigh in more on that particular OO => FP question. But he tends to hold back when solid answers are already in place
@JimmyHoffa said, "You could have the function change the object in place, then return the object. If so, then why not make the function take the object as a parameter and free it from the confines of it's parent object? Freed from the parent object it will be able to work on other types as well." THX! This is actually the best answer I've heard to a question I posted a while back: programmers.stackexchange.com/questions/212515/…
@JimmyHoffa said, "The reason you abstract things to map and reduce." And there's the ultimate problem with Java. It does not provide abstractions suitable for use with immutability. Specifically, it's collections return something useless like "true" when you call add() instead of returning a new collection. It's functional object interface (which some call a functor) has no return type. Unless Java does an about-face, it will never be compatible with immutability.
@JimmyHoffa said, "functions are not bound to containing objects so they can be used on a myriad of types through parametric polymorphism. [that's why] functional composition [is] where functions can abstract over types generally." OK, but how does that work with type safety? Clojure seems to make this trade-off, providing really general functions at the expense of runtime safety.
Oct 16, 2013 14:18
I will never... never ... ever... even at gunpoint .... work at a company that even so much as entertains the notion of even considering Websphere Application Server
NEVER
AGAIN
COMPLETE
user41796
WAS had its day
TOTAL
GARBAGE
user41796
not so much anymore
No Glen... no... you don't understand...
you just don't understand how bad this is
user41796
I think the lads in Hursley started pursuing crap that just didn't make sense for the real world. And they were doing such crazy stuff to begin with that they couldn't bring the code back around to reality
user41796
Oct 16, 2013 14:19
oh, I used to know some of the R&D devs for WAS....
I just want to crawl in a hole and die
rather than have to try and fix another friggin environment issue
user41796
Websphere apps have that effect on folk. They are pretty brittle
user41796
I administered some MQ systems and tangentially touched some websphere AS stuff too
I have opened 5 different PMRs just to upgrade JSF on a single application, and after following their advice a classloader issue has completely crashed the server
user41796
in my case, it was a pretty static environment, so I lucked out and didn't have to do much
user41796
Oct 16, 2013 14:22
@maple_shaft go critical on L2 then. Truly - if you're not getting the support you need then convert the PMR to a critical situation
That will have to be the next step then
charges should be brought against companies that peddle such unstable pieces of steaming refuse as this
user41796
IBM support really doesn't like having a PMR go critical, but such is life. Sometimes L2 and L3 simply can't get the resources you need to answer your question until it goes critical
@GlenH7 - I've dabbled in Haskell with the hope of understanding Monads. I still don't understand Monads. There are so many things I want to learn... I'm sure a Haskell pro would take offense at this, but I tend to think of Scala as Haskell for the JVM. Since I'm tied to the JVM, I've been exploring Scala instead.
user41796
@GlenPeterson they irony of there being an open Haskell discussion in the chat room and @JimmyHoffa NOT BEING INVOLVED is simply palpable....
user41796
I fear this day will go down in infamy for him
Oct 16, 2013 14:24
@GlenPeterson That's Clojure's approach, JavaScript does the same thing, it's indicative of dynamically typed FP languages which aren't uncommon, but I was trying to make clear the type system itself isn't really the hard-line that makes a language FP. The HM type system exists with the explicit purpose of giving static typing in the vain of allowing those highly general abstractions, ties back to Algorithm W
> Among the properties making HM so outstanding is completeness and its ability to deduce the most general type of a given program without the need of any type annotations or other hints supplied by the programmer. Algorithm W is a fast algorithm, performing type inference in almost linear time with respect to the size of the source, making it practically usable to type large programs.
(emphasis mine)
lol
speak of the devil
user41796
@maple_shaft When you contact them on the 5th PMR, just politely request that you need to escalate the issue to sev 1 and to make it critical. Point out that having 5 PMRs to resolve an issue is unacceptable. Then point out that the last resolution crashed your server so you have lost use of the application.
user41796
The first item justifies the crit sit. The second item justifies the sev 1
user41796
and don't let them talk you into a lower severity until your server is up and running again.
But the HM type system just rises as a side effect of trying to have those general abstractions and trying to get compile-time type checking, Clojure says rightly "FP doesn't need compile-time type checking" but Clojure doesn't mistake to say "Functions don't need to be composable by way of taking data as parameters and returning values"
user55340
Oct 16, 2013 14:26
@GlenH7 I'm fairly sure that @JimmyHoffa has a haskell program that polls the chat room transcript for various mentions and sets off a gong when someone mentions a 'monad' or other key words. The only problem is that setting off a gong induces a state change...
Clojure allows the dynamicism explicitly to allow that generalized abstraction
user41796
@MichaelT wretched, wretched state changes....
user55340
@GlenH7 Its really quite limiting... imagine never being able to change your state out of, say, Colorado. Pure FP programmers can never change their state.
@GlenH7 I have a critical deadline to resolve some proof of concept stuff then I absolutely must start on features. What this means is that I will have to use plain JSP's for my portal development as opposed to JSF which we are all experienced in. I am writing an architecture guide currently and I need to finish this before the dev team starts writing portlets. Without this document they will create an unmaintainable mess
Oct 16, 2013 14:28
@GlenPeterson I don't take it as an insult, I just personally disagree with the purpose of OO in FP, as many say they're orthogonal concepts and I don't disagree, but they're orthogonal like a bike and a car: You can have both, but when you do, one of them becomes pretty pointless
While I agree with you on escalation... it is just easier for me to reinstall
@MichaelT I have to rely on the runtime to mutate my state for me :(
user41796
@maple_shaft That's always a hard decision point. Just because you go critical doesn't guarantee you'll have a resolution in the timeframe you need. I would still escalate it, but hedge your bets by following the other path you mentioned. Keep in mind that if you don't go critical then they'll never really know what a steaming problem it was that you ran into
@GlenH7 Is @maple_shaft about to become an unstoppable chain reaction? Don't do it @maple_shaft, just remember Three Mile Island!
user41796
"Back in the day", Support had to tally the total number of crit sits they had for the year. And they also ranked them by severity. Too many situations meant long talks with development about fixing the core issues.
user41796
Oct 16, 2013 14:32
@JimmyHoffa past tense. He already changed state.
@GlenH7 I am beyond caring what they know.... they obviously are ineffective at preventing such problems to begin with because they encourage the brain drain and technical debt that led them to this sorry pathetic state their ridiculous company has put themselves in
it just doesn't matter
user41796
@maple_shaft I have heard similar from many Websphere clients...
The core fact remains their software is unusable, and the conspiracy theory part of me believes this is by design so that they can sell you yet another project
or sell you consultants
F***** ingrates
user41796
@maple_shaft nah, Global Services really doesn't have much feedback into the design cycle. You're safer just blaming the eggheads who created WAS to begin with.
@GlenPeterson Scala doesn't seem a terrible language, but encapsulating a method in an object just lacks reason in FP because again, you're coupling that method with it's parent type then, and FP is all about generalizing methods and removing tight coupling. In procedural code we couple things sequentially, in OOP we couple things rationally, in FP we try to stop coupling things altogether.
Oct 16, 2013 14:35
The only part of me that cares is posting what I DO know in an SO question, (that can actually be indexed by Google unlike their horrible documentation sites) and self answer so that other people like me don't have to suffer through what I did...
user41796
Hursley makes some amazing, amazing stuff, as do the other R&D sites. But they are not ready for enterprise consumption out of the gate. And if you build up a monstrous application stack without the right foundation then you're doomed to see it collapse upon itself.
but I am exhausted
We're not used to thinking about a method inside an object as type coupling because it's the only way you can have a method in OOP, but it is coupling, and it is unnecessary, as well as it leads the horse to the water of non-compositional functions. As soon as your method is in an object, it's a really short step from saying 'well, I might as well just let it change the field in here instead of returning a new one since it's in here already...'
and starting to NOT care about anybody but myself at the moment
user41796
dirty secret - I once wanted (and still kind of do) to work in an IBM R&D center. Nearly applied to work at Almaden.
Oct 16, 2013 14:38
@maple_shaft shit, at this point even venting the irradiated material won't stop you will it... the best we can hope for is a 40' thick cement sarcophogus. @GlenH7 get on it, you're the only real engineer around here...
Sorry guys... just venting to prevent nuclear meltdown its the lesser of two evils
I will still probably get cancer from this though
user41796
@JimmyHoffa Cost of living is what stopped me from applying. They simply couldn't provide a large enough uplift to make it worth considering
@GlenPeterson does this make sense what I'm saying? Am I just rambling madmanese? Here ye here ye! All have the lost buffalo within them! One need open their eyes, ears, and hair! Eat from the flesh of the electronics, the sky will bequeeth to you a woog-woog and we shall be slain, err saved, err slaved err RUN AWAY RUN AWAY...
@JimmyHoffa If you decouple all your functions from all but the most general type it could operate on, how do you organize your programs? Do you use files, or namespaces? Small programs sometimes use all globals, but large programs are all but impossible with that approach.
@GlenPeterson Module systems vary, but are usually effectively like namespace organization
Oct 16, 2013 14:41
@JimmyHoffa It takes me time to read things like the Wikipedia entry on the Hindley-Milner type system.
@JimmyHoffa I didn't think you were crazy until your madmanese post. :-)
Note though, because multiple things are together in a module means nothing of their existence to interact with eachother so it's not like a class, they're just as you said, code-organization techniques. You may have modules with nothing but groups of functions that all work on a couple different general primitive types, and are organized together because they can be composed
or for any reason you wanted to organize them together really
the HM type system just refers to a type system based on what is commonly called Algebraic Data Types, Scala has those no?
Scala breaks down and fails to accomplish Algorithm W quality inferrence though because it's type system also has objects and non-ADT structures
@JimmyHoffa My experience is that when code is used in a way it was not intended to be used, it often breaks. Even for simple functions, it is very easy to make significant mistakes. Types are documentation of what the author was thinking and what they designed the function to handle. Once-again, this seems like trading wide reuse for safety.
@GlenPeterson Sorry, referring to what exactly?
You're saying the HM type system gives safety but doesn't allow wide reuse?
@JimmyHoffa yes.
@JimmyHoffa No
@JimmyHoffa :-) Thinking...
think about this ADT and function:
data Tree a = Node a (Tree a) (Tree a) | Nothing

treeMap :: (a -> b) -> Tree a -> Tree b
treeMap f (Nothing) = Nothing
treeMap f (Node val left right) = Node (f val) (treeMap f left) (treeMap f right)
Notice how it generalizes allowing to be used on a tree that has any type of value?
the type signature of treeMap :: just says (a -> b) so it's first param is a function that goes from any arbitrary type a, to any other arbitrary type b, and a Tree with values of that arbitrary type a (the part Tree a), and returns a Tree with values of the arbitrary type b (the last part of the sig saying Tree b)
the ADT definition is saying tree can be either of those things on each side of the | (you could add more |s to define more things the Tree could have been etc)
Oct 16, 2013 14:53
@JimmyHoffa - yes. In Java this is done with "generics" which is a little bit like currying in the sense that you slap a type parameter on a function and get back a function that works only on that type. Because you've parameterized the type, you can make functions that work on any type, yet be type-safe.
So think about that, and then think about the fact that, the treeMap can be generalized every further to where it doesn't even have to work on a Tree type, but any type that contains a type of a like the tree does:
fmap :: (a -> b) -> f a -> f b
@JimmyHoffa are you talking about duck-typing like Go? If a function requires a foo() method, you can pass anything with a foo() method as an argument?
in this way it parameterizes the Tree itself as f, so it could be a List a, a Tree a, a Window a, anything, all of which fmappable so long as there's a definition for the fmap typeclass
It's similar to duck typing
not exactly the same though because: The function is outside of the type.
@JimmyHoffa - I think Scala calls type classes traits.
So you could take a type someone else defined, define the fmap function for it and then it can be used in all the code that's written to fmap stuff
@GlenPeterson Yes.
The key being that they are defined separate from the type that they work with
This type of generalization which is even further than my initial quite general treeMap above is only possible when you accept implementing the functions outside of the types, so that the functions can generalize across many types
Oct 16, 2013 14:57
@JimmyHoffa and mixed-in without changing the original argument to the function.
So as I said above, putting a function inside a type is type coupling. FP is all about decoupling to the primitive base degree. Some do this using dynamicism, some do this using type systems like HM or in other varied ways, but the key is removing coupling allowing functions to be generalized, and generalized to the purpose that they may be composed arbitrarily and easily
@JimmyHoffa - even poor old Java can do this, but it requires that your function accept an interface. You may have to manually code a wrapper/converter class to implement that interface in a way that makes sense for the wrapped class. Anything you can write a sensible wrapper class for, you can pass to that function.
I can compose filter with take with drop with map with fold, all without caring which type any of them are working on, it might be a tree or a list or a function
@GlenPeterson to an extend interfaces may mimic this, but even then you need to then implement a decorator that implements the interface, it's all very bulky and results in OO code that's hard to maintain
@JimmyHoffa - Yeah, though technically possible in a language like java, the effort of writing all the wrappers would make it completely impractical.
@JimmyHoffa - we could call this The Fallacy of Touring Completeness. Just because it's technically possible to do anything in one Touring complete language, doesn't mean that it's PRACTICAL.
@JimmyHoffa - But Java does not define OOP. It was merely a popular implementation of OOP when OOP was a huge fad. If we consider OOP to mean "allowing user-defined types" then I think we have something we don't have to hate. Something that isn't preventing arbitrary compositions with take, drop, map, and fold.
@GlenH7 It's not really a question I was real interested in answering because converting OO code to FP code is more than a refactor, and more importantly the correct answer wouldn't answer his question, the answer he needs is to the question "How do I go about learning FP?" which isn't an appropriate Q for SE
Oct 16, 2013 15:06
@JimmyHoffa - I mean, they talk about modeling with "verbs" instead of "nouns" in FP and that's great. And most of us have been living in a noun-dominated world for years and there deserves to be a reaction against that. But just as all-nouns is not the answer, I suspect that all verbs is not either. I mean, we all deal with data structures all the time.
@GlenPeterson I prefer to take the common OOP relies on Encapsulation (of data and methods in an object), Inheritance (of data and methods from a parent object), (Subtypal/liskov) Polymorphism, and Abstraction (allowing methods to be specific as you get to lower types in the hierarchy)
@JimmyHoffa - there is nothing inherently bad about structured data. In fact, I would argue that structured data, like side effects, is necessary in order to get work done. There's a benefit to having the compiler inspect your data structure, or functional interfaces, or whatever and alert you when you try to plug a European 240V plug into a US 110V outlet. But I acknowledge that this safety comes with a cost.
@GlenPeterson The HM type system is an implementation of structured data, it's the functions coupled to your types that is part and parcel of OOP that I reject from FP
@JimmyHoffa - So, I've been programming in OOP for years, and my personal experience is that Ihneritance is junk. Even Josh Bloch's item 16 says "favor composition over inheritence."
Oct 16, 2013 15:11
@JimmyHoffa - Encapsulation has helped me out many times. Polymorphism is just what we are talking about. Actually, I would argue that we are just agreeing that Polymorphism is critical and that a broad, yet safe implementation is a huge win.
I agree, but I find it most effective to frame OOP in that way to stop people from just saying "Every language is OOP!", which becomes a useless way of trying to identify distinctions and similes between approaches because that oh-so-common thought ends at "All design approaches are identical!"
@GlenPeterson I'm more argueing against Encapsulation, we agree about Polymorphism yes but encapsulation is counter to the abstraction of FP because FP's abstraction isn't based on subtypal polymorphism due to subtypal inheritance being nowhere to be seen (due to it being crap as you said)
@JimmyHoffa - the root of my current discontent goes back to a comment you made yesterday. The Clojure Camp sets up OOP as a straw man to take the blame for all the evils inherent in the Von Neuman architecture, and virtually all common programming practices. It's not fair, it confuses issues, and it distracts from meaningful discussion of good and bad programming techniques.
@JimmyHoffa - Encapsulation has saved my butt multiple times. Interface is a keyword in Java and other languages, but I'm going to use the word interface with a lower-case i to mean the concept of what one piece of code exposes to another piece of code, whether in the same code base, or across a network, or whatever. interfaces (lower-i) are everywhere.
@GlenPeterson Well don't worry about that from me, I'm not standing up a straw man nor am I a card carrying clojure dev :P I don't blame OOP for all the ills, I just think within the framing of FP's more general more safe and easier to use abstractions, the OO approach loses use. I've written happy C# OOP code day in day out for enough years to not be claiming it a straw man, it put's food on my table and it works just fine for me to get fairly good quality applications written
@JimmyHoffa - With even a few thousand lines of code, interfaces are what allow you to cut apart your code in such a way that unrelated functions are not dependent on each other. This way, when you have to make a change in one area, there are other areas which are not affected at all.
@GlenPeterson and data-based interfaces are great to have bundled with your implementations, but functions being bundled with the implementation are unnecessary, as soon as all the data of your varied implementations is exposed via an itnerface, you can make a single implementation of the necessary functions that works in the general case across all types and therefore having that function encapsulated with the varied data type implementations lacks purpose
Oct 16, 2013 15:20
@JimmyHoffa - In this way, encapsulation is a wonderful thing because it allows you to decouple whole aspects of your application. If you have duck typing, or dynamic types, then you run into stuff like namespace collission, where one data structure uses :name or name() to represent one thing, and another data structure uses the same :name or name() to represent something else. Pass that to a general function and things break.
I said structured data is good, HM type system has structured data like the tree I showed above, it's encapsulating functions into those types I disagree with
@JimmyHoffa - But why does a class or a type have to be more than a namespace to stick functions in?
@JimmyHoffa - even in Clojure, if you declare a function, it goes in the /user namespace or some such thing.
@GlenPeterson Make all classes static and you don't have to, but then are you writing OOP anymore?
@JimmyHoffa - I'm saying that OOP does not prevent that.
@GlenPeterson No, but it's counter to OOP to put all your functions in static classes and all your data in DTOs
Oct 16, 2013 15:23
@JimmyHoffa - It's counter to any kind of popular programming that's more than 5 years old.
2 mins ago, by GlenPeterson
@JimmyHoffa - But why does a class or a type have to be more than a namespace to stick functions in?
answered your own question :P
@JimmyHoffa - I think my answer is that a class or type can be just a namespace. It doesn't need to mutate, or extend, or be particularly data-specific.
@JimmyHoffa - where did I contradict myself?
@GlenPeterson no it doesn't, but if you write your classes like that "It's counter to any kind of popular programming that's more than 5 years old."
@JimmyHoffa - yes, but a lot of my point is that these evils we've been talking about are not OOP evils, They are just old state-of-the-art evils.
@GlenPeterson They can be avoided as we've said, but as you just said the approach to avoiding them is no longer writing OOP, not idiomatic or practical OOP anyway
OOP isn't evil, I write (what I think) is quality software in OOP every day, it tends to be pretty good flexible stuff that's easy to maintain and extend if I do say so myself
Oct 16, 2013 15:29
@JimmyHoffa - So my point is that we have a new way of doing things that doesn't make obsolete only OOP, but most of the things that came before OOP as well. We aren't talking about shortcomings of OOP, rather OOP is simply old, and these are shortcomings of every old paradigm of programming of which OOP happens to be the most popular/recent. Mutable state is the basis of Von Neuman architecture which was invented in 1945.
But to write FP is to choose an abstraction that no longer shows encapsulating data and methods together as worthwhile, and that encapsulation is core to OOP
@JimmyHoffa - It's not the fault of OOP that people in 1970 coming up with OOP assumed that mutability was a good thing.
@GlenPeterson I think you're argueing with these card-carrying clojure folks you talked about :P I really don't think OOP is evil
@JimmyHoffa - Ah, but FP does not prevent encapsulation or interfaces.
@JimmyHoffa Because FP is so strong a tool, you can encapsulate with closures and with functions. Really, that's a strength of FP - that we can make better, yet more flexible abstractions.
@JimmyHoffa - I guess that to me, FP is just a bunch of awesome new techniques that solve problems we didn't even know we had 10 years ago. It makes a lot of OOP stuff less useful, but there are still some ideas that came into focus with OOP that are good. I suppose we are just drawing lines in our definition of OOP slightly differently, but it makes for interesting discussion.
@JimmyHoffa True.
@JimmyHoffa I'm going to have to focus on work for a while, but this has been a very interesting discussion. I'll definitely have to read more about Hindley-Milner and make an effort to learn more Haskell, at least enough to understand Peyton-Jones Monad paper.
@GlenPeterson Same, carry on. Besides I think we've sufficiently assaulted the chat room heh
 
Conversation ended Oct 16, 2013 at 15:39.