Fork me on GitHub
#clojure
<
2016-04-19
>
dpsutton03:04:42

re a macro taking multiple arguments from before, i'm not sure if you solved your issue but i ran across a neat way to handle it inside of zach tellman's primitive arithmetic library. Here, he's jacking with the standard addition, subtraction, etc, and making it a macro call. you can see that if name was + here, it would turn into (+ (+ arg1 arg2) arg3 arg4) => (+ (+ (+ arg1 arg2) arg3) arg4) by calling the macro repeatedly. nice implemntation here

slester06:04:16

I can't seem to get compojure to grab all URLs at once, is that possible? I want all routes that don't match the previous ones to go to the SPA

hiredman06:04:18

what have you tried?

hiredman06:04:51

a (ALL ....) at the end should do it, or just put your ring handler for the spa at the end

slester06:04:54

well, (GET "*" request handler) is too greedy as it matches clojurescript's required base.js and such files, which I can't figure out how to move

hiredman06:04:38

oh, are you serving that up using some middleware?

hiredman06:04:29

e.g. if middleware is trapping requests that 404 on the routes, any catch all route you create is going to interfere with the middleware

slester06:04:00

hmm, something is making it write out js/compiled/out/goog/base.js but I'm too much of a newb to figure out where that particular bit is coming from

hiredman06:04:46

well, the writing out doesn't matter, right?

hiredman06:04:59

the issue is, you have web requests for it, right?

slester06:04:43

it's writing it out in a different directory than my resources are listening for it

hiredman06:04:29

ok, so that has nothing to do with a wildcard route, then

slester06:04:10

it does 😞 but I'm just bad at explaining it I guess

slester06:04:28

never mind! thanks for the help.

slester06:04:26

do I need to do anything to make lein 2.6.1 + Java 1.8 + clojure 1.8.0 see .cljc files besides adding it to :source-paths in project.clj?

slester06:04:50

I'll ask in #C0AB48493 since it's probably an issue there.

daan09:04:12

Hi everyone! I have a question about some Clojure execution details. Yesterday me and a colleague were interviewing a candidate who made an interesting remark. He said that in the following form, expression-1 and expression-2 are not guaranteed to be executed in that order.

(defn my-func []
    (expression-1)
    (expression-2))
I cannot find support for this notion anywhere in the Clojure documentation. In fact, it says here: https://en.wikibooks.org/wiki/Learning_Clojure/Special_Forms about do: > (We typically don't use do very frequently because a function body is effectively an implicit do that usually meets our needs.) So what are your thoughts? Is the candidate wrong in this, or am I missing something?

mpenet09:04:26

he's wrong

hans09:04:41

@daan: I think they're wrong, as the compiler cannot determine whether (expression-1) has any side effects.

pastafari10:04:38

@daan: what does ‘executed’ mean simple_smile

moizsj11:04:26

Can someone suggest a Clojure websocket client that supports the 'permessage-deflate' extension? By support I dont mean just configuring it in the handshake, but also performing the actual compression/decompression. I have tried gniazdo, aleph, and http.async.client already

jimmy11:04:55

@moizsj: didn't know about it ? Does it help alot ?

moizsj11:04:54

@nxqd: you mean permessage-deflate? yes it definitely helps. I need this for a test tool so I can benchmark my websocket server with this extension enabled

nberger11:04:08

@moizsj: it seems sente doesn't support it either, but this discussion might be relevant: https://github.com/ptaoussanis/sente/issues/72

daan11:04:53

@pastafari: executed has a pretty clear meaning right? simple_smile

pastafari11:04:28

@daan: what if expression-1 looked like this (future ginormous-db-scan) and expression-2 looked like {:status 202, :url ‘…’}

daan11:04:52

ah sorry for the confusion

daan11:04:29

obviously I'm not talking about expressions that in themselves are inherently asynchronous for some reason, and therefor cannot be reasoned about as far as ordering goes 😉

