#clojure log - Sep 02 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:38 ddellacosta: is there a simple way to cleanly include utility functions in project.clj other than simply pasting them in at the top of the file?

0:39 load-file has problems when used in context with other stuff, unfortunately

0:39 I would even be happy to use "declare" at the top but that doesn't work

2:13 Empperi: http://blog.getprismatic.com/schema-1-0-released/

2:35 crocket: Why does (swap! server (fn [x & rest])) cause clojure to say "Unable to resolve symbol: x in this context"?

2:35 I just set the atom to null.

2:35 I just want to set the atom to null.

2:36 opqdonut: the fn needs a body I guess

2:36 hmm, it seems you can skip the body

2:36 crocket: It doesn't need a body.

2:36 opqdonut: btw, why not (reset! server nil)

2:36 crocket: ouch

2:37 opqdonut: anyway, that snippet works for me, are you sure you don't have a non-breaking space in there or something like that

2:37 crocket: I use clojure 1.7

2:37 opqdonut: oh right

2:38 I was actually on 1.5 just now

2:38 crocket: What did rich hickey do?

2:38 Now, it's doing something that I don't understand.

2:38 (swap! server (fn [x & rest])) doesn't compile

2:50 Empperi: you're missing function body

2:50 (swap! server (fn [x & rest] nil))

2:50 will compile

3:17 crocket: Empperi, It seems that if I (swap! server (fn [x & rest] nil)) in a when-let form, clojure says "Unable to resolve symbol: x"

3:17 If I put (swap! server (fn [x & rest] nil)) in a when-let form, clojure says "Unable to resolve symbol: x"

3:21 TEttinger: crocket: I'm guessing somewhere a paren isn't lined up

3:21 Empperi: yeah

3:21 got to be that

3:22 TEttinger: also, (constantly nil)

3:22 ,(swap! (atom 0) (constantly nil))

3:23 clojurebot: nil

3:23 TEttinger: or just

3:23 ,(reset! (atom 0) nil)

3:23 clojurebot: nil

3:26 crocket: TEttinger, impossible

3:26 TEttinger: ,(swap! (atom 0) (fn [x & rest] nil))

3:26 clojurebot: nil

3:26 crocket: Now, put that in a when-let form.

3:26 TEttinger: (doc when-let)

3:26 clojurebot: "([bindings & body]); bindings => binding-form test When test is true, evaluates body with binding-form bound to the value of test"

3:27 crocket: ,(when-let [ohayo true] (swap! (atom 0) (fn [x & rest] nil)))

3:27 clojurebot: nil

3:27 TEttinger: ,(when-let [server (atom 0)] (swap! server (fn [x & rest] nil)))

3:27 clojurebot: nil

3:27 crocket: weird

3:27 ,(version)

3:27 clojurebot: #error {\n :cause "Unable to resolve symbol: version in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: version in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: version i...

3:27 TEttinger: something got screwed up in your REPL I imagine

3:28 ,*clojure-version*

3:28 clojurebot: {:major 1, :minor 8, :incremental 0, :qualifier "alpha3"}

3:28 TEttinger: &*clojure-version*

3:28 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

3:28 TEttinger: &(when-let [server (atom 0)] (swap! server (fn [x & rest] nil)))

3:28 lazybot: ⇒ nil

3:28 TEttinger: in 1.7 and 1.8 alpha3, it is the same behavior. it is not a clojure bug

3:28 crocket: TEttinger, The problematic code is http://dpaste.com/3F22TJ7

3:29 TEttinger: ha

3:29 you used fn for the name

3:29 luma: you're overwriting fn

3:29 crocket: Hell

3:29 luma: so your (fn [x & rest]) isn't a function

3:29 it's not the fn macro

3:29 crocket: Now, it compiles.

3:29 How did I not catch it?

3:30 TEttinger: why did you use fn for a name in the first place?

3:30 crocket: I was trying to write it fast.

3:30 TEttinger: well that's a mistake that you won't make again, I bet :)

3:30 crocket: I thought @server evaluated to a function before.

3:31 TEttinger: it might

3:32 but the binding is a name, so you would have a local (with the value of whatever @server is) called fn, and since it can't be a macro, anything that passes it [x & rest] will evaluate x

3:32 crocket: ok

3:33 I didn't think twice about the name.

3:33 TEttinger: I feel like eastwood might catch that automatically

3:34 seems like something a linter might catch quickly

