#clojure log - Jul 26 2013

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

0:05 TimMc: ...which it does, right?

0:09 callen: TimMc: the whole point of bcrypt is to produce hashes from values such that the relationship cannot be precomputed.

0:10 TimMc: Are you saying that bcrypt(A) sometimes produces B and sometimes produces not-B?

0:11 callen: ...yes

0:11 mmarczyk: bcrypt uses a random salt which is included in the output

0:12 along with the work factor (how many iterations of an expensive procedure to use)

0:12 Raynes: bcrypt would be an amazing thing if it didn't, let me tell you.

0:12 mmarczyk: then to verify it extracts salt, work factor and the actual hashed password

0:13 the (plaintext, salt, work-factor) -> hashed output relationship is deterministic, of course

0:14 TimMc: Oh, sure.

0:14 alexgunnarson: Hey everyone! So… i'm looking to develop a write-once-deploy-anywhere Clojure app. I'm looking for a general direction to go in in terms of the platform. Clojure+JavaFx+Java+JVM, Clojure+Flex+Flash, ClojureScript+HTML+CSS… all of them are great but they have their own individual pros and cons. The JVM is fast and has amazing, mature, well-documented libraries. But, from what I've seen, it doesn't run on iOS or Android excep

0:14 with hacks (at least, not yet - waiting on Oracle there). Flash has great functionality and graphics, which Java only does moderately well by comparison, but Flash Player is proprietary and has terrible performance. And finally, HTML5 is supposed to be the future, but the spec's not even completed (2020, anyone?), it lacks key functionalities, it doesn't have uniform behavior across platforms and browsers, and it's not as

0:14 performance-geared as, for instance, the JVM. Thoughts?

0:14 callen: alexgunnarson: jesus dude.

0:14 alexgunnarson: :D

0:14 aka: ha

0:14 callen: alexgunnarson: just use Luminus.

0:16 alexgunnarson: callen: thanks for the suggestion. i'll look into that. what advantages does it have?

0:16 callen: alexgunnarson: I'm not here to play mixologist. If you want to make a web app with Clojure, just use Luminus.

0:16 advantages - uhmmm, it won't fuck you around and will force you to just make your app instead of jacking off to acronyms.

0:17 Raynes: lol

0:17 aka: that should be it's official motto

0:18 alexgunnarson: yeah post that on the homepage

0:18 callen: I think yog is too professional for that.

0:18 Raynes: alexgunnarson: What callen is trying to say is that you're spending far too much time trying to find the best thing ever when you'd likely be better served by just doing what you want to do.

0:19 alexgunnarson: Raynes: if i "just did what i wanted to do" i'd be stuck with actionscript and flash and my app would be dead at some point

0:19 Raynes: Then don't use flash.

0:19 callen: alexgunnarson: do you want to make a web app in clojure or not?

0:19 Raynes: Flash isn't even supported on iOS.

0:19 So I don't know how using flash would help you anyways if that's a goal.

0:20 alexgunnarson: Raynes: not in the browser but in AIR it is

0:20 Raynes: AIR isn't supported in Linux.

0:20 And is a piece of shit regardless.

0:20 callen: AIR is garbage.

0:20 Raynes: When it was supported, everyone hated it.

0:20 alexgunnarson: i know… anything that uses flash player is terrible

0:20 Raynes: Well, that's not what I was saying.

0:20 aka: alexgunnarson: it is literally impossible to write software that runs everywhere and perfoms ideally on all platforms

0:21 Raynes: I enjoy flash games from time to time.

0:21 callen: Raynes: tower defense yo.

0:21 alexgunnarson: me too!

0:21 Raynes: You're just overthinking thing.

0:21 callen: so can we get back to the Clojure?

0:21 futile: callen: hey callen im working on some ObjC right now

0:21 alexgunnarson: aka: the JVM comes close and hopefully oracle will push it onto mobile platforms but we're still holding our breath on that

0:21 callen: futile: I don't care.

0:21 alexgunnarson: hahaha

0:21 futile: callen: you told me to say so!

0:22 aka: how is oracle going to push it to iOS?

0:22 callen: no I didn't.

0:22 futile: in general, please don't talk to me unprompted.

0:22 futile: I don't like ignoring people, but I don't like *wanting* to /ignore them either.

0:22 alexgunnarson: aka: they almost did back in like february or something i can't remember the date

0:22 futile: callen: stop talking about yourself

0:22 callen: futile: I'm talking about you.

0:22 futile: you're doing it again

0:22 Raynes: We really need moderators in here.

0:22 alexgunnarson: aka: they announced that it would happen but they never really carried their plans out

0:23 callen: Raynes: 4rlz.

0:23 Raynes: callen is too hostile, futile is too dumb.

0:23 That combination is pretty deadly.

0:23 futile: ill fix it

0:23 callen: thank god

0:23 Raynes: Was it something I said? :\

0:23 alexgunnarson: yeah let's get some admin privileges in here

0:23 callen: problem is, he'll come back in 5 minutes then talk about how terrible of a person he is.

0:23 Raynes: he does like that like every other day, don't take it personally.

0:24 Raynes: callen: Suggestion though: ignore him. You don't have to /ignore him. It's easy: you don't respond to what he says.

0:24 I don't ignore anybody at all and I get by just fine.

0:24 callen: he takes over the channel too often

0:24 Raynes: And trust me, I hate people too.

0:24 callen: haha, fair enough :)

0:24 aka: alexgunnarson: how would they implement that? there is still going to be a disconnect from the native sdk

0:25 Raynes: Good news is that the language is popular enough now that this happens, callen.

0:25 High schoolish fights and such.

0:25 callen: there's always an impedance mismatch between a generic toolkit and native. It's inescapable.

0:25 alexgunnarson: aka: hold on let me get the article

0:25 callen: Raynes: we need local dictators/warlords/ircops to police though.

0:25 aka: anyways, alexgunnarson, you want to build a mobile app or a web app?

0:25 Raynes: All three!

0:25 callen: Raynes: god willing.

0:26 Raynes: also, do you use Xmonad?

0:26 Raynes: callen: I was responding to aka, but sure. :p

0:26 alexgunnarson: http://java.dzone.com/articles/oracle-gets-java-running-ios

0:26 callen: oh, woops.

0:26 Raynes: callen: I use OS X.

0:26 I used xmonad ages ago when I still used linux.

0:26 alexgunnarson: "Oracle ADF Mobile uses a native container that runs applications on both iOS and Android from a single source base. One part of that native container is a headless/lightweight JVM."

0:26 callen: YourKit and jvisualvm don't seem to work with xmonad.

0:26 This...deeply upsets me.

0:26 poggio: I'm using xmonad right now

0:26 callen: alexgunnarson: that doesn't change what I said.

0:26 alexgunnarson: the impedance mismatch is in your code.

0:26 alexgunnarson: not in the tools you're using.

0:26 alexgunnarson: although i suppose the "headless/lightweight JVM" might not support clojure…

0:27 callen: you have a point

0:27 callen: alexgunnarson: at best you could IFDEF and write specific platform code for each

0:27 alexgunnarson: but then you're back to the days of C and C++

0:27 alexgunnarson: which would be terrible

0:27 callen: alexgunnarson: there is no "one platform to rule them all, and in the darkness bind them"

0:27 alexgunnarson: well okay for specific tasks

0:27 callen: well, it produced nice user experiences, even if it wasn't easy to work with as a developer.

0:27 alexgunnarson: which makes me sad, because i always loved LOTR :D

0:27 callen: alexgunnarson: why don't you tell us what you want to do?

0:27 Raynes: I booted into windows to play DmC: Devil May Cry callen. Why is this channel more entertaining than that game?

0:27 alexgunnarson: callen: very true

0:28 callen: Raynes: because I'm here, knocking heads.

0:28 Raynes: why are you playing the bastard child DMC game?

0:28 Raynes: I've played all the others and not this one...

0:28 alexgunnarson: callen: i want to basically make a clojure OS that runs on the JVM

0:29 Raynes: o_o

0:29 callen: alexgunnarson: no.

0:29 alexgunnarson: haha

0:29 Raynes: If you want to invent an operating system, you probably shouldn't worry about interoperablity with... operating systems.

0:29 callen: probably shouldn't use a language that requires a VM host *and* an OS host.

0:29 alexgunnarson: well it's a virtual OS

0:30 Raynes: So it's emacs?

0:30 ~rimshot

0:30 clojurebot: Badum, *tish*

0:30 callen: Raynes isn't kidding though. lisp OS in a bucket.

0:30 samrat: callen: I think `export _JAVA_AWT_WM_NONREPARENTING=1` before running jvisualvm fixes it.

0:30 alexgunnarson: hmm. true. emacs haha

0:30 callen: samrat: I'll have to try that with yourkit as well. Thank you!

0:31 poggio: you may want to check this out as well, I needed to add it to my xmonad.hs http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-SetWMName.html

0:33 ToBeReplaced: emacs hackers in terminal mode -- do you just use C-<right> and ilk for paredit instead of C-) ?

0:36 karvus: I do, but only because I'm in terminal mode seldom enough that I don't care enough to come up with a reasonable, alternative scheme.

0:40 ToBeReplaced: thanks

1:09 alexgunnarson: it seems like everyone's dead…

1:09 hey so how about concurrent, functional UIs? anyone seen this?: http://augustl.com/blog/2013/truly_concurrent_user_interfaces/

1:10 it's a project called concui

1:13 vilonis: I'm having trouble finding standard library documentation for clojure (even a list of all the modules), anyone know of a good source?

1:14 noidi: vilonis, http://clojure.github.io/clojure/

1:15 vilonis: ah, I wasn't sure if that was it

1:16 noidi: you can find usage examples etc. on http://clojuredocs.org/

1:16 brehaut: out of date examples

1:16 clojuredocs.org is only current up to 1.3; 1.5.x the latest release

1:19 noidi: I don't think there have been many backwards-incompatible changes

1:19 it may be missing stuff but I doubt that many of the examples are wrong

1:21 futile: is callen gone yet?

1:21 i love the clojure community, including the irc community. they're all such nice people.

1:22 zRecursive: sure

1:22 Clojure makes interested in Java again

1:22 makes me

1:23 futile: *you're all

1:23 thats why im shocked callen hasnt been banned by now

1:26 SegFaultAX: I just got +b from #python for talking about dependency injection. :/

1:26 I knew they hated Java but shit.

1:27 Just explaining what it is to someone is enough to get +b

1:28 futile: SegFaultAX: that cant possibly be why

1:29 SegFaultAX: theres nothing wrong with that as a concept, its perfectly legit and useful

1:30 SegFaultAX: futile: Read the scrollback.

1:30 futile: SegFaultAX: the dependency injection part?

1:30 noidi: you're pretty much doing dependency injection when you work with higher-order functions :P

1:31 futile: heh

1:31 never thought of it that way

1:31 not sure its right

1:31 noidi: me neither :)

1:32 SegFaultAX: futile: You'll see that right before I was +b, I was suggesting reading Martin Fowler.

1:32 noidi: I think there are some parallels with dependency injection if you're calling e.g. merge-with or sorted-map-by

1:33 mthvedt: as an enterprise java refugee, let me say a major reason for DI is composable execution contexts

1:33 futile: SegFaultAX: heh

1:33 mthvedt: this is huge when you have 1 million lines of bad java code expected to run in 50 places

1:34 with each module being a moving part

1:34 SegFaultAX: mthvedt: That and being able to swap out components for eg testing.

1:34 dpathakj: does anyone know an easy way to inspect a Clojure function's enclosing scope at runtime? e.g. suppose I do (defn incrementer [n] (fn [i] (+ i n))). is there a way to take (incrementer 5) and no other arguments, and return 5?

1:34 SegFaultAX: Integration testing without DI in Java is extremely painful.

1:34 futile: yea

1:34 in ruby too

1:34 SegFaultAX: futile: Well in Ruby you can literally modify anything at runtime

1:35 Including the root objects that dominate the entire object tree.

1:35 futile: thats what makes it so painful

1:35 mischov: Has anybody else been having problems with Carmine not wanting to let a macro be build around wcar as shown in the github docs?

1:35 SegFaultAX: Kernel, Module, Object, BasicObject, etc.

1:35 futile: yeah

1:35 you can just delete Kernel iirc

1:35 that was fun

1:35 SegFaultAX: I don't think you can undef Kernel, but maybe.

