#clojure log - Apr 28 2014

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

0:00 TravisD: beamso: Do you know if there is already an effort to wrap this library?

0:01 beamso: i haven't heard of one

0:01 TravisD: Hehe, perhaps I will work on one and if it ever matures make it available :)

0:02 beamso: cool

0:05 TravisD: I didn't know about apache commons math. Looks like a pretty useful library

0:05 TerranceWarrior: no main manifest attribute.

0:07 nevermind i'll figure it out. :)

0:12 TravisD: Is there a guide somewhere for including dependencies from Maven Central in lein? I'm looking on the github page, but not seeing it

0:12 Frozenlock: Anyone has the indentation config in clojure-mode for this https://www.refheap.com/81966 ?

0:13 technomancy: TravisD: `lein help tutorial` should cover that

0:14 arrdem: Frozenlock: there should be an add-to-list you can do, but I don't know offhand

0:14 Frozenlock: I don't think that clojure-mode uses a monolithic indentation policy regex but it ma

0:14 *may

0:15 TravisD: technomancy: Is that different from the tutorial at https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md?

0:16 Frozenlock: arrdem: I mostly want to change the behavior. Currently it indents to the end of the function, but I'd prefer if it indented only 3-4 characters.

0:16 Like elisp :-p

0:16 technomancy: TravisD: same thing

0:16 TravisD: Ah, cool. I skimmed through that, but not carefully enough :)

0:18 arrdem: $google clojure-mode github

0:18 lazybot: [clojure-emacs/clojure-mode · GitHub] https://github.com/clojure-emacs/clojure-mode

0:19 TravisD: technomancy: I was looking specifically for more information on the Maven format for dependencies. I'm not familiar with maven

0:25 arrdem: Frozenlock: it looks like there's an indentation width list in here somewhere, but my computer is lagging too hard for me to read it :C

0:26 Frozenlock: arrdem: I found this. https://github.com/weavejester/compojure/wiki/Emacs-indentation

0:26 Still not what I wanted, but better than nothing

0:27 arrdem: Frozenlock: ah ok I saw define-clojure-indent but I didn't read it. Something is indeed better than nothing...

0:29 TerranceWarrior: Just made a jar. As Ray Stantz would say 'Now that wasn't sure a chore now , was it?'

0:29 3 megs for hello world.

0:29 ha!

0:29 arrdem: Lean Clojure should fix that right up.. in a few months :P

0:29 TerranceWarrior: thats like the total ram in a 1993 pc.

0:30 TravisD: It's sure a good thing it isn't still 1993!

0:30 arrdem: $google pascal p code

0:30 lazybot: [p-code machine - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/P-code_machine

0:30 arrdem: I guess the JVM is just terrible then..

0:33 TerranceWarrior: hello world, maybe less than 24 bytes on a c64?

0:35 arrdem: ,(length (seq "Hello, world!\n"))

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

0:36 arrdem: ,(count (seq "Hello, world!\n"))

0:36 clojurebot: 14

0:36 TravisD: I wondered the same thing :)

0:36 arrdem: well... you can probably do it in 30 bytes on a 16 bit machine with a write to stdout MMIO op.

0:37 because you have one write per char at 15 chars including null... so 28 bytes if you optimize out the null char...

0:38 if you "get" the C stdlib for free from the loader you could probably do "push $STR; call puts; ret;" in 20 bytes...

0:38 on an x86 AFAIK