3:34 (especially if you have a much more complicated function that #clojure can't make sense of easily but a linter might)

4:58 neoncontrails: Any former Schemers here? Is alter just set!, or is it different somehow?

4:58 The 'transaction' component throws me off a little bit.

5:01 amalloy: it is super different

5:01 neoncontrails: I had a hunch.

5:02 amalloy: you can't just set! any old thing. most values and bindings are immutable

5:02 instead of figuring out alter, try figuring out swap!, which is much more common and also simpler

5:02 neoncontrails: Are we talking Scheme or Clojure? You must mean Clojure.

5:03 amalloy: of course

5:04 neoncontrails: Interesting. Let me see if I'm putting the pieces together correctly...

5:05 In Scheme, mutation is accomplished either by changing the atomic value (if the variable is an atomic type) or else by changing the evaluation environment

5:05 In Clojure, mutation is... kind of a switcheroo, followed by garbage collection?

5:06 amalloy: mutation is mostly not done

5:06 but in the particular case of objects which exist for the purpose of being mutable cells pointing to other immutable data, such as (atom 0)

5:07 then we have functions that let you compute the new value for the mutable cell to point to, based on the old value

5:07 neoncontrails: oh wow. I'm going to need a second to process this

5:10 I think this is starting to explain some things I was obliquely confused about last week

5:14 So if I'm understanding you right, atoms can't arbitrarily be made to point at an anonymous function (a self-incrementing counter, for instance) because....

5:15 The main difference with Scheme being the result of applying functions to objects are computed in an even lazier fashion?

5:15 amalloy: no, i think everything you just said is false

5:15 well

5:16 some confusion may arise from your use of the word "atom", which means different things in scheme and clojure

5:16 neoncontrails: i'm definitely wording it quite badly, in either case

5:16 Huh. What's the difference?

5:16 Scheme defines it as not a list

5:17 amalloy: yeah, well clojure has more than one data structure so that is not a very useful definition

5:17 neoncontrails: which clearly isn't expressive enough for a Clojure definition

5:17 Haha, yes

5:17 amalloy: clojure doesn't really have a synonym for the scheme concept of atom. there's just "values"

5:17 instead, an atom is

5:17 ,(doc atom)

5:17 clojurebot: "([x] [x & options]); Creates and returns an Atom with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn If metadata-map is supplied, it will become the metadata on the atom. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the v...

5:18 amalloy: a box that holds a single pointer to some value, and can be made to change that pointer to some other value

5:19 neoncontrails: I see. So it's not in any sense structurally a pair

5:19 amalloy: ,(let [x 1, a (atom x)] (do (swap! a + 5) {:x x, :a @a}))

5:19 neoncontrails: it's just a name with a pointer

5:19 clojurebot: {:x 1, :a 6}

5:19 amalloy: not even a name

5:19 it is just a value, like the number 1

5:20 in my example here, in that particular lexical environment a is bound to an atom, but that's in the environment: the atom itself has no name

5:20 ,(swap! (atom 5) + 10)

5:20 clojurebot: 15

5:21 neoncontrails: So an atom with a name is not an atom then? But an 'object'?

5:21 (what's more correct than object in this context?(

5:21 amalloy: object is fine

5:22 neoncontrails: Closure?

5:22 amalloy: but there is no such thing as an atom with a name. there are objects, including as one special case atoms. and there are names for things, in a lexical environment or the global environment

5:23 neoncontrails: what is the name of the list (1 5 8)?

5:23 neoncontrails: I don't suppose that it has one, does it?

5:23 amalloy: it doesn't have one, of course. you might choose, in some context, to create a name for the purpose of referring to it, but the list itself doesn't have a name as some internal property

5:24 this is a fundamental concept of how variables work in clojure, and it's the same as how they work in scheme so i don't understand what you are confused about

5:25 there are values, which don't have names, and then there are lexically-scoped names that refer to those values

5:26 neoncontrails: I'm just trying to get a feel for the similarities and differences, because there's lots of both

5:27 In Scheme atoms are concretely implemented as pairs, in which case a variable and its name share the same scope I think

5:27 Small difference, but it seems like a difference

5:27 amalloy: no, in scheme an atom is literally something that is not a pair

5:28 variables and names are roughly the same thing, but that's very different from a *value*. (let ((x 1)) ...), 1 is a value, x is a variable/name

5:29 neoncontrails: Hmmm... you could be right

5:30 amalloy: you can't talk about a name, or a variable, divorced fom the scope/context in which it's valid. but the number 1 is always going to be 1, whether i call it x or n

5:30 neoncontrails: My university really brow-beat us on the fact that everything that Scheme is ultimately represented as a pair, which in the case of atoms were just a name and a value

5:31 amalloy: wellllllll, in a particular scheme implementation that may be how the interpreter implements the concept of an environment

5:31 neoncontrails: Because in Scheme it's appropriate to call an x defined by (define x 3) an atom

5:32 amalloy: but from the point of view of someone using the language, not implementing it, it's certainly not the case that everything is a pair

5:32 neoncontrails: that's a good point. We used a very particular dialect optimized for object-oriented pedagogy

5:33 yes that's true

5:34 At a high level, how would you summarize the differences between Scheme and Clojure?

5:34 amalloy: uh

5:35 neoncontrails: I mean, differences of JVM and datastructures aside

5:35 amalloy: decline to state

5:35 neoncontrails: There's probably a philosophical difference in there somewhere

5:35 amalloy: a lot of them

5:36 try watching one of rich's introductory videos, like simple made easy, or clojure for lisp programmers

5:36 neoncontrails: I might do that. I've seen him speak before and it left a huge impression on me before I had any idea what he was talking about

5:37 I should revisit them now that I'm a little more experienced

5:40 spacepluk: is anybody familiar with storm? why isn't it possible to pass a predicate as a parameter to a bolt but it does work in the body?

5:48 neoncontrails: Not familiar with storm, but I'm looking at the sourcecode for shits and giggles. Holy macros. Quite nice

5:49 spacepluk: :)

5:49 neoncontrails: Does that behavior not follow from the defmacro for bolt?

5:50 It just seems like the way that function is defined, you'd be applying a predicate to a predicate

5:50 spacepluk: I have no idea my knowledge of both storm and clojure is still superficial :?

5:51 I have this "problem" with defbolt though

5:53 the (if (:prepare opt) part

5:54 no sorry the (if params ...

5:55 when you define a bolt with params it returns a function that you can call to create a configurable bolt

5:56 I'd like to define map/reduce/filter bolts but it doesn't seem to be possible

5:56 neoncontrails: ooh I see. Yeah this macro syntax is above my head, I see what you mean though

5:56 spacepluk: I've skimmed through it but I'm not ready hehe

5:59 neoncontrails: What if you use a for loop instead of applying a map?

5:59 *what happens if, rather

5:59 spacepluk: yeah, I just implemented specialized bolts

6:00 but I wanted the bolts to be sort of composable with the core logic functions

6:02 then it's a lot easier to chage the computations at topology level

6:06 neoncontrails: try this http://stackoverflow.com/questions/7314413/is-there-standard-foreach-function-in-clojure

6:07 If I'm not mistaken, mapping over objects in a functional context really only makes sense insofar as you're trying to get the side effects

6:08 if it's the attribute values you want, then you need to use a forEach-like construct

6:09 spacepluk: now I'm lost hehehe

6:11 in storm a bolt is like a function/computation that gets applied to stream tuples that pass through it

6:12 then you can emit new/more/less tuples (or nothing) depending on what you're trying to do and that can get piped to other bolts

6:12 so it's like operating on lists but distributed

6:13 that's why I thought it could be useful to have map/reduce/filter bolts I think it fits

6:13 am I getting it all wrong?

6:15 neoncontrails: No I think you can still do what you're trying to do, but it's just a slightly different syntax

6:17 spacepluk: ok, so I don't get what I should do with foreach

6:17 I mean doseq

6:17 skeuomorf: erm, what do you folks use as a CSPRNG?

6:18 TEttinger: concurrent secure pseudo RNG?

6:18 skeuomorf: Cryptographically secure pseudo random number generator

6:18 TEttinger: "not mersenne twister"

6:19 gilliard: java.security.SecureRandom ?

6:19 skeuomorf: heh

6:19 TEttinger: I'd be curious how Secure SecureRandom is

6:19 skeuomorf: gilliard: So, there isn't a native clojure thingy? I suspected so

6:20 spacepluk: skeuomorf: maybe /dev/random if you don't need cross-platformness :P

6:20 gilliard: I guess there's probably a wrapper lib somewhere? https://github.com/weavejester/crypto-random/blob/master/src/crypto/random.clj

6:20 TEttinger: it's not at all hard to implement the few random functions clojure has using SecureRandom

6:20 shuffle, rand-nth, rand-int, rand, what else?

6:20 neoncontrails: spacepluk: wish I could answer your question, I'm hesitant to answer it for fear of leading you astray :P

6:20 I did have a similar problem in Scheme once

6:21 skeuomorf: TEttinger: Well, I gave a quick look on the impl of SecureRandom just now, code is horrible, it calls sth called getProviders, and this sometimes falls back to something that starts with SHA1, I am horrified, will investigate later

6:21 spacepluk: neoncontrails: I appreciate any ideas you can throw at me :)

6:21 skeuomorf: spacepluk: Please don't use /dev/random, use /dev/urandom

6:21 neoncontrails: So you can think of map as basically acting on objects. Right?

6:21 spacepluk: skeuomorf: I was just checking the manual I never remember which one is the good one

6:21 skeuomorf: spacepluk: re: http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ and http://www.2uo.de/myths-about-urandom/

6:22 gilliard: TEttinger: I'd like to understand it better, too. SecureRandom's javadoc has citations.

6:22 skeuomorf: spacepluk: The manual is a LIE!

6:22 spacepluk: skeuomorf: really? wtf!

6:22 neoncontrails: You can map a typecasting operation to objects, for instance.

6:22 skeuomorf: spacepluk: Exactly!

6:22 spacepluk: skeuomorf: I'll read those, thanks for the tip

6:22 skeuomorf: np

6:23 neoncontrails: But contrast that to what other languages (not Clojure apparently) call forEach(), which basically means you can control what the object does

6:23 skeuomorf: After I sleep and wake up, I will take a look at SecureRandom and assuming it's legit, I will use that

6:23 ideally, it'd use /dev/urandom on *nix and CryptGenRandom() on the horrible crap that's windows

6:23 neoncontrails: so you can have it return values, and in the context of the forEach-like loop, apply your predicate

6:24 skeuomorf: I never have high hopes regarding Java crypto

6:24 spacepluk: neoncontrails: hmm, I see I'll explore that

6:24 skeuomorf: Last time I looked at the Android source code -a couple of months ago-, they defaulted AES to ECB mode

6:25 neoncontrails: and I think in most functional languages (i.e. not Python) you actually need the latter pattern to retrieve variables from the object since its namespace is private

6:25 roelof: Hello, Im doing the labrepl course and im stuck

6:26 I have made a file called student.clj with as namespace (ns student.dialect) and put it into the src directory

6:27 but as soon as I open repl in the head directory and enters (use 'student.dialect) I see this error message : CompilerException java.lang.Exception: namespace 'student.dialect' not found, compiling:(NO_SOURCE_PATH:26:1)

6:27 oddcully: spacepluk: Urandom as in the gUd random

6:27 roelof: I thought that because it's in the src dir it gets found automatical

6:27 spacepluk: oddcully: hahaha that's good :D

6:31 oddcully: roelof: in src/student/dialect.clj right?

6:31 roelof: your binding ::0 problem fixed? what was it?

6:32 roelof: oddcully: wrong port I was using port 8000 where labrepl was using 8080

6:32 spacepluk: neoncontrails: I'm not sure if I can do that in storm because it has the control of the stream and the calls to the bolts bodies

6:32 roelof: next time I will do this not just before I goto sleep

6:32 spacepluk: neoncontrails: also the bolts might be running in a different process/machine

6:33 roelof: oddcully: yep, the file is in src/student/dialect.clj

6:35 wierd, my cloud box rebooted and now everything is working well

6:37 neoncontrails: spacepluk: I'm excited for you to dig into continuation-passing style :D because it absolutely does not seem like it should work

6:37 for all of those reasons you mentioned

6:37 https://en.wikipedia.org/wiki/Continuation-passing_style

6:38 This is the basic mechanism of the forEach loop

6:39 roelof: maybe a stupid question replace sentence #"\.$" " does replace the . with a space ?

6:40 neoncontrails: I'm trying to think of a simple way to explain CPS without oversimplifying it

6:41 When mapping operations to objects, you're basically just going down the line and whacking each one with your metaphorical hammer

6:41 TEttinger: roelof: that doesn't look like a valid... regex on its own

6:42 oddcully: ,(clojure.string/replace "Hello! World!" #"!$" "?")

6:42 clojurebot: "Hello! World?"

6:42 oddcully: roelof: it replaces the last `.` in sentence with the part that you omited

6:42 TEttinger: ,(clojure.string/replace "thanks, oddcully." #"\.$" "...")

6:42 clojurebot: "thanks, oddcully..."

6:43 roelof: oke, then I understood that part wel. The assignment is now making a pig-latinaze

6:48 neoncontrails: Oh, forgot to finish that thought. When using a continuation-passing style, you're literally giving the object itself as an argument

6:48 So it can use its own methods

6:49 And side-effects can occur on whatever schedule those side-effects decide to happen

6:52 In the context of your question, at a high level you're basically just going to have the bolts perform a predicate test on themselves, then do something if it's true

6:52 (if I'm understanding your problem)

6:54 spacepluk: I want to apply the predicate on the tuples that pass through the bolts and emit new tuples (or not) based on the result of the predicate

6:54 so *do something* would be my predicate I guess

6:55 and the different map/reduce/filter bolts would have different tuple emitting behaviors

6:55 or that's the idea at least

6:56 I think that the problem is more about storm than clojure, but most people seem to be using java with storm :/

6:56 it's hard to get help

6:58 I think I see where you're going though

7:27 roelof: Is there a good book for a beginner to learn clojure. I like to many exercises so I can get a good hang of things ?

7:30 spacepluk: roelof: there's a good list here -> http://clojure.org/getting_started

7:30 Kneiva: roelof: Not a book but a lot of exercises: http://www.4clojure.com/

7:36 roelof: spacepluk: I will look in the list if there is a good book for me

7:37 spacepluk: I've read "clojure for the brave" and "joy of clojure" and I think they're good but I guess that's very subjective

7:38 I'm still going through the exercises in 4clojure I'm learning a lot and it's fun :)

7:38 tsdh: When a deftype has a field x-y, then you can access it either with (.x-y foo) or (.x_y foo). CIDER autocompletes the latter because the class of the deftype has an x_y field. Is there any reason to prefer one over the other?

7:39 roelof: oke, I tried to learn from labrepl but it seems that a lot of info is not be told. For example how to get the first letter of a word or how to check if that letter is a vowel or not

7:41 spacepluk: if it's anything like 4clojure I think you're supposed to check the api docs for that

7:41 doing simple tests in the repl helps too

7:42 roelof: like (first "asdf")

7:44 roelof: or (re-matches #"[AEIOUaeiou] (first "asdf"))

7:46 roelof: spacepluk: thanks, I have to write a pig-latin function

7:46 I think I have a idea how I can do that

7:47 spacepluk: np :)

7:48 roelof: I think I can also use a few suggestions from this page : http://stackoverflow.com/questions/686375/why-does-def-vowel-set-aeiou-work

7:51 spacepluk: using the set is probably faster than the regex

7:52 roelof: with set you mean this part : (def vowel? (set "aeiou"))

7:53 sorry for much questioins but im a super beginner in clojure

7:53 spacepluk: yes, a set is a data structure but you can use it as a function

7:55 roelof: oke, thanks

7:56 spacepluk: roelof: for example ((set "aeiou" \a)) returns \a because it's in the set

7:57 sorry ((set "aeiou") \a)

7:57 if the argument is not in the set it returns nil

7:58 https://clojuredocs.org/clojure.core/set

7:58 roelof: oke, so then if I have for example the word aap then I can get the first letter with (first "aap") but then I do not have the / before it

8:00 spacepluk: yes you do, it returns a char

8:00 roelof: so I cannot do ((set "aeiou") (first "aap")) ??

8:00 lazybot: roelof: Definitely not.

8:01 spacepluk: I think that should work

8:01 oddcully: roelof: do you have leiningen installed?

8:02 roelof: yes, I have

8:02 oddcully: roelof: then do `lein repl` and try it out

8:02 spacepluk: yup

8:02 Rurik: or better

8:02 noncom: ,((set "aeiou") (first "aap"))

8:02 clojurebot: \a

8:03 spacepluk: and \a is truthy

8:05 roelof: thanks all, I will try things out and hopefully get a hang of things

8:09 noncom: tsdh: probably because "-" is not allowed for java variables (fields) names

8:10 tsdh: therefore, the process known as "munging" and its counterpart, "unmunging" are applied to names to make them valid java or clojure names

8:11 tsdh: noncom: Yes, I know. My question is rather if it is ok to use the munged, underscored name from within Clojure because that's conveniently suggested by CIDER.

8:12 noncom: Or if the existence of x_y is just an implementation detail I should not rely on.

8:13 spacepluk: I think using the munged names doesn't make sense in the language

8:14 I would use the names as they are defined

8:14 in clojure

8:14 noncom: tsdh: well, it is an implementation detail... but the one that clojure tries to get away from java in. so, valid clojure would certainly be "-". IDK, i guess there cannot be a definite answer. you could 1) make a request for CIDER to manage the autocomplete for "-" names. 2) stick with "_" and just know that it is a sign of a java field..

8:14 spacepluk: yeah, that's closer to me too

8:15 spacepluk: also using _ might break if you want to port your code to clojure-clr or clojurescript

8:15 noncom: good point

8:16 so, the result would be: ask cider to work with "-" ?

8:16 tsdh: noncom: I guess there's nothing CIDER can do because how should it know that a class has been generated for a deftype?

8:17 spacepluk: maybe just replacing _ with - is good enough for real idiomatic code

8:17 noncom: well... firstly i guess it can inherit something unique for a deftype, and secondly - maybe just ... ah, spacepluk already said that :)

8:17 spacepluk: :)

8:17 tsdh: spacepluk: And how would I then access Integer/MAX_VALUE?

8:18 spacepluk: you'd need to type that

8:18 kandinski: just a quick question: why don't 'alter' and 'ref-set' have the bang like 'swap!' and 'reset!"?

8:18 spacepluk: I said "good enough" hehehe

8:18 tsdh: spacepluk: So you say that CIDER's autocomple should suggest the Integer/MAX-VALUE which is incorrect? That would inverse the problem.

8:19 kandinski: they too change the state of their respective ref, just like reset! and swap! does with an atom

8:19 spacepluk: yes, which one is worse?

8:19 kandinski: so why didn't they get the bang?

8:19 spacepluk: something like noncom sugests would be better, that's just a quick hack

8:19 tsdh: spacepluk: Your suggestion is worse. :-)

8:19 spacepluk: hehehe ok

8:19 weird

8:20 noncom: tsdh: here: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L396

8:20 spacepluk: nice

8:20 so replace only for ITypes sounds good, it might still break if somebody actually uses _

8:21 noncom: but that could be made a on-off thing so you can turn it off when needed

8:21 tsdh: noncom: Ah, that's good!

8:24 noncom: kandinski: a good question

8:24 kandinski: noncom: thanks, but does it have an answer? :)