1:35 dpathakj: (besides the obvious (- ((incrementer 5) 0) 0)… i'm wondering more about a reflection-type solution.

1:37 the closest thing i've found is clojure.repl/source, but that doesn't do what i'm thinking of.

1:37 futile: SegFaultAX: i remember using python before ruby and thinking how dumb it was that i could modify my own classes but not String or Object.

1:37 SegFaultAX: You mean str or object I assume.

1:37 futile: yep

1:37 been too long

1:40 mthvedt: segfaultax: right, but that's a subset of setting up execution contexts.

1:40 SegFaultAX: mthvedt: I suppose that's true. Good point.

1:41 mthvedt: if/when big companies start writing millions of lines of bad clojure code, i wager clojure DI will become a lot more popular

1:42 noidi: ,(require 'clojure.reflect)

1:42 clojurebot: nil

1:42 SegFaultAX: mthvedt: stuartsierra's blog post about his workflow is basically DI.

1:42 noidi: ,(reflect (let [foo 10] (fn [] foo)))

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

1:42 noidi: ,(clojure.reflect/reflect (let [foo 10] (fn [] foo)))

1:42 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: sandbox$eval84$fn__85>

1:43 noidi: dpathakj, oh well, for me that returns a map containing #clojure.reflect.Field{:name foo, :type long, :declaring-class user$eval171$fn__172, :flags #{}

1:43 SegFaultAX: noidi: I think it's disabled by clojail.

1:44 noidi: dpathakj, presumably you can then use something like https://github.com/arohner/clj-wallhack to get the field's value

1:46 futile: ,(let [list [:foo :bar "baz" :quux :yay], [a [b & c]] (split-with (complement string?) list)] [a b c])

1:46 clojurebot: [(:foo :bar) "baz" (:quux :yay)]

1:47 dpathakj: noidi: cool. could be interesting. thanks.

1:51 (luckily I don't have a specific use case other than the toy problem I mentioned; this is more a matter of exploration…)

1:56 zRecursive: ,(Math/sqrt 10000000000)

1:56 clojurebot: 100000.0

2:09 futile: ,(into {} (zipmap [1 2 3] [:a :b :c]))

2:09 clojurebot: {3 :c, 2 :b, 1 :a}

2:12 SegFaultAX: futile: Why?

2:12 futile: what SegFaultAX?

2:12 SegFaultAX: ,(zipmap [1 2 3] [:a :b :c])

2:12 clojurebot: {3 :c, 2 :b, 1 :a}

2:24 futile: SegFaultAX: cuz i wanted to make a map from keys/vals

2:24 ,(map identity [1 2 3] [:a :b :c])

2:24 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$identity>

2:24 futile: ,(map vector [1 2 3] '[a b c])

2:24 clojurebot: ([1 a] [2 b] [3 c])

2:26 futile: ,(map #(hash-map :a %1 :b %2) [1 2 3] '[a b c])

2:26 clojurebot: ({:a 1, :b a} {:a 2, :b b} {:a 3, :b c})

2:26 futile: is there a nicer way of doing that?

2:26 ,(map #(hash-map :a %1 :b %2) [1 2 3] '[4 5 6])

2:26 clojurebot: ({:a 1, :b 4} {:a 2, :b 5} {:a 3, :b 6})

2:35 cespare|home: When I start lein repl, it says it started nREPL on some port but it doesn't create target/. Isn't it supposed to?

2:35 (nobody is responding on #leiningen)

2:35 callen: SegFaultAX: best reason to get banned I've ever heard.

2:39 futile: cespare|home: i dont think target/ has anything to do with the port nrepl connects on.

2:39 i think target is just a temporary place to put compiled files

2:39 cespare|home: How does e.g. vim-fireplace know what port to listen on?

2:40 by what I'm reading it looks for target/repl-port

2:53 SegFaultAX: cespare|home: What port to listen on?

2:54 cespare|home: Fireplace connects to nrepl.

2:55 Raynes: SegFaultAX: Yes. Over a port.

2:55 Which it has to get from leiningen.

2:55 And cannot get from Leiningen magically.

2:55 It requires a file, just like cespare|home said.

2:55 cespare|home: In any case, you can make it connect by using :Connect nrepl://localhost:<port> (it will autocomplete the first parts if you hit tab a couple of times).

2:56 SegFaultAX: Raynes: Does fireplace open a port? Maybe I misunderstood.

2:57 Raynes: SegFaultAX: If there is no port file, it gives up and creates a repl itself and then everything you evaluate takes 10 seconds to evaluate.

2:58 SegFaultAX: Raynes: Orly?

2:58 Raynes: It's better to connect to a running lein repl instance, which it can do if there is a port file there or if you use :Connect.

2:58 No, I'm just kidding.

2:58 * Raynes throws shit off his desk and storms away.

2:58 SegFaultAX: Heh

2:58 I didn't know that.

2:58 Thanks for the clarification.

2:59 I've never actually had fireplace spin up its own repl. I've /always/ connected to an already running one.

2:59 Raynes: If you go to a project that doesn't have a repl running and do cqc, it'll work.

3:01 SegFaultAX: Raynes: Does it spin up a new one everytime you evaluate something or does it persist across the rest of your session?

3:01 futile: (inc clojure)

3:01 lazybot: ⇒ 14

3:01 futile: only 14?

3:01 $karma clojure

3:01 lazybot: clojure has karma 14.

3:01 futile: $karma amalloy

3:01 lazybot: amalloy has karma 67.

3:02 futile: thats not right.

3:02 Raynes: SegFaultAX: I thought it persisted across your session, but given that it takes about a month to evaluate anything I expect I'm wrong.

3:02 (identity futile)

3:02 lazybot: futile has karma 2.

3:02 futile: ,(dotimes [i 10] (inc clojure))

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

3:02 futile: aww

3:02 zRecursive: (identity zRecursive)

3:02 lazybot: zRecursive has karma 0.

3:02 SegFaultAX: futile: Wrong bot.

3:02 Raynes: And it isn't actual code anyways.

3:02 It's just parsing it to be clever.

3:02 futile: ,(dotimes [i 10] (println "(inc clojure)"))

3:02 clojurebot: (inc clojure)\n(inc clojure)\n(inc clojure)\n(inc clojure)\n(inc clojure)\n(inc clojure)\n(inc clojure)\n(inc clojure)\n(inc clojure)\n(inc clojure)\n

3:03 Raynes: That wouldn't work either.

3:03 futile: didnt help.

3:03 Raynes: lazybot ignores clojurebot.

3:03 futile: awwww

3:03 zRecursive: :-D

3:03 karma 0

3:03 futile: (+ clojure 1000) ;; just make this work plz Raynes

3:03 noidi: ,(list? '(1 2 3))

3:03 clojurebot: true

3:03 noidi: ,(list? `(1 2 3))

3:03 clojurebot: false

3:04 futile: ,(seq? '(1 2 3))

3:04 clojurebot: true

3:04 futile: ,(seq? `(1 2 3))

3:04 clojurebot: true

3:04 futile: neat

3:04 noidi: that bug took me quite a while to find...

3:04 SegFaultAX: ,`(1 2 3)

3:04 clojurebot: (1 2 3)

3:04 futile: noidi: ow

3:04 noidi: ,(class `(1 2 3))

3:04 clojurebot: clojure.lang.Cons

3:04 futile: hmm, 2am. not good.

3:05 zRecursive: ,(def song (ref #{}))

3:05 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

3:05 Raynes: &`(1 2 3)

3:05 lazybot: ⇒ (1 2 3)

3:05 futile: &(inc clojure)

3:05 lazybot: java.lang.RuntimeException: Unable to resolve symbol: clojure in this context

3:05 futile: &(inc 'clojure)

3:05 lazybot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number

3:05 futile: :D

3:05 Raynes: That's interesting.

3:05 futile: &'(inc clojure)

3:05 lazybot: ⇒ (inc clojure)

3:05 Raynes: &(type `(1 2 3))

3:05 lazybot: ⇒ clojure.lang.Cons

3:05 futile: Raynes: yeah, make it a built-in function.

3:06 Raynes: &(type '(1 2 3))

3:06 lazybot: ⇒ clojure.lang.PersistentList

3:06 zRecursive: ,(eval &'(inc clojure))

3:06 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

3:06 Raynes: I guess that'd do it, noidi.

3:07 futile: ,((juxt type class) `(1 2 3))

3:07 clojurebot: [clojure.lang.Cons clojure.lang.Cons]

3:07 futile: ,(= type class)

3:07 clojurebot: false

3:07 futile: oh

3:07 zRecursive: ,(type type)

3:07 clojurebot: clojure.core$type

3:08 zRecursive: ,(type class)

3:08 clojurebot: clojure.core$class

3:08 futile: ,(doc type)

3:08 clojurebot: "([x]); Returns the :type metadata of x, or its Class if none"

3:08 futile: ,(doc class)

3:08 clojurebot: "([x]); Returns the Class of x"

3:08 Raynes: You guys can get a repl by typing 'lein repl', by the way.

3:08 futile: ah

3:08 but we're experisharilearning

3:08 Raynes: Look at all the people leaving because of you.

3:09 zRecursive: Raynes: can we message bot ?

3:09 Raynes: (leave guys, they need to think you're bothering them)

3:09 See!

3:09 zRecursive: Yes.

3:09 futile: (:O

3:09 callen: zRecursive: no, the bot broke IRC

3:09 zRecursive: Raynes: which bots to use ?

3:09 callen: zRecursive: the bot is a magical special case of IRC

3:09 Raynes: Either bots to use.

3:10 zRecursive: lazybot and clojurebot is same ?

3:10 futile: bedtime

3:10 Raynes: Not the same.

3:10 They're completely different bots.

3:10 zRecursive: then message to who ?

3:11 Raynes: Either oen.

3:11 one*

3:11 zRecursive: why not one bot as lambdabot in #haskell ?

3:13 callen: zRecursive: 'murica.

3:13 Raynes: Because it's entirely legal to write IRC bots and some people enjoy doing it.

3:13 This isn't a democracy, we don't vote for bot president.

3:13 SegFaultAX: I for one... blah blah overlords.

3:14 zRecursive: see

3:14 metellus: a bot election

3:14 Raynes: lazybot supports abortion.

3:14 metellus: that would be.

3:14 Raynes: Just a heads up.

3:14 callen: Raynes: post-natal abortion of people that abuse bots in public channels?

3:15 Raynes: ~rimshot

3:15 clojurebot: Badum, *tish*

3:47 cespare|home: Is there a way to get the repl to automatically reload my project code when the file changes?

3:47 (I'm using lein repl if that matters)

3:49 AtKaaZ: hi, was there a function that would return true if all items in collection would satisfy some passed function? ie. testfor(fun, [1,2,3,4]) where fun would test for equality let's say so if 1==2 then 2==3 then 3==4 then return true, else false; or something like that

3:49 SegFaultAX: ,(every? even? [2 4 6])

3:49 clojurebot: true

3:50 AtKaaZ: does it work for equals?

3:50 like 2==4==6 ?

3:50 Chousuke: you can apply =

3:50 ,(apply = [1 1 1])

3:50 clojurebot: true

3:50 AtKaaZ: oh yes that makes sense

3:50 so it's like (= 1 1 1)

3:51 SegFaultAX: AtKaaZ: Yes.

3:51 AtKaaZ: but suppose you don't have = that can take more than 2 params

3:51 Chousuke: you can reduce

3:51 AtKaaZ: so you can only do (= 1 1) or (fun 1 1)

3:51 SegFaultAX: ,(every? #(= 1 %) [1 2 3])

3:51 clojurebot: false

3:51 SegFaultAX: ,(every? #(= 1 %) [1 1 1])

3:51 clojurebot: true

3:51 Chousuke: though reduce won't be lazy

3:52 AtKaaZ: ok but I want that 1 inside the function to be the first element from the list

3:52 ie. not hardcoded

3:52 ok more like fun should take two params

3:52 SegFaultAX: AtKaaZ: What are you implementing? RLE?

3:52 Chousuke: AtKaaZ: just take it from the list then :P

3:52 AtKaaZ: (something? #(= %1 %2) [1 1 1])

3:52 no, I am just trying to remember the name of a clojure function which already does this

3:53 hyPiRion: ,(let [[f & r] [1 2 3]] (every? #{f} r))

3:53 clojurebot: false

3:53 AtKaaZ: (cause i think there's one?)

3:53 SegFaultAX: AtKaaZ: Checking if every element = the first element is the same as applying =

3:53 AtKaaZ: wasn't there some justone function though?

3:54 SegFaultAX: you may be right, but I think I worded it wrongly

3:54 SegFaultAX: AtKaaZ: Tell us what you really want, then.

3:54 AtKaaZ: what I want is something like this (something? #(= %1 %2) [1 1 1]) where %1 and %2 is previous and next(or current) element

3:54 from that list

3:55 like comparing elements I think

3:55 SegFaultAX: How is that different from apply =. You're just doing it pair-wise.

3:55 amalloy: &(partition 2 1 [1 2 3])

3:55 lazybot: ⇒ ((1 2) (2 3))

3:55 amalloy: SegFaultAX: he's asking for functions in general, not = in particular

3:56 SegFaultAX: He specifically asked for equals.

3:56 AtKaaZ: ,(sort #(> %1 %2) [1 3 2 9 -1])

3:56 clojurebot: (9 3 2 1 -1)

3:56 hyPiRion: ,(->> [1 2 3 4] (partition 2 1) (every? (fn [[a b]] (== (inc a) b))))

3:56 clojurebot: true

3:56 amalloy: equals was the example he gave

3:56 AtKaaZ: grr I think it's sort lol

3:56 SegFaultAX: ,(sort-by > [1 2 3 4])

3:56 clojurebot: (1 2 3 4)

3:56 SegFaultAX: ,(sort-by < [1 2 3 4])

3:56 clojurebot: (1 2 3 4)

3:56 AtKaaZ: yes that one, thanks guys! sorry for my poor expressive skills

3:56 SegFaultAX: What am I doing, haha.

3:57 hyPiRion: wat

3:57 SegFaultAX: AtKaaZ: You were looking for sort-by?

3:57 hyPiRion: sort is not taking the previous and next(or current) element

3:57 AtKaaZ: for sort I think, why did your sort-by give the same results?

3:58 oh ?

3:58 wait actually it's not sort, because it returns a list xD

3:58 and i want it to return true or false depending on what function returns when taking elements by 2

3:58 hyPiRion: ,(sort-by :foo > [{:foo 1} {:foo 2} {:foo -5}])

3:58 clojurebot: ({:foo 2} {:foo 1} {:foo -5})

3:59 hyPiRion: when taking elements by 2 -> elaborate

3:59 AtKaaZ: (somefn? #(> %1 %2) [1 2 3 4 5]) returns true but (somefn? #(> %1 %2) [1 2 3 5 4 6 7]) returns false

3:59 SegFaultAX: ,(sort-by identity > (range 10))

3:59 clojurebot: (9 8 7 6 5 ...)

3:59 SegFaultAX: I forgot keyfn was first that's all.

3:59 cespare|home: AtKaaZ: hyPiRion already gave you your answer

4:00 AtKaaZ: cespare|home, where? I missed it

4:00 cespare|home: you can use partition to get the pairs of two, and then use every?

4:00 hyPiRion: ,(->> [1 2 3 4] (partition 2 1) (every? (fn [[a b]] (== (inc a) b))))

4:00 clojurebot: true

4:00 AtKaaZ: ah, but wasn't there just one function?

4:00 hyPiRion: ^

4:00 SegFaultAX: AtKaaZ: Wrap it in a defn and it will be.

4:00 hyPiRion: just one function?

4:00 AtKaaZ: I mean, some idiomatic function that does it

4:00 SegFaultAX: AtKaaZ: Do you mean something in clojure.core?

4:01 AtKaaZ: (somefn? #(= %1 %2) [1 2 3 4 5]) returns false; and (somefn? #(= %1 %2) [1 1 1 1 1]) returns true;

4:01 amalloy: AtKaaZ: there is no single pre-built function that does the six things you are asking for

4:01 AtKaaZ: somefn? aka one function :)

4:01 amalloy: you will have to build one

4:01 AtKaaZ: lol

4:01 cespare|home: AtKaaZ: you can do it with a complicated reduce, i think.

4:02 SegFaultAX: AtKaaZ: You keep using =, but is your actual use case just for general functions?

4:02 AtKaaZ: yes SegFaultAX

4:03 SegFaultAX: AtKaaZ: Then you have your answer.

4:03 AtKaaZ: ok thank you :(

4:03 hyPiRion: AtKaaZ: you can spin it off in another way

4:04 cespare|home: ,(reduce = (map #(apply = %) (partition 2 1 [1 2 3 4])))

4:04 clojurebot: false

4:04 cespare|home: AtKaaZ: ^^ another way.

4:04 hyPiRion: ,(let [foo [1 2 3 4]] (->> (map #(= %1 (inc %2)) foo (rest foo)) (every? true?)))

4:04 clojurebot: false

4:05 AtKaaZ: :) but still I failed to find that one function, so either I am remembering wrongly(likely the case but sad) or I am unable to find that one function

4:05 SegFaultAX: If it's acceptable to process the entire list maybe.

4:05 AtKaaZ: What difference does it make? Why does it need to be from clojure.core?

4:06 amalloy: cespare|home: what on earth is that function supposed to do?

4:06 AtKaaZ: SegFaultAX: it's because i wanted to know the name of that function xD to see if other langs have it

4:06 cespare|home: amalloy: which function?

4:06 oh oops.

4:06 amalloy: the one you just offered. it seems to return true if either all the elements are the same or they are all pairwise different

4:07 AtKaaZ: amalloy: assert thatfun(testfn, a,b,c,d,e) where thatfun applies testfn to a and b then to b and c etc...

4:07 so my use case was for = but still

4:07 cespare|home: ,(every? true? (map #(apply = %) (partition 2 1 [1 1 1 2])))

4:07 clojurebot: false

4:08 cespare|home: amalloy: ^^ is what I meant

4:08 SegFaultAX: Your use case is for =... we answered that 10 minutes ago.

4:08 amalloy: cespare|home: but like hyPiRion and SegFaultAX have already said, that's just a bad way to write (apply = [1 1 1 2]))

4:08 cespare|home: is there an easier way to do (every? true? ...)?

4:08 AtKaaZ: SegFaultAX, was it with apply = ?

4:08 cespare|home: SegFaultAX: false, you can put any other function instead of =

4:08 hyPiRion: cespare|home: reduce =

4:09 cespare|home: hyPiRion: not the same

4:09 hyPiRion: cespare|home: reduce = true

4:09 ,(reduce = true [false])

4:09 clojurebot: false

4:09 hyPiRion: ,(reduce = true [])

4:09 clojurebot: true

4:09 cespare|home: ok, that's more characters though

4:09 hyPiRion: it's obviously not easier though

4:10 SegFaultAX: ,(reduce = true [false false])

4:10 clojurebot: true

4:10 SegFaultAX: So no.

4:10 cespare|home: ruby has all?, i was hoping for the same.

4:10 SegFaultAX: ,(reduce = true [true false false])

4:10 clojurebot: true

4:10 SegFaultAX: ^ that was amalloy's point

4:11 hyPiRion: yeah, bugger.

4:11 SegFaultAX: cespare|home: That's what every? is, but more general.

4:11 hyPiRion: apply = true it is then

4:11 SegFaultAX: cespare|home: You could do (every? identity ...) and that's the same.

4:12 cespare|home: To match ruby's impl, we don't care that they all equal exactly true... only true in a boolean context ("truthy")

4:13 Which for clj is anything other than nil and false.

4:13 AtKaaZ: ,(and true true false)

4:13 clojurebot: false

4:13 cespare|home: SegFaultAX: right, it would be convenient if, if you didn't specify a pred, it used a default check for truthiness

4:14 haha, 'and' would indeed do that heh.

4:14 hyPiRion: convenient sure, but it wouldn't increase your productivity by some factor.

4:14 SegFaultAX: cespare|home: Doubtful. How often are you really checking if every item is not nil or false?

4:14 cespare|home: uh, in the context where it just came up?

4:14 where I know each item is true or false?

4:14 SegFaultAX: cespare|home: But AtKaaZ's case is after applying a predicate function :)

4:15 AtKaaZ: yeah, I remember it could take a function

4:15 SegFaultAX: cespare|home: So why have (every? (map pred L))?

4:15 hyPiRion: (every? true? ...) is more evident than (every? ...) though.

4:15 AtKaaZ: and it would apply it to each element, however I don't remember if it would need an extra element to apply it to first one like (fn 0 firstelem)

4:15 SegFaultAX: hyPiRion: If you only care about /actually true/, right.

4:16 cespare|home: SegFaultAX: ah this is true.

4:16 SegFaultAX: cespare|home: (every? pred L) is clearly cleaner and more general.

4:16 hyPiRion: SegFaultAX: Sure. And if not, do (not-any? #{nil false} ...) instead

4:17 SegFaultAX: cespare|home: In ruby, you most often apply all? with a block anyway.

4:17 [1,2,3].all? { |e| e % 2 == 0 }

4:17 hyPiRion: (every? even? [1 2 3])

4:18 see, you're using pred the same way really

4:18 AtKaaZ: maybe it was like this: (thefn pred 0 [1,2,3,4,5]) and it would apply (pred 0 1) and if true continues, apply (pred 1 2) ... so on until false then return false

4:18 SegFaultAX: hyPiRion: Exactly.

4:18 cespare|home: SegFaultAX: yes i saw your point, which is why i agreed with you.

4:19 SegFaultAX: Ruby's iterator protocol is pretty neat. Implement 1 method (#each) and you can mixin Enumerable to get a bunch of stuff for free.

4:20 cespare|home: lol, took me forever. Does this work then? (defn atkaaz [f s] (every? #(apply f %) (partition 2 1 s)))

4:20 (atkaaz = [1 1 1 1]) -> true

4:20 (this is literally my first day writing clojure btw)

4:20 AtKaaZ: cool then, seems to do the job :)

4:20 (I don't really know clojure though, as if that's not obvious haha)

4:20 SegFaultAX: You could have a second clause that takes n, the size of the slice to use.

4:21 cespare|home: (atkaaz < [1 2 3 4]) -> true

4:21 AtKaaZ: SegFaultAX, i'm glad i found functional ruby aka elixir :)

4:22 SegFaultAX: ,((fn atkaaz ([f s] (atkaaz 2 f s)) ([n f s] (every? #(apply f %) (partition n 1 s)))) = [1 1 1 1])

4:22 clojurebot: true

4:22 SegFaultAX: ,((fn atkaaz ([f s] (atkaaz 2 f s)) ([n f s] (every? #(apply f %) (partition n 1 s)))) 3 = [1 1 1 1])

4:22 clojurebot: true

4:22 SegFaultAX: Not a good test case, but yea.

4:23 AtKaaZ: almost hurts my head trying to understand it lol

4:31 almost like map-indexed except it doesn't pass the index but the previous element heh

4:32 almost like reduce... hmm maybe I remember reduce wrongly

4:49 oh man, I really think I remembered reduce wrongly(maybe also combined it with every? in my head and saw it as 1 function), and that's the one function that I thought did what I expected, sad so sad but must accept it: I was wrong

4:57 Guest__: how do i put the contents of a vector into a map? i use (into {} (partition 2 [1 2 3 4])).

4:58 what am i doing wrong here?

4:58 thanks. :)

5:00 hyPiRion: ,(conj {} '(1 2)) ; no work

5:00 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry>

5:00 hyPiRion: ,(conj {} [1 2]) ; works

5:00 clojurebot: {1 2}

5:00 hyPiRion: But even better, use ##(apply hash-map [1 2 3 4])

5:00 lazybot: ⇒ {1 2, 3 4}

5:00 Guest__: hyPiRion thanks!

5:03 ucb: beat me to it

5:04 :)

5:41 ddellacosta: is there a way to ensure I'm using the === operator in ClojureScript?

5:42 ah, from looking at source, looks like I use "=="

7:05 mmarczyk: ddellacosta: identical? actually

7:06 ddellacosta: unless dealing with numbers, in which case it's indeed ==

7:07 ddellacosta: mmarczyk: thanks!

7:07 mmarczyk: np

9:12 stuartsierra: An experiment: clojure.walk reimplemented with protocols https://github.com/stuartsierra/clojure.walk2

10:02 dsapala: Does anyone here know why I might get "Entity used in relationship does not exist" in Korma when I "defentity" in a function? I'm doing a "declare" before the function to make sure they're "def"'d.

10:05 I'm trying to use Stuart Sierra's approach to clojure workflow (http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded) and this is the only thing I haven't been able to overcome yet.

11:01 futile: what's the point of interning clojure symbols if it always creates a new one?

11:02 gfredericks: ,(identical? (symbol "foo") (symbol "foo"))

11:02 clojurebot: false

11:03 gfredericks: futile: you might be referring to a different thing?

11:03 futile: possibly the same thing

11:03 gfredericks: what interning are you talking about?

11:03 futile: gfredericks: https://groups.google.com/forum/#!topic/clojure/crmUDnGIVCg

11:04 ,(Symbol/intern. "foo")

11:04 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: Symbol, compiling:(NO_SOURCE_PATH:0:0)>

11:04 futile: ,(clojure.lang.Symbol/intern. "foo")

11:04 clojurebot: #<CompilerException java.lang.IllegalArgumentException: No matching method: intern., compiling:(NO_SOURCE_PATH:0:0)>

11:04 futile: ,(clojure.lang.Symbol/intern "foo")

11:04 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

11:04 futile: that one

11:05 gfredericks: futile: I don't know for sure but I think the point here is to avoid duplicating the String objects

11:05 futile: ok

11:05 gfredericks: symbols themselves can't be interned simply (like keywords can) because of metadata

11:05 futile: oh right

11:06 gfredericks: or conversely, keywords can't have metadata so that they can be interned simply :)

11:29 futile: $mail brehaut btw hopefully this gets rid of the confusion: https://github.com/sdegutis/zephyros

11:29 lazybot: Message saved.

12:03 mbarbieri: hi, midje question: I have a data structure (map with keywords as keys and lists of lists as values) and I want to test some functions I wrote to get values from it, but I don't want to use the actual structure, because it could change.

12:04 if this is my data: (def mydata {:blah [[1 2 3] [4 5 6]]} I thought I could substitute it with a test version of it, using (let [mydata my-test-date] …tests…) but it doesn't work

12:06 futile: mbarbieri: I've been solving that issue by considering the data structure opaque, and writing functions that return everything I need to know about it, in a way that's not determined by the original data structure.

12:06 mbarbieri: if the data structures have to change, then only those functions that access it have to change, nothing else in my program does, since those functions will always return the data in the same structure

12:07 asteve: does anyone have examples on parsing dates?

12:08 I'd like to take a string in the format YYYYmmdd and create a java.util.Date object from it

12:08 I'm not sure if that's the clojure way

12:08 futile: ,(.parse (SimpleDatFormat. "yyyy") "1985")

12:08 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: SimpleDatFormat, compiling:(NO_SOURCE_PATH:0:0)>

12:09 futile: ,(.parse (java.text.SimpleDateFormat. "yyyy") "1985")

12:09 clojurebot: #inst "1985-01-01T00:00:00.000-00:00"

12:09 futile: re asteve

12:09 mbarbieri: futile: it's what I'm doing, I had this data structure, and now it changed, so I'm trying to write some function to access it and keep the data structure opaque, my question was about testing it with midje

12:10 futile: mbarbieri: well it doesnt matter what lib you use to test it, you'd do it the same way: have functions that create this opaque data structure for you, rather than creating it yourself.

12:10 mbarbieri: in fact id argue midje encourages the bad practice of re-binding functions to return data structures you created in the test, which you shouldnt do anyway

12:11 it just causes fragility problems

12:12 mbarbieri: futile: ok now I get it: have functions that create the data structure. Noted. Thanks!

12:13 futile: mbarbieri: yeah, let the data structure be *entirely* encapsulated in your src/ file, dont let test/ files know anything about it

12:19 mbarbieri: futile: *entirely* is a dynamically binded var right? :)

12:20 futile: #<Unbound Unbound: #'mbarbieri/*entirely*>

12:31 g06|in: why doesn't this work -- (.printf System/out "!") ?

12:36 ToxicFrog: g06|in: interesting. System/out is a java.io.PrintStream, which has two printf methods, printf(Locale, String, Object...) and printf(String, Object...)

12:36 gfredericks: having java varargs means you need to pass an array

12:36 ToxicFrog: Something like (.printf System/out "!" nil) works

12:36 Aah

12:36 gfredericks: (.printf System/out "!" (into-array []))

12:36 also works

12:36 g06|in: thanks!

12:36 gfredericks: g06|in: note clojure.core/format

12:36 in case that's what you really want

12:38 scgilardi: or clojure.core/printf

12:38 gfredericks: oh right

12:38 of course :)

12:38 g06|in: thanks!!

12:46 redderhs: Hi, the link in this message is in regards to an Open Source Computing to further the developments of hardware for the mobile industry. It's time for Linux to be the #1 Consumer Operating System, Ubuntu Edge movement! http://pastebin.com/j57Dc29E We can all make a difference for as little as One Dollar! Thank You for your time.

12:56 aka: there are commercials in this channel?

12:56 gfredericks: not welcomed, no

12:59 aka: :)

13:09 wink: damn ubuntu zealots

13:35 callen: what a bastard.

13:50 futile: just wrote a book proposal and realized i already own a book that has exactly the same chapters, and i just never opened it before.

13:51 callen: futile: do you have a facebook or twitter account?

13:54 seangrove: Uhg, NPE when running cljsbuild test. Incredibly frustrating

13:57 wei_: poll: which clojurescript data binding library do you use? cljs-binding, purnam, something else?

13:58 futile: callen: no

13:58 callen: why?

13:58 seangrove: wei_: Please update us on the poll results when they're in ;)

13:59 callen: futile: it's a good outlet for random thoughts like that

13:59 futile: you should try 'em.

13:59 futile: callen: oh. didnt realize i was doing irc wrong.

13:59 it was about Clojure, does that make it relevant?

14:00 callen: futile: try to think in terms of the utility others might derive from it.

14:00 futile: you couldn't tell you were talking about Clojure, or what book you were talking about

14:00 wei_: seangrove: will do, if there's enough responses!

14:00 callen: futile: you speak for your own benefit and it's obvious.

14:00 futile: callen: oh i see.

14:01 you're just a prick. a total prick.

14:01 well i think maybe we'd be better off if you were banned.

14:01 callen: you make this channel horrible to be in.

14:01 or rather, you're horrible to be around.

14:01 justin_smith: look who's talking

14:02 callen: I'll get some gauze and ointment for that burn. back in a flash.

14:02 (inc justin_smith)

14:02 lazybot: ⇒ 4

14:13 ToBeReplaced: will mapply or something like it make its way into clojure core?

14:15 bbloom: ToBeReplaced: monad apply?

14:15 ToBeReplaced: i don't foresee any kind of monad stuff making it into core any time soon

14:15 ToBeReplaced: ,mapply?

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

14:15 bbloom: even if it was of interest, it's always best to assume core won't change fast enough for your needs

14:15 ToBeReplaced: hm...i thought there was a clojurebot thing for mapply

14:16 bbloom: ~mapply

14:16 clojurebot: You could (defn mapply [f & args] (apply f (apply concat (butlast args) (last args))))

14:16 bbloom: ooooh that kind of mapply

14:16 pgr0ss: does anyone know how to test a compojure app that uses cemerick/friend? i can't find a way to setup a fake session that bypasses the authentication

14:18 ToBeReplaced: bbloom: yeah i seem to use it a fair amount

14:18 pgr0ss: i tried grabbing the value of :session from a real requst, and then assoc'ing it (request :post "/url_behind_auth" :session saved-session) but friend still seems to think the request is unauthenticated

14:19 bbloom: ToBeReplaced: i haven't felt the need, or maybe i just think about it differently. curious: what do you use it for?

14:19 justin_smith: pgr0ss: what about conditionally bypassing the friend code by wrapping the handler in a conditional?

14:20 something like (if (= (System/getProperty "debug") "true") (handler request) (handler (friend request)))

14:21 ToBeReplaced: optional keyword arguments -- i was about to open source a lib to connect clojure.java.jdbc specs to c3p0, and realized i would prefer to use it there

14:21 ie (pool db :max-statements 10), or (pool db)

14:22 pgr0ss: justin_smith: I suppose I could, but then I can't test that some routes require auth, some don't

14:22 justin_smith: also, what about code that relies on the current logged in user?

14:22 justin_smith: pgr0ss: yeah, that would be an issue, I don't know enough about friend to know how to best handle that

14:22 bbloom: ToBeReplaced: ah. i try to avoid optional keyword arguments like that or provide an alternative "plumbing" function that takes a normal map

14:23 justin_smith: pgr0ss though you could manufacture a request map that is sure to be denied if auth is required, and succeed otherwise

14:23 ToBeReplaced: bbloom: my default is to expose the unrolled version, and use the collected version internally

14:23 justin_smith: pgr0ss: and similarly, you could manufacture a map with the user data when you bypass friend

14:23 bbloom: ToBeReplaced: hm, yeah those sorts of optional kw args seem to only really be useful for "porcelain" commands that will be used at the repl

14:23 but even then, i tend to prefer maps

14:23 pgr0ss: justin_smith: yeah, that's what i'm trying to do - i can't seem to get a request map that satisfies friend authentication

14:24 justin_smith: pgr0ss: this is how I unit test web apps with session / auth at least

14:24 that is why I suggested optionally turning the auth off

14:24 ToBeReplaced: bbloom: you would rather pack up connection pool options? my reason for not is that typically you wouldn't be calling this with a configuration from somewhere else

14:25 ToxicFrog: bbloom: why (apply concat (butlast args) (last args)) rather than (apply concat args)?

14:25 justin_smith: ie. manufacture the session friend would return for testing code needing user in session, and then verify that friend doesn't let you in when not bypassing it on the right routes, that covers the two cases you mentioned

14:25 bbloom: ToxicFrog: i find that the map versions are much easier to work with and don't mind the extra two chars in general :-)

14:25 not the least of which, is the need for something like that mapply function

14:26 ToxicFrog: bbloom: not the question I'm asking.

14:26 pgr0ss: justin_smith: got it; yeah, maybe i'll go down this route if i can't seem to figure out how to test with friend dirctly

14:26 bbloom: ToxicFrog: (last args) is assumed to be a map

14:26 ToxicFrog: Aah

14:26 bbloom: sorry, that previous message was for ToBeReplaced

14:27 justin_smith: pgr0ss: the way I generally test controllers is to mock up the request as it hits the controller

14:27 since my controllers are less stable than my request handler (generally)

14:27 ToBeReplaced: ToxicFrog: the last argument is assumed to be a map, so concat flattens it out

14:28 justin_smith: and then I test each handler fn in isolation, if it tests well, it should compose properly

14:28 ToxicFrog: bbloom: so the result basically ends up as [arg1 arg2 .. argn [k1 v1] [k2 v2] [k3 v3]]

14:28 ?

14:28 bbloom: ToxicFrog: the idea is to call a function like (f arg1 arg2 :kwarg1 1 :kwarg 2) like this: (mapply f arg1 arg2 {:kwarg1 :kwarg 2})

14:29 er, only with a correctly typed map: {:kwarg1 1 :kwarg2 2}

14:29 * ToxicFrog nods

14:30 ToBeReplaced: bbloom: i'm wondering whether if map were available, the unrolled version would be more widely used

14:30 *mapply

14:31 Raynes: Which Haskell web framework is trying the least to be rails?

14:31 ToBeReplaced: it's in the library coding standards, and is practical i think

14:32 Raynes: That sounds like something totally non confrontational to put on twitter!

14:32 hexa: Hi all , I'm been juggling around a little problem , say I want to create a map based on multiple functions returning keys and taking the same argument list ... would using comp and having the result be like [result-map argument-list] be a good idea or I'm missing a simpler way... ? (I'm building multiple parts of web page)

14:33 troydl: Howdy, quick question if I may: Is there a function to spit out a range of letters the way (range 0 5) works for numbers?

14:33 bbloom: ToxicFrog: *shrug*

14:33 Raynes: <smug>sounds like you want a monad, hexa</smug?

14:33 justin_smith: hexa: juxt?

14:33 ToxicFrog: bbloom: ?

14:33 Raynes: >

14:33 hexa: juxt is probably what you want, but it's hard to tell unless we saw what the code takes and returns for real.

14:33 bbloom: ToxicFrog: dunno if it would see more use or what the best decision is. i was just curious about your need for it. thanks for explaining

14:34 justin_smith: hexa: if the functions should all receive the same args, and you don't want laziness, juxt is a perfect match

14:34 ToxicFrog: bbloom: what need for it? I'm confused

14:34 hexa: Looks like this : https://www.refheap.com/16937

14:34 checking juxt :)

14:34 bbloom: ToxicFrog: gah, sorry

14:34 ToBeReplaced: that was for you again ^^

14:34 ToxicFrog: you're a victim of my two-characters-then-tab expansion strategy that my fingers have memorized

14:35 ToxicFrog: troydl: (->> (range (int \a) (int \z)) (map char)) ?

14:35 hexa: Right juxt is it thx!

14:35 justin_smith: hexa: in that code, should test-map1 and test-map2 see the same args or different?

14:35 if they should see the same args, yeah juxt

14:35 Raynes: bbloom: Whenever Raynos talks after me, people start exploding into flames because their clients usually prefer tab completion for whoever talked last.

14:35 ToxicFrog: ,(->> (range (int \a) (int \k)) (map char))

14:35 clojurebot: (\a \b \c \d \e ...)

14:36 Raynes: It's quite entertaining.

14:36 hexa: justin_smith, same args

14:36 bbloom: Raynes: damn irc clients need fuzzy completion or CamelHumpsOrSomething

14:36 Raynes: snaplets make no sense.

14:36 bgilbert: troydl: I've used this before: (def all-chars

14:36 (map char (range 97 123)))

14:37 ,(take 10 (map char (range 97 123)))

14:37 clojurebot: (\a \b \c \d \e ...)

14:37 justin_smith: ,(char 96) ; is jealous to not be considered a char

14:37 clojurebot: \`

14:38 troydl: Thanks guys. Neocons didn't like dealing with numbers as keywords. I ended up doing (map keyword (repeatedly 3 gensym)) which seems to have worked out.

14:38 antares_: troydl: Neo4j does not like dealing with numbers as keywords, so does Neocons

14:38 troydl: Right

14:40 justin_smith: neocons huh, someone should make a sbcl backend for clojure and call it newleft (sbcl - steel - stalin getitlol)

14:40 Raynes: callen: Oh callen, look at you hiding in the twitters.

14:41 troydl: justin_smith: Lol, yeah the name neocons makes for some interesting google results when I have problems

14:41 callen: Raynes: Scotty.

14:41 Raynes: callen: Have you played with snap at all?

14:41 * justin_smith starts working on his rails-killer webapp project, 2gic

14:41 justin_smith: *2g1c

14:41 that is

14:42 Raynes: callen: Is it just me, or do snaplets sound absolutely batshit bloody insane. It's like "Hey, don't use libraries, write this weird ass special thing for our web framework cuz cool!"

14:42 callen: Raynes: it's a combinatorial framework

14:42 Raynes: I avoided it like the plague.

14:42 Raynes: It's like the antithesis of all things that are good in functional languages.

14:42 callen: beyond using some lower level tooling

14:42 Raynes: I mean, you're describing a lot of Haskell in general.


14:42 Raynes: I just don't get why it's all so terrible.

14:43 Yesod is a monstrous nuclear disaster zone with the worst dependency tree I've ever seen and so many template Haskell hacks that I'm not sure the language still qualifies as Haskell when you write it.

14:43 callen: That's why Yesod gets its own book.

14:43 not for making web apps, just for explaining/apologizing for Yesod.

14:44 Raynes: I feel mean for saying all this, but goodness.

14:44 callen: Raynes: I don't think Haskellers have ever had a notion of making a thing that does things.

14:44 justin_smith: I dunno if the amount of haskell discussion on this channel should make me glad we are keeping up with the joneses or make me jealously wonder if they are talking about clojure on #haskell

14:44 callen: at least the Scala people get work done in-between hacking on scalaz and making periodic table of operator libraries.

14:45 Raynes: callen: And now I'm sad because the homepage for Scotty is a .edu page.

14:45 * Raynes sighs

14:45 callen: Raynes: it's the best way to make a web app in Haskell I've found. Sorry :)

14:45 justin_smith: they don't talk about Clojure in #haskell because they're too busy ENDOFUNCTOR MONOID HILBERT SPACE

14:45 Raynes: I wonder if anyone has written actual websites in snap or yesod. Like. ones humans can look and interact with.

14:46 justin_smith: I think there are mathematical jargon spaces that are compact enough that a markov chain could hold its own for a while

14:46 callen: Raynes: lots of Haskeller blogs.

14:46 Raynes: also I just checked the FPComplete Yesod tutorial

14:47 the *first* line of the *first* example is the following: {-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings #-}

14:47 ^^ lol.

14:47 Raynes: lol

14:47 callen: second line? import Yesod

14:47 Raynes: callen: Also, the reason I was looking at this stuff is because I want to do a website with a friend, but he doesn't really want to do it in Clojure but we both want to do it in something reasonably interesting and Haskell seemed like a reasonable option at first since we're both kinda into it.

14:48 callen: Raynes: do it in Elixir.

14:48 Raynes: But, I feel like my apartment will slowly sink into a basement and all light will be seeped out of my life if I try to do this in Haskell.

14:48 callen: Raynes: Elixir+Dynamo

14:48 practical, fun, interesting.

14:48 (Dynamo in this case refers to the elixir cowboy wrapper, not the data store)

14:48 Raynes: I can't really do anything in Elixir because of… I guess OCD issues related to how terrible Erlang ports are and how nobody cares enough to fix them.

14:49 Which to be fair includes me because I do not intend to dig into the Erlang C code.

14:49 ToxicFrog: Raynes: do it in Scala~

14:49 callen: Raynes: Chicago Boss is Elixir compatible and doesn't require digging around in too much Erlang.

14:49 Raynes: He already does Scala.

14:49 callen: Raynes: I really think you're not giving Elixir and Chicago Boss a fair shake here.

14:49 Adeon: I know someone who made his blog in sed

14:49 Raynes: callen: Because if I decide I need to shell out then I'm screwed and that bothers me.

14:50 I can't really get over it.

14:50 If Erlang ports stop sucking, I'll be a big Elixir guy again.

14:50 callen: Raynes: that bad? ow.

14:50 I know ports suck, but damn.

14:50 Raynes: Racket? Common Lisp?

14:51 Raynes: I can't talk to something on stdin, close it, and then read from stdout. When I mentioned this in #erlang, I got responded with "Well, I don't know of any languages that can do that." to which I o_o'd out and explained very politely how that was incorrect.

14:51 ToxicFrog: wait what

14:52 callen: Raynes: OCaml?

14:52 Raynes: Racket isn't a terrible idea.

14:52 I mean, this particular project won't require any shelling out (at least, not that I can foresee) so Elixir would be a fine option.

14:53 callen, ToxicFrog: https://www.refheap.com/13920 I wrote this ages ago and showed it to Erlangers and they were like RETWEET RETWEET OMG but shit, no way I'm messing with this C insanity to fix it.

14:53 :p

14:53 callen: Raynes: Common Lisp + Clack + Caveman is cool.

14:55 Racket doesn't have a very serious/good web stack though

14:55 CL's is more mature

14:56 Raynes: callen: https://github.com/mattsta/erlang-stdinout-pool This is the result of the Erlang port issues.

14:56 * Raynes shudders

14:56 callen: this is why I just write Clojure and thereby not suffer unnecessary problems.

14:56 I'd still really like the ability to produce self-contained binaries that start and die quickly

14:57 Raynes: callen: I never actually figured out how to report this as an actual issue to Erlang though.

14:57 They have like 12 different mailing lists for issues and 'proposals' and all this nonsense.

14:57 callen: Raynes: they're a political hive in emulation of their VM process model.

14:57 Raynes: callen: I asked in #erlang what the best way to report the bug would be, they said to not bother unless I'm going to fix it as well.

14:57 callen: LOL

14:58 Raynes: At which point I gave up entirely and just started complaining to everyone who would listen instead.

15:03 callen: Raynes: these sorts of problems are also why Python is still my default glue language, to my eternal chagrin.

15:03 Raynes: Heck, I might write the site in Python just for shits and giggles.

15:03 At least you can actually do things with it. *shrug*.

15:04 callen: Raynes: if you write in Python then I could probably answer any questions off the top of my head limitlessly.

15:05 Raynes: not to mention being able to recommend some pimp-ass libraries.

15:05 seangrove: monocle

15:05 Very dapper o_

15:05 callen: seangrove: no.

15:06 seangrove: I've been thinking about monocle compared to core.async a bit recently

15:06 callen: async in Python is dumb.

15:07 Twisted is the purest form of Pythonic evil I've ever seen.

15:07 seangrove: callen: Async in every language seems to be pretty unpleasant overall

15:07 And yes, twisted is an amazing achievement

15:07 callen: "amazing"

15:07 seangrove: Probably should have put amazing in quotes, yes

15:07 callen: seangrove: not really.

15:08 http-kit is quite pleasant.

15:08 lacks thread affinity, otherwise quite nice.

15:08 seangrove: Hrm, I used the http-kit client in a small test project, really didn't care for it

15:08 Consuming twitter's streaming api with it was unpleasant

15:09 callen: I've not had occasion to use the client, I've only used it server-side.

15:09 and for that, it's very nice.

15:09 seangrove: But I haven't thought hard enough if that's fixable through a bit of client design, or if it's a language-level issue

15:09 It looks very solid though

15:12 callen: async has been done well before

15:13 seangrove: Where? Really curious to see different approaches to make it easier to reason about

15:13 Ahk, but I have ot catch the bus

15:13 Will ask again in a bit

15:17 futile: anyone have experience with HTTP 30? codes?

15:18 callen: I gotta say, 30 is a new one for me.

15:19 when did they start doing 2-digit HTTP status codes?

15:19 bbloom: sounds like somebody fat-fingered a 301 or 203

15:19 er 302, i'm apparently number dyslexic

15:19 futile: and i thought 30* would not be so clear as 30?

15:19 bbloom: and/or have fat fingers

15:19 futile: ffs

15:20 upwardindex: Is this the idiomatic way to get an element deep inside maps: (reduce get {:a {:b {:c {:d 4}}}} [:a :b :c :d]) ?

15:20 bbloom: upwardindex: get-in

15:20 futile: upwardindex: get-in

15:20 upwardindex: Thank you both!

15:21 ystael: I'm clearly missing something fundamental about dynamic vars; can someone explain? https://www.refheap.com/16938

15:21 bbloom: ystael: they interact badly with laziness

15:21 change map to mapv

15:21 or (doall (map ...))

15:21 ystael: *facepalm* of course. thank you very much!

15:21 i had completely forgotten about that part

15:22 ztellman: I'm not sure "of course" is the right reaction to that

15:22 yedi_: callen: you google "user authentification in clojure" and friend comes up

15:22 but you're right, i should roll my own

15:23 ystael: ztellman: in the sense of "i'm pretty sure i saw a post last month where somebody else ran into this, but i forgot" :)

15:24 ztellman: ystael: fair enough, but no one will ever convince me that's an intuitive interaction between clojure primitives

15:25 ystael: ztellman: the evidence proves there can be no argument from me :D

15:26 gfredericks: ztellman: is this a "clojure should be different" objection or a "it's hard to write a useful language that isn't complicated" lament?

15:27 ztellman: gfredericks: I suppose lazy-seqs could close over the thread-local context on creation, but that would cause a host of other problems

15:27 so the latter, I guess

15:28 gfredericks: k just curious :)

15:28 muhoo_: here's a stupid exception-handling question: is there any less ugly way than this to print the INPUTS to a function if a postcondition fails? https://www.refheap.com/16939

15:28 gfredericks: I don't actually know of any problems with the former approach, unless perf is an issue

15:28 muhoo: i tried dire, it doesn't seem to have any way to showwhat args exactly broke the thing.

15:29 ztellman: gfredericks: it lets thread-local data escape the local context

15:29 can cause resource leaks of all kinds

15:29 muhoo: also {:post [()]} just throws an exception, doesn't tell me what exactly was the incorrect args going in to the function

15:29 gfredericks: ztellman: oh I guess that could be weird

15:30 muhoo: for debugging I normally do an alter-var-root

15:30 muhoo: easy to make general helpers that use that approach

15:30 rather than changing a function itself

15:30 muhoo: gfredericks: any examples out there of that technique?

15:31 gfredericks: (alter-var-root #'foo (fn [f] (fn [& args] (or (apply f args) (throw (ex-info "" {:poop! args}))))))

15:32 muhoo: thanks. actually i'm pretty sure dire use alter-var-root under the hood.

15:33 i'm hoping to put stuff in place for production to make the exceptions more helpful.

15:33 gfredericks: I've been noodling the idea of logging helpers that let you declaratively add interesting logging in an aspect-oriented style

15:33 muhoo: an exception that doesn't show what args caused the error is pretty useless to me. i'm dealing with massive amounts of unpredictable data inputs; anything can break things and i'm playing whack-a-mole

15:34 callen: muhoo: this is pretty standard enterprise style logging

15:34 PuercoPop: is there something like * from the cl repl in clojure?

15:34 callen: fn + args + exception, sometimes with full trace.

15:37 muhoo: gfredericks: well thanks, the above is a lot cleaner than the (if-let [res (stuff)] res (throw ...)) approach

15:37 `cbp: PuercoPop: *1, *2, *3

15:39 callen: gfredericks: I've been considering the same thing!

15:39 defn-traced, defn-logged, etc

15:41 gfredericks: callen: oh mine would be alter-var-root style helpers to put after the functions

15:41 and combined with a logging lib that uses data rather than strings

15:41 muhoo: dire is pretty awesome. it seems an alter-var-root that prints the input args if the postcondition fails would be a good addition to it

15:42 i've used the erlang-style "supervise" functions of dire with good results

15:42 PuercoPop: `cbp: thanks

15:42 callen: gfredericks: sounds solid.

15:44 PuercoPop: is there a way to do partial aplication in a way I bind the second and third params but not the first?

15:46 llasram: PuercoPop: Just use an anonymous function: #(some-function % arg1 arg2)

15:46 PuercoPop: thanks

15:48 ivan: &(((fn [f y z] #(f % y z)) - 5 6) 13)

15:48 lazybot: ⇒ 2

16:00 tbaldridge: llasram: but...but...I want all my code to be point free!

16:00 ivan: and running on a point-free CPU

16:01 bbloom: tbaldridge: looking at the state monad inside core.async, i couldn't help but think "oh man, this would be awesome for some concatenative action"

16:02 tbaldridge: interesting...I've had a passing intrest in Forth in the past. How would this be done in a concatenative language?

16:02 bbloom: a "state monad" in a concatenative programming are just functions which take a state from the stack & then leave it modified back on the stack when done

16:03 give it a try with https://github.com/brandonbloom/factjor :-)

16:03 somethingg like (cat/run {:the "state"} (foo 1) (bar 2 3))

16:03 where foo and bar have stack effects [state x -- state*] and [state x y -- state*]

16:05 i discovered that variadic functions don't make for clean interop, sadly. i've been toying with the idea of a version of clojure core which defines all arity overload as syntax rules over fixed arity functions. but you'd also need multi-valued returns

16:06 https://github.com/brandonbloom/domscript/blob/master/src/domscript/cat.clj

16:06 tbaldridge: ^^ that's a good example of the "jquery monad" basically

16:08 but in the case of your state monad, you have essentially stacks of bindings, which you can implement as dynamic variables

16:09 factor calls them "namespaces": http://docs.factorcode.org/content/article-namespaces.html

16:09 unfortunately, factor's primary data structures are all mutable, so you can't really do speculative execution, but that's not an inherent limitation

16:12 tbaldridge: bbloom: the one problem I see is that a language like this assumes that that your execution model is...well..stack based. Sometimes I need to create a block reference it in every other operation

16:13 bbloom: tbaldridge: you can mix and match

16:13 tbaldridge: bbloom: It seems like you'd end up with something like coding JVM bytecode by hand. Simple ops, almost impossible to understand for more complex code.

16:13 bbloom: Factor is sorta "extremist programming" to see how far they can push the idea

16:13 but the answer is "surprisingly far"

16:14 tbaldridge: factor supports lexical variables with full closure semantics: http://docs.factorcode.org/content/article-locals-examples.html

16:14 so you can do whatever you need to do in the style that is most appropriate

16:15 personally, i think the applicative style is a better default, but that doesn't mean the concatenative style isn't super useful

16:15 basically every time you reach for ->, you're programming concatenatively in a very limited way

16:15 tbaldridge: agreed.

16:16 bbloom: tbaldridge: while i've got you here. SSA questions....

16:17 tbaldridge: yes

16:17 bbloom: i know that core.async's SSA is very limited to it's particular use case

16:17 but would it make sense to do an SSA -> JVM or JS backend?

16:17 or are the lambda-calculus-ish clojure primitives a better match for the underlying hosts?

16:19 tbaldridge: No, I'd prefer to target JVM bytecode. It was simpler the way I implemented it, but targeting bytecode would give you access to the JVM jump bytecodes which would (most likely) dramatically improve performance in some cases

16:20 bbloom: sorry, No to which question?

16:20 tbaldridge: as it stands, the blocks are put into a big switch statement, so doing state transitions means you have to bounce out of the switch and back in to the next block. With bytecodes you could just jump right to the target location.

16:20 are sexprs better....no

16:20 they're simpler that's all.

16:20 bbloom: ok, that's what i thought

16:21 i'm wondering if it would make sense to define a dynamically typed SSA language that had good backends for JVM ByteCode & JavaScript

16:21 ie so that more of the compiler front ends can be recycled

16:22 tbaldridge: I've been thinking about that as well. I'd like to see that happen at some point, but it's a fair amount of work.

16:24 bbloom: oh yeah, big project for sure

16:24 tbaldridge: I was hoping the GSOC CinC project would do something like this but they seem to be going down the route of writing yet another Clojure analyzer.

16:24 bbloom: :-/

16:26 i tried to find if anybody was doing SSA->JS & i saw some mention of Dart, but i couldn't find that in the codebase

16:26 since i figured SSA->JVM was a no brainer

16:26 but i realized that you're doing SSA back to CLJ, which is probably close enough to SSA->CLJ

16:26 er i mean close enough to SSA->JS

16:28 tbaldridge: a few days ago I implemented a CLJ->SSA->Cython "translator". It was a fun experiment, but the output was so different from "normal" python that it actually ran slower than interpreted bytecode

16:28 bbloom: heh cool

16:39 futile: hey so has anyone figured out how to get rid of clojure's s-exps?

16:40 justin_smith: why would you want to?

16:40 futile: i think the only thing left to solve is how to disambiguate between a value or a fn call with no args

16:40 bbloom: we have a solution to that… they are called parenthesis…

16:40 gfredericks: this comes up every few months

16:40 futile: i know, im reading old threads, thats how i found this topic

16:40 gfredericks: there was even an april fools language devoted to it

16:41 the name of which escapes me

16:41 justin_smith: oh, yeah, I almost chuckled out loud at that one

16:41 mthvedt: gfredericks: squarejure?

16:41 futile: i dont care for it myself, i like parens. im just wondering if theres any news on its progress

16:41 mthvedt: no, that's wrong

16:41 gfredericks: oh nevermind

16:41 that was about swapping square brackets and parens

16:41 mthvedt: clochure

16:42 gfredericks: futile: I don't think anybody expects progress

16:42 any "solution" you come up with is bound to be much more complicated and problematic than whatever "problems" are associated with the normal syntax

16:42 malyn: https://github.com/one-more-minute/clarity (although I don't actually want to use that :)

16:42 callen: Raynes: http://www.stephendiehl.com/posts/haskell_web.html

16:42 Raynes: I saw that.

16:42 callen: damn

16:42 Raynes: Made me want to punch a kitten.

16:43 callen: Raynes: "javascript code generation" KITTY_SCARED.JPG


16:43 callen: Raynes: "disk-backed key-value store that only works in Haskell"

16:43 Derander: I was incredibly amused by that intro example

16:44 gfredericks: malyn: hah is that just a macro that uses :column metadata?

16:44 Derander: my first thought: "wtf is forM_"

16:44 Raynes: I know what forM_ is. Still think it's all silly.

16:45 arrdem: malyn: wat no

16:45 malyn: gfredericks: Not sure how it works. At first it sounded interesting, but any non-trivial example started making me uncomfortable.

16:45 ("interesting" in a theoretical sense)

16:46 gfredericks: I wonder how it handle double-open-parens

16:47 Raynes: callen: I've been contemplating offering money for the first person to submit a pull request to fix the port issues I've had.

16:47 It'd be a fun social experiment.

16:47 submit and get accepted, of course.

16:48 callen: Raynes: gittip is neat, but I'd still really like to see a github-aware bounty system.

16:48 or just a bounty system in general that actually works and lets people pitch in if they want it to happen too.

16:50 Raynes: is there such a thing? An escrow/bounty system for OSS?

16:50 Raynes: I saw something recently.

16:51 callen: http://coderbounty.com/ here is one thing.

16:52 callen: Raynes: looks so horrendously ghetto.

16:52 ToBeReplaced: just in case anyone is interested -- created two mini libraries i've had to use in lots of places: https://github.com/ToBeReplaced/jdbc-pool https://github.com/ToBeReplaced/mapply

16:53 callen: ToBeReplaced: ...you are aware of bonecp right?

16:53 futile: ToBeReplaced: ive heard bone cp is better

16:53 Raynes: callen: What's amusing is that it wants you to link to a github issue but oh look you can't open issues on otp, only pull requests.

16:53 callen: Raynes: I was thinking of something more generic.

16:54 Raynes: callen: Because apparently you aren't supposed to send issues without patches or some shit.

16:54 futile: ~mapply

16:54 clojurebot: You could (defn mapply [f & args] (apply f (apply concat (butlast args) (last args))))

16:54 ToBeReplaced: i've heard yeah -- just not currently used in my work environment

16:55 maybe should have named it jdbc-c3p0-pool ... probably would have been better... should have asked first

16:55 callen: ToBeReplaced: well there are existing c3p0 libs for clojure too :P

16:55 futile: oh, mapply is neat

16:56 although i think a better solution is just write fns that take an optional map at the end

16:56 ToBeReplaced: the pooling we use internally is all down-and-dirty, so i'm not one to understand diff between either lib

16:56 callen: links? quick google didn't show

16:57 i also didn't want to do anything other than provide a thin wrapper for easy setup into a org.clojure/java.jdbc specification

16:58 Derander: ~mapply

16:58 clojurebot: You could (defn mapply [f & args] (apply f (apply concat (butlast args) (last args))))

16:58 ToBeReplaced: futile: i think it depends -- use cases for both for sure

16:58 futile: ToBeReplaced: i like that answer a lot

16:58 its not the fanboyish all-or-nothing approach of some idiots.

16:58 :)

17:04 callen: not duplicating effort is valuable and reduces clojars noise.

17:10 ToBeReplaced: callen: what is that in reference to?

17:12 callen: I don't think it needs a prompt.

17:13 bbloom: callen: do you have a twitter account?

17:14 callen: bbloom: I feel like this is a setup for something.

17:14 bbloom: I do.

17:14 bbloom: callen: not a few hours ago you were giving futile shit for saying something without context. now you're doing it.

17:14 justin_smith: I swear #clojure is turning into an epistolary novel with all the subtle intregues and indirect insults

17:15 callen: bbloom: it was in reference to the conversation about the connection pooling libraries.

17:15 bbloom: I said it didn't need a prompt, I didn't say it didn't have one.

17:15 bbloom: there are more valid reasons to harangue me than this. Find them and then raise cane with me.

17:15 rattboi: raise cain

17:16 futile: hey guys

17:16 remember how we all love Clojure?

17:16 lets agree that Clojure is pretty great, yeah?

17:16 rattboi: Clojure is awesome

17:16 futile: (inc rattboi)

17:16 lazybot: ⇒ 1

17:16 callen: rattboi: so it is, thank you.

17:16 (inc rattboi)

17:16 lazybot: ⇒ 2

17:16 futile: is it pronounced Closure or Clo-jure?

17:17 callen: futile: Clozhure

17:17 but quickly, you don't rest on the zh

17:17 in french it'd be a dj

17:17 futile: do you emphasise the U or the O?

17:17 callen: errrr, j

17:17 derp.

17:18 futile: it's pretty close to the pronunciation of closure, if not identical for the most part. It's just that it's specifically zh sound whereas I've heard some brits pronounce closure differently.

17:18 rattboi: I emphasize the O

17:18 futile: also, why does the Clojure wikipedia article have an example that does defn inside a let? that seems wrong

17:18 rattboi: ive just been saying Closure.

17:19 Okasu: futile: Wikipedia seems mostly wrong, do not rely on it too much.

17:19 futile: Okasu: but surely *we* can fix the Clojure page up?

17:19 callen: futile: last time we tried to use Wikipedia, they deleted Hickey's page.

17:19 I think we're scurred now.

17:20 futile: uhh

17:20 justin_smith: def[u]n inside let is a standard common lisp idiom for mutable private data, it happens to work in clojure, but not be standard clojure style

17:20 futile: heh http://en.wikipedia.org/wiki/Rich_Hickey

17:20 justin_smith: we should change it to look more idiomatic.

17:20 the examples there.

17:20 not that im qualified to do it..

17:22 ok, we were on the topic of pronouncing Clojure, and 2 Seans just joined. is it too off topic to ask why Sean is pronounced Shawn?

17:22 callen: futile: irish name.

17:23 futile: oh

17:23 callen: originally from "John"

17:23 the sound went from "John" to "zhawn" to "shawn"

17:23 Okasu: Yawn.

17:24 Extreme form John.

17:24 of*

17:24 futile: ok thx guys

17:26 Okasu: callen: Wow, you mean like when time passes clojure well go forl "Clojure" to "Clozha" to "Closhaw"?

17:26 s/well go forl/will go from/

17:28 gtrak: justin_smith: not only is it not idiomatic, it'll break with threads

17:28 justin_smith: yet it claims to be threadsafe

17:29 callen: Okasu: lol

17:29 gtrak: where?

17:29 clojurebot: where is forget where

17:30 Okasu: gtrak:

17:30 >A thread-safe generator

17:30 https://en.wikipedia.org/wiki/Clojure

17:30 gtrak: doh.. that is fine

17:30 sorry, I was thinking scheme's nested 'define'

17:31 justin_smith: gtrak: wait, I see an atom there, won't that be thread safe - or was that a recent edit?

17:31 heh, our conversation threads lost sync for a second there

17:32 gtrak: yea, I use defs within lets occasionally just to screw with my team

17:32 justin_smith: hey, sometimes you gotta keep secrets!

17:33 gtrak: sometimes you gotta understand when/how top-level things actually get evaluated ;-)

17:34 justin_smith: (let [fn-I-will-only-need-here (fn [..] ....)] (def do-foo (fn-I-will-only-need-here ...)) (def do-bar (fn-I-will-only-need-here ...)))

17:34 gtrak: so what is the pitfall with something like that?

17:35 I suspect it is probaly just some vestigal cl-based instinct being followed - but is it something that actually breaks things?

17:35 gtrak: oh, there isn't one.. just saying it's possible to get in trouble. it's just helpful to know it's closing over some variables during the static initializer of the namespace

17:35 justin_smith: oh, yeah, sure

17:35 gtrak: and also during compile-time

17:35 justin_smith: yeah, so you don't want any state modifications in the let bindings

17:36 gtrak: generally, you should move your state to the top of your app

17:36 so it's not bound to a namespace lifecycle, vars have the same problem.

17:36 in that case of the symbol generator it doesn't matter

17:36 futile: gtrak: thanks for sharing about Datomic

17:37 gtrak: do you like it?

17:37 futile: After reading about 5 documents and blog posts and stuff on it, I finally get it.

17:37 justin_smith: we did a big transformation not long ago - took all the state-atom-maps we had at the tops of our libs and moved them into config that is explicitly generated (so things could become re-entrant)

17:37 futile: I don't think it's that complicated, I think those documents just need to emphasize that attributes are free-floating and any entity can have any attribute.

17:38 justin_smith: then rather than setting an atom in the lib, you pass config into lib functions

17:38 futile: gtrak: I like it so far, but it feels a little daunting to setup at first. There's no built-in convenience functions for creating schemas, which makes them seem huge.

17:39 srsly, 6 lines per single attribute!

17:39 Raynes: callen: I'm working with Jose to see what we can do about that ports issue finally. I sent an email to the erlang-questions mailing list to see what reception it gets, and he is gonna try to bring it up to Joe Armstrong and see what he thinks/potentially get it added to the internal otp issue tracker and such. So hopefully we can get some progress made on that and my mental anguish can subside.

17:40 callen: Raynes: I'm surprised it flew under Joe's radar.

17:40 gtrak: justin_smith: yea, that makes testing much easier (tractable at all)

17:40 callen: Raynes: in the meantime, use Elixir!

17:40 Raynes: with Dynamo or Chicago Boss :D

17:40 futile: whoa, elixir looks crazy

17:41 Raynes: futile: It's crazy awesome. I wrote the URI library and original mix when it was still really early. Then I saw how bad Erlang ports were and got sad and ran away. Stayed friends with Jose though. He consults with me a lot about Clojure design choices because he likes Clojure and wants to do as much of what Clojure did right as he can, which is why I love Elixir so much.

17:42 futile: Raynes: oh neat

17:43 callen: Raynes: Jose is a very nice person.

17:43 he's probably the only nice Rails core dev.

17:43 Raynes: He holds a special place in my heart.

17:43 futile: oh man, is he into Rails 'magic' philosophy?

17:44 callen: I don't think so. He's definitely into having nice tools though.

17:44 Raynes: Well, he made Elixir.

17:44 So I don't think so.

17:44 noncom|2: hi, i have a (defn) in another namespace and i have an alias to that namespace (made by :as), how do i get that what is defined with (defn)?

17:45 smth like (ns-resolve 'that-another-ns-alias (symbol (name defn-name))) does not work...

17:45 says cant find that-another-ns-alias

17:45 justin_smith: noncom|2: (ns foo) (defn bar [] ...) (ns user) (require '[foo :as f]) (f/bar)

17:46 gtrak: noncom|2: (def the-new-var old-var-ns/old-var)

17:47 noncom|2: i have the defn-name unknown at compile-time, so i think that i have to formulate somehting like that require

17:47 gtrak: ah, I thought you wanted to make an alias to the function

17:47 noncom|2: like (require '[foo :as (symbol (name user-defined-name))])

17:48 gtrak: yeah, but that is dynamic, so i'm knoking my head at the wall now :)

17:48 gtrak: what is dynamic, the old one?

17:48 noncom|2: oh nono, i mean it is known only at compile-time

17:48 gtrak: not sure what you mean

17:48 what isn't known at run-time in clojure?

17:49 noncom|2: a user passes a keyword or a string, and i have to resolve that as a binding in another namespace (which is also specifield at runtime)

17:49 but they are specified in different places

17:49 namespace first

17:49 gtrak: ah, you want ns-resolve with aliases?

17:50 noncom|2: yeah, i tried, but did not work. i guess maybe the require thing will work?

17:51 gtrak: check it out: https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L3943

17:51 noncom|2: i mean, ns-resolve does not accept smth like (ns-resolve (symbol (name use-defined-ns-name)))

17:51 gtrak: you can build up the env parameter from your current namespace, I believe

17:51 noncom|2: i am fully unaware of what is env in clojure

17:52 i mean envirinemnet

17:52 oh my spelling/...

17:52 gtrak: user> (take 20 (ns-map *ns*)).....([sorted-map #'clojure.core/sorted-map] [read.......

17:52 you should be able to figure it out from there

17:52 noncom|2: ah that is

17:52 yeah, i will have to go to study things

17:53 this is basic, but i did not use it before

17:53 gtrak: the functions are here: http://clojure.org/namespaces

17:53 it's nice that it's all data, like a lot of clojure

17:54 noncom|2: not a word on envs though.. will have to dig up additional sources.

17:54 gtrak: ns-aliases?

17:54 it's probably fastest just to read the impl

17:54 noncom|2: yeah, about data - one day i found out that clojure namespaces are not maps!

17:54 yeah, i think i will do it

17:55 gtrak: it's not something people do a lot..

17:56 noncom|2: btw, knowing that clojure nss are not maps, terrifies me in some way...

17:56 :)

17:56 gtrak: objects are data too? ;-)

17:56 or can be viewed as such

17:57 noncom|2: hmmm.. all is data and all is code.. but not all is valid ahaha :)

17:57 yeah, that's like hebrew. all their data is code and vice-versa

17:58 gtrak: all this fuss to flip some bits on the screen

17:58 noncom|2: true and i won't even remember that in 1000 years after...

17:59 or no, i'll be sitting and rememberin, contemplating on it, specially..

17:59 :))

18:02 justin_smith: noncom|2: user> (require '[clojure.string :as s]) ;;; nil ;;; user> (resolve 's/join) ;;; #'clojure.string/join


18:02 something like that should work for what you want, yes?

18:03 using (comp resolve symbol) on whatever the user provides (if they are providing a string)

18:03 squidz: dnolen: is it possible to create source maps yet for clojurescript

18:03 justin_smith: ,((comp resolve symbol) "clojure.string/join")

18:03 clojurebot: #'clojure.string/join

18:04 noncom|2: so i will try now!

18:04 gtrak: clojures docs says 'same as (ns-resolve *ns* symbol)'

18:05 justin_smith: oh, ok

18:05 but does ns-resolve work with ns aliases in that way?

18:05 gtrak: *ns* isn't going to give you what you want at runtime

18:05 noncom|2: hmmmm

18:05 gtrak: yea, seems like ns-resolve will do it

18:06 but you should pass in a hardcoded ns symbol I guess

18:06 noncom|2: but hey! looks like it went just fine!

18:06 gtrak: call it from another namespace?

18:06 see how that goes

18:06 noncom|2: i have this now:

18:07 (let

18:07 [mk-grabber ((comp resolve symbol) (str "jcv/" (name grabber-type)))

18:07 ...

18:07 gtrak: if *ns* is a var.. then it's not going to work, I'm not sure if it is or not

18:07 noncom|2: and yes, it goes into that ns, takes that grabber-maker-fn, and later, in the (let), it passes arguments to that maker and the grabber creation is being attempted

18:08 ,(type *ns*)

18:08 clojurebot: clojure.lang.Namespace

18:08 noncom|2: oh

18:08 well, (resolve) is same as (ns-resolve *ns*)....

18:08 gtrak: ,(class #'*ns*)

18:08 clojurebot: clojure.lang.Var

18:08 noncom|2: oO

18:08 gtrak: it's for repl stuff

18:09 justin_smith: will ns-resolve work with aliased namespaces?

18:09 noncom|2: let me try

18:09 gtrak: meaning, it's not getting reset all the time when your code runs, only at the repl and read/eval time.

18:10 noncom|2: what you mean not getitng reset?

18:10 justin_smith: I have done (require '[clojure.string :as s]) - (resolve (symbol "s/join")) works, (ns-resolve 's 'join) does not

18:11 or am I using ns-resolve wrong?

18:11 noncom|2: ahaha

18:11 here:mk-grabber (ns-resolve (resolve 'jcv) (name grabber-type))

18:11 NullPointerException java.util.concurrent.ConcurrentHashMap.hash (:-1)

18:12 (resolve 'a)

18:12 ,(resolve 'a)

18:12 clojurebot: nil

18:12 squidz: stuartsierra: or do you maybe know?

18:12 stuartsierra: eh, what?

18:12 noncom|2: hmmm, creating a meaningful example for clojurebot takes thinking...

18:13 it's just that jcv is surely already aliased before it gets to that line

18:13 in my code.

18:13 ,(ns-aliases)

18:13 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$ns-aliases>

18:13 noncom|2: ,(ns-aliases *ns*)

18:14 clojurebot: {}

18:14 noncom|2: oO

18:14 squidz: stuartsierra: what the status is about sourcemaps with clojurescript

18:14 stuartsierra: squidz: no idea

18:14 gtrak: hope this illustrates the point: $ java -jar clojure-1.5.1.jar -e "(ns user2) (defn n [] *ns*) (ns user) (user2/n)" ... #'user2/n ... #<Namespace user>

18:15 noncom|2: squidz: a little off-topic: in my experience clojurescript debugs like heaven with standard browser console

18:15 gtrak: *ns* isn't where the function lives.

18:16 bbloom: squidz: seangrove is the guy most recently tooling around w/ source maps

18:16 noncom|2: gtrak: right, it's where it was called from, this is fine i guess?

18:16 gtrak: I thought you cared about aliases defined in your namespace?

18:17 not the namespace that the user is in

18:17 squidz: bbloom: oh okay, does he get on the channel?

18:17 noncom|2: ah, i see

18:17 i seee waht you meen

18:17 gtrak: cool :-)

18:17 bbloom: squidz: yeah, he's here relatively frequently

18:17 gtrak: was hard to explain :-)

18:17 noncom|2: sorry :))

18:18 i'll make a test now

18:18 seangrove: squidz: What do you need to know?

18:19 squidz: seangrove: if it is possible to create sourcemaps for clojurescript

18:19 noncom|2: gtrak: yes, surely you're right, it fails when i'm not there

18:19 oh man

18:20 gtrak: so.. back to 15 minutes ago :-), you'll have to hardcode the ns if that's what you want

18:21 noncom|2: but is there a way to not hardcode it?

18:21 gtrak: unless there's a more convenient way... not sure

18:21 ah, I have a terrible idea, let me try it

18:21 squidz: I saw this site that explains how to generate sourcemaps but not sure how to do it with clojurescript or if it's possible http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/

18:21 noncom|2: :))

18:22 bbloom: squidz: clojurescript source maps are a work in progress, they are not available for general use yet

18:22 gtrak: simple :-)

18:23 ,(namespace `ljldfljdfjldfljdsfljsdfljsdf)

18:23 clojurebot: "sandbox"

18:23 seangrove: bbloom: I think they're in there already

18:23 bbloom: seangrove: ok, you know better than me :-) you help squidz

18:23 seangrove: They only have line info, and it's off by one, but you just have to add a :source-map key to your cljs-build compiler options

18:23 Let me try it...

18:24 squidz: seangrove: wow cool I really want to try it out

18:24 noncom|2: gtrak: yeah, and when you said you have an idea, i recalled ns-find also!

18:25 and it like wox with strs.. ? (namespace) is close to (ns-find) afaik..

18:25 gtrak: right, backtick means the symbol doesn't have to actually exist... though, so that's not hardcoding anything :-)

18:26 noncom|2: well, that's super-great!

18:26 so now i can have fun with even more bad style dynamically resolving code :D

18:26 gtrak: heh, yes. I'd be curious if there's a better way.

18:27 ah!

18:27 it all comes back around, close over the value of *ns* at compile-time

18:27 in a let

18:27 noncom|2: )))

18:27 i'll try

18:27 now

18:28 seangrove: Ah, I get an NPE with it. Lame.

18:28 gtrak: noncom|2: yep, works :-). $ java -jar clojure-1.5.1.jar -e "(ns user2) (let [the-ns *ns*] (defn n [] the-ns)) (ns user) (user2/n)"...#'user2/n...#<Namespace user2>

18:29 noncom|2: heh))

18:29 squidz: seangrove: hmmm I would really like to test it out even though it's one line off

18:29 noncom|2: good hacking this is

18:31 seangrove: squidz: I haven't used it from cljsbuild, checking it now

18:32 noncom|2: but that feels a little crazy

18:32 squidz: seangrove: wow i'm crossing my fingers, that would be so cool

18:33 gtrak: noncom|2: pretty sure it'll work

18:33 seangrove: I'm getting an NPE, let me see if I can track it down

18:33 noncom|2: yeah, it does! :) fun stuff. thank you!

18:34 squidz: I had no idea it was so close until I saw something about it yesterday

18:34 seangrove: squidz: What did you see yesterday?

18:35 squidz: I saw an article where somebody mentioned having the :source-map option in the cljsbuild options

18:35 justin_smith: gtrak: what was that we were saying about defn inside let?

18:35 lol

18:35 gtrak: justin_smith: right :-)