0:39 dbasch: `/join #clojure

0:40 TerranceWarrior: Ha, either way it's still a 3 meg difference, lol!

0:40 arrdem: dbasch: this is #assembly wrong chan

0:40 dbasch: drats

0:40 arrdem: TerranceWarrior: yea Clojure's "compiler" drags more than a change of pants along for the ride..

0:41 TerranceWarrior: arrdem: i am sure that'll be fine when I tap my laptop at 32 gigs of RAM.

0:41 technomancy: clojure is bad at a lot of things

0:42 TerranceWarrior: which for a 30 year veteran starting with a 3k ram vic-20 this month is pretty incredible.

0:42 arrdem: TerranceWarrior: I mean... I'm an optimizing compilers wonk, but given the rate that storage is becoming effectively free I appreciate the tradeoff that Clojure makes in terms of having the compiler and stdlib at runtime despite the size implications. sometimes.

0:43 TerranceWarrior: damn. welcome to the future :P 21 never had a machine with less than 128Meg

0:43 TerranceWarrior: yeah, i am figuring too that the multicore situation combined with ram will hold clojure in high regards for many years to come.

0:43 arrdem: embedded systems not counting due to artificiality...

0:45 TerranceWarrior: well bear in mind that a large part of the "multicore" performance of clojure is the JVM's multithreaded garbage collector ;_;

0:45 TEttinger: technomancy, do you write clojure for work, as a hobby, both, neither, what now?

0:45 TerranceWarrior: hm, 21 years ago pcs typically had 4 (or was it 40) megs?

0:45 technomancy: TEttinger: I'm not sure

0:45 I write clojure at work and will keep doing so till they tell me to stop

0:45 but not very often

0:45 arrdem: TerranceWarrior: I had a 1998 Gateway with a Pentium II I think...

0:45 TerranceWarrior: arrdem: oh no, don't say that. I think i just lost my hard on! hahahah

0:46 arrdem: in 1993? lol

0:46 arrdem: TerranceWarrior: I said I'm dated '92, the computer was '98 :P

0:46 technomancy: TEttinger: I hang out in here for all the good jokes mostly

0:46 TerranceWarrior: ah, i see.

0:47 arrdem: in 1995 i was working with Solaris and also a pc with a 500 meg hard drive.

0:47 TEttinger: I like clojure for scripty stuff myself, but I don't think it's been a good fit for the game dev I'd like to be doing.

0:48 arrdem: I like Clojure because I feel more able to hack stuff at the REPL in Clojure than I do in Python

0:49 that and I find the transition from REPL "hacks" to apps to be near zero which is awesome.

0:49 TerranceWarrior: arrdem++

0:50 TravisD: TerranceWarrior: That doesn't appear to be the clojure way

0:50 arrdem: (inc TravisD) ; both for the demo and because funny

0:50 lazybot: ⇒ 3

0:50 TravisD: :D

0:51 arrdem: int foo = (void*)(god_only_knows++)*3+128

0:52 TerranceWarrior: TravisD: sorry. that thought did occur after the return press.

0:52 rhg135: arrdem: i've actually seen that somewhere :(

0:52 TravisD: TerranceWarrior: The bots in here keep track of fake internet points for everyone in the channel. Points are given by (inc username)

0:52 arrdem: rhg135: I had to write that :(

0:52 $karma arrdem

0:52 lazybot: arrdem has karma 24.

0:53 TravisD: ah, fake internet points, also known as karma.

0:53 arrdem: TravisD: I seem to have more fake internet points than you, "sir"...

0:53 rhg135: i mean i sadly have seen that in real codebases

0:53 with different names ofc but still

0:53 arrdem: rhg135: so did I... embedded hardware and drivers are evil.

0:53 TerranceWarrior: INC ARRDEM

0:53 TravisD: arrdem: I hope your karma causes you to be showered with good fortune

0:54 rhg135: they are arrdem

0:54 arrdem: TravisD: well it got me GSoC which pays next to nothing so I can't complain too loudly :P

0:54 TerranceWarrior: $karma TerranceWarrior

0:54 lazybot: TerranceWarrior has karma 0.

0:54 arrdem: TerranceWarrior: karma is sandboxed by channel... you can't /msg (inc foo)

0:55 TerranceWarrior: 6510, same as clojure, acept no parens.

0:55 arrdem: also #clojure-social for more offtopic chat :P

0:55 rhg135: there's a social chan?!?

0:55 TerranceWarrior: (inc arrdem)

0:55 lazybot: ⇒ 25

0:55 technomancy: TerranceWarrior: dang; one of my life goals (long term) is to learn 6502

0:55 rhg135: man nobody tells me

0:56 TerranceWarrior: technomancy: i recommend the c64 PRG and vice emulator (real thing, but that can be a hassel)

0:56 TravisD: rhg135: You'd better join it right now.

0:56 TerranceWarrior: +or the real thing

0:57 technomancy: I almost tried to pick up AVR, but the docs I could find were junk

2:02 trap_exit: when the cljs compiler bitches at me: "map must have even number of forms"

2:03 is there anyway to tell it "which fucking file and which fucking line" ?

2:03 s/tell it/ask it/

2:03 dbasch: trap_exit: what’s the exact error message?

2:04 trap_exit: Caused by: clojure.lang.ExceptionInfo: Map literal must contain an even number of forms

2:06 dbasch: trap_exit: you’re missing the rest of the stacktrace. How are you compiling?

2:06 trap_exit: cljsbuild autodev

2:06 Caused by: clojure.lang.ExceptionInfo: Map literal must contain an even number of forms at line 1 /home/x/code/client/cljs/app/all.cljs core.clj:4327 clojure.core/ex-info analyzer.clj:267 cljs.analyzer/error analyzer.clj:1415 cljs.analyzer/analyze-seq analyzer.clj:1506 cljs.analyzer/analyze[fn] analyzer.clj:1499 cljs.analyzer/analyze analyzer.clj:1494 cljs

2:06 except everything looks fine in app/all.cljs

2:10 dbasch: trap_exit: what’s line 1? or can you paste the whole thing somewhere?

2:10 johann: dbasch: line 1 is probably the namespace form

2:11 dbasch: johann: yes, it’s probably malformed in a subtle way

2:13 TravisD: Does anyone know of a statistically sane way to seed multiple random number generators?

2:15 dbasch: TravisD: why do you need multiple rngs?

2:15 TravisD: dbasch: one for each of several threads

2:16 dbasch: TravisD: all the numbers will come from the same source anyway, you might as well use SecureRandom

2:16 TravisD: in fact, you should use SecureRandom

2:17 TravisD: SecureRandom will be substantially slower than a Mersenne twister, for example, no?

2:17 dbasch: TravisD: possibly, it depends on what you need the randomness for

2:18 TravisD: and how much you need

2:18 TravisD: I'm running some monte carlo simulations. It'd be great to parallelize it

2:18 quite a lot of random bits, I expect

2:19 Ah, SecureRandom is often a PRNG that is just seeded randomly. That makes sense

2:25 fifosine: Is there an if-let form that will hit the else clause when the test evaluates to the empty sequence, ()?

2:26 TravisD: I think what I'll do is have one PRNG governed by STM that is used to seed a PRNGs for each thread.

2:26 Probably that will not introduce any substantial statistical badness and will allow me to reproduce experimental results

2:28 dbasch: fifosine: no, the empty sequence is truthy

2:28 fifosine: merr

2:40 pyrtsa: fifosine: (if-let [xs (not-empty xs)] ... ...)

2:43 dbasch: pyrtsa: that’s a good one

2:44 pyrtsa: Note that unlike (seq xs), (not-empty xs) returns xs when not empty. ;-)

2:44 ,(not-empty [1])

2:44 clojurebot: [1]

2:44 pyrtsa: ,(seq [1])

2:44 clojurebot: (1)

2:44 pyrtsa: Useful. :)

2:44 fifosine: pyrtsa thank you!

3:27 ollivera: Is there any library that helps to create a nested map from a sql query result? so much so that it could result on { username: "ollivera", contact: {phone: "1234-1234", email: "ollivera@example.com"}}

3:28 kelseygi: anybody down for a code review for ~30 lines of very newbie code?

3:29 scottj: kelseygi: best to just share a link and see what happens

3:32 kelseygi: https://gist.github.com/kelseyq/51dce2e997b393f469b5

3:32 it's pretty unpleasantly imperative

3:32 Glenjamin: oh wow

3:32 i'd recommend extracting functions

3:33 kelseygi: yeah there's one really glaringly obvious one

3:34 can i do local functions? so i still have access to the atoms?

3:34 Glenjamin: you just pass them along

3:34 also, it's not clear to me why you have atoms at all

3:35 kelseygi: i'm using a twitter api library

3:36 but the chunked responses from twitter don't break cleanly on tweet boundaries

3:36 Glenjamin: there's no shared state here, so you should be able to use locals

3:36 kelseygi: it's shared over multiple calls to the callback, no?

3:36 Glenjamin: oh, sorry

3:36 i see

3:37 it's not a loop

3:37 kelseygi: i mean ideally the callback would take a promise or something

3:37 mpenet: chunked responses from twitter do not guarantee so split at tweet boundaries

3:37 to*

3:37 kelseygi: but i'm on like day 3 of clojure and not sure i'm ready to take a crack at taht

3:37 yes

3:37 mpenet: from what I can remember

3:37 kelseygi: that's why i'm doing this

3:37 which seems like something a streaming api library should handle

3:37 Glenjamin: try having only one atom

3:37 mpenet: You're better off using twitter4j if you are short on time btw

3:38 kelseygi: but ¯\_(ツ)_/¯

3:38 mpenet: it handles all the errors/retries etc nicely

3:38 kelseygi: well the point of this project was to play with clojure

3:38 so i'd really rather not

3:38 Glenjamin: ah, ok

3:38 yeah, so try a single atom which is a map of {:expected :count :tweet}

3:39 extract the function passed to the callback into a named top-level defn

3:39 you don't need the (do) in there either

3:39 kelseygi: heh i was just doing that--reading how to pass another function around

3:39 atom as map makes sense, thanks

3:39 lol i think i got kind of lost and just started throwing do's & parens in there

3:39 Glenjamin: in fact, every time you have a (do), name a function and pass it the state it needs

3:40 once you've got that it should be easier to read, and thus easier to reason about

3:40 kelseygi: great, thank you

3:40 clgv: kelseygi: right, break that down into several functions

3:42 kelseygi: you should also review whether you really need those atoms. that gist looks a lot lilke imperative programming and not functional

3:44 kelseygi: i explained why up above, and yes i'm not thrilled about it

3:45 if there's a way to share state over multiple calls to that callback without them that'd be rad

3:59 Frozenlock: How does one redirect on auth with friend? I've seen this https://github.com/cemerick/friend/issues/100, but I'm a little confused as to how/where I need to add this metadata.

4:00 (and why in the metadata?)

4:02 szymanowski: hello!, how can i turn "camelCaseStuff" into ("camel" "Case" "Stuff") ? i've tried (clojure.string/split #"[A-Z]" my-string) but it grabs the uppercase chars

4:04 (clojure.string/split

4:04 my-string

4:04 #"[A-Z]")

4:04 sorry

4:08 Frozenlock: szymanowski: Found this with a quick google. It should answer your question :) https://www.refheap.com/82154

4:08 TEttinger: ,(re-seq #"[A-Za-z][a-z]+" "camelCaseStuff")

4:08 clojurebot: ("camel" "Case" "Stuff")

4:09 szymanowski: Thank you very much

4:09 TEttinger: it'

4:09 it's a fun problem to solve

4:09 clojure has nice regex support thanks to java

4:09 you can extend it to other languages too

4:12 ,(re-seq #"\p{L}\p{Ll}+" "ΒαλεντίνΒολόσινοφ")

4:12 clojurebot: ("Βαλεντίν" "Βολόσινοφ")

4:13 TEttinger: \p{L} is any letter, \p{Ll} is any lower case letter

4:20 clgv: Frozenlock: I'd guess you provide that in the middleware options of friend/authenticate

4:21 Frozenlock: clgv: but where? I 'with-meta' the credential-fn?

4:22 clgv: Frozenlock: sounds complicated, I'd thought in the map as usual key value pair

4:22 szymanowski: what is the way to go for working with rational numbers in clojurescript?

4:24 clgv: Frozenlock: but according to the readme you seem to be right. https://github.com/cemerick/friend/#todo

4:24 Frozenlock: clgv: Like you I would have expected to just assoc it in the credential map.

4:25 using with-meta seems... I don't know... dirty?

4:25 clgv: well if it there was a consistent distinction between meta properties and regular settings that would be ok. but I cant read that from the docs

4:26 Frozenlock: I'll ask cemerik tomorrow if he shows up on IRC

5:02 TravisD: szymanowski: As an alternative to the camel case splitting, you could do it this way:

5:02 ,(defn split-camel-case [str] (butlast (re-seq #"[A-Z]?[^A-Z]*" str))) (split-camel-case "thisIsATest")

5:02 clojurebot: #'sandbox/split-camel-case

5:02 TravisD: =/

5:02 ,(letfn [(split-camel-case [str] (butlast (re-seq #"[A-Z]?[^A-Z]*" str)))] (split-camel-case "thisIsATest"))

5:02 clojurebot: ("this" "Is" "A" "Test")

5:03 szymanowski: thank you Travis

5:03 TravisD: there might be some corner cases though :)

5:04 TEttinger: ,(letfn [(split-camel-case [str] (butlast (re-seq #"\p{Lu}?\P{Lu}*" str)))] (split-camel-case "thisIsATestΒαλεντίνΒολόσινοφ"))

5:04 clojurebot: ("this" "Is" "A" "Test" "Βαλεντίν" ...)

5:07 TravisD: Ah, TEttinger, I didn't see your message earlier

5:07 I am happy that I came up with essentially the same thing

5:08 it was /so/ frustrating that I couldn't think of a way to use "partition-by" or "split-with"

5:16 this was the best I could come up with without using regular expressions

5:16 https://www.refheap.com/82182

5:30 owl-v-: can clojurec outperform clojre on math problems?

5:32 TEttinger: owl-v-, sounds possible but I wouldn't think likely

5:33 if you're doing just numerics stuff you might find more people doing that type of thing in Julia than in Clojure, and I was suprised at the similar library coverage

5:33 clgv: is clojurec a "usable thing" already?

5:33 TEttinger: Julia would almost certainly outperform clojure on math because it defaults to using the highly optimized BLAS libs for math

5:34 clgv: if it is that one https://github.com/schani/clojurec/graphs/commit-activity there seems not much recent activity

5:35 TEttinger: yeah. if you were targeting LLVM that would be what Julia does as well

5:35 so maybe they would both be pretty fast

5:38 owl-v-: somebody did little test on python julia clojure java -> http://matthewrocklin.com/blog/work/2014/01/13/Text-Benchmarks/

5:42 TEttinger: that seems like a pretty poor benchmark since it only tests startup time

5:48 owl-v-: ya, i think startup time is also important, but providing bunch of loops, arithmetic operations, and io operation would have helped.

5:49 TEttinger: well it's just too short of a test to gauge actual performance

5:50 I don't think Python uses a JIT compiler by default, so it has less startup cost, but will take longer for larger inputs

5:56 ollivera: How can I map something like {:a 2, :b 4, :c 6, :d 7} to {:a 2, {:b 4, :c 5, :d 7}}?

5:57 opqdonut: ollivera: {:a 2, {:b 4, :c 5, :d 7}} isn't valid syntax

5:57 you're missing the key that corresponds to {:b 4, :c 5, :d 7}

5:58 ,{:a 2, {:b 4, :c 5, :d 7}} -- see?

5:58 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

5:59 ollivera: opqdonut, okay thank you ... anyway how can I do such map ... with the valid key

6:01 opqdonut: what do you want the key to be? what would you do with {:foo :a, :bar 3, :quux nil}?

6:02 ollivera: opqdonut, I want to create a nested map with the keys/values bar and quux

6:02 opqdonut: so you want to leave :foo out? why :foo? a clojure map is not really ordered

6:03 owl-v-: TEttinger: why not compile once? we can save startup cost at the same time we can have better optimization.

6:04 TEttinger: owl-v-, and indeed you can in clojure

6:04 opqdonut: ,{:a 1 :x 2 :c 3}

6:04 clojurebot: {:c 3, :x 2, :a 1}

6:04 TEttinger: I think his benchmarks didn't do that, by the way

6:04 opqdonut: ollivera: see above, (normal clojure) maps don't have a stable ordering

6:05 owl-v-: I hope android updates its jvm.

6:06 it's very interesting to see how ios uses 64bit registers when GC is used :)

6:07 what is it called.... tags?

6:07 incremental indexing ..hm..

6:08 ollivera: opqdonut, I could create a key ... but I would like to have a nested map .. see example

6:08 user=> {:a 2, :b 4, :c 6, :d 7}

6:08 {:c 6, :b 4, :d 7, :a 2}

6:08 user=> {:a 2, :new {:b 4, :c 6, :d 7}}

6:08 {:new {:c 6, :b 4, :d 7}, :a 2}

6:10 ssideris: ollivera: look into select-keys, assoc and dissoc, you'll probably have to use all of those functions

6:16 owl-v-: im going to make a tree. but i want to mark values to the elements. how do i do it when the tree is immutable structure?

6:17 clgv: owl-v-: essentially you rebuild the tree as you update values

6:18 owl-v-: my tree is going to be quite big, and multiple duplicates of that is... :-(

6:18 clgv: owl-v-: btw that shootout is not reliable. measuring one time duration leads to false results

6:21 owl-v-: what if I want to preserve memory by removing modules?

6:23 ashish_: In java we read the properties file by Myclass.class.getProtectionDomain.getCodesource.getLocation.getPath() But how this read in clojure

6:25 ssideris: owl-v-: clojure uses structural sharing, the copy will refer back to the old tree and consume very little extra memory

6:26 only the changed values will be extra

6:29 ueje: Why does Clojure use [vectors] so much, instead of lists as in most lisps? Like for definings args to a function for instance

6:30 ashish_: In java we read the properties file by Myclass.class.getProtectionDomain.getCodesource.getLocation.getPath() But how this read in clojure

6:31 owl-v-: let structure be like {depth {index {value path-value}}} then change from {0 {0 {3 0}}} to {0 {0 {3 4}}} then what is changed?

6:31 ssideris: ashish_: (.getPath (.getLocation (.getCodesource (.getProtectionDomain (Myclass/class)))))

6:31 owl-v-: only 0 to 4?

6:32 ssideris: owl-v-: not sure, I'm not familiar with the intimate details of the persistent data structures implementation

6:33 pyrtsa: ssideris, owl-v-: That very case will probably end up sharing nothing.

6:33 clgv: ssideris: well if you build a tree of maps and update almost all leaves you will completely rebuild the tree

6:34 pyrtsa: Actually, wipe the "probably" in the above.

6:36 ashish_: See also the macros `..` and `->`, e.g. `(-> (MyClass/class) (.getProtectionDomain) (.getCodesource) (.getLocation) (.getPath))`.

6:39 ssideris: with -> you dont even need all the parens

6:40 pyrtsa: Correct.

6:40 ssideris: (-> (MyClass/class) .getProtectionDomain .getCodesource .getLocation .getPath)

6:44 clgv: style suggestion (.. (MyClass/class) getProtectionDomain getCodesource getLocation getPath)

6:44 ,(.. String getProtectionDomain getCodesource getLocation getPath)

6:44 clojurebot: #<CompilerException java.lang.NoSuchFieldException: getProtectionDomain, compiling:(NO_SOURCE_PATH:0:0)>

6:45 clgv: something is missing

6:45 ssideris: clgv: that's nice too, hadn't used it before

6:45 owl-v-: pyrtsa: clgv: ssideris: so it is better to implement this stuff in c/cpp?

6:46 clgv: owl-v-: not necessarily.

6:47 owl-v-: why would you want to use c/c++ voluntarily if the program fulfills all your performance and memory requirements in clojure?

6:48 ssideris: owl-v-: it depends, I think in many cases you may be able to re-phrase your problem to better fit clojure. for example for trees/graphs you can represent them using "flatter" data structures which work better in clojure

6:49 pyrtsa: clgv: I tend to avoid .. altogether and just move the . prefix as close to Java interop as possible, i.e. every method call. But it's a matter of taste with no real winner, IMO.

6:52 owl-v-: I'm unsure what you mean by "this stuff".

6:54 owl-v-: i'm afraid that creating multiple versions of tree might take too much time compared to simply changing a value in a structure.

6:55 clgv: owl-v-: well being afraid and knowing are two pair of shoes ;)

6:57 trap_exit: is milk price at $5.50 / gallon? I thought it was $3.509 / gallon

6:57 owl-v-: clgv: knowing that there will be multiple trees, knowing that copying tree takes time, knowing that copying is slower than changing value, knowing that this is my problem?

6:57 clgv: owl-v-: you could make a small prototype to check

6:58 owl-v-: maybe the representation of the tree is not optimal. there is more then one possibility to represent a tree

6:59 owl-v-: I assumed you will use nested persistent datastructures but that is not mandatory.

6:59 owl-v-: you could use an indirect representation similar to adjacency matrix/lists

7:08 ssideris: clgv: yeah, that's what I meant about "flatter" data structures

7:13 phiware: Hello, I’m new here and new to clojure :)

7:13 I think I’ve found a bug in clojure.core, in particular, it relates to `binding`...

7:14 my understanding of `binding` is a bit hairy, so I’m happy to be proved wrong :)

7:14 can someone help me out?

7:16 trap_exit: create a minimal test case

7:16 showing the result and the expected result

7:16 then post to the mailing list

7:17 phiware: ok… it’s going to be quite a task to shrink my test case!

7:18 trap_exit: then mostly likely there's something wrong with your "test case"

7:18 phiware: yeah, that’s usually the way it goes…

7:19 but…

7:20 trap_exit: what's a reasonable cost for grocery for 1 person / day

7:20 clgv: phiware: build a minimal viable gist post it to refheap.com (or similar sites)

7:20 trap_exit: I can't seem to get mine below $10.00 / day

7:20 clgv: lol what?

7:20 trap_exit: this is half a gallon of milk + half a gallon of orange juice + 6 bagels + cream cheese

7:20 clgv: how much do you spend on food / day ?

7:21 clgv: trap_exit: honestly, I dont know exactly

7:21 trap_exit: estimate

7:21 $10.00 / day ? $20.00 / day ?

7:21 agarman: in college, it was $3/day

7:21 trap_exit: agarman: how did you pull that off?

7:21 agarman: now-a-days much much more :-)

7:22 clgv: lunch is between 3-5 euro. and the rest? hmm maybe in average closer to 10 euro / day than 20

7:22 ssideris: clgv: what country?

7:22 trap_exit: united states

7:22 fucking silicon valley

7:22 even food here is more expensive

7:22 grimmulfr: can someone please explain to me how deps work in lein (on windows)? I'm trying some simple gfx so I though I'd use quil. Added (:use quil) in my source, and [quil "1.7.0"] in the project file. ran lein deps, all seemed to work, but when compiling (from within a working emacs windows environment) I get FileNotFoundException Could not locate quil__init.class or quil.clj on classpath: clojure.lang.RT.load (RT.java:4

7:22 43)

7:23 I see what the error means, but not sure what extra steps I need to take to make the library available

7:23 clgv: ssideris: germany. lunch at university for student prices ;)

7:23 agarman: grimmulfr: can you post your project.clj to refheap.com

7:24 grimmulfr: Nothing fancy, just ran `lein new' and added that deps line, but will do

