Fork me on GitHub
#clojure
<
2017-11-10
>
qqq03:11:28

is there an example of clojure.spec-ing either SVG or HTML so if my 'hiccup data' passes the spec, it's valid HTML/SVG ?

qqq07:11:37

in standard usage of spec, when ::foo shows up in different maps (of the same namespace), is it expected that the value associated with ::foo will always be of the same 'shape' ?

joost-diepenmaat09:11:22

in spec the mapping of a qualified keyword to a spec (shape) is global by design, so yes.

joost-diepenmaat09:11:12

though you can make the spec match a set of pretty much arbitrary shapes if you’re set on doing that.

the-kenny09:11:31

qqq: Well the value of ::foo must match whatever the spec behind ::foo says. You can use spec/or or similar for disjunction.

the-kenny09:11:52

qqq: as for a hiccup "spec", I used http://p.tarn-vedra.de/hiccup-spec.html in the past. This also has the benefit of conforming to a nice tree that can be converted to html by a simple tree-walk. Note that :tag is just keyword?, you can extend htis and :attrs with better specs describing the set of allowed tags / attributes.

tomc14:11:45

Question about type hinting: I have code like: (def ms-per-second 1000) (def ms-per-minute (* ms-per-second 60)) - I get a boxed math warning w/ that second def unless I use (def ms-per-minute (* ^long ms-per-second 60)). I'd like to type hint ms-per-second once where it's defined to avoid needing to type hint it everywhere it's used. Is that possible?

bronsa14:11:52

however if you want to avoid boxing, you should probably use ^:const too

tomc14:11:51

Could you please show me what that syntax looks like? I haven't been able to get any placement of the ^long hint to work. I get this error: java.lang.IllegalArgumentException: Unable to resolve classname: clojure.core$long@5aadb195

bronsa14:11:35

in pseudo syntax, what's happening is w/o type hint: Numbers.multiply (Long(60), (Long)ms-per-second.get()), w/ type hint: Numbers.multiply((long) 60, ms-per-second.get().longValue()), w/ const Numbers.multiply((long) 60, (long) 1000))

bronsa14:11:52

