Fork me on GitHub
#clojure-spec
<
2017-06-19
>
flyboarder01:06:54

@gfredericks thanks, I guess thats the difference between runtime specs for cljs

gfredericks01:06:21

@flyboarder the same applies to clj-jvm

matan06:06:36

@alexmiller @seancorfield what's wrong with encapsulation, from the colujarians' world view? 🙂

matan06:06:48

I don't recall a very convincing blog post, or have just forgotten if I saw one

matan06:06:21

Oops should have moved it to #off-topic

matan06:06:17

Anyway I am very happy about spec, it is really a "missing piece" for robust programs that teams can collaborate on

Alex Miller (Clojure team)12:06:16

@matan in OO (particularly thinking of Java / C++ here), encapsulation is used to hide or protect the data inside an object and access it via methods. Because this data is mutable, the accessor/mutator methods are also a place where you can apply a locking strategy to protect that mutable data in multi-threaded usage.

Alex Miller (Clojure team)12:06:23

Clojure turns this inside out and says, data is actually the most important thing here - make it visible, introspectable, and directly manipulable via a generic data interface, rather than via a custom set of API methods that is different for every class.

mobileink19:06:20

alexmiller: #off-topic an alternative perspective, just for fun: "immutable datum" is just another way of saying "pure function". we could discard the notion of "data" altogether.

Alex Miller (Clojure team)12:06:24

Immutable data structures allow you to do this while also being automatically thread-safe and avoiding the need for locking around access and manipulation of mutable data completely.

gfredericks12:06:12

even more than thread-safety, you get independence of usage -- you can pass the same object to different pieces of code and not worry about what things they will each "change" that might affect the other which may or may not be what alex's last sentence meant

matan11:06:01

gfredericks: sorry for being late to return to the party 😅 I am not sure why I would not worry about different pieces collaborating on the raw data. Or how this is different than the claim of concurrency/thread-safety.

gfredericks11:06:09

they're not collaborating, they're doing completely independent things

leonoel12:06:55

@alexmiller to make data explicit and visible is undoubtedly a good thing, but there is definitely situations where encapsulation is valuable https://github.com/clojure/clojure/blob/clojure-1.9.0-alpha14/src/clj/clojure/core.clj#L4939

leonoel12:06:08

core.async channels and go blocks are another good example of encapsulation

Alex Miller (Clojure team)12:06:17

Go blocks are about process, not data. Channels are about conveyance of values, not encapsulation

leonoel12:06:36

sure, but they both have opaque internal state

leonoel12:06:18

which doesn't make them bad primitives, btw

leonoel12:06:50

I get your point, but "encapsulation is bad" goes a bit too far imo

Alex Miller (Clojure team)12:06:55

Agreed, but I didn't say that

Alex Miller (Clojure team)12:06:41

Most encapsulation in OO is incidental, not useful

gfredericks12:06:53

this is not quite the same topic but it just occurred to me that one of my biggest frustrations with legacy OO codebases that I haven't heard articulated before is that the classes I encounter have unclear lifecycles

gfredericks12:06:43

the thing I want to understand about a class to help me understand the whole codebase is how/why the objects get instantiated, what you do with them while they're alive, how they get discarded, how that relates to the lifecycle of the program as a whole; and I've never seen an OO codebase where that's remotely clear

gfredericks12:06:37

perhaps there's a similar question about how functions are used in a functional codebase, but it seems like less crucial of a question for some reason

Alex Miller (Clojure team)12:06:23

“lifecycle” implies some degree of statefulness to me. mutable state requires coordination. all of that is often a mess in OO.

Alex Miller (Clojure team)12:06:14

although I’d say that aspect is a distant second problem for me after the notion of not having a generic data interface and/or clear equality semantics in OO

carocad16:06:08

alexmiller: that is an interesting thought. I am wondering, is there a consensus about “this is not generic enough”. Currently I am working on a program were I need to squeeze every inch of performance that I can get so I ended up defining some custom interfaces to access the data. Nevertheless this puts the clear equality semantics and generic data interface a bit to the limit since the interface is no longer Clojure-like but rather case-specific.

Alex Miller (Clojure team)19:06:51

I have no problem with breaking every rule in the book in very narrow areas where you are seeking the ultimate performance :) hopefully that is about 0.1% of the code

carocad20:06:15

