Fork me on GitHub
#clojure
<
2018-01-09
>
jgh03:01:15

anyone have any recommendations on a pgp lib?

jgh03:01:20

i pretty much just need it to decrypt a gpg file.

qqq05:01:08

is there a clojure builtin which does: (fand f g h i) -> #(and (apply f %&) (apply g %&) (apply h %&) (apply i %&)) ?

qqq05:01:12

(fand f g h i) -> #(and (apply f %&) (apply g %&) (apply h %&) (apply i %&))

onionpancakes05:01:40

every-pred is pretty close

qqq06:01:27

implementation so far:

(def fand0                  (fn [lst]
                                (let [args (gensym "args")]
                                  `(fn [& ~args]
                                     ~`(and ~@(for [f lst]
                                                `(apply ~f ~args)))))))

  (fand0 '[a b c])

  (defmacro fand [& lst]      (fand0 lst))

octahedrion09:01:20

my project X has a dependency on a project Y which depends on Loom, but when I require a namespace from Y that uses Loom I get

java.lang.RuntimeException: No such var: pm/priority-map-keyfn
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: No such var: pm/priority-map-keyfn, compiling:(loom/alg.cljc:570:33)

octahedrion09:01:56

...however, if I include Loom in X's dependencies, it works...why is that ?

blueberry10:01:57

if you use a namespace directly, you have a direct dependency on a project. this is enforced by maven's design.

octahedrion10:01:20

ok how does that explain the reason for the error ?

octahedrion10:01:34

(just to be clear, the error happens when requiring a namespace from Y in a namespace of X, when X doesn't itself include Loom as a dependency (Loom is a dependency of Y))

qqq11:01:06

(binding [r/*read-eval* false] (r/read-string (slurp "src/a/abcd.cljc")))

qqq11:01:25

this results in "conditional read not allowed"

bronsa11:01:08

that has nothing to do with read-eval

qqq11:01:30

yeah, it has to do with {:read-cond :allow}

qqq11:01:15

here is the XY problem: I have a *.cljc file; I want t read it in and do some static analysis on it

qqq11:01:36

unfortunately, (read-string {:read-cond :allow} ...) is basically replacing all my #?(...) with nil

bronsa11:01:48

you need :features

qqq11:01:46

#?(:clj 2)
-> 2 but I want it to literally return for me
#? ( :clj 2 )

qqq11:01:01

is that possible, or is this not possible becuse #? does not exist at the 'sexp layer'

bronsa11:01:04

that’s not possible

bronsa11:01:13

you can use :read-cond :preserve

bronsa11:01:19

but then you have to do some interpretation

qqq11:01:57

(let [ans (binding [r/*read-eval* false]
                 (r/read-string {:read-cond :preserve}
                                (str "#?(:clj 2)" )))]
       [ans (type ans)])
(comment
 [#?(:clj 2) clojure.lang.ReaderConditional])
     
I can work with this

rauh11:01:43

@qqq Not sure what your goal is but maybe also check out: https://github.com/aengelberg/cljsee

qqq11:01:46

https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ReaderConditional.java <-- alright, so I see a valAt but how do I get the list of possibl ekeys

qqq11:01:28

@rauh: is that library for *.cljc for clojure < 1.6? taht's not my target market.

bronsa11:01:52

@qqq you can only get :form and :splicing?

bronsa11:01:05

form will be (:clj 2)

bronsa11:01:19

splicing? will be false for #? and true for #?@

qqq11:01:13

brilliant, this is precisely what I needed; thanks!

qqq11:01:50

for all intent purposes, I can imagine it's a

{:form (actual code after the #?)
:splicing? (whether it's #? or #?@) ?
except it's a java object and not a clojure map

qqq11:01:28

@bronsa: thanks for all your help; this saved me hours of digging

qqq11:01:58

@bronsa:

(def cljc-read-string    (fn [fname] (binding [r/*read-eval* false]
                                            (let [ans (r/read-string {:read-cond :preserve}
                                                                     (str "(\n" (slurp fname ) "\n)"))]
                                              ans))))

     (for [x (cljc-read-string "src/a/abcd.cljc")]
       (meta x))
(comment
 (nil nil nil nil))
     
any advice on how do pull the meta data ?

bronsa11:01:38

which metadata

qqq11:01:53

line / row numbers

bronsa11:01:08

don’t use read-string

qqq11:01:14

I need to use IndexingReader ?

qqq11:01:48

actually, can you just point me at docs? I'm somehow not finding them, and taking up too much of your time

robert-stuttaford11:01:33

@qqq:

[clojure.tools.reader :as r]
            [clojure.tools.reader.reader-types :as reader-types]

(defn indexed-read [data]
  (-> data
      reader-types/indexing-push-back-reader
      r/read))

qqq12:01:08

@robert-stuttaford: worked brilliantly, thanks!

qqq12:01:45

https://github.com/clojure/tools.reader/search?utf8=%E2%9C%93&amp;q=comment&amp;type= does NOT support preserving comments does it? (for part the app, I need to do *.cljc -> hyperlinked svg files for displaying the code, so I have a slight preference of keeping ";; ... " style comments if possible)

stijn12:01:07

(def model (-> "model/data-model.edn" io/resource slurp read-string))
=> #'user/model
(s/conform ::ddd/model model)
=> :clojure.spec.alpha/invalid
(s/explain ::ddd/model model)
Success!
=> nil

stijn12:01:13

what can be the reason that explain is successful on an invalid conform?

robert-stuttaford12:01:43

ask in #clojure-spec, @stijn 🙂

stijn12:01:50

oh yes 🙂

qqq13:01:47

(def idx-read-one        (fn [rdr] (try (r/read {:read-cond :preserve} rdr)
                                             (catch Exception e nil))))

     (def idx-read-all        (fn [fname]
                                (binding [r/*read-eval* false]
                                  (let [rdr (-> fname io/file io/reader java.io.PushbackReader.
                                                reader-types/indexing-push-back-reader)]
                                    (loop [forms []]
                                      (let [form (idx-read-one rdr)]
                                        (if form
                                          (recur (conj forms form))
                                          forms)))))))

I find the last 5 lines inelegant. There should be some way to say "tun this until it's nil"

romni13:01:41

looks like you can replace that use of if and let with if-let too

qqq13:01:07

maybe (take-while id (repeatedly ...))

manutter5113:01:10

hmm, (for [form (idx-read-one rdr) :while (not (nil? form))] form)

manutter5113:01:44

haven’t tried that, but maybe that would work?

qqq13:01:35

@manutter51: yeah, the take-while and for solutions should do the same

madstap13:01:50

I think it'd have to be (for [form (repeatedly #(idx-read-one rdr)) :while (some? form)] form)

manutter5113:01:19

ah, right, that’s what I meant 😉

qqq13:01:43

(take-while id (repeatedly #(idx-read-one rdr)))

qqq13:01:50

slightly shorter, but same idea

manutter5113:01:07

Looks good to me

fantomofdoom15:01:52

Smb know how add step before

lein uberjar
like build or execute some bash script?

noisesmith17:01:52

https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L262 - this shows top level prep-tasks, but you can also use that key inside the :uberjar profile

Lone Ranger18:01:45

does anyone know if there's a good place to learn about the specific design decisions and philosophy that went into Clojure?

hiredman18:01:10

rich's various conference talks

Lone Ranger18:01:37

my brother is clojure dev and he's fascinated me with little nuggets of wisdom like "a sequence is anything that implements first, rest, and cons..." and I'm like, "whoa". And other things like "never program to a datatype, program to an abstraction". and I'm like "whoa" again.

Lone Ranger18:01:46

Do those sorts of nuggets come from Rich's talks?

noisesmith18:01:50

yes, he talks about those things

donaldball18:01:07

“Are we there yet?” is a talk that holds up well and is perhaps the most accessible

hansw18:01:21

It's fair to say Simple Made Easy changed the way I perceive programming...

sundarj18:01:52

Design, Composition, Performance talks about his approach to design itself. i think it's a great counterpart to Simple Made Easy @goomba

phronmophobic18:01:28

the talks are definitely the most accessible. if you’re willing to dig a little bit more, the jira for clojure has had lots of interesting discussions, https://dev.clojure.org/jira/secure/IssueNavigator.jspa

Garrett Hopper21:01:28

Are ^:const definitions replaced before macro expansion?

Garrett Hopper21:01:17

Also, is there a difference between clj and cljs?

hiredman22:01:01

there are many large and small differences between clj and cljs, including how const works

Garrett Hopper22:01:05

Alright, that may be my issue then. I have a cljc file, and I'm trying to use a ^:const inside a macro usage. I'm assuming the macro is trying to modify the contents of the const. Still waiting on a response in #rum on that.

Garrett Hopper22:01:12

So is my best bet to create a macro to return that static data?

hiredman22:01:11

I would recommend never using ^:const

Garrett Hopper22:01:24

That's interesting. What's the reasoning for that?

hiredman22:01:00

I have yet to talk to anyone who wanted to use it that understood what it does completely

hiredman22:01:55

by that I mean the way const works has knock on effects that interact weirdly with other things like case (which if I recall is one one of the differences between clojure and clojurescript)

hiredman22:01:47

as far as I know there is little to no documentation about what it does, the only way to know is to read the compiler

hiredman22:01:16

but the name is so unassuming that anyone reading it will assume they know what it does

Garrett Hopper22:01:14

That makes sense. I've only just run across it, and you're right, I did immediately assume it was what I expected. (constants in haxe)

hiredman22:01:54

if I recall, I think some other advice I have seen regarding const is: only use it for primitive numeric literals

hiredman22:01:21

(def ^:const x 1)

Garrett Hopper22:01:48

Makes sense, thanks!

Garrett Hopper22:01:11

So the only way to do a true multi-place replacement would be a macro?

hiredman22:01:14

I guess, I would continue and ask, "why are you doing that at all?"

Garrett Hopper22:01:14

Inline styles in rum. Rum needs to convert the style edn, but it doesn't seem to unless it's actually in the macro (not just referencing a variable).

Garrett Hopper22:01:33

So I have a "class" which is just some inline styles and can be used in multiple places.

hiredman22:01:43

the macro likely won't work either

Garrett Hopper22:01:55

Macros are expanded in order, no?

Garrett Hopper22:01:01

From bottom to top?

hiredman22:01:08

nope, other way

Garrett Hopper22:01:45

No that you say that, it makes sense.

Garrett Hopper22:01:51

So a macro could return another macro.

potetm22:01:12

That spells it out pretty nicely. But yeah, pretty niche use case for how often I come across it.

hiredman22:01:30

if anything the example there is kind of the reverse case of what most people assume ^:const means

potetm22:01:37

(That’s not to say that was easy to find.)

Garrett Hopper22:01:41

So it's only for definitions which aren't static but require a transform of other static data?

hiredman22:01:54

I think it actually does both

Garrett Hopper22:01:18

In any case, it doesn't do it before macro expansion.

potetm22:01:20

yeah that’s my impression as well

hiredman22:01:16

ok, right, it does do the thing you expect(sort of) but that example is taking advantage of clojure's top level form as a compilation unit to make it sort of do the other thing

hiredman22:01:35

the line defining pi is compiled and run more or less normally as a def, the value part is executed to get the value of the var, then whenever the var is reference elsewhere, instead of compiling as a var deref, it is compiled as a quoted form of whatever value the var has at that point

Garrett Hopper22:01:05

I just did a quick test of a macroexpand with a ^:const, and it does indeed not expand it.

Lambda/Sierra23:01:59

I encountered a bug related to ^:const not long ago https://github.com/danlentz/clj-uuid/issues/37