Fork me on GitHub
#clojure-spec
<
2017-06-18
>
flyboarder02:06:31

How can I use a spec on a macro to test for a cljs custom type?

gfredericks02:06:32

probably rewrite as a macro + function and put the spec on the function

gfredericks02:06:39

macros can't recognize runtime types

matan02:06:53

@weavejester thanks, so which parts of clojure.spec are ignored when code runs uninstrumented, and which parts always execute?

weavejester02:06:53

@matan All parts are ignored. If you write a spec for a function, it doesn’t affect how the function runs unless you instrument it.

matan03:06:45

mmmm now it all makes sense. thanks a lot @weavejester 🙂

matan03:06:15

nice stuff, spec, IMO should have been there from the beginning of clojure, as a way of taking/extending the good parts of OO rather than dismissing OO benefits so dichotomously

Alex Miller (Clojure team)04:06:01

I think Clojure has always embraced some parts of OO (like interfaces and polymorphism) while letting some parts go (encapsulation, concrete inheritance)

seancorfield04:06:25

@matan I'm curious: how do you think spec relates to the "good parts of OO"?

seancorfield04:06:56

(and I guess that would also prompt me to ask "What do you think the good parts of OO are?" -- and, full disclosure, I was on the ANSI C++ Standards Committee from '92 to '99, and got started with Java in '97, so with that background I'm often very interested when I hear folks talk on this topic)

matan06:06:11

I think the good part, as it relates to what spec is, is that structure is kept validated (in OO, only in terms of types and composite types, which is what most objects in a program are) at most points. This helps 50% of the programmer population keeping programs in check, although, recently, unit-tests have culturally evolved into another aid in that regard.

matan06:06:55

@U04V70XH6 obviously my thoughts aren't that interesting, I've not been on any committee.

seancorfield22:06:56

The problem is that with Java, and several other OO languages, you have no way to separate type and structure — they are conflated. You can’t talk about data structures without giving them class/type names and your only form of “validation” really is the type system. It’s both “not enough” and “too much”. So I don’t find that to be a good part of OO — I find it to be a failing. The same with encapsulation: it makes it harder to treat data generically and so you end up with a stack of design patterns to workaround the restrictions of the OO type system — and I’ve just gradually found the downsides outweigh the benefits. Mind you, you’re right about the “50% of the programmer population”: Java is very effective at allowing large numbers of average developers to work together to build large, complex systems. Java makes developers fungible… But I don’t think developers should be fungible 🙂

matan10:06:34

I concur on all points made. Just not sure how encapsulation makes it hard to generically treat data

matan10:06:19

It might seem valid to encapsulate, especially when delivering a library (to make the codebase have a restricted API facade or making it explicit what are the internals of a module vs how to use it)

matan10:06:41

But as said, I probably need help seeing the negative implications. I am sincerely curious about them

seancorfield16:06:45

If you encapsulate your data in a specific type, then you need a function on that specific type to manipulate it. If you want to use a generic function, you have to use the underlying implementation data, “breaking” encapsulation, and then put all the data back afterward. In other words, in Java, if you have an object that contains an array of other data, you can’t use generic array functions without exposing the array directly, i.e., unencapsulating it. Clojure’s approach is that the “API” is just data — immutable data — so if the implementation is a vector (array), then you can use any generic sequence function on it.

richiardiandrea20:06:26

Newbie question, why does s/or have keyword branches for predicates and s/and does not? I have never noticed that until now 😄 I was kind of assuming the same API but go burned there.

gfredericks20:06:38

my guess is because it's useful for s/or to know which branch matched

gfredericks20:06:07

and not useful for s/and, since you already know that all of them matched (though I suppose you could argue it would be useful to know which one didn't match in the case of an error

richiardiandrea20:06:54

Yep that is true, it would be great to know which one didn't and also to have uniformity in the API I guess

gfredericks20:06:06

the difference is that one is used for conforming and the other isn't

gfredericks20:06:28

whether that's a good reason for the API to be different is a different question