Fork me on GitHub
#clojure
<
2017-03-29
>
shdzzl01:03:24

Is there a preferred, idiomatic way to convert a map to a flat array (ie. [:a 1 :b 2 :c 3])? I can think of about 3 different ways to do it.

shdzzl01:03:33

(flatten (vec my-map), (vec (mapcat identity my-map)), (into [] cat my-map)...

shdzzl01:03:39

Uh, there we go

noisesmith01:03:52

also, flatten is pretty much never the right answer

noisesmith01:03:15

(and problems that really call for flatten are usually a symptom of a design problem elsewhere)

shdzzl01:03:31

You mean flatten the function or, the operation in general I was asking about?

noisesmith01:03:55

specifically flatten

shdzzl01:03:17

Yeah, I was leaning towards cat with into, but I have this niggling memory of having read somewhere that converting maps to vecs with into is not considered idiomatic.

shdzzl01:03:24

Maybe that was just for the trivial case without any additional transformation, or maybe it was just a bad source.

bcbradley01:03:10

how do you set a static field of a java class in clojure using interop?

bcbradley01:03:38

Classname/staticField is how you get it (from https://clojure.org/reference/java_interop)

bcbradley01:03:46

i can't find anything about setting it though

noisesmith01:03:12

haha, anyway ... https://clojure.org/reference/java_interop (set! (. Classname-symbol staticFieldName-symbol) expr)

mars0i02:03:33

@josh.freckleton partial might be slightly helpful. Possibly its distant cousins -> and ->>, too. I think we don't have arity functions like you want because they're easy to write--as you have done.

mars0i02:03:07

not really cousins.

bcbradley04:03:36

is it possible for a function in clojure to do different things based on the types of its arguments, in a general sense?

bcbradley04:03:53

protocols can dispatch on the type of the first argument, i know that

bcbradley04:03:03

and i know you can define functions of multiple arity

bcbradley04:03:17

but what i mean is the general case of different types per argument and different numbers of arguments

bcbradley04:03:07

for instance, if you had a function foo that could take 2 strings, 1 int and 1 string or 1 string and 1 int, and each of these overloads does something different, how would you implement it?

adambrosio07:03:16

bcbradley: not that this is the right way, but basically dispatch by mapping type over your arguments https://github.com/untangled-web/untangled-spec/blob/develop/src/untangled_spec/contains.cljc

qqq04:03:55

(defn foo [a b] (if (== (type a) ... ))

bcbradley04:03:30

hrm, is there a way to do it efficiently? (protocol dispatches on the type of the first arg in constant time, regardless of the number of types)

mars0i04:03:37

Sounds like a job for defmulti and defmethod.

mars0i04:03:53

I don't know about its efficiency, though.

adambrosio07:03:44

@branch14 Looks weird, but dispatching with identity feels wrong in the first place.

adambrosio07:03:41

Why identity, and not say type?

branch1407:03:21

@adambros This is an example. I'm dispatching on identity to keep the the example simple.

adambrosio07:03:09

Sure but you could use the instance from the arguments, and dispatch based on that it's a C

branch1407:03:56

No, because I've different instances of C that I want to dispatch on.

adambrosio07:03:42

Well but surely there's a dispatch for telling them apart

adambrosio07:03:57

Other than equality?

adambrosio07:03:50

Actually that's a weird one, what does it use... What kind of equality is it doing, and are vars/pointers messing that up

branch1407:03:00

That might be, I can try to find one, but that would be a work around for the issue I'm facing, which I haven't fully understood yet. 😉

adambrosio07:03:40

Essentially, you should be able to tell two instances apart, or they'd be the same

adambrosio07:03:16

But I could see cases, like regex, where it's hard to tell if they capture the same strings

matan07:03:20

Hi, a question about package naming conventions and leiningen? I notice that if my project.clj :main definition refers to something like org.my-project.core, then leiningen fails finding my code when I try to run, even if I do have something like the following in my source files: (ns org.my-project.core (:gen-class)) What should I know about the source directories hierarchy in clojure/leiningen project, to get around this? Should the directory structure under src/ strictly mirror the namespaces which I declare?

adambrosio07:03:12

matan: what's the file name, it should have underscores instead of dashes

branch1407:03:23

Yes, which works for records and generally it works for vars declared up front. But it doesn't seem to work for records declared up front.

adambrosio07:03:13

Well so why are you trying to use declare like this... Why isn't there a better dispatch function?

adambrosio07:03:40

@matan lol was that it? You'd be surprised at how many times silly things can get the most experienced developers

adambrosio07:03:53

Wouldn't worry about it

matan07:03:00

@adambros Oh, well I think I nailed it

matan07:03:54

Just trying to fiddle an interleaving of Java → Clojure → Java leiningen compilation here 🙂

adambrosio07:03:55

Ah yeah I've seen co-workers run into nightmare ish issues with that stuff

branch1407:03:08

The reason to use declare and dispatching on record instances are beyond the example. I can find other ways and rewrite the code, but I was hoping that I just missed something.

adambrosio07:03:22

Yeah I just feel it's wrong to declare a thing, dispatch based on identity, and then put an (complicated) object in that var...

adambrosio07:03:51

For all I know, it could be holding on to the value of c when you defined the multi method

adambrosio07:03:12

Thereby causing the problem you are seeing

branch1407:03:41

I see, but wouldn't that be a general problem with dispatching on upfront declared vars?

matan07:03:44

@adambros thanks for the encouragement 😉

matan07:03:25

but it feels mostly "right" when writing a library project that should be used from Java not only from clojure applications

pesterhazy07:03:30

@noisesmith Oh that's annoying, should I catch throwables instead?

matan08:03:30

@adambros thanks it was probably a mixture of uppercase and lowercase naming of source file names (a al Java) and clojure namespaces, close enough to your dash/underscore guess 🙂

xsyn08:03:32

Who maintains http://clojure.org ? There’s a broken link on the swag page (not broken, but it doesn’t direct properly)

chrisetheridge08:03:05

if i run a test with clojure.test/run-tests, if a test fails, does it exit with 0 or 1? the docs don’t really say how it exits

m08:03:50

is there any better we can do to read a properties file into a hashmap:?

(defn props [path] 
     (->> (doto (java.util.Properties.)
                 (.load ( path)))
             (map (juxt #(.getKey %) #(.getValue %) ))
             (into {})))

xiongtx16:03:46

This is available in the propertied library: https://github.com/michaelklishin/propertied

mpenet08:03:01

maybe with bean,or maybe not (untested)

pesterhazy08:03:43

@m, seems like a decent solution already

pesterhazy09:03:33

@m, (-> (doto (java.util.Properties.) (.load ( "test.properties"))) pr-str read-string) 😆

pesterhazy09:03:26

oh, or (into {} (doto (java.util.Properties.) (.load ( "test.properties")))) @m ^^

matan09:03:52

So much for sandwiching clojure between Java compilation steps? 🙂 https://github.com/technomancy/leiningen/issues/847#issuecomment-290026580

matan09:03:08

I should probably give up on that..

pesterhazy09:03:56

@m, or (clojure.lang.PersistentHashMap/create (doto (java.util.Properties.) (.load ( "test.properties")))) 🙂

dpsutton12:03:07

is there a way to find all implementations of a protocol?

dpsutton12:03:33

i see in core there's a find-protocol-impl but it lacks documentation

bronsa13:03:19

that's an internal function

bronsa13:03:49

there's really no good way of doing that as classes can implement the underlying protocol interface (e.g. if you implement a protocol inline)

bronsa13:03:13

and that's not visible unless you inspect every loaded class

dpsutton13:03:40

so from a tooling standpoint, this will need to be done from a textual starting point rather than a semantic point and using clojure itself?

bcbradley15:03:47

@tbaldridge I had some time to think about what you said about breaking GL (and other) naming conventions with the lwjgl wrapper i was making, and after carefully considering it I think you are probably right. It'd be a shame to throw away all the work I've done, so maybe I'll make a json file out of the edn I extracted from the lwjgl javadocs and put it somewhere on a forum for people who might be interested in having it.

qqq16:03:04

what is the simplest way in clojure to get a list of all fonts I can use ?

noisesmith16:03:27

@qqq (into [] (.getAvailableFontFamilyNames (java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment)))

noisesmith16:03:03

the into call just gives you something that’s readable in the repl in its printed form, if you plan on iterating on the result the into call is not needed

qqq16:03:47

@noisesmith : thanks! I didn't realize getLocalGraphicsEnvironment was a static member function, which threw me off

poverholt17:03:15

I can fix the "Unable to resolve symbol: POne" by adding "(:import (rec_test2.protocols POne)" in ns function, but then I get ClassNotFoundException: rec_test2.protocols.POne. I tried requiring the namespace in various ways, and compiling the protocols file first, but nothing has helped yet. Any ideas would be appreciated.

mars0i17:03:10

In your Leiningen project.clj, specify that you want to AOT-compile this file using the :aot option. I think that something like that will help.

mars0i17:03:46

(Or maybe I'm not thinking it through properly.)

noisesmith17:03:01

@poverholt be sure that you require the other ns too

noisesmith17:03:05

just the import doesn’t suffice

noisesmith17:03:16

and no, this doesn’t need aot

poverholt17:03:36

Those are the areas I am trying. No luck yet. :aot did not help. I have both the require for the ns and import for the protocol symbol itself. No luck there either. Do I need the gen-class in the protocol's namespace?

noisesmith17:03:31

no, you don’t need gen-class

noisesmith17:03:52

can you share the code for the namespace that attempts to use POne?

yonatanel17:03:47

Any best practices for Component/Integrant, like where to define the components and how to name integrant keys?

laujensen17:03:45

Does the clojure.core.cache/ttl actually evict values and drop them from memory ones the ttl expires, or does it simply respin once queried?

noisesmith17:03:23

laujensen it doesn’t even know how to mutate your store (I use it with an immutable cache object, and use the cache function to swap! it)

noisesmith17:03:45

it can’t evict until a query happens (unless you have a timer running to swap! on it periodically I guess…)

noisesmith17:03:18

@poverholt minimal working example

justin@S: /tmp/proto-example$ cat src/example/a.clj
(ns example.a)

(defprotocol Aproto
  (foo [this])
  (bar [this]))
justin@S: /tmp/proto-example$ cat src/example/b.clj
(ns example.b
  (:require [example.a :as a]))

(defrecord Brecord []
  a/Aproto
  (foo [this] :one)
  (bar [this] :two))

justin@S: /tmp/proto-example$
justin@S: /tmp/proto-example$ cat src/example/c.clj
(ns example.c
  (:require [example.a :as a]
            [example.b :as b]))

(defn -main
  [& args]
  (println (a/foo (b/->Brecord))))
justin@S: /tmp/proto-example$ java -cp ~/bin/clojure.jar:src clojure.main -m example.c
:one

noisesmith17:03:30

literally wrote and ran this just now

noisesmith17:03:26

@poverholt lines 21 and 22 in test2.core need to namespace qualify the method calls

noisesmith17:03:29

and you don’t need to use import

poverholt18:03:08

@noisesmith It works! Thank you. The primary problem was NoClassFoundException and removing all gen-class seems to have fixed that. In the end, our team will compile all code, but that is a problem for another day. Thanks again.

noisesmith18:03:51

@poverholt why are you compiling the code?

noisesmith18:03:01

there’s valid reasons to never do so, is why I ask

poverholt18:03:43

@noisesmith We have never deployed source code and I expect we would have to jump through hoops with our lawyers before we could do so. It's not impossible, just not likely. What are the concerns?

noisesmith18:03:19

aot tends to break things in unpredictable ways, protocols in particular

noisesmith18:03:04

it’s manageable (especially with the help of stuartsierra/component and clojure.tools.namespace/refresh) - but it’s a big hassle and it’s nice to avoid it altogether if you can

noisesmith18:03:33

but if you have a reason to not deploy source, that makes sense

noisesmith18:03:52

one nice trick for aot on deploy but never having it break things during dev (which is when it really tends to be a hassle), is to create a shim namespace that only uses clojure.core, and none of your other code. Inside that namespace (which uses gen-class) you have a -main that calls require at runtime and then uses resolve to find your real main and run it

poverholt18:03:58

@noisesmith Thanks. I'll check out the links.

noisesmith18:03:41

as long as you never use the shim namespace during dev (and you don’t need to) you can avoid a lot of the aot related dev time problems

ag20:03:45

is there a better/more composable way of saying: “if function applied to a value returns true, return the value, otherwise nil”? Having to wrap whole thing in a lambda doesn’t look great, e.g: (#(if (.isValid %) %)), you can use this in threading macros and with comp but I’m wondering if there’s nicer way?

ag20:03:56

I’m looking for minimal, readable/concise construct

liamd20:03:02

i need to connect to a redshfit database and I’d like to use HugSQL, what should my db map look like?

nathanmarz20:03:39

@ag with specter it's just (select-first some-pred? some-val)

ag20:03:19

@nathanmarz nice, but we’re not using specter yet (not in all our projects)

jr20:03:49

(defmacro keep-when [x & preds] `(when (and ~@(map (fn [pred] `(~pred ~x)) preds)) ~x))

shdzzl20:03:09

@ag some-fn ? Returns false, is that important?

ag20:03:18

@shdzzl I need to return the value itself, e.g. identity

shdzzl20:03:26

Returns nil actually.

bja20:03:31

do you need the result of the computation or the value?

bja20:03:41

i.e. (foo f x) do you want (f x) or x?

shdzzl20:03:16

Misunderstood, my bad.

xiongtx20:03:32

x, not (f x)

ag20:03:38

@bja if (f x) is true, return x

noisesmith20:03:14

(and (f x) x)

bja20:03:40

(and (true? (f x)) x)?

noisesmith20:03:43

(when (f x) x) ; if you prefer nil to false

noisesmith20:03:00

oh, if the literal value true is important, yeah

noisesmith20:03:40

(when (true? (f x)) x) - if you need nil if not literally a true

bja20:03:19

(defmacro when-pred [f x] `(let [y# (~f ~x)] (when (true? y#) ~x)))

noisesmith21:03:14

just curious, why is this a macro?

bja14:03:34

otherwise method invocations would need to be wrapped in an anonymous function or memfn. Consider the function-based definition:

(defn when-pred-fn [f x] (when (true? (f x)) x))
(when-pred .isEmpty "a")
to
(when-pred-fn .isEmpty "a")
In the when-pred-fn case, it'll throw, and you'll need to say something like:
(when-pred-fn #(.isEmpty %) "a")
or
(when-pred-fn (memfn isEmpty) "a")

bja20:03:29

I thought I saw something very similar to this in a utility library once upon a time

ag20:03:17

sigh. I just want to do something like this:

(some-> v js/moment (#(when (.isValid %) %))
it’s clojurescript (but that’s irrelevant). I thought there’s nicer way, but seems lambda is unavoidable

ag20:03:13

@mobileink how’s that different? You still need lambda

quaeledyn20:03:53

Why can't you just use filter?

ag21:03:27

@quaeledyn filter complicates it even more - you can’t “filter” single value - have to wrap it in a list, then return very first value

noisesmith21:03:39

though (comp first (partial filter f) list) has a certain point-free charm, as a definition

ag21:03:02

I think it just makes sense to have fn like this:

(defn some-val
 [val pred-fn]
 (when (pred-fn val) val))

ag21:03:15

and just use it

ag21:03:23

¯\(ツ)/¯

bja21:03:00

@ag the definition of when-pred I provided basically is some-val as a macro. It doesn't need to be a macro I guess.

bja21:03:32

(some->> v js/moment (when-pred (memfn isValid)))

bja21:03:46

I don't think you'll really get around memfn though, unless you build in support for it

bja21:03:14

(or use a lambda instead of memfn)

noisesmith21:03:21

oh - a method call is a reason to use a macro maybe

bja21:03:04

you could definitely take something passed as a "function", determine if it's a symbol, and if it is, and it starts with a period, interpret that as an interop call

bja21:03:24

which would be a valid way to use a macro, although probably a bit too magical for my personal taste

bja21:03:27

such that this would work (when-pred .isValid x) => (when (true? (.isValid x)) x)

bja21:03:27

theoretically .isEmpty works without doing that detection, but I didn't try it

ag21:03:46

btw. can someone tell me is there equivalent in clojure of Haskell’s flip? Function that flips first two arguments?

quaeledyn22:03:26

(defn flip [v] (flatten ((juxt second first nnext) v)))

adambrosio23:03:03

that’s not haskell’s flip @quaeledyn I’ve used this:

(defn flip [f]
  (fn
    ([] (f))
    ([x] (f x))
    ([x y] (f y x))
    ([x y z] (f z y x))
    ([a b c d] (f d c b a))
    ([a b c d & rst]
     ((comp (partial apply f)
            #(concat % [d c b a])
            reverse)
       rst))))
but most of that is just to be faster at smaller arities, essentially the code is just (defn flip [f] (fn [& args] ((comp (partial apply f) reverse) args)))

adambrosio23:03:52

although it looks like im fudging the definition of “haskell’s flip” by supporting more than flip :: (a -> b -> c) -> b -> a -> c

adambrosio23:03:01

potentially where i “borrowed” this from: https://gist.github.com/micmarsh/bcbe19c9de8bb7a471bf

quaeledyn23:03:21

I think I get it, so given a function, if it takes two or more arguments, return an equivalent function where the first two are swapped? so (f [a b]) -> (f [b a])?

rplevy00:03:09

(defmacro flop
  "create a version of a function with a modified arity as specified by a
   vector of zero-indexed positions, e.g. [0 3 1 2]"
  [f positions]
  (let [syms (vec (repeatedly (count positions) gensym))]
    `(fn [~@syms] (~f ~@(map syms positions)))))

rplevy00:03:57

I wrote that in 2012 but I don't see any reason it wouldn't still work.

quaeledyn00:03:07

I think this should work, though I haven't tested:

(defn flip [f]
  (fn [& args] 
    (->> ((juxt second first nnext) args)
         flatten 
         (filter identity)
         (apply f))))

quaeledyn00:03:56

Tested now:

user=> ((flip -) 6 9)
3
user=> ((flip -) 6 9 2)
1
user=> ((flip -) 6 9 2 1)
0

quaeledyn21:03:10

How about (as-> x (if (. isValid x) x))?

quaeledyn21:03:04

e.g.

(some-> 1 (as-> n (if (even? n) n)))
nil
(some-> 2 (as-> n (if (even? n) n)))
2

mobileink21:03:10

(.isValid x) cannot return x if true?

quaeledyn21:03:46

(I don't know what .isvalid is, so I'm guessing at your actual use case)

ag21:03:35

@quaeledyn oh, yeah, I guess I forgot about as->

quaeledyn21:03:56

I'd prefer an anonymous function myself, but each their own I guess 🙂

mobileink21:03:16

defmacro ->?, passing the output of expressions but the input of predicates that eval true?

quaeledyn21:03:06

If you look at what gets done to make as-> work I can't imagine why you'd want to use it for this (presumably) simple case

mobileink21:03:31

not much difference between using as-> and a lambda, no?