18:35 seangrove: Yeah, looks like it works, but you can't use optimizations :whitespace, it has to be at least :simple

18:35 gtrak: like i said, it's helpful to know how eval works..

18:36 especially if you like being nasty

18:36 seangrove: And after the js is generate, you have to edit the soureMappingURL comment at the bottom so it points to the right location for your map

18:36 And after *that*, you have to copy all your source code somewhere the browser can find it

18:37 Ah, and edit the *.js.map.merged file to point to the relative location of the copied source

18:37 squidz: seangrove: can you put an example in a gist. I really want to try it out

18:37 seangrove: I hope I'm wrong about all of that, but I haven't found a way to make it work without those crazy manual-edits and copying the entire source code to a browser-accessible url

18:37 squidz: seangrove: it't really exciting

18:37 seangrove: Sure, One second

18:38 squidz: seangrove: thanks a ton. It's really nice of you

18:39 seangrove: squidz: No proble, just be ready to write me a clojure backend for reliably downloading imap emails

18:39 Which is what I'm escaping from by making this gist...

18:41 justin_smith: sounds like a fair trade

18:42 seangrove: Gotta leverage all this source map work I've been doing somehow

18:42 squidz: seangrove: hehe, well I have no idea about imap emails. But if I could, I would

18:42 seangrove: It's not very pleasant, I wouldn't recommend it