7:24 https://www.refheap.com/82198

7:24 oh, added :main too

7:25 nbeloglazov: grimmulfr, it should be quil.core I think

7:25 clgv: grimmulfr: looks fine. it is quil.core

7:26 grimmulfr: so [quil.core "1.7.0"] ?

7:26 or the :use thing in my source is quil.core?

7:26 nbeloglazov: in :use

7:26 agarman: no, the dep looks fine

7:26 grimmulfr: Oh, thank you, will try now

7:26 No suck namespace qc :(

7:26 such*

7:27 need to read an actual documentation page methinks

7:27 nbeloglazov: grimmulfr: I would suggest to start with example from README: https://github.com/quil/quil#getting-started It should work fine out of box.

7:27 grimmulfr: cheers

7:27 agarman: for quil, it's (require 'quil.core)

8:09 grimmulfr: (:require [quil.core :refer :all]))

8:09 This worked

8:09 Yey, first gfx :)

8:34 jcidaho: Hi - anyone using Stuart Sierras component lib?

8:35 it's great for starting up components, but if a component blows up during startup you ideally want it to gracefully shutdown components already started

8:36 agarman: I looked at it

8:36 and started playing with https://github.com/juxt/jig

8:37 jcidaho: how did jig treat you?

8:37 agarman: haven't gotten far with it

8:40 clgv: what I dont get with jig: why do you have to clone the project? is it not usable as lib? wouldn't a lein template be the better choice?

8:41 gfredericks: jcidaho: I think if your start/stop methods are idempotent you could just call stop on the system after failure

8:42 jcidaho: good point gfredericks

8:43 pyrtsa: What I don't get in Component is why start has to be separate from initialization.

8:44 It would be much simpler if you simply couldn't start a service without its dependencies passed in as arguments and, hence, started first.

8:45 AWizzArd: Btw guys, there’s also a german speaking Clojure channel: #Clojure.de

8:45 pyrtsa: The whole interface (protocol) could be just function to stop the service.

8:47 gfredericks: pyrtsa: I've used the initialize/start separation in tests to modify the component before starting it

8:48 pyrtsa: gfredericks: Why do you need to modify it? Why don't you just modify the arguments you use to construct it?

8:48 I thought mutation was considered bad here. :o

8:48 gfredericks: because that constructing happens in the app code

8:48 and I'd have to duplicate it in the test code to do it your way

8:48 it's not mutation, it's record modification

8:49 (-> (app-code/make-system) (assoc :component (mock-component)) (component/start))

8:50 pyrtsa: gfredericks: Does (assoc c :component (mock-component)) replace something in c?

8:51 gfredericks: yep

8:53 pyrtsa: I think that approach is conflating two interests: the "system" record is both its configuration and a handle to a stateful system.

8:54 gfredericks: yes the record + statefulness approach is super weird

8:54 but I don't have a better idea

8:54 pyrtsa: My approach wouldn't be much different, something like (-> (app-code/make-config) (assoc :component (mock-component)) (component/run))

8:55 ...The main difference being that the app does its own (assoc c :component ...).

8:55 gfredericks: what does (mock-component) return?

8:55 pyrtsa: And sorry, actually there is no component/run in my model.

8:56 (mock-component) returns a mocked component (in this case, with no arguments).

8:56 gfredericks: already started?

8:56 pyrtsa: Yes.

8:56 gfredericks: so (app-code/make-config) contains other started components also?

8:56 pyrtsa: Separating the start from the initialization is, I think, a mistake.

8:56 Yes.

8:57 gfredericks: you were complaining about conflating two things and now you're arguing for conflating two things :P

8:57 so what if (mock-component) has dependencies inside (app-code/make-config)?

8:58 pyrtsa: See, it's then up to you to choose how the plain-old-data config and resource-like arguments need to be created. In practice, I'd have those in separate steps

8:59 gfredericks: If mock-component had dependencies, you couldn't call it like (mock-component), you'd call it like (mock-component {:dep1 d1, :dep2 d2, :foo "bar", ...})

9:00 gfredericks: would those args be started or not? it sounds somewhat difficult to reason about the ordering of things

9:00 pyrtsa: That itself defines the DAG of dependencies, and all visible in code.

9:01 By default, these components are started when they are created. After that, they can be only stopped, then garbage collected.

9:02 Then, anything you need to do before starting a component, you must by definition do before creating the component.

9:03 Of course you could group all dynamic configuration into one single map that is used by all components that need (parts of) it.

9:35 rodnaph: hi - i'm using "lein bin" to create an executable, and trying to set -Xmx via JAVA_OPTS or JVM_OPTS but it doesn't seem to have any effect. can anyone help? thanks.

9:39 hyPiRion: Raynes: someone is using your plugin and want some help with it

9:40 phiware: ,(def ^:dynamic *modulus* 10) (defn f [x] (-> x (inc) (mod *modulus*))) (binding [*modulus* 3] (take 3 (iterate f 1)))

9:40 clojurebot: #'sandbox/*modulus*

10:00 mdrogalis: https://twitter.com/feross/status/459259593630433280

10:00 * mdrogalis runs away.

10:02 rodnaph: Raynes: trying to use JVM_OPTS with your "lein bin" plugin but they don't have any affect, can you help?

10:02 ssideris: mdrogalis: !!!

10:03 mdrogalis: ssideris: I'm not sure if that's a joke.

10:04 * arrdem sprints after mdrogalis, nopeing hard

10:04 grimmulfr: Anyone know of a simple step by step clojurescript tutorial that gets me from creating a basic lein project to actually publishing a working "hello world" html + js? (not looking for starting my own server locally, as I already run one). I just want something to get me going with doing the scripting

10:05 mdrogalis: I mean, why would we hear about this at 54 gigs? You'd think someone would have to make a public outcry at, say, 20 gigs.

10:05 Someone just *snapped*!

10:05 rodnaph: grimmulfr: swannodettes example as as concise as it gets if you're after bare-bones - http://swannodette.github.io/2013/10/27/the-essence-of-clojurescript/

10:06 grimmulfr: Nice, thank you :)

10:06 phiware: ,(vector (def ^:dynamic *modulus* 10) (defn f [x] (-> x (inc) (mod *modulus*))) (binding [*modulus* 3] (take 3 (iterate f 1))))

