Fork me on GitHub
#clojure-spec
<
2017-02-28
>
luxbock03:02:55

when writing variations of an existing spec, such as "order" -> "open order", "closed order", should there be a convention for how to name the namespace part of a spec

luxbock03:02:11

right now I tend to define order as ::order and then for the variations I add the variation name after a dot to the end of the namespace, so :my.ns.closed/order

luxbock03:02:08

I do this without creating a new namespace, i.e. I just write the full keyword out for the variations

dergutemoritz09:02:14

@luxbock Another option would be ::order.closed. That way you can still use the real namespace and thus the auto resolving shortcut syntax.

luxbock09:02:18

@dergutemoritz yeah but then I can't use use it as an unqualified key in a map

luxbock09:02:04

my use case is basically where there are a series of transformations on this value in a map, and I want to capture some properties about the transformations having done what they were supposed to

dergutemoritz09:02:08

Oh okay, if you are specing legacy maps, I wouldn't know what's the best way to go about that

luxbock09:02:21

I think using unqualified keywords is the only way to do this type of thing, where I want to capture changes in the value between functions

luxbock09:02:47

if I were to use a qualified keyword for the map then the spec has to be static

dergutemoritz09:02:19

Note that you can also create and alias a namespace from within another namespace like this: (create-ns 'my.ns.closed) (alias 'closed 'my.ns.closed) which then allows you to require the my.ns.closed namespace from other namespaces and use it in the current namespace via ::closed/

luxbock09:02:45

hmm yeah that could be another good option

dergutemoritz09:02:16

Re capturing changes in the value between functions: One central idea of spec is to not use the same key for different kinds of values but to attach a global meaning to a key - so different things should use different keys

dergutemoritz09:02:31

Maybe you can do that, too

dergutemoritz09:02:04

In other words: what's keeping you from using different keys?

luxbock09:02:02

yeah I suppose that might be a better a better practice

dergutemoritz09:02:14

Worth a try at least šŸ™‚

luxbock09:02:58

I was thinking that since all of the values that are changed only live during one pass from a function to another, the use of unqualified keys would capture this transient nature of theirs

dergutemoritz09:02:28

Sounds like you have a deep chain of calls which pass a map through each other, each modifying that map? From a maintenance perspective, I think using different keys makes sense here, too. Imagine reading that code for the first time, you'd see the same keys being used in a dozen functions but in each they may have very different values, depending on from where they're called.

luxbock09:02:10

yeah I think you are right

dergutemoritz09:02:39

Well, it might be easier with un specs but still unnecessarily context sensitive I'd think

ikitommi09:02:40

@viebel have also looked for easy way to define more local key specs. Did a simple helper on top of spec to define deeply nested map/vector/set specs. But currently pollutes the spec registry with generated keys: https://github.com/metosin/spec-tools#simple-collection-specs. There could be a custom keys in spec-tools supporting local keys..

Alex Miller (Clojure team)15:02:01

@dergutemoritz re the earlier suggestion of ::order.closed - per https://clojure.org/reference/reader#_literals, keywords should not contain . in the name. This is not enforced anywhere, but I think you should steer away from it in general.

dergutemoritz15:02:05

@alexmiller Ah, thanks for the hint! Yeah it's not enforced anywhere in my experience, I'd rather not rely too heavily on unspecified behavior so the headsup is definitely welcome

vikeri17:02:09

I know spec does not check ā€œunspecced" keywords for a number of reasons. But sometimes it would be very handy to check big nested map (eg. re-frame app-db) and get the keys that are not specced so that I can add specs for them. Is there any way of enumerating the registered specs?

bbloom17:02:51

@vikeri instrument etc does this - so you can probably look at how those work

Alex Miller (Clojure team)19:02:53

@vikeri you can call s/get-spec to check whether a spec is in the registry

mikerod19:02:18

Many Clojure features are based on some past research/books/papers. Is there a list of these for Clojure spec?

mikerod19:02:13

quoted: > clojure.spec takes "Matt Might et. al. Parsing with Derivatives" and really, really runs with it.

mikerod19:02:38

RDF and Racket contracts

mikerod19:02:56

Iā€™ve seen those too, but I wasnā€™t sure on which aspects of those and if how it related to the parsing stuff

Alex Miller (Clojure team)19:02:08

the parsing stuff is specific to the regex op specs

mikerod19:02:11

but thanks for reminding me that those were at the bottom of the about spec page - I forgot

Alex Miller (Clojure team)19:02:39

contracts are at a high level similar to what spec is doing

Alex Miller (Clojure team)19:02:30

the rdf reference is really about building growable information systems (Datomic steals liberally from this as well)

Alex Miller (Clojure team)19:02:42

Rich is being somewhat modest imo in that heā€™s been thinking about some of the parts for as long as heā€™s been working on Clojure (like maps as a set of attributes)

mikerod19:02:46

Thanks for that added insight Alex.

mikerod19:02:09

> the parsing stuff is specific to the regex op specs Does this mean that "Matt Might et. al. Parsing with Derivativesā€ is not really relevant to an understanding?

Alex Miller (Clojure team)19:02:31

only about understanding that very specific part of the code

mikerod19:02:38

I do intend to dig into the parsing of spec some out of interest in what it is doing. I was just wondering if reading that paper would have any relationship. Iā€™ve read a bit of it so far.

mikerod19:02:09

I know spec has more to it than parsing of course. I can understand how the RDF is about the growable systems and Racket contracts as a similar lang feature.

Alex Miller (Clojure team)19:02:09

thereā€™s very little ā€œparsingā€ - the only part doing anything youā€™d call parsing is the regex stuff

Alex Miller (Clojure team)19:02:26

everything in spec works on Clojure data, not strings

mikerod19:02:39

Yeah, I have seen that much.

Alex Miller (Clojure team)19:02:35

we looked at a lot of other existing libs in the research for this (I built a couple versions prior to Richā€™s work that were thrown away)

Alex Miller (Clojure team)19:02:01

of those, I would point most at Christopheā€™s seqexp lib, which is really quite lovely

Alex Miller (Clojure team)19:02:25

and Ghadiā€™s pex is similarly interesting https://github.com/ghadishayban/pex

Alex Miller (Clojure team)19:02:06

spec does not take either of those approaches, but they were helpful as points in the design space

Alex Miller (Clojure team)19:02:51

Iā€™d say the ideas of a) starting from predicates and b) automatically generative from the start are also things that Rich insisted on from the very first conversation