18:42 squidz: is it for business?

18:43 seangrove: The imap stuff is, not source maps

18:43 squidz: because I can't imagine it's for pleasure

18:43 seangrove: It turns out to be pretty cool to query your inbox for all sorts of things from clojure

18:43 But That's only after you have a local copy of it, etc.

18:44 squidz: for some kind of app? Do you have ideas of what you would do with the emails?

18:48 seangrove: Yup, works, one line off

18:48 One second, will post the gist

18:49 squidz: seangrove: awesome work I really owe you one

18:59 seangrove: squidz: Try this https://gist.github.com/sgrove/6092756

19:00 Let me know if it works for you

19:00 squidz: okay i'll try it out now. Thanks so much. I'll tell you if I get it going

19:01 seangrove: Hopefully this can all be folded into cljsbuild at some point

19:02 And very hopefully I'm wrong about source-maps not being able to access file urls, so we don't have to copy all the source code to browser-accessible urls

19:02 But there's remarkably little written about this stuff for source maps that I've been able to find so far

19:03 squidz: yeah i'm sure other poeple would like to see your write up

19:04 i'm getting this whin i try to run lein cljsbuild -> java.lang.Exception: Unknown build identifier: prod

19:04 is prod for production|/

19:04 ?

19:05 seangrove: yeah