8:25 noncom: kandinski: https://scott.mn/2014/02/09/playing_with_refs/ do ctrl+f "bang"

8:25 kandinski: noncom: thanks a lot

8:26 noncom: awesome!

8:26 noncom: :D

8:27 kandinski: thanks a lot, I was definitely thinking in a scheme way

8:27 spacepluk: tsdh: noncom: maybe it's worth taking a look at how the munging is implemented, you might find a complete solution

8:27 noncom: so, yeah, some fundamental stuff there. good to know

8:27 kandinski: noncom: is that your weblog?

8:28 noncom: kandinski: nope! i just googled "alter ref-set no bang" and that was the first or second find iirc :)

8:29 kandinski: shame on me. I did google "atoms vs refs" but got nowhere.

8:29 cheers, and thanks again

8:31 noncom: kandinski: np :) this place is for chatting, so that's what we're doing :D

8:35 spacepluk: tsdh: I don't get any munged names with fireplace on vim

8:36 and it's using cider afaik

8:36 noncom: spacepluk: it shows "-" ?

8:37 spacepluk: yup

8:37 noncom: interesting. at this point i'm a bit sad that i'm not on vim or emacs...

8:38 spacepluk: it's never too late :D

8:40 noncom: spacepluk: haha. well, i tried some emacs.. actually i find myself pretty comfortable with it and i use it for editing some other lisp, not clojure. other lisps rarely have a support in good ides...

8:40 spacepluk: you're on vim? can you recommend a good setup for it? i mean, plugins and stuff.. maybe there's a ready-to-use distribution? i'd like to try it out too.

8:41 spacepluk: noncom: this one is very popular http://vim.spf13.com/

8:41 I'm actually on neovim now but it's pretty much the same :)

8:42 there's also spacemacs that might be easier if you already know emacs

8:42 noncom: spacepluk: does spf13 have everything for clojure?

8:42 spacepluk: I don't think so

8:43 noncom: spacepluk: ok

8:43 spacepluk: is neovim better than just vim?

8:44 spacepluk: this are my clojure plugins https://gist.github.com/spacepluk/e1dfef7af7bf1a08e209

8:44 it's better for async stuff that is the worst part of vim

8:44 you can even open a terminal in a buffer now which is pretty cool

8:44 ceruleancity: can anyone help me with clojure.tools.cli? I'm trying to accept a file path as a cmd line param and having issues. it seems my :validate function is always receiving a boolean as input

8:44 spacepluk: and script shit on it

8:44 noncom: eh, i see the list of differences, i guess i won't be able to appreciate them since i never suffered the issues they resolve. but terminal and multithreading sounds really good. does bare vim really miss htat?

8:45 spacepluk: there are workarounds but they suck hehe

8:46 noncom: I'd like to try this some day https://github.com/syl20bnr/spacemacs/

8:46 I'm just too lazy to change my setup now that it works so well hehehe

8:49 noncom: oh spacemacs...

8:49 look sinteresting

8:51 spacepluk: yes, it sounds like a nice middle ground

9:52 troydm: is it possible to use core.logic via http://www.tryclj.com/ ?

10:03 wombawomba: I want to launch an external (unix) process asynchronously, and stream the output to stdout. What libraries should I use, and how?

10:07 troydm: wombawomba: https://gist.github.com/codification/1984857

10:11 galaux: Hi!

10:12 In a clojure/lein project, I hit this bug: http://dev.clojure.org/jira/browse/CLJ-843

10:13 (System/loadLibrary uses the current classloader – Clojure's – instead of the parent's)

10:13 But … it still does not work in clojure 1.6. Only on 1.7

10:14 which seems very strange to me

10:14 wombawomba: troydm: for that example, I would like to read from the :out stream line by line. Any idea how I would accomplish that?

10:17 Pupeno: According to https://github.com/technomancy/leiningen/blob/master/sample.project.clj, `:bootclasspath true` will place the agent jar on the bootstrap classpath, but this doesn’t seem to be happening and I’m not sure how to debug it. Where should this jar be present?

10:23 wombawomba: troydm: nvm, got it; thanks

10:52 ceridwen: Is this the right place for a question about an algorithm in Clojure's implementation? I'm trying to figure out why some design choices were made in the zipper implementation.

10:53 dstockton: ceridwen: yes