daan11:04:50

I'm talking about normal synchronous execution flow

pastafari11:04:07

@daan: ok then, im out of counter-examples 😉

daan11:04:33

hahaha ok good to know 😉

pastafari11:04:42

@daan: but imo executed does not have a clear meaning.

daan11:04:10

> put (a plan, order, or course of action) into effect.

pastafari11:04:25

@daan that is a runtime construct.

daan11:04:27

I think it's a pretty clear definition, even with regards to futures etc.

pastafari11:04:48

@daan agreed, but as you said, we can’t reason about ordering.

daan11:04:51

the future is put into effect, regardless of how long it takes. The future is "scheduled" at that point

daan11:04:04

not if any form of async code is involved, true.

pastafari11:04:08

@daan: so i guess im being pedantic

pastafari11:04:22

i know what you mean.

daan11:04:57

But from a language standpoint, like, how does the compiler translate the code, and how does the JVM interpret that bytecode, you can safely say that expression-1 is "put into effect" before expression-2

pastafari11:04:44

@daan: we are in agreement there!

daan11:04:01

as they say in dutch: "top!"

alexmiller12:04:16

@daan: the reader reads an expression into Clojure data. If the thing in function position is a function (not a macro), then the arguments are evaluated and the function is invoked.

daan13:04:09

thanks for the clarification @alexmiller

andrewzhurov13:04:00

Hi, guys, could somebody help me with example solution of state-space problem on clojure ?

fasiha13:04:05

Didn't realize how using Double/NaN would break deep equality check via =, since (= NaN NaN) ; => false!

bojan.matic13:04:48

yeah, you can’t compare NaN to anything, it’s not equal to itself either 😄

pinkturtle13:04:58

what is NaN?

bojan.matic13:04:26

but check this

bojan.matic13:04:31

> typeof NaN
'number'

pinkturtle13:04:44

its like an uncertain number

bojan.matic13:04:24

this should be in #C03S1L9DN

pinkturtle13:04:56

why? is there no NaN in clojure?

pinkturtle13:04:07

err, no uncertainty?

bojan.matic13:04:10

i thought NaN is specific to javascript

fasiha13:04:39

NaN is specified in the IEEE-754 floating point spec for float & double

bojan.matic13:04:45

(defn NaN?
  "Test if this number is nan"
  [x]
  ; Nan is the only value for which equality is false
  (false? (== x x)))

pinkturtle13:04:59

sometimes, it would be nice if some random grandmother was returned when i ask for a NaN

bojan.matic13:04:20

scratch that, it might be best to just use Double/isNaN

fasiha13:04:37

I have NaNs deep inside big maps which previously I was comparing with =… time for Plan B

cupello14:04:18

Hi guys! Is there an easy way to merge data in a collection?

xcthulhu14:04:31

(into a b) might be what you want

xcthulhu14:04:44

If a and b are hash-maps this will merge them, if they are vectors this will concatenate them...

xcthulhu14:04:42

If they are lists it's a bit confusing; (into '(1 2 3) '(4 5 6)) ; => (6 5 4 1 2 3)

cupello14:04:53

@xcthulhu: thanks! But I would like something like (merge my-collection-with-hash-maps)...

xcthulhu14:04:06

Okay, you could do (reduce merge my-collection-with-hash-maps) in that case

xcthulhu14:04:04

Assuming my-collection-with-hash-maps looks something like [{:foo :bar} {:baz :bot, :blah 8}]

cupello14:04:08

@xcthulhu: thanks a lot !

cupello14:04:07

@xcthulhu: But would it work with [ {:name range :ranges ({:initial 1234 :end 5678} )} {:name range :ranges ({:initial 4321 :end 8765} )} ] ?

xcthulhu14:04:01

It'll just be {:name range :ranges ({:initial 4321 :end 8765} )}

xcthulhu14:04:22

The first one will get clobbered with the second one