19:05 Should be dev

19:05 Updated

19:06 squidz: it says Unknown build identifier: dev

19:06 callen: Raynes: if not Elixir, there's always Go too >:)

19:06 Raynes: if I wanted to kill myself there are easier ways to do it, callen.

19:06 seangrove: squidz: Do you have a dev build id?

19:07 squidz: no

19:07 seangrove: Can you paste your project.clj somewhere?

19:08 squidz: seangrove: https://www.refheap.com/16946

19:08 Raynes: Oh dear.

19:08 That's impressive.

19:09 seangrove: squidz: Looks like you haven't updated it like the example in my gist

19:10 You'll need to give your builds ids, and also to pass :source-map to the compiler section

19:10 squidz: h now I see the build id

19:10 seangrove: squidz: https://github.com/emezeske/lein-cljsbuild#multiple-build-configurations look at "optionally assign an id"

19:11 squidz: okay it compiled on to the next step

19:14 egghead: is there a 'best choice' for websockets in clj currently (preferably easily working w/ ring/compojure)

19:17 err, I guess I'll just want two web servers and a main method instead of lein ring, right?

19:18 squidz: seangrove: what about source entries that refer to "file:/home/albert/.m2/repository/org/clojure/google-closure-library/0.0-2029-2/google-closure-library-0.0-2029-2.jar!/goog/base.js"