10:57 ceridwen: I'm a Clojure novice, so if I'm wrong on my interpretation of the code, please correct me. Two starter questions: in Huet's paper, the type of a path is (in Ocaml) Top | Node of tree list * path * tree list;; . In Clojure, there are two additional fields, pnodes and changed? . What's the function of these fields? Am I right in believing that l and r correspond to the first and third entries in Huet's type, and that ppath is the second?

11:00 Second, I notice that on https://github.com/clojure/clojure/blob/master/src/clj/clojure/zip.clj#L132 , there doesn't seem to be a reverse for l in the concatenation. In Huet's paper, it's

11:00 let go_up (Loc(t,p)) = match p with

11:00 Top -> failwith "up of top"

11:00 | Node(left,up,right) -> Loc(Section((rev left) @ (t::right)),up);;

11:02 For comparison, someone wrote up a zipper implementation in Clojure using deftype that does reverse the left entry: https://github.com/akhudek/fast-zip/blob/master/src/cljx/fast_zip/core.cljx#L134

11:07 Bronsa: ceridwen: there's no reverse because l is a vector rather than a sequence

11:07 roelof: how can I make these warnings away : ARNING: record? already refers to: #'clojure.core/record? in namespace: midje.parsing.0-to-fact-form.formulas, being replaced by: #'midje.clojure.core/record?

11:10 ceridwen: I was suspicious of that, but how does changing from a sequence (or list in the Ocaml context) to a vector make the difference?

11:16 roelof: no midje expert here ?

11:23 justin_smith: roelof: you can make that warning go away by using a version of clojure old enough so "record?" is not defined in clojure.core, or a version of midje new enough that it doesn't shadow record? with its own function of the same name.

11:23 roelof: said "version of midje new enough" may or may not actually exist in our reality

11:24 roelof: oke, and which version must I take then 1.6.x ?

11:24 justin_smith: not sure...

11:24 (-> #'record? meta :added)

11:24 ,(-> #'record? meta :added)

11:24 clojurebot: "1.6"

11:25 justin_smith: so older than 1.6

11:25 the thing is though, the warning is just a warning - the midje authors defined that function not expecting clojure.core/record? to exist

11:26 the idea with the warning is if you accidentally do (def count 10) and then all usage of clojure.core/count are going to be weirdly broken

11:26 but if you were never intending to use the clojure.core version of the function, then you are fine

11:27 roelof: midje is updated a long time ago , I see the last relaase on 10 nov 2011

11:32 I think I use a too old version. I use lein-midje 1.3.1

11:33 justin_smith: https://clojars.org/lein-midje yeah looks like you could update to 3.2-RC4

11:34 I bet recent versions have eliminated that warning

11:34 roelof: justin_smith: I wil try that

11:37 justin_smith: nope, the error messages stays

11:38 justin_smith: worthy of an issue on the repo, I'd say

11:39 they can fix it with (:refer-clojure :exclude [record?]) in the offending namespace(s)

11:42 roelof: justin_smith: oke, so adding that piece to this (ns training-day) schould do the trick ?

11:43 justin_smith: roelof: it needs to be done in the ns which has the warning "record? already refers to: #'clojure.core/record? in namespace: midje.parsing.0-to-fact-form.formulas

11:43 "

11:43 so they need to fix midje.parsing.0-to-fact-form.formulas

11:44 roelof: oke, then I have to look where that can be found ? I only have a training namespace

11:44 justin_smith: roelof: this is in the midje code, which is why I suggested posting it as a bug to the midje project

11:45 roelof: I did make a remark on the lein midje page. This is the same contribor as midje has

11:45 justin_smith: but thanks for the help and the explanation

11:45 justin_smith: np

11:52 roelof: justin_smith: made also a report on midje: https://github.com/marick/Midje/issues/324

11:53 justin_smith: roelof: was 2.3-rc4 a typo? their latest is 3.2-RC4

12:02 roelof: yes, I m going to change that

12:02 andyf_: ceridwen: In answer to question you asked a while ago, in Clojure, doing ‘conj’ onto a vector adds new elements at the end, not the beginning. Doing ‘conj’ onto other kinds of sequences, e.g. lists, adds new elements at the beginning.

12:03 justin_smith: andyf_: or ¯\_(ツ)_/¯ ##(conj #{:a "a" 'a} \a)

12:03 lazybot: ⇒ #{\a a "a" :a}

12:04 andyf_: justin_smith: I don’t consider a set a kind of sequence.

12:05 justin_smith: fair enough

12:06 andyf_: funny that I randomly picked an example that would add in the "front" though

12:10 roelof: a question for the future. Is it 'easy' to make a web app with clojure ?

12:12 hfaafb: it's certainly simpler!

12:12 justin_smith: the fact that you can use clojure on the backend and clojurescript on the frontend is definitely handy

12:13 I can't honestly answer the question because I haven't built webapps with other languages

12:18 roelof: oke, before dinner what do you use for web development, justin_smith

12:19 justin_smith: roelof: ring, figwheel, reagent, sente, kafka, onyx are the big pieces

12:24 neoncontrails: justin_smith: interesting. Clojure and Clojurescript run on totally different VMs though, don't they?

12:24 How does that work in practice?

12:25 justin_smith: neoncontrails: I use cljc for code that the two sides should share

12:25 then I use sente to send vanilla clojure data structures between the two ends

12:26 zerokarmaleft: ,(inc justin_smith)

12:26 clojurebot: #error {\n :cause "Unable to resolve symbol: justin_smith in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:...

12:26 justin_smith: one nice thing with websockets, is either end can push data to the other at any time, you're not limited to the classic request/response cycle

12:26 zerokarmaleft: for not saying isomorphic

12:26 neoncontrails: interesting. So in a sense, they don't really communicate... they just share assets. Is that right?

12:26 pseudonymous: Clojure on the front- *and* backend.. Sounds like the promise made by the JS devs, just with a decent language this time ^^

12:26 justin_smith: neoncontrails: no shared assets - I push data between the two

12:26 that's not the same as a shared asset

12:27 neoncontrails: I see. My misunderstanding

12:27 justin_smith: pseudonymous: it is working out like a dream - especially with the help of cljc and sente

12:28 neoncontrails: in practice, I send tuples - the first half is treated as a "routing" that decides how it gets handled, the second part is the data provided to that handler

12:28 and usually, part of the data sent is another routing to send the response(s) to if any

12:30 neoncontrails: the really fun part is that we added a distributed cluster (using onyx) to the backend, which means that I provide not only a route to send a reply to, but a whole itenerary describing a series of hops to make between the backend server and the compute cluster before sending the result back to the frontend

12:30 neoncontrails: Oh, cool. Sounds like a register machine. Is it basically that?

12:30 justin_smith: brb

12:34 neoncontrails: I'd love to understand how that gets implemented in practice. The nuts and bolts of it

12:36 I've noticed I'm easily overwhelmed by web development stacks, even ones I might understand okay at a conceptual level. Very difficult to think about so many layers all at once

12:38 pseudonymous: neoncontrails: What Justin's doing sounds pretty complex. But I think the confusion is generally good argument against end-to-end solutions in general. Sure, frameworks work great, right until their design tradeoffs and your needs diverge and then you're in hell. Seems like both the Clojure and Go communities have learnt from that by arguing in favour of small to-the-point libraries which you compos

12:38 e yourself.

12:39 (Apologies for the novel)

12:40 neoncontrails: Yeah, I hear that. How eerie, I've had the very same thoughts before

12:42 pseudonymous: What's a good starter library in Clojure/CS? Something lightweight to get one's feet wet

12:43 justin_smith: neoncontrails: I'd start with figwheel - it's an awesome dev tool that makes cljs dev really slick. And then use one of the react wrappers for controlling the frontend DOM (om or reagent)

12:44 figwheel doesn't become part of the end product, it just provides things like a clojurescript repl, auto-reload of clojure and css changes, etc.

12:45 pseudonymous: neoncontrails: wouldn't presume to know. I'm ~8 days in myself. What I *can* tell you is that I read (and re-read) sections of "Clojure for the true and brave" and picked up "Clojure Applied". From there, I just sort of picked up ring (wrapper for..jetty?) and compojure (routing) and went from there. I think I've picked up some 15 minor libraries by now.

12:45 neoncontrails: cloning now. :)

12:46 justin_smith: pseudonymous: ring is a protocol based wrapper for various web servers (including jetty, but also a tomcat container, or http-kit, among others)

12:47 pseudonymous: it provides an easy way to make a modular webapp that can run on whatever server you end up needing to use

12:47 pseudonymous: justin_smith: ahh. It's literally the only thing I just picked up from a tutorial and went on with :P

12:48 justin_smith: pseudonymous: by default it uses jetty if you use "lein ring"

12:48 but the same code you run via lein ring can also be shipped to run inside tomcat, or can self-host via http-kit, or whatever

12:48 neoncontrails: Oh, wow. From git-clone to a working interactive Flappy Bird session in the browser in less than 60 seconds. That's pretty darn cool :)

12:48 pseudonymous: justin_smith: yup, I do - hence my half-arsed assumption about it wrapping jetty in particular :)

12:49 justin_smith: neoncontrails: the figwheel demo?

12:49 neoncontrails: yeah

12:49 justin_smith: neoncontrails: with "lein new figwheel" you can get the bare bones setup to make your own figwheel / cljs project too

12:50 neoncontrails: This is much less painful than when I tried to get set up with Node!

12:50 justin_smith: pseudonymous: this discussion reminds me, I plan on trying the ring adapter for aleph one of these days

12:51 neoncontrails: ls