Well that depends on how you define 0.1% of the code. The loc that use those custom interfaces are very short but the ones that consume it are probably very long and very different. Which is what got me thinking. I think it is a similar situation to what Clojure does i.e defining algorithms and interfaces in java yet using them in Clojure.

gfredericks12:06:06

the "no generic data interface" complaint also applies to type-oriented functional programming (haskell etc.), right?

Alex Miller (Clojure team)12:06:26

I haven’t done enough of it to say

gfredericks12:06:25

that feels like the biggest difference to me between clojure and most of the rest of FP, even more than static vs dynamic type system

gfredericks12:06:51

though I'm sure the static vs dynamic dimension is highly correlated with generic vs typey

spieden18:06:09

yeah not having equality, robust hashing and string representations built into your data structures is terrible

gfredericks18:06:19

I had a giant dump of ruby data the other day and would have appreciated being able to read it into a repl and analyze it, but I just had to decide to not want to do that

mobileink19:06:49

gfredericks: that must'v hurt like hell.

gfredericks19:06:45

so much #<...>

mobileink19:06:57

gfredericks: i hate sharps in my dumps.

spieden18:06:38

one of my complaints with clojure is actually that the default string representation isn’t EDN — this decision confuses me. e.g.

(println {:foo "bar"})
{:foo bar}
=> nil

spieden18:06:08

i use prn-str for everything, so it’s not a big deal

spieden18:06:23

i guess not all clojure data can be represented as EDN because of nested Java objects, but why not quote “foo” above?

gfredericks18:06:54

because then (println "foo") would be surprising

gfredericks18:06:05

you'd need some other mechanism for printing a raw string

spieden18:06:57

ah yeah, that makes sense

spieden18:06:12

i guess you could special case strings inside of collections

gfredericks18:06:06

that would bother me even more

gfredericks18:06:58

but that might be a personality thing; some people like things that are less complicated to describe, others like things that are more likely to do what you wanted

spieden18:06:34

well said. i lean towards the former too

gfredericks18:06:06

ironically, now that I think about it, I feel like gripes about clojure are pretty evenly split between people wanting the former and getting the latter, and vice versa

spieden18:06:23

a good knife’s edge to balance on =)

gfredericks18:06:37

I suppose there are also gripes about situations where neither ideal is achieved

shaun-mahood20:06:57

@alexmiller: Is there a place on the http://clojure.org site that would make sense for compiling links to blog posts, videos, and other external resources related to spec? There's a bunch of good ones on the Cognitect blog and elsewhere that I wouldn't know how to find if I were looking at it for the first time.

Alex Miller (Clojure team)21:06:04

The community/resources page is one place but may not be best for everything

potetm21:06:23

@spieden Just to make sure it's said: pr does exactly what you want.

potetm21:06:01

The docs actually say: > By default, pr and prn print in a way that objects can be read by the reader

Alex Miller (Clojure team)21:06:25

@shaun-mahood give me examples and I can help find answers

shaun-mahood22:06:06

I just noticed your previous reply - the main motivation for my question was realizing that if I only look at http://clojure.org as it stands right now, none of the really interesting or exciting use cases jump out at me. Might not be a goal though, so I didn't want to put any work into a PR without figuring out what kind of thing might be useful for others.

naomarik22:06:06

i could appreciate such a compilation

Alex Miller (Clojure team)05:06:06

@shaun-mahood broadly, I think it’s hard to give a list of blog entries the right context to be useful and survive well over time. It just doesn’t make sense to try to track every spec blog (most of which are now out of date). What’s useful on the site is curated reference or tutorial content that is kept up to date. So I guess largely, I would say these should not be added to http://clojure.org. One thing that I have been (very slowly) working on is a reference page for spec which I think is a good complement in between the rationale, the guide, and the api docs.

Alex Miller (Clojure team)05:06:03

and the spec workshop notes are not intended to be public - they are training materials copyright Cognitect and represent probably 100 hours of work over the last year.

shaun-mahood05:06:51

That sounds reasonable to me. I love the idea of a reference page - I'm still trying to come to grips with the boundaries of the new clojure and clojurescript site.

shaun-mahood05:06:15

I hope the workshop notes at least made the book easier to write.

shaun-mahood05:06:12

It was definitely worthwhile to take at last years Conj, I would consider taking it again to pick up the new stuff and the bits I missed.