10:06 clojurebot: [#'sandbox/*modulus* #'sandbox/f (1 2 3)]

10:07 grimmulfr: That is pure clojurescript right? no extra libs and whatnot?

10:07 * grimmulfr is new and will like to stay away from libs for now :D

10:07 arrdem: purity is overrated..

10:08 grimmulfr: Not a purist, just trying not to mess my head up at this stage in the learning process :D

10:08 mdrogalis: That's fair.

10:08 rodnaph: just leiningen and clojurescript afaik

10:08 grimmulfr: Awesome, thank you

10:09 owl-v-: how do i memory trace?

10:09 phiware: ,[(def ^:dynamic *modulus* 10), (binding [*modulus* 3] (take 3 (iterate #(-> % (inc) (mod *modulus*)) 1)))]

10:09 clojurebot: [#'sandbox/*modulus* (1 2 3)]

10:10 phiware: Sorry to pester clojurebot, but this represents the bug I have encountered in the repl…

10:12 pyrtsa: phiware: take is lazy.

10:12 grimmulfr: Yey, it worked. Time to see how I can do everythign from within emacs, I just hate running lein from the console

10:12 pyrtsa: ,[(def ^:dynamic *modulus* 10), (binding [*modulus* 3] (vec (take 3 (iterate #(-> % (inc) (mod *modulus*)) 1))))]

10:12 clojurebot: [#'sandbox/*modulus* [1 2 0]]

10:13 phiware: yup, but what about binding conveyance?

10:13 ToxicFrog: The lazy sequence doesn't close over its (binding)s?

10:13 Eek.

10:13 hyPiRion: ToxicFrog: not the dynamic ones

10:14 owl-v-: how do i trace memory?

10:14 phiware: ,[(def ^:dynamic *modulus* 10), (binding [*modulus* 3] (last (take 3 (iterate #(-> % (inc) (mod *modulus*)) 1))))]

10:14 clojurebot: [#'sandbox/*modulus* 0]

10:14 hyPiRion: phiware: you can use bound-fn to bind dynamic values to functions

10:14 ToxicFrog: Manually making sure I never let something lazy defined in terms of dynamic bindings escape is not something I should have to worry about!

10:15 hyPiRion: ,(binding [*modulus* 3] (take 3 (iterate (bound-fn [x] (mod (inc x) *modulus*)) 1)))

10:15 clojurebot: (1 2 0)

10:15 hyPiRion: ToxicFrog: solution: Don't use dynamic vars

10:16 although I get your concern, it's a pain with IO as well.

10:16 ToxicFrog: hyPiRion: when dynamic binding is useful it is really fucking useful.

10:17 hyPiRion: ToxicFrog: huh? It usually allows you to pass in a parameter less to a function

10:17 phiware: dynamic var fits my needs, I have a group of functions that all use the same var and it should remain constant for a given application

10:19 ToxicFrog: hyPiRion: yes. And when you have an entire call stack that all need access to some configuration map or similar, not needing to manually thread that through every function that needs it makes things way cleaner.

10:20 Or, for example, when you're using something like Saturnine and you can bind *to-client* and *to-server* to upstream or downstream appropriately depending on which direction you're processing in.

10:21 hyPiRion: ToxicFrog: Sure, it makes stuff seem cleaner, and in general it's easier to work with.

10:22 but it's hard to reason about it when it comes to higher order functions

10:25 phiware: hyPiRion: even with HOF it’s easy when the bebound var doesn’t change in the context of the application/domain

10:25 rebound*

10:29 I still think that binding conveyance should take care of the laziness of take

10:29 (no pun intended)

10:30 hyPiRion: phiware: Sure, but if it doesn't change, then what's the point of a dynamic var?

10:31 phiware: it can be rebound. When building a library I can make that decision for all applications

10:32 can’t* make that decision

10:33 gtrak: what's the closest thing to ruby's mechanize these days?

10:33 I like the whole cookies.. stateful object thing.. but ruby.

10:33 hyPiRion: right, which is why functions per definition cannot lock their dynamic scope

10:33 (at least not by default)

10:34 CookedGryphon: Does anybody have an idea how to use profiles with cider-jack-in? I hate having an extra terminal floating around running my headless repl just because I want to use a profile other than :default

10:35 gtrak: I guess I could hack something together with clj-http and laser

10:36 dakrone: gtrak: maybe check out https://github.com/sonian/cartridge also?

10:37 gtrak: ah, cool.

10:37 that's like VCR

10:37 but I imagine less monkey-patchy :-)

10:39 szymanowski: hello, does anyone know how can I call a function given its "string-name" in clojurescript?

10:40 like (call "+" 1 1)

10:41 gtrak: dakrone: trying to work around lack of basic auth for an oauth api :-)..

10:41 figured I could fill in the login form programmatically and extract the token out of the redirect.

10:42 phiware: hyPiRion: the group of functions I’m developing share a common *word-length*, dynamic vars seems to fit the bill (there’d be nothing to stop an application from changing the *word-length* “mid-stream” but it would be breaking the rules of my group of functions)

10:43 owl-v-: szymanowsky: i don't know anything about clojurescript. maybe there is #clojurescript in irc?

10:44 hyPiRion: phiware: yeah, as long as they work within the same dynamic scope, you're fine

10:44 phiware: hyPiRion: I could place the word-length as the first arg, and then the application could redefine each function using partial… would that be idiomatic?

10:45 hyPiRion: phiware: no need, just be aware of the scope of dynamic vars

10:45 szymanowski: thank you owl-v- it seems to be a #clojurescript IRC i will try

10:45 phiware: it’s the whole thread-local nature of dynamic vars doesn’t fit with me…

10:46 hyPiRion: I'm just saying that whenever you pass a function down or up a scope, stuff may get very confusing

10:48 CookedGryphon: alternatively, does anyone know of a way to specify the leiningen profile to use when no other is specified? Sort of like :default, but doesn't get included if you with-profile something else

10:53 phiware: ,[(def ^:dynamic *modulus* 10), (let [*modulus* 3] (take 3 (iterate #(-> % (inc) (mod *modulus*)) 1)))]

10:53 clojurebot: [#'sandbox/*modulus* (1 2 0)]

10:54 technomancy: CookedGryphon: I don't understand what you mean about with-profile

10:54

10:55 phiware: hmmm, a dynamic var is a hairy thing indeed

10:57 CookedGryphon: technomancy: so I have a project with multiple profiles, some for clojurescript, some for android, and some for running midje on my desktop

10:57 technomancy: when I cider-jack-in, I want the profile with all the desktop stuff and midje

10:57 but cider jack in provides no option for that

10:58 if I set default, that breaks my other profiles, because it pulls all teh midje stuff into my android and clojurescript builds

10:58 phiware: ,[(def ^:dynamic *modulus* 10) (defn f [x] (-> x (inc) (mod *modulus*))) (let [*modulus* 3] (take 3 (iterate f 1)))]

10:58 clojurebot: [#'sandbox/*modulus* #'sandbox/f (1 2 3)]

10:58 pyrtsa: phiware: Nothing prevents you from hiding names in a let binding. But you shouldn't use *earmuffs* in a let binding, that isn't recommended.

10:59 phiware: pyrtsa: I’m explore dynamic vars, you’ll notice I’ve def’ed that way…

11:00 pyrtsa: A let binding doesn't touch the dynamic var at all.

11:01 phiware: yeah, I thought that it did, my mistake

11:01 is `binding` the only way to redefine it?

11:03 pyrtsa: You can use e.g. set! too.

11:04 But dynamic vars aren't pretty.

11:05 hyPiRion: phiware: It's recommended to just use binding, I think. Using set! can be... nasty

11:05 stuartsierra: http://stuartsierra.com/2013/03/29/perils-of-dynamic-scope

11:05 phiware: but they do have a purpose…

11:09 technomancy: CookedGryphon: you can change cider's jack-in command

11:10 CookedGryphon: yeah, I'm looking at that, but ideally this should be something that doesn't break jack-in for my other projects and which my other team members can just pick up and use

11:10 I'm writing a cider-jack-in-with-profile (profile-name)

11:11 would be nice if there was something officially supported though, not sure this is going to be neat enough for a PR

11:11 phiware: set! doesn’t work if the dynamic var is defined in another ns

11:18 stuartsierra: I have read that blog post before …but it was worth a reread :)

11:18 stuartsierra: phiware: thanks

11:19 phiware: I’n not trying to manage a resource as in DSSR

11:19 I’m trying to parameterise a group of functions…

11:21 consider modular arithemetic: clock-add, clock-multiply, clock-diff, etc… all based on 24 hours in a day

11:21 but why not 12 hours, imagine a decimal clock!

11:22 once an application has chosen the number of hours per day, it is encourge to stick to it.

11:24 technomancy: CookedGryphon: you can use emacs dir-locals to scope it to one project

11:24 CookedGryphon: technomancy: so I've written a cider-jack-in-with-profile which takes a profile string

11:24 it's a bit repeaty of cider-jack-in, but it works

11:25 might tidy it up and see if anybody wants it

11:25 phiware: I propose ^:dynamic *hours-on-clock*… but it lacks indefinite extent…

11:26 mikerod: I'm reading through the Clojure v1.6 changelog on github. I noticed this item: "(no ticket) Rich Hickey fix: use non-loading classForName"

11:26 Is there a way I could get more information on this?

11:26 rovar: blarg

11:26 mikerod: Perhaps see what this change entails?

11:27 Just digging around some. I have observed a slight change of behavior from 1.5.1 to 1.6 around RT#load

11:27 rovar: what is the simplest way to make a basic templated site with partials in clojure? I'm thinking its enlive but I was wondering if there were other options.

11:27 I have to maintain a pure static html5 site, and so I just want to partial the nav, headers etc..

11:27 I don't need a full fledged blog static generator

11:28 phiware: yes, I have considered partials, and they are lookin more and more attactive

11:28 mikerod: Previously it seemed that using RT#load multiple times on a namespace I had with a defrecord in it only compiled the ns once; and thus didn't recreate the defrecord class. In 1.6 I'm seeing this defrecord being compiled repeatedly upon multiple calls to RT#load

11:29 gtrak: CookedGryphon: cider would probably take something that customizes cider-jack-in via variables. Not sure what the closeest thing to a dynamic binding in elisp is.. except all of it.

11:29 mikerod: I'm just trying to track down what made this happen since none of the changes I can see are immediately obvious. I know the fix for it is to not use RT#load when I don't want the re-compile; just use something like `require`.

11:29 llasram: mikerod: If that's what I think it was, there had been some mailing list discussion, and I didn't realize had been slipped into 1.6

11:29 mikerod: Tracking down commit, but I believe is about JVM class loading, not namespace loading

11:29 mikerod: llasram: hmmm I'm trying to figure out how to search for it. I can search in the mailing list

11:31 gtrak: rovar: selmer's pretty neat.

11:31 Luminus uses it, if you create a new luminus project, you can see how it's all wired up.

11:32 llasram: mikerod: Here's the commit: https://github.com/clojure/clojure/commit/38a129f2631a75ed999b52d8e0440f730b00da1f

11:32 gtrak: I think it'd be easy to generate files from it.

11:32 technomancy: gtrak: .dir-locals.el is best for stuff like that

11:32 phiware: I realise I’ve mostly been talking to myself here …but helps to talk out loud, thanks

11:32 gtrak: technomancy: awesome

11:32 CookedGryphon: ^

11:32 rovar: gtrak, wow. that is pretty advanced.

11:33 mikerod: llasram: oh, awesome

11:33 thanks!

11:33 llasram: mikerod: But... v confused, because doesn't seem to reflect current reality

11:34 gtrak: rovar: the template inheritance stuff is something not built-in to things like hiccup.

11:34 I'd just use hiccup for small stuff.

11:34 llasram: mikerod: Wow, what a mess

11:35 mikerod: llasram: what doesn't reflect reality?

11:35 oh, the LispReader

11:35 llasram: mikerod: The RT method was introduced in that commit, but that single use was in the EvalReader, and was re-written back to just classForName in 53201d8c38a984401ae9d70190cf1959902edf64

11:35 rovar: gtrak, I don't think I want to get that crazy just yet. I think I'm just going to slurp partials and inject them with the enlive selectors.

11:36 that way the html stays pure html..

11:36 gtrak: cool, I've been using laser myself. same idea.

11:36 but I didn't already know enlive

11:37 llasram: mikerod: The one remaining classForNameNonLoading call is in 5cf6aa3f90778498c116d143750ce31a0e2cee39, which was part of an attempt to make `read`ing safer prior to adding the explicit EDN reader in the last commit I mentioned

11:38 So... Really that change doesn't belong in the log, because nothing really happened which matters to anyone, except that Record JVM classes aren't loaded upon reference in the LispReader

11:38 mikerod: llasram: yeah, I'm seeing what you mean now looking at these commits

11:39 Hmm. So it isn't looking likely that these changes is what has cause my `defrecord` to create multiple definitions of the same class when multiple RT#load calls are called on its enclosing namespace.

11:39 TerranceWarrior: How to cleanly stop java clojure daemon processes under linux? ctrl-z leaves them continously running in the background.

11:39 mikerod: changes are*

11:40 iwillig: does anyone know the emacs minor-mode that highlights the current paren or scope you cursor is in

11:40 rovar: gtrak, laser looks pretty cool. Very similar to enlive, and the author is right, enlive is very full featured for what it does. A bit overkill for me, but whatevs.

11:42 llasram: iwillig: `show-paren-mode`

11:42 TerranceWarrior: i am suprised this doesn't happen to anyone else.

11:43 llasram: TerranceWarrior: Well, in a terminal ctrl-z normally sends SIGSTOP to a process, leaving it suspendend in the background

11:43 So it's utterly unsurprising it does this to Clojure processes too

11:44 iwillig: thanks llasram

11:44 ToxicFrog: TerranceWarrior: to get back a backgrounded process, use 'jobs' to list them and then 'fg %n' to foreground one. Then you can ^C or the like as you see fit.

11:44 rovar: is there a function to map a function f across a seq of K's and return a hashmap of { K f(K) }

11:45 ToxicFrog: rovar: (zipmap ks (map f ks)) ?

11:45 rovar: i can do it in two loops.. can't think of a way to do it in one..

11:45 ToxicFrog, lemmme look at zipmap and see if that's what I'm after..

11:46 ToxicFrog: ,(let [ks [1 2 3 4]] (zipmap ks (map #(* %1 %1) ks)))

11:46 clojurebot: {4 16, 3 9, 2 4, 1 1}

11:46 coventry: For one loop, there's (into {} (for [k ks] [k f (k)]))

11:46 rovar: ToxicFrog, yea that'll do, although that is also technically two loops

11:46 coventry: Er, (f k)

11:47 TerranceWarrior: ToxicFrog: 'jobs' produces no results.

11:47 rovar: ah.. man for seems to come in handy

11:47 coventry: Yeah, for is even better than juxt

11:47 ToxicFrog: TerranceWarrior: you're doing it from the same shell you ^Z'd them from?

11:47 jobs are shell process specific.

11:48 TerranceWarrior: ToxicFrog: wow, now it works.

11:48 ToxicFrog: thank you.

11:49 ToxicFrog: do you happen to know how to default lein {command} to the latest clojure (without needing a project.clj file)?

11:50 ToxicFrog: TerranceWarrior: no idea, sorry

11:51 TerranceWarrior: oh yeah, and as for job control - note that something in the background is suspended. If you genuinely want it to keep running in the background, use 'bg %n' (or just 'bg' to background-resume the most recently suspended process)

11:51 This is basically the same as running it in the first place with '&'

11:51 * ToxicFrog tends to forget the '&' on X apps a lot, and then ^Z\ bg to get the shell back

11:54 cbp: TerranceWarrior: You need to run leiningen from source to use the latest clojure by default

11:54 TerranceWarrior: cbp: ah ok. thanks.

12:02 owl-v-: clojure on ios?

12:04 TerranceWarrior: cbp: you mean this: https://github.com/technomancy/leiningen/tree/master/resources/leiningen/new/app

12:04 ?

12:04 cbp: TerranceWarrior: I'

12:04 er

12:05 I'm not entirely sure what you're pointing out

12:05 TerranceWarrior: cbp: ok

12:05 cbp: But sure that commit hasnt been released yet

13:22 TravisD: Given some mutable java object, are there some standard techniques for exposing a functional interface?

13:23 grimmulfr: what exactly does "mies" in lein cljsbuild auto hello-world provide? I tried retracing the (working) example that I put together at work and it doesn't seem to work for me anymore. i made a new project with lein new cljs, copied over the inde.html that I had from work (since without the mies part it doesn't get created), I replicated the src code and added everything to the project file (changing all hello-world to

13:23 cljs of course), and even though cljsbuild-start (in emacs) says that it compiled, it doesn't build all the files, I only get goog so cljs.core is not available. I tried to build it manually with `leim cljsbuild auto and it just hand at "Compiling ClojureScript". Any ideas? What Am I missing here?

13:23 sorry for the spammy question :)

13:23 replace the first command with `lein mies auto hello-world' :)

13:24 danneu: What's the Clojure equivalent to `Terminal.Color.Red`?

13:27 hyPiRion: In clojure-lanterna, it's `:red`

13:28 danneu: hyPiRion: thanks, i'll check out clojure-lanterna

13:32 yeoj___: is there any easy way to slurp a file, and if it's large just grab the first 100 rows?

13:32 or should i be looking at a lazyseq read file type thing.

13:32 gtrak: yeoj___: line-seq takes a reader

13:32 slurp is not lazy

13:35 danneu: line-seq is great.

13:43 amalloy: danneu: Terminal.Color.Red wouldn't even really work in java - you have to at least spell it RED

13:43 but, since Color is an inner class of Terminal, which has RED as a constant, it would look like Terminal$Color/RED

13:59 danneu: amalloy: thanks. Lanterna docs had both Red and RED

14:30 yeoj___: If i'm filtering based on re-matches with regex groups... how can i reference the individual groups after the filter is matched? It seems as though it comes across as a line only... the groups are gone.

14:30 basically i want to pass the results of re-matches from a filter, rathre than the line that is inbound

14:30 not sure if thats possible

14:33 justin_smith: ,(re-matches #"this((that)other)" "thisthatother") yeoj___

14:33 clojurebot: ["thisthatother" "thatother" "that"]

14:33 amalloy: i think yeoj___ is probably looking for keep rather than filter, or map followed by filter

14:34 yeoj___: ahh ok i don't know about keep yet, i'll look that up.

14:34 i'm puling in a lin-seq based on regex groups, and i want to use the groups inside the with-open .... and I'm sure i don't want to run regex-matches twice...

14:34 i'll check on keep

14:35 justin_smith: yeoj___: anyway, if I understand you correctly you would want to define groups in your RE and look at some of the other indexes in the vector returned by re-matches

14:37 yeoj___: justin_smith: yeah thats the idea

14:40 justin_smith: and yeah, keep or filter⋅map will help there too

14:48 yotsov: I've been trying (unsuccessfully) to understand what Brandon Bloom's Extensible Clojure is. It seems to have its roots in Haskell concepts I am not familiar with. Can anybody recommend any somewhat "simple" read explaining what this sort of extensibility is about?

14:50 justin_smith: yotsov: for one thing, it is very much a work in progress. Do you know the names of any of these haskell concepts in question?

14:50 yotsov: justin_smith: monad transformers to begin with

14:50 justin_smith: yotsov: I trust you saw the link to this on his github http://okmij.org/ftp/Haskell/extensible/

14:51 yotsov: justin_smith: yes indeed, it didn't help me, my knowledge of haskell is basic

14:51 justin_smith: yotsov: there are way too many monad tutorials, maybe #haskell could help you find a good one, or maybe they will just make jokes about mexican food

14:52 mercwithamouth: haskell or #scala in fact if you can get ahold of dibblego (Tony Morris) in either one of those rooms he's one of the best teachers i've come across as far as programming concepts are concerned

14:53 justin_smith: yotsov: birds eye simplistic view, it looks to me like eclj differs from clojure in that clojure (the jvm version especially) tries to be as thin an interface as can be implemented while having a somewhat clean / sane semantics

14:53 yotsov: justin_smith: hehe, I have a basic understanding of monads, but far from enough to grasp the meaning of this paper abstract. The thing is, I was wondering if I could somehow understand the concepts in extensible clojure without deepening my haskell knowledge first

14:53 justin_smith: yotsov: where instead it wants a general view of program transformation that would be portable across clojure implementations, and bootstrapped in clojure itself

14:55 iow what is wanted is to be able to programmatically simplify / optimize / manipulate programs. This is why you want to account for and manipulate side effects of code that is not run yet. Which is where monads and transformations on monads come in.

14:55 I think.

14:56 I would double check the those speculations, but they are based on what bbloom has said so far on this channel, and my understanding of what a "mondad transformer" would be

14:59 yotsov: justin_smith: thanks! that gives me some ideas which way to dig further.

14:59 TerranceWarrior: fireplace.vim is pretty weak.

14:59 nDuff: Is there a way to reexecute cljsbuild when "cljx auto" rewrites generated cljs code?

15:00 technomancy: nDuff: if you had a generalized auto-task thing you could chain them instead of having every plugin reinvent the wheel with auto-watching

15:00 I don't know about cljx auto specifically, but it makes me grumpy

15:02 justin_smith: lazybot: fortune

15:02 lazybot: Difficulty at the beginning usually means ease at the end...except in bed

15:11 fifosine: I have this anonymous function (fn [item] `(foo ~item)) that includes quoting and unquoting. Is there a way to write this with the #(…) macro?

15:12 Chousuke: not really

15:12 fifosine: no? ok

15:13 cbp: #(do `(foo ~%))

15:13 Chousuke: you can do something like #(do `(foo ~%)) I guess but the fn looks nicer

15:13 :P

15:13 justin_smith: yeah, agreed the fn is nicer than that

15:13 fifosine: ok

15:13 why do you guys prefer it?

15:13 justin_smith: unlike ' (quote) I don't think ` has a non-reader-magic version

15:14 fifosine: the fn is not much longer, and is much clearer to read

15:14 and comes out to be the same code

15:15 syntax-quote is the name of `, and it is not bound in clojure.core

15:16 fifosine: Sorry, I'm only just learning clojure, what does non-reader-magic refer to?

15:16 justin_smith: the reader expands some things before macro-expansion

15:16 ` is not a macro, it is a reader-macro

15:16 fifosine: oh ok

15:17 why are there two levels of macro expansion?

15:17 justin_smith: ,(macro-expand '`(this that something))

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

15:17 justin_smith: ,(macro-expand-1 '`(this that something))

15:17 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: macro-expand-1 in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:17 justin_smith: hrmph

15:17 fifosine: because a prefix-character does not follow the standard clojure reading rules

15:18 so special reading rule changes are needed, thus reader-macros

15:18 fifosine: ok, gotcha

15:18 justin_smith: similar for anything beginning with #

15:18 cbp: ,(macroexpand-1 '`(this that something))

15:18 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/this)) (clojure.core/list (quote sandbox/that)) (clojure.core/list (quote sandbox/something))))

15:18 justin_smith: ahh, silly me, thanks

15:18 notice no mention of quasiquote above - the reader expands it before macroexpand-1 sees it

15:18 fifosine: ok

15:19 justin_smith: similar issues for most things with . in them

15:20 honza: what's the idiomatic way of checking if an optional parameter was passed to a function (from inside the function)?

15:21 dbasch: honza: it depends on what you want to do, do you want to have a default value or do you want to do something else?

15:22 honza: dbasch: in this case, i want to set a reasonable default; but interested in both

15:22 dbasch: honza: for a default you could do (or variable default-value)

15:22 justin_smith: ,(map (partial apply (fn [& [y]] (not (nil? y)))) [[] [1] [:a] []]) ;honza

15:22 clojurebot: (false true true false)

15:23 honza: dbasch: yes, but the optionality of the arg makes it a seq

15:24 justin_smith: honza: note how in my example I made it not a seq

15:24 cbp: ^ You can nest destructuring

15:24 honza: (defn f [a & b] ... b is a seq here

15:24 justin_smith: ,(map (partial apply (fn [& [y]] [y (not (nil? y))])) [[] [1] [:a] []]) ;honza

15:24 clojurebot: ([nil false] [1 true] [:a true] [nil false])

15:24 honza: justin_smith: sorry, missed your reply

15:25 justin_smith: np

15:25 dbasch: ,((fn [x & [optional]] (println optional)) 1 2)

15:25 clojurebot: 2\n

15:27 dbasch: ,((fn [x & [optional]] (println (or optional 2))) “A”)

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

15:27 dbasch: ((fn [x & [optional]] (println (or optional 2))) 1)

15:27 ,((fn [x & [optional]] (println (or optional 2))) 1)

15:27 clojurebot: 2\n

15:31 honza: justin_smith: dbasch: welp, somehow it didn't occur to me that it would be nil --- thanks

15:32 dbasch: np

15:46 Glenjamin: hi everyone - is there a shortcut for #(= (:key %) :val) when applied to a map?

15:46 specifically, I'm filtering a seq of maps where (= (:key %) :val)

15:47 fifosine: Is there a way within repl to view what java source is generated by a function?

15:51 dbasch: fifosine: you mean bytecode?

15:51 fifosine: No, I mean the human-readable source

15:52 dbasch: fifosine: clojure compiles to bytecode, not java

15:52 fifosine: Oh ok

15:52 cbp: You can compile and then use a decompiler

15:52 Bronsa: fifosine: https://github.com/gtrak/no.disassemble is the best you can get

15:52 fifosine: I was just wondering if there was something quick so that while I'm exprimenting in the repl, I can just see other interpretations of the code

15:53 I don't want anything complicated

15:53 gtrak: fifosine: it's possible to hook up a java decompiler, I'd welcome a PR :-).

15:54 Bronsa: gtrak: I don't think all the bytecode generated by clojure has a corrispondence with java though

15:54 gtrak: oh, huh, good point.

15:54 ambrosebs: Glenjamin: (comp #{:val} :key)

15:54 gtrak: can't hurt to try.

15:54 http://jd.benow.ca/ supports up to 1.7

15:54 fifosine: there are instructions in java bytecode that can't be represented decompiled?

15:54 gtrak: this is not meant to be used in production :-)

15:54 Glenjamin: ambrosebs: thanks, i thought there was a trick with sets, but couldn't remember it

15:55 technomancy: fifosine: yeah

15:55 fifosine: huh, that's weird

15:55 technomancy: fifosine: locals clearing being the main one that comes to mind

15:55 gtrak: invokedynamic?

15:55 technomancy: iirc you can also do intra-method gotos in bytecode

15:55 Bronsa: technomancy: I was thinking of that aswell

15:55 dbasch: here’s an interesting series of posts about decompiling clojure to bytecode http://blog.guillermowinkler.com/blog/2014/04/27/decompiling-clojure-iii/

15:55 technomancy: (or maybe that was just a proposal)

15:55 gtrak: technomancy: within one method, that's how loop-recur works.

15:56 sets a jump target.

15:56 technomancy: oh sure

15:56 dbasch: fifosine: it’s not java bytecode, it’s jvm bytecode

15:57 fifosine: If I have a function that returns a sequence, but I know in specific situations it will return a sequence of one element, is there a prettier way of retrieving that singleton versus (first …)?

15:57 technomancy: fifosine: you can destructure it

15:58 fifosine: technomancy: What does that mean?

15:58 gtrak: fifosine: well, no-disassemble can return data structures now, it would be easy to walk over them and print it however you like.

15:58 dbasch: ,(let [[a & rest] [1 2 3 4]] a)

15:58 clojurebot: 1

15:59 fifosine: I guess I prefer first over a let

16:00 justin_smith: fifosine: yeah, it makes more sense when the value is already in a fn args list or in a let

16:01 ,((fn [[a & rest]] [a a]) (range))

16:01 clojurebot: [0 0]

16:03 klokbaske: any clojure shops in copenhagen? :-)

16:08 grimmulfr: Anyone that does web dev with clojure & friends: do you work with clojure alone? Or integrate with php backends of sorts? (maybe clojurescript + json/ajax requests?!)

16:08 lvh: hi

16:08 mercwithamouth: grimmulfr: friend library?

16:09 lvh: I'm trying to write something that interacts with a foreign rest service through clj-http

16:09 justin_smith: grimmulfr: clojure on the backend, js+sass on the frontend (we are a shop mainly known for design / frontend quality)

16:09 lvh: for testing I obviously don't want to actually itneract with the rest service

16:09 rhg135: php...

16:09 mercwithamouth: funny i was just aboutt o ask a similar question. does anyone use liberator ad friend together

16:09 justin_smith: grimmulfr: so my job on the backend is to make things seamless for frontend, and let them do things as they would normally

16:09 lvh: in python, I would pass around an object with some interface, and just stub the methods

16:10 how do I do it in clj? pass around a map with some functions?

16:10 justin_smith: lvh: a map can have functions in it

16:10 lvh: justin_smith: Yes, I understand; that's what I'm suggesting :)

16:11 justin_smith: ahh, I misparsed "with" there

16:11 lvh: e.g. {:validate #(...) :submit #(...)}

16:11 is that a reasonable way to do it?

16:11 justin_smith: lvh: in general my best results in clojure are making things pure stateless functions whereever there is any "logic" to speak of

16:11 grimmulfr: I meant friends as in clojurescript/jayq/hiccup etc :)

16:11 justin_smith: and making all imperative/stateful parts into minimal logic free stubs

16:12 that makes it easy to do comprehensive testing of everything that is not a remote service

16:12 which you would not test directly anyway

16:12 lvh: justin_smith: sure, absolutely; but the rubber has to hit the road somewhere right

16:12 I guess Id on't really have to test the I/O bits and just supply some JSON response strings

16:12 justin_smith: right, because IO is part of the stateful stuff

16:13 and I really do mean abstract out everything stateful

16:13 so the remaining functional code can get a map / json as input and you can verify it has the right output

16:14 grimmulfr: Thing is, the projects I usually work on involve a server that I don't have access to (actual access, to run ring and whatnot) so I don't really know how to grasp the whole full clojure backend thing

16:14 I guess I could handle all the routing and whatnot, and use a clojure library for mysql (if that's even possible /me = new )

16:16 justin_smith: grimmulfr: yeah, clojure.java.jdbc works nicely with mysql

16:16 grimmulfr: There's so many things that do similar stuff, my head is spinning. I just need to find a working list of items that have good sinergy

16:16 mercwithamouth: heh...extremely overwhelmed even trying to begin dealing with authentication with liberator and friend =(

16:16 grimmulfr: synergy even :D

16:17 I have my own PHP coder that cand handle the backend when the time comes so that's really not a problem.

16:17 I mostly do frontend stuff anyway nowadays. and usually flash, but I plan on slowly switching to html5/6

16:17 justin_smith: mercwithamouth: I think I almost have friend figured out, but it was definitely not intuitive for me at least, so don't feel bad about that

16:17 grimmulfr: So tired of flash, god damn it

16:20 Is there a nice and widely accepted as "good/the best" templating (or general frontend ui stuff) library?

16:20 if for example I want to build my content from the ground up

16:20 Also, compojure seems to be the most used routing lib, would that be accurate?

16:21 justin_smith: grimmulfr: folks here will try to help I am sure, but for frontend (clojurescript) stuff, be sure to ask on #clojurescript

16:21 grimmulfr: yes, but it is a backend routing lib

16:21 grimmulfr: Oh, sorry, didn't know that existed :)

16:21 * grimmulfr will update the autojoins

16:22 justin_smith: grimmulfr: np, it is all clojure, but this channel has a strong jvm-clojure bias I think

16:23 grimmulfr: Not to say that I won't ever do backend too. I kind of like the speed clojure provides when working with lists, and I work with a ton of those (I work in advertising, and we have a ton of campaigns involving codes, ids, saved data etc)

16:26 justin_smith: grimmulfr: I am also in an agency shop, but really I think clojure's immutable / data-centric approach is almost always a win (with a few possible exceptions for when you need the absolute best possible cache line and memory performance, where you wouldn't be using PHP or the like anyway)

16:32 grimmulfr: Plus, clojure source is freakin sweet

16:32 aesthetic-wise :)

16:33 jamesnvc: if I want to compile clojurescript at runtime via cljs.closure/build, is there something special I need to do to make :require work?

16:34 Just generating js is working okay, but If I try to require om, I get a bunch of errors about undeclared vars and an exception when I try to load the page

16:35 nullptr: jamesnvc: just a guess, but are you providing an extern for react (or react itself)?

16:35 jamesnvc: yup

16:35 doing the :preamble [“react/react.min.js”] and the :externs

16:35 TimMc: At work we have some Clojure libraries that we'd like to expose to Java consumers but also keep easily available to Clojure callers. Is this a reasonable solution?

16:36 Export example: https://github.com/timmc/lib-3844/blob/cbe53bab9/src/lib_3844/api.clj#L58

16:36 How it would look as an API: https://github.com/timmc/lib-3844/blob/cbe53bab9/src/lib_3844/core.clj

16:37 devn: I have a go loop which is doing blocking takes from a port. I know i need alts!! or alt! or alts! here, but I'm having trouble setting it up right. I basically want to wait a few seconds, and if (<!! my-port) is still blocking and waiting, i want to System/exit 0

16:38 lvh: hi

16:38 how do I read some bytes from the OS' CSPRNG?

16:38 devn: (go-loop [v (<!! port)] ...)

16:38 lvh: (Does Java's SecureRandom do that by default if it can?)

16:40 TerranceWarrior: How does one do 3d Graphics in Clojure or ClojureScript?

16:41 l1x: is there any serious performance difference between a () and a []?

16:41 devn: l1x: depends on what you're doing, but yes, there can be

16:41 l1x: i am storing a bunch of small hashes in it for further processing, size is 1000 elements max

16:42 ok i guess i need to benchmark it

16:42 justin_smith: l1x: use [] if you need lookup by index or addition at the end, () if you need addition at the front

16:42 devn: l1x: adding to the front vs adding to the end

16:42 l1x: i see

16:42 devn: what justin said

16:42 ,(conj '() 1)

16:42 clojurebot: (1)

16:42 devn: ,(conj '(1 2) 1)

16:42 clojurebot: (1 1 2)

16:42 devn: ,(conj [1 2] 1)

16:42 clojurebot: [1 2 1]

16:43 l1x: yep, thank you guys, much appreciated

16:43 devn: np

16:43 justin_smith: also () can be lazy, [] cannot

16:44 dbasch: lvh: yes, use SecureRandom

16:44 amalloy: lvh: i don't think you care about reading from any particular cryptographically secure RNG, just about getting some secure bytes

16:44 and that's what SecureRandom is for

16:44 jamesnvc: Are there any severe gotchas around calling cljs.closure/build at run time?

16:45 Because it is starting to seem to me that either I’m insane, missing something big, or computers hate me

16:47 lvh: amalloy: That's true, but I trust the OS's CSPRNG a lot more than I trust a userspace one.

16:48 dbasch: Is that "yes, SecureRandom is just something that secretly reads from /dev/urandom on *NIX and calls CryptGenRandom on Windows"?

16:48 dbasch: lvh: not sure about Windows, but that’s what it does on Unix

16:50 lvh: Gotcha.

16:51 dbasch: lvh: yes, it uses CryptGenRandom on windows

16:51 lvh: I was thinking of the issues with Android's SystemRandom, but apparently that's only Android

16:52 And, IIUC, on Android today it still means "OpenSSL CSPRNG output"

16:57 ucb: am I right to think that if I want a namespace with hypens in its name, e.g. root.my-ns, then the file must be named with underscore, i.e. my_ns.clj?

16:57 arrdem: ucb: correct.

16:57 ucb: oh, urgh

16:57 arrdem: ucb: if you use dashes in the filename, the clojure compiler can't find it.

16:57 ucb: I think I came across a Java thing then

16:57 yes

16:58 so I can require root.my-ns

16:58 but if I want to reference a record in there, I have to do so like root.my_ns.Record :/

16:58 arrdem: aren't implementation details a gem!

16:58 ucb: gorgeous!

16:58 arrdem: I'd actually open a ticket over that... just because it isn't the "obvious" behavior.

16:59 Bronsa: ^^ thoughts?

16:59 ucb: arrdem: https://gist.github.com/11383711

16:59 technomancy: there's a ticket for it already

16:59 arrdem: technomancy: oh good.

16:59 ucb: ah, cool

16:59 I was puzzling over this for a good ... 2h now.

16:59 arrdem: ucb: that really means you log in and vote for the existing ticket then :P

16:59 Bronsa: arrdem: it's one of the most voted ticket too.

16:59 technomancy: it's tragic how much time it wastes

16:59 ucb: arrdem: log in? how? where?

16:59 * arrdem rolls his eyes

16:59 technomancy: usability woooo

16:59 ucb: heh

17:00 arrdem: ucb: dev.clojure.org jira lemme find it...

17:00 technomancy: http://dev.clojure.org/jira/browse/CLJ-1297

17:00 arrdem: (inc technomancy)

17:00 lazybot: ⇒ 107

17:01 arrdem: oh good I already voted that one up.

17:01 technomancy: basically crickets from anyone who actually has the power to do anything though

17:01 as usual

17:01 justin_smith: yogthos|away: I pushed the updated unit tests for the rss:atom pr, I guess I need to update the pr too

17:02 ucb: hrm

17:02 but that issue isn't quite what I have on my hands now

17:02 I knew about the - _ duo

17:02 my beef is with not being able to talk about root.my-ns.Record

17:02 justin_smith: yogthos|away: oh, never mind, I guess github tracks against the head of the branch I issue the pr on, so it is updated automatically, never mind the noise

17:02 ucb: but rather having to talk about root.my_ns.Record

17:03 because Java (I assume)

17:20 devn: Anyone mind taking a peak at this? https://gist.github.com/devn/72d8d9ad414ef448ced3 -- core.async stuff.

17:21 I could use some help. `lein run` will just sit there. I need a way to exit once I know all the work has been completed.

17:22 justin_smith: devn: I think shutdown-agents is required along with the System/exit

17:22 (doc shutdown-agents)

17:22 clojurebot: "([]); Initiates a shutdown of the thread pools that back the agent system. Running actions will complete, but no new actions will be accepted"

17:22 devn: I'm not seeing it print "STOP!"

17:23 justin_smith: oh, that's odd

17:23 technomancy: https://github.com/fredericksgary/system-slash-exit

17:23 justin_smith: devn: are you running from a terminal or via nrepl/cider/whathaveyou?

17:23 devn: term

17:23 justin_smith: devn: if the latter, you may need to check the process output buffer because threads

17:23 devn: i think there's something wrong with my core.async stuff

17:23 justin_smith: oh

17:24 technomancy: surprised that doesn't also wrap shutdown-agents actually

17:24 technomancy: gfredericks: ^^

17:25 justin_smith: also, congrats, I think that is the smallest actual clojure lib I have ever seen

17:26 tempted to submit code-golf prs to that repo, given how small it is already :)

17:26 devn: justin_smith: yeah, it's the async stuff. if i add a (println [v c]) i see that it will return :continue :default forever

17:26 hmmm

17:28 amalloy: gfredericks: https://github.com/fredericksgary/system-slash-exit/blob/master/src/com/gfredericks/system_slash_exit.clj#L4-L5 - i don't see many people restricting themselves to 70-column lines

17:32 stompyj: How has core.typed been received?

17:33 devn: pretty well i'd say

17:33 considering it was well-funded on kickstarter, has some serious users

17:34 pulsar being one of the more substantial i've seen lately

17:34 TerranceWarrior: do you people generally distribute .jnlp s ?

17:34 devn: "you people

17:34 "

17:35 justin_smith: TerranceWarrior: never touched it

17:36 TerranceWarrior: if you install icedtea-netx , it will autorun java from within a browser.

17:36 TEttinger: TerranceWarrior: uberjars are pretty common I think

17:36 stompyj: devn: is pulsar a lib? or a company?

17:37 I donated to it, then promptly forgot it existed

17:37 and am wondering if it wouldn’t help me right now

17:38 devn: stompyj: they are a YCombinator company

17:38 and yes it is a lib

17:38 stompyj: https://github.com/puniverse/pulsar

17:38 it wraps quasar

17:38 stompyj: i didn't get too far with it last friday, but it is certainly cool

17:39 TerranceWarrior: TEttinger: right

17:39 stompyj: devn: thanks!

17:47 mmitchell: anyone here use bidi, the routing lib?

17:47 amalloy: suppose i have a list like '(a b c), and i want to repeat its items five times to get a single list of 15 elements. is there a better way than (apply concat (repeat 5 xs))? that apply concat feels unpleasant

17:48 i suppose i could also write `(~@xs ~@xs ~@xs ~@xs ~@xs). yikes

17:48 justin_smith: dunno, (mapcat identity (repeat 5 xs))

17:48 that's not really any better

17:48 amalloy: i guess i was just hoping there's a repeat-cat in core that i don't know about

17:48 TEttinger: (doc cycle)

17:48 clojurebot: "([coll]); Returns a lazy (infinite!) sequence of repetitions of the items in coll."

17:49 amalloy: no, i don't much care for mapcat identity/seq

17:49 justin_smith: (take 15 (cycle xs))

17:49 (inc TEttinger)

17:49 lazybot: ⇒ 17

17:49 justin_smith: beat me to it

17:49 TEttinger: ,(take 15 (cycle '(a b c)))

17:49 clojurebot: (a b c a b ...)

17:49 TEttinger: hooray

17:49 amalloy: yeah, i did consider cycle. but then i have to know how many items are in xs and do multiplication

17:49 Bronsa: justin_smith: TEttinger that's assuming your list has a known length

17:50 justin_smith: oh, yeah

17:50 mikerod: I heard in a talk/read somewhere an explanation of the -> vs the ->> macros in clj. The explanation described how they are typically for different "modes" of sequence operations. What is this that I'm trying to remember?

17:50 Bronsa: looks like it would be trivial to add a 2-arity version of cycle though

17:51 amalloy: i actually need some other stuff in between, so `(~@xs ~@xs ~@xs ~foo ~@xs) is not looking so bad

17:51 TEttinger: one supplies an arg to the first position in an arglist, one supplies an arg to the last position, mikerod

17:51 justin_smith: Bronsa: yeah, that would be nice, following in the example of repeat and partition for example

17:52 TEttinger: mikerod, I guess the talk is probably about argument order in clojure and how the API is arranged?

17:52 mikerod: TEttinger: yes, I'm more trying to recall this good way of explaining the difference. I understand where threaded items are placed. thanks though

17:52 TEttinger: I can't remember :( I was just explaining the thread macros to someone and wished I could remember what I heard on that topic. I was just wondering if it was something obvious that someone would immediate recognize.l

17:52 justin_smith: mikerod: often the last arg will be a sequential argument, while the first arg will be an associative one

17:53 amalloy: mikerod: functions that deal with sequences should be arranged to make ->> convenient, while those which work with other stuff should make -> convenient

17:53 justin_smith: not just associative, but also atoms, refs, and so on

17:53 justin_smith: ahh, yeah, pretty much all the non-sequential stuff :)

17:54 mikerod: Hmm, ok. That sounds like a pretty reasonable way to put it.

17:54 justin_smith: I was thinking of how often a map or ref would be the first arg

17:54 s/ref/record

18:12 Bronsa: justin_smith: amalloy http://dev.clojure.org/jira/browse/CLJ-1412

18:12 justin_smith: very nice!

18:14 technomancy: Bronsa: does that have the optional argument first?

18:15 justin_smith: http://dev.clojure.org/jira/secure/attachment/12965/0001-Add-2-arity-version-of-cycle-that-takes-the-number-o.patch yup, like the other optional count args

18:15 Bronsa: technomancy: yes, like repeat/repeatedly & friends

18:15 technomancy: huh; I thought that was an anti-pattern

18:16 but I guess there's precedent

18:16 amalloy: technomancy: seems pretty normal for functions which take sequences (which, as recently discussed, take those sequences last)

18:18 actually, IIRC you're in favor of a multi-arity filter, right? (filter xs) => (filter identity xs)? same thing there

18:18 technomancy: amalloy: that is the main reason I haven't pushed harder on multi-arity filter, yeah =)

18:18 I guess it's just a problem if you take var-args

18:18 grimmulfr: Hmm, this might sound stupid but can ypu not use more than one :use in a source?

18:19 Bronsa: amalloy: that's also the same for reduce. (reduce f coll), (reduce f init coll)

18:19 justin_smith: :use can take multiple libs, so that is not an issue. Also seriously consider :require [foo.bar :as bar] ... instead of :use, it is better in the long run

18:19 amalloy: reduce is even weirder, because its optional arg comes in between the two required ones

18:20 grimmulfr: I want to have both jayq and hiccup in my file, but apparently I can't ":use" them both, and I'm just following their wikis :(

18:20 justin_smith: grimmulfr: (:use [foo.bar] [baz.quuz]) it can all go in one :use block

18:20 technomancy: amalloy: weird behaviour there is easy to blame on CL

18:21 Bronsa: amalloy: right. my brain was thinking of "reduce f" as a singleton

18:21 amalloy: technomancy: i'm not really interested in blaming anyone for it. it's the most natural order, i think

18:21 hyPiRion: technomancy: actually, CL is more sane there

18:21 justin_smith: grimmulfr: but really even though the docs show :use, :require with :as is better

18:21 grimmulfr: I tried that and still no go. My line is: (:use [jayq.core :only [$ append delegate data]] [hiccup.core])

18:21 I get clojure.lang.ExceptionInfo: Only [lib.ns :only (names)] specs supported in :use / :use-macros; offending spec: [hiccup.core] at line 1

18:21 amalloy: well, maybe that's not true, but nothing else is lots more natural, anyway

18:22 hiredman: if anything, clojure's reduce arities come from haskell or ml, not cl

18:22 technomancy: huh

18:22 hyPiRion: (reduce #'list '(1 2 3 4) :initial-value nil) and (reduce #'list '(1 2 3 4) :from-end t)

18:22 amalloy: grimmulfr: does hiccup exist in cljs?

18:23 grimmulfr: Hmm...I'll just play the I'm new and have no idea card here

18:23 technomancy: hiredman: but the reducer function itself takes flipped args in ML iirc

18:23 nullptr: there is sablono, but that's targeted towards om usage

18:23 technomancy: always threw me off

18:23 tieTYT2: how does that quote go? 100 functions on 1 collection is better than 10 functions on 10 collections

18:23 technomancy: or maybe that was racket

18:23 amalloy: i guess it does. but the readme for hiccups (https://github.com/teropa/hiccups) doesn't include that ns form - it looks like you're trying to use the jvm version of hiccup on cljs, grimmulfr

18:24 grimmulfr: I used regular hiccup :(

18:24 Frozenlock: amalloy: https://github.com/ibdknox/crate

18:25 hiredman: my kingdom for a web browser that would show you anchors points even if the author of the thoughtless didn't include a link to them

18:25 justin_smith: sounds like an awesome userscript or chrome extension lib

18:26 amalloy: hiredman: amusingly, over the weekend i sent someone a pull request to add hrefs to the anchors they already generated

18:26 Frozenlock: hiredman: How would you do that, considering that IDs are used everywhere in js?

18:26 tuft: hiredman: yeah, and how about one that gives you keyboard hints for everything that's clickable instead of just an annoying subset =)

18:26 Frozenlock: (not just for anchors)

18:26 amalloy: Frozenlock: <a name="...">, not everything with an id

18:26 Frozenlock: ah right

18:27 tuft: hiredman: need a webkit browser programmed in cljs

18:27 justin_smith: yeah, how many times have I found a heading I want to share in wikipedia, then had to navigate to the top of the article to find a link to it :(

18:27 hiredman: technomancy: http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html#6_Iterators

18:28 technomancy: hiredman: yeah, I was thinking of racket

18:28 amalloy: ugh, the autogenerated signatures for foldr/foldl are confusing

18:28 they swap the meaning of a and b, instead of swapping the argument order to your folder

18:28 Bronsa: hiredman: there's https://addons.mozilla.org/en-us/firefox/addon/show-anchors-2/

18:29 justin_smith: amalloy: yeah, that's pretty dysfunctional

18:29 hiredman: Bronsa: jokes on you, I don't have a kingdom

18:29 amalloy: *chuckle*

18:29 justin_smith: https://chrome.google.com/webstore/detail/show-anchors/nhppnhnadikeniijclnghjfblnojgige?hl=en for chrome

18:30 hiredman: amalloy: and fold_right takes the list and the init in a different order too

18:30 Bronsa: I didn't want it anyway.

18:31 amalloy: hiredman: i'm choosing to ignore the gross signatures in ocaml, and instead focus on the mildly-confusing ones from haskell

18:32 hiredman: "here, have three half built castles" "wait, but is only half built!" "well, you know, I was sling morter one day and realized the morter was drying to faster which would compromise the wall, so I started play with mud, and well time makes fools of us all..."

18:33 arrdem: (inc hiredman)

18:33 lazybot: ⇒ 45

18:40 nDuff: Hmm. I'm having an issue w/ code generated by cljs.core.async's go macro complaining about a (recur) at the end of a try block but for a catch; the try block is the last item in the enclosing (loop). Is there a relevant behavioral difference here? I don't have comparable problems on the JVM.

18:46 Bronsa: nDuff: youy mean (loop [] (try (catch Exception _ (recur)))) ?

18:47 nDuff: @Bronsa, rather, (loop [] (try (recur) (catch Exception _ (do nil))))

18:47 js/Error rather than exception, but...

18:47 Bronsa: nDuff: are you sure that works on the jvm? there should be no way to recur across try blocks

18:47 coventry: That gives me a compile error in jvm clojure (outside a go block.)

18:48 nDuff: that was rough draft rather than actual code; one moment...

18:51 gfredericks: amalloy: my apologies

18:51 justin_smith: technomancy: why would wrapping shutdown-agents be useful?

18:52 it's already a var

18:52 justin_smith: gfredericks: just for convenience, because exiting and calling shutdown-agents often go together

18:52 nDuff: Okay -- that was a misconstructed example. The actual macro I've been using with clojure/jvm, with (loop [] ...) constructs within the body, is https://www.refheap.com/e59721cb94ebe17f094e7b582

18:52 justin_smith: gfredericks: I can see few situations where you would want to exit and not shut the agents down

18:54 gfredericks: justin_smith: I would be happy to see somebody create a system-slash-exit-and-shutdown-agents lib

18:54 arrdem: that'd be messy... you'd have to either track all the agents at init time or introspect the clojure core threadpool...

18:55 justin_smith: I'd probably call it ejector-seat

18:56 arrdem: I am just talking about calling the shutdown-agents function so the jvm can exit sooner

18:58 arrdem: justin_smith: alternative names: bang-seat, loud-handle, martin-baker

18:58 justin_smith: !seat

18:58 lol

18:58 coventry: nDuff: If the loop compiles outside that context, sounds like a bug.

18:59 arrdem: did you hear me say _BANG_seat?

18:59 :P

18:59 justin_smith: you don't pronounce ! as bang?

18:59 arrdem: why would I read _BANG_ as "bang"....

19:00 johann__: hey guys--i am trying to set up datomic on a heroku postgres instance. when i try to connect my transactor to it i am getting the error "sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"

19:01 mdeboard: johann__: Wow.

19:01 johann__: We had an issue with this error last week unrelated to clojure/heroku/datomic

19:01 arrdem: justin_smith: trap is another potential term..

19:02 johann__: mdeboard: atleast i am not alone!

19:02 mdeboard: It just means (i think) that Java's SSL library doesn't recognize the certificate authority of the SSL cert

19:02 johann__: Out of curiosity, what key length was used to generate the cert? Do you know? 2048? 4096?

19:03 johann__: Do you know who the CA is for your SSL cert?

19:03 johann__: mdeboard: not a clue.

19:05 mdeboard: try connecting over http instead of https?

19:07 johann__: mdeboard: i'll give it a shot! thanks :)

19:12 wink: johann__: OS X/Windows? ;) https://github.com/technomancy/leiningen/issues/619 https://github.com/technomancy/leiningen/issues/613

19:12 * wink faintly remembers ssl weirdness

19:16 johann__: wink: woe to the endless labyrinth of technologies. i'm on osx

19:18 justin_smith: arrdem: SHUT DOWN FOR WHAT‽‽‽‽ (sorry)

19:18 arrdem: justin_smith: I'll send you pics when we use that for a party...

19:18 justin_smith: thanks for the idea :D

19:20 justin_smith: heh

19:29 kurtharriger: hey yo

19:29 danielglauser: kurtharriger: technomancy: Intro

19:29 technomancy: ohai

19:32 dbasch: if you ever need to generate bitcoin addresses in clojure, it’s not pretty. https://www.refheap.com/82567

19:33 Frozenlock: dbasch: ugh

19:33 mdeboard: dbasch: What's the .. sigil?

19:33 key-params?

19:33 amalloy: ,(doc ..)

19:33 clojurebot: "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."

19:33 justin_smith: mdeboard: chains methods

19:33 clojurebot: Huh?

19:34 justin_smith: mdeboard: lets you do the equiv of x.y.z.bar() in clojure

19:34 mdeboard: Wow.

19:34 Now... that is a difficult operation to google.

19:34 amalloy: really (.. foo x y z) is more nicely written as (-> foo .x .y .z) these days

19:34 dbasch: mdeboard: sigil?

19:34 amalloy: .. is a relic of the days before ->

19:35 mdeboard: amalloy: ah

19:35 dbasch: Oh, I guess I used the wrong word

19:35 I should've just said symbol

19:35 dbasch: gotcha

19:35 amalloy: choose you flavor of ugly :)

19:36 technomancy: kurtharriger: hey, can you identify with nickserv so I can pm you?

19:36 amalloy: mdeboard: well, sigil was reasonable, since not every funny squiggle in .clj code is actually a symbol

19:36 eg, ~@

19:36 mdeboard: dbasch: Oh man I think the threading semantics are just gorgeous

19:37 dbasch: I guess creating bitcoin key/address pairs is ugly in every language

19:37 mdeboard: I don't think that's particularly ugly

19:37 kenrestivo: i've not seen a language in which crypto was not ugly

19:38 mdeboard: Though putting the mutations in the let block strike me as kinda weird

19:38 but as good as any

19:38 s/weird/unfamiliar

19:39 eraserhd_: Time to code some more on my weird, heavy threading macro.

19:53 mdeboard: Are there any battle-tested authentication & authorization bits for Compojure out there? I saw cemerick's Friend repo but it's still pretty early on that one.

19:55 dbasch: mdeboard: that’s as battle-tested as there is. I had to write my own password authentication based on scrypt for an app.

19:55 mdeboard: Wow that's surprising

19:56 I mean I'm wondering what Prismatic uses

19:56 dbasch: mdeboard: indeed. I’ve been thinking about how to create a user/password store that’s modular / abstract enough to share

19:57 mine uses scrypt and postgres

19:57 and specific details about users that not everyone will care about

19:57 mdeboard: Well, I think table stakes there is user/pass + openid/oauth/etc. support

19:57 justin_smith: dbasch: if you want aes128 and persistance of an arbitrary clojure form (likely a map) on disk, there is my cryptlj lib

19:57 https://github.com/noisesmith/cryptlj

19:57 mdeboard: or rather, account management + sso support

19:58 dbasch: mdeboard: friend is good enough if you want openid

19:59 justin_smith: that looks useful for a different use case, but probably not what I need for passwords

19:59 passwords are not really encrypted, just one-way hashed

19:59 justin_smith: my use case was: you want credentials at runtime, and not everyone who has access to the repo should have access to those credentials

20:00 dbasch: OK, friend has bcrypting of passwords built in

20:00 or you could directly use whatever bcrypt lib

20:00 I think that is pretty much the state of the art (last I checked)

20:00 dbasch: justin_smith: yes, it does bcrypt but you have to provide the store

20:01 it assumes you have a db somewhere to check against

20:01 justin_smith: well it can be any lookup function you desire

20:01 but a db is the most common case

20:01 dbasch: not to mention that (to my knowledge) nobody has implemented things like change-password, reset-password, create-user, etc

20:02 justin_smith: that is just some set of functions on the store (which friend is rightly agnostic to)

20:02 dbasch: justin_smith: of course, but there should be a user management component somewhere

20:02 justin_smith: definitely outside of friend

20:03 justin_smith: dbasch: the downside to clojure's opinionated dislike of frameworks I think (it is a space where two featuresets (persistence and auth) intersect, so you must connect dots)

20:03 that said, I think avoiding frameworks is the right thing (despite being a maintainer of a framework)

20:04 dbasch: justin_smith: I tend to agree with that opinionated dislike

20:04 technomancy: justin_smith: I dunno, I think friend being complicated goes beyond just disliking frameworks

20:04 justin_smith: technomancy: here I thought I had it all figured out :) what other problems do you see?

20:04 dbasch: justin_smith: that’s why I don’t know how to implement a user management layer that’s modular / abstract enough to be useful

20:05 technomancy: justin_smith: I remember staring at the readme blankly and deciding to do something else a couple times.

20:05 maybe it's gotten better

20:05 justin_smith: dbasch: kind of like a last-mile problem

20:05 dbasch: justin_smith: yes, and one that pretty much everyone has

20:06 justin_smith: technomancy: sounds like my experience too - but based on my attempts to use it, I think this has to do with the preference for libs that do one thing in clojure, and how that conflicts with the existential / sweeping demands of security

20:06 dbasch: everyone needs to create and maintain user stores at some point

20:07 technomancy: justin_smith: maybe. I haven't written a full-fledged user-handling web app, so my needs have been simpler, but I think you could do better on the usability front without sacrificing orthogonality.

20:07 dbasch: and that includes reallly unpleasant tasks like email verification, forgotten passwords, enforcing password standards, etc

20:07 justin_smith: except the paridigmatic cowboy solitary genius programmer, he only writes single user programs that solve all his problems and he doesn't need our help

20:08 technomancy: yeah, but to be honest I don't know how - it's a tricky space

20:09 dbasch: justin_smith: indeed, and it’s also kind of a full-stack problem

20:10 justin_smith: and full stack problems in a modular space are DWIM complete :)

20:10 dbasch: especially when you bring 2FA into the mix

20:13 danielszmulewicz: Hi, anybody knows how to do entity expansion in OM/sablono? Given a string "It&#39;s one of kind.", how do I render the apostrophe?

20:17 justinholguin: Does anyone here use emacs/evil for Clojure development?

20:18 I mean emacs _and_ evil

20:19 Jaood: ,anyone

20:19 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: anyone in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:19 TEttinger: ~anyone

20:19 clojurebot: anyone is anybody

20:19 TEttinger: ~anyone

20:19 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 ..."

20:20 justinholguin: Just looking for some general pointers or advice on using CIDER with evil, I guess.

20:20 mdeboard: 20:02 <justin_smith> technomancy: sounds like my experience too - but based on my attempts to use it, I think this has to do with the preference for libs that do one thing in clojure, and how that conflicts with the existential / sweeping demands of security

20:21 Nailed it

20:21 ,(inc justin_smith) ;; hope I did this right

20:21 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:21 mdeboard: dammit

20:21 metellus: (inc justin_smith)

20:21 lazybot: ⇒ 36

20:21 clojurebot: It's greek to me.

20:21 mdeboard: (inc justin_smith)

20:21 lazybot: ⇒ 37

20:21 mdeboard: cool

20:21 pdk: ,pdk

20:21 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: pdk in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:21 pdk: weak

20:23 mdeboard: justinholguin: What is it about that combo that makes it worth the hassle?

20:23 evil + cider, I mean

20:25 justin_smith: mdeboard: if you'd rather be using vim but fireplace is not good enough

20:25 justinholguin: mdeboard: Fair question, but right now I'm sort of trying to figure out what makes emacs/cider so great in the first place. I don't really want to give up the speed of vim.

20:25 mdeboard: oh

20:25 justinholguin: What my co-Justin said

20:25 mdeboard: Yeah I feel your pain, but in reverse

20:25 justin_smith: heh

20:26 justinholguin: In reverse how?

20:26 mdeboard: elixir-mode for emacs is broken, but the vim plugin for elixir works great

20:26 justinholguin: Ahh

20:26 mdeboard: so when I want to write elixir, I have to use vim

20:26 and it feels like a fish riding a bicycle

20:26 justinholguin: But you want some sort of... emacs mode?

20:26 haha

20:26 mdeboard: naw

20:26 justin_smith: one of the outdated vi-emulation modes (name escapes me) was my gateway drug to emacs

20:26 mdeboard: Just saying I understand if you're muhc more proficient with vim why you'd be looking for an integration

20:26 justinholguin: A wise man once said, there's rarely a problem that can't be solved by rubbing a little elisp on it.

20:26 justin_smith: oh yeah, ViPer

20:28 justinholguin: Jumping straight into the evil/cider combo was a mess. Too many shortcuts clashing, I guess. I was hoping to get some idea of how other people reconcile the two.

20:28 mdeboard: fwiw I tried evil because I do like a lot of things about vim (also because I use it a non-trivial amount), but it just didn't go well for me

20:28 ambrosebs: vim fireplace is just fine for me.

20:28 mdeboard: justinholguin: Is there something wrong with fireplace? I've heard it's really good

20:29 ambrosebs: It's not emacs.

20:29 so it sucks apparently.

20:29 mdeboard: now now

20:29 I'm sure no one still thinks that

20:30 Well, no one who'd use Clojure

20:30 justinholguin: Fireplace isn't terrible by any means (praise tpope), but the grass still looks a lot greener on the cider side of things.

20:30 Also elisp>vimL

20:30 mdeboard: by speed did you just mean your vim muscle memory?

20:30 or editor runtime

20:30 justinholguin: More muscle memory, I can cope with the start time

20:30 mdeboard: Yeah

20:31 It's rough. But gotta use the best tool for the job

20:31 That said I don't write much elixir because it's tiring thinking about struggling with vim for an hour before I can get in the groove

20:31 justinholguin: I find that a lot of the vim commands I use a lot don't have any equivalent in emacs (outside of evil)

20:31 mdeboard: like what

20:32 nullptr: danielszmulewicz: i don't see any clean way to do it, but you can use goog.string.unescapeEntities as a workaround

20:32 justinholguin: Number 1 would be most things involving a motion, like dt; (delete upto the next ;) or something

20:33 danlamanna: justinholguin: zap-to-char?

20:33 mdeboard: I'm sure there's an equivalent for that

20:33 technomancy: learning the expression-based movement commands helps a lot

20:33 justinholguin: There are equivalents for all of them... in evil

20:33 mdeboard: I mean when it comes to just straight-up text editing I can't imagine the two aren't extremely close in features/capabilities

20:34 technomancy: forward-sexp, etc

20:34 paredit helps more

20:34 mdeboard: paredit drives me nuts

20:35 justinholguin: Yeah, I'm sure that emacs will end up being able to do everything I want, but it seems like the most parsimonious way to do that probably starts with evil

20:35 technomancy: mdeboard: paredit will be there for you when you change your mind

20:35 justinholguin: I love paredit

20:35 mdeboard: technomancy: It's just that it makes me change how I do certain things, and I have never taken the time to acclimate

20:36 justin_smith: I have found that any friction between my habits and paredit are flaws in my habits :)

20:36 technomancy: truth

20:39 danielszmulewicz: So it's `unescapeEntities` in google's Closure library.

20:40 amalloy: from what i hear, vim's text-objects are pretty cool and useful, and we emacsers just don't get it. i mean, we can do most things anyway, via special-cased functions like forward-sexp, but it's a little condescending to say "dude paredit does everything" unless you really know what vim stuff mdeboard misses

20:45 justin_smith: lein question: is there a convenient way to run a one-off piece of code from the command line? the client has been using their own servers (including db), but I need to write code that fixes something on their end (as a one-off bit of clojure code that would fix up the db issues)

20:45 technomancy: amalloy: sure, iiuc the main difference is that emacs mashes together "forward" and "sexp" as a hard-coded defun while vim composes them gracefully.

20:45 justin_smith: lein run -m clojure.main -e "(stuff)"

20:45 mdeboard: tbh I don't use forward-sexp etc. in emacs, just C-<Space> set-mark-command (kinda like visual mode in vim)

20:45 justinholguin: justin_smith try the lein-exec plugin

20:45 justin_smith: technomancy: great, thanks, I'll just shove that in a shell script and have them run it

20:45 technomancy: amalloy: I wouldn't say paredit is better than text objects, just that emacs without paredit kinda sucks

20:46 amalloy: mdeboard: i take back everything good i ever said, you're a heathen

20:46 mdeboard: lol

20:46 Oh wait, yeah I do, I just didn't know the keybind I was using was called that

20:47 technomancy: may the ~guards have mercy on your soul

20:47 amalloy: i was gonna say, set-mark-command is terrible for general navigation

20:47 justin_smith: lazybot: fortune

20:47 lazybot: addfortune everywhere is within walking distance if you have the time

20:47 justin_smith: amalloy: it's great if you want to have a stack of locations in buffers kind of like pushd/popd in the shell

20:48 mdeboard: I use all the search varieties way more than navigatin

20:48 technomancy: amalloy: depends how you define "general". it's really useful in a lot of situations.

20:48 amalloy: i can't figure out how to maintain such a stack. i just use it as "what was i doing a minute ago? C-u C-SPC. no, not that...C-SPC, C-SPC...oh right, there i was"

20:48 justin_smith: https://www.gnu.org/software/emacs/manual/html_node/emacs/Mark-Ring.html

20:49 amalloy: ^^

20:49 you are doing it already, looks like :P

20:49 amalloy: yes, yes, i know about the mark ring. just using it effectively is hard

20:49 i rarely/never set mark myself on purpose

20:49 just as a side effect of selecting text or using navigation commands

20:50 nullptr: usually in cases where you want an explicit "mark" it's better to set a point register

20:50 "C-x r SPC runs the command point-to-register"

20:50 "C-x r j runs the command jump-to-register"

20:52 turbofail: oh hm. i didn't know #(.foo ^TypeWad %) actually worked until just now

20:52 i seem to recall it not working in the past

20:53 mdeboard: amalloy: I'm not even sure why I said C-<Space>, the only time I ever use it is to copy paste or bulk delete

20:53 I guess I just wanted to fit in.

20:58 justin_smith: mdeboard: if you are selecting a form for pasting, try M-h

20:58 (for copying then pasting, of course)

20:58 mdeboard: That too, but not usually selecting the whole deal

20:58 But I also use M-x gist-region a *lot*

20:58 justin_smith: I use refheap-paste-region

20:59 amalloy: justin_smith: M-h? blech. i don't select whole defns nearly as often as i select subforms

20:59 mdeboard: Also I use emacs for a lot more than just clojure

21:01 technomancy: amalloy: spend some time doing forth, then you'll get better at stacks =)

21:04 mdeboard: Is that the programmer equivalent of "Go lift some weights then come talk to me"

21:04 justin_smith: bro do u evn lambda-lift?

21:05 technomancy: haha, probably

21:09 justin_smith: of course that already existed http://cdn.memegenerator.net/instances/500x/33992180.jpg

21:10 mdeboard: ha

22:09 yedi: anyone have exp with chord or sente?

22:09 tryna decide which to use for an upcoming project

22:59 justin_smith: how best to discover image files that are corrupted or invalid from clojure? attempt to make a BufferedImage and return false from a try / catch?

23:54 Jaood: clojure is hard ;)

23:54 * Jaood skips transients for now

23:54 arrdem: clojure is different, and largely pure

23:54 transients are not something you should try and learn until you need them.

23:55 Jaood: good!

23:55 cbp: just maps and functions all the way baby

23:56 Jaood: can you take out macros, datatypes, protocols and multimethods too? ;)

23:56 egghead: Jaood: those are super userful, but also not necessary to write decent clj apps

23:57 arrdem: protocols and multimethods are worth learning, defrecord/deftype are sorta worth it and macros are usually not the right tool for the job.

23:57 egghead: never use a macro where you could have used a function

23:58 arrdem: good multimethod example, https://github.com/clojure/algo.generic + https://github.com/arrdem/meajure

23:58 no I'm not biased at all :P

23:58 higherarchies are a weird language artifact that's largely disused. ignore it at your discression.

23:59 cbp: heh

23:59 Jaood: I would though macros would be the more useful of the four, to decrease redundacy

23:59 cbp: I wanna see an example of hierarchies use

23:59 arrdem: cbp: I would too :P

Logging service provided by n01se.net