Fork me on GitHub
#clojure
<
2016-06-02
>
danburton00:06:47

Is there a way to specify jsonb operations in honeysql, or something similar? For example, can I represent this query? select * from my_table where json_col @> '{"type": "foo"}'?

danielcompton03:06:04

Is there a way to write a prismatic schema checker that checks if a map is a subset of a schema? Just make every key in the schema optional?

d-t-w04:06:48

hey @danielcompton, something like a custom predicate?

d-t-w04:06:51

(let [acceptable #{:key-1 :key-2}]
  (s/validate (s/pred (fn [m]
                        (not-any? nil? (map acceptable (keys m)))))
              {}))
=> {}
(let [acceptable #{:key-1 :key-2}]
  (s/validate (s/pred (fn [m]
                        (not-any? nil? (map acceptable (keys m)))))
              {:key-1 1}))
=> {:key-1 1}
(let [acceptable #{:key-1 :key-2}]
  (s/validate (s/pred (fn [m]
                        (not-any? nil? (map acceptable (keys m)))))
              {:key-1 1
               :key-2 2}))
=> {:key-1 1, :key-2 2}
(let [acceptable #{:key-1 :key-2}]
  (s/validate (s/pred (fn [m]
                        (not-any? nil? (map acceptable (keys m)))))
              {:key-1 1
               :key-2 2
               :key-3 3}))
ExceptionInfo Value does not match schema: (not (user$eval5812/fn--5813 a-clojure.lang.PersistentArrayMap))  schema.core/validator/fn--2411 (core.clj:151)

d-t-w04:06:41

you'd def that s/pred somewhere and give it a name I guess.

d-t-w04:06:50

(def HasKeys (s/pred (fn [m] (not-any? nil? (map #{:key-1 :key-2} (keys m))))))
=> #'user/HasKeys

(s/validate HasKeys {:key-1 1})
=> {:key-1 1}

(s/validate HasKeys {:key-1 1
                     :key-3 3})
ExceptionInfo Value does not match schema: (not (user/fn--5980 a-clojure.lang.PersistentArrayMap))  schema.core/validator/fn--2411 (core.clj:151)

d-t-w04:06:56

Better, probably a terrible name though.

(def HasKeys (s/pred #(every? #{:key-1 :key-2} (keys %))))

mpenet06:06:06

@danielcompton: I wrote something like this in the past:

mpenet06:06:19

(defn validate-subset
  [schema value]
   (-> (select-keys schema (keys value))
       (s/validate value)))

mpenet06:06:35

since a schema is just a map in that case

danielcompton06:06:29

@d-t-w: thanks, I think @mpenet’s example is what I was after, as I want to validate the vals on the keys too

mpenet06:06:08

btw is it possible to write something equivalent in clj.spec?

martinklepsch07:06:04

bit late to the question but that's exactly what boot excels at/is made for.

genRaiy08:06:40

to answer my own question @yogthos is compiling a catalogue of common clojure error messages so I will add it there https://github.com/yogthos/clojure-error-message-catalog

genRaiy08:06:52

please support the effort!!

bg10:06:30

;;; so doall didn't trigger the exception here, because it's first
;;; level only. OK.
user> (def x (doall {:a {:b (cons 1 (take 10 (lazy-seq (repeat (/ 1 0)))))}}))
#'user/x
;;; Here the exception is also obvious. REPL is evaluating everything.
user> x
ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:158)
;;; What about this? After the first eval, x now doesn't throw an
;;; exception (cached value?). But how is the whole (take... ) form
;;; being replaced by nil?
user> x
{:a {:b (1)}}
user> 

bg10:06:04

Folks, need some tip here to understand the ⬆️ behaviour.

mpenet10:06:05

anyone knows what's the purpose of clojure.lang.ILookupThunk ?

rauh10:06:27

@bg You're right, lazy seq will cache the result after the first exception. The result is nil. And (take 10 nil) is the empty sequence

bg10:06:20

@rauh: can you point me to the source where that exception becomes nil upon evaluation? I couldn’t find the relevant part.

rauh11:06:50

@bg not exactly caught, but you can understand what's going on here which is equivalent construct to your take (which again constructs a lazy-seq and thus a nested lazy seq):

rauh11:06:49

The first run of the outer lazy-seq ONLY constructs the inner lazy seq and thus successfully returns and caches the value. Only printing the value on the repl will result in the full realization and the one time exception

rauh11:06:05

After that the outer lazy-seq is already realized and not evaluated again.

rauh11:06:33

The outer run, never throws and never sees the exception since the inner doesn't get evaluated until later.

fabrao13:06:57

Hello, I have this string :

port                : 8888
load-balance-servers: 1
antispam-force-off  : disable
antispam-cache      : enable
antispam-cache-ttl  : 6000
antispam-cache-mpercent: 2
antispam-license    : Contract
antispam-expiration : Wed Dec 14 2016

antispam-timeout    : 7
avquery-force-off   : disable
avquery-cache       : enable
avquery-cache-ttl   : 1800
avquery-cache-mpercent: 2
avquery-license     : Contract
avquery-expiration  : Wed Dec 14 2016

avquery-timeout     : 7
webfilter-force-off : disable
webfilter-cache     : enable
webfilter-cache-ttl : 6000
webfilter-license   : Contract
webfilter-expiration: Wed Dec 14 2016

webfilter-timeout   : 15
webfilter-sdns-server-ip:
webfilter-sdns-server-port: 53
source-ip           : 0.0.0.0
ddns-server-ip      : 0.0.0.0
ddns-server-port    : 443
How do I get all the *-expritation from all text using re-seq?

fabrao13:06:03

I tried with ( . -expiration\s+ : )\s+( . )\n but returns only the first one

manutter5113:06:12

I would probably try something like use clojure.string/split to break it into a seq of lines, then a combination of filter and re-matches to get just the expiration values

madstap13:06:55

Not actually using re-seq, but that's how I'd do it. I generally find using the clojure.string fns together with regex more readable than just one complicated regex, YMMV.

james13:06:36

Swapping to a star for the first \s fixes it too. #"(.*-expiration\s*:)\s+(.*)\n”

lmergen14:06:43

is there a short-hand to write a function like this?

(fn [v] {:foo v})

mpenet14:06:30

(partial hash-map :foo)

mpenet14:06:37

not really shorter tho

rauh14:06:56

@lmergen: #(-> {:foo %})

lmergen14:06:19

why that -> ?

mpenet14:06:41

you can also substitute -> with do

lmergen14:06:30

ah yes i see

lmergen14:06:39

it's of course not in a do block yet

fabrao14:06:04

@madstap: Thanks, worked !

hailin14:06:36

#(hash-map :foo %)

ghadi15:06:17

@mpenet it's used in optimization for 'keyword lookups'

(:foo m)

ghadi15:06:57

if m is a defrecord, it can optimize it to field access (.-foo m)

ghadi15:06:42

the bytecode for it is really gross though

mpenet15:06:05

oki, thanks

josh_tackett15:06:39

@seancorfield: What about something like this:

(mapv #(try
             (run-scraper (:scraper scraper-data)
                          (:username %)
                          (:password %))
             (catch Exception e (str "Error when parsing for " (:username %) " at " vendor)))
          (:creds scraper-data))

mpenet15:06:47

ghadi: you probably know the answer to this one as well: when I create a record, the factory fn map->Foo contains ref to "user.Foo/create", where does this /create comes from?

mpenet15:06:15

nevermind: #object[java.lang.reflect.Method 0x159fa310 "public static user.Foo user.Foo.create(clojure.lang.IPersistentMap)"],

mpenet15:06:55

well I still unclear where exactly it is defined, I guess I need to dig into core

loganmhb16:06:34

@mpenet: I believe that method is emitted during compilation, not defined in core, as it’s a static method on the generated class (`Object/method` is the interop syntax for invoking a static method)

bronsa16:06:45

@mpenet: it's not defined in core, it's hardcoded in the compiler

loganmhb16:06:51

rather, Class/method

seancorfield16:06:11

@josh_tackett: What about it? Looks like it would work (but without knowing more about what the code does, hard to say).

josh_tackett16:06:46

@seancorfield: Yep it works well 🙂

eggsyntax17:06:07

Coincidentally, another question about records: suppose that I have a reference to a record class.

(defrecord foo [_])
(def foo-ref foo)
How can I construct an instance of the record? I imagined that (new foo-ref nil) would work, but I get java.lang.IllegalArgumentException: Unable to resolve classname: foo-class.

cored17:06:26

hi, what's a good book for Clojure beginners ?

ghadi17:06:34

eggsyntax: (->foo args)

ghadi17:06:02

As-in

(defrecord Bar [a b c] ... body)
(->Bar a b c)

eggsyntax17:06:13

Ah, sorry, should have been clearer: I don't actually have foo at hand, only foo-ref.

cored17:06:47

mvaline: oh, thanks

eggsyntax17:06:51

foo is defined in a different ns.

loganmhb17:06:55

@eggsyntax: normally you would either import the actual record, or refer the constructor fn ->RecordName from the ns where the record is defined. is there some reason you can’t do that?

eggsyntax17:06:39

Ah, ok, wait. I think I see; my problem is that I'm defining foo-ref to be the imported class instead the required constructor in the ns where I have to create an instance. facepalm

hans20:06:33

can anyone hint me how i can instantiate a Map<String, Object> in clojure? I need that specific type.

noonian20:06:35

hmm, I would think that {“foo” :anything-deriving-from-object} or just an empty map would do the trick?

hans20:06:04

Would that match the type signature of a Java method that accepts a Map<String, Object>?

noonian20:06:06

It should since Clojure maps implement the Java Map interface. My (probably limited) understanding is that those type checks are done by the Java compiler and not the jvm runtime, so you don’t need to declare anything special from the Clojure side.

hiredman20:06:10

that is the java language level type signature

hiredman20:06:38

this is one of a few places where the jvm and the java language differ

hiredman20:06:16

generics (or type parameters) exist in the java the language type system, but not on the jvm

hans20:06:32

Ah, okay, that's cool. Thanks, both of you!

hiredman20:06:46

in the jvm's type system it is all just maps of objects to objects

seancorfield20:06:13

Gotta love type erasure in generics… 🙂

tjg22:06:25

Sorry if this is was in an obvious place, but I heard there was a proposed change to keyword syntax. (To make them more convenient to use with namespaces.) Does anyone know where I might read more on this?

hiredman22:06:08

it isn't so much a change to keyword syntax, as the addition of some map related syntax, that effects keyword literals in maps

hiredman22:06:12

new map syntax that gives some new semantics to some existing syntax within maps

ov22:06:50

Can someone explain why i must wright (map #(Character/toLowerCase %) str) but not just (map Character/toLowerCase str) ?

danielcompton22:06:10

@ov Character/toLowerCase is Java interop, not a function

fabrao23:06:40

Hello, is there any way to get all quoted elements in here:

(re-seq #"set member (.*)" "set member \"02-05-16\" \"06-05-16\" \"23-05-16\" \"30-05-2016\" \"HORARIO_CICLICO_TERCA_QUINTA\"")
?

hiredman23:06:44

yeah, because of the way the clojure reader constructs regexes for regex lterals you need double the escaping

hiredman23:06:04

double? maybe triple? I froget, lots

hiredman23:06:14

you may want re-find and not re-seq too

fabrao23:06:36

I´ll give a try

hiredman23:06:26

(rest (re-find #"set member (\".+\")+" "set member \"02-05-16\" \"06-05-16\" \"23-05-16\" \"30-05-2016\" \"HORARIO_CICLICO_TERCA_QUINTA\""))

fabrao23:06:41

hiredman worked, thanks a log

raynes23:06:26

Thank that log too, man, it gave its life for paper I wrote a note on today.