12:51 lazybot: home lib64 lost+found mnt opt proc root sbin srv tmp usr var

12:52 neoncontrails: sigh sorry guys thought you were terminal

12:52 justin_smith: (inc lazybot)

12:52 lazybot: ⇒ 37

12:53 pseudonymous: justin_smith: only briefly encountered a discussion about various HTTP servers. Hoping to get back to it once the first version of this service is done - but definitely *not* now

12:54 justin_smith: yeah, the nice thing with ring is it lets you make the choice later

12:54 without having to do a major code revamp

12:54 more things should be like that

12:54 pseudonymous: Seems to be a general thing of lisp, even. I'm really liking this

12:55 justin_smith: pseudonymous: lisp somewhat, clojure very much so

12:55 pseudonymous: see also the generic collection operations and higher order functions

12:56 pseudonymous: justin_smith: hmm? What do you mean ?

12:57 justin_smith: pseudonymous: the whole language is built up on generic operations using a protocol that allows your custom implementation choice to be used

12:58 pseudonymous: Oh in that sense. Yes, very much so. Played a bit with protocols too, fun times :)

12:58 justin_smith: pseudonymous: as opposed to multiple ad-hoc versions of the same functionality, or concrete inheretence, or generics, or any of the other silly alternatives

12:58 pseudonymous: eg every time you use filter or map you are exploiting protocols (the fact that the first arg can be any IFn, the last arg can be anything seq knows how to turn into a list)

12:59 pseudonymous: Yup, these are basically the things I'm falling in love with, head over heels, in fact ;)

13:09 noncom: if i am using reagent to create html from cljs, then how do i reflect some changes in this html, produced by new data that arrived from a websocket?

13:10 in other words, the reagent-generated html is static, i don't know how to regenerate it when new data arrives

13:10 how to sustain dynamic html

13:11 justin_smith: noncom: when you get the message on the websocket, alter an ratom, and have a component that watches the value of the ratom in your page structure that reagent is rendering

13:11 noncom: when i was programming in plain coffee script, that was easy - i looked for particular objects inside my html and simply replaced their content with the new one generated upon the new data

13:11 justin_smith: aaaaahhh..

13:11 thaath's what!

13:11 thank you very much :)

13:11 justin_smith: noncom: so you know how to define a component inside the page structure, right?

13:12 the rest should be straightforward

13:12 noncom: yes, i am still following the luminus guidelines. i think that if i add the reagent atoms, all will work just as you've described

13:12 justin_smith: noncom: I'd check out the basic docs for reagent, because this is the crux of how reagent is used

13:13 noncom: yes, i will read them too. at least now i know the right direction

13:13 justin_smith: https://reagent-project.github.io/

13:13 noncom: i was really lost there

13:13 justin_smith: the docs there are good ^

13:13 noncom: oh, yes, i see it, looks very clear

13:14 cool :)

13:14 justin_smith: after the third example they introduce something using an ratom - once you get used to this model it is really much easier than finding and mutating elements in a page

13:15 noncom: sure :) that's so minimal and functional. looking at it i find it beautiful. the binding i mean. that kind of thing similar to how binding in seesaw works

13:16 but this one is bidirectional

13:40 sdroadie: Hey all. I've run into an issue inserting vectors into Postgresql using yesql.

13:41 The error I get is a little unhelpful: INSERT has more expressions than target columns.

13:42 justin_smith: sdroadie: well, jdbc expects your data to be inserted to be in a vector, right?

13:43 that's how I recall it at least, and would match that error message. It's saying that the yesql statement produces a jdbc call to insert N pieces of data, and your vector contains more than N items

14:35 dnolen: Opportunity grants available for Clojure/conj http://clojure-conj.org/opportunity

14:51 sgs03: Does anyone use honeysql? How might I apply a modifier to only one column? For example, I'd like to do: `Select id, max(last_modified) from...`

15:05 wombawomba: I want to define a macro that automatically creates a bunch of bundings; i.e. given (my-macro [some-name some-other-name] (println some-name some-other-name)) would print two values defined by the macro. Is this possible?

15:06 muhuk: wombawomba: `(let ...) ?

15:06 wombawomba: er, bindings*, not bindings

15:06 ...not bundings*

15:07 muhuk: ah, so I could generate the first argument to let? good call, I guess

15:07 muhuk: wombawomba: when you're writing macros, it helps a lot if you write expanded code by hand first.

15:09 wombawomba: cool, thanks

15:20 TimMc: &(map #(re-find % "foo\n") [#"o\n$" #"o$"]) ;; why are both of these found?

15:20 lazybot: ⇒ ("o\n" "o")

15:25 wombawomba: muhuk: I can't seem to get that working.. perhaps because let is a special form? e.g. (let [a ['b "c"]] (let a b)) gives 'java.lang.IllegalArgumentException: let requires a vector for its binding'

15:33 muhuk: wombawomba: why do you have two let's there?

15:34 wombawomba: `(let [~'a ~a-value ~'b ~b-value] ~@body)

15:34 wombawomba: not sure about ~'a, maybe it was '~a

15:34 wombawomba: muhuk: in the macro, I want to go through the provided list, and create a binding for each item. I then want to expose those bindings to the macro body

