#clojure log - Nov 16 2014

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

0:00 oskarkv: i don't remember what i did before :P

0:00 andyf: tools.namespace is a more general solution, but the (use ns :reload) is fine if you just want to reload a single namespace

0:00 and do not have many namespaces to deal with in your project

0:02 If you have just a small number, (require '[my.namespace.name :as myns] :reload) might be preferable, to avoid bringing in all of your Vars together into the user namespace

0:04 munderwo: Hi all. im attempting to play around with datomic, and use the repl thats shipped. I was wondering if anyone knows if it has a nrepl port built in? or how I could expose it to cider?

0:08 marchdown: I did it! https://gist.github.com/marchdown/d1388e064570439a39fb thanks guys. (that’s non-gender-specific _guys_ if anyone cares.) Off to write some tests.

0:09 andyf: excellent

0:35 TEttinger: marchdown: brosephina is probably acceptable as a gender-neutral substitute for guy

0:39 sohum: hey, so I have a flawed little recursive program here that never bails out of its recursion, but the interesting thing is it never StackOverflowError's either

0:40 it just infinite loops

0:40 j201: sohum: tail call optimized?

0:40 sohum: I'm not using recur, so I don't _think_ any TCO is going on...

0:40 j201: hm

0:56 andyf: sohum: Is there any looping going on within one "level" of the recursive function?

0:57 An infinite loop at one level could give inf loop without stack overflow

0:59 sohum: andyf: I'm not sure what that would look like, but here's the minimal-as-far-as-I-can-tell example of this behaviour http://pastebin.com/6Y98s9UV

1:02 zerkms: sohum: how does it stop actually?

1:02 sohum: zerkms: it doesn't!

1:03 I'm going to leave an instance of this running in a different shell, to see if it does StackOverflowError, just a long time later

1:03 if it's, I dunno, trying to do increasingly complicated arbitrary precision arithmetic, or something

1:05 zerkms: that's strange

1:05 sohum: yes, it is :D

1:05 well, it's certainly pegging a cpu

1:06 zerkms: I changed it to be 2 levels only, without invoking average

1:06 sohum: clojure 1.6.0, if it matters

1:06 zerkms: and now it overflows

1:07 sohum: oh, really?

1:07 zerkms: (defn improve [guess x]

1:07 (/ x guess))

1:07 with this

1:07 (I understand I've broken the computation logic, but still)

1:07 sohum: oh, I've been stripping parts out myself, too

1:08 but interestingly,

1:08 if you put that logic back into improve, without the function call

1:08 (defn improve [guess x] (/ (+ guess (/ x guess)) 2))

1:08 it still loops forever

1:08 zerkms: :-S

1:08 sohum: so, yes, something about the arbitrary precision arithmetic

1:09 zerkms: I'm curious to ask it on stackoverflow

1:09 would you?

1:09 sohum: yea, I'm definitely curious

1:09 is there a clojure stackoverflow, or should I just use the normal one

1:11 zerkms: http://stackoverflow.com/q/26954404/251311

1:11 :-P

1:11 sohum: well fine :p

1:12 dbasch: sohum: you neglected to say that you’re running it with a long and not with a double

1:13 if you try it with 1.0 and 4.0 it stackoverflows quickly

1:14 sohum: dbasch: oh, I guess 1 and 4 default to longs?

1:14 dbasch: sohum: they are longs

1:14 sohum: yes, so it's _definitely_ the arbitrary precision arithmetic, then

1:15 dbasch: it’s computing very long rationals

1:17 sohum: I don't know why that stops it from throwing a StackoverflowError, though, unless it _eventually_ will

1:17 dbasch: sohum: it will but it will take a while

1:17 andyf: Wild guess: It will stack overflow eventually, but very slowly, because the arguments you are using cause it not to allocate new Longs.

1:18 sohum: mmm

1:18 yeah, that makes sense

1:19 zerkms: andyf: so they are integers?

1:19 dbasch: if I run it with 1.0 and 4.0 it stackoverflows after ~6500 calls on my machine

1:20 but if I run it with longs it gets very slow after 10 calls

1:20 so most likely you won’t see it blow the stack

1:21 sohum: yeah, I've had it running for twenty minutes on my machine, and still none

1:21 it's just getting very, very slow

1:21 that makes a lot of sense

1:23 clojure_beginner: What is the best book to learn clojure from ? I am currently using Programming Clojrue 2nd edition

1:25 andyf: hmm. If you give it integers, not doubles, then the intermediate results are rationals, which get to be BigInteger numerators and denominators very quickly

1:26 the size of those BigIntegers seems to approximately double with each recursive call of sqrt-iter

1:26 clojure_beginner: What is the difference of reduce and apply ?

1:27 andyf: I don't know what the run-time of the BigInteger arithmetic ops are, but I wouldn't be surprised if it was linear in the size of the integers for addition, and the product of their sizes for multiplying

1:27 pdk: reduce takes a function F that accepts two arguments and a sequence

1:27 zerkms: clojure_beginner: apply - invokes a function with arguments

1:27 and reduce converts a sequence into somethingelse

1:27 pdk: calls F on the first two items of the sequence, then calls F with the result of the first call and the third item of the sequence, repeats until end of the list

1:28 eg (reduce + [1 2 3 4]) would add 1 and 2, add the result of that to 3, then add the result of that to 4

1:29 if i recall apply essentially lets you unpack a list of arguments to a function and call it with them

1:29 clojure_beginner: Ahhh I see.

1:29 pdk: ,(apply + 1 2 [3 4])

1:29 clojurebot: 10

1:29 pdk: yea

1:30 clojure_beginner: Ok, I understanded already how reduce worked, I got confused because sometimes I was able to use reduce or apply and it worked the same

1:30 pdk: so if you have a case where some or all of the arguments you want to give to a function are stored in a list

1:30 clojure_beginner: thanks for explaining apply, now I understand, unpacking the list of arguments and calling the function with that arguments

1:30 pdk: you can put the list as the last argument in your call to apply and it will essentially take each item in the list out to pass as an argument to whatever function you're applying

1:32 clojure_beginner: yo uactually put vector as the last argument not a list

1:32 zerkms: it may be any sequence

1:32 clojure_beginner: aha ok

1:32 zerkms: ,(apply + '(1 2))

1:32 clojurebot: 3

1:32 zerkms: ,(apply + #{1 2})

1:32 clojurebot: 3

1:33 pdk: vectors lists and lazy sequences are broadly grouped together as seqs

1:34 clojure_beginner: yeah, I learned that today :) So basically I can do (reduce str (reverse "Hello")) or (apply str (reverse "Hello"))

1:35 but this is just because str takes 2 or more arguments

1:35 pdk: yea

1:35 reduce will always call the passed function with 2 arguments

1:36 apply will call it with as many arguments as you give it

1:36 clojure_beginner: I see. It is clear now, thanks. But which solution is faster ?

1:36 pdk: name the use case

1:36 zerkms: speed doesn't matter

1:36 semantics does

1:36 TEttinger: for str, apply

1:36 I think

1:36 pdk: most likely

1:36 apply is just making a single call to str with a bunch of arguments for you

1:37 reduce is going to call str N-1 times for an N item list

1:37 TEttinger: reduce creates temporary two-element collections to call str on

1:37 zerkms: (apply str (reverse "Hello")) <--- this actually does not work as you expect

1:37 clojure_beginner: so basically those for appy and reduce return a lazy sequence ?

1:37 pdk: so it will invoke a lot of intermediate calls

1:37 zerkms: because it calculates the (reverse) call

1:37 pdk: apply will just return whatever the function given returns

1:37 similarly reduce can return whatever

1:38 eg reducing + over a list of numbers returns the sum of that list

1:38 clojure_beginner: aha, so apply is not part of the list comprehensions functions

1:39 pdk: it can let you call a function with an arbitrary number of arguments at runtime but it's still only calling that function once and returning its result

1:41 clojure_beginner: Aha ok, so (apply + [1 2 3 4] [5 6]) is basically just doing (+ 1 2 3 4 5 6) at runtime

1:41 pdk: iirc only the last argument to apply gets unpacked if it's a list

1:41 ,(apply + [1 2] [3 4])

1:41 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>

1:41 pdk: yea

1:42 all arguments before the last get preserved as is

1:43 clojure_beginner: ah, nice gotcha

1:43 pdk: it lets you supply fixed arguments at the beginning

1:44 clojure_beginner: yea

1:44 pdk: ,(reduce concat [1 2] [3 4] [5 6])

1:44 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core/reduce>

1:44 pdk: hm

1:44 ,(apply concat [1 2] [3 4] [5 6])

1:44 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

1:44 TEttinger: ,(apply map [inc [1 2 3]])

1:44 clojurebot: (2 3 4)

1:44 zerkms: ,(apply concat [[1 2] [3 4] [5 6]])

1:44 clojurebot: (1 2 3 4 5 ...)

1:45 TEttinger: ,(concat [1 2] [3 4] [5 6])

1:45 clojurebot: (1 2 3 4 5 ...)

1:45 pdk: i assume there's gotta be some standard function to concatenate a series of lists together

1:45 TEttinger: concat you mean?

1:45 pdk: well yeah :p

1:46 oh wait now i see why it didnt work

1:46 ,(reduce concat [[1 2] [3 4] [5 6]])

1:46 clojurebot: (1 2 3 4 5 ...)

1:46 pdk: ,(reduce + (reduce concat [[1 2] [3 4] [5 6]]))

1:46 clojurebot: 21

1:46 pdk: that's one way you could accomplish what you intended with the (apply + [1 2 3 4] [5 6]) example

1:46 clojurebot: Titim gan éirí ort.

1:46 clojure_beginner: that returns LazySeq pdk

1:47 pdk: yea

1:47 it's lazily concaenating all of the lists together into one

1:47 then reducing + over the combined lazy sequence

1:47 clojure_beginner: So basicaly what is returned is not the end result yet..

1:47 TEttinger: ,(into [] [1 2] [3 4] [5 6])

1:47 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core/into>

1:47 TEttinger: ,(into [] [[1 2] [3 4] [5 6]])

1:47 clojurebot: [[1 2] [3 4] [5 6]]

1:47 TEttinger: hm

1:47 clojure_beginner: Only when you say for example (nth 9 my-seq) you get a result

1:48 pdk: yes

1:48 lazy sequences defer calculation of the actual list values until the point they're requested

1:48 and only so far as needed to fulfill the request

1:48 clojure_beginner: aha

1:48 TEttinger: ,(into [1 2] [3 4])

1:48 clojurebot: [1 2 3 4]

1:49 pdk: this allows for generating infinite lists or lists where each item takes a large amount of memory without exhausting resources while also letting regular functions be agnostic to what type of list they're dealing with

1:50 fair warning though that if you hold onto the head of a 1 million item lazy seq when you're already at the million item then all the intermediate items will still be in memory

1:50 at the millionth item*

1:51 clojure_beginner: yea I read about it, then you have some doall and dorun functions that actually walk over all the sequence before returning it

1:51 pdk: yea they force evaluation of the list

1:51 clojure_beginner: dorun does not keep the previous value of the seqence in memory, only current value i believe

1:51 What would be the use case of this ?

1:52 if you want to make some temp calculation with elements from the seq ?

1:53 pdk: usually the do* functions are useful for code that has side effects

1:53 clojure_beginner: aha, so by side effects you mean the function does something else not related with its return value

1:53 pdk: yes

1:54 usually i/o or changing an object's state or global state

1:54 clojure_beginner: cool.

1:58 Thanks pdk. Clojure is so interesting. I sure won't be learning it in 21 days :)

1:58 I give it 2 years :)

1:58 pdk: depends a lot if you're coming into it with an existing lisp background

1:59 luxbock: clojure_beginner: check out https://www.4clojure.com/problems if you haven't already

1:59 very fun way to get started

2:00 clojure_beginner: no lisp background, just java, ruby, some c. I was learned OO ways, which I am starting to doubt in

2:00 Thanks luxbock, I'll take a look

2:01 I can sense the future will be bright for clojure, but I can not understand why TIOBE index is not showing it yet.

2:03 wow, great resource

2:03 amalloy: clojure_beginner: there's a google group for discussing 4clojure problems, if you need assitance

2:06 clojure_beginner: tnx amalloy, I am sure I will use that mailing list. . Already registered to 4 clojure now, so Ill be doing that today :)

2:09 kenrestivo: what i'm trying to do can't be impossible nor has it likely never been done, but i can't find any working examples: stuffing the input and output of a shell process into core.async channels

2:35 amalloy: kenrestivo: get it as a seq via line-seq, and then use onto-chan or whatever it is?

2:36 kenrestivo: ok, will try that

2:42 aha, buffering is ruining my day

2:43 i've tried with clojure.java.io, raw (.exec (Runtime/getRuntime)...), and conch. the issue is in java-land somewhere, buffering.

2:44 i think i got it, nevermind. thanks!

3:15 ugly, but works! https://www.refheap.com/93446

3:20 borromakot: I'm fairly new to clojure, but I'm trying to find a way to get a range from 1 to infinity. I want to (take-while pred (range 1 infinity), but pred returns true for two things, which are 0, and the answer. I don't want to modify pred, as it SHOULD return true for 0.

3:20 any ideas?

3:21 the fact that pred returns true for 0 means I can't just say (take-while pred (range))

3:23 zerkms: borromakot: (iterate inc 1)

3:23 borromakot: :zerkms facepalm thank you!

3:24 that being said, I'm doing a project euler problem and my solution is almost definitely a bad one.

3:25 TEttinger: also,

3:25 ,(rest (range))

3:25 clojurebot: (1 2 3 4 5 ...)

3:25 TEttinger: rest returns a lazy seq

3:26 borromakot: nice

3:27 At first, I was under the impression that clojure was really difficult to understand, and it gave me a lot of trouble. Something clicked a few days in and I realized its far simpler than almost any other language I've come across.

3:27 TEttinger: it's funny how that is, huh

3:27 the symbols are part of it

3:27 but the way data is in clojure is so elegant

3:27 borromakot: the whole damn language is just (function args)

3:29 I'm not sure if they would be called special forms or not, but other languages are filled with these special language forms and control flow things.

3:29 kenrestivo: messing with all this shell and channels stuff, i've never restarted my jvm and repl so many times before

3:30 it's an emacs-using-100%-CPU and java-using-200%-CPU kind of experience

3:30 jack_rabbit: eww.

3:31 borromakot: kenrestivo: what are you doing that requires all that?

3:32 kenrestivo: nothing at all. it just tends to happen.

3:32 borromakot: have you tried lighttable?

3:32 kenrestivo: there's a lot of just runaway loops, <!! endlessly returning nil

3:33 borromakot: lol

3:33 kenrestivo: closed channels, orphaned processes, unkillable threads

3:33 it's amusing in it's botched-ness.

3:35 borromakot: I've just started learning myself, doing some project euler projects and the like, so I haven't gotten to that point.

3:35 hope I never do

4:20 kenrestivo: oh, euler projects won't do that to you. dealing with java interop and unix processes and such will

4:21 stay in the nice, safe world of pure functions and you'll be fine :-). it's all that side-effecting stuff where the ugliness is

4:27 dysfun: kenrestivo: you said unix. yes. well. i'm just waiting for the better thing that isn't coming

4:27 like the double-fork idiom for daemonising

4:27 ewwww

8:12 justin_smith: so, for this contract job, I promised to be on GMT time until after the deadline...

8:13 Bronsa: justin_smith: and what would your timezone be?

8:13 justin_smith: US west coast

8:13 so I'll be adjusting a bit

8:14 but I live in Portland, where the sun is rarely out, so it's just an arbitrary number that is changing for the most part :)

8:15 I just got my system time zone set up so everything on my computer tells me it is GMT

8:15 Bronsa: 8hour offset is a bit crazy

8:15 justin_smith: yeah, it is

8:16 but I can handle it for a few days

8:16 Bronsa: ah ok, I thought it was for an extended period of time

8:16 justin_smith: oh, no

8:16 yeah, that would be a big commitment

8:16 we're in the final stretch here

8:17 Bronsa: I've lived in a 5/6 hour offset for most of the summer but irl stuff makes it really hard

8:17 justin_smith: I'm taking a shell script with - no joke - 72 stdio stream redirects, that keeps crashing, and trying to do it in clojure so that each individual process can be restarted

8:18 instead of "oh, one of your 144 programs crashed? whole thing goes down"

8:18 making me wish I knew erlang :)

8:18 Bronsa: yeah that sounds like it would be the perfect fit for this kind of thing

8:18 but I don't know any erlang myself

8:20 justin_smith: it is kind of hilarious using a for comprehension to build all the redirect clauses in one shell invocation

8:21 clojureRule: (defn av [x] (.java.lang.Math.round (/ (reduce + x) (count x))))

8:21 gfredericks: coooomputers

8:21 justin_smith: gfredericks: seriously tho

8:21 gfredericks: ,(Math/round 41.9)

8:21 clojurebot: 42

8:21 clojureRule: No matching field found: java.lang.Math.round for class java.lang.Long clojure.lang.Reflector.getInstanceField (Reflector.java:271)??

8:21 lazybot: clojureRule: Definitely not.

8:21 justin_smith: uhoh

8:22 clojureRule: how to fix thetype/

8:22 gfredericks: clojureRule: ^ I showed you up there

8:22 Bronsa: lol I thought clojureRule was clojurebot for a second

8:22 justin_smith: Bronsa: I was afraid it was a new bot

8:28 clojureRule: (Math/round (+ 1 2 3)) ,wont run with integers,my question is if i would difficult to mix static libraries with a dynamic languange

8:29 ,(Math/round (+ 1 2 3.1)) works ok

8:29 clojurebot: 6

8:29 clojureRule: ,(Math/round (+ 1 2 3)) works ok

8:29 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: round>

8:32 justin_smith: ,(Math/round (+ 0.0 1 2 3))

8:32 clojurebot: 6

8:32 clojureRule: whenever i use a java librarie , i have to be carefull to call with the exact type ? (Math/round (/ (+ 2 3) 2)) in a dynamic languange is 2,

8:33 so i have to take care of the types when calling java libraries...?

8:33 justin_smith: well, even with normal clojure, sometimes types are an issue

8:33 ,(pop [1 2 3])

8:33 clojurebot: [1 2]

8:33 justin_smith: ,(pop '(1 2 3))

8:34 clojurebot: (2 3)

8:34 justin_smith: ,(pop (list 1 2 3))

8:34 clojurebot: (2 3)

8:34 justin_smith: ,(pop (map identity [1 2 3]))

8:34 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentStack>

8:34 justin_smith: so you either get the beginning elements, the ending ones, or an error

8:34 based on type

8:34 Bronsa: woah, I didn't know PersistentList implemented IPS

8:36 clojureRule: the problem is tha jvm is build for static languanges/

8:36 justin_smith: Bronsa: it's useful - if you don't need quick indexed lookup on a stack, and want lifo, then PersistentList is your best bet

8:37 clojureRule: well, we also want the performance you can only get if you specialize on types a bit

8:37 fully generality has a price

8:38 clojureRule: i was thinking about clojurescript tha runs on a dynamic vm

8:38 Bronsa: justin_smith: I frequently forget about the existence of pop/peek. I think I've written (nth v (dec (count v))) a bunch of times because of that

8:38 justin_smith: haha

8:38 clojureRule: is clojurescript slower tha clojure?

8:38 justin_smith: generally, yes. Also the development toolchain is more complex / weirder.

8:40 clojureRule: thanks room :) have a nice day with lots of clojure

8:40 justin_smith: you too

9:08 gfredericks: pop with vectors makes me realize you could probably write multipop pretty efficiently inside the vector class but I'm not sure it's possible otherwise

9:08 like a constant-ish time impl I mean

9:08 (in contrast to transients which would be linear time)

9:10 not that I've ever needed that.

9:28 justin_smith: multipop?

9:32 gfredericks: like pop 10 things

9:32 justin_smith: ahh, right

9:32 you'd want multipeek to go with it

9:32 gfredericks: if I have a vector of 5,000,000 elements and I want to pop 3,000,000 of them

9:32 multipeek doesn't make as much sense

9:33 llasram: Aren't those things both already O(1) via `subvec`?

9:33 gfredericks: yes, but subvec has a big asterisk though

9:33 of the "memory leak" flavor

9:33 whereas multipop you could do in the proper fashion

9:33 llasram: Asterix the Gaul is actually pretty small

9:33 Gotcha

9:35 gfredericks: I think multipeek would just be subvec though

9:39 Bronsa: gfredericks: isn't subvec your multipop?

9:43 gfredericks: Bronsa: see above

9:44 basically multipop is a special case of subvec that could remove the memory leak

9:44 hyPiRion: gfredericks: yeah, takev is O(~1). As efficient as WC pop.

9:44 gfredericks: WC?

9:44 hyPiRion: worst case

9:45 justin_smith: hyPiRion: is takev a thing?

9:46 gfredericks: presumably means the same thing as multipop and is just as unreal

9:46 justin_smith: I can't find it in clojure 1.7-alpha3

9:46 gfredericks: oh I guess it takes a slightly different arg

9:46 hyPiRion: justin_smith: not yet, but multipop is just a different name on take

9:46 justin_smith: gfredericks: specifying the amount to leave rather than remove

9:46 hyPiRion: itym drop

9:46 hyPiRion: justin_smith: itym?

9:46 justin_smith: takev / dropv would be good names

9:46 I think you mean

9:46 pop tells you how many to remove

9:47 not how many to keep

9:47 gfredericks: no drop is the thing you *can't* do better than subvec

9:47 but take you can

9:48 justin_smith: oh, I thought the idea with multipop was "pop n times", but you meant "pop until n remain" ?

9:48 hyPiRion: justin_smith: no, but one can be represented by the other

9:48 gfredericks: right, doesn't matter

9:48 call one multipop and the other takev

9:48 hyPiRion: drop-lastv is probably a better name

9:48 gfredericks: but they're the same impl

9:48 okay

9:49 takev & drop-lastv

9:49 implemented in terms of each other

9:49 like some sort of weird haskell typeclass

9:49 hyPiRion: yeah

9:51 gfredericks: my point though is I don't think you can do this at all without doing it inside the PV class[es]

10:47 engblom: Besides just indentation (which both vim and emacs does), is there a tool for tiding up a file? Something breaking up a long line in a sane way?

10:50 Nathell: engblom: pprint?

10:50 engblom: pprint will remove comments and make some stuff really strange

10:51 ,(pprint '#(+ 1 %))

10:51 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: pprint in this context, compiling:(NO_SOURCE_PATH:0:0)>

10:52 gfredericks: yeah pprint is not meant for code at all

10:52 I've thought a customizable auto-formatter would be an excellent lib; but probably difficult.

10:55 justin_smith: gfredericks: I bet a script you could run based on emacs -q would work (just launch emacs as an elisp interpreter, load clojure-mode, format the file, write to stdout)

10:55 gfredericks: does clojure-mode do a decent job of formatting *arbitrary* code?

10:55 justin_smith: so even people who don't want to interact with emacs can still get the formatting

10:55 gfredericks: I thought it just indented

10:55 justin_smith: hmm

10:55 engblom: It would be quite nice if you could specify the width of the file and the script would make sure the file never gets wider and formats it according to that.

10:56 justin_smith: yeah, you would need some extra logic for real formatting I think

10:56 gfredericks: and a requirement for this is a round-tripping reader

10:56 I can never remember if somebody's written that or not

10:56 justin_smith: but emacs clojure-mode already has a bunch of the logic, and is already runnable as a non-interactive tool, so it may be a decent start

10:56 mavbozo: C language has formatter that can change your code format to allman, k&r, or stroustroup style

10:57 gfredericks: my ideal is a tool where you can put the config file for it in your repo and wire up git or tests to enforce it

10:57 engblom: mavbozo: It was the fact that C has this that caused me to ask if Clojure has it.

10:57 mavbozo: do we--lisp programmers, has such styles?

10:57 gfredericks: another thing you'd need is a way to declare which vars deserve macro-style indentation

10:58 mavbozo: engblom: even Common Lisp does not have it

10:59 maybe we--clojure programmers, has one format style already, let's call it bbatsov https://github.com/bbatsov/clojure-style-guide

10:59 gfredericks: I think that guide has some non-standard things in it

11:02 mavbozo: engblom: and the fact that Common Lisp does not have a program to automatically format code

11:02 engblom: makes me think that such a program is really hard to make that those smart common lisp people still could not build it

11:05 gfredericks: mavbozo: probably one thing that makes it hard is that due to macros the meaning of form structures is somewhat open-ended

11:09 * engblom finally has a Vim setup he is happy with for Clojure :D

11:11 justin_smith: I think you could get pretty far with a formatter that did no parsing, but just had special case rules for various flavors of macro, and then just applied function rules for everything else

11:12 then you can give it a config file for the macros that should use various indenting flavors (ie. tell it for is indented using the same rules as doseq)

11:13 not a clojure parser, or even editor, just going through and removing/adding whitespace until things are good

11:15 gfredericks: what do you do when it gets something wrong?

11:15 at least in emacs you can manually opt out by formatting it yourself and trying really hard not to autoformat that form again

11:15 I'd like a workflow like gofmt where you can make the tool authoritative

11:18 llasram: That would be nice... Last time I tried to create some organizational style guidelines my team at the time failed to agree on anything at all, even a maximum line length

11:19 justin_smith: gfredericks: if all it did was make whitespace changes, and it was good about strings, what could it break?

11:19 gfredericks: um

11:19 idunno

11:20 justin_smith: whitespace changes as in replace one range of 1 or more whitespace characters with some other range of 1 or more characters, and never adding it (except perhaps betwen ')(' etc.)

11:21 gfredericks: would it ever add/remove line breaks?

11:21 TimMc: justin_smith: comments

11:21 llasram: I was wondering something related recently. Are there any cases in Clojure where the presence or absense of whitespace *between* complete forms would change the interpretation on reading?

11:22 gfredericks: llasram: well in some cases I think no whitespace would make it one form

11:22 llasram: gfredericks: Such as?

11:22 TimMc: a b

11:22 gfredericks: ,(map count [[:foo:bar] [:foo :bar]])

11:22 clojurebot: (1 2)

11:22 llasram: Oh duh

11:22 gfredericks: a b is good too :)

11:22 (inc TimMc)

11:22 lazybot: ⇒ 80

11:22 justin_smith: TimMc: OK, I think the set of rules would be pretty small, tractable, and doable in a tool like elisp or even perl that doesn't actually know any clojure

11:22 llasram: (int TimMic)

11:22 (inc TimMic)

11:22 lazybot: ⇒ 1

11:22 llasram: Geez, typing toda

11:22 I apparently need to turn up the heat a bit

11:23 (inc TimMc)

11:23 lazybot: ⇒ 81

11:23 llasram: I went straight to thinking about tagged literals and missed the forest for the trees

11:23 gfredericks: we could start with a rudimentary tool if there were a rigorous opt-out mechanism

11:24 then improve it as things come up

11:25 Bronsa: llasram: both tagged literals and record ctor literals don't care about whitespaces

11:27 justin_smith: so, for implementation, I can see the advantages of using clojure (it's guaranteed available in contexts where you need this tool, right?) but also it may be more apropriate to use a string processing tool like elisp or perl or whatever

11:27 gfredericks: ;; autofmt-ignore +5

11:28 I feel like committing to something non-clojure is just going to be eternally regretted

11:28 compared to the one-time cost of figuring out how to do whatever is hard about it

11:29 justin_smith: gfredericks: fair point

11:29 and maybe we would get a sweet string-processing lib for clojure out of the deal

11:29 gfredericks: :)

11:30 the name of the lib should have something to do with yak shaving

11:30 yak-razor

11:30 justin_smith: heh

11:30 yak-barber?

11:32 gfredericks: is there a good greek/latin prefix related to yaks similar to "hippo-" for horses?

11:32 apparently the word is from tibetan so I'm not optimistic

11:33 llasram: Yakrazor would be a great name for the sword of a swords&sorcery/programming parody character

11:33 dbasch: “The yak (Bos grunniens and Bos mutus) “

11:33 grunniens is a good name

11:34 $google grunniens

11:34 lazybot: [Yaks | Grunniens Yak Ranch | Tibetan Yak Breeder | Farm - Ranch] http://www.theyakranch.com/

11:34 gfredericks: bov- can refer to an ox

11:35 justin_smith: given that grench would be a good way to run the tool, grunnien sounds good

11:35 gr gr gr

11:35 TimMc: (inc grunnien)

11:35 lazybot: ⇒ 1

11:35 dbasch: official soundtrack of yak shaving https://www.youtube.com/watch?v=ZnHmskwqCCQ

11:36 TimMc: That had better be that one Bach piece

11:36 oh well

11:37 dbasch: close enough

11:39 llasram: Bach yak shaving?

11:41 TimMc: yeah, still searching

11:41 yach-shaving

11:45 Kleines Harmonisches Labyrinth

11:47 GEB mentions this as a piece that keeps changing key and then changes back but not quite to what it was in the beginning.

11:47 justin_smith: TimMc: when I youtube it, one of the side bars is "Grelling's Paradox"

11:47 yet another gr

11:48 TimMc: ("I could swear that I wrote this sweet string-processing library for *something*. Oh well.")

11:50 although I don't have enough musical training to hear the missing resolution.

11:51 engblom: Someone here had a quil fork for a more functional way of programming. I have forgotten what it was called. I would want to pass down to draw arguments without having some kind of global variable (with def).

11:52 justin_smith: TimMc: yeah, pop music doesn't really do the whole evolution / tension / resolution paradigm of classical in the same way, and that's what most of us can understand natively as a musical language

11:55 engblom: I found it myself. Inkwell it is called.

11:56 TimMc: justin_smith: I can hear it in a lot of electronic music.

11:57 justin_smith: TimMc: but electronic music isn't using the same rules - it has it's own cues / rules for tension and resolution, that partly overlap

11:57 TimMc: one of my big pet peeves is the over-generalization of classical music theory to other music

11:59 jeffterrell: Question: I'm consistently getting a timeout for 4clojure #131, even though it runs locally on the test cases in ~100ms. Any ideas/common pitfalls with 4clojure I should be aware of?

11:59 Where by "it" I mean "my solution".

11:59 justin_smith: jeffterrell: are you sure you are using all the same inputs locally?

11:59 jeffterrell: Problem is here BTW: http://www.4clojure.com/problem/131

12:00 I got it using the foreclojure lein template, which has been serving me well for the last ~20 problems.

12:00 And they do look identical…

12:03 dbasch: jeffterrell: which case gets you the timeoutÇ

12:03 ?

12:03 jeffterrell: The first one. I mean I get no passes or failures, just a timeout.

12:03 I can share my solution if that would be helpful.

12:04 dbasch: I just re-ran my solution and it passed just fine

12:04 sure, go ahead

12:06 jeffterrell: OK thanks, one sec.

12:10 Here's what I have, including passing test cases.

12:11 gfredericks: I just got it to pass after a couple iterations

12:12 jeffterrell: Weird. So 4clojure is accepting some solutions, just not mine. :-)

