Journal 2019.11 - spec/select, clj jiras, tools.deps


I spent most of the week on spec/select and committed the first version of it. The idea with s/select is to separate the set of attributes allowed in a map from which ones are required in a given context - see Maybe Not. In the talk, Rich uses s/schema to declare the keyset but that is still in flux, so you can currently use either an s/keys spec or a vector of attrs to declare the keyset.

(require '[clojure.spec-alpha2 :as s] 
         '[clojure.spec-alpha2.gen :as gen])

(s/def ::street string?)
(s/def ::city string?)
(s/def ::state string?) ;; for demo
(s/def ::zip int?)      ;; for demo
(s/def ::addr (s/keys :opt [::street ::city ::state ::zip]))

(s/def ::id int?)
(s/def ::first string?)
(s/def ::last string?)
(s/def ::user (s/keys :opt [::id ::first ::last ::addr]))

;; (s/select keyset selection)
;; The selection pattern is a vector of either keywords for 
;; required attrs or maps of optional attrs to a selection pattern
;; to use in a submap.
(s/valid? (s/select ::user [::id ::addr {::addr [::zip]}]) 
          {::id 100 ::addr {::zip 63011}})
;;=> true

;; And it gens, using all the optional sub-parts, but ensures all
;; the required selected paths
(gen/sample (s/gen (s/select ::user [::id ::addr {::addr [::zip]}])))
;;=> (#:user{:last "", :id 0, :addr #:user{:city "", :zip -1}}
;;    #:user{:last "", :id 0, :addr #:user{:zip 0}}
;;    #:user{:first "ie", :id -2, :addr #:user{:city "", :zip -1}}
;;    #:user{:last "uS", :id -1, :addr #:user{:city "9G2", :zip -4}}
;;    #:user{:id -2, :addr #:user{:zip -2}}
;;    #:user{:last "i0T97", :first "", :id -3, 
;;           :addr #:user{:street "88", :city "joOc", :zip 1}}
;;    ...)

You can reuse the same keyset but select different paths (and get different gen and conform):

    (s/select ::user [::first ::last ::addr
                      {::addr [::street ::city ::state ::zip]}])))
;;=> (#:user{:id -1, :first "", :last "",
;;           :addr #:user{:city "", :street "", :state "", :zip -1}}
;;    #:user{:id 0, :first "", :last "",
;;           :addr #:user{:city "", :street "C", :state "x", :zip 0}}
;;    #:user{:first "vU", :last "",
;;           :addr #:user{:city "", :street "0", :state "d", :zip 1}}
;;    ... )

select can also take a vector of possible keys (as a keyspec):

(gen/sample (s/gen (s/select [::first ::last] [])))
;;=> (#:user{:last ""}
;;    #:user{:last "", :first "J"}
;;    {}
;;    #:user{:first "p"}
;;    #:user{:first "a9", :last "0"} ...)

Note that this spec has no required keys (the second vector), so may be empty, or have :first, :last, or both.

And the vector keyspec can provide inline specs for unqualified keys:

(gen/sample (s/gen (s/select [{:a int? :b string?}] [])))
;;=> ({} {:a -1} {:a 1, :b "f"} {:a 1, :b "5j9"} ...)

THIS SYNTAX AND MANY DETAILS IS ALL A WORK IN PROGRESS. It will change, don’t get stuck on it.

Clojure jiras

Stu screened the two jiras I’ve discussed in prior journals, CLJ-2484 (the Java performance regression when loading user.clj) and CLJ-2463 (improving error printing for the clojure.main runner). Rich will look at them next. Still moving towards a 1.10.1 RC with these.


A number of people installed and tested clj on Windows this week. Some known issues to work through and seems to be a lot of ways people like to install things. Try it if you haven’t!

I spent some time this week on TDEPS-74 (and related TDEPS-106) for fixing issues around using relative paths in local deps, and I committed some changes for that. Also going to look at the proxy support ticket TDEPS-20 and get all this stuff released.

It also came to my attention that the newest versions of jgit have greatly expanded support for ssh keys and other things via Apache MINA which would potentially resolve several issues we’ve seen in ssh git deps. Hoping to take a look at that soon.

Other stuff I enjoyed this week…

This time of year, my heart is in one place - the SXSW music festival in Austin. My parents lived there for about 15 years and I started going to SXSW in 1996. I went almost every year for a number of years and last attended in 2007 (and brought my 1 and 2 year olds along at the time!). I know Austin has changed a lot in the decade since, and SXSW too I have no doubt, but I’m going to choose to believe that the spirit of serendipity and love of music continues to thrive there.

Literally the first music I saw at the first SXSW I went to was an Iggy Pop show, on a stage in the middle of 6th St. Amazing. Back when I was attending regularly, one of my favorite venues was the Steamboat (long gone) where I discovered local Austin bands I loved for years, like Sister 7 (nee Little Sister), Vallejo, and Pushmonkey. I spent many magical sxsw nights there with my closest friends seeing great shows. I’ll be throwing back a Shiner Bock this weekend to these and dozens more memories of those times.

Here’s a good video of Vallejo doing House at the Steamboat in 1996. I’m pretty sure when we saw them in 1996 at sxsw they were at the Ritz (name changed many times since then, not sure what it is now). Never in my life have I seen a band hit the stage with so much energy. It was like walking into a tornado. Instantly hooked. I saw them more times than I could count - every SXSW but also many other times in Austin and other cities. Me and a good buddy saw them in Cincinnati once on a frigid winter night and we were literally the only people in the place, but they did an incredible gig anyways.

Written on March 16, 2019