15:36 afaik I would then have to do something like (defmacro [things & body] (let [bindings (map ... things)] `(let bindings ~@body))

15:36 ...since I don't know the length of things

15:38 muhuk: wombawomba: (defmacro [params body] (let [bindings (reduce (fn [acc x] (into acc [x (calculate-val x)]) [] params)] `(let bindings ~@body))

15:39 wombawomba: yes, I was confused since the 2nd let didn't have the quoting.

15:39 wombawomba: map doesn't work though because it would give [a b c] -> [a-val b-val c-val]

15:40 wombawomba: makes sense?

15:41 wombawomba: muhuk: that won't work though

15:42 it gives 'clojure.core/let requires a vector for its binding...'

15:44 muhuk: wombawomba: what does (reduce (fn [acc x] (into acc [x (calculate-val x)]) [] params) produce?

15:45 wombawomba: well, if I do

15:45 (defmacro mymacro [params body]

15:45 (let [bindings (reduce (fn [acc x] (into acc [x (str x)])) [] params)]

15:45 (prn bindings)

15:45 `(let bindings ~@body)))

15:46 then (mymacro [something] (println something)) prints [something "something"] before throwing

15:47 amalloy: muhuk: isn't that just an eager version of (mapcat (juxt identity calculate-val) params)?

15:48 muhuk: amalloy: sure. I just don't want people to *share* don't do concat links with me anymore.

15:48 luma: wombawomba, your problem is that your macro generates a let that doesn't have a vector as its binding form

15:49 amalloy: wombawomba: `(let ~bindings ~@body)

15:49 muhuk: wombawomba: "~bindings", not just "bindings"

15:49 luma: that code has just the symbol 'bindings, and even if you had ~bindings there it would be a lazy sequence, not a vector

15:49 amalloy: luma: no, it's a vector

15:49 luma: oh, sorry

15:49 i read that wrong then

15:49 wombawomba: amalloy: cool, thanks!

15:54 pseudonymous: Having "fun" wrapping various Amazon S3 classes. Running into a situation where the docs say a method should exist but calling it from clojure fails (as in it doesn't exist). Which tools do you typically use to inspect java objects? Specifically their publicly available methods (own + inherited)

15:55 Bronsa: ceridwen: sorry i went afk -- adding elements to a vector adds them to the tail, adding them to a seq adds them to the front

15:55 ceridwen: the vector already has the elements in reverse order compared to the seq, so there's no need to reverse

16:06 TimMc: &(map (comp count clojure.string/split-lines) ["" "\n" "\n\n"])

16:06 lazybot: ⇒ (1 0 0)

16:07 roelof: In the book Clojure Web Development Essentials they talked about a profiles.cjl but I do not have one

16:07 Where do I put this one

16:08 pseudonymous: roelof: you'd usually have this file if you made a project with leiningen

16:08 roelof: https://github.com/technomancy/leiningen/ (read the "Basic Usage" guide for details)

16:10 luxbock: pseudonymous: you are probably thinking of project.clj

16:10 roelof: you can create one in ~/.lein/

16:10 https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md

16:12 roelof: luxbock: and if I create one in ~/.lein does that then count for all project or can I make one per project ?

16:12 pseudonymous: Oh, misread (& misremembered). project.clj is the per-project file and profiles.clj is for cross-profile settings. Whoops. That said, seems like a really bad idea (tm) if you work with others

16:12 amalloy: pseudonymous: there are plenty of things that are totally reasonable to put in profiles.clj

16:13 luxbock: roelof: yes profiles.clj is for all projects, and if you want per project profiles then you can add those to your project.clj's :profiles key

16:13 amalloy: like i have a few dependencies that are only useful to debugging/profiling stuff, which i include only in the repl profile

16:15 pseudonymous: amalloy: but wouldn't most people on your team probably want to use those same tools, too ? If you tell them "Oh just do x-y-z to see what's going on" they'll get an error until they go out and fetch the very same things

16:16 roelof: oke but then I have made a project and I could not do this : :user {:plugins [[luminus/lein-template "1.16.7"]]}

16:16 because then luminus is already installed

16:20 Am I right or wrong here ?

16:24 amalloy: pseudonymous: not really. do you put a cider dependendency in the :dev profile of every clojure project you use?

16:24 developers have their own suite of debugging tools that they're familiar with

16:31 justin_smith: wait, why would roelof want a template in his plugins? or do they use confusing names for things?

16:31 ceridwen: Bronsa, andyf_: Thanks! Anyone know about my other question?

16:32 pseudonymous: amalloy: yes, right along with a bundled copy of '.emacs' :) (OK, I see your point)

16:47 skeuomorf: If anybody was curious about our SecureRandom discussion earlier, here http://bugs.java.com/view_bug.do?bug_id=4705093

16:47 TL;DR "What a confusing mess."

17:04 neoncontrails: pseudonymous: your earlier problem sounds interesting. Did you ever find a better way to inspect the properties of Java objects?

17:21 pseudonymous: neoncontrails: I'm sure I made a mistake (sleepy). That said, yes, clojure.reflect/reflect is *very* verbose but should have it all. I say should because I abandoned rummaging through its output because the object I applied it on is rather large.

17:22 amalloy: pseudonymous: well you don't rummage through it by hand, you use functions to do it

17:24 ,(use 'clojure.reflect)

17:24 clojurebot: nil

17:24 amalloy: ,(take 5 (map :name (filter (comp :public :flags) (:members (reflect String)))))

17:24 clojurebot: (replaceAll CASE_INSENSITIVE_ORDER codePointCount getChars regionMatches)

17:25 neoncontrails: Mmm. I can imagine that taking a while. The only times I've ever gotten bored waiting for a Java program to terminate have been reflective programs :)

17:25 pseudonymous: amalloy: had I had more time I would've begun parsing it or looking for snippets to do so. Anyway, I found my answer by other means

17:25 amalloy: ,(take 5 (sort (map :name (filter (every-fn :return-type (comp :public :flags)) (:members (reflect String))))))

17:25 clojurebot: #error {\n :cause "Unable to resolve symbol: every-fn in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: every-fn in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: every-f...

17:26 amalloy: ,(take 5 (sort (map :name (filter (every-pred :return-type (comp :public :flags)) (:members (reflect String))))))

17:26 clojurebot: (charAt codePointAt codePointBefore codePointCount compareTo)

17:26 amalloy: and so on

17:26 neoncontrails: pseudonymous: Can I rephrase your specific question about A3 objects as a general question, if you've already solved it?

17:27 pseudonymous: neoncontrails: I don't quite follow ? Rephrase it in what context ? To whom ?

17:30 Bronsa: I find that clojure.reflect returning symbols rather than Types/Classes is really inconvenient

17:30 neoncontrails: Haha, sorry. I worded that badly. I'm just curious about the general case where you have an object, possibly of some user-defined type, and possibly its methods are a black-box to you, but you need to be able to interact with it, usefully and safely. Is there's a general "Clojure strategy" for

17:30 skeuomorf: There isn't a clojure log() function, right? Just Java's `java.lang.Math.log()`

17:30 neoncontrails: *"Clojure strategy" for this situation?

17:32 justin_smith: neoncontrails: generally get the class and look for the source / javadoc

17:32 well, javadoc first

17:32 neoncontrails: also, for some objects you can get the bean

17:32 ,(bean (java.util.Date.))

17:32 clojurebot: #error {\n :cause "denied"\n :via\n [{:type java.lang.ExceptionInInitializerError\n :message nil\n :at [java.lang.reflect.Proxy$ProxyClassFactory apply "Proxy.java" 672]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbo...

17:32 justin_smith: :P

17:32 &(bean (java.util.Date.))

17:32 lazybot: ⇒ {:day 3, :date 2, :time 1441229560282, :month 8, :seconds 40, :year 115, :class java.util.Date, :timezoneOffset 0, :hours 21, :minutes 32}

17:33 neoncontrails: That's for library-defined object types, right?

17:33 Not for user-defined objects?

17:33 justin_smith: neoncontrails: that's for any object

17:33 bean uses reflection

17:33 oddcully: also vinyasa has some inspection stuff

17:33 justin_smith: there's also clojure.reflect of course

17:35 neoncontrails: Oh, neat. Are you always able to assume that the source code of a user-defined object is available to you?

17:35 justin_smith: neoncontrails: well, not always of course

17:36 neoncontrails: usually if I am writing code that deals with some non-clojure Object, I am targeting some interface

17:36 neoncontrails: if I am developing, and want to know how to interact with an object I get from some API, I check javadocs related to that API, or failing that the source code, since I am not using any closed source libs right now

17:38 pseudonymous: Will actually second that. I had one issue with Amazon's AWS classes to which I couldn't get an answer from either their docs, an IRC channel dedicated AWS services or blog posts - turns out it was easy enough to search through the code (it's nicely commented).

17:38 neoncontrails: I see. Between having lots of surgical functions targeting some specific interface vs. trying to make a single function robust against different types of objects (using reflection, say) do you lean toward one or the other?

17:39 justin_smith: neoncontrails: the point of an interface is that it is an abstraction that many objects implement

17:39 neoncontrails: which is why my first choice is to develop against some interface

17:39 neoncontrails: Objects of a type...

17:40 justin_smith: neoncontrails: if I write my code for a given interface, it should work with any object implementing that interface in a useful way

17:40 neoncontrails: Oh, I see what you mean

17:40 amalloy: nobody tries to write a function that uses reflection to guess at what methods a particular object has that might be relevant

17:40 except the EJB people and they are certifiable

17:40 justin_smith: right, that's going to waste a lot of time

17:40 haha

17:41 amalloy: you just say, look, here is an interface with two methods i need you to implement. pass my function something that implements that interface

17:41 and a lot of java code written as classes implementing interfaces anyway, so it is simple to interop with that

17:42 neoncontrails: Yes, that makes a lot of sense

17:44 amalloy: (and if they give you something that doesn't implement that interface, you don't use reflection to try and figure out something to do. you (throw (CmonManWhatTheHeckException. "Dude gimme an IWhatever"))

17:46 neoncontrails: I have a feeling that the way I've been interacting with objects in Python is somewhat clumsy and violent, and not translable to Clojure

17:50 Specifically, in Python, it seems like the way variables are scoped basically contradicts the idea of private namespaces -- it's so easy just to call Foo.name rather than use getters/setters

17:50 pseudonymous: Actually a bit curious about that - how are clojurists feeling about exceptions ? The host platform itself absolutely adore them, but what of clojure ? Is it preferred to write functions to throw a bunch of exceptions or should errors be signalled via nil or... ?

17:50 neoncontrails: I had an interesting debate the other day in Python about this

17:50 *in #Python about this

17:51 pseudonymous: neoncontrails: well, you can obscure the name by prefixing fields with __ and the Python mantra definitely is "We're all consenting adults, here" :)

17:52 neoncontrails: Haha. I hadn't heard that mantra, but it makes a lot of sense for a scripting language.

17:53 But what if you're writing software? I cannot see the justification for eliminating getters/setters. I don't think they're just a long-winded version of calling Foo.var

17:54 They strike me as a design choice, and a fairly good design choice

17:59 justin_smith: neoncontrails: in clojure we use immutable objects instead

18:00 you don't need getters when the fields literally cannot change

18:00 (and setters would kind of ruin the whole plan)

18:02 neoncontrails: You'll probably have to remind me of this another 4-5 times before my Pavlovian anxiety over mutable state goes away

18:02 justin_smith: neoncontrails: also getters/setters fit well with the OO paradigm where messy state stuff is hidden on the insides of things, but often in fp we want to push messy state stuff to the outside / boundaries between things and leave the inside side effect free

18:03 neoncontrails: You're right, of course. I see how that moots my concern, I'm just not used to having such assurances :)

18:03 justin_smith: neoncontrails: the horrifying thing is when you get used to it and then try to go back

18:04 amalloy: you'd be surprised how many of the java classes with getters and setters you write could be replaced with: public class FooHolder {public final int a; public final int b; public final String s; public FooHolder(int a, int b, String s) {this.a = a; this.b = b; this.s = s;}}

18:05 neoncontrails: Heh. I found the Scheme -> Java transition sort of soothing in a way, even though it was fun building classes from basically construction paper, macaroni shells, and paste

18:05 amalloy: which is a bit wordy itself, compared to just using a generic map in clojure. but compared to writing out all the getters and setters to "abstract" over the "private" "state"

18:07 justin_smith: neoncontrails: I'm sure you know about CLOS and the fact that it is available for scheme and you were just re-inventing OO for fun

18:07 neoncontrails: Yep. Well, our instructors were too, of course, they wouldn't have made it that easy ;)

18:08 justin_smith: right, of course

18:09 amalloy: CLOS for scheme seems like it could appropriately be renamed to SOS

18:09 justin_smith: amalloy: if only they had your wit

18:10 amalloy: i think that rather i lack their discretion. it's the sort of pun you fall into without even trying, so i presume they intentionally didn't do it

18:10 hiredman: amalloy: don't forget to add custom value hashing and equality

18:11 amalloy: well yes. those are things you should do too, if you want your objects to be able to participate in equality and hashing

18:11 does java 8 have any kind of Pair<A,B>/Triple<A,B,C> yet, or do you still have to go use one of eighty different external libraries?

18:13 justin_smith: short answer appears to be no, long answer appears to be wow those people are nuts

18:14 amalloy: yeah

18:14 i am reading about it now

18:20 neoncontrails: I asked a senior CS major whether I should take the 5th (optional) SICP unit, in which the idea is basically, now that you have a CLOS-like object system, let's use it!

18:20 He told me the unit was made optional because of its unusually sadistic pedagogical approach

18:22 Which basically culminates in the realization that the object system you have defined is an absolute nightmare and just very crazy, all of your objects being instantiated in exactly the same global namespace, etc

18:24 Which eventually you fix, and that's the last project, but the professors supposedly wanted to impress on students the obscenity of building an object system in that fashion

18:25 justin_smith: neoncontrails: well, if you plan on doing software professionally, one should get accustomed to creating obscene atrocities

18:26 at least there was a "fix it" stage :)

18:27 neoncontrails: That's true! There's something nice about that approach, too, I think

18:29 You would be grumbling in your head about the difficulty of such things you can barely put into words, because it's brand new difficulty, and then next week, learn that your frustrations are precisely the focus of the lecture

18:34 justin_smith: I want to implement a function that would detect a client sending a message in a loop. I'm thinking some kind of cache could help with this? maybe this is a functionality that has a name I am ignorant of?

18:35 amalloy: justin_smith: i don't really understand "detect a client sending a message in a loop"

18:35 justin_smith: eg. if I get more X messages in Y time period from any client that have identical contents, I want to log that fact

18:35 amalloy: is the client, in a loop, sending a message?

18:36 neoncontrails: I can think of some ways (cycle) could help you do this

18:36 justin_smith: amalloy: yes, specifically in a distributed system where we want to track down where the looping is (and people's first motivation is to blame their client - we can prove someone went rapid fire but can't always prove who did it)

18:37 neoncontrails: take lengthnum*2 samples from the message. if they're equal, message is in a loop right?

18:37 justin_smith: so it could be a server triggering itself, it could be react triggering reloads within its loading component and sending a request on each load...

18:37 amalloy: if you're getting a small enough number of messages that iterating over Y of them to check for dupes every time you get a new message this isn't too hard

18:37 justin_smith: neoncontrails: yeah, I just wonder if there is an existing thing for this

18:38 amalloy: yeah, that makes sense. I hoped someone would be like "you want message duplication via sampling, as implemented by ztellman/deus-ex-machina, very easy to use!"

18:38 * justin_smith is lazy.

18:39 amalloy: well the thing is, i have this vague feeling that there is something in lamina that's *related* to this, but not directly applicable

18:39 justin_smith: haha, I even had the author right

18:41 amalloy: justin_smith: i guess see lamina.stats/rate

18:42 where the idea, if you were going to actually use this, would be to demux your inputs into one channel per input, and check the rate of every channel to see if it's above Y? i dunno, seems like a lot of work for not much value, but this is what i was thinking of

18:42 that is, one channel per equality-partition of the inputs

18:43 justin_smith: right, interesting

18:44 neoncontrails: Hey... why don't you try mergesort?

18:45 If there's a cycle, it'll appear as an uninterrupted sequence of double+ letters

18:46 wait let me think this logic through more carefully

18:50 justin_smith: amalloy: for my purposes I don't even need to check message equality, just having monitoring that says "client X is asking for resource Y at rate Z" is often enough to track down an issue

18:51 amalloy: justin_smith: i made something that's close to that for 4clojure, lo these many years ago

18:52 https://github.com/4clojure/4clojure/blob/develop/src/foreclojure/social.clj#L11

18:52 obviously it isn't exactly a solution to your problem, and i guess it only works where N=1, but it has some useful techniques probably

18:56 emauton: justin_smith: Depending on the resources you're willing to spend, perhaps you could hash the messages and check-and-update a count associated with each hash to (probably) locate rapid-fire dups.

18:57 amalloy: emauton: that's a little cheaper than just storing the messages themselves in a hashmap, but it's the same general approach. and it has the same problem: how do you decrement the count for a message? incrementing is easy

18:57 justin_smith: emauton: yeah, I would want to track rate and set thresholds based on our own design for warnings

18:59 emauton: amalloy: I guess ideally it'd be nice to age them out, resetting a TTL every time a message is updated, but it all sounds a bit finicky.

19:05 justin_smith: I think the clean way to do it would be a "grouping function" which is like a loosey-goosey hashing function that might only care about the request path and/or client id, a sample-rate that decides how often your metrics are updated, and a mutable cache that gets updated with each incoming request. The task that builds the metrics would also throw away stale input.

19:06 now that I come to this conclusion, I will probably see that the way lamina's rate function did it was better

19:08 emauton: oad...

19:08 00:36 < amalloy> if you're getting a small enough number of messages that iterating over Y of them to check for dupes every time you get a new message this isn't too hard

19:08 00:36 < justin_smith> neoncontrails: yeah, I just wonder if there is an existing thing for this

19:08 Bah, sorry.

19:09 justin_smith: let me guess, erc?

19:09 emauton: https://github.com/clojure/core.cache/wiki/TTL looks usable for something like this, fwiw.

19:09 justin_smith: emauton: yeah, caching overlaps here I think

19:09 emauton: No, just a tricky Thinkpad touchpad & irssi. :o)

19:11 Bronsa: just disable click on touch

19:12 I did that after like 2 hours of having a laptop

20:27 mordocai: Anyone know if eldoc and company-mode integration is currently broken for CIDER 0.10.0SNAPSHOT? Doesn't appear to be working for me and I want to make sure it's not me. Was working last time I checked, but that's been a bit.

20:27 amalloy: mordocai: are you sure eldoc mode is active?

20:28 i had trouble in slime where sometimes it turned itself off

20:29 mordocai: Actually it is just eldoc mode. Company mode is working. amalloy: Yeah, definitely active. I've toggled it a couple times.

20:29 Is there a way to manually make eldoc return what it would say in the minibuffer? Maybe something with my minibuffer is broken.

20:33 So that's strange. It works in the repl buffer but not in the file buffer. It is supposed to work in the file buffer right?

20:34 amalloy: is that file associated with an nrepl session? if you have a cider connection in project A, then it won't necessarily be able to provide documentation in B

20:36 Bronsa: I've never been able to make eldoc work on file buffer with either cider or slime :/ only in repl buffers

20:36 mordocai: amalloy: I got it working by running (ns <project name>.core)

20:36 Idk why that made it work

20:36 It was in user namespace before that

20:37 Bronsa: Haven't tried slime, but it was working for for Elisp in scratch.

20:49 felipedvorak: Hi. I'm extra dupper noob, and in my recently installed Prelude with cider installed with packages-list-packages, when I do cider-jack-in it successfully opens the repl window but with an error saying cider version 0.10-0-snapshot doesnt match cider-nrepl's version (not installed).. any ideas?

20:51 mordocai: felipedvorak: Yep, see cider-nrepl docs

20:51 one sec

20:52 felipedvorak: https://github.com/clojure-emacs/cider-nrepl

20:53 Make a file called ~/.lein/profiles.clj and put {:user {:plugins [[cider/cider-nrepl "0.10.0-SNAPSHOT"]]}} in it

20:53 So same as the docs but for the version

20:54 You'll have to update that version in lockstep with cider itself in emacs or you'll get that error

20:56 felipedvorak: mordocai: update in lockstep you mean manually?

20:56 I'm following a tutorial so I missed that documentation. Thanks :)

20:56 mordocai: felipedvorak: Yeah, i don't know of a way to do it automatically. Doesn't take long though.

20:56 I had similar troubles when I was first setting it up, so NP.

21:05 If I update my project dependencies in lein is there an easy way to get cider to reload or should I just close and jack-in?

21:07 futuro: mordocai: you might be interested in clj-refactor.el, which does many things, but hot-loading is among them

21:07 otherwise you probably want...alembic, I think it's called

21:07 I'll look for it

21:08 yeah, alembic

21:08 felipedvorak: mordocai: You know if I should run some install command after that? emacs isn't recognizing it..

21:08 futuro: clj-refactor, when used with the refactor-nrepl middleware, uses alembic to do hot-loading

21:09 so if you don't want to set all that up, pulling in alembic should do what you want

21:09 (though I've never used just alembic, so I'm not positive)

21:14 mordocai: futuro: Coolness. I'll have to try out clj-refactor.

21:14 felipedvorak: So it's actually for leiningen so it should "just work". Do you kill cider and do a new cider-jack-in?

21:14 futuro: I've really enjoyed having it

21:14 felipedvorak: mordocai: yeah.. :/

21:17 mordocai: felipedvorak: Looking up how to check if a middleware is installed with lein

21:19 felipedvorak: Not quite what i'm looking for, but run lein show-profiles user in terminal and pastebin the result.

21:21 felipedvorak: mordocai: lein show-profiles user outputs nothing, ive tried substituting user for my actual username, which also outputs nothing, and only lein show-profiles outputs base, debug, default, leiningen/default, leiningen/test, offline, uberjar, update

21:22 mordocai: Yeah lein isn't seeing your profiles.clj then

21:22 Double check it is in /home/<your username/.lein/profiles.clj

21:22 felipedvorak: mordocai: confirmed

21:23 mordocai: Can you put the contents of profiles.clj on a pastebin?

21:23 Also check permissions

21:23 Mine are 644 for that file. 600 should be fine (hell 400 should be, but idk)

21:24 felipedvorak: permission is just read-write for the user, read for the rest

21:24 mordocai: Yeah, that should be fine

21:24 That's what mine are

21:27 felipedvorak: all that it contains is {:user {:plugins [[cider/cider-nrepl "0.10.0-SNAPSHOT"]]}}

21:29 mordocai: felipedvorak: Weirdness. What's lein version say

21:29 felipedvorak: Leiningen 2.5.2 on Java 1.7.0_85 OpenJDK 64-Bit Server VM

21:30 mordocai: Same as me besides build version of java VM (which shouldn't matter). I'm at a bit of a loss as to why lein isn't loading that then.

21:30 I'm thinking some small typo that isn't showing up in our communications but idk

21:31 I'm not really an expert

21:31 felipedvorak: mordocai: no problem, I thank you a lot for your help :)

21:36 TimMc: pseudonymous: org.timmc.handy.repl/show for inspection

21:38 https://github.com/timmc/handy/blob/3da099f0c1440d5a8ab31cb9d369f414067a1204/src/org/timmc/handy/repl.clj#L53

21:49 mordocai: So I'm working on a little maildir library for a project of mine and I could use some help on idiomatic clojure. Specifically looking for help with clojure-maildir.core/move-email right now. It works, but I don't see how to test my corrupted file checking properly errors and I feel it could be written better. Ideas? https://github.com/mordocai/clojure-maildir

22:14 justin_smith: mordocai: is comparing the hashes of the file contents even easier than just checking byte by byte equality in this case?

22:15 if you have both files on disk, and need to consume the files to check the sha1, why not just compare every byte?

22:15 it might be a different consideration if you calculated the first sha while copying the first file, saves a file read

22:17 skeuomorf: so, defn- makes the function accessible only within the ns it was defined in?

22:17 justin_smith: sort of

22:17 there's always the @#'var trick

22:18 skeuomorf: justin_smith: Why "sort of"? The docs aren't very verbose

22:18 justin_smith: ah, so by that I could access it

22:18 justin_smith: @#'var will access the value even if it is annotated :private

22:18 right

22:18 skeuomorf: I see

22:18 justin_smith: but I guess privacy always has some caveat

22:19 defn- will definitely make it clear to people using your lib that you intend the function to be private

22:19 skeuomorf: Yeah

22:21 Is there a document somewhere which lists all the available abstractions with brief but terse explanations? By abstractions, I mean (defrecord, protocols, deftype,..etc)

22:21 justin_smith: http://conj.io has that and more

22:21 * skeuomorf looks

22:21 justin_smith: also the docs on clojure.org of course

22:22 skeuomorf: I skimmed the docs

22:22 http://conj.io is like the cheatsheet but a little nicer

22:22 justin_smith: yeah

22:58 mordocai: justin_smith: Theoretically i'm checking at the filesystem level that there wasn't corruption. A bit overkill, but i'm particular about my email. I was thinking of making the verification an optional flag (defaulting to on) anyway. Besides that is there anything that jumps out at you?

22:58 filesystem-ish level

22:58 OS caches and all that jazz

22:59 justin_smith: no, otherwise it looks fine enough

23:00 mordocai: Cool. The other stubbed out functions is all that I require for my little application I'm writing (clojure-mailfilter) for my personal usecase. So close!

23:03 I suppose if I really wanted to be sure I should force a fsync and reload the files then check byte equality. Not sure how to do all that in java, and definitely overkill.

23:10 irctc: hello

23:11 how do you debug a classnotfound exception?

23:12 mordocai: Probably post it to a pastebin, give more context, and we can try to walk you through debugging it.

23:12 Easiest way i've found to learn besides blogs/books/beating your head against the wall.

23:12 justin_smith: irctc: ClassNotFound is either a typo, or your deps are set up wrong

23:12 irctc: yeah, share the stack trace in a paste if you can

23:13 irctc: (ns web-scraper.core ;; (:gen-class) (:import [com.mohaps.xtractor Extractor] [com.mohaps.fetch Fetcher])) (defn -main "I don't do a whole lot ... yet" [& args] (println "Hello, World!")) (let [xtractor (Extractor. (Fetcher.))])

23:13 http://pastebin.com/29nRbpyG

23:14 justin_smith: irctc: how are your deps set up?

23:14 irctc: http://pastebin.com/uWz1sFw8

23:14 I am using this https://github.com/tobyhede/lein-git-deps

23:16 justin_smith: irctc: well, I know nothing about htat plugin, but ClassNotFoundException makes me think you either spelled something wrong or didn't set the plugin or dep up correctly

23:16 irctc: right

23:16 justin_smith: are you building the java code yourself?

23:16 does the plugin build the code?

23:19 irctc: I am importing it directly

23:19 Can cider evaluate defproject?

23:20 justin_smith: no, I mean, javac has to run in order to build java code, are you running the compilation or does the plugin do it for you?

23:21 irctc: I think it only adds the dependencies. See: https://github.com/tobyhede/lein-git-deps/blob/master/src/leiningen/git_deps.clj

23:21 justin_smith: OK, so did you compile the code?

23:21 irctc: It was extracted from the cljscript leiningen

23:22 http://pastebin.com/0H496P9Z

23:22 I am too sure

23:23 Can leiningen build it automatically?

23:23 justin_smith: irctc: I think with a java project you'll have to define the task if it can at all - because different java projects use different build tools

23:24 irctc: right

23:24 can cider evaluate defproject?

23:24 justin_smith: maybe you'll need to figure out where lein-git-deps puts the source and compile it yourself?

23:24 irctc: it puts it in a folder call .lein-git-deps in the project root

23:24 justin_smith: irctc: I'm not sure what you mean, it can start up a repl, what are you expecting cider to do with your defproject?

23:25 irctc: I get this error:1. Caused by java.lang.RuntimeException Unable to resolve symbol: defproject in this context Util.java: 221 clojure.lang.Util/runtimeException

23:26 this is what happens when I evaluate the defproject file

23:26 justin_smith: defproject isn't for a clojure repl to load, it's for leiningen. I mean you can load the leiningen libs and use load-project to load up a project but you don't usually need that...

23:26 irctc: oh

23:26 I see

23:26 thanks!

23:27 justin_smith: leiningen uses the project.clj file to figure out how to start your repl - by the time you have your repl the defproject is usually done its work already

23:28 irctc: if the java library uses maven, how can I get leiningen to compile it automatically?

23:30 justin_smith: I guess you'll need a custom prep-task that finds the directory where the plugin did the git checkout and then runs the right maven command? seems like it would be complicated to me though, what about just cloning the git repo manually and using maven to install it to your local repo?

23:31 mordocai: Idk much about maven, but this seems to suggest that maven and lein work together? http://stackoverflow.com/questions/15910567/does-leiningen-read-maven-settings-in-m2-settings-xml

23:32 justin_smith: mordocai: lein can use maven settings, but he is talking about auto-building a maven project with an obscure lein plugin...

23:32 I mean maybe there's an easy way to do it but... ?

23:33 irctc: What I meant is whether leiningen will automatically compile the source

23:33 justin_smith: irctc: the problem is the source you want compiled uses a maven setup

23:33 it's not even configured for lein

23:33 it's not part of your lein project

23:33 irctc: right.....

23:34 felipedvorak: mordocai: fixed it! hehe had to add :profiles {:dev {:plugins [[cider/cider-nrepl "0.7.0"]]}}) to the end of the projects project.clj. nothing like reading the docs, now back to the tutorial :D thanks again

23:34 justin_smith: how would lein know how to build it?

23:34 irctc: so I will have to retrieve the dependencies using maven right?

23:34 felipedvorak: ops, substituting 0.7.0 to 0.10.0-SNAPSHOT of course

23:34 mordocai: felipedvorak: The user namespace way should have done it too but *shrug*. Glad it fixed it.

23:35 irctc: doesn't leiningen use maven beneath it?

23:35 justin_smith: no

23:35 felipedvorak: mordocai: I'll make sure to investigate this further after finishing the tutorial :)

23:35 justin_smith: irctc: leiningen uses some of the same libs maven uses, but it doesn't use maven

23:36 irctc: justin_smith: Do you know what is the command the need to be ran in order to retrieve the maven dependency?

23:36 *dependencies

23:36 Will this work: https://github.com/kumarshantanu/lein-localrepo

23:36 ?

23:37 justin_smith: irctc: you have to have maven installed, and then you can run "maven compile"

23:37 https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

23:38 but I think it would be easier to just run "maven install" and then tell lein to use that jar

23:38 unless you need to frequently update to the latest version of that java code

23:40 irctc: nope, the development for that project has pretty much completed and I am using it from my github repo

23:43 talios: justin_smith - if that's a _real_ project and not some toy - install a repository manager, and deploy it there, so the rest of your company can use it - without having compile :)

23:47 irctc: I just checked the library source, the maven pom file is only used for building. All dependencies is stored in the git directory

23:47 https://github.com/mohaps/xtractor/blob/master/pom.xml

23:47 so I don't actually **need** maven

23:49 talios: mmm there not in the git repo tho... they're in a maven repo tho

23:50 xtractor isn't even a clojure project...

23:51 justin_smith: irctc: well something has to turn the .java files into .class files before you use them

23:52 usually maven would do that

23:52 talios: exactly

23:52 irctc: currently I am getting dependency errors as leiningen is trying to compile the webapp together with the library

23:52 justin_smith: irctc: the class isn't found because you aren't compiling it

23:53 irctc: leiningen cannot compile it because there's a web app

23:53 justin_smith: use maven install, or do as talios says and install to a shared repo

23:53 irctc: as in the "library" is in the same repo as the web app

23:53 justin_smith: irctc: leiningen can't compile it because it's not a lein app, it's a maven app

23:53 s/app/lib

23:54 anyway I'm out for the night, good luck

23:54 irctc: oh

23:54 thanks

23:55 it worked

23:55 thanks a ton!

23:55 justin_smith: np, glad you figured it out

Logging service provided by n01se.net