Fork me on GitHub
#clojure
<
2019-11-11
>
didibus02:11:25

I don't think rebl can be extended like that yet

👍 4
seancorfield02:11:28

You can implement datafy and nav for such things tho'... or rather the underlying protocols...

👍 4
valerauko06:11:33

I have a macro problem: what's the way to get the correct autogensym if unquoted once?

(defmacro def-foo
  [name args subject]
  `(defn ~name ~args
    (let [fix-text# (pr-str ~subject)]
      ~(cond
        (:foo subject)
          `(let [len# (count fix-text#)]
            (if (> len# 0)
              len#
              :error))
        (:bar subject)
          `(clojure.string/reverse fix-text#)
        :else `fix-text#))))

valerauko06:11:10

> (-> '(def-foo bar [a] {:value a :foo true}) 
.. macroexpand-1 
.. clojure.pprint/pprint)
(clojure.core/defn
 bar
 [a]
 (clojure.core/let
  [fix-text__1288__auto__
   (clojure.core/pr-str {:value a, :foo true})]
  (clojure.core/let
   [len__1283__auto__ (clojure.core/count fix-text__1284__auto__)]
   (if (clojure.core/> len__1283__auto__ 0) len__1283__auto__ :error))))

valerauko06:11:13

I'd expect the fix-text#s to all refer to the same autogensym which is clearly not the case

valerauko06:11:23

How do I make them the same?

valerauko07:11:44

Is manually gensym'ing the symbols used across quotes in an encompassing let the only way?

dominicm08:11:46

There's a ztellman library for this, but otherwise yes. Nesting expansion is a new context.

cddr09:11:03

What's the zachware you're referring to?

valerauko09:11:47

potemkin iirc

valerauko10:11:12

linters really can't handle potemkin's magic so i prefer not to use it though

sgerguri12:11:33

I am looking at profilers for Clojure and two libraries that appear viable are https://github.com/ptaoussanis/tufte and https://github.com/clojure-goes-fast/clj-async-profiler. Any recommendations on which to use?

dominicm12:11:11

Different use cases for both.

dominicm12:11:17

What's your use case?

sgerguri12:11:08

We have a Kafka-driven service that also talks to the DB and is heavy on spec, and I would like to see if we have an actual bottleneck in code. We occasionally spike our input lag and take some time to recover from that, but that could just be a property of the sizeable messages we are ingesting. So whilst I look into the latter it would be also nice to take the generators for a spin, introduce some random traffic locally and see where time is being spent processing it.

dominicm13:11:44

If you're doing it locally then the async clj profiler is the best choice.

sgerguri13:11:40

Perfect - I'll give it a spin then. Thanks.

gleisonsilva14:11:07

Hello, guys! May u could help me... I'm trying to quote/unquote a code snippet but I couldn't figure out the right way Given this snippet:

clojure
(defn spec
  [evt tbl]
  {:event "event"
   :trigger-event evt
   :where '(fn [{:keys [table query-seq query-count]}]
             (and (= query-seq query-count)
                  (= table tbl)))
I need only tbl to be evaluated. But I couldn't find how... I've tried ~, ~@, etc... but it gives me back something like (quote tbl) instead of the value associate with this symbol... can u help me?

dominicm14:11:26

You have to use ` for ~ to work.

gleisonsilva14:11:06

when I change ' for , it mess up another things... basically it interpret symbols changing, for example, fn` to clojure.core/fn.. but I need to keep it "clean", like written

dominicm14:11:55

Use ~' where you want it to be clean

dominicm14:11:30

Or use list / some other templating approach.

bronsa14:11:13

do you really need to keep it as written or are you just trying to make the argument symbols not get namespace qualified?

gleisonsilva14:11:45

basically get rid of namespaces

bronsa14:11:59

why do you need to do that for fn/`and`/`=`?

Henry14:11:15

Hi, does anyone here use clojure.data.xml? I’m trying to read an xml string without replacing entity references. http://clojure.github.io/data.xml/#clojure.data.xml/parse-str and a look at https://github.com/clojure/data.xml/blob/master/src/main/clojure/clojure/data/xml/jvm/parse.clj suggests that we should be able to use (xml/parse-str document :replacing-entity-references false) but that doesn’t work..

gleisonsilva14:11:01

@bronsa i'm trying to write out a edn file based on a map where some keys have functions as values

bronsa14:11:57

ok but if you're evaluating the quoted value at some point, then namespacing the vars should be desiderable -- if you're just parsing them then I understand

bronsa14:11:26

but if you are indeed evaluating them, there's a better solution:

`(fn [{:keys [table# query-seq# query-count#]}]
             (and (= query-seq# query-count#)
                  (= table# ~tbl))

gleisonsilva14:11:28

it's a Joker script that will writes the file for later processing in Clojure

gleisonsilva14:11:40

it's not pretty, but works:

:where `(~'fn [{:keys [~'table ~'query-seq ~'query-count]}]
             (~'and (~'= ~'query-seq ~'query-count)
                    (~'= ~'table ~tbl)))