12:12 gfredericks: my powerset function didn't have a base case :)

12:14 jeffterrell: Ha, nice.

12:14 Incidentally, I love that I can do this in Clojure (for sets that don't contain nil anyway): (fn intersect [s1 s2] (set (keep s1 s2)))

12:15 gfredericks: clojure.set/intersection

12:15 jeffterrell: Yeah, but not in 4clojure.

12:15 gfredericks: I used it

12:15 jeffterrell: Really? Hmm… Did you require it or just call it directly?

12:16 gfredericks: just called it fully qualified

12:16 jeffterrell: Huh, alright. I thought I tried that and it didn't work. Trying again, thanks!

12:17 If only clojure.set had a power-set function.

12:17 gfredericks: my favorite powerset impl uses a range of integers

12:18 I wonder if there's some number theory way to make a pseudorandom permutation of (range 2^n)

12:19 that would let you do a shuffled lazy power set on arbitrarily large input

12:19 which is useful for...spaceships.

12:19 and...marketing.

12:19 and cancer.

12:20 jeffterrell: By range of integers, are you basically going from 0 to (2^n)-1 and using the binary representation of the number to control whether an item is included or excluded?

12:20 justin_smith: gfredericks: map xor (rnd) across the range?

12:20 gfredericks: justin_smith: hey that's a good enough one

12:20 jeffterrell: Hmm, interesting. I bet there's a PRNG out there that can do that.

12:20 gfredericks: I bet there are tricks you can layer on top of that to get alternate orderings

12:21 jeffterrell: yes that exactly

12:21 jeffterrell: Yeah cool.

12:21 gfredericks: wait I take back my tricks suspicion

12:22 justin_smith: it's crazy how many possibilities there are with that method but how far short it comes of giving you all permutations

12:27 is there any perf reason that clojure's bit operations shouldn't support BigInt?

12:34 justin_smith: looking more closely, since the number's being treated as a bit set it's actually not a very random looking order that results

12:34 i.e., the high bits are pretty static

12:46 justin_smith: gfredericks: yeah, makes sense

12:47 jeffterrell: gfredericks: I wonder if Knuth's tome has a good algorithm for what you want. Half of Volume 2 is about random numbers.

12:49 justin_smith: gfredericks: is there an weird semi-rng that is guaranteed to not repeat any output?

12:50 lol, an-weird

12:53 gfredericks: justin_smith: yeah that's what I was wondering; number theory with all the groups seems the most promising

12:54 every group defines N permutations...but getting a useful group of size 2^N seems hard;

12:54 you could pick the next prime above 2^N and then...

12:54 get a permutation from that and just filter out the stuff that's too large

12:55 jeffterrell: What version of Clojure does 4clojure use to evaluate code?

12:59 jkj: 4clojure is quite boring when you are not following anybody. anyone care to be stalked?

12:59 dbasch: jeffterrell: you never shared your code

13:00 jeffterrell: dbasch: lol, totally thought I did, sorry about that

13:00 https://www.refheap.com/93465

13:00 justin_smith: I am using refs to hold hash maps of identifier to Process (as created by ProcessBuilder). I have a checker that restarts those processes and replaces the value in the map if they exit. How do I ensure that this isn't retried? because with retries I am getting multiple processes for each index (but only one actually tracked in my map of processes, so it has effectively leaked)

13:02 I should probably be using atoms, but an atom would retry too...

13:03 gfredericks: a function that returns a lazy shuffled version of (range 2^n) via the prime thing I just thought of: https://www.refheap.com/93466

13:04 dbasch: justin_smith: how do you test if a process has exited?

13:05 justin_smith: (.isAlive process)

13:05 maybe I should just isolate all actions on processes to one thread, that is likely the simplest solution...

13:18 (inc eastwood)

13:18 lazybot: ⇒ 1

13:18 justin_smith: (inc andyf)

13:18 lazybot: ⇒ 7

13:18 justin_smith: that tool just keeps saving me from my own stupidity

13:19 andyf: justin_smith: cool. If you are going to the conj (unfortunately I am not) hiredman will be leading an unsession on it. You can go and rave about it there.

13:20 justin_smith: sadly I am not going either

13:20 andyf: justin_smith: Or if you have any favorite examples of things it caught for you, I can add them to some 'teaser slides' I have early in a slide deck that ask people 'do you see anything wrong with this'?

13:20 gfredericks: I am not going either let's the three of us hang out in #clojure and gripe

13:21 andyf: Wait, you can do other things in #clojure besides gripe?

13:22 gfredericks: you can make the bots factor numbers

13:23 &((fn factor [n] (if-let [p (->> (range 2 (inc (Math/sqrt n))) (filter #(zero? (mod % n))) (first))] (cons p (factor (/ n p))) [n])) (System/currentTimeMillis))

13:23 lazybot: ⇒ [1416162185644]

13:24 gfredericks: I don't think that worked right.

13:24 andyf: gfredericks: Regarding your earlier question about bit ops on BigInteger, I don't know the details, but I suspect performance is the reason that it isn't built into clojure.core

13:24 gfredericks: &((fn factor [n] (if-let [p (->> (range 2 (inc (Math/sqrt n))) (filter #(zero? (mod n %))) (first))] (cons p (factor (/ n p))) [n])) (System/currentTimeMillis))

13:24 lazybot: ⇒ (2 491 1442120377)

13:24 gfredericks: andyf: the strange thing about it though is that the *other* perf-sensitive functions do support BigInt

13:24 ,(inc 3N)

13:24 clojurebot: 4N

13:24 gfredericks: ,(bit-not 3N)

13:24 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: bit operation not supported for: class clojure.lang.BigInt>

13:25 andyf: If someone finds a way to extend them to work on BigInteger, with the right kinds of performance tests showing little or no slowdown, that would be interesting.

13:25 to me. Can't say whether clojure.core maintainers would find it interesting.

13:25 gfredericks: andyf: do you know something about bit ops vs normal arithmetic that I don't?

13:26 andyf: yes.

13:26 gfredericks: okay good.

13:26 andyf: :) I don't know what, but probably something

13:26 gfredericks: I'm just wondering why it's worth doing this for bit ops but not addition etc

13:26 it smells more like not-implemented-yet

13:27 andyf: Why it might be difficult to get bit ops to perform well in Clojure, that I don't know.

13:27 I am pretty sure it was there in an earlier version, and was removed, maybe as part of Clojure 1.3 numeric changes.

13:27 gfredericks: hey I bet leiningen would let me try out 1.2 pretty easily

13:28 arrdem: yes, yes it will

13:28 whether you'll like what you find...

13:28 gfredericks: (inc leiningen)

13:28 lazybot: ⇒ 6

13:28 gfredericks: (inc lein)

13:28 lazybot: ⇒ 2

13:28 gfredericks: (inc line)

13:28 lazybot: ⇒ 1

13:28 gfredericks: (inc lint)

13:28 lazybot: ⇒ 1

13:28 gfredericks: (inc lent)

13:28 lazybot: ⇒ 1

13:29 gfredericks: haha actually `lein new; switch to 1.2.1; lein repl` fails

13:29 probably something to do with cider-nrepl

13:29 arrdem: switch to?

13:29 gfredericks: I'm just gonna call java with that dang jar.

13:29 this is not worth figuring out

13:30 clojure.lang.BigInt didn't even exist

13:31 but looks like bit ops did work on BigInteger

13:31 hey I bet abedra would know this

13:33 andyf: https://github.com/clojure/clojure/commit/601d9521f88f8fb00e670d2823857cdcb2b2e1c3 Removed during alpha releases leading up to Clojure 1.3.0

13:36 http://dev.clojure.org/jira/browse/CLJ-767 and http://dev.clojure.org/jira/browse/CLJ-772 look like they may have the patches. I haven't read through them in enough detail to see what the rationale was.

13:37 clojure-dev discussion thread: https://groups.google.com/forum/#!topic/clojure-dev/IZHL8ASNjKY

13:37 ok, now that I've thrown a denial-of-service attack at gfredericks :)

13:38 arrdem: clearly he just needs to learn to read faster

13:38 I'm on the dev thread :P

13:39 Bronsa: so the rationale is "Rich said so"

13:39 gfredericks: "People that are using

13:39 shifts as nature intended are doing so for the utmost performance, and

13:39 any conditional test kills it."

13:39 -- rhickey

13:40 andyf: Bronsa: well, he gave reasons for the decision in the thread.

13:40 gfredericks: I guess the conditional has something to do with edge cases in the shifters? and it was cleaner to just not support any bit ops for consistency?

13:40 justin_smith: gfredericks: so clearly we need a slow-* variant for each bitwise op

13:41 andyf: justin_smith: At least as far as naming goes, putting a ' at the end would be fairly consistent with inc' +' etc.

13:41 Bronsa: andyf: well removing them alltogether isn't the best solution though, we have + and +', we could have bit-foo and bit-foo'

13:41 arrdem: &(let [c 63] (bit-shift-right (bit-shift-left 1 c) c))

13:41 lazybot: ⇒ -1

13:41 gfredericks: justin_smith: the numeric-tower lib doesn't solve this problem, does it?

13:42 arrdem: (bit-not 0)

13:42 &(bit-not 0)

13:42 lazybot: ⇒ -1

13:42 andyf: Someone could ask Medley maintainers whether they are interested.

13:42 arrdem: numeric tower seems inactive

13:42 gfredericks: ,(bit-not' 7)

13:42 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: bit-not' in this context, compiling:(NO_SOURCE_PATH:0:0)>

13:42 arrdem: sorry no it's algo.generic that's inactive-ish

13:42 gfredericks: oh. that's an interesting one. what bit width would you expect for that?

13:43 andyf: arrdem: I haven't looked recently -- tickets with no response for a long time, or no tickets?

13:43 gfredericks: arrdem: ah right no idea

13:43 andyf: no tickets could just mean no one is looking to change it.

13:44 arrdem: andyf: no response. ALGOG-5 being the ticket in question.

13:44 olivierrr: Is there a way to get subs from a number?

13:45 arrdem: olivierrr: subs?

13:45 olivierrr: substring

13:45 andyf: arrdem: you could try personal email to Konrad, if you haven't already.

13:45 olivierrr: i wanna pop the last character

13:45 andyf: (quot num 10)

13:45 if by character you mean 'decimal digit'

13:45 arrdem: gfredericks: I think the answer is that you get the same width you put in back

13:46 gfredericks: anything else will be... silly

13:46 Bronsa: andyf: jira emails only the project authors that requested it right?

13:46 gfredericks: arrdem: oh righto

13:46 andyf: is medley your preferred utils lib?

13:46 arrdem: gfredericks: I mean... ~0 is clearly infinite so... we have to do something

13:47 andyf: Bronsa: I believe Alex Miller changed it early 2014 so that by default all project leads get email on all project JIRA ticket updates (with a few exceptions, probably clojure core itself)

13:47 olivierrr: That should do it andyf, thanks

13:47 Bronsa: ok

13:48 andyf: gfredericks: For Eastwood, extra dependencies are more pain than for the average project. I tend to copy in individual functions I want and attribute the source, if licenses are compatible. Only 3-4 functions right now, I think.

13:48 gfredericks: medley looks nice; enough overlap with plumbing that I probably won't use it though

13:48 arrdem: Bronsa: interesting comment about platform types. do you really find that dominates host interop forms?

13:49 andyf: I don't have full knowledge of the contents of Plumbing, Useful libs, for example, given their size and my lack of taking time to explore them fully.

13:49 gfredericks: every time plumbing doesn't have something I want I just make a PR

13:50 engblom: Has anyone managed to get Quil to run on Android?

13:50 gfredericks: I feel like there has to be a nicer way to do util libs but I have no idea what that is

13:50 Bronsa: arrdem: I wouldn't say they dominate host interop forms, but not having all the necessary predicates + unimported classes/interfaces makes it really hard to write "portable" clojure

13:50 arrdem: Bronsa: understood

13:50 andyf: Bronsa: arrdem: Even though notes on tickets should auto-email project leads, sometimes a private email can be effective, since it doesn't look auto-generated.

13:51 Bronsa: arrdem: I'm thinking about tools.analyzer. the only necessary jvm interop there is because of that & to work around clojure bugs

13:52 also not having ex-info? & ExceptionInfo auto-imported makes writing portable clojure unnecessarily difficult

13:53 arrdem: I'm very entertained by the automatic imports

13:53 Bronsa: entertained?

13:54 arrdem: I would not have thought of the code sharing that it enables and I think it's neat

13:54 Bronsa: andyf: I mean, if I have to go through all that trouble just to get a bug report noticed I might just use another library

13:56 andyf: Bronsa: Understood. hence the mention of Medley/Plumbing/useful, one of which may be more responsive.

14:08 stephenmac7: Is there a good reference for people who want to learn clojure but already know scheme?

14:09 Or, any other lisp dialect

14:10 andyf: Clojure: Also Lisp-1, use let or letfn instead of nested define/def, Clojure even more encouraging of defaulting to immutable data than Scheme

14:10 gfredericks: clojure.org has a list of differences

14:11 $google clojure clojure.org lisp

14:11 lazybot: [Clojure - lisp] http://clojure.org/lisp

14:11 gfredericks: that page is not what I meant

14:11 haha clojure.org/lisps is it

14:12 godd2: stephenmac7 try http://www.braveclojure.com/getting-started/

14:12 dc_: who's the guy that does Cursive Clojure?

14:12 Bronsa: dc_: cfleming

14:13 andyf: I came across this via a few Google search terms, but don't know whether I would recommend it yet, as I haven't dug through it, and the fact that it mentions Clojure version 1.2 at the top (about 4 years since that was released?) is not greatly encouraging: http://hyperpolyglot.org/lisp

14:13 dc_: Bronsa: cool, thanks

14:13 stephenmac7: gfredericks: andyf: godd2: Thanks

14:13 Bronsa: andyf: yeah that's really old & has some unidiomatic clojure code

14:14 andyf: Yes, scanning through Clojure examples I can see some of those

14:14 Glenjamin: gfredericks: i've had this idea for a while to make a "lein misc" which builds a util.clj by letting you depend on individual functions

14:15 dc_: cfleming: i'm having a minor issue in cursive involving the debugging. when i add breakpoints to my code, execution halts on those breakpoints the first time i run the function that contains them, but not after that. i have to rerun the debugged REPL to trigger the breakpoints again

14:15 cfleming: i'm not sure if it's an actual error or just user error

14:15 gfredericks: Glenjamin: ah ha so the main difference would be your requires, right?

14:16 Glenjamin: i've not thought too heavily about it, but the rough idea is you'd require myproject.utils :as utils, and put something in project.clj that's used to generate myproject/utils/clj

14:16 gfredericks: Glenjamin: this reminds me of dot-slash & lein-shorthand, but would be more production-oriented than dev-oriented

14:17 Glenjamin: yeah, i think it's similar. in this case i'd want a registry with functions and a dependency graph

14:17 gfredericks: dep graph?

14:18 Glenjamin: yeah, so i wrtil a util flatten-maps, which needs another util traverse-maps

14:18 gfredericks: you wrtil it?

14:18 Glenjamin: write

14:18 typing not my strong point today

14:18 gfredericks: I thought this was about using util libs, not writing them?

14:18 Glenjamin: it'd be like clojars for functions

14:19 gfredericks: oh you're trying to solve versioning and whatnot too

14:19 I'm thinking something more restrained

14:19 Glenjamin: basically i'd like to be able to take a few functions from useful, some from medly etc

14:19 gfredericks: it would mainly solve the problem of duplication between util libs and having to remember what namespaces all your dang utils come from

14:20 Glenjamin: ah, so you'd still pull them all in as the usual jars, but then rename them into a single ns?

14:20 gfredericks: so you would add all N util libs as deps to your project, and then have a list in the project.clj of the functions you want to use, and they get packaged into one namespace so you can require without thinking

14:20 andyf: Glenjamin: Someone put a link to a video of a talk by Mark Hibberd about annex recently that I watched part of. You might be interested in watching it. I'll send the video link if I can find it: https://thestrangeloop.com/sessions/towards-annex-a-fact-based-dependency-system

14:21 Glenjamin: cheers andyf, will make sure it's on my to-watch list

14:21 andyf: Glenjamin: Making that work for what you want in Clojure is perhaps a much bigger job than the feature you're looking for, though.

14:21 gfredericks: paging hugoduncan

14:22 andyf: Glenjamin: here is the video link: https://www.youtube.com/watch?v=JjYAnBhF2JU

14:22 Glenjamin: ta

14:22 i should probably stop talking about it and start building it

14:22 gfredericks: Glenjamin: check out lein-shorthand first

14:23 Glenjamin: i just skimmed it now, looks pretty neat

14:23 doesn't solve the versioning/namespace conflict issue though :)

14:23 gfredericks: I'm thinking that's not too big a deal

14:23 for my use case

14:23 Glenjamin: probably not, but it's a fun* problem to tackle

14:24 *possibly not at all fun

14:25 gfredericks: things get drastically less fun once you have to start worrying about commiting to things that lots of people will use for years

14:27 csd_: Is there any way to put a constructor inside a defrecord call? Like (defrecord x [foo] #(rand-int 10)) where the function sets foo?

14:28 Glenjamin: you can replace the generated factory functions

14:29 csd_: Can you give an example?

14:30 Put another way I guess what I'm looking for is a way to create a record where it's properties are generated endogenously

14:30 andyf: Dang, I should have done this months ago -- support Eastwood warning output format in emacs compilation-mode buffer format. I could have saved myself so many hours

14:30 justin_smith: andyf: nice, please do - clickable links would be awesome

14:30 gfredericks: csd_: I think that's a problem you want to solve with not-just-records

14:30 i.e., use a regular function to do the logic you want

14:30 csd_: gfredericks: what do you mean?

14:31 andyf: It will definitely be in next release. I just finally implemented it a few mins ago

14:32 and started about 10 mins before that. I knew it wouldn't be hard, but just didn't do it.

14:32 csd_: have defrecord x and function x-caller to construct x?

14:34 kenrestivo: i'm having a brain-fart. is the most idiomatic way to modify keys (into {} (for [[k v] [k (something v)])) ? or is there less verbose way?

14:34 urg, sorry (into {} (for [[k v] m] [k (something v)]))

14:34 andyf: kenrestivo: that is most concise way I know of, if you don't use map-vals in some of the utils libraries.

14:35 Bronsa: kenrestivo: yeah there's no update-vals in clojure.core. you can use reduce-kv if you prefer

14:35 kenrestivo: right reduce-kv, thanks

14:35 Bronsa: andyf: I keep thinking update-vals is a better name for map-vals

14:36 gfredericks: csd_: yep

14:36 Bronsa: but it looks like everybody else disagrees with me on this one :P

14:36 csd_: ok well thanks

14:37 gfredericks: Bronsa: update suggests calling f once, map suggests N times

14:38 Bronsa: gfredericks: map-vals to me means (fn [f m] (map f (vals m)))

14:39 gfredericks: that one I always name call-vals-and-then-call-map-with-the-result

14:39 for clarity

14:39 andyf: (inc gfredericks)

14:39 lazybot: ⇒ 105

14:39 Bronsa: lol

14:40 andyf: verbosejure - it will make you swear for a different reason

14:41 gfredericks: (defn like-last-but-from-the-other-size [[x]] x)

14:41 andyf: coboljure

14:41 gfredericks: side*

14:48 hyPiRion: From experience it's not verbosejure. It's just common lisp.

14:50 I mean, when you have functions named update-instance-for-different-class

14:55 kenrestivo: haha, digging through old code, i found a function i didn't know what to name: https://www.refheap.com/93469

14:55 i think i was rewriting walk

14:56 andyf: *cough* unsigned-bit-shift-right

14:58 csd_: Is it possible for records to inherit fields from other records?

15:00 * gfredericks just pushed the monads in test.check a little farther below the surface

15:00 gfredericks: contrasigned-byte-buffer-shift-up-and-slightly-to-the-left

15:01 kenrestivo: but-not-too-far-i-dont-want-it-to-block-the-window

15:02 andyf: Reflection warnings give a file path name relative to the classpath they are in. Is there a way (without modifying the source code of Clojure itself) to get the full path, or at least prefix that with the classpath directory?

15:04 csd_: What is the proper way to subclass datatypes-- i.e. your typical Person, Employee example? Ostensibly, Employee should be able to inherit something like Person.name, rather than have its own name field for the same person

15:05 Bronsa: andyf: don't think so

15:06 gfredericks: csd_: there's a hodgepodge of approaches

15:06 andyf: I added full paths, or relative to the current working dir, to Eastwood warnings recently, and that saves me confusion of where files are. Do other people get confused by this?

15:07 csd_: gfredericks: I found this really long thread on the mailing list about it from back in 2012, but no one seemed able to agree on best practice

15:07 Some even said it's a bad idea to even try to do it (I don't know what the alternative would be?)

15:07 andyf: I mean, especially for cljx projects where they put auto-generated clj/cljs files in target/generated/foo/bar/baz

15:07 gfredericks: csd_: yeah I feel like somehow clojure users don't have a common use case they're attacking so nothing obviously standard has coalesced

15:07 csd_: are you literally dealing with an Employee type and a Person type?

15:08 csd_: Not that use specifically, but essentially

15:08 record-type Monster, and then subclass Orc that inherits Monster

15:08 gfredericks: csd_: I think the most interesting approach that I haven't actually done much with myself is multimethods, with inheritance hierarchies if necessary

15:08 andyf: csd_: If you are not dealing with existing class hierarchy, a common recommendation is "use maps with the fields you want, and write functions that operate on them, perhaps using preconditions or something like Schema to catch you if you try to pass the wrong 'map type' in"

15:09 gfredericks: yeah ^that approach is pretty normal too

15:09 csd_: andyf: so use merge to get the parent class fields?

15:09 gfredericks: parent?

15:09 csd_: the inheritee

15:09 gfredericks: oh merge like at construction-time?

15:09 andyf: csd_: There would be no separate classes using that approach, just maps with different collections of keys, and functions that operate on those maps

15:10 csd_: yes at construction time

15:10 gfredericks: yeah you could do that

15:10 csd_: i guess you could have the subclass be a value in the map of the parent too

15:10 does that make any sense

15:11 I have basically zero experience working with defrecords, deftypes, multimethods, etc in clojure

15:12 gfredericks: andyf is advocating one flat map per object

15:12 you could namespace the keys if you like that

15:12 csd_: So person foo gets two maps?

15:12 gfredericks: ,{:monster/name "ROhhohnvth" :orc/sword-length 11}

15:12 clojurebot: {:orc/sword-length 11, :monster/name "ROhhohnvth"}

15:13 gfredericks: no when I said "one" I specifically meant "not two"

15:13 andyf: csd_: Caveat emptor: I haven't gone off and written big systems using that approach, so can't give any info based on experience on what the pros/cons of that approach are, but I think some Clojure developers have.

15:13 gfredericks: I can see how it could be interpreted both ways though :)

15:13 csd_: I see, I was thinking of Employee and Person representing distinct objects

15:13 gfredericks: maybe I shoulda said "instance"

15:14 csd_: The truth is this is just toy code. I just want to learn how to do things the Right Way

15:14 gfredericks: clojure doesn't have a lot of right ways in this area

15:15 csd_: For a beginner, difficulty is directly proportional to lack of established consensus

15:15 yeah

15:15 gfredericks: if you just want to inherit base functionality, just write a function that does the same thing for everything. If you need per-type overrides, try a multimethod.

15:15 csd_: I'm more concerned with being able to inherit the parent fields

15:16 multimethods wouldn't fix that I don't think

15:16 gfredericks: yeah merge in your constructors is fine

15:16 csd_: I guess I'll give maps a go

15:16 gfredericks: where "constructors" are regular functions

15:16 they're the most flexibleest

15:17 csd_: So you think I should just get rid of defrecords altogether for this use case?

15:17 gfredericks: yeah

15:17 bbloom: Bronsa: how hard would it be to do what i proposed in https://groups.google.com/d/msg/clojure-dev/6pnIeXFRwnI/_KyMvgtszOsJ ?

15:17 Bronsa: my guess is relatively easy, but you're the tools.reader expert

15:17 csd_: ok

15:18 thanks

15:18 gfredericks: csd_: it's actually pretty normal to antirecommend defrecord for beginners

15:18 csd_: I've seen that

15:19 I see the advantage but I imagine most people coming from an OO background feel uncomfortable with it

15:19 bbloom: gfredericks: https://github.com/clojure/clojure/blob/05af4b52a474bc60d2eb931e388b302c14edc884/src/jvm/clojure/lang/Numbers.java#L1096 maybe there's a reason?

15:20 Bronsa: bbloom: should be quite trivial, yes btw wrt "uninterpreted tagged literals", clojure/tools.reader have *default-data-reader-fn*

15:23 bbloom: another place where the reader depends on an available namespace env is for var qualification on syntax-quote

15:23 gfredericks: bbloom: yeah andyf unearthed a discussion that suggested that other types require extra logic for weird shifting cases, thus not worth it

15:24 bbloom: arrdem: assuming twos-complement, shouldn't the bit width not matter?

15:24 andyf: bbloom: negative numbers and complement leave options available

15:26 bbloom: andyf: extra dependencies are a pain for all projects... people just don't realize it right away

15:26 andyf: bbloom: no argument. I've just imposed some extra pain on myself for Eastwood

15:30 annelies: https://twitter.com/lvsn/status/533685461957349376

15:32 estKris: Hi, a clojure beginner here, would anyone be willing to show me a way to construct something like this [[0 0] [0 1] [0 2] [1 0] [1 1] .. [2 2]] in a Clojure like style :)


15:32 andyf: ,(for [v1 (range 3) v2 (range 3)] [v1 v2])

15:32 clojurebot: ([0 0] [0 1] [0 2] [1 0] [1 1] ...)

15:33 annelies: ,(for [x (range 3), y (range 3)] [x y])

15:33 clojurebot: ([0 0] [0 1] [0 2] [1 0] [1 1] ...)

15:33 csd_: ,(for [x x] (range 3))

15:33 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:33 annelies: Oh. :P

15:33 csd_: (for [x (range 3)] [x x])

15:33 andyf: Better 3 answers than 0 :)

15:33 csd_: ,(for [x (range 3)] [x x])

15:33 clojurebot: ([0 0] [1 1] [2 2])

15:34 csd_: ok dont listen to me

15:34 annelies: Actually

15:34 ,(vec (for [x (range 3), y (range 3)] [x y]))

15:34 clojurebot: [[0 0] [0 1] [0 2] [1 0] [1 1] ...]

15:37 estKris: Haha, excellent, many thanks. I was hesitating to use (for ) as I thought it was not the "Clojure way" of doing things. Am I trying to hard to be functional or is for a part of functional programming as well?

15:37 Bronsa: estKris: clojure's for is not the imperative for

15:37 andyf: estKris: Clojure's for is functional, if you don't do side effects inside of it yourself.

15:37 csd_: clojure's implementation of for is functional

15:38 estKris: Man, you guys are eager to help, seems what I've heard about Clojures community is true :)

15:39 mi6x3m: hey clojure, is it customary to have predicates with more than 1 argument?

15:39 like

15:39 deps-in-order? [a b]

15:41 annelies: If you need it, you need it.

15:42 Though something like deps-in-order? would be variadic, like < and > are.

15:47 gfredericks: $google github gfredericks compare

15:47 lazybot: [gfredericks (Gary Fredericks) · GitHub] https://github.com/gfredericks

15:47 gfredericks: that was insufficient

15:49 andyf: gfredericks: If you are interested in functions that get, if not all the way, at least closer to being able to compare arbitrary objects, I've got some code for you

15:51 gfredericks: andyf: I have a library that just does clojure.core/compare on things

15:51 which is good enough for most of my purposes

15:52 andyf: gfredericks politely and deftly deflects andyf's subtle attempt to foist off code maintenance on him.

15:52 gfredericks: andyf: what're you trying to maintain

15:53 andyf: nothing :)

15:53 gfredericks: out with it

15:54 andyf: Seriously, I have a tiny bit of example code in thalia docs that shows how to generalize compare to be able to work for a larger variety of pairs of things. 1 or maybe 2 people have asked if I have put it in a lib somewhere, but I haven't.

15:54 annelies: gfredericks: I'm looking at your qubit library.

15:54 andyf: your lib has the right name

15:54 gfredericks: andyf: :)

15:54 annelies: AFAIK qubits can only be observed once. Why can it be observed twice in your library?

15:54 gfredericks: annelies: I've never heard that

15:55 annelies: Oh wait nevermind.

15:55 gfredericks: subsequent observations are trivial to my knowledge -- you keep getting the same result

15:55 annelies: You observer them multiple times you get the same alue.

15:55 bbloom: Bronsa: what type does that return?

15:55 Bronsa: bbloom: whatever you make it return

15:56 bbloom: Bronsa: if you look at transit, it has a custom type for tagged values

15:56 annelies: brainfart :p

15:57 Binary X is controlled NOT right?

15:57 bbloom: Bronsa: seems like there should be a way for all reader evaluated forms to be defined in terms of unknown tagged literals

15:57 Bronsa: for example, both `... and (clojure.core/syntax-quote ...) could become #clojure.core/syntax-quote ...

15:57 Bronsa: http://sprunge.us/CPVf?clj

15:57 gfredericks: annelies: right

15:58 bbloom: Bronsa: and ::foo/bar could become #clojure.core/keyword [#clojure.core/resolve-alias-or-something foo bar]

15:58 annelies: I always wanted to implement this in Clojure but I never actually did it.

15:58 Have a star.

15:58 bbloom: Bronsa: similar story for wherever feature expressions land

15:58 seems like it would address the "more reader features hurts tooling!" complaint

15:58 Bronsa: bbloom: yeah, that's a solution

15:58 gfredericks: annelies: thanks :) I spent a while a couple weeks ago trying to implement shor's algorithm. lots of binary arithmetic work.

15:59 Bronsa: bbloom: those return value would need a backing type, not sure if it should be the job of tools.reader to define that type though

15:59 andyf: gfredericks: In case you every have more time than sense: https://github.com/jafingerhut/thalia/blob/master/src/thalia/comparators.clj

15:59 * bbloom waits for 3 people to show `for expressions simultaneously

15:59 bbloom: i expected at least one more :-P

15:59 i must have counted myself when i decided not to answer

15:59 :-)

16:00 gfredericks: andyf: what on earth

16:00 bbloom: are you watching this channel with a 10 minute delay?

16:00 andyf: he's catching up

16:00 godd2: he's on challenge mode

16:01 gfredericks: I guess I shouldn't expect a response for another ten minutes

16:01 andyf: test msg to see if my IRC client stays scrolled back in history if I type a message

16:01 ok, he's not using the same client I am then :)

16:02 bbloom: ,(doc instance?)

16:02 clojurebot: "([c x]); Evaluates x and tests if it is an instance of the class c. Returns true or false"

16:02 bbloom: ,(doc satisfies?)

16:02 clojurebot: "([protocol x]); Returns true if x satisfies the protocol"

16:02 Bronsa: ahah, he definitely is

16:02 bbloom: ,"hello?"

16:02 clojurebot: "hello?"

16:02 bbloom: &"hi?"

16:02 lazybot: ⇒ "hi?"

16:02 annelies: gfredericks: implementing Shor's algorithm is a fun exercise. Gonna try that with your library :)

16:02 gfredericks: annelies: let me know if you succeed

16:02 andyf: All the talk of qubits has caused bbloom to become a Dr. Who-like time traveler

16:03 Bronsa: I bet those were to answer mi6x3m question about 2-args predicates

16:03 gfredericks: I figured he was just reading the backlog until he made the comment expecting everybody else's responses imminently

16:03 ghost_of_bbloom: bbloom: wtf?

16:03 seems like my outbound messages are delayed...

16:03 gfredericks: oh right that's the other way this could happen

16:04 Bronsa: ghost_of_bbloom: yeah we have all been talking about it for the last 5 minutes

16:04 ghost_of_bbloom: you'll catch up with the rest of the world in about 3 minutes

16:04 ghost_of_bbloom: ghost_of_bbloom: so werid

16:05 annelies: gfredericks: fo' shor

16:05 SCNR

16:05 ghost_of_bbloom: nope

16:05 restarting my irc client didn't seem to fix it

16:06 i feel like somebody is playing a prank on me ...

16:06 bbloom: ghost_of_bbloom: ping

16:06 gfredericks: annelies: every time I implement qubit math I get mad at trig functions and having to use floating point

16:06 annelies: Probably the hardest part is getting the library to work. :V

16:06 I have never used a non-Maven library with Clojure.

16:06 Like, from project.clj.

16:07 justin_smith: annelies: like, nothing from clojars?

16:07 gfredericks: annelies: `lein install` will put it in your local

16:07 annelies: Yeah clojars.

16:07 Ah ok.

16:07 Bronsa: annelies: clone the repo and lein install it

16:07 gfredericks: but I never released it because it did not occur to me anybody would use it that way

16:08 ghost_of_bbloom: this explains why puredanger was ignoring me the other day...

16:08 andyf: so the delay is gone now, I take it.

16:08 ghost_of_bbloom: no, i'm using a web-based irc client

16:08 annelies: gfredericks: I'll put it up here: https://github.com/rightfold/shor

16:08 gfredericks: hey bbloom how many fingers am I holding up

16:08 bbloom: gfredericks: 3

16:09 gfredericks: bbloom: correct

16:09 bbloom: oh hey, looks like that one was fast?

16:09 gfredericks: yep

16:09 bbloom: stupid distributed systems.

16:20 gfredericks: ~distributed systems |are| stupid

16:20 clojurebot: Ik begrijp

16:24 annelies: woot clojurebot knows Dutch

16:33 bbloom: namespaced keywords are weird.

16:34 intuitively, un-namespaced keywords feel like global variables to me

16:34 but that just doesn't seem to match the experience of using them

16:34 until you want to make something remotely extensible, then it's like "oh crap. everybody behave themselves and namespace your keywords!"

16:34 meanwhile...

16:34 ,(def foo foo)

16:35 clojurebot: #'sandbox/foo

16:35 andyf: #cloure is not available right now. It should be able to read your message in 10 minutes, when we will get back to you.

16:35 bbloom: ,{foo 123}

16:35 clojurebot: {#<Unbound Unbound: #'sandbox/foo> 123}

16:35 bbloom: andyf: heh

16:37 andyf: bbloom: The (def foo foo) thing leaving foo unbound has something to do with keyword namespacing, or another topic?

16:37 hyPiRion: that's different from kw namespacing

16:37 bbloom: andyf: related thought. idea being that a keyword is just an undeclared self-evaluating symbol

16:38 the fact that it's undeclared is convenient and also problematic

16:38 Factor, for example, doesn't have "keywords"

16:38 instead there is http://docs.factorcode.org/content/word-SYMBOL__colon__,syntax.html

16:38 which basically is the same as (def foo foo)

16:39 hyPiRion: ,(declare bar)

16:39 clojurebot: #'sandbox/bar

16:39 hyPiRion: ,bar

16:39 clojurebot: #<Unbound Unbound: #'sandbox/bar>

16:39 bbloom: maybe it's more like:

16:39 ,(def foo 'foo)

16:39 clojurebot: #'sandbox/foo

16:39 bbloom: ,foo

16:39 clojurebot: foo

16:39 andyf: The (def foo foo) thing has been mentioned in a recent ticket. http://dev.clojure.org/jira/browse/CLJ-1591

16:39 Bronsa: ,(def foo #'foo)

16:39 clojurebot: #'sandbox/foo

16:39 Bronsa: ,foo

16:39 clojurebot: #'sandbox/foo

16:40 bbloom: i'm just thinking through the design space a bit

16:40 andyf: I believe there is a rationale for it: it makes it easier in the implementation (or no other reasonable way?) to have functions call themselves recursively via their vars.

16:40 bbloom: in mathematica, symbols self-evaluate unless they have definitions

16:40 Bronsa: andyf: yup

16:41 hyPiRion: bbloom: so in Forth, "keywords" have to be defined before used? And they're self-evaluating and namespaced?

16:41 I guess that makes sense

16:41 Bronsa: andyf: also useful for recursive lazy-seqs

16:41 bbloom: hyPiRion: not forth, that's factor

16:41 hyPiRion: Factor : Forth :: Clojure : Common Lisp -- i guess

16:42 but yeah, namespaced... they call them "vocabularies" though

16:42 mi6x3m: thanks to all for the deps-in-order? answers :)(

16:42 I was away

16:42 bbloom: weirdly lots of places in Factor use strings instead of symbols

16:43 hyPiRion: hrm

16:43 bbloom: another thing about "declaring" keywords, is that you need to import them too

16:43 which is also true of double-colon keywords in clojure with alias

16:44 annelies: gfredericks: why does this work? https://github.com/gfredericks/qubits/blob/master/src/com/gfredericks/qubits/examples/deutsch_jozsa.clj#L42

16:44 Isn't map lazy?

16:45 mi6x3m: thanks for the answer some time ago annelies :)

16:47 andyf: annelies: It is, and that looks like either a bug, or at least dead code.

16:49 bbloom: another thought: double colon keywords are a copy/paste nightmare

16:49 every time i've used them, copy-pasting burns me

16:53 mi6x3m: what would you pick for a a plural of ns (namespace)?

16:54 andyf: mi6x3m: nss

16:54 mi6x3m: yeah thought so too

16:56 kenrestivo: i've always wondered about the frequent lein trampoline errors like Exception in thread "main" java.io.FileNotFoundException: /home/src/target/84fe468ce05c57c6782ee7bc16cc0a927b58c9a8-init.clj

16:57 rm -rf target/trampolines seems to clear them out, but not sure why they happen

17:04 olivierrr: !clj (str "testing")

17:04 clojure-eval: "testing"

17:05 kenrestivo: what is !clj?

17:05 new bot?

17:05 !clj (str "~clj! is a new bot")

17:05 clojure-eval: "~clj! is a new bot"

17:05 olivierrr: yeah :p

17:06 danielcompton: ooh, a new bot to play with

17:06 kenrestivo: !clj (println "~clj! is a new bot")

17:06 clojure-eval: ~clj! is a new bot

17:06 nil

17:06 clojurebot: A nod, you know, is as good as a wink to a blind horse.

17:06 kenrestivo: :-P

17:06 wink: dammit clojurebot, shut up

17:06 kenrestivo: three bots, no waiting.

17:06 * danielcompton !clj (mine-bitcoins)

17:07 * danielcompton !clj (str "test)

17:07 justin_smith: haha

17:07 olivierrr: !clj (range)

17:07 kenrestivo: hahah

17:07 bot torture

17:08 justin_smith: more like checking the bot's basic viability

17:08 bbloom: ,"you don't see the" #! comment macro too often, huh?

17:08 clojurebot: "you don't see the"

17:08 kenrestivo: ooh, didn't know about that one

17:08 #_, sure but not #!

17:08 * kenrestivo goes diving for documentation

17:09 bbloom: i'm not sure #! offers anything that ; doesn't

17:09 justin_smith: it's for #!java -jar

17:09 danielcompton: in shell land, not clojure land?

17:09 jeffterrell: ,"testing multiple forms in eval" (+ 1 2)

17:09 clojurebot: "testing multiple forms in eval"

17:09 kenrestivo: ah! that explains that syntax in lein bin files

17:09 justin_smith: danielcompton: for shell scripts that are really cjojure files

17:09 danielcompton: on those operating systems that don't make it impossible

17:09 bbloom: aaaahh duh, #! is for scripts

17:09 dur

17:09 danielcompton: justin_smith: do you have an example?

17:10 kenrestivo: i guess just yer basic #!/bin/bash

17:10 danielcompton: or are we just talking about basic shell scripts?

17:10 kenrestivo: bbloom: yeah, but i wouldn't expect that as a reader macro

17:10 jeffterrell: ,"testing again: should throw exception if 2nd form eval'd" (- a b)

17:10 clojurebot: "testing again: should throw exception if 2nd form eval'd"

17:10 justin_smith: danielcompton: basic shell script, where the top like is something like #!/usr/bin/java -jar clojure.jar

17:11 and the rest is your clojure file

17:11 danielcompton: justin_smith: ah that's cool, hadn't thought of doing it that way

17:11 justin_smith: danielcompton: turns out, on linux passing args on the top line of a shell script doesn't work

17:12 danielcompton: justin_smith: is there any other OS?

17:12 justin_smith: but you could use another OS, or make a "clj" program, and make the top like be #!/bin/clj

17:12 or whatever

17:12 danielcompton: justin_smith: so it works in OS X?

17:12 justin_smith: danielcompton: iirc bsd based systems allow args on the shebang line

17:12 yeah

17:13 danielcompton: brb just swapping linux servers for Mac Pro's in the data center

17:13 justin_smith: haha

17:14 maybe easier to just make that clj program :)

17:14 danielcompton: or lein run?

17:14 justin_smith: no args, remember

17:14 oh yeah, just using lein run, sure

17:16 kenrestivo: huh, says it works on windows, mac, and linux: https://github.com/Raynes/lein-bin

17:20 man i gotta get with this schema program. tired of trying to remember which map structure i'm dealing with in which function

17:21 danielcompton: why are we able to alias clojure.set to set, and still use (clojure.core/)set without qualifying it?

17:23 justin_smith: danielcompton: namespaces and vars are not in the same namespace

17:23 it is never ambiguous whether the thing you refer to is a namespace or a var

17:27 danielcompton: justin_smith: so set/intersection is resolved to clojure.set/intersection?

17:28 Bronsa: danielcompton: correct

17:37 justin_smith: yeah

17:49 * danielcompton ,(doc <=)

17:57 gfredericks: annelies: yeah that map call looks like something I should've used doseq for...or should probably just delete;

17:57 thanks!

17:57 clojurebot: Huh?

17:59 gfredericks: annelies: even if it wasn't lazy it wouldn't change the outcome, so I think it was just there in an older version of the function

18:05 danielcompton: !clj (doc <=)

18:05 clojure-eval: -------------------------

18:05 clojure.core/<=

18:05 ([x] [x y] [x y & more])

18:05 Returns non-nil if nums are in monotonically non-decreasing order,

18:05 otherwise false.

18:05 nil

18:05 gfredericks: what

18:05 arrdem: whois clojure-eval

18:06 lodin: Maybe the wrong channel, but is there a word for functions that map types from a to (x a), and conversely for functions that maps from (x a) to a? (E.g. vector resp. first.)

18:06 danielcompton: olivierrr might know

18:06 gfredericks: ,(println "!42")

18:06 clojurebot: !42\n

18:06 gfredericks: ,(print "!clj 42")

18:06 clojurebot: !clj 42

18:06 clojure-eval: "!clj 42"

18:06 42

18:06 gfredericks: what

18:06 ,(* 2 3 7)

18:06 clojurebot: 42

18:07 danielcompton: irc bot quine

18:07 olivierrr: clojure eval... evals clojure

18:07 arrdem: kenrestivo: what's unique about clojure-eval

18:07 since clojurebot and lazybot still exist :P

18:07 gfredericks: ,(print "!clj (println \",42\"))

18:07 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

18:07 gfredericks: ,(print "!clj (println \",42\")")

18:07 clojure-eval: "!clj (println \",42\")"

18:07 clojurebot: !clj (println ",42")

18:07 clojure-eval: ,42

18:07 nil

18:07 clojurebot: 42

18:08 gfredericks: welp

18:08 olivierrr: it's my bot arrdem, no real reason for it

18:08 danielcompton: ,(println "println \"!clj println "))

18:08 clojurebot: println "!clj println \n

18:08 clojure-eval: "println \"!clj println "

18:08 gfredericks: it's only a matter of time now

18:08 arrdem: amalloy: yo ignore can lazybot clojure-eval before this gets out of hand

18:08 hiredman: you can't here me, but it's time to add to the ignore list

18:09 gfredericks: don't some of them do throttling anyhow?

18:09 &(inc 41)

18:09 lazybot: ⇒ 42

18:09 gfredericks: &(inc 41)

18:09 lazybot: ⇒ 42

18:09 gfredericks: &(inc 41)

18:09 lazybot: ⇒ 42

18:09 gfredericks: &(inc 41)

18:09 lazybot: ⇒ 42

18:10 gfredericks: &(inc 41)

18:10 lazybot: ⇒ 42

18:10 gfredericks: &(inc 41)

18:10 lazybot: ⇒ 42

18:10 Bronsa: olivierrr: we already have 2 bots, what's the reason for another one?

18:10 gfredericks: &(inc 41)

18:10 lazybot: ⇒ 42

18:10 gfredericks: &(inc 41)

18:10 lazybot: ⇒ 42

18:10 gfredericks: looks like it

18:10 er

18:10 arrdem: Bronsa: none apparently

18:10 gfredericks: nevermind

18:10 arrdem: gfredericks: lazybot doesn't have ratelimiting, he has throttling on concurrent ops

18:10 olivierrr: no reason Bronsa

18:10 godd2: "We already have X programming languages, what's the reason for X+1 of them?"

18:11 amalloy: $login

18:11 lazybot: You've been logged in.

18:11 amalloy: $reload

18:11 lazybot: Reloaded successfully.

18:11 Bronsa: godd2: that's a really moot argument, adding useless bots to a channel is only going to create confusion

18:11 godd2: I agree, I was just being obtuse :P

18:13 gfredericks: !clj (println "&'testing-lazybot")

18:13 Bronsa: gfredericks: the bot quit

18:13 olivierrr: killed the bot

18:13 gfredericks: bye bye bot

18:13 olivierrr: since we already have one

18:13 cfleming: dc_: Are you on IntelliJ 14?

18:13 arrdem: olivierrr: thanks

18:13 amalloy: thanks, sorry for the ping

18:14 danielcompton: pour one out for clojure-eval, we barely knew ye

18:14 * arrdem throws his glass at the fireplace, misses

18:14 cfleming: dc_: The breakpoints have always been slightly flaky, but v14 seems to have broken a lot of debugger functionality, they changed a bunch of their APIs.

18:14 godd2: ,(print ",(print \"hello, world\")")

18:14 clojurebot: ,(print "hello, world")

18:15 olivierrr: hahah, no worries, he lives in #learnclojure

18:15 danielcompton: olivierrr: good to know he hasn't gone to the great garbage collector in the sky

18:17 godd2: who needs garbage collection when you can just unplug your computer?

18:18 pdk: yea

18:19 if your application's requirements don't account for periodic hard reboots you got some problems!

18:36 gfredericks: that's not even a joke is it; I heard something about jvm restarts being a decent GC approach for low-latency app servers

18:37 bbloom: i believe that's what we call "region based memory management"

18:37 where region == the entire damn vm

18:38 arrdem: Okay. anyone with a live repl and two seconds, please try running cider-grimoire on a symbol and see if you get HTML

18:38 kbd C-c C-d C-g

18:40 gfredericks: you made my computer touch the internet

18:40 I have a *cider grimoire* buffer that appears to be empty

18:40 arrdem: what did you doc?

18:40 what symbol

18:47 gfredericks: +

18:47 from a repl buffer not a normal source buffer

18:49 arrdem: weird that worked just fine for me

18:49 I didn't see a request for + go into the logs except mine

18:53 gfredericks: this mccarthy paper just pointed out that and/or are not commutative

18:53 which hadn't occured to me

18:55 they are if the inputs are strictly booleans

18:56 TimMc: and not side-effecting expressions :-)

18:57 gfredericks: yeah I meant booleans in the concrete sense

18:57 not "thing that supposedly evaluates to a boolean"

18:57 which is what you'd get in a statically typed language, e.g.

19:09 danielcompton: cfleming: I'm liking the unused vars feature. Was just thinking about it this morning

19:10 cfleming: danielcompton: Awesome - yeah, I like that one too.

19:10 danielcompton: It's not 100% reliable - the offline one will be.

19:10 danielcompton: But it shouldn't produce false positives.

19:10 danielcompton: cfleming: Analyze > Inspect Code ?

19:11 cfleming: danielcompton: Yeah, but that inspection doesn't work offline yet, only in the editor.

19:11 danielcompton: You can use Analyze->Inspect to find all unused imports and aliases though, and you can even fix all the imports at once.

19:12 danielcompton: Just create an inspection profile with those two inspections and run it over all your code.

19:12 danielcompton: You can also configure that to be run before you commit.

19:13 danielcompton: There'll be more unused items found in use/require statements soon too.

19:14 danielcompton: It's kind of embarrassing how much I managed to clean up my own code just with those two.

19:16 danielcompton: cfleming: that's really cool, didn't realise you could run it before committing

19:17 * danielcompton deletes half of util namespace

19:17 cfleming: Haha

19:17 It's amazing how satisfying deleting code is, given that it's also fun to write.

19:19 TEttinger: cfleming: are you the coolguy behind Cursive? I can't remember

19:20 cfleming: TEttinger: Um, well, I'm the guy behind Cursive, yes

19:20 TEttinger: The jury is out on how cool I am though.

19:21 TEttinger: it seems really nice! it's good to have more IDE support and it makes clojure much more usable to folks like me who can't grok emacs

19:21 arrdem: eh you build good tools you can't be all bad

19:21 cfleming: TEttinger: Thanks! I'm glad it's useful - having it be easier to use is definitely a major goal.

19:22 arrdem: *blush*

19:22 arrdem: lol

19:23 there is a special place in hell where you have to use tools you made a long time ago

19:23 cfleming: Man, I don't want to go there.

19:24 My last real job was working on an IDE product - occasionally I went back to try versions from 6 months or a year earlier, it's really painful.

19:27 cfleming: It helps when your issue tracker is overflowing to remember that you're still much better off now than you were then

19:27 kenrestivo: ~garbage collection

19:27 clojurebot: Huh?

19:28 kenrestivo: ~garbage collection is who needs garbage collection when you can just unplug your computer?

19:28 clojurebot: Gabh mo leithscéal?

19:28 arrdem: kenrestivo: ~garbage collection |is| ...

19:28 kenrestivo: ~garbage collection |is| who needs garbage collection when you can just unplug your computer?

19:28 clojurebot: Cool story bro.

19:28 kenrestivo: ~garbage collection

19:28 clojurebot: It's greek to me.

19:28 TEttinger: ~garbage colection

19:28 clojurebot: excusez-moi

19:28 kenrestivo: aw, nevermind

19:28 arrdem: kenrestivo: sorry. you don't need the leading ~

19:29 TEttinger: clojurebot: garbage collection |is| something you don't need, since you can just unplug your computer?

19:29 clojurebot: Titim gan éirí ort.

19:29 TEttinger: ~garbage colection

19:29 clojurebot: Pardon?

19:29 kenrestivo: it was funny the way godd phrased it.

19:29 TEttinger: didn't see it

19:30 hm, are any facts working?

19:30 ~anyone

19:30 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

19:30 danielcompton: ~clojurebot

19:30 clojurebot: clojurebot is a multimap

19:31 TEttinger: clojurebot: garbage collection is who needs garbage collection when you can just unplug your computer?

19:31 clojurebot: Pardon?

19:31 TEttinger: ~garbage colection

19:31 odd

19:31 ~garbage collection

19:31 arrdem: I had a writeup of this on clojurewiki... but it looks like bitemyapp has deleted that site

19:32 TEttinger: lol

19:32 arrdem: better go read the lazybot source code

19:32 TEttinger: clojurebot

19:32 arrdem: s/lazybot/clojurebot/g

19:32 TEttinger: $help

19:32 lazybot: You're going to need to tell me what you want help with.

19:33 TEttinger: @help

19:33 gah

19:36 amalloy: TEttinger: clojurebot won't accept factoids with a ? in them

19:36 TEttinger: haha

19:36 wow

19:37 clojurebot: garbage collection |is| who needs garbage collection when you can just unplug your computer

19:37 clojurebot: c'est bon!

19:37 TEttinger: ~garbage collection

19:37 clojurebot: garbage collection is who needs garbage collection when you can just unplug your computer

19:37 TEttinger: yay amalloy

19:37 (inc amalloy)

19:37 lazybot: ⇒ 190

20:43 emaczen`: Can I ask someone here about clojure's luminus web framework?

20:46 TEttinger: emaczen`, you can ask your question, it might help get an answer sooner

20:46 arrdem: ~ask applies here

20:46 not that I can activate it...

20:47 TEttinger: ~ask

20:47 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

20:48 arrdem: also going by Grimoire's traffic logs, US buisness hours account for ~75% of traffic so asking during those hours here is likely to reach more active people.

20:49 TEttinger: or ask TEttinger whenever it isn't US business hours

20:49 emaczen`: Okay

20:49 TEttinger: get online at 4:00 PM, go offline at 4:00 AM

20:49 arrdem: hehe

20:50 danielcompton: emaczen`: you had a question?

20:50 emaczen`: Yes, I am trying to express it cleanly...

20:51 So, I am trying to serve my local mongodb database with the luminus framework.

20:52 If you run lein new luminus <app-name> +mongodb -- you get a nice template.

20:52 Then running lein ring server, is pretty much where I am at.

20:53 A browser will open, and it tells me my mongo connection is not happening... and just says I need to go to /src/app-name/db/core.clj and set the connection parameters, but I had no diea what these are.

20:54 I have been able to connect to my mongodb instance with a clj repl... but everything I have tried does not seem to work...

20:54 Am I making any sense to anyone? hah

20:54 TEttinger: emaczen`, yeah, I've used mongo a bit

20:54 arrdem: /src/<app-name>/db/core.clj should be a file in your generated source tree..

20:55 emaczen`: Yes, everything I have tried in there (like I did when I experimented in the REPL) is not working...

20:55 arrdem: should be able to just go edit it as the error says

20:55 TEttinger: you're running mongod (the daemon process) right?

20:55 emaczen`: Yep.

20:55 arrdem: restart the app with the edited file?

20:55 the app won't magically reload on changes..

20:55 * usually

20:56 emaczen`: I did lein clean and lein compile -- is that sufficient for restart?

20:56 Then lein ring server again of course.

20:56 TEttinger: Yes, I am running mongod

20:56 arrdem: There isn't an official error message? It looks just like html..

20:57 dc_: lulz @ topic

20:57 newer versions with still higher numbers

20:57 but how high?

20:58 arrdem: something something drill something heavens

20:59 TEttinger: emaczen`: http://clojuremongodb.info/articles/connecting.html you can use some clojure wrappers around mongo to make this easier

21:00 emaczen`: TEttinger: This template uses monger as a dependency. Also, I have successfully connected to Mongo from the REPL using monger.

21:01 TEttinger: good good. then the info there should be applicable

21:01 should be the same connection params, really...

21:06 emaczen`: Can someone verify that my 'compiling' step is correct/

21:06 I use, lein clean

21:06 Then lein compile

21:06 then lein ring server

21:09 arrdem: you don't need to clean or compile unless you're using AOT

21:10 emaczen`: arrdem: what is AOT?

21:10 arrdem: also you can do "lein do clean, compile, ring server" to only spin up one JVM for lein

21:10 emaczen`: class generation, which you almost certainly aren't

21:10 emaczen`: Then it is sufficient to just kill my server and restart it?

21:11 arrdem: yep

21:11 emaczen`: cool.

21:12 arrdem: you can actually do better than that if you've got emacs or some other REPL set up...

21:12 you can boot and kill your server from the repl meaning you never restart Clojure

21:12 you just reload code

21:29 emaczen`: arrdem: I toyed around with the Austin repo for attaching cider to a browser repl -- do you know what I am tlaking about?

21:29 arrdem: emaczen`: can't help you with cljs stuff sorry :/

21:30 emaczen`: could you help me get setup with what you were talking about then? I see what you mean, restarting a server is kinda slow...

21:31 arrdem: emaczen`: https://www.refheap.com/93493

21:31 oops

21:31 https://github.com/clojure-grimoire/grimoire/blob/master/src/grimoire/web/service.clj

21:55 andyf: ~anyone

21:55 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

21:56 andyf: Sorry, that was intended to be a response from before I last dropped off for 45 mins -- I didn't check the time stamps when I should have.

22:04 gfredericks: andyf: based on the symptoms I diagnose you with bbloomitis

22:05 andyf: give it to me straight, doc. Don't sugar coat it.

22:05 gfredericks: andyf: you've only got 3 months to release a programming language.

22:06 arrdem: (inc gfredericks)

22:06 lazybot: ⇒ 106

22:06 arrdem: good lord when did you rack up that much karma

22:06 gfredericks: makin jokes

22:06 arrdem: well I'm laughing now, so I can't disagree

22:06 andyf: making refined jokes for the discerning palate, I would say.

22:07 kenrestivo: really, most of the traffic on grimoire is business hours? that's pretty amazing. either that means clojure is something heavily used at work, or used as a way to slack off while at work.

22:07 andyf: Probably many of them with subtle hINCs that not only don't make people wINCe, but convINCe them of what they ought to do next.

22:08 gfredericks: andyf: was that a recipe for tripling your karma throughput?

22:08 arrdem: kenrestivo: so that's what Google Analytics reports, but I think it's lying because my server side logging suggest 10x more traffic-ish

22:08 kenrestivo: but yeah 2-4pm CST is peak Grimoire traffic time IIRC

22:08 andyf: No, I was just accusing you of using subliminal advertising in your jokes.

22:08 gfredericks: (inc andyf)

22:08 lazybot: ⇒ 8

22:08 andyf: Shoot, I did it again -- explaining the obvious. My son is trying to cure me of that.

22:09 gfredericks: I'd give you two more but lazybot won't let me

22:10 kenrestivo: HINcs? what is that? Happy Isles Nature Center? Haskell Indians Nations College?

22:10 andyf: With most or all of the Internet available, I have a hard time believing people would slack off while browsing grimoire (no offense, arrdem -- I like it, but slacking off while using it?)

22:10 kenrestivo: ~hinc

22:10 clojurebot: Gabh mo leithscéal?

22:11 kenrestivo: ~Gabh mo leithscéal?

22:11 clojurebot: Gabh mo leithscéal?

22:11 arrdem: andyf: yeah... reading docs is not my idea of relaxation either :P

22:12 andyf: Unless 'static html' includes links to some racy sites :)

22:12 arrdem: not that I know of

22:12 * arrdem poker face

22:13 Glenjamin: anyone else find the clojuredocs update makes it look like grimoire?

22:13 arrdem: lol

22:14 Glenjamin: the typeahead search thing is pretty neat though

22:15 andyf: Clearly we need to get Reid and Zachary Kim at a Conj together, and have a cage match.

22:15 arrdem: not this conj.. clojure/west maybe

22:17 andyf: what would you think of a PR to thalia that uses the lib-grimoire backend and adds a dep to a package packing core docs & notes as lib-grimoire notes?

22:17 basically where I'm going with Grimoire itself..

22:18 andyf: arrdem: Sounds fine to me.

22:18 arrdem: andyf: okie doke.

22:26 kenrestivo: wow a for with a :let and a :when in it sure smells funny

22:26 arrdem: really? I love :when and :let

22:26 you just need to get the indentation right

22:27 andyf: kenrestivo: Feel the pressure to conform. It smells fine. :)

22:27 seriously, I've started using it more often in some code I've been writing, and I kind of like it.

22:28 kenrestivo: it's ok... it just seems compected to me. like, i've got a thinking flaw here and should bust this up somehow

22:28 arrdem: for is literally my favorite thing about clojure besides ->

22:28 and the datastructures

22:29 kenrestivo: for was the most familiar thing to me when i was first learning clojure coming from python

22:29 "list comprehensions, oh cool, know these!"

22:29 andyf: :when makes it easy to skip things conditionally in the resulting sequence, without sticking in nil's and remove'ing them later.

22:29 kenrestivo: yeah, that's how i ended up with it in this case.

22:29 arrdem: :when also makes it really nice to write "search"ish problems in fors..

22:33 kenrestivo: so. i have a function that is piping data to a c daemon to be processed and returned asynchronously. should i name it foo! or just foo. it's pure in the sense that it doesn't launch any missiles, but callign it is something that definitely must happen in a doseq and not for :-/

22:33 arrdem: -! is officially only for STM unsafe (non-idempotent) operations

22:34 but... it's not used to denote side-effects

22:34 so

22:34 up to you

22:34 andyf: you can stick a word like write/print/pipe in the name to give a strong hint.

22:34 arrdem: there have been a couple attempts I've seen to nail puredanger or someone else down on the subject of the -! convention to no avail that I'm aware of

22:35 andyf: pipe actually not so strong of a hint as write/print

22:35 arrdem: "do" is a good hint

22:35 (do-deamon-process ...)

22:37 kenrestivo: send- has been what i've been usnig

22:37 using

22:37 send-foo

22:37 arrdem: send is good

22:38 what we really need is an annotative effects system library...

22:38 or at least it'd be nice

22:39 andyf: idle curiosity, do you have a dog in the feature expressions fight?

22:39 andyf: I haven't looked at core.typed enough to know whether ambrosebs is hoping to include effects?

22:40 ambrosebs: hoping!

22:40 but not clear how to do it

22:40 arrdem: ^ yeah

22:41 andyf: arrdem: Not that I can think of. There could easily be good/bad consequences of the proposals that I haven't thought of, though.

23:03 arrdem: idle thought - local caching and federation on a Grimoire API rather than distributing datafiles in a package?

23:04 I have relatively serious reservations/design issues with slapping resource packages on the classpath, whereas just using the 0.4.0 API and caching the result with configurable bounds on cache size/freshness would be pretty easy

23:05 andyf: For development machines I doubt cache size will ever be an issue. freshness maybe

23:07 arrdem: yeah. so the issue is that, as presently designed, lib-grimoire assumes that you can "stat" a "directory" to list stuff like all artifacts and all versions of an artifact and soforth

23:07 which is great, but turns out to be a real pain when you have a classpath not a real monolithic shared dir tree

23:07 one approach is to have a ".list" file, but then you have to search for classpath aliases and concatenate all results

23:07 which is messy

23:08 or you can walk the classpath and look manually, which is messy

23:08 or I could punt, call out to a web API, which is clean, and cache in a dir which I can work with nicely

23:09 probably just gonna do that..

23:18 danielcompton: Is there a more idiomatic way to compare byte arrays in Clojure than using java.util.Arrays/equals ?

23:19 andyf: not in core that I'm aware of

23:19 wouldn't be surprised if some lib out there had something for it

23:21 brennon: hey all, have a question I'm hoping someone can help clear up

23:21 danielcompton: ~ask

23:21 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

23:22 brennon: is there a way, in clojure, to replicate the concept of (Integer. 12) => 12 with any other clojure object

23:23 i.e. (deftype Big. [v]) then (Big. 12) => 12

23:23 rather than (Big. 12) => #<Big 12>

23:23 bbloom: brennon: just use a function

23:23 ,(deftype Big [x])

23:23 clojurebot: sandbox.Big

23:23 bbloom: ,(defn big [x] (if (instance? Big x) x (Big. x)))

23:23 clojurebot: #'sandbox/big

23:23 bbloom: ,(big 5)

23:23 clojurebot: #<Big sandbox.Big@120e76d>

23:24 bbloom: ,(big (big 5))

23:24 clojurebot: #<Big sandbox.Big@4a04aa>

23:24 brennon: im trying to abstract out the necessity of calling an additional function from the end user of my library

23:24 bbloom: that's probably the opposite of what you want to do

23:24 brennon: i.e. i internally box a primitive to gain the aspects of the object

23:24 bbloom: you should expose factory functions rather than types, where possible

23:24 brennon: because i want to be able to store metadata

23:24 bbloom: do you actually care about UNBOXED values?

23:25 if that's the case, you're out of luck. primitives are special on the JVM

23:25 brennon: yes

23:25 thats what i was afraid of

23:25 bbloom: the jvm does not allow custom unboxed types

23:25 while they certainly have their uses, you probably don't really need them though...

23:25 why do you want them?

23:26 brennon: trying to add metadata to any obj passed into my function

23:26 and quickly realized if someone just had a primitive id have to box it just to get metadata

23:27 or add an extra function to create a map with {:val <actual-val>, :other ...}

23:27 bbloom: boxing occurs automatically, but metadata must be baked in to a type when it's defined

23:27 so you're going to have to wrap boxed values too, like strings

23:27 ,(with-meta "abc" {:x 1}) ; will fail, but "abc" is boxed

23:27 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IObj>

23:27 brennon: hmmm

23:27 good point

23:27 bbloom: maybe instead of metadata, you just want a map?

23:28 brennon: thats what im thinking

23:28 bbloom: almost always a good call

23:28 brennon: but then i need to provide an 'unbox' method to the downstream dev

23:28 wanted to alleviate them from calling (getValue <someMap>) etc.

23:28 TEttinger: they would in java too

23:29 bbloom: if it's a well known key, (:value <someMap>) is probably just fine

23:29 TEttinger: collections can't contain primitives, though autoboxing helps

23:29 bbloom: it really depends on your use case though, w/o knowing what you're doing, i can't suggest more

23:29 brennon: yeah i think im just going to have to go with a known key plus some helper fns

23:30 thanks for the tip on the JVM though, good to know

23:30 bbloom: do the clients of your library ever need the metadata?

23:30 you can unwrap objects you give back to callers after you're done w/ your metadata

23:30 brennon: yeah theyll want the metadata

23:30 bbloom: then maps are definitely the right answer

23:30 brennon: but i wanted to mask it for them so they could continue using the objects as normal

23:31 bbloom: simply not possible on the jvm

23:31 danielcompton: clojurebot: map |is| put a map on it

23:31 clojurebot: Ok.

23:31 arrdem: hehe

23:31 brennon: darn, okay thanks

23:40 danielcompton: is there a way to only show reflection warnings for code you're writing?

23:41 andyf: lein check will show reflection warnings for source (not test) files, but also any compiler errors

23:42 I guess it would show other kinds of warnings, too, but not sure what you might want to disable in your 'only' qualifier

23:45 danielcompton: they're showing up in the cursive REPL, but I assume the solution would be general to all REPL environments

Logging service provided by n01se.net