Fork me on GitHub
#clojure
<
2017-06-13
>
ravster00:06:29

In the REPL, if I call the public method, I get an Illegal argument exception

hiredman00:06:49

so you most likely have the precondition in the wrong place

hiredman00:06:57

or it isn't failing

hiredman00:06:13

and you are mistaking the illegal argument exception for a failed precondition

hiredman00:06:37

so do the exact same thing in the repl you are doing in the tests

devth00:06:32

is there a lib that contains a function like template in:

(template
   ":label must be a string between :min-length and :max-length characters"
   {:value "First Name"
    :label ""
    :min-length 3
    :max-length 100})
which returns "First Name must be a string between 3 and 100 characters"?

devth00:06:03

(i think i have written that function before. can't find it 😂)

noisesmith00:06:32

I guess you could start with plumatic/schema ? I don't know about the string parsing part though

noisesmith00:06:08

but it's straightforward to give a data shape to schema and get back the parts that didn't match in a readable form

devth00:06:36

you're talking about parsing it out and building the function right?

devth00:06:42

i'm assuming it already exists somewhere

noisesmith00:06:26

not that I've seen

noisesmith00:06:23

oh wait - is this just a templating question? ugh, I totally misread it

devth00:06:23

ah cool. not sure i want to pull in an entire template system

noisesmith00:06:35

I thought you were asking for data validation with string parsing

noisesmith00:06:43

not string inerpolating templates, lol

ravster00:06:29

@hiredman Fixed my issue. Thanks for your help.

ibarrick01:06:16

I can't seem to get rid of this error running lein repl: Warning: cider-nrepl requires Clojure 1.7 or greater I've tried deleting ~/.m2/ and I've verified with lein deps :tree that I'm getting Clojure 1.8.0 (which I have as a manual dependency, not a transitive). Once the repl loads (clojure-version) returns 1.8.0, as expected.

ibarrick01:06:05

Does anyone know of anything else I can try?

noisesmith01:06:35

sounds like a cider bug

noisesmith01:06:43

how recent is your cider version?

ibarrick01:06:47

@noisesmith I'm using cider-0.14.0

yogthos03:06:07

@devth there's cl-format https://clojuredocs.org/clojure.pprint/cl-format that can do all kinds of crazy stuff

devth13:06:08

thanks. can't believe i hadn't come across this earlier!

yogthos03:06:00

no prob, it's a surprisingly little known feature 🙂

alex.ter.weele03:06:50

how can you find the powerset of a set? I see two options: (1) do it myself (2) use combinatorics, as recommended in https://stackoverflow.com/a/20914117. However, somewhere between version 0.0.7 of combinatorics and the present, subsets lost the ability to operate on sets. To use the most recent version of the library, I’d have to transform my input from a set to something else.

brabster05:06:16

Hey folks, I'm playing with Apache Beam which relies on overriding methods in a DoFn class. Based on beam-clj, I've got a Java class that resolves a var to an IFn to get around that but I'd like to pass in an anonymous IFn directly instead of having to define elsewhere and resolve it. When I pass an IFn directly, I get a ClassNotFoundException for my anonymous IFn when Beam is trying to deserialize the class that contains it

brabster05:06:14

I'm using Leiningen and working at the repl here

brabster05:06:59

What is different about the anonymous (fn...) vs. a (defn...)? I thought they both produced classes when compiled?

brabster05:06:51

Or is it the clojure.java.api.Clojure.var("foo", "bar") that's working the magic here?

bfabry07:06:05

@brabster if you aot a namespace the things in defn will become classes. anonymous functions are created at runtime so cannot have classes created for them ahead of time

rauh07:06:07

@bfabry I don't think that's true.

bfabry07:06:59

... which bit?

rauh07:06:19

That anonymous functions are crated at runtime and don't have classes.

rauh07:06:53

Functions defined within a function are still compiled AOT, possibly with a Constructor parameter if they're Closures

bfabry07:06:14

ah that's interesting. til. I think for the purposes he's talking about it'll amount to the same thing though. he'll need the entire closure available an invocation time which can happen on different machines to creation

bfabry08:06:34

@brabster fwiw, we've been writing beam jobs in clojure for about 6 months now, and we've settled on DoFn's that load the required clojure code (if needed) at runtime and invoke the specified vars with any arguments needed. we do this by specifying either a var "`#'foo`" or a var with any extra (serializable) closure args as "`[#'foo :bar]`" which gets translated into a little bit of data like {:ns 'user :name 'foo :args [:bar]} and gets invoked by the DoFn as (user/foo whatever beam params make sense in context :bar)

bfabry08:06:47

this removes any need for aot

brabster08:06:40

Nice, thanks chaps... @bfabry I reckon there's a nice blog post in what you've described there ;)

razum2um11:06:58

Has anyone in this chat already wrote his update-in-each function, which acts like update-in but only if finds a seq - update-in-each’s all the elements? I found https://github.com/ctford/traversy but it’s not composable but links to haskel’s lenses, which makes me find http://funcool.github.io/lentes/latest/ but I don’t see anything abstract, which will focus any item in collection... so anyone sticks with own version of update-in-each?

razum2um15:06:45

nathanmarz: looks fine 👍 I’m talking about structure like this

(def ex {:x {:y [{:a {:b 1}} {:a {:b 2}}]}})
(update-in ex [:x :y] (fn [xs] (mapv #(update-in % [:a :b] inc) xs)))
if vec happes twice it gets even worse 😕

nathanmarz20:06:29

with specter that's just (transform [:x :y ALL :a :b] inc ex)

nathanmarz13:06:10

if you have a particular example of input -> output I can show you how to do it

miikka13:06:33

Is it still the case that if you extend-protocol to two interfaces and you call protocol methods on an object that's instance of both of them, you can't know which implementation you will get?

mahdix13:06:53

I am not a Clojure expert but have a question regarding the language.

mahdix13:06:59

I hope I can get my answer here.

mahdix13:06:21

Is it possible that a Clojure function returns a mutable reference to a local variable to the caller?

ghadi14:06:20

no that is not possible @mahdix

mahdix14:06:59

So function "must" return an immutable result.

jeff.terrell14:06:52

@mahdix - Not exactly. The atom function, for example, returns a reference to a mutable thing.

jeff.terrell14:06:02

It kinda depends on what you mean by "local variable".

jeff.terrell14:06:22

In Clojure (and Lisps in general) this is usually a let binding, meaning the association of a name to a value.

jeff.terrell14:06:41

The binding itself is immutable, although it can be shadowed by another binding for the same name to a new value.

jeff.terrell14:06:09

So if you could return that binding, it wouldn't be mutable.

jeff.terrell14:06:34

But then, returning the binding isn't really how it would work anyway. If you returned anything from the function, it'd almost certainly be the value of that binding.

jeff.terrell14:06:48

And one of the possible values in Clojure is a mutable reference type, like an atom.

jeff.terrell14:06:54

Does that help?

mahdix14:06:51

What I am looking for is to know whether something like this is possible to happen in Clojure:

mahdix14:06:36

We call a function f which starts a new thread/process and passes some data to it which is returned to us at the end as a mutable data.

mahdix14:06:42

So now we have a "shared mutable state"

mahdix14:06:54

which is shared between caller of the f function and the newly created thread.

mahdix14:06:06

At least the caller of f will be able to mutate that data.

mahdix14:06:12

Can this happen? Does it make sense?

weavejester14:06:45

@mahdix Yes. You can just return an atom

weavejester14:06:39

(defn f []
  (let [a (atom nil)]
    (future (Thread/sleep 1000) (reset a :done))
    a)

weavejester14:06:55

More usually this is done with a promise, which can only be written to once.

mahdix14:06:12

@weavejester if I call f and modify it's output value, will it affect the a which is used inside the thread? In other words, will calling f result in shared mutable state?

weavejester14:06:07

If I’m understanding you right, yes, @mahdix

weavejester14:06:18

So for example:

weavejester14:06:20

(def f []
  (let [a (atom nil)]
    (future (Thread/sleep 10000) (println @a))
    a))

weavejester14:06:36

That sleeps for 10 seconds, then prints the value held in a

weavejester14:06:37

user=> (def output (f))
user=> (reset! output "hello")
...
hello

weavejester14:06:01

So you can change the value after the function has returned.

rinaldi14:06:59

I am trying to refactor a function that uses as-> (commented) to ->> thread macro format for learning purposes. I got this far but I am getting an arity exception error. What am I missing?

;; (defn anagrams [word words]
;;   (as-> words w
;;     (string/lower-case w)
;;     (map #(compare word %) words)
;;     (.indexOf w (apply min w))
;;     (get words w)))

(defn anagrams [word words]
  (->> word
       (string/lower-case)
       (map #(compare word %) words))
       (apply min)
       (.indexOf)
       (get words)))

joshjones14:06:42

.indexOf is not a clojure function. Must make it #(.indexOf %)

noisesmith17:06:14

joshjones: ->> is a form rewriting cosntruct, it doesn’t care that methods are not first class, method calls without function wrappers are allowed inside ->> / -> / as-> etc.

noisesmith17:06:49

(as long as they end up in a method invocation position and not a value position in the resulting form)

joshjones17:06:44

good call, I was confusing this with something else, thanks

jeff.terrell14:06:43

I think (memfn indexOf) would work too.

rinaldi14:06:11

Still got an exception:

RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException (Util.java:221)
ArityException Wrong number of args (1) passed to: core/apply  clojure.lang.AFn.throwArity (AFn.java:429)

mgrbyte14:06:59

extra ) after compare word

rinaldi14:06:00

Nevermind, it runs now! I messed up the file.

rinaldi14:06:19

Still doesn't give me back the same result as the commented code would though, still something is off.

rinaldi14:06:48

This is what I am using by the way: https://repl.it/Ij2N/0

alricu14:06:35

I am just trying to go over each element in a sequence; but when one condition is fulfilled, break the dorun

joshjones15:06:38

you could reduce it, and short-circuit

joshjones15:06:41

(reduce #(if some-condition
           (reduced "ending value")
           (do (something-else)))
        coll)

alricu16:06:45

joshjones: I used the some function!

jeff.terrell15:06:16

@rinaldi - Your map line breaks the flow of ->>, since it doesn't use the threaded value. Haven't thought about what you might be trying to do, but just noticed that the pattern didn't quite fit so thought I'd mention it.

rinaldi15:06:31

@jeff Oh man, that makes a lot of sense actually!

jeff.terrell15:06:28

rafaelrinaldi: I think you're tagging the wrong Jeff, FWIW. :-)

rinaldi15:06:47

Ops, I am sorry!

urbank15:06:42

Is there a partition-all function in core that also fills in the sequences that are too short with some value?

rinaldi15:06:01

@jeff I thought about extracting that piece to its own function but couldn't come up with something that works

wiseman16:06:30

@urbank does this work for you?

> (partition 10 10 (repeat :pad) [1 2 3 4 5 6 7 8 9 10 11])
((1 2 3 4 5 6 7 8 9 10) (11 :pad :pad :pad :pad :pad :pad :pad :pad :pad))

michaellindon16:06:25

I'm having trouble accessing a method from within a utility class. I do not know a great deal about utility classes in java. The class I'm trying to access the digamma method of org.apache.commons.math3.special.Gamma. For the documentation I cannot find any constructor of this class (docu here http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/index.html). When I try (new org.apache.commons.math3.special.Gamma) I get No matching ctor found for class org.apache.commons.math3.special.Gamma

hiredman16:06:19

it is just a much of static methods

hiredman16:06:17

you don't construct it, you just invoke the static methods

hiredman16:06:32

static methods are methods that don't require an instance

michaellindon16:06:04

@hiredman thanks for your response, I have tried (.digamma org.apache.commons.math3.special.Gamma 3.2) but I get No matching method found: digamma for class java.lang.Class

michaellindon16:06:18

where 3.2 is an arbitrary double

michaellindon16:06:30

is this the incorrect way to accesss a static method?

bfabry16:06:44

@michaellindon the syntax is (org.apache.commons.math3.special.Gamma/digamma 3.2)

bfabry16:06:51

or at least that's one of the syntaxes

michaellindon16:06:10

thank you 🙂

urbank17:06:22

@wiseman Oh, thats very cool! I wouldn't have thought of that... didn't know you could pass multiple arguments to partition. Thanks!

devth18:06:58

https://funcool.github.io/cuerdas/latest/#interpolate provides string interpolation, but the literal string must be provided at compile time (like in its examples). for example:

(let [value 1
       e "foo ~{value}"]
   (cstr/istr e))
returns "e" but:
(let [value 1]
   (cstr/istr "foo ~{value}"))
returns "foo 1". is eval the only way to work around this? (not sure this would even be a workaround. a bit confused on when macro expansion is happening and how or if i can delay it).

bfabry18:06:17

@devth looks like that macro just delegates to a function -interpolate, so you could call that (it is private so there's no guarantee it will work across versions etc)

devth18:06:39

i guess the reason it needs to happen at compile time is because it captures outer scope

devth18:06:56

apparently what i really need is templating

bfabry18:06:15

oh you're totally right

bansari.desai18:06:42

Hi, can we output test result in junit xml format with mvn test on clojure web app ?

noisesmith18:06:51

clojure.test has a with-junit-output macro you could hook up (I don’t know the details about hooking clojure.test up with maven though)

noisesmith18:06:45

I haven’t tried this plugin but it claims to set this up for you https://github.com/talios/clojure-maven-plugin

bansari.desai19:06:54

Do you know some example I can refer to?

alricu19:06:42

Do you know if there is a way to verify a set of client certificates against a CA cert? I mean,

alricu19:06:20

I need to create in clojure a function that given a client certificate can show me if the certificate was issued by a CA,

alricu19:06:35

I have the CA Cert

alricu19:06:49

I cannot find something to Clojure

rinaldi20:06:42

For those curious, the solution for my as-> to ->> problem that I posted earlier today was to split my chain into more functions: https://repl.it/IjtX/1

jeff.terrell00:06:42

rafaelrinaldi: Great solution. Cheers!

wiseman20:06:53

i feel like i have a relatively vanilla project, but lein test won’t run if i don’t have a network connection. is that expected?

wiseman20:06:21

[wiseman@Yoyodyne cca_intent_classifier (master)]$ lein test
Jun 13, 2017 1:45:57 PM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (java.net.SocketException) caught when processing request to {s}->https://clojars.org:443: Network is unreachable

wiseman20:06:43

all my dependencies are already available locally.

captainlexington20:06:05

@wiseman Do all other lein commands run?

wiseman20:06:11

@captainlexington no. lein run also fails. It complains about a jar that is not in clojars/maven, that i have installed locally using lein install.

wiseman20:06:36

Could not transfer artifact com.xxxxx:xxxxx-java-client:pom:1.2.0 from/to central (): : unknown error

wiseman20:06:08

specifically, i have C depends on B depends on A. A is a separate java jar that B.project.clj uses by doing :repositories [["project" {:url "file:maven-repo" username "" :password ""}]]

wiseman20:06:48

(and then including com.xxxxx/xxxxx-java-client in :dependencies)

wiseman20:06:12

maybe there’s a better way to include the A.jar in B?

Matthew Davidson (kingmob)21:06:18

Is it not possible to use records and/or types as atom values? Getting an odd error when I try to stick my trie record type into an atom

noisesmith21:06:06

atoms can hold anything, and are reasonable for any immutable type

noisesmith21:06:33

@kingmob what does the line of code putting the thing in the atom look like?

Matthew Davidson (kingmob)21:06:11

@noisesmith (atom (default-alphabet-trie-node 0)) where default-alphabet-trie-node is a factory fn

noisesmith21:06:36

yeah, that would only fail if the call to default-alphabet-trie-node did

Matthew Davidson (kingmob)21:06:49

It’s not failing there

Matthew Davidson (kingmob)21:06:59

It’s failing on a @db call

Matthew Davidson (kingmob)21:06:29

Trys to call deref-future instead of `(.deref ref)

noisesmith21:06:39

those are the same thing

noisesmith21:06:46

what’s the actual error

Matthew Davidson (kingmob)21:06:04

Unhandled java.lang.ClassCastException user.AlphabetTrieNode cannot be cast to java.util.concurrent.Future

Matthew Davidson (kingmob)21:06:17

core.clj: 2206 clojure.core/deref-future core.clj: 2228 clojure.core/deref core.clj: 2214 clojure.core/deref REPL: 79 user/process-op REPL: 73 user/process-op

noisesmith21:06:20

so you aren’t derefing the atom, you are derefing the thing in it

noisesmith21:06:38

deref tries a few things, finally trying to deref a future, so the error message is slightly misleading

Matthew Davidson (kingmob)21:06:04

Hmmm, the default-alphabet-trie-node fn is memoized…could that be related?

noisesmith21:06:26

somewhere you replace your handle to the atom with the contents of it

noisesmith21:06:33

perhaps by taking the value of swap!

Matthew Davidson (kingmob)21:06:58

OK, I am recurring with the db being in the loop bindings

noisesmith21:06:32

sounds like the db shouldn’t be a loop binding if it’s an atom?

noisesmith21:06:43

since you’d want the same thing for every recursion

noisesmith21:06:58

(unless the loop were inside the function you pass to swap! of course)

Matthew Davidson (kingmob)21:06:10

Right, right, if it’s an atom, it doesn’t need to be rebound

noisesmith21:06:06

@kingcode correcting what I said above - deref checks if something is a clojure IBlockingDeref instance, and if not it trys deref-future. So any object that doesn’t actually support deref will get an error message mentioning deref-future

Joshua Suskalo22:06:22

Is there any way to destructure as a set? to check for keys as flags for example?

Joshua Suskalo22:06:39

Like this for example? (defn useful [& #{:keys [print console window sound async]}] (when print (println "Hello, useful")))

hiredman22:06:49

it doesn't make sense to destructure a set

hiredman22:06:16

sets are unordered, and the only keys are the objects in the set

Joshua Suskalo22:06:43

Is there a better way to do what I'm thinking of using it for then? as the example?

hiredman22:06:05

hard to say exactly what you mean by that code

hiredman22:06:09

I guess a set of keywords?

hiredman22:06:33

(defn useful [caps] (when (caps :print) (println "....')))

Joshua Suskalo22:06:54

That looks fine, but then the arguments will actually have to be passed in as a set, rather than simply being queried to see if keywords exist among the args. The desire would be to be able to call the function as (useful :print :console) rather than as (useful #{:print :console})

seancorfield23:06:39

(defn useful [& args] (let [caps (set args)] ...))

hiredman23:06:51

or just pass the set

hiredman23:06:21

even for maps that style of destructuring is problematic and I would avoid it, better to pass the map

seancorfield23:06:42

It’s a similar set of trade offs with unrolled keyword arguments vs passing an options hash map. Passing the set or map composes better but is slightly less convenient for humans to type.

seancorfield23:06:05

(e.g., java.jdbc used to be all based on unrolled keyword arguments but it was a bit of a pain to work with when building abstractions on top of it — so I made a breaking API change to accept a hash map of options instead: users have to type { } around their options now but composing the functions is so much easier)

Joshua Suskalo23:06:27

Okay, so the general form of using the keyword arguments destructuring is generally considered bad practice then?

Joshua Suskalo23:06:15

Or at least when having the user pass it in as separate forms rather than as an actual map?

hiredman23:06:42

that advice got dropped from the "Library Coding Standards" page recentishly

seancorfield23:06:09

Yeah, I was just looking at that. All it says now about argument destructuring is: “Idiomatic code uses destructuring a lot. However, you should only destructure in the arg list if you want to communicate the substructure as part of the caller contract. Otherwise, destructure in a first-line let. Example: my snake code from the book fails this test, doing too much destructuring in arg lists.”

hiredman23:06:21

oh, right, and it was advice to unroll it

hiredman23:06:04

or something, I dunno, that just reads confusingly the more I look at it

seancorfield23:06:52

I wonder if it was more around the configuration being least variant and therefore coming first (in java.jdbc the options are always the last argument)?

Alex Miller (Clojure team)23:06:12

I removed it because I did not think it was good general advice

Alex Miller (Clojure team)23:06:53

There are times when kwargs are good, times when maps are good, etc

seancorfield23:06:32

That is ringing some bells… there was a discussion about human-facing functions vs composable machine-facing functions, wasn’t there? Was it here or on the mailing list?

eriktjacobsen23:06:26

After writing a lot of production code using unstructured keyword args ie (foo data :key 1 :key 2) I would definitely advise against it, I won't do that again, instead passing an options map as first arg. Too much overhead when trying to restructure args, refactor, applying args from a list, etc

Matthew Davidson (kingmob)23:06:22

Are there any gotchas with using recur in a protocol fn?

Matthew Davidson (kingmob)23:06:24

E.g.

(add-substring [n s]
    (let [[c & cs] s]
      (when c
        (let [i (alpha-idx c)
              child (children i)]
          (when-not child
            (set! children (assoc children i child)))
          (recur child cs)))))
seems like it should work, but I get an error about mismatched num of args for recur

Matthew Davidson (kingmob)23:06:39

(Ignore the set! I’m going for extreme performance here ofr a coding challenge)

Matthew Davidson (kingmob)23:06:26

Basically, it adds a string to a trie, and should recurse on the appropriate child, with the rest of the string…

hiredman23:06:36

yes, you cannot rebind the "this" argument with recur

Matthew Davidson (kingmob)23:06:40

But I get Mismatched argument count to recur, expected: 1 args, got: 2

Matthew Davidson (kingmob)23:06:50

Oh, is that documented anywhere?

hiredman23:06:03

you would need to establish a new recur frame with loop

Matthew Davidson (kingmob)23:06:12

I’m finding the type/record documentation worse than most of CLojure’s docs…

bfabry23:06:14

yeah the recur call you have there could be a different function requiring another whole stack

Matthew Davidson (kingmob)23:06:24

Ahh, because it’s polymorphic?

bfabry23:06:45

that's the first problem I think of yeah

hiredman23:06:29

I am not sure where it is documented, it only exists for protocol/interface methods inline in a record/type

hiredman23:06:03

so the documentation could be with protocols, or with records or types, or some special place for just that overlap

hiredman23:06:31

it is in the docstring for defrecord

hiredman23:06:48

"Note also that recur calls to the method head should not pass the target object, it will be supplied automatically and can not be substituted."