cupello14:04:25

@xcthulhu: hmm... I see... But I want something like [ {:name range :ranges ({:initial 1234 :end 5678} {:initial 4321 :end 8765} )} ] ...

xcthulhu14:04:22

You could try (reduce (partial merge-with #(cond (every? coll? [%1 %2]) (into %1 %2), :else %2)) my-collection-with-hash-maps)

cupello14:04:39

@xcthulhu: Thanks man! It works!!

bitsynthesis15:04:27

hey folks. any alternatives to clojure.java.shell that allow for more bash like experience? i'm trying to execute some docker commands, which would be easiest if i could run "eval $(docker-machine env machine-name)" to set environment vars docker-machine requires. or even to run "export FOO=123" for the same. but clojure.java.shell/sh doesn't support "eval" or "export", even if i call them with "/bin/bash".

bitsynthesis15:04:44

i know about setting environment vars with sh's :env or with-sh-env, but that'll require a lot of string manipulation to reform perfectly good "export" statements.

elarson15:04:33

bitsynthesis: one method I've seen used (generically) is to write a bash script you execute that prints out the envvars that you then read in. at the very least that gets you out of guessing if you've parse the script correctly

bitsynthesis15:04:09

ruby handles this no prob, fwiw simple_smile

bitsynthesis15:04:01

so "docker-machine env machine-name" will give me a file of export statements

bitsynthesis15:04:16

how can i use those statements without converting them to a map for with-sh-env?

elarson15:04:17

bitsynthesis: ah interesting! I'm going to look at what they do

plexus15:04:55

@bitsynthesis: the problem is that to start a subprocess with certain environment variables you would have to set them on the java process before starting the subprocess, people get around this by wrapping their command in a shell. Ruby does the same

plexus15:04:24

managing subprocesses from a JVM can be painful, especially when you want to communicate with the subprocess. That said the JRuby folks have done some great work in jnr-process https://github.com/jnr/jnr-process

bitsynthesis15:04:02

@plexus: so is wrapping my command in a shell an option in clojure? you mean like "bash -c"?

plexus15:04:00

something like that, yeah

moizsj15:04:26

Posting again in the hope of more people seeing this -- Can someone suggest a Clojure websocket client that supports the 'permessage-deflate' extension? By support I dont mean just configuring it in the handshake, but also performing the actual compression/decompression. I have tried gniazdo, aleph, and http.async.client already, and they dont do the job. Thanks! I need it for writing a benchmarking tool for a websocket server of ours.

bitsynthesis15:04:41

thanks @plexus this is interesting, a good lead

eraserhd15:04:40

I have an odd problem: I’ve changed a (:use …) to a (:require [… :refer :all]) in a ns form and it broke a build… but only for clojure 1.5.0.

eraserhd15:04:07

the symbol causing the exception was introduced in 1.6.0, so I can’t figure out why it worked prior.

eraserhd15:04:35

Are there any weird differences between :use and :require … :refer :all?

moizsj17:04:47

@cmcfarlen: was hoping to find a Clojure one

tel18:04:36

If I’d like to use checkout deps in lein for an unreleased project… how can I get that into my depenedencies vector?

tel18:04:55

or do I need to put an alpha release up on clojars?

tel18:04:30

(or somewhere public anyway)

manutter5118:04:42

check out ‘lein install'

manutter5118:04:58

iirc that just installs it to your local .m2 directory so lein can find it

tel18:04:05

oh, nice

bostonaholic18:04:06

@tel: what I do is lein-install a -SNAPSHOT version of a lib I’m working on then depend on that that -SNAPSHOT in my app

tel18:04:10

beautiful, thanks everyone simple_smile

rmuslimov18:04:39

Can you please suggest me the way how can I send huge number of keys to memcached in a fastest way. I've checked spyglass client for memcached it support only set and it’s blocking. Based on that, even if set will take 1ms putting 1M keys will take 1K seconds, which is too long I guess.

rmuslimov18:04:05

Of course, I can create few threads, however it’s still too long

scriptor19:04:34

is it possible to use binding or something like it force alter-var-root to only affect a var within binding's body?

hiredman19:04:58

with-redefs

scriptor19:04:50

got it to work, thanks hiredman

pesterhazy19:04:57

@rmuslimov: I'm sure you can use any java-based memcache clinet easily

rmuslimov19:04:11

@pesterhazy: Sorry for newbie question, do you think will need any java code in my project, or just clojure-java interop will be enough?

d-side19:04:10

@rmuslimov interop should be enough most of the time, you'll sometimes need knowledge of inner Java workings though. Like overloads needing static type hints, generics having no real arguments and such.

d-side19:04:56

//not sure if I'm speaking sense, I'm new here as well

pesterhazy19:04:56

@rmuslimov: you never need actually java code (java libraries are more easily used from clojure than from java)

rmuslimov19:04:36

@d-side: @pesterhazy Thanks, for explanation - I will try. I’ve took a look to that spyglass code which has some java code inside, and that’s why i’ve asked. Btw, great, hope it will work!

pesterhazy19:04:36

@rmuslimov: easy of integrating java libs is clojure's strength

borkdude20:04:15

It seems clojure.java.api.Clojure.read("foo") and clojure.java.api.Clojure.read("'foo") both return a Symbol. What is the reasoning behind it?

borkdude20:04:45

for example clojure.java.api.Clojure.read("false") returns a Boolean and not a Symbol

hiredman20:04:44

it is exactly read

hiredman20:04:12

in clojure source code false is the boolean false, and foo is the symbol foo

hiredman20:04:43

read("(+ 1 2)") wil return a list, the first element of which is the symbol +

numberq20:04:42

I'm having some trouble with JSON and PSQL. Essentially what I'm doing is encoding a clojure map into JSON with clojure.data.json, then using jdbc/insert! to put it into a database. That part works fine. The thing I need advice on is when I query it at a later date. Some of the keys in my map have ? in them, which I didn't realize at the time would count as parameterized query. Now my code is littered with references to this ? key. My question is, can I somehow escape all instances of ? in my JSON database entry (not necessarily in the database itself, but for future inserts), or is my best bet to go through and remove all the ? from my code?

bvulpes21:04:20

numberq: you really want to go clean that up.

bvulpes21:04:43

also let me know how the pg json querying works for you

bvulpes21:04:02

when i want to store clojure data structures i default to datomic instead of serializing them to json

bvulpes21:04:15

json serialization is all sorts of lossy, does not preserve type semantics etc.

bvulpes21:04:44

i personally would go so far as to actually write a sql schema if i were going to use postgres.

cnilliams21:04:06

hello, how do I create an issue/pull-request for a specific docs page (and my subtle implication is why is there no link to the source on the docs page)? Example: http://clojure.org/reference/atoms

mikekap21:04:35

hey guys i have a qq about AOT compilation. I’m experimenting with AOT compiling incrementally. In this scenario I’m compiling clojure/tools.logging and then compiling clojure/java.data with the output from tools.logging in the classpath. Everything is fine there so far, but compiling java.data produces a few files like clojure/tools/logging$eval32.class, even though I AOT compiled every single file in tools.logging. This is currently exclusive to tools.logging and prismatic/schema. Is this a bug or intentional?

bvulpes21:04:15

cnilliams: your editor doesn't have jump-to-definition wired up?

cnilliams21:04:17

@borkdude In a sense but not really, why isn't there a link to the page on github? I have to read all that before I can suggest the example is poor?

cnilliams21:04:51

My editor is my face, I don't write clojure. I just want to understand atoms simple_smile

borkdude21:04:31

@cnilliams: anyway, we can help you understand atoms here, but it doesn't take way the problem you noticed in the docs

cnilliams21:04:09

No worries, I appreciate the offer. I will read the big long contributing guidelines in the morning simple_smile

cnilliams21:04:05

(However I can't help feeling like a trick has been missed here).

hiredman21:04:09

mikekap: the answer to ever aot question is pretty much: don't aot

borkdude21:04:32

@cnilliams: I'm looking at the docs and it surely doesn't read as a gentle tutorial. It is terse.

cnilliams21:04:54

Yeah .. the fibonacci example, really?

hiredman21:04:09

mikekap: it is hard to say why additional class files are showing up without looking at your exact setup, but there are definitely reasons they do

cnilliams21:04:35

Anyway, thanks @borkdude, bye!

borkdude21:04:38

@cnilliams: well, atoms are mutable references that you can change with swap! if you want to use the old value and reset! when the old value isn't important. The change happens synchronously. Atoms are implemented using Java's AtomicReference.

hiredman21:04:39

aot compiling is asking to spend time fighting with all kinds of weird bugs

mikekap21:04:48

@hiredman: well the files aren’t bad per se, the issue is that they sometimes collide (if you AOT from different processes)

hiredman21:04:36

they will be bad at some point, and you will spend a day trying to figure out why your build doesn't work

mikekap21:04:56

so is there a way to enable direct linking without AOT?

hiredman21:04:37

the only place you should aot, if you are going to aot, is at the very end of your build pipeline, if you are produce some kind of application (never if you are produce a library)

mikekap21:04:52

correct, this is what i am doing

hiredman21:04:13

are you sure, you said you were incrementally aot compiling

mikekap21:04:16

except it takes like 2 minutes right now, so I thought by AOT compiling the third party deps I can cut down on the time

hiredman21:04:38

direct linking happens with or without aot compilation

hiredman21:04:25

what is your end goal? do you care about direct linking? or do you really just care about startup time?

cnilliams21:04:46

I appreciate the explanation @borkdude, will save til I'm in a clearer frame of mind. Unfortunately your explanation requires a lot of context too, so I will have to get back into Clojure mode to

cnilliams21:04:19

... (ugh accidental submit) ... grasp simple_smile

cnilliams21:04:55

Anyway, will lurk, ta.

hiredman21:04:55

do you care about compile times?

mikekap21:04:57

@hiredman: execution time - at the end of the day this is making an uberjar for a web server

mikekap21:04:06

and yes, I definitely care about compile times

hiredman21:04:40

mikekap: ok, aot has nothing to do with performance

mikekap21:04:54

the clojure code gets executed 3-4x in the build pipeline (tests, etc.) so AOT compiling has quite a bit of savings

mikekap21:04:07

to be exact: SOME modules get executed 3-4x; most are 2x (css + test); main is 1x

hiredman21:04:21

depending on how long that is taking, I would be inclined to take the longer build times vs aot

amonks21:04:35

@cnilliams: An atom is a name that can refer to different values over time. Some code can ‘dereference’ the atom, which means to ‘get the value it’s referring to at that time’. Even if the value of the atom changes, that code’s dereferenced value stays the same.

hiredman21:04:19

aot or not won't effect performance in production at all

hiredman21:04:48

adding aot is opening the door to weirdness that steals a day here and there

cnilliams21:04:36

@amonks: okay I'm familiar with dereferencing from C etc. which confirms my thinking that doc page is just pretty bad 😕

cnilliams21:04:28

I still need to read up some more, but thanks!

hiredman21:04:44

to be clear, I am not saying aot is buggy, I am saying the way it interacts with the rest of the language has some odd behaviors that people don't take in to account in their mental model of clojure, so you can end up with weird problems

bvulpes22:04:11

@cnilliams: dude the link to the source is 2 clicks away

bvulpes22:04:19

first you click the "atom" link

bvulpes22:04:26

then you click "source" right underneath wherever that takes you

amonks22:04:41

@bvulpes I think @cnilliams meant the source of the documentation page

amonks22:04:49

could be wrong

cnilliams22:04:00

Yeah that's what I meant

cnilliams22:04:46

e.g. 'this doc page is not helpful, can I offer a suggestion quickly?' (answer appears to be no).

hiredman22:04:06

I think the next stage in coming to understand the badness of aot is asking" ok, well for example what could go wrong?"

bronsa22:04:54

if you're distributing your libraries AOT compiled you're either hitler or clojure.jar

bvulpes22:04:03

> hitler.jar

bvulpes22:04:17

great, next set of project names are going to be famous facists

mikekap22:04:48

i’m not distributing any libraries; though i was hoping to get incremental compilation & faster startup times

hiredman22:04:19

yeah, to be entirely fair, that issue is a result of distributing aot'ed jars as a library, I meant it more as example of the kind of stacktraces you will see, and what it will take to figure out the problem

mikekap22:04:13

yea though the build tool is smart enough to recompile when the clojure version changes (or any other deps for that matter)

bronsa22:04:29

I think most of the actual AOT bugs have been fixed in the past few releases, but that's still not going to save you from the combined effects of AOT and version conflicts

alexmiller22:04:23

@cnilliams: having a link from the site page to the github page is a good idea and very doable. If you file a GitHub issue on clojure-site to remind me, I'd be happy to add that

mikekap22:04:59

part of my hope was to run the clojure code during development, so it’d have to run in < 5s (including booting the jvm)

cnilliams22:04:11

@alexmiller: Awesome, thanks will do!

stuartsierra22:04:21

Even on Clojure 1.8 I encounter issues with AOT-compiled files in development.

bronsa22:04:48

(with CLJ-1874 probably being the only one that could affect reloading)

mikekap22:04:29

I guess the thing I’m seeing is a bug only if you AOT using multiple processes

alexmiller22:04:31

Thanks, I'm moving right now so won't be able to look at it for a few days

cnilliams22:04:12

No worries, I'm just a Clojure lurker, so I won't hold you to anything. I just feel like it will help and appreciate you responding so fast.

mikekap22:04:57

so more concretely, when would I ever want to AOT clojure?

hiredman22:04:28

if you have an app you want to start up faster, aot can help with that, and if you are deploying to certain environments (like some kind of app server) where the app server doesn't let you monkey with classloaders

hiredman22:04:03

if you use gen-class at all you need to aot, but usually that can be avoided

numberq22:04:46

@bvulpes: man, I was hoping not to use datomic :P We tried using it the start of the project and ran into problems, which is why we're using postgres now. I didn't consider that JSON was lossy, but I don't expect that to be a problem since it will only ever be strings and ints in the nested map structure.

mikekap22:04:09

hmm ok; so i guess the suggested config is ^:skip-aot on :main in lein?

hiredman22:04:58

skip-aot is default for :main since some old version of lein

hiredman22:04:20

or just leave out main altogether

hiredman22:04:46

java -jar uberjar.jar clojure.main -m your.namepsace

mikekap22:04:08

cool that works :thumbsup:

bvulpes22:04:12

@numberq: what problems did you have with datomic?!

mikekap22:04:23

though that startup time: 14s

numberq22:04:52

I think we had issues getting it set up properly with Heroku

bvulpes22:04:09

numberq: that is a PITA, yeah.

mikekap22:04:10

heh well i have a cure for that which i might release later :X

bvulpes22:04:22

but hey, i'm looking for alpha testers for my hosted transactor service

bvulpes22:04:51

currently uses dynamodb instead of postgres, although that'll change shortly.

bvulpes22:04:58

also no charge for the alpha period!

mikekap22:04:04

alright well I think I’ll open a jira just in case; though I’ll just work around it for now via disabling AOT

numberq23:04:04

@bvulpes: not sure if that's a good fit for this particular project since we have a close deadline on it, but I'll keep that in mind for future stuff!