19:19 seangrove: squidz: Ignore them

19:19 They're inside jar files anyway, browser won't be able to open them up

19:21 tomjack: hmmmmm https://www.refheap.com/0fdbc1b0180c4af8d46db6b10

19:26 Raynes: O.O

19:27 squidz: seangrove: so if it works I should be able to see the clojurescript files in chromes debugger(I enabled source-maps in the settings)

19:28 callen: tomjack: hahahahahah what the fuck did you do?

19:28 seangrove: squidz: Yeah, more or less

19:28 You should see them listed under sources

19:30 squidz: Example: http://dl.dropbox.com/u/412963/Screenshots/ce.png

19:31 Raynes: AJ!

19:31 AH!

19:31 What is this it's scary.

19:33 callen: seangrove: source maps are live?!

19:33 seangrove: callen: They've been live for awhile, it's just not a full implementation

19:33 But it'll get you down to the line number at least

19:33 callen: seangrove: :D :D :D

19:34 seangrove: version?

19:34 seangrove: 0.0-1844

19:34 But as you can see from the gist above, it's *not* a smooth process

19:34 A lost of it needs to be rolled into cljsbuild probably

19:35 squidz: shit i really want to get it but its not showing up

19:35 seangrove: squidz: What's the source-map comment at the end of the compiled js file, and from what url are you serving it?

