Fork me on GitHub
#beginners
<
2017-04-13
>
tbaldridge00:04:37

@didibus the whole "OOP is good at modeling Father/Son/Mother/Daughter" stuff is a promise OOP made, but doesn't really map to reality. '

tbaldridge00:04:32

Not only does such a model neglect time, (I wasn't a father 10 years ago, but I am now), but real relationships are also much more complex than a few interfaces. For example, I'm a father, male, American, software engineer, live in Colorado, etc. Depending on how you slice all of that, your object model is going to get really complex.

tbaldridge00:04:15

Hence Clojure's approach of putting it all in a hash map, that way you are free to chop up your data based on the local domain of a function.

didibus00:04:48

Sure, though that's a little different from what I was trying to convey. In a domain where you need all these dimensions and pivots, I'd agree with you. The important aspect is to distinguish model from language construct. You use a hashmap because it is easier for you to create a relational model with it. Or maybe you'd model it as a graph, using a datastructure that can do that. Querying over these is easier, so you can pivot on the data in the way you want. But if you actually have something that is just a simple set of grouped data, with simple interactions, an object model is a fine choice. Maybe I'm writing a life sim game, and you can't do a whole bunch, you have to choose do I create a father, daughter, etc. And that will just change how they interact. Its fine to just define those as simple objects.

tbaldridge00:04:37

Sure, but even the video game industry ditched OOP about 15 years ago, for this very reason.

tbaldridge00:04:19

and I could counter with "why define a type when a hash map will do". 🙂

didibus00:04:37

I don't disagree, not trying to defend OOP 😛. What I mean is that nothing in Clojure prevents you to model things as objects. But in Java, everything must be modeled with them. The language only gives you tools that lets you implement object models. Clojure gives you whatever you want, while maybe trying to steer you along a simpler path.

noisesmith00:04:38

@didibus it may not be normal, but Lmax disruptor is an example of the contrary - it’s a java library that uses plain data types (for performance reasons)

didibus00:04:18

And I find a lot of Java programmers, they can not separate object modeling from the tools Java has anymore. So they start to associate programming is equal to object modeling. So when you say Clojure doesn't have X tool, they don't understand how you can code anything without it. Now if you say Actors are objects, they get confused again.

didibus00:04:13

Ya, actually I'm always tempted to write Java where everything is a pure static function, and my data is a mix of objects with no methods and data inside data structure 😛

tbaldridge00:04:13

actors are async objects, double the pain, half the fun, lol

didibus00:04:16

I guess I keep saying that, but I doubt there is a formal agreed upon definition of what an object model is. I like to think of it as a technique where you can group data together, and group functions operating over that group of data together with the group of data itself.

didibus00:04:23

But in practice, you rarely need this. Often time, you don't want data grouped together, but free floating data related to one another. Similarly, you rarely have a set of functions that pertain only to one group of data. When you do, its very rare that each functions needs all the data in the group to do its job. If you try to decompose your objects like that, you might end up with a lot of objects that each have one field and maybe no method or one or two methods at most. Suddenly, you wonder, why don't I just have independent data, and a pile of functions that each take one or more of these individual data point instead. The object becomes an unnecessary wrapper. It groups data together that is never required all together, forces methods to limit themselves to one group of data, or it becomes an unnecessary box around plain functions or plain data. That's when you become an FP convert 😛

Drew Verlee02:04:08

At my first job it took me 5 hours to track down a bug where my insert to the db (this was rails) called a before hook that created another object whose after hook created an effect that was causing problems. I was like, “this can’t be it, There has to be a better way” I’m not sure the problem was related to OO, but i wanted to have a better discipline around state changes. Thats why i ended up here 🙂

Drew Verlee02:04:43

Well here in sprit if not employment 😅 Also, i finished another post https://drewverlee.github.io/posts-output/2017-4-12-abstract-factory-pattern/ I promise to not link these all in beginner chat, as their probably off topic.

mbcev02:04:56

Honestly I kind of appreciate them for what it's worth @drewverlee

donaldball02:04:10

I had a similar breaking point, where I realized, after too much time spent trying to reason through a particularly weird state bug, that you simply can’t tell, in a large enough ruby project, what will happen when you call a method on an object without actually doing it, and just hoping you can observe all the side effects

Drew Verlee03:04:39

@mbcev i’m glad to here someone else is enjoying them. I hope they get better, i’m glancing over them and realizing i need an editor.

mvnetbiz06:04:09

Hi, I'm following the luminus "guestbook" tutorial, just beginning with clojure, and I get the error no such var db/get-messages. my db/core.clj has "(conman/bind-connection db "sql/queries.sql")" which is apparently supposed to automatically generate the functions based on that sql file's annotations. is that not correct or up to date?

mvnetbiz07:04:15

Nevermind, figured it out, it was supposed to be the save-message function in home.clj not the db file, and the function declaration was out of order

didibus08:04:08

@drewverlee Read that last one. Not sure this makes sense to me, since in your example you're avoiding the part about building objects. Which is the whole point of abstract factory pattern.

Drew Verlee14:04:16

@didibus This is great! Your right this is more in the spirit of the pattern. I considered doing something like this, but i wanted to see if i could avoid using defrecord, which i felt might be more in the spirit of Clojure. But now im questioning if thats really true. Given what your modeling, i think protocals would be the way to go. I really apperciate this, would you mind if i included it in the blog as another example?

fingertoe15:04:23

So, regular expressions are mighty powerful. Is there a compelling reason to avoid using them? for XML paring for example?

sveri15:04:38

@fingertoe Did you ever try to understand one you did not write your self?

fingertoe15:04:57

I have been playing with the zip-xml stuff.. It works fine — just seems like it would be simpler. I kinda assumed there was a big tradeoff I didn’t know about.

sveri15:04:20

Ok, maybe I have not been clear enough 😄 regex usually are super hard to read and understand and kept in memory while trying to understand what a function, class whatever does. Unless you work with them all day long or you coworkers do so, you will have trouble later on if there is a bug or some support needs to be added. Thats just one disadvantage and there are more.

mbcev15:04:24

My recommendation: http://youtube.com/watch?v=9Q--oX5muxw whenever possible. One of my favorite talks from that year.

fingertoe15:04:05

I had assumed I need scolded for the thought. It’s probably best to delve into the common tools rather than take shortcuts..

sveri15:04:55

@fingertoe its up to you to weight the advantages vs. the disadvantages.

fingertoe16:04:36

@mbcev I will check that out, thanks!

didibus22:04:46

@drewverlee I don't mind at all. You can use the code however you want.

didibus23:04:16

@fingertoe They're normally brittle in that you can easily use them wrong. Especially in the case of escape sequences, like having < appear not within a tag. They're also slower in performance, because they need to backtrack a lot.

mbcev23:04:18

What's a good pattern/model to deal with holding data in memory in a concurrent application without having functions/data mix each other up because they're in the same namespace? What I would typically have done in say Java would be to create my object which has whatever data structures and functions in it and then just toss that object off onto it's own thread to process itself and now I don't have to worry about it doing work on some equally named data structure/variable X as long as X is contained within that object.

mbcev23:04:59

What I intend to do is use a future to send off my processing loop, but will say an atom I defined within that namespace be shared across all such futures?

john23:04:11

I asked this over in #clojurescript but I'm not sure if this is more of a beginners question. This could be pretty simple. I'm trying to use an :advanced build while using webworkers. I have a stub file that calls my main.js file. That worker stub file was using goog.require(... (in :none compilation mode). Is there a way to launch the js file, without goog.require?

noisesmith23:04:44

@mbcev use arg passing - make the process take its data as an argument

noisesmith23:04:52

don’t use namespace level stuff for runtime data