mikerod19:02:26

Thanks for all the details. Thatā€™s good background info. Itā€™s always good to get to hear some of the thought process behind these sorts of things to understand the design process some.

ghadi19:02:01

If I were to rewrite pex, I'd globally register match patterns like spec does.

bbloom19:02:27

@ghadi still happy with the bytecode interpreter approach?

bbloom19:02:41

iā€™ve tried to do some parsing with derivatives and have had pretty poor luck

bbloom19:02:57

i find the derivative of a grammar to make sense, but the derivative of a parser makes my brain hurt

ghadi19:02:53

bytecode interpreter is super fast and I love it

ghadi19:02:05

but -- I didn't implement a stack overflow guard

bbloom19:02:12

ĀÆ\(惄)/ĀÆ

ghadi19:02:35

I am not 100% sold on registers vs locals though. @cgrand did registers in segexp

bbloom19:02:04

am i reading that right? only two registers?

cgrand19:02:48

No N registers of two slots

bbloom19:02:56

what are the slots?

cgrand19:02:30

Each end of a sub match.

bbloom19:02:44

ah - gotcha

bbloom19:02:17

parsing is fun/terrible šŸ™‚

cgrand19:02:35

The goal was to avoid head retention

bbloom19:02:17

like for streaming parsing? assuming you donā€™t have unbounded backtracking in your grammar?

cgrand19:02:50

I use it to query live healthcare data streams.