19:36 squidz: oh i skipped the js comment

19:38 holy shit it works

19:38 thanks seangrove

19:43 seangrove: Ah, glad to hear it

19:43 Spread the word squidz ;)

19:43 squidz: yeah I really should

19:44 my clojurescript file is found but it appears to be empty

19:44 seangrove: Try right-clicking and opening in a new tab

19:44 What url is it at?

19:45 squidz: okay yeah its the wrong url

19:47 oh my god I can't believe this is working

19:47 with break points and everything

19:47 i'm as giddy as a school girl

19:48 I will spread the word

21:11 tomjack: callen: no clue..

21:11 not my POM..

21:19 akurilin: Need an opinion. Say I'm passing some data from my clojure web app to an ObjectiveC client. The former is pretty happy with working with maps stitched together from different db tables. The latter generally prefers a class for every object type. I could technically use something like NSDictionary to try to mimic a clojure map, but I don't know if I should avoid trying to copy that idiom.

21:20 On the other hand making a boilerplate class for each chunk of JSON I pass back from the web app is a bit of a pita.

21:25 callen: akurilin: NSDictionary is fine.

21:25 that's a standard choice for any kind of JSON data.

21:36 akurilin: callen, as in, most people don't bother wrapping it in container classes with cozy typed properties/

21:36 *?

