This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-10
Channels
- # adventofcode (9)
- # bangalore-clj (1)
- # beginners (130)
- # boot (6)
- # cljs-dev (8)
- # cljsjs (12)
- # cljsrn (3)
- # clojure (33)
- # clojure-brasil (3)
- # clojure-korea (4)
- # clojure-russia (150)
- # clojure-sanfrancisco (4)
- # clojure-spec (159)
- # clojure-uk (3)
- # clojurescript (100)
- # code-reviews (9)
- # core-async (1)
- # datascript (3)
- # dirac (58)
- # hoplon (8)
- # jobs-discuss (10)
- # luminus (18)
- # om (2)
- # onyx (14)
- # protorepl (19)
- # re-frame (34)
- # reagent (28)
@bbloom I can't really spec test.check generators meaningfully without parameterized specs
@gfredericks 1) i assume that there’s existing code out there for which that’s true 2) i’d love to hear why and 3) i’m curious if you’d do things differently now to avoid that
@bbloom what's a good generator for the function (defn vector "Returns a generator of vectors of items from g" [g] ...)
?
right now I just have the args as (s/cat :g generator?)
and the ret as generator?
, which doesn't remotely capture the relationship between the two
or even the fact that the return value generates a vector
so there's two aspects to this
well at least now we can join the Go community in complaining that our “type system” doesn’t have generics 🙂
I can't imagine what would be done differently to avoid this
any comment I've seen about higher-order-ish things is usually along the lines of "specs are for data"
a corollary of which I have to imagine is "specs aren't useful for things like generators", but I couldn't defend that and haven't heard it explicitly taken that farb
yeah you can't spec map
completely for the same reason
so I guess you're right that they must have thought about it :)
in theory it could be extended to spec more things, but you’re not going to serialize a generator to edn
you ultimately can't, because of bind
even fmap
I guess
i guess “spec doesn’t cover that use case” is fine - i’m just curious if that’s now & more stuff could be spec’d later with more powerful primitives, or if it’s like “eh, this approach only goes so far & you can spec some other way later if you need to"
like in theory you could reuse specs in another context, which i guess is what Typed Clojure will do: generate types from specs
basically: “hey spec, save me the trouble of looking at this thing and checking to make sure it looks right"
so a parameterized spec is a function that takes a spec and returns a spec
presumably you could make a spec for that function
and test it by generating specs?
this is really hazy
haskell uses =>
to talk about this stuff doesn't it?
oh I guess the parameterization is more basic
listOfThings :: [a]
is already parameterized
so like if you have some type a => b -> c that says you have some function of type b, returning c, and there exists some a… and you can constrain it like: Num a -> b c there exists some a such that a is tagged with the class Num
does that mean anything interesting if a
doesn't appear on the right side of the =>
?
listOfNumberishThings
i believe that the it’s required to be on the right side at least in haskell 87 w/o extensions
hey @bbloom I think I got my lens stuck in a monad transformer can you help.
are those all special?
or fspec
I've wondered if (generator integer?)
could be a thing
presumably it could be implemented with the lower-level machinery
even then you couldn't fully describe gen/vector
this is the "function from specs to specs" idea
however, this gets in to an area where i feel the current tradition of type systems is real bad
uh oh
types are curried in haskell (i think), but still, you don’t actually get a type until you give it all the args
where does that get awkward?
"oh shit, this function has an effect. ooooh well, let’s change the signature of every function everywhere"
if i were designing a type system with generics, i’d make all generic parameters named and optional
so you’d have (List {}) and (List {:element String}) - in the former case, the default for :element would be Any
so "the type system knows about effects" seems like a positive thing, it's just the "and I have to type it in all sorts of unrelated places" that's the bad part, right?
would a more advanced inference system fix that?
if you have some function that has an effect, you just leave the monad as the last parameter & then if you change the monad, that’s fine b/c you’re using curring / point-free to avoid mentioning the monad type as much as possible
the monad is the last constraint mentioned before the =>
? or it's actually a physical argument?
is that a general thing you deal with with monad transformers?
a lot of these problems stem from the fact that they don’t have associative or open structures in their type systems
if you want to combine more than 1 monad without manually creating a custom monad, you can layer them and the order in which you layer them matters b/c the type of a monad stack is essentially a cons list of monad types
the "extensible effects" stuff comes up with a clever way to encode a set without order in to the type
GHC now has some kind of union types with some extension, but at some people they were like sorting types to represent a multi-set or some craziness to achieve “order independence”
okay so static types aren't all good yet.
everybody in the ML/Haskell camp AND the Lisp camps were afraid to take a step back and say “hey, what happens if we have maps and sets” 🙂
what is the current best idea for how to spec a map with (un-namespaced) symbol keys? The best I've figured is to use every to spec map entries, not very satisfying.
@cemerick I don't know of anything besides an opaque function
I haven't investigated how to use the lower-level facilities to build something more first-class
@gfredericks having something equivalent to s/keys (s/syms? :-P) doesn't look hard, but way more work than manually :syms destructuring and conforming each part
I'm more likely to need strings, personally
and bob needs numbers, and poor jane is dealing with maps that have namespaced and un-namespaced keywords with the same name carrying different stuff
make a new system and call it spec2
your convo with @bbloom above is serendipitous. I was really trying to get spec to do way more than it's meant to last night, notwithstanding my cat
problems.
someone should build some sort of adapter to plumatic/schema for fallback needs
teach spec that schemas are specs and teach schema that namespaced keywords are schemas
well, part of my frustration is in wanting to get useful generators out of specs, so, things like schema aren't super useful
schema has generator support too
it's just more wiring to do
insofar as I need to do extra work to get corresponding generators (esp. if schema/spec is a separate thing from the generator), it's not super useful
I mean, beyond doing the work to have a validating/destructuring spec and corresponding generator
I'm not sure what extra work you're thinking of; I think the overhead to get to generators is comparable in the two systems
my recollection was that I ended up bailing and hand-writing my own generators at a certain level of complexity
the big unfortunality is that (every version I've used) has bad errors when there's a missing generator you need to fill in
it just says "Missing leaf generator" or something of that sort and doesn't attempt to tell you which schema caused the problem
but once you build up your stockholm syndrome around that issue then it goes pretty well
@cemerick i too suffer from instantly running in to edge cases and limits when attempting to use new things 🙂
I don't know that I find dark corners any more frequently or quickly than others. Probably just louder than most about it, maybe
@cemerick Re your question above, did you look at s/keys with :req-un ?
@gfredricks for string keys, you can use a leading conformer that converts to keywords as a workaround
Assuming you have an information map with keys that are strings ala json
@alexmiller was the s/keys with :req-un
the same as your other two comments, or about something different?
I didn't know about the leading conformer idea, so that's useful
It was about the original question of maps with unqualified keys
you can do lots of tricks with leading conformers, like for example calling select-keys to narrow the key set you’re validating
yada yada beware of conformers yada yada
@alexmiller unqualified keys are pretty basic, right? chas had been asking about symbols as keys, which I assume is the same approach as strings
oh, right I heard unqualified keys in my head
but you could use a leading conformer for symbol->keys too
I like using strings when talking about javascript in clojure
s/javascript/json/
my rule of thumb is not using keywords that don't appear in the source code anywhere
in the past I've used schemas to describe both the internal clojure-fluent version of data but also the external JSON-flavored version
and I found that terribly useful
spec does not fit that pattern nearly as well as p**matic/schema
I’m curious why you don’t use keywordize at the boundary? I find that approach far more natural.
I essentially do, but I prefer it in a less blind way
to be clear, these are mostly just thoughts. I've only tried this in one codebase, but couldn't figure out how to get a nice API for it. most of my thoughts are here: https://github.com/gfredericks/schema-bijections#rationale
so what I want is something like ↑ that library, but less confusing/verbose, and maybe involving spec if that ends up making sense
I suppose that readme doesn't talk about trying to separate bijections and surjections, which I never figured out how to do
I wish bijections and surjections were first-class concepts
they compose well; surjections are interesting for generators
if I can ever work this into a better library it probably ought to be named jections