just (def ^{:const true :tag 'long} ms-per-second 1000)

bronsa14:11:09

or (def ^:const ^long ms-per-second 1000)

bronsa14:11:32

the long tag is actually useless with const as the compiler will be able to infer it after inlining

tomc14:11:02

Thank you very much

nathanmarz14:11:12

@abdullahibra that use case is very easy to handle with specter: (transform [ALL (srange 0 2)] clojure.string/reverse ["hello" "world"])

nathanmarz14:11:30

a great example of using composition to avoid having to reinvent the wheel (in this case, string reversal)

rickmoynihan15:11:59

can you type hint the return of a protocol function signature?

rickmoynihan15:11:17

or do you have to do it at the call site?

bronsa15:11:56

(defprotocol P (f ^MyType [..]))

rickmoynihan15:11:29

don’t know why I didn’t just try it lol

amann15:11:11

Is there a proper channel for asking 1.9 questions? #clojure-spec ?

bronsa17:11:37

if they're about spec ask there, otherwise here is fine

qqq15:11:45

is there anything special about `unq in

(s/def :unq/person
  (s/keys :req-un [::first-name ::last-name ::email]
          :opt-un [::phone]))

or is this literally the :person keyword in the unq namespace ?

taylor15:11:56

:unq is the namespace part of the :unq/person keyword

taylor15:11:26

there’s nothing really special about it, it could be anything

rickmoynihan16:11:52

@U3JURM9B6 the single : syntax doesn’t presuppose any loading, so there’s no guarantee that unq maps to a namespace at all. :: will implicitly be a real namespace, as it will either be the current namespace or ::alias/foo where alias will have to have been require :as’d.

qqq19:11:13

@U06HHF230 @U3DAE8HMG: makes sense; thanks!

triss16:11:22

hey all. I need to set an Object’s field but I don’t know it’s name until runtime.

triss16:11:21

I’d like to do do: (set! (.-field object) value) but I have .-field as a String.

Garrett Hopper17:11:47

Anyone know of a way to use ring or bidi to create a url with certain query params from a map? Doing string concatenation feels wrong in this case. I'm trying to general an oauth redirect link.

triss17:11:54

Thanks @hiredman I was beginning to suspect I’d need to fall back on Java’s reflection.

hiredman17:11:09

definitely with bidi you should be using one of its built in functions for doing that

pelletier17:11:27

Is there a recommended way to use protobuf with clojure? The first few projects that come up after a google search don't seem to be actively maintained. I'm specifically looking for something that plays nice with repl dev

qqq19:11:59

(s/def :event/type keyword?) 
(s/def :event/timestamp int?) 
(s/def :search/url string?) 
(s/def :error/message string?) 
(s/def :error/code int?)

(defmulti event-type :event/type)

(defmethod event-type :event/search [_]
  (s/keys :req [:event/type :event/timestamp :search/url])) 

(defmethod event-type :event/error [_]
  (s/keys :req [:event/type :event/timestamp :error/message :error/code]))

(s/def :event/event (s/multi-spec event-type :event/type))

(s/explain :event/event
          {:event/type :event/search
           :event/timestamp 123456789
           :search/url ""})
can someone please explain to me why this is failing? I don't understand the error of: val: {:event/type :event/search, :event/timestamp 123456789, :search/url ""} fails spec: :event/event at: [nil] predicate: event-type, no method

taylor19:11:18

you should join the #clojure-spec channel too

qqq19:11:25

ah, it works now: the above code works fine; problem was, I initially defined the defmulti wrong, and then upon correction, it was not being redefined until I called a remove-ns

amann20:11:06

So in working on an application which interacts with PSQL, I’ve setup some standard tooling which pulls dates out of the records and transforms them from sql times to jodatimes (because clj-time has this functionality). However, in working with 1.9, the inst? operator expects a java.util.date. I’m curious if there’s been any public conversation around what timestamps clj should be using going forward, especially now considering there’s java.time in jdk 8, etc.

rauh20:11:24

@amann inst? works just fine for java.time.Instant

amann20:11:41

Good point. My above question was from a standpoint of what should I expect to be using in 6 months, etc. Thanks for pointing this out!

seancorfield20:11:19

@amann I think at this point I would switch to Java Time. I'm one of the maintainers of clj-time and we've been wrestling for a long time with the question of whether to migrate/produce a new version of clj-time on top of Java Time. The feeling is that we can't realistically do it in a compatible way and therefore we'd need a new artifact name (rather than change the API and/or semantics and violate the spirit of Rich's Spec-ulation talk) -- so it would be a "new" library altogether (similar to clj-time). But none of us have the time(!) or inclination for that, so I'm switching to clojure.java-time which is based on Java Time and that's what I'm recommending folks use.

seancorfield20:11:24

I've introduced clojure.java-time at work and we're slowly migrating off our current combination of date-clj (for java.util.Date stuff) and clj-time (for Joda Time stuff).

amann20:11:58

This is great information. Thanks Sean. The debates we’ve had at work have been mostly the same, but having some indication from the maintainer of clj-time itself definitely helps.

seancorfield20:11:09

clj-time will continue to be maintained, but it's much less useful now we have Java Time. I've been very happy with clojure.java-time so far in production code.

localghost20:11:55

i'm trying to use spyscope from https://github.com/dgrnbrg/spyscope. Added the dependency to my project.clj but when I try and add [require [spyscope.core as spy] in my namespace, repl refuses to start. The error is:

Exception in thread "main" clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec:
In: [2] val: ((require [clojure.pprint :as pp] [clojure.string :as str] [clj-time.core :as time] [clj-time.format :as fmt])) fails spec: :clojure.core.specs.alpha/ns-form at: [:args] predicate: (cat :attr-map (? map?) :clauses :clojure.core.specs.alpha/ns-clauses),  Extra input
 #:clojure.spec.alpha{:problems [{:path [:args], :reason "Extra input", :pred (clojure.spec.alpha/cat :attr-map (clojure.spec.alpha/? clojure.core/map?) :clauses :clojure.core.specs.alpha/ns-clauses), :val ((require [clojure.pprint :as pp] [clojure.string :as str] [clj-time.core :as time] [clj-time.format :as fmt])), :via [:clojure.core.specs.alpha/ns-form], :in [2]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x3c7c886c "clojure.spec.alpha$regex_spec_impl$reify__2436@3c7c886c"], :value (spyscope.core "This co" (require [clojure.pprint :as pp] [clojure.string :as str] [clj-time.core :as time] [clj-time.format :as fmt])), :args (spyscope.core "This co" (require [clojure.pprint :as pp] [clojure.string :as str] [clj-time.core :as time] [clj-time.format :as fmt]))}, compiling:(spyscope/core.clj:1:1)
any clues? (oh, and I'm using clojure 1.9.0-RC1)

seancorfield20:11:40

@clojurian Which version of spyscope did you use?

seancorfield20:11:11

0.1.6 is the latest.

seancorfield20:11:39

Looks like 0.1.6 includes the fix for the issue you saw above -- I see commits fixing the ns forms.

seancorfield20:11:39

Although it looks like you may run into this https://github.com/dgrnbrg/spyscope/issues/26 until the maintainer releases 0.1.7.

seancorfield20:11:32

(that starts out as the bug you encountered @clojurian but notes there's a 0.1.6 release but that also has a blocking bug and the library needs a 0.1.7 release made, since the fix is already merged)

lvh23:11:15

Hi; I’d like to experiment with program obfuscation and one part I’d like to do via term rewriting — does anyone have a favorite term rewriting library? It seems expresso and stratege and termito are the common ones; expresso seems to be focused on symbolic mathematical expressions, but I don’t think that really matters