21:36 clojurebot: * is just for when you are lazy and sloppy

22:13 isaacbw: you guys

22:13 I love you so much

22:17 is there a function in core like C's strstr?

22:17 i.e get the position of a substring

22:31 does clojure have a core function for finding substrings?

22:32 bbloom: use regex

22:32 (find-doc "re-")

22:32 r0bgleeson: my hair is awesome

22:32 isaacbw: I guess I can just use java.lang.String's indexOf as well

22:33 bbloom: or that

22:56 callen: akurilin: not necessarily.

23:26 isaacbw: would anyone mind sanity checking my line buffering function? It works, but I have no idea if it's very idiomatic http://pastie.org/8179805

23:26 futile: isaacbw: for idiomaticity i would use refheap.com

23:27 isaacbw: it looks like you're just recursing, which means you can ditch letfn and use recur

23:27 ,(doc recur)

23:27 clojurebot: It's greek to me.

23:27 futile: aw

23:27 isaacbw: also its usually more idiomatic in Clojure to rely on (possibly lazy) sequences rather than recursion

23:28 and functions which act on sequences, like filter, reduce, etc.

23:28 isaacbw: can you show me some sample usage for this function?

23:29 isaacbw: futile: here's a simple (not very useful) example https://www.refheap.com/16951

23:30 this is for processing line-based network streams

23:31 futile: i guess i just dont understand it well enough

23:31 r0bgleeson: i am a line-based network stream

23:31 futile: i mean, that code prints "hi" but returns "there!".

23:31 isaacbw: more importantly, it prints "hi" and puts "there!" into the buffer

23:31 futile: isaacbw: so, itll do whatever function you give it to each line, and return the last one?

23:32 hmm

23:32 isaacbw: so when more input comes in, line-buffering can continue where it left off

23:32 futile: isaacbw: i think i see.

23:32 isaacbw: though I guess I can get rid of the atom swapping in line-buffer and do that outside

23:33 futile: isaacbw: why not use clojure.string/split ?

23:33 isaacbw: or even better: http://clojuredocs.org/clojure_core/clojure.string/split-lines

23:33 isaacbw: because I can't differentiate the result between (split "ab\nc") and (split "ab\nc\n")

23:33 futile: isaacbw: oh i think i see why you wouldnt want that, because you might not have a completed line at the end.

23:34 isaacbw: both return ["ab" "c"]

23:34 futile: heh i think i did this a few years ago when parsing irc messages.

23:34 isaacbw: yea

23:34 futile: ok let me think for a bit on this

23:44 isaacbw: https://www.refheap.com/16952

23:44 im not perfectly content with it

23:45 feels a bit wordy somehow. but this is the general approach i'd take

23:45 yeah, wait, this is stupid.

23:45 i got too juxt-happy

23:47 ok second try: https://www.refheap.com/16953

23:49 i still dont like it. dont know why though.

23:49 isaacbw: ah, that's much more readable than what I had!

23:49 thank you!

23:50 this all requires a pretty different way of thinking

23:50 futile: yeah, ive been doing clojure full-time for 9 months and its still not natural for me yet

23:51 i think the only way i get by is because i keep forcing myself to think in terms of sequences

23:52 ,(conj [1 2 3] [4])

23:52 clojurebot: [1 2 3 [4]]

23:52 futile: ,(concat [1 2 3] [4])

23:52 clojurebot: (1 2 3 4)

23:52 futile: ok yeah thats what i should use. i dont trust conj ever.

23:53 isaacbw: this always returns a string that you can append more data to and process in the same way.

23:54 isaacbw: and by append i really mean pass (str old-buffer new-data) to the function

23:55 ,(concat [1 2 3] [])

23:55 clojurebot: (1 2 3)

23:55 futile: oh hey that makes it simpler i think

23:56 ,(concat [1 2 3] nil)

23:56 clojurebot: (1 2 3)

23:56 futile: woo!

23:56 https://www.refheap.com/16954

23:56 its even simpler isaacbw

23:58 guys, is there a way to do destructuring that works like butlast/last ?

23:58 oh duh, reverse the seq.

23:59 hmm, i cant tell if this made it better or worse: https://www.refheap.com/16955

Logging service provided by n01se.net