Fork me on GitHub
#clojure
<
2016-10-18
>
amacdougall01:10:05

More of a basic question here. I have a grid of {::x int? ::y int? ::exits (spec/coll-of ::direction :type set?)} cells, specced as ::grid/cell. This isn't really a clojure.spec question, but maybe the spec helps? I want to implement Dijkstra's Algorithm to find the shortest path by following exits. Dijkstra assumes an omniscient view of all nodes, which is fine: I can say that the unvisited set is (all-cells grid). But the algorithm is most easily expressed by maintaining a map of the current distance from the origin node to each target node. But a map keyed by keywords or strings does not seem appropriate here. It's more natural to use cells themselves as keys. In a language with a dictionary that allowed arbitrary objects as keys, you would say:

distances = new Dictionary()
distances.set(origin_cell, 0)
remaining_cells = all_cells.without(origin_cell)
remaining_cells.each(cell =>
  distances.set(cell, nil) # initial setup, no known distance
Is there a data type in Clojure that will let me use arbitrary data as keys? Or would I be better of making a simple key function such as (fn [cell] (format "%d,%d" (::x cell) (::y cell)))?

jrheard02:10:46

does clojure not do this?

jrheard02:10:55

have you tried using cells as keys?

jrheard02:10:15

also: working on a game? care to trade github repo links? 😄 always looking to learn from other clj/s gamedevs

jrheard02:10:40

cljs.user=> (defrecord Foo [a b c])
cljs.user/Foo
cljs.user=> {(Foo. 1 2 3) 3}
{#cljs.user.Foo{:a 1, :b 2, :c 3} 3}
cljs.user=> {[1 2] 3}
{[1 2] 3}

jrheard02:10:48

either i’m misunderstanding your question or clojure already does what you want 🙂

jrheard06:10:13

( ^ @amacdougall, fyi when you wake up 🙂 )

baptiste-from-paris09:10:22

hello guys, I have a question ^^. Does someone know how to exactly have the list of possible metadatas for def

jannis09:10:34

Hi folks. What do people do to avoid huge uberjars in deployments? I'd rather not generate 100+ MB jars if I can avoid it. Is excluding specific dependencies a viable option? Is it better to avoid uberjars alltogether?

nikki09:10:56

@jrheard i potentially have livecoding cljs working for ios + android on react-native with opengl bindings, and you can use like http://regl.party for declarative gl http://g.recordit.co/Clb3hsjxtc.gif

yonatanel09:10:13

@triss Found this just now for some general purpose functions including map-vals: https://github.com/weavejester/medley. It also references in its readme some other libs.

anmonteiro10:10:08

@jannis is your uberjar including some classpath weirdness like transitive dependencies that are not used?

jannis10:10:08

@anmonteiro It contains a number of huge packages like com.ibm.icu (37.9MB unpacked), it.unimi.dsi.fastutil (63MB unpacked). I'm not using them in my code but my immediate dependencies might.

anmonteiro10:10:45

hah, right. I don’t have a solution for that, no

sveri10:10:37

Project Jigsaw will be able to reduce the size of generated jars, but it will be available from Java 9 on only and if you can use it with clojure, I dont know at all.

ben-long11:10:45

Hi, hoping someone might be able to help me with an issue I'm having. I need to make an API call but two of the params require a string, so I have 2 strings inside a string, like this: (client/get (format "https://graph.facebook.com/v2.8/act_%s/insights?level=ad&amp;access_token=%s&amp;filtering=[{field:"ad.impressions",operator:"GREATER_THAN",value:0}]&limit=2000&offset=0" "123" "456")) Unfortunately it appears that the " in front of ad.impressions is being treated as the end of the url causing it to throw CompilerException java.lang.ClassNotFoundException: ad.impressions. Is there a way to nest strings?

mpenet11:10:14

add a \ in front of the "

mpenet11:10:25

"foo \" bar"

amacdougall14:10:51

@jrheard : Well I'll be darned.

(let [m {[0 0] :a
         [0 1] :b
         [0 2] :c}]
  (m [0 0]))
Somehow it just never occurred to me to try, since people use maps almost exclusively with keyword or string keys! This may not be everyday Clojure, but it solves my problem precisely.

jannis14:10:12

If I wanted to find all namespaces in a Clojure project that use a specific macro (e.g. deffoo) - how would I best approach that?

amacdougall14:10:36

Seriously not trolling here: grep?

amacdougall14:10:08

If you need to find it as part of a Clojure program, for use in a Clojure program, sure, you might need to be fancier, but if you're just curious, well...

alexmiller14:10:24

if you have programmatic goals, then you could scan all of your source files with tools.reader

alexmiller14:10:37

or I guess even just the regular reader

alexmiller14:10:44

then look for that symbol using walk

jannis14:10:55

@alexmiller Hehe, yeah, grep would not be good enough. tools.reader sounds good. Plus tools.namespace to walk over the files in a source tree?

jannis14:10:05

Cool, I'll give that a shot.

dominicm15:10:45

@robert-stuttaford we're probably way OT for #datomic now.. Not sure about laziness. I imagine the trick is, like tufte, to do the measurement in the inner loop. That way, unless map is slow in itself, you repeatedly measure the inner loop.

dominicm15:10:40

That's how I did it anyway, I got odd results with tufte when surrounding the map directly.

idiomancy17:10:33

Anyone know how to use unprintable unicode characters in clojure strings?

idiomancy17:10:58

Like, I want a string to be, for instance "Hello, \x1D World"

idiomancy17:10:32

thats the character for separation of groups

idiomancy17:10:45

the character I used there to represent it is the character you would use in java regex

idiomancy17:10:21

(re-split #"\x1D") for instance, would split the string on the group character

idiomancy17:10:06

but if I try to just say the string "\x1D" I get:

CompilerException java.lang.RuntimeException: Unsupported escape character: \x

hiredman17:10:34

you can do octal escapes like \101 (which would be A)

hiredman17:10:51

you can do unicode points with \u

hiredman17:10:27

so "Hello, \35 World" would be the ascii group separator

hiredman18:10:16

in theory, at least

idiomancy18:10:41

Huh, so theres no way to do the hex?

idiomancy18:10:06

the oct works, though, thanks hiredman

liamd18:10:32

can someone tell me what’s wrong with this? http://pastebin.com/Cmdpj3WT i feel like i’m either a) missing something incredibly obvious or b) misunderstanding the -> macro

liamd18:10:54

gives me java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector on line 2

jr18:10:02

wrap the last anonymous function in a list

jr18:10:29

so it threads into the operand position of calling the anonymous function

jr18:10:01

user=> (-> 2 #(+ % 1))
CompilerException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.ISeq, compiling:(NO_SOURCE_PATH:20:1)
user=> (-> 2 (#(+ % 1)))
3

mikeb19:10:39

@jannikko it doesn't really fix the large uberjar problem but rsync works quite well for uploading large jars after the initial upload. Also I have also from time to time thought about using docker as a solution, but never tried. You could create a docker image with the large dependencies added to the image before your app jar. Then build a non-uber jar put it in the image and reference the prior deps on the classpath. That should cache the dependencies and should only incur the small app jar changes when the image is pushed a second time. Of course each time you change your set of dependencies, you would need to make sure they got added to the image.

sveri19:10:47

@mikeb @janniko that docker approach you suggest definitly works, I have been something similar already and its one of the selling points of docker.

mikeb19:10:12

Can I ask, how do you gather and copy all the deps into a directory?

sveri19:10:34

you could just run lein uberjar, it will download them once and keep them cached on your server. Leiningen / maven will do that for you.

sveri19:10:44

Then you just update your project and build a new uberjar

sveri19:10:01

there is not even the need for docker in that process

sveri19:10:11

When I come to think about it 😄

sveri19:10:52

Or you copy them from the maven cache somewhere and add them to the classpath when starting the thin jar

sveri19:10:50

But, I am not sure if something like this works for heroku and friends

hiredman19:10:17

there is a lein plugin that generates a tarball of your project, which has directory lib/ which contains all the jars

hiredman19:10:53

lein classpath will give you want lein thinks the classpath for your project is (which may work depending on what you are using this directory for)

liamd19:10:04

i want to make a bunch of http requests in parallel and then wait for them all to be finished and collect their results in a list. what’s the best way of going about this?

liamd19:10:26

ah, i said http requests to make it simple, but it’s actually using the AWS sdk

hans19:10:23

liamd Just a bunch of futures maybe?

liamd19:10:18

so i have a vec of input, then map to a vec of futures, then deref em all?

hans19:10:50

as long as it is not thousands of requests, that should work just fine

liamd19:10:00

yeah it’s like 10-30

hans19:10:10

sounds good.

hiredman19:10:12

pmap is a thing, but it is the worst

liamd19:10:20

i haven’t really messed around with threads, that’s going to spawn that many threads right?

hiredman19:10:49

also, if you are mapping with 'map' be sure to force the seq before derefing

hans19:10:20

@liamd the exact threading behavior is underspecified, but i'd guess yes

sveri19:10:23

I think agents use a thread pool

hiredman19:10:45

there are two agent thread pools, and futures use one of them

liamd20:10:16

how do i force the seq?

hiredman20:10:29

doall or use mapv instead of map

liamd20:10:04

this is my first naive try:

(defn get-all-configuration-settings [environments]
  "Gets all config settings in parallel"
  (->> environments
       (mapv #(future (describe-environments %)))
       (mapv (fn [x] @x))))

liamd20:10:12

where describe-environments is the long call

liamd20:10:25

seem right?

hans20:10:35

(fn [x] @x) is better written as deref

hans20:10:47

other than that, looks good.

liamd20:10:41

to force it using mapv which map is important? the deref one or the one creating the futures?

hiredman20:10:09

mapv doesn't need to be forced

liamd20:10:21

to force the seq i mean

hiredman20:10:28

vectors are not seqs

hiredman20:10:33

mapv produces a vector

liamd20:10:48

a seq is anything that implements ISeq right?

liamd20:10:51

vecs don’t?

hiredman20:10:22

user=> (supers (type []))
#{java.util.Collection clojure.lang.IPersistentStack clojure.lang.Reversible clojure.lang.APersistentVector clojure.lang.Sequential java.util.RandomAccess clojure.lang.Associative clojure.lang.IReduce clojure.lang.IEditableCollection clojure.lang.IPersistentCollection clojure.lang.IPersistentVector java.util.List clojure.lang.AFn clojure.lang.IKVReduce clojure.lang.Counted clojure.lang.Seqable clojure.lang.IFn clojure.lang.IReduceInit clojure.lang.IHashEq clojure.lang.Indexed java.lang.Iterable clojure.lang.ILookup clojure.lang.IMeta java.lang.Comparable java.io.Serializable java.util.concurrent.Callable clojure.lang.IObj java.lang.Runnable java.lang.Object}
user=> 

hiredman20:10:56

things that operate on seqs tend to call seq on their arguments before hand

hiredman20:10:39

and seqs can be lazy, but noting else is (baring user created what evers)

alexmiller20:10:19

vectors are seq-able

alexmiller20:10:33

that is, they can produce a sequence view when asked

idiomancy20:10:11

anyone know how to properly compare strings for equality when they contain unicode?

liamd20:10:26

i currently run my webapp using lein ring headless but i’m pretty sure i need a core namespace for deploying to heroku and packaging a jar and all that? any idea?

hiredman20:10:09

lein ring has a few built in options

hiredman20:10:16

well, two I guess

hiredman20:10:48

1. it generate an uberwar, a war file being a common format for java app servers and you can use tools like jetty-runner to run it standalone

hiredman20:10:14

2. lein ring uberjar will generate an uberjar that will launch a jetty server serving your app

hiredman20:10:24

those will both base their configuration on the same configration that lein ring headless uses, so if lein ring headless works, either of those should launch your app fine

kwladyka20:10:24

I don’t get ex-info when doing deftest from code like (throw (ex-info "Invalid input for label" (s/explain-data ::sl/label-main product))) i get only https://www.refheap.com/c34d52b669b6a34e7a5a04364 . What can i do to get ex-info data during tests from exception?

hiredman20:10:46

I am not sure which of those options is applicable to heroku

codefinger20:10:16

@liamd i’d recommend uberjar for heroku. heroku will run lein uberjar by default (not sure if that results in lein ring uberjar in your app)

codefinger20:10:37

otherwise, you can heroku config:set LEIN_BUILD_TASK=“ring uberjar”

liamd20:10:52

yeah the compojure app template doesn’t have that so i’m trying to add it in

liamd20:10:38

i added a core namespace with:

(defn -main []
  (run-jetty app))

liamd20:10:34

gives me uhhh: Caused by: java.lang.UnsupportedOperationException: nth not supported on this type: Symbol

liamd21:10:38

seems to be some sort of issue with my project.clj

hiredman21:10:57

the stacktrace will tell you

liamd21:10:21

yeah it wasn’t giving me a linenumber but there was accidentally some garbage in there

kpsf21:10:41

what is the more updated/used source of Clojure documentation, http://clojuredocs.org, http://clojure.org, others? I ask because I’m on http://clojuredocs.org and I see some examples missing and I’m wondering if I should add them (in this case for clojure.zip).

reefersleep21:10:19

Speaking for just myself, I always go to clojuredocs. As far back as I can recall, it has had explanatory examples for all of my needs. But I've no idea if there's actually a better source, I haven't felt the need or itch to pursue it 🙂

jrheard21:10:27

(add ‘em!)

hiredman21:10:16

http://clojuredocs.org is more or less a crowd sourced site, unless something has changed it is not run by the same entity that runs http://clojure.org