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: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.