tks, @dominicm

alexbaranosky17:11:35

does this work for your needs?

:where `(fn [{tbl# :table
              qs# :query-seq
              qcnt# :query-count}]
          (and (= qs# qcnt#)
               (= tbl# ~tbl)))

peterdee14:11:31

I am trying to make this warning go away, but I can’t figure out where to put the type hint: recur arg for primitive local: max_len is not matching primitive, had: Object, needed: long

(defn- max-depth
  "Return the max depth of the taxonomy for the give sequence of synsets"
  [syn-seq]
  (loop [sseq syn-seq
         max-len 0]
    (if (not sseq) 
      (inc max-len) ; inc: didn't count arg. 
      (let [synset (first sseq)
            len (apply max (map count (hypernym-paths synset)))]
        (recur (next sseq)
               (max len max-len))))))

bronsa14:11:43

len (long (apply ..))

bronsa15:11:06

you need to unbox, not type hint

peterdee15:11:53

Yes. That worked. Thanks!

vlaaad15:11:38

interesting that code above compiled as is for me

bronsa15:11:31

(set! *warn-on-reflection* true)

vlaaad15:11:40

(after replacing (hypernym-paths synset) with [])

vlaaad15:11:45

ah, reflection

josh_tackett16:11:54

Anyone know how to capture the body of a get request via a selenium webdriver?

josh_tackett16:11:17

Yep that's what we are using, and we are trying to use https://github.com/igrishaev/etaoin#devtools-tracking-http-requests-xhr-ajax but it doesn't seem to contain the body of the get request.

jeroenvandijk16:11:58

Do you want the body of the request or the body element of the html page?

jeroenvandijk16:11:46

maybe you can do it via https://github.com/igrishaev/etaoin#executing-javascript and then how you would normally get the body. If that doesn't work maybe you have run into a CORS issue

Andrew Brock16:11:06

The issue we're running into with using Javascript is there is a cookie (correlation ID) that has to be sent with the request... and that correlation ID is formed in part from a third party authentication service that we can't access directly. What we're really needing to do is be able to grab the response body from the Chrome developer console.

jeroenvandijk16:11:58

ok, sounds like you have dived into it a lot more than I did 🙂 Good luck!

👍 4
danielneal16:11:43

heya, I’m struggling to do basic counting today… anyone got some clues how to generate a lazy seq of strings from an alphabet "abcde…" like ("a" "b" "c" "d" "e" "aa" "ab" "ac" … "aaa" "aab" …)

hiredman17:11:46

the given solutions all seem very bad given that it sounds like what you have is just mapping numbers to strings of digits.

hiredman17:11:09

(defn base27 [n]
  (loop [s ()
         n n]
    (let [r (rem n 27)
          q (quot n 27)
          c (if (zero? r) \space (char (+ 96 r)))]
      (if (zero? q)
        (conj s c)
        (recur (conj s c) q)))))


(for [i (range 1000)
      :let [s (apply str (base27 i))]
      :when (not (.contains s " "))]
  s)

hiredman17:11:25

I was fighting with something like that recently in a toy compiler, turning type variables (which are numbers in the compiler) into strings for pretty printing

hiredman17:11:44

there must be some even better way to do the base thing that avoids the space stuff

peterdee18:11:31

I had a counting problem like this once where I wanted to map natural numbers to the column names of an Excel spreadsheet. (a,b,…z,aa,ab). You’d think it would be just a base 26 representation, but it’s not.

peterdee18:11:04

I gave up in the end. Allowed 26^2, I think.

hiredman18:11:06

The problem with base26, where a is 0 is you never get the a prefixes because b = ab, so you have to do some kind of shift, treating 0 as special which always feels inelegant, it seems like there should some purely numeric function that would do it.

jumpnbrownweasel20:11:26

Not sure, but is this the sort of thing you're looking for?

(defn letter-combo [i]
    (apply str
      (map #(char (+ % (int \a)))
        (loop [s (), i i]
          (if (< i 26)
            (conj s i)
            (let [q (quot i 26)
                  r (rem i 26)]
              (recur
                (conj s r)
                (dec q))))))))

  (map letter-combo (range 24 28))

=> ("y" "z" "aa" "ab")

hiredman20:11:14

Ah, interesting

yuhan20:11:55

had fun trying to come up with a recursive solution:

(defn string-permute
  ([chars] (string-permute [""] chars))
  ([prev chars]
   (let [strs (mapcat (fn [c] (map (fn [s] (str c s)) prev)) chars)]
     (lazy-cat strs (string-permute strs chars)))))

(string-permute "abc")
;; => ("a" "b" "c" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc" "aaa" "aab" "aac" "aba" "abb" ...

yuhan20:11:31

ah, didn't see the previous solutions in the channel which are quite similar

peterdee21:11:22

These are nice. Thanks!

peterdee22:11:24

I should get more familiar with lazy-cat!

jumpnbrownweasel23:11:53

(I had posted some lazy examples here but they were holding onto the head, so I deleted them, so others don't copy them.)

dominicm16:11:12

Math combinatorix might help

bronsa16:11:42

(defn permutations [els]
  (when-let [[f & r] (seq els)]
    (let [perms (permutations r)]
      (cons [f] (concat perms (map (fn [r] (cons f r)) perms))))))

bananadance 4
bronsa16:11:24

I guess you can

(defn permutations-str [els]
  (when-let [[f & r] (seq els)]
    (let [perms (permutations-str r)]
      (cons (str f) (concat perms (map (fn [r] (apply str f r)) perms))))))

danielneal16:11:59

will that trigger any of these concat warnings stuart was telling me about

danielneal16:11:15

hmm I’m not sure this is right

danielneal16:11:21

I want to generate them in order

bronsa16:11:40

if you want them in order switch the order of args in concat

bronsa16:11:07

(no as in: it shouldn't be a concat bomb)

danielneal16:11:21

ah no wait in the other order

danielneal16:11:30

like all the single characters, then the doubles then the triples

vlaaad16:11:41

(defn- boop [i]
  (case i
    0 nil
    1 (map str "abcdefghijklmnopqrstuvwxyz")
    (for [x "abcdefghijklmnopqrstuvwxyz"
          y (boop (dec i))]
      (str x y))))

(take 100
      (->> (range)
           (mapcat boop)))

alexbaranosky17:11:39

You're just reading it upside down!

danielneal16:11:48

looks like the idea from @vlaaad will work

vlaaad16:11:04

I don't know correct name for boop

bronsa16:11:25

that's going to be very expensive on the recursive subcalls, but I guess if i is small that's not a big deal

danielneal16:11:27

will that do the requisite lazy seq caching

bronsa16:11:57

no, you'd need to memoize it manually

alexbaranosky17:11:35

does this work for your needs?

:where `(fn [{tbl# :table
              qs# :query-seq
              qcnt# :query-count}]
          (and (= qs# qcnt#)
               (= tbl# ~tbl)))

peterdee18:11:43

I had a counting problem like this once where I wanted to map natural numbers to the column names of an Excel spreadsheet. (a,b,…z,aa,ab). You’d think it would be just a base 26 representation, but it’s not.

noisesmith18:11:07

I got inspired to try this, and yeah, it's got a few tricky bits beyond the obvious ones...

noisesmith18:11:32

like making it go from z to aa instead of ba

josh_tackett20:11:31

anyone know how to run cli commands from clojure?

shdzzl20:11:27

@josh_tackett Not sure if it's still the preferred library for this use case, but I've seen https://github.com/Raynes/conch used a lot for that purpose.

josh_tackett20:11:05

@shdzzl I'm trying to use /sh but it just prints it out rather than decrypting it: (shell/sh "echo" "U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ=|openssl" "aes-256-cbc" "-d" "-a" "-pass" "pass:aaa")

shdzzl20:11:43

I'm going to guess that you can't pipe like that. Does this work? (shell/sh "openssl" "aes-256-cbc" "-d" "-a" "-pass" "pass:aaa" :in "U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ=") Not at a REPL right now, so can't test.

shdzzl21:11:03

Looks like it wants a filename there for the input stream when passing a string.

shdzzl21:11:44

This is likely easier with conch's piping facilities, as sogaiu suggested.

shdzzl20:11:43

I'm going to guess that you can't pipe like that. Does this work? (shell/sh "openssl" "aes-256-cbc" "-d" "-a" "-pass" "pass:aaa" :in "U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ=") Not at a REPL right now, so can't test.

sogaiu20:11:57

may be as shdzzl suggested as an alternative, conch may work better for this? https://github.com/Raynes/conch#piping

noisesmith21:11:21

That is definitely better than using shell/sh, but also I found for interactive communication with a process via input-stream and output-streams using Process and ProcessBuilder directly is actually less complicated than using conch

sogaiu21:11:56

thanks for the tip!

josh_tackett21:11:55

Anyone an openssl expert here?

shdzzl21:11:24

Not an expert, but the following terminal command decoded correctly for me: echo "U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ=" | openssl enc -d -aes-256-cbc -a -pass pass:aaa

sogaiu21:11:47

not an openssl expert, but isn't U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ= base64?

sogaiu21:11:16

decoded, that starts with: Salted__

shdzzl21:11:24
replied to a thread:Anyone an openssl expert here?

Not an expert, but the following terminal command decoded correctly for me: echo "U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ=" | openssl enc -d -aes-256-cbc -a -pass pass:aaa

sogaiu21:11:54

worked here too: hola 🙂

andy.fingerhut21:11:24

@josh_tackett Does the command pipeline you showed work for you when started from a shell prompt?

noisesmith21:11:10

the problem here is that shell/sh doesn't start an sh (it's somewhat misleadingly named) so there's nothing to interpret | as an IO redirect or start openssl as a separate process

noisesmith21:11:47

what was shown above will work at a shell prompt, because you are using an instance of sh which understands redirects and the associated syntax

noisesmith21:11:59

to do this with clojure.java.shell/sh you need to explicitly use a shell

noisesmith21:11:23

user=> (clojure.java.shell/sh "sh" "-c" "echo U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ=|openssl aes-256-cbc -d -a -pass pass:aaa")
{:exit 1, :out "", :err "bad decrypt\n4469843564:error:06FFF064:digital envelope routines:CRYPTO_internal:bad decrypt:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.200.4/libressl-2.6/crypto/evp/evp_enc.c:533:\n"}

shdzzl21:11:46

That's interesting.

noisesmith21:11:30

btw that's the same output I get for your command above @shdzzl

shdzzl21:11:13

Hmm I get a single \n in :out from clojure.java.shell/sh with an explicit shell (`sh`) and the expected result from my terminal emulator

shdzzl21:11:12

libressl vs openssl?

noisesmith21:11:28

same for my example - notice that :err had a string but not :out

shdzzl21:11:50

I'm guessing libressl might have a different API to openssl here?

noisesmith21:11:58

by changing echo to echo -n I get "error reading input file" instead of the digital envelope bad decrypt

noisesmith21:11:02

not sure what's going on though

noisesmith21:11:22

(this is both in a normal shell and in clojure via shell/sh)

shdzzl22:11:34

Could this be it? https://github.com/libressl-portable/portable/issues/378 What happens if you include the "-md" "sha256" param suggested?

noisesmith22:11:13

that fixes it

noisesmith22:11:16

user=> (clojure.java.shell/sh "sh" "-c" "echo 'U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ='|openssl aes-256-cbc -d -a -pass pass:aaa -md sha256")
{:exit 0, :out "hola\n", :err ""}

shdzzl22:11:33

Same, more or less:

user=> (clojure.java.shell/sh "sh" "-c" "echo U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ=|openssl enc -d -aes-256-cbc -a -pass pass:aaa")
{:exit = 0
 :out = "hola\n"
 :err = "*** WARNING : deprecated key derivation used.\nUsing -iter or -pbkdf2 would be better.\n"}

dominicm22:11:51

Is it possible to use the clojure.main api to start a prepl?

noisesmith22:11:17

if nothing else, a variation on this

user=> (clojure.main/main "-e" "(+ 1 1)")
2
nil
perhaps there's something more elegant though

dominicm22:11:54

My question is flawed really. I have something using clojure.main/repl and overriding :eval in order to perform a useful nested repl. I wanted to make it a nested prepl (I have a way of binding the original *out* so I can nest it) so that I can use it with tooling.

noisesmith22:11:42

oh, that's a different question yes

noisesmith22:11:16

user=> (clojure.java.shell/sh "sh" "-c" "echo 'U2FsdGVkX19YpBxGXZiFhpXjmogTE5OIbdQaHrXUIVQ='|openssl aes-256-cbc -d -a -pass pass:aaa -md sha256")
{:exit 0, :out "hola\n", :err ""}

borkdude23:11:21

am I right that you can vote on http://ask.clojure.org for issues but not on JIRA? just checking

andy.fingerhut23:11:27

I recall Alex Miller suggesting that people vote for issues on http://ask.clojure.org, since that is the current supported way to create issues for Clojure and other contrib projects, and creating an account there does not require any manual work by anyone (whereas I believe the new Clojure JIRA has manual effort required for all new accounts, and they might be trying to keep the number of those to a low number, perhaps due to licensing and/or free support tier issues).

Alex Miller (Clojure team)23:11:16

If you’re a user, vote on ask. If you’re a developer with a jira account, vote on jira