#clojure log - Dec 30 2013

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

0:56 deadghost: so guys

0:56 after 3 weeks of using clojure

0:56 I am nearly done with my first project


0:56 TEttinger: deadghost, you're fast

0:56 deadghost: thing that's stopping me is libre office actually

0:57 TEttinger: it took me a year...

0:57 what?

0:57 clojurebot: what is http://gist.github.com/306174

0:57 deadghost: what I'm doing is trying to start a web site making business

0:57 nothing complicated

0:57 just wordpress

0:57 so

0:57 I scrape yellowpages for businesses with no listed site

0:57 using clojure

0:57 compile that info into a db

0:58 then wrote a web interface to enter an url if they actually do have a site

0:58 TEttinger: that's handy

0:59 deadghost: and creating mailing labels using libre office and postgresql

0:59 I think I just spent 4-5 hours just trying to get the template to work

0:59 not even getting the data into it

0:59 just the template margins and such

1:00 TEttinger, you probably finished a more complex project

1:00 TEttinger: ... maybe

1:00 my first project that I think was "real" was probably a CSV reader lib

1:00 there already was one but it wasn't very flexible

1:01 deadghost: I shouldn't even need to scrape since yp gave me api access

1:01 but for some reason the data was less accurate than a scrape

1:01 TEttinger: hahaha

1:01 that's awful

1:02 deadghost: anyways result was about 20,000 businesses nearby with no listed website

1:02 hopefully I get enough bucks to not need to find work

1:03 TEttinger, I'm not sure whether I'd count this project as slow or fast

1:03 3 weeks since I touched or read any kind of clojure

1:04 but it's a small project that should take a day or two in a familiar language

1:05 TEttinger: nice though

1:05 think you understand the language better than when you started?

1:06 deadghost: yes

1:06 TEttinger: good stuff

1:06 deadghost: but I'm sacrificing some learning to shove things through

1:06 kind of how I wrote a pornhub clone without understanding how a function worked

1:07 but with actual learning

1:07 TEttinger: clojure has such a large and powerful standard lib, that's the big thing I need to learn more of. there's tricks with stuff like distinct and into, that I still don't get yet

1:07 deadghost: if you didn't say clojure

1:08 I'd mistake that as describing sql

1:08 TEttinger: heh

1:08 (doc distinct)

1:08 clojurebot: "([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"

1:08 TEttinger: and that can be used to check for whether something contains duplicates

1:09 deadghost: I still need to figure out macros

1:09 enlive/compojure

1:09 TEttinger: same here

1:09 deadghost: unit tests

1:09 emacs environment

1:09 TEttinger: I use light table

1:09 deadghost: lein set up

1:09 TEttinger: lein rules.

1:10 deadghost: there's a designer that wants to do a start up with me

1:10 and good shot I'll be the only programmer

1:10 ddima: then maybe stick to something you already know well for the beginning? ;)

1:10 deadghost: so kind of need to grind through every thing

1:10 nope I'm inexperienced with everything

1:10 full speed with clojure

1:11 ddima: ahok :)

1:16 arrdem: anyone have a hosted email solution they'd promote?

1:28 bitemyapp: arrdem: http://i.imgur.com/HBzJCEg.jpg

1:28 arrdem: fastmail I've heard good things about.

1:28 if that's not what you meant, please do clarify.

1:28 arrdem: bitemyapp: ohai. goddamn pugs totally broke my win streak. I won one of five games today.

1:29 bitemyapp: arrdem: the problem with running your own postfix server isn't that it's hard, it's that you have no credibility in the overall email network and it's hard to guarantee deliverability without taking a few measures.

1:29 arrdem: bitemyapp: and yeah that's what I was looking for. sorta.

1:30 bitemyapp: such as? I've tried to run my own postfix before and I noticed that my sendmails never got delivered but I never figured out why or how to mitigate it.

1:32 bitemyapp: arrdem: nobody trusts an anonymous postfix server.

1:32 arrdem: setting things up so you can get your email delivered is a whole industry unto itself.

1:33 the situation with spam is bad enough that individuals basically can't expect perfect deliverability on their own mail servers.

1:33 deadghost: explains why no one gets my emails

1:33 bitemyapp: no offense, but people that don't know about these issues or how to mitigate them - probably shouldn't be running their own mail server

1:34 and should instead point their MX records at a service like fastmail and let them handle it.

1:34 * arrdem considers how much offense to take

1:35 * deadghost wonders how my email was set up

1:35 deadghost: my friend wanted to set up email and I totally don't know how well he did

1:35 * TEttinger ponders what pugs are

1:35 arrdem: TEttinger: Pick Up Gamers

1:35 deadghost: I do know that google was mad at my email for a while because of ipv6 or some such

1:36 and then magically stopped being mad and took my emails

1:36 bitemyapp: arrdem: yeah pugglies are awful.

1:36 arrdem: TEttinger: random people you get matched with. Typically the word PUG implies that they are totally incompetent to boot

1:36 TEttinger: arrdem, heh that would be me, if I played

1:36 instead, I am a Fatlus

1:36 bitemyapp: TEttinger: oh you like Atlus games?

1:36 TEttinger: yes

1:37 bitemyapp: TEttinger: are Persona games Atlus?

1:37 TEttinger: I think so. normally I think it refers to fans of the atlus hard-core RPGs

1:37 deadghost: I thought they were

1:37 bitemyapp: TEttinger: I played Persona 4, found it too grindy.

1:37 TEttinger: for me that means the NIS-made games, disgaea, makai kingdom, etc.

1:38 bitemyapp: I think I prefer Tactical RPGs that are balanced for no grinding.

1:38 TEttinger: heh, I'm the opposite

1:38 bitemyapp: I liked Disgaea a bit too, but the same grinding problem.

1:38 I don't like wasting my time.

1:38 and I don't like skinner boxes.

1:38 TEttinger: it isn't a waste if numbers go up!!111

1:38 deadghost: I thought kotr wasn't grindy enough

1:39 or was it KOTOR

1:39 TEttinger: knights of the old republic?

1:39 deadghost: yes

1:39 play through felt incredibly fast

1:39 TEttinger: I still need to play that and the mass effect series

1:39 not very good at real-time games

1:40 puggle

1:40 deadghost: I need to get around to playing civ 5

1:40 because of the anime mods

1:40 bitemyapp: man, KOTOR. Such a great game.

1:40 TEttinger: haha

1:40 bitemyapp: too bad the sequel was so janky.

1:40 TEttinger: is janky getting popular now?

1:40 the word I mean

1:42 deadghost: how many hours a day do you spend on programming activities

1:43 everyone seems more knowledgeable and make more stuff than me

1:43 makes me wonder if everyone is a neckbeard consistently putting in 12 hours a day or something

1:44 ryanf: anyone know of a good blog post or something about the relationship between multimethods and namespaces?

1:45 specifically I'm wondering, if there are defmethods scattered in different namespaces, does the file where the method is being called need to refer to those namespaces somehow in order for the method definitions to be available

1:45 or do they just need to be loaded or what?

1:50 nvm, got it working

1:55 bbloom: help me out you persistent data loving crazy wonderful people you: http://stackoverflow.com/questions/20834721/what-libraries-provide-persistent-data-structures/

1:57 bitemyapp: bbloom: what, you want me to list off a bunch of Haskell libraries?

1:57 deadghost: why did you ask a question

1:57 then immediately answer yourself

1:57 then comment to your own answer right after

1:57 bbloom: deadghost: http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/

1:58 bitemyapp: sure, why not :-P

1:58 bitemyapp: bbloom: poasted.

1:59 bbloom: linked tim's work on clojure-py and unordered-containers.

1:59 bbloom: does clojure py expose its data structures?

1:59 bitemyapp: bbloom: considering I've been using them, yes.

1:59 bbloom: we use clojure-py as a library at work for production stuff.

1:59 bbloom: bitemyapp: awesome

1:59 bitemyapp: 'course that's also why I bitch about it incessantly because it's not mature at all.

1:59 bbloom: why didn't i think to look there? :-)

2:00 bitemyapp: bbloom: you need hashable collections to represent edn in Python. That's why we needed clojure-py.

2:00 That it has a lisp reader as well was just a bonus.

2:02 deadghost: ok I'll be sure to be more schizo

2:02 and talk to myself on stacko

2:12 bitemyapp: bbloom: I found examples of libraries in C#, Java, and JavaScript - edited my post to add them

2:13 bbloom: I expect upboats o_o

2:14 bbloom: bitemyapp: upboat delivered

2:14 thanks :-)

2:14 bitemyapp: bbloom: I tried to make certain they weren't dumb copying collections.

2:17 bbloom: k past my bed time. i'm maybe going to attempt to do some work tomorrow after this lazy ass week

2:26 mischanix: I'm new to clojure; I'm designing a clojure model of an existing card game (CCG; Hearthstone), and I have a large class of functions which each alter a tiny part of the game state. I'm trying to describe, as succinctly as possible, an action which is the composition of two smaller actions, but with a different dice roll for each of the smaller actions.

2:27 TEttinger: (doc comp)

2:27 clojurebot: "([] [f] [f g] [f g h] [f1 f2 f3 & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

2:28 TEttinger: mischanix, the different die roll thing is... I think you might want to pass in a variable for the kind of roll?

2:29 mischanix, do you have some examples?

2:30 mischanix: Before I draw an example, do you know if in a situation like this the argument containing the game state should be the last or the first?

2:30 TEttinger: I'd say first

2:30 for purposes of -> I guess

2:30 though last you can just use ->>

2:31 mischanix: How do you do partials with just the first argument needing to be applied?

2:31 Is there anything in the library for that or should I diy it?

2:31 TEttinger: ,(#(+ % 10) 5)

2:31 clojurebot: 15

2:31 TEttinger: ,(#(+ 10 %) 5)

2:31 clojurebot: 15

2:38 mischanix: Yeah, I found a nice way to do it now, thinking about it just as plain partials. Thanks.

2:39 TEttinger: np

2:42 marcopolo`: is there some library that does automatic currying in clojure? has anyone used it?

2:42 I guess automatic is a bit superflous

3:58 ryanf: dnolen: I'm seeing a bug in clojurescript 2127 that looks related to this http://dev.clojure.org/jira/browse/CLJS-643

3:58 are you aware of anything like that?

3:58 or anyone else

3:59 I don't really understand what's going on well enough to diagnose it, but array-map-index-of-keyword? is returning null because cljs.core.constant$keyword$6 isn't defined https://gist.github.com/rf-/882121c30ec6ffc178c7

4:00 the upshot is that (assoc a-map :keyword value) is returning null

4:01 (that gist is manually deobfuscated compiler output)

4:02 lgs32a: you can't assoc anymore?

4:03 ryanf: it's specifically the path where you call three-arg assoc and the key is a keyword that isn't already in the map -- at least, that's the case where I know it's not working

4:03 it looks like other things would probably be broken for the same reason though

4:06 clearing out my compilation targets and running cljsbuild once from scratch fixes it

4:06 which makes sense based on the stuff in that jira issue

4:06 but I made a temp commit if anyone wants to see how to repro it

4:06 going to bed now though

4:31 seriously_random: & more is not very clear: http://pastebin.com/MC266AiN

4:31 lazybot: java.lang.RuntimeException: Unable to resolve symbol: more in this context

4:33 pyrtsa: seriously_random: How about (cons x (cons y more))?

4:34 Or (apply list x y more)

4:34 cons is probably better in this case.

4:34 seriously_random: cons is fine

4:39 TEttinger: ,((fn ([] 1) ([x] x) ([x y] (* x y)) ([x y & more] (reduce * (concat [x y] more)))) 1 2 3 4)

4:39 clojurebot: 24

4:40 TEttinger: seriously_random: ^

4:50 bitemyapp: $seen ucb

4:50 lazybot: ucb was last seen quitting 18 hours and 28 minutes ago.

4:50 bitemyapp: dermert.

4:53 seriously_random: TEttinger, agree, that is even more clear

4:54 TEttinger: hooray

5:06 hyPiRion: (list* x y more)

5:08 pyrtsa: Ha, didn't know about list*!

5:08 TEttinger: (doc list*)

5:08 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & ...]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

5:08 TEttinger: nice

5:54 seriously_random: stuck with predicate and reduce: http://pastebin.com/S3iXWm6w

5:58 pyrtsa: seriously_random: Check some-fn and every-pred.

6:25 seriously_random: pyrtsa, sorry that doesn't help me much. Can you give a hint how to chain "and" recursively? Do I need to create every possible pair from the sequence of preds?

6:27 abaranos`: seriously_random: if you use filter you cannot get the effect you want

6:28 you could combine reductions with filter to get the filtered results at each step of the way

6:30 TEttinger: ,(loop [data [1 0 4 -2 :a 7 "a" 2] fns [number? integer? pos? even?]] (if (empty? fns) data (recur (filter (first fns) data) (rest fns))))

6:30 clojurebot: (4 2)

6:31 TEttinger: there you go

6:32 seriously_random, does that do the job?

6:40 pyrtsa: seriously_random: Like abaranos` suggested:

6:40 ,(reductions #(filter %2 %1) [1 0 4 -2 :a 7 "a" 2] [number? integer? pos? even?])

6:40 clojurebot: ([1 0 4 -2 :a ...] (1 0 4 -2 7 ...) (1 0 4 -2 7 ...) (1 4 7 2) (4 2))

6:43 abaranos`: pyrtsa: yeah like that :)

6:43 I think seriously_random isn't on anymore... my nick autocompletion doesn't work for him anymore

6:44 pyrtsa: It does for me.

6:44 seriously_random: sorry, was afk.

6:46 TEttinger, the function has to be use like this: (filter (pred-and even?) [a-seq])

6:47 abaranos`: your suggestion is impossible

6:47 filter doesn't work that way

6:47 though I could be misunderstannding you. its late

6:47 seriously_random: abaranos`, http://iloveponies.github.io/120-hour-epic-sax-marathon/one-function-to-rule-them-all.html#exercise-11

6:48 TEttinger: pred-and might call filter repeatedly on a partial arg

6:48 abaranos`: i see

6:49 pyrtsa: seriously_random: (def pred-and every-pred)

6:50 seriously_random: the issue I have is how to build recursively (fn [x] (and (and (and (....

6:51 TEttinger: http://clojuredocs.org/clojure_core/clojure.core/every-pred#source

6:52 seriously_random, the source seems to be pretty uh... yeah...

6:52 seriously_random: TEttinger, lol

7:00 pyrtsa: seriously_random: Your definition of every-pred should almost fit in one line by using (reduce #(...) true preds) and reduced in the definition of #(...).

7:33 seriously_random: pyrtsa, is this right in any way at all? http://pastebin.com/iLgYUySd

7:46 pyrtsa: seriously_random: It fails for 0 predicates at least.

7:52 lumafi: with 1 argument, it returns a sequence of functions. with more arguments, it returns a single function, that either returns a falsy value or recurses (returning a list of functions or a single function again)

7:52 doesn't look correct

7:54 pyrtsa: Shouldn't write straight answers to questions like this but couldn't resist: (reduce (fn [_ p] (if (apply p args) true (reduced false))) true preds)

7:57 hyPiRion: #(apply every-pred (constantly true) %&)

8:06 seriously_random: hyPiRion, can't use apply, I am supposed to use reduce, sort of like that: http://pastebin.com/JFDxrP8V

8:36 mdrogalis: Guess I'll give Cider a try now. Seems more sturdy.

8:47 bitemyapp: mdrogalis: brave.

8:48 mdrogalis: bitemyapp: How're you?

8:50 bitemyapp: mdrogalis: pretty good, spending most of my time in Haskell-land. my recently built desktop didn't have java installed until I needed ElasticSearch.

8:50 mdrogalis: and you?

8:50 mrhanky: anybody have an idea which the fs/init method doesnt work on loading my webpage? it does work if i call it from my web repl after loading the page: https://www.refheap.com/22309

8:50 mdrogalis: bitemyapp: We do miss you. :P I'm alright, a little slower around the holiday.

8:50 It's pretty excellent to tune out for a while.

8:51 bitemyapp: mdrogalis: I've been spending the holiday tinkering, coding, learning. That's partly how I got away with not installing Java for ages.

8:51 mdrogalis: bitemyapp: Conj talks are coming up for entertainment. :P

8:51 Always need more tinkering time.

8:52 * bitemyapp rubs chin

8:52 bitemyapp: mdrogalis: most of my time so far has been spent hammering out the web dev patterns I knew in Clojure and finding their parallels in Haskell.

8:53 some stuff is better, some stuff ain't. The stuff that ain't is pretty rectifiable.

8:53 mdrogalis: Web dev always felt so mechanical to me. :/

8:54 bitemyapp: mdrogalis: that's partly why people are okay with using frameworks, it factors out the redundancy.

8:54 sometimes those frameworks hurt more than they help, but that's the tradeoff.

8:54 daGrevis: hello! what's the clojure alternative for join function? i want to get list of string to a string with seperators between them. (list "a" "b" "c") -> "a b c". I tried apply fn, but don't know how can I set separator for it.

8:55 ,(apply str '("a" "b"))

8:55 clojurebot: "ab"

8:55 mdrogalis: ,(doc clojure.string/join)

8:55 clojurebot: "([coll] [separator coll]); Returns a string of all elements in coll, as returned by (seq coll), separated by an optional separator."

8:55 pandeiro: can nrepl/cider not jump to a function definition of whatever is at point?

8:56 daGrevis: mdrogalis, thanks:)

8:56 mdrogalis: daGrevis: :)

8:57 daGrevis: mdrogalis, just... how can I import it? (sorry for pythonic terms)

8:58 bitemyapp: pandeiro: nrepl can. I dunno if cider is unfucked enough yet for that, but I'm sure it will eventually.

8:58 mdrogalis: (require [clojure.string :as s])

8:58 daGrevis: ,(clojure.string/join " " (list "a" "b"))

8:58 clojurebot: "a b"

8:58 pandeiro: bitemyapp: huh, damn. what about basic eldoc-like functionality?

8:58 bitemyapp: don't ask me about cider.

8:58 daGrevis: mdrogalis, can I do it like in above example?

8:59 bitemyapp: I can only tell you what nrepl can do.

8:59 pandeiro: bitemyapp: and do you know the function name in nrepl?

8:59 bitemyapp: pandeiro: C-h m

8:59 pandeiro: cheers

8:59 mdrogalis: daGrevis: Sure, why not?

9:28 daGrevis: i have some vars and I do this

9:28 ,'(a b)

9:28 clojurebot: (a b)

9:28 daGrevis: but if I do the same using (list ..)

9:29 ,(list a b)

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

9:29 daGrevis: i quite not get it, I thought (list ..) and '(..) are equal

9:31 pyrtsa: ,(list 'a 'b)

9:31 clojurebot: (a b)

9:32 teslanick: I thought the ' notation was for quoting symbols

9:33 i.e. what pyrtsa said

9:33 pyrtsa: Quoting affects everything within the quoted form. It just happens that e.g. quoted numbers, keywords, strings, lists etc. evaluate to the numbers themselves, and symbols remain as symbols.

9:34 (Doh, meant to say "evaluate to the numbers, keywords, strings, lists etc." of course)

9:35 hyPiRion: the ' notation is just the same as saying (quote ...), and that in turn means "do not evaluate the following expression"

9:37 pyrtsa: I didn't think it was that obvious before I started to understand what's said here: http://clojure.org/reader

9:41 philed: ,(list (+ 1 2))

9:41 clojurebot: (3)

9:41 philed: ,'(+ 1 2)

9:41 clojurebot: (+ 1 2)

9:41 philed: quotes are special forms. They don't use the normal evaluation rule.

9:45 pyrtsa: Quoting can be confusing to beginners. It can be argued that they make Lisps in fact not referentially transparent: (apply + (range 3)) isn't the same as (apply + (1 2 3)) because (1 2 3) is read as a function call.

9:46 Not that it matters that much.

9:48 (Doh, and of course replace (range 3) with (range 1 4) above. (blush.)

9:49 philed: I liked the fact the Paul Graham started out explaining evaluation rules and quotation at the very beginning of ANSI Common Lisp.

9:49 pyrtsa: Makes sense.

9:49 hyPiRion: yeah, that book is awesome

9:52 gdev: I'm pretty sure one of the Clojure books starts out with evaluation rules. 80% though, don't quote me on that

10:02 ambrosebs: didn't some-fn and every-pred return multi-arity functions.

10:02 I assumed they returned predicates.

10:02 *didn't realise

10:04 daGrevis: how could I get first ten elements from a list?

10:04 i know about first, rest and nth

10:04 pyrtsa: (take 10 xs)

10:04 hyPiRion: (take 10 my-list)

10:04 daGrevis: thanks!

10:07 gdev: (set! *print-length* 10) (println my-list)

10:08 Bronsa: ambrosebs: +1 for the jvm.tools.analyzer ns segment change btw

10:08 ambrosebs: Bronsa: yep should have done it ages ago

10:10 Bronsa: ambrosebs: i tried to lint core.typed w/ eastwood but looks like there are some weird circular dependencies that make it hard to do automatically

10:10 ambrosebs: Bronsa: totally insane circular stuff going on yes.

10:11 Bronsa: calling clojure.core.typed/load-if-needed should load everything

10:13 Bronsa: ambrosebs: noted, thanks

10:15 gdev: using Rx to develop a pharmacy front end makes for some confusing namespaces

10:39 daGrevis: how can I make my fn to be lazy?

10:40 it computes a inf. list of integers and I want to do something like (take 10 (myfunc))

10:40 currently it throws out integer overflow

10:43 levinm: daGrevis are you familiar with lazy-seq ?

10:44 daGrevis: not really

10:44 but I'm reading about it now http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci

10:45 levinm, it says that 2nd example should be avoided. why's that? http://clojuredocs.org/clojure_core/clojure.core/lazy-cat#example_850

10:46 levinm: my expertise probably doesn't extend as far as yours, I just knew the name. You might also want to look at accepted answer at http://stackoverflow.com/questions/4992298/clojure-lazy-sequence-usage

10:47 daGrevis: trust me, I have no experience ;)

10:47 thanks for the link tho ;)

10:51 marcopolo`: daGrevis: You don't want to keep the head because then you can't GC

10:54 teslanick: I'm curious: is it because you can't GC the first two elements, or does it somehow prevent GC on the entire seq that has thus far been realized?

10:55 marcopolo`: teslanick: If you don't keep track of the head then you only have to keep in memory the current chunk of the seq that has been realized

10:55 nDuff: teslanick: holding the head caches everything that's been realized.

10:55 teslanick: ...which can be convenient if you have something that was expensive or side-effecting to calculate.

10:55 marcopolo`: If you do keep track of the head, you have to keep track of every element that has been realized because it's a linked list

10:56 nDuff: good job team!

10:56 teslanick: That's exactly what I wanted to know, thanks!

11:05 daGrevis: I guess it doesn't make sense to filter out lazy seq

11:05 because it will run forever, right?

11:05 it will be like: good, good, good, bad, bad, bad, bad and will never stop

11:07 so I have fib-seq that's lazy and I want to filter out all integers that are below 4'000'000

11:08 rovar: daGrevis: if your filter is lazy, it will not run at all

11:08 teslanick: daGrevis: filter itself returns a lazy http://clojuredocs.org/clojure_core/clojure.core/filter

11:08 rovar: until you ask it for results..

11:09 daGrevis: rovar, teslanick : you are right. the problem came from me trying to get sum of all later

11:09 http://vpaste.net/Xy8hL

11:17 teslanick: daGrevis: The problem is with your lazy-seq definition, not the filter or sum.

11:25 Jarda: wut

11:25 oops

11:25 is it possible to transform keys recursively of a map

11:26 {:foo-bar {:ding-dong 15}} -> {:foo_bar {:ding_dong 15}} is the desired outcome

11:26 abaker: is there a good lein template for clojurescript? cljs-kickoff? cljs-template? something else?

11:26 Jarda: ,help

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

11:27 samrat: abaker: there's also David Nolen's mies

11:27 abaker: ah, nice, I'll try that one out

11:27 thanks samrat

11:51 dnolen: abaker: there are better ones if you want a webserver setup, mies is just about playing around with ClojureScript w/ minimal fuss.

11:51 seangrove: dnolen: About to experiment with using om for production - any strong recommendations against this, or should it be alright with the correct expectations?

11:52 dnolen: seangrove: not sure if I would use it on a production project just yet, but it's getting there

11:53 abaker: dnolen: I'm looking for something simple, create a cljs impl (or maybe wrapper) for other JS libs

11:53 dnolen: abaker: ok, then mies might work for you.

11:55 seangrove: dnolen: Sounds like a ringing endorsement, so long as we have the right expectations

11:55 dnolen: It'd either be this or writing a wrapper around React anyway

11:57 dnolen: seangrove: the labeled issues give an idea for what I think is problematic http://github.com/swannodette/om/issues?state=open

11:58 seangrove: only show stopper is the #30 at the moment, but people may find other things

11:58 rovar: I am trying to create define functions in another namespace, I was hoping to use binding to do so.. this is what I have..

11:58 serializable functions at that..

11:58 https://www.refheap.com/22313

11:59 mullr: dnolen: woohoo! that's my bug!

11:59 rovar: it appears to be successfully creating the function, but not in the ns I'm hoping for..

11:59 dnolen: mullr: heh :)

12:00 mullr: thanks for the minimal case

12:00 rovar: does binding only work for reading from said ns?

12:00 mullr: dnolen: no problem

12:01 rovar: om looks pretty sweet. once I get to the webdev portion of my project I hope to give it a spin.

12:01 at this point I'm still trying to create a multi-user lisp

12:02 I guess I should look at the source for binding. I was hoping it was a scoped setter.. I just need to push a ns onto a stack and then pop it off..

12:02 mayhaps I should just write that function..

12:07 seangrove: dnolen: Trying to use the latest (r2127) cljs, getting this error - seem familiar at all? https://www.refheap.com/2719477a1e7002a6bcc21f66d

12:07 Could be a deps issue with some other google library

12:08 dnolen: seangrove: latest google closure compiler required JDK 7

12:08 reqires

12:08 erg, requires

12:09 seangrove: if you want it to work with something else you need to build it yourself.

12:09 seangrove: that might not be it, but this looks similar to what someone else reported and that was the conclusion

12:09 seangrove: dnolen: looks like I have javac 1.7.0_21 here

12:10 daGrevis: whyes this runs forever? http://vpaste.net/0QO9B

12:10 dnolen: seangrove: k, then it's some other dependency issue

12:10 seangrove: dnolen: is the ticket on cljs?

12:10 err, JIRA?

12:10 dnolen: seangrove: no

12:10 seangrove: this is some Java dependency issue

12:10 seangrove: Fun fun. I'll look into it

12:10 Thanks for the pointer

12:10 dnolen: seangrove: or that's what it looks like to me. if you can determine that's it not then yes open a ticket.

12:11 seangrove: google closure pulls in a lot of dependencies, may be lein deps tree will make it obvious what's going wrong?

12:11 daGrevis: if I replace filter with take 10, it runs and gives me an integer. what's wrong with my filter? http://vpaste.net/yNftE

12:12 seangrove: dnolen: Looks like it must be a problem with some other com.google.* deps

12:13 S11001001: daGrevis: how does filter know when to stop looking for more elements for which the test returns true?

12:13 daGrevis: S11001001, good point. any ideas how can I say it to stop after first false?

12:14 S11001001: daGrevis: filter isn't the right function for that. Look at the other functions available

12:14 philed: daGrevis: Write a take-while function.

12:14 If not in the standard library.

12:16 daGrevis: philed, S11001001: found it! http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/take-while and it works :)

12:18 philed: Sweet!

12:21 rovar: clojuremud.core> (defmacro do-in-ns [next-ns & stuff] `(let [old-ns *ns*] (do (in-ns next-ns) (eval ~stuff) (in-ns old-ns))))

12:21 #'clojuremud.core/do-in-ns

12:21 clojuremud.core> (do-in-ns (s/fn inc2 [x] (inc (inc x))))

12:21 CompilerException java.lang.RuntimeException: Can't let qualified name: clojuremud.core/old-ns, compiling:(/tmp/form-init8607824030701866727.clj:1:1)

12:21 seangrove: dnolen: Yup, depenedency issue from a random jar, thanks.

12:22 rovar: in this case I really do wish to capture *ns* in old-ns

12:22 well.. at run time.. not compile time..

12:24 oic.. should have gensym'd the old-ns

12:25 alandipert: rovar: you could (declare ^:dynamic *old-ns*) before the macro and bind it to *ns* in the macro

12:26 rovar: alandipert: that was my first approach..

12:26 alandipert: https://www.refheap.com/22313

12:26 it didn't seem to want to bind the function to the new ns when I did it that way

12:27 although mayhaps I screwed something up.

12:32 dnolen: seangrove: cool

12:51 rovar: eerg..

12:52 my macro expansion seems to be embedding my form in an additional set of ()'s

12:52 thus trying to execute what I've created

12:52 foofoobar: Hi! I'm reading "Clojure - Functional Programming for the JVM" and have a question: (def vowel? (set "aeiou")) ; When a set is used as a function, it returns the argument if it is in the set and nil otherwise.

12:52 so I tried ((set "aeiou") "a") and I get nil, why ?

12:53 scottj: foofoobar: (seq "aeiou") gives a seq of characters like \a, where "a" is a string

12:53 foofoobar: set runs seq on its arg before putting them in a set

12:53 seangrove: ,(set "aeiou")

12:53 clojurebot: #{\a \e \i \o \u}

12:53 seangrove: ,((set "aeiou") \a)

12:53 clojurebot: \a

12:54 foofoobar: ah, so what I did wrong was passing a string instead of a \a ?

12:54 scottj: foofoobar: yes

12:54 seangrove: foofoobar: Yeah, exactly. Just different data types, s'all.

12:54 foofoobar: ,((set "aeiou") (seq "a"))

12:54 clojurebot: nil

12:54 foofoobar: :/

12:55 scottj: ,(seq "a")

12:55 clojurebot: (\a)

12:55 foofoobar: ,((set "aeiou") (first (seq "a")))

12:55 clojurebot: \a

12:55 foofoobar: ah, okay :) Thanks for help!

12:56 gdev: ugh, Windows ftl, leiningen won't show my profiles or plugins from my profile.clj unless I'm in the .lein directory. how do I debug this?

13:03 mocker: 4clojure needs a 'Follow people who aren't super awesome but have solved more than you' option. :)

13:03 seangrove: mocker: So you can understand their solutions?

13:03 mocker: My solution to problem 19 isn't pretty: #(first (drop (count (rest %)) %))

13:03 seangrove: So I don't feel so bad about my solutions.

13:05 seangrove: mocker: Well, consider the bad feelings as dues paid to become awesome ;)

13:05 mocker: hehe

13:07 rovar: how can I un-paren something in a macro?

13:07 or un-nest

13:07 seangrove: rovar: You can splice

13:08 rovar: ,(doc splice)

13:08 clojurebot: It's greek to me.

13:08 seangrove: rovar: http://stackoverflow.com/questions/4571042/can-someone-explain-clojures-unquote-splice-in-simple-terms

13:08 rovar: that looks like what I want..

13:08 but how did it get this way in the 1st place?

13:08 is question for another day

13:09 seangrove: rovar: Probably best to post the macro itself if you're looking for help with that

13:10 rovar: seangrove: here is my latest version : https://www.refheap.com/22316

13:10 still a problem with quoting of namespaces..

13:10 also.. probably my approach in general. I wish to be able to create and bind functions to arbitrary namespaces..

13:10 mocker: seangrove: Or maybe a 'users not participating in the code golf' would be better.

13:10 rovar: the (binding [*ns* myns] blah doesn't seem to work.

13:11 also the straightforward (def my-ns/myfn (s/fn blah)) doesn't seem to work..

13:12 seangrove: What namespace is s/ supposed to refer to in that case?

13:12 rovar: oh. right.. s is serializable-fn

13:13 basically I want people to be able to share the same environment and add/remove functions to their and other namespaces at runtime..

13:13 and of course I want to be able to serialize them so progress is remembered

13:13 seangrove: Sounds a bit mad, but interesting

13:13 rovar: it's for a mud :)

13:14 that you build from the inside out

13:14 more of a multi user repl, really..

13:14 seangrove: The error it's giving you is about a namespace being cast to a symbol, do you know which form causes that?

13:14 rovar: in my first approach, I just did a contextual-eval with a hash of each user's symbol

13:15 seangrove: I am assuming it's for the first setting of in-ns at (clojure.core/in-ns (quote room-ns))

13:15 but I don't know why that would be...

13:16 the 2nd use of in-ns evals against the gensym variable I set

13:19 edw: I naively assumed that building an uberjar twice in succession from the same source would lead to jars with identical checksums. I was wrong. Anyone have insight into what changes? An internal timestamp of some sort?

13:19 nDuff: edw: yes, jars contain timestamps.

13:20 edw: ...the META-INF folder also contains build time data, if my memory is at all correct.

13:20 edw: nDuff: Ugh, seems dubious to me.

13:20 nDuff: edw: ...also, I'm not certain that the compression algorithms used are guaranteed to be deterministic; one could create two different jar files with the same contents but different compression tables, files in different orders, etc.

13:22 rovar: edw: I think it is a good thing for signatures and hashes of packages to contain the timestamp at which they were created

13:22 edw: nDuff: Right, though I would guess that the LZ77 or whatever algo is stable/consistent, even if there are multiple possible correct representations of a given series of bits.

13:22 rovar: I would agree, if I could get lein to build IFF the uberjar is out of date.

13:23 nDuff: edw: LZ77 may be consistent, but (f'rinstance) iterating over an unordered set to get contents to put into that archive may not be.

13:24 edw: nDuff: I hear you. Per my comment to rovar, my fundamental issue is that I can't get lein to perform a NOP if the jar is up-to-date with respect to the sources.

13:24 nDuff: *nod*.

13:25 rovar: so it should use timestamps of artifacts vs source instead of hashes..

13:27 edw: I'm building a Makefile to handle deploying a jar, and at this point I have to depend on human judgement/intervention to build the jar, unless I want to re-implement half of lein in Make.

13:29 Hello, it's Unix version six calling, it would like its features back, since we're clearly not using them.

13:32 rovar: wtf? https://www.refheap.com/22317

13:33 TimMc: edw: I believe there is specifically a timestamp in the pom.xml files.

13:34 edw: This script may be useful in investigating differences in JARs: diff <(unzip -c -- $1) <(unzip -c -- $2)

13:35 nDuff: "$1" / "$2", with quotes, if there are spaces or glob characters anywhere in the names (or if you don't know the value of IFS)

13:35 TimMc: True!

13:36 Funny that I remembered to use -- but forgot to quote.

13:36 edw: TimMc: That was my next step. I think I'm going to need to have to assemble a list of all the on-disk files included into the jar and list them as prerequisites in the Makefile.

13:37 TimMc: But yeah, we *really* should be using cross-platform deterministic builders. It's great for auditing.

13:37 nDuff: unzip -c only works if you assume equivalent ordering.

13:38 ...unless unzip offers guarantees itself on that count.

13:38 TimMc: I see no guarantee of that in unzip's manpage.

13:39 edw: TimMc: I didn't think it would be such a hassle to get lein to do nothing if nothing needed to be done.

13:41 gregorstocks: MD5=`md5 x.jar`; lein uberjar; if [ $MD5 -ne `md5 x.jar` ] ; then lein uberjar ; fi

13:42 TimMc: gregorstocks: See above conversation on timestamps in JARs.

13:42 clojurebot: Pardon?

13:43 gregorstocks: TimMc: that's probably not the biggest problem with my proposal

13:43 bitemyapp: gregorstocks: http://www.youtube.com/watch?v=rLw-9dpHtcU

13:44 gregorstocks: bitemyapp: good point

13:45 bitemyapp: gregorstocks: you should visit more often.

13:46 edw: I'm going to kludge this so I look for the newest file in src/, test/, and resources/ (as well as project.clj) and then compare the newest timestamp to the timestamp of the uberjar. Jeebus.

13:46 TimMc: gregorstocks: Oh. Yes, indeed. :-P

13:46 gregorstocks: bitemyapp: yeah, beats working

13:46 bitemyapp: gregorstocks: I can't trick Dave into coming here.

13:46 TimMc: I'm like the Clojure compiler, I just freak out at the first error and stop reading.

13:47 gregorstocks: bitemyapp: set up a Jabber bot that messages him with every message from this channel

13:47 bitemyapp: TimMc: and spew something senseless yet vaguely proximate?

13:47 gregorstocks: and forwards his replies here

13:47 koalallama: TimMc: sldkjfslfjsdsferrorors are you sure about that?

13:47 bitemyapp: Gregor Stocks, King of Duct Tape.

13:52 WWWest: Hi

13:52 I've got an async question

13:53 bitemyapp: WWWest: I've got an async answer, many even, no guarantees about when you'll get them though.

13:53 rovar: do you expect to block on your request?

13:53 WWWest: so I've got fun1, which processes values inside a go block, and returns a value at the end

13:53 TimMc: bitemyapp: Some days, some days.

13:53 WWWest: so that value is inside an implicit chan

13:54 rovar: WWWest: you might be able to more succinctly describe this with code

13:54 jussayin

13:54 WWWest: now, somewhere else, also inside a go block, I'm trying to map fun1 and get a seq

13:54 bitemyapp: rovar: no no, let him keep rolling with this.

13:54 rovar: it's like talking to an academic, this is fun.

13:54 WWWest: :)

13:54 rovar: is your channel of uniform density?

13:55 WWWest: so I

13:55 bitemyapp: WWWest: why do you need a seq?

13:55 edw: Hey, "all" I have to do is compare my uberjar's timestemp to the following file:

13:55 WWWest: do this : (map #(<! (fun1 %)) values)

13:55 edw: find . \( -type f \) -and \( -path './resources/*' -or -path './project.clj' -or -path './src/*' -or -path './test/*' \) -and -not -path '*~' | xargs ls -lt | head -n 1 | cut -c 45-

13:55 Yay.

13:55 WWWest: why is this wrong?

13:56 bitemyapp: I need a seq because it seems natural and clojury

13:56 bitemyapp: WWWest: there are HOFs in core.async if you want something like map.

13:56 rovar: map<

13:56 bitemyapp: WWWest: http://clojure.github.io/core.async/#clojure.core.async/map> and map<

13:56 WWWest: aha

13:56 bitemyapp: WWWest: you're being clingy.

13:56 rovar: http://clojure.github.io/core.async/#clojure.core.async/map<

13:57 that's actually not exactly what you're after..

13:57 bitemyapp: WWWest: you're that boyfriend that won't let his girlfriend spend time with her friends asynchronous. You keep wanted to hold her entire schedule in your hands all at once.

13:57 WWWest: stop that.

13:57 rovar: because it creates a new channel with all the stuffs

13:57 bitemyapp: WWWest: just let her do what she wants.

13:57 WWWest: use the damn core.async functions. Don't try to realize/comprehend stuff in channels into sequences.

13:57 It's a mispattern.

13:58 rovar: WWWest: but to answer your question, you need to run anything with a channel operation inside of a go block, you were attempting to run it inside of a lambda inside of a map

13:58 WWWest: bitemyapp: ok, I'll go over map< and see what I can do with that

13:59 rovar: so to do what you wanted would end up rather kludgy, as bitemyapp said, better to use the core.async tools.

13:59 bitemyapp: rovar: well, unless you want to do a one-off blocking operation against the channel.

13:59 rovar: right.. could do that..

13:59 bitemyapp: I mean, I've written "channel drainers" but that's because I had a clumpy value distribution and I knew how to abuse a while loop.

13:59 but uh, you know. Hypocrisy is okay sometimes if you actually know what you're doing.

13:59 Cf. C++

14:00 dnolen: add ICloneable protocol to CLJS, prep for specify, but it means you can do specify like things today.

14:00 https://github.com/clojure/clojurescript/commit/00008eeca5979f90e5f2e147478202e15949ea8d

14:00 s/add/added

14:48 rovar: amalloy_: are you about?

15:05 shock_one: Hi. Is it the right place to ask about Korma?

15:05 nDuff: shock_one: it's not a bad place to ask about it.

15:07 shock_one: How would I write the GROUP_CONCAT part? https://gist.github.com/shockone/841609292144d260a8fb

15:08 * nDuff -- to be clear -- isn't the person to answer this one, having sworn off korma ages ago.

15:09 shock_one: What do you recommend instead?

15:11 nDuff: shock_one: I wrote my own thin layer on top of clojure.java.jdbc, but there's a lot to choose from.

15:11 shock_one: my big beef with Korma is that it's so macro-centric as to make it hard to compose.

15:11 shock_one: ...that's a problem that HoneySQL (for instance) doesn't have.

15:14 shock_one: Yeah, I also noticed that. But you have to agree: it looks cool. In my case it's not a problem, we'll execute only one query, but it will be quite complicated.

15:19 rovar: does anyone here use either Titanium or Jiraph?

15:19 I can't get either to work for different reasons..

15:20 shock_one: nDuff: by the way they surely know about this issue, and try to provide non-macro versions where it's possible. https://dl.dropboxusercontent.com/u/608214/scrn/1388434649.png

15:20 nDuff: shock_one: Whether it's known hardly matters.

15:32 edw: OK, so that took a while. Makefile and lein now play nice. $(shell find ...) is my new best friend.

15:35 nDuff: ...

15:35 * nDuff shudders at the (ab)use of string-splitting.

15:36 * binski is guilty of clojure.string/split abuse

15:41 * nDuff is more concerned with the variety wherein a stream listing pathnames is split by any delimiter other than NUL (which is the *only* character which can't legally be present in a UNIX filename).

15:41 nDuff: err, pathname.

15:41 (since filenames can't contain '/' either).

15:43 TimMc: nDuff: Fuck tha po-leece.

15:45 * TimMc goes off to write a new OS that lets him have the track listing from Ambient 1: Music for Airports without munging the track names.

15:47 TimMc: nDuff: Do you know what happens if a '/' ends up on disk in a filename?

15:49 gdev: oh wow, my lein_home environment variable was set to .lein\bin instead of just .\lein -_- so it was probably looking for my profiles.clj in the bin folder

16:15 rovar: what is the recommended approach for making a mutable map of mutable maps?

16:15 e.g. (def foo (ref {})

16:16 seangrove: rovar: You ask the darndes' questions.

16:16 rovar: where foo would be altered with things that go into foo, which would also be refs to maps

16:16 seangrove: I'd say, the recommended approach is to approach the problem without mutable maps

16:17 rovar: neat idea.. how would you recommend keeping a list of users that could be altered frequently, each with their own set of properties which could be altered frequently.

16:17 seangrove: rovar: Why not use immutable maps and get/assoc/update-in?

16:17 rovar: thought about it..

16:18 but when user moves from room a to room b, their map gets updated

16:18 seangrove: Sure, assoc-in

16:18 rovar: so I don't want to recreate the entire set of all users because one user changed...

16:18 seangrove: rovar: Persistent data structures...

16:18 rovar: i'm well aware of the concept.. but we're talking potentially thousands of updates per second..

16:18 seangrove: Cross that bridge when you come to it?

16:19 You're not recreating the entire set of all users, changing the data is generally very efficient

16:20 rovar: so make the users map an atom?

16:20 and just swap in a new one?

16:20 seangrove: If you need to. Depending on your loop, you probably don't need an atom

16:21 rovar: I'm not serializing these requests within the loop, so I'd need something to do that for me.

16:22 seangrove: rovar: I don't know enough about what you're trying to do to give you any solid recommendations other than you probably don't need mutable data structures at all here

16:23 rovar: so a multi-user environment where a number of transactions could occur, consider, for instance, a user moving from one room to another.. In one transaction, the rooms's contents will be emptied of said user and that user will be added to the list of users in another room. Simultaneously, the user's reference to its container will need to be updated into its new room.

16:24 its effectively two indices, because I will need random access of users in a room, and also constant time access of a room for that user..

16:25 dnolen: rovar: thousands of updates a second is not that many for Clojure data structures

16:25 rovar: I would abandon your mutable map of mutable maps

16:25 and just do something functional as suggested

16:26 rovar: that's fine, but I'd still need to update both indices atomically. I could make them part of the same map, and swap out the entire map..

16:26 but logically, it seems sane to have one map be "rooms" and the other "users"

16:28 dnolen: rovar: ok, then two refs and transactions would probably work for you. I've never really used the STM so perhaps some one has a better suggestion.

16:30 rovar: if I use the single map approach, I'd still have to use an atom for the map, because I'd want to guarantee consistency if every thread in the threadpool tries to update it simultaneously. one could end up with lost writes or A B A problems..

16:30 whomp: how do you unquote?

16:31 like if i'm given 'a, how do i get a?

16:32 dnolen: whomp: like you want to look up the value the var a is bound to?

16:32 seangrove: rovar: Then you could probably do (atom {:rooms ... :users ...})

16:32 whomp: dnolen, yeah

16:32 it appears eval does the trick

16:32 llasram`: whomp: There's a few answers to that question, but usually needing to ask it means you're approaching the problem from a non-idiomatic direction

16:32 seangrove: rovar: But you'll probably want to spend some time considering your data structures, since it's going to severaly hamper or help you once things get going.

16:32 llasram`: whomp: Unless you're developing tools

16:32 dnolen: whomp: or you could resolve the var, but you'd need to provide a namespace.

16:33 ,(doc resolve)

16:33 clojurebot: "([sym] [env sym]); same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)"

16:33 whomp: i was making a swap function, (swap a b) switches values of a and b

16:33 llasram: whomp: Like, swap the values of two vars?

16:33 whomp: yeah

16:34 llasram: If you really wanted to do that, the right way would be to pass the vars -- #'a syntax

16:34 But I'm skeptical that's something you'd actually want to do :-)

16:34 seangrove: whomp: Generally, swap would be implemented as (fn swap [a b] [b a]) ;)

16:35 whomp: thx :)

16:36 llasram: whomp: Why do you need such a `swap`?

16:37 whomp: just realized i don't need it haha

16:37 llasram: kk

16:37 whomp: trying to do the euclidean algo

16:37 mi6x3m: hey clojure, how come the REPL prints sequences with list literals?

16:38 Cr8: how else would it print them

16:38 mi6x3m: Cr8: with a generic type indication, no need to indicate the contents?

16:39 Cr8: that's how java objects that don't have any print method defined are printed

16:39 llasram: mi6x3m: I believe just convenience

16:39 Cr8: any data type that can be printed in a way that the data inside can be read back though, will be

16:39 llasram: mi6x3m: A lazy seq printed as a list, then re-`read` as a list will have all of the same properties as the original sequence (once fully realized)

16:40 Cr8: ,(read-string (pr-str (range 10)))

16:40 clojurebot: (0 1 2 3 4 ...)

16:40 dnolen: whomp: yeah swapping two vars is strange, if you're trying to write GCD you just need recursion

16:40 whomp: yeah i see the solution now

16:40 llasram: mi6x3m: Actual lists support a few extra operations, but you rarely use/need them in practice

16:40 whomp: ty

16:41 mi6x3m: llasram: yes, but 'sequence' is just a property right? so this will give me a list although I didn't print a list

16:41 anyhow, it doesn't matter

16:41 I just wanted to ask :)

16:41 the book I read doesn't get that straight

16:42 llasram: mi6x3m: Yes and no. The abstraction lets you treat anything on which you can call `seq` as a "sequence", but printing is via the type hierarchy, and will never call `seq` on its own

16:43 mi6x3m: llasram: yes, I am aware :)

16:43 llasram: Ok, cool

16:43 mi6x3m: thanks for clarifying, this helps me a lot

16:44 but this list output

16:44 is purely a REPL thing right?

16:44 llasram: Well, REPL + using `pr` etc for serialization

16:47 alandipert: mi6x3m: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj#L145

16:48 mi6x3m: alandipert: ah, this makes it crystal clear :)

16:48 thanks !!

16:51 alandipert: mi6x3m: np!

17:03 TimMc: &(map (juxt counted? class) ((juxt identity (comp read-string pr-str)) (range 5)))

17:03 lazybot: ⇒ ([false clojure.lang.LazySeq] [true clojure.lang.PersistentList])

17:05 whomp: can i apply a function n times to a value? like (func 5 f a) would give f(f(f(f(f(a)))))

17:08 TimMc: There's iterate...

17:08 mikerod: ,((apply comp (repeat 5 inc)) 1)

17:08 clojurebot: 6

17:08 mikerod: sort of weird :)

17:09 _zip: Hello

17:09 zerokarmaleft: ,(take 5 (iterate inc 0))

17:09 clojurebot: (0 1 2 3 4)

17:09 amalloy: (nth (iterate f a) 5)

17:09 alandipert: ,(reduce #(%2 %1) 1 (repeat 5 inc))

17:09 clojurebot: 6

17:09 TimMc: Using iterate here is also weird, because it generates a seq you don't use

17:09 amalloy: TimMc: why weird? that seems perfectly normal

17:09 _zip: ,(iterate inc 5)

17:09 clojurebot: (5 6 7 8 9 ...)

17:10 amalloy: if discarding bits of a sequence were considered bad, nth wouldn't exist

17:10 mikerod: iterate seems like the most to-the-point

17:10 approach*

17:10 S11001001: TimMc: all data is transient

17:10 TimMc: amalloy: Oh, it's a perfectly normal functional programming way of doing things. I guess I'm just more aware recently of perf-y things, even though it usually doesn't matter.

17:11 S11001001: :-)

17:11 Yes, I should practice non-attachment.

17:12 "In 10000 years, your data will long since have crumbled to dust. No one alive will even know the name of the storage media it resided upon."

17:13 mikerod: ,((apply comp (repeat inc 100)) 0)

17:13 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.core$inc cannot be cast to java.lang.Number>

17:13 mikerod: ,((apply comp (repeat 100 inc)) 0)

17:13 clojurebot: 100

17:20 seangrove: dnolen: Should https://github.com/swannodette/om/blob/master/examples/mouse/core.cljs#L27 be inside an om.core/transact! ?

17:21 I'm getting an error as-is: "Cannot manipulate cursor outside of render phase, only om.core/transact! and om.core/read operations allowed"

17:21 (could also be a typo, but trying to understand the om lifecycle)

17:21 dnolen: seangrove: om.core/transact! and om.core/update! do the same thing - just different signature.

17:23 seangrove: dnolen: Got it, thanks

17:41 shriphani: hi everyone. I am trying to work around this problem: (read-string "{:url http://grails.1312388.n4.nabble.com/}")

17:41 bbloom: shiney: \"

17:41 sorry i mean shriphani

17:41 shriphani: and the reader complains that the value there is an invalid token

17:41 bbloom: your url is not quoted

17:42 shriphani: bbloom, that is read from a file

17:42 bbloom: then your file is invalid

17:42 shriphani: I did (spit f s)

17:42 and it put that there

17:42 bbloom: ,(read-string "{:url \"http://grails.1312388.n4.nabble.com/"}")

17:42 clojurebot: {:url "http://grails.1312388.n4.nabble.com/&quot;}

17:42 shriphani: ah, so how do I coerce spit to put the quotes for me ?

17:42 bbloom: what was the class of the object that outputted that URL?

17:43 shriphani: erm.. i sent the map to spit...

17:43 and the map contained a key :url and a value i.e. the url itself

17:43 bbloom: (-> the-map :url class)

17:43 what is it?

17:44 shriphani: java.lang.String

17:44 bbloom: ah ok, i see

17:44 use (spit f (prn-str s))

17:44 i'm not sure why you're getting such a bogus string representation

17:45 i suspect that spit is calling str instead of prn

17:45 ,(str {:url "http://grails.1312388.n4.nabble.com/&quot;})

17:45 clojurebot: "{:url \"http://grails.1312388.n4.nabble.com/"}"

17:45 bbloom: hm no...

17:45 shriphani: (spit filename (with-out-str (prn content)) :append true)

17:45 bbloom: ,(.toString {:url "http://grails.1312388.n4.nabble.com/&quot;})

17:45 clojurebot: "{:url \"http://grails.1312388.n4.nabble.com/"}"

17:45 shriphani: that is what I have in my spit

17:45 so I should not call it prn ?

17:45 bbloom: no, that should be precisely what you want

17:46 shriphani: ok it puts in the quotes now.

17:46 thx bbloom

17:47 bbloom: btw, with-out-str & prn together like that is just prn-str

17:47 shriphani: ah.

17:47 I just copy-pasted that off an s/o answer

17:48 bbloom: shriphani: submit a correction :-)

18:06 zerokarmaleft: what's the quickest way to mock out friend's authentication for testing?

18:12 seems like (with-redefs [friend/current-authentication ...] ...) would do the trick but I'm not sure what needs to be in the map

18:22 whomp: what's the diff between --> and ->?

18:23 splunk_: whomp: perhaps you mean -> vs. ->>?

18:25 whomp: splunk_, yeah

18:26 splunk_: it's "thread second" vs. "thread last"

18:26 compare (-> "x" (str 1 2)) vs. (->> "x" (str 1 2))

18:26 or I usually think of it as "thread first" vs. "thread last"

18:27 the former inserts the "x" as the first arg to the `str` (the second element of the list)

18:27 the latter inserts the "x" as the last arg to the `str`

18:27 make sense?

18:28 algal: zerokarmaleft: I just used ring.mock.request and helper function wrap-in-credentials to create properly authenticated requests.

18:30 zerokarmaleft: Perhaps manually building a mock request map is only sensible if you're using a straightforward authentication method like HTTP Basic Auth

18:30 zerokarmaleft: algal: I'm trying to avoid going through OAuth

18:31 whomp: splunk_, thx :)

18:31 also, where can i see other people's solutions to 4clojure challenges?

18:32 Raynes: If you have an account and you solve a problem, it'll give you a link to the soluitons.

18:33 splunk_: anybody know idiomatic way to get the equiv of a line-seq for edn? like an edn-seq?

18:34 dsrx: whomp │ [23:23:04] what's the diff between --> and ->?

18:34 ah the good old C down-to operator :)

18:34 rovar: splunk_: what if your edn is already in a seq?

18:36 splunk_: rovar: I'm not sure I understand--if it's already in a seq, how did it get in there? I'm trying to loop over a file reading EDN out of it until it's EOF, but that's very...not Clojure-y.

18:38 Hoping to avoid just `line-seq`ing it, because don't want to be dependent upon one EDN value per line

18:38 shock_one: whomp: you have to follow users if you want to see their results. I would recommend you to follow all the guys who solved every single problem, it's pretty enlightening to look at their solutions.

18:39 rovar: splunk_: slurp the file and then call read-string on it?

18:39 whomp: shock_one, when i follow someone, nothing happens

18:39 dsrx: shock_one: you say enlightening, i say ego-destroying :P

18:40 rovar: yea I think the site is kind of broken

18:40 splunk_: rovar: yeah, that'll work, though I presume it's not lazy, so I'll have a 1+ gig string in mem

18:40 shock_one: whomp: https://www.4clojure.com/problem/solutions/1

18:40 whomp: ohh i c thx

18:42 rovar: splunk_: I don't think it's lazy. If you want to pull one sexp of edn out at a time, you'll need to write a parser. If you have each edn separated by a newline only, then readline it and pass that to read-string one at a time..

18:44 splunk_: rovar: yeah that'll do for now. thx.

18:45 This appears to have the full slightly awkward solution:

18:45 https://github.com/clojure-cookbook/clojure-cookbook/blob/master/local-io/read-write-clojure-data-structures/read-write-clojure-data-structures.asciidoc

18:45 at the bottom

18:46 rovar: that looks cool

19:19 dnolen: significantly cleaned up Om TodoMVC using the latest stuff, http://github.com/swannodette/todomvc/blob/gh-pages/labs/architecture-examples/om/src/todomvc/app.cljs, enjoy!

19:26 noonian: sweet, thanks!

19:36 devn: is there a way to convert "10101" to an int using bitwise ops?

19:37 TEttinger: devn: as a string first?

19:38 ,(Integer/parseInt "10101" 2)

19:38 clojurebot: 21

19:44 seangrove: dnolen: Why do you (check (...)) for ILookup on MapCursor? Surely we're just reading at that point, not manipulating the cursor?

19:46 bitemyapp: devn: what you're thinking of is basically impossible.

19:46 devn: at least, not in an efficient sane way. You can't just mask something that is an array of multiple bytes like that.

19:46 devn: you *could* write an algo to do it, but I doubt it's any faster than the default impl.

19:48 devn: bitemyapp: that was what i wanted to confirm. my own sanity.

20:06 dnolen: seangrove: no operations allowed on the cursor outside of the render phase

20:07 seangrove: you will likely not see something consistent with the app state

20:38 johnwalkergh: any news on 1.6.0 release ?

20:46 tpope: technomancy: hey, I'm finally circling around to take a look at nrepl-discover

20:58 whomp: any ideas what's wrong with this code? it tells me, "invalid token: match" but i have no idea why

20:58 https://gist.github.com/anonymous/ee3cfb4934510563253a

21:00 justin_smith: for starters you likely want a ' before the vector in pairs

21:00 seangrove: whomp: Also, it's not json

21:00 {match: ..} => {:match ... }

21:01 whomp: seangrove, brilliant thx :)

21:01 justin_smith: yeah, it wasn't saying "invalid token: match" it was saying "invalid token: match:"

21:02 some quoting around the thing being called invalid would help there

21:02 whomp: yeah

21:02 seangrove: justin_smith: Good point

21:02 whomp: it's also just hard to code in the repl

21:04 seangrove: whomp: I don't think you'll find many people who agree with that ;)

21:04 justin_smith: whomp: just a style thing, leave currMap for jvm method names, a clojure binding is better named curr-map

21:04 seangrove: whomp: But it looks like you're developing out of it and then copying back in - that's not a good way to learn for now. Try sticking in the repl a bit more.

21:04 whomp: ohh ok cool. and it isn't even supposed to be a map lol

21:04 bbloom: seangrove: i can't code worth a damn AT the repl

21:04 whomp: no, i develop in the repl

21:04 bbloom: seangrove: i also can't code worth a damn without the repl being a keystroke away :-)

21:05 whomp: what's the shortcut to compile and run in the main screen?

21:05 justin_smith: whomp: emacs has C-M-x for that

21:05 dunno what editor you are using though

21:05 whomp: emacs + evil

21:06 justin_smith: sometimes instead of C-M-x I do M-h M-w to capture the current form, and then control-y to paste it in the repl, so my repl becomes more of a log of what I have tried

21:07 I am sure evil has some equivalent commands (grab entire form surrounding point / copy it / paste it)

21:07 seangrove: bbloom: Heh, yes, sorry. Should have been more specific that you pretty want to keep your code syntactically valid where you can for quick evaluation

21:07 Rather than building up a big block of pseudo-code and then trying to figure out where the syntax errors are

21:07 bbloom: I know you specifically have a different approach though ;)

21:07 seancorfield: justin_smith: I use a function that Stuart Sierra posted to copy and paste the surrounding top level form into the repl - and have it bound to C-c e

21:08 bbloom: seangrove: but i'm a weirdo indeed

21:09 seangrove: bbloom: Perhaps one we should all be emulating though.

21:09 justin_smith: sometimes I write my code on paper or a whiteboard if I am in full on hammock-driven mode

21:09 bbloom: seangrove: nah, find your own process. you can't have mine :-P

21:10 * seangrove cargo-cults bbloom and applies everything to emacs

21:23 dnolen: mullr: that bug was good excuse to move on ICloneable, specify is going to be fun, I may just take a crack at it myself.

21:23 mullr: dnolen: specify?

21:23 dnolen: mullr: extending individual instances to a protocol

21:24 it's going to be awesome

21:24 mullr: dnolen: ... I think I want that

21:24 seangrove: Sounds pretty interesting

21:24 dnolen: Just finished converting a basic widget over to om/sablono, seems pretty interesting so far

21:25 mullr: seangrove: I've been using sablono as well and am very happy with it

21:25 dnolen: seangrove: nice! I'm pretty happy with Om now, it was really putting a barrier between the render phase and event handlers that cleaned things

21:25 seangrove: it's actually a bit of a problem in React, people accidentally holding onto stale stuff

21:26 seangrove: mullr: I've noticed a few oddities with it, but it's good enough for now

21:27 mullr: dnolen: Have you thought about a way to get the path from a cursor? It'

21:27 dnolen: mullr: I have a bit, what's your use case?

21:27 mullr: s attractive to do a top level event loop to handle the succession of an app state atom, and the path of a cursor is very useful in that case

21:28 dnolen: crude example: https://gist.github.com/mullr/8191555

21:29 dnolen: mullr: open a Github issue

21:30 seangrove: mullr: I've been thinking about this + pattern matches to case ui succession

21:30 Haven't gotten anything concrete yet at all though

21:32 mullr: dnolen: https://github.com/swannodette/om/issues/33

21:33 dnolen: mullr: thx

21:33 majyk: I'm using Clojurescript 0.0-2134 (although that version doesn't matter) and lein-cljsbuild 1.0.1 and everytime I build my Clojurescript code the modified date on the output JS file is Dec 31, 1969. This is happening on Windows 8.1. My timezone is set correcly in the OS. Anyone know what is going on?

21:33 bbloom: seangrove: what's that about pattern matching / ui succession?

21:34 dnolen: majyk: maybe a platform bug in CLJS? but that seems weird to me

21:34 majyk: this has been happening to me for a while but I just caught on

21:34 bbloom: that sounds like a timestamp of -1

21:36 seangrove: bbloom: Trying to think about making widgets as widget-y as possible. Have them come with default behavior that modifies a path of a big ui data structure and (separately) dom representation they're part of, then have a top-level event loop that compares data changes from the last loop and this loop and dispatches behavior accordingly.

21:36 So custom behavior is implemented based on changes to the ui data structure, separate from the widget behavior itself

21:36 bbloom: hm, not sure i follow

21:36 i'll wait until you have an example or something, even if it doesn't run :-P

21:37 seangrove: bbloom: no worries, I should have something more concrete before I talk about it with a lot of people

21:37 john2x: sablono should be called "nom". om nom

21:38 seangrove: Or just h => om with hiccup in it => ohm

21:38 bbloom: (inc john2x)

21:38 lazybot: ⇒ 2

21:39 lsdafjklsd: k

21:40 bitemyapp: john2x: that was a meme in the Haskell mailing list

21:40 john2x: making new monad transformers om and nom.

21:40 runMonad $ do om . nom . nom >>= etc etc etc

21:44 lsdafjklsd: anyone working with Om right now?

21:45 seangrove: lsdafjklsd:

21:45 dnolen: lsdafjklsd: people are starting to play around w/ it yes

21:45 bitemyapp: lsdafjklsd: did you roll your face on your keyboard to get that nick or your cat's face?

21:46 I need a cranial diameter here.

21:46 lsdafjklsd: it's epic.. it's a 'kinetic' name

21:46 justin_smith: bitemyapp: I read it as a portmanteu of a favirite drug and a trollish junk key sequence

21:46 lsdafjklsd: muscle memory

21:46 it's home keys, a few trips around the block and you got it down :D

21:46 bitemyapp: I'm going to assume you'

21:46 are quite mad.

21:46 lsdafjklsd: dnolen: I asked because I had a question :D

21:47 dnolen: lsdafjklsd: ask away

21:47 lsdafjklsd: I have an input that, when a user hits the return key, it's state get's reset

21:48 bitemyapp: lsdafjklsd: it is state get is reset

21:48 lsdafjklsd: so on the js hash, I have {value: (:input-val cursor)}

21:48 but when I do that I can not type in the input

21:48 I think it has to do with react

21:49 dnolen: lsdafjklsd: yes inputs are handled a bit in a special way, have you looked at Om TodoMVC, it demonstrates how to do things the React/Om way

21:49 lsdafjklsd: if you are using sablono or some other sugar you may run into issues, Om provides fixed version of React input elements

21:50 lsdafjklsd: https://github.com/swannodette/todomvc/blob/gh-pages/labs/architecture-examples/om/src/todomvc/item.cljs

21:51 lsdafjklsd: dnolen: ah, Ok was not looking in that file

21:51 dnolen: lsdafjklsd: I would use component local state for the value in the text field

21:51 lsdafjklsd: dnolen: yes this is the simple code I was trying https://gist.github.com/lsdafjklsd/8191733

21:52 dnolen: I'm suuuuuper slow at learning clojure / om at the same time.

21:52 dnolen: but have two days off so going to try and build something

21:52 dnolen: lsdafjklsd: you need to "commit" the changes to the text field, this is done by setting the value of the text field

21:53 lsdafjklsd: if you don't do this, React/Om won't let the text field value change

21:53 lsdafjklsd: dnolen: ok, because that was creating odd behavior

21:53 dnolen: boom, nailed it. exactly

21:53 dnolen: thanks so much man

21:53 dnolen: lsdafjklsd: this basically lets you intercept changes and do fancy stuff etc.

21:54 lsdafjklsd: no problem

21:54 lsdafjklsd: dnolen: do you have any meetup talks in the works on this stuff anytime soon?

21:54 dnolen: lsdafjklsd: yeah likely to talk about it more than a few times this year

21:55 lsdafjklsd: dnolen: cool, im new to NYC and have yet to get out too a meet up

21:55 dnolen: I missed your core.async talk, but caught it on youtube. amazing

21:55 dnolen: lsdafjklsd: cool, yeah will probably do something in NYC in the next couple of months

21:56 bbloom: lsdafjklsd: om is a bit experimental, so it might not be a great place to start learning clojure

21:56 dnolen: lsdafjklsd: heh thanks, but the actual awesomeness of core.async is mostly due to other people, same for Om :)

21:58 lsdafjklsd: bbloom: yea, I'm not just starting with clojure.. but coming from rails / ember the whole functional thing is a lot to take in

21:58 bbloom: lsdafjklsd: my usual recommendation is to do the puzzles at 4clojure.com & follow some of the top users. great way to learn the stdlib and get comfortable with the syntax

21:59 lsdafjklsd: bbloom: yea 4clojure.com is great. I worked through stuart halloway's book

21:59 bbloom: and have been working through functional programming for the object orientated programmer by marick ( WHICH IS AMAZING )

22:36 dnolen: BOOM https://github.com/clojure/clojurescript/commit/571e156d2daa223dcef273106827e932283e2f93

22:36 ClojureScript gets specify

22:36 Bronsa: neat

22:37 rovar: cool! what is specify?

22:39 bitemyapp: lsdafjklsd: beware - Marick isn't an authority on FP

22:39 dnolen: rovar: you can extend a value to a protocol

22:39 rovar: ah

22:39 bitemyapp: lsdafjklsd: if you want to learn higher level patterns, FP, specifically in the Clojure community Stuart Sierra is a better exemplar.

22:40 dnolen: rovar: like giving a particular map or vector some functionality without polluting all instances w/ that functionality

22:40 lsdafjklsd: bitemyapp: I found that book to be a really fresh approach

22:40 bitemyapp: lsdafjklsd: you can do better still than that if FP is what you're into, but I'll leave it at that. I don't want hackles to get raised :)

22:40 rovar: that was pretty clear from the tests: (assert (= (specify noz IWoz (-woz [_] :boz)) noz))

22:40 :P

22:40 lsdafjklsd: bitemyapp: I appreciate it any help to stay on track

22:41 bitemyapp: looking forward to the joy of clojure 2

22:41 rovar: dnolen: does clojure proper have docs on this? It seems like a fairly common javascript idiom..

22:41 bitemyapp: lsdafjklsd: JoC is better.

22:42 rovar: been reading JoC2 good stuff.. the bits on macros could have been better..

22:42 there are a lot of interesting examples, but the text doesn't really explain them or bring them together..

22:42 lsdafjklsd: it's worth the meap?

22:42 bitemyapp: lsdafjklsd: I'm being a little unfair, but I think a very simple and approachable way to indicate my overall point would be that he defs everything at the top-level of the namespace.

22:42 dnolen: rovar: well the bad version of it is common in JS, usually involved slow cloning and adding some methods and name clashes

22:42 rovar: and a bunch of other horrible things

22:42 rovar: yea

22:42 dnolen: rovar: this avoid all that non sense

22:43 lsdafjklsd: bitemyapp: marick?

22:43 bitemyapp: lsdafjklsd: yes.

22:43 rovar: dnolen: I've tended to avoid such things for much the same reason that I've managed to avoid prototyping languages. Except for javascript.

22:44 didn't have a choice there.

22:44 lsdafjklsd: bitemyapp: He said something like "file modularity has worked for c, it's good enough for us in clojure"

22:44 bitemyapp: lsdafjklsd: let me expand my original statement to be more complete: he's not an authority on FP, programming in general, or Clojure.

22:45 lsdafjklsd: you can't quote marick at me. That's like quoting the Bible to an Atheist.

22:45 rovar: bitemyapp: Marick said you'd say that.

22:46 dnolen: lsdafjklsd: btw, I recommend ignoring most of the things that bitemyapp says. He means well.

22:46 lsdafjklsd: bitemyapp: haha, we'll I'll read with a grain of salt then. but the first half of the book you build an OO language with clojure and I found that very helpful in bridging the gap between the two worlds

22:46 bitemyapp: it's a terrible idea and a terrible way of teaching FP.

22:47 you have to unmoor yourself.

22:47 rovar: that's like giving methadone to a heroin addict

22:47 lsdafjklsd: hahaha

22:47 rovar: or maybe just less heroin

22:47 whichever is worse..

22:47 lsdafjklsd: to be fair, I have like no OO experience

22:47 bitemyapp: lsdafjklsd: it doesn't matter, it's familiar to imperative programmers.

22:47 lsdafjklsd: other than rails

22:47 which isn't really oo programming

22:47 bitemyapp: OO and imperative have similar operational semantics.

22:48 lsdafjklsd: ya

22:48 bitemyapp: that's my point.

22:48 you have to unmoor yourself.

22:48 rovar: I spent the first 10 years of my career mucking about with imperative pseudo OO nonsense..

22:48 bitemyapp: rovar: CL was the only language to really make a go of it anyway and AOP carried water for it in the end.

22:48 rovar: IMO there is a way to code in clojure which captures the best of OO features, but I wouldn't call it OO, but I would call it idiomatic

22:48 bitemyapp: it's not OO

22:49 it's just taking unoriginal features common to some OO languages that happen to also make sense in virtually any programming language.

22:50 they're more "deconstructed" than how they usually appear.

22:50 rovar: it depends on who you ask.. it's not java/c++ style pseudo OO, but you get encapsulation, interfaces, message passing when needed

22:50 bitemyapp: dnolen: I see two possibilities, either you didn't see his mailing list antics - in which case you don't know any better and were somehow not on the ML during that time period (unlikely)

22:50 rovar: inheritance is already pretty much considered a mis-pattern

22:50 bitemyapp: dnolen: or you were on the mailing list and you're being a hypocrite.

22:50 and choosing to pretend his understanding of Clojure is somehow not problematic.

22:51 rovar: really? you should tell the FP-lite peeps over in #scala that.

22:51 dnolen: bitemyapp: eh, it's a big world. People can use Clojure how they like.

22:51 bitemyapp: their libraries and ecosystem appeared to not have gotten the copy-pasta memo.]

22:51 dnolen: as long as they don't put defn's in defn's :D

22:51 bitemyapp: dnolen: so you won't say a thing if I propagate mis-patterns like him?

22:51 dnolen: can I hold you to that?

22:52 because if so, I have some counter-revolutionary ideas for driving people to Haskell.

22:52 rovar: bitemyapp: people attracted to the implicits and other DSL tools of Scala deserve what they get.

22:52 bitemyapp: (inc rovar)

22:52 lazybot: ⇒ 1

22:52 rovar: it's like trying to fix c++ template metaprogrammers

22:52 they're broken in a strange way

22:52 bitemyapp: "so we're going to put a def in out defn to make things extra deffy and fast!"

22:52 dnolen: bitemyapp: I wouldn't care beyond saying I don't like this or that pattern, this or that approach.

22:53 bitemyapp: my experience is people eventually come around and there's little point in trying to push them too hard along

22:53 * bitemyapp rubs hands together, evil raccoon style

22:53 dnolen: bitemyapp: I started Clojure by writing an Object system, yessir.

22:53 rovar: rovar: back to work.

22:53 bitemyapp: dnolen: now the world is upside down and Mori is a thing.

22:53 dnolen: have you seen that I have to use clojure-py in production? the edn parsing situation in Python is a disaster but the hashable collections are nice.

22:54 dnolen: bitemyapp: I have not followed clojure-py at all

22:54 bitemyapp: dnolen: well, given the limitations of Python's collections you basically need something like Mori for Python in order to implement an edn parser.

22:54 dnolen: you can't have #{ {:a 1} } in python.

22:54 it's inexpressible.

22:55 and not because of the keyword, either.

22:55 so between the lispreader and the collections, we had to use clojure-py to talk to Datomic.

22:55 Pretty bad :(

22:57 rovar: I think clojure-rust would be fun to write

22:57 bitemyapp: very glad clojure-py exists though.

22:57 life-saver so far.

22:57 rovar: still no facking TCO.

22:58 grumble grumble grumble

22:58 rovar: yea.. TCO is at ods with reference mgmt, who knew..

22:59 but that's ok, because we can use the recur trick to build iterative loops..

22:59 even GNU C gets CTO, though.. :/

22:59 TCO

22:59 bitemyapp: rovar: I eagerly anticipate Zed Shaw's "Rust is a Ghetto" blog post.

23:00 justin_smith: gnu c does self call, or generalized tail call?

23:00 bitemyapp: justin_smith: almost certainly self-call.

23:01 justin_smith: http://www.prodogtivity.com/ you like doges right?

23:01 Wild_Cat: bitemyapp: what are you using clojure-py for, out of curiosity?

23:02 bitemyapp: Wild_Cat: Python <---> REST API <---> Datomic

23:02 pretty messy situation though.

23:02 alew: what is the difference between self call and generalized tail call?

23:03 Wild_Cat: bitemyapp: wait, you're only using it to parse EDN?

23:03 bitemyapp: we're basically tip-toeing around clojure-py's rough patches.

23:03 Wild_Cat: ...I'll grant you it's a valid use case, though.

23:03 bitemyapp: Wild_Cat: did you read everything I said?

23:03 it's not just the parsing.

23:03 justin_smith: alew: generalized tail call can turn two functions that each tail call the other into a loop

23:03 Wild_Cat: bitemyapp: sorry, no, I jumped in in the middle of the conversation. I will now.

23:03 justin_smith: alew: eliminating all the function call / return in the mutual recursion

23:04 very useful for state machine / parser type stuff

23:04 bitemyapp: alew: self-call: a ( a ( a ( a ( a ( a ( a ( a

23:05 alew: is that related to trampoline?

23:05 bitemyapp: alew: mutual: a ( b ( c ( a ( b ( c ( a ( b ( c

23:05 justin_smith: alew: it eliminates the need for trampolining often

23:05 under the hood you get a loop / switch basically

23:05 but you get to express it as functions calling other functions

23:06 with trampoline you still have function calls, they just only go one deep, and you need to translate to return a function instead of calling it

23:06 with generalized tail recursion it is just normal code that calls other functions

23:07 alew: I'm guessing clojure doesn't have that?

23:07 bitemyapp: these differences can lead to much much nicer code than it would otherwise indicate.

23:07 justin_smith: it doesn't have either kind of tail call optimization

23:07 alew: right

23:07 limitations of the jvM/

23:07 jvm?*

23:07 bitemyapp: uh, hold up

23:07 Wild_Cat: that's because the JVM doesn't support TCO, right?

23:07 bitemyapp: it's not a fundamental limitation

23:07 it's a tradeoff.

23:08 Wild_Cat: Clojure has loop/recur for that stuff, though

23:08 bitemyapp: you can do TCO on the JVM and there are languages that do

23:08 Wild_Cat: it's not as great, but it works.

23:08 bitemyapp: Clojure chose to favor interoperability and performance.

23:08 it was not a "given" though.

23:08 alew: is TCO not performant?

23:08 justin_smith: well you can't do cross method goto, which makes tail recursion between functions hard, unless you put all your code in one method

23:08 bitemyapp: alew: it is in the right language implementation, the JVM doesn't make that easy to do in a generic way.

23:09 alew: in languages like Haskell and OCaml recursion compiles down to the same assembler you'd see from C for all intents and purposes.

23:09 Wild_Cat: the lack of TCO isn't that big an issue when you have proper looping constructs anyway

23:09 justin_smith: alew: it is very performant, compared to regular function calls, and very readable / maintainable compared to huge loops with switch statements

23:09 bitemyapp: Wild_Cat: no. No. No.

23:09 Wild_Cat: no. no. Stop. no. No. Don't ever say that again. No. No.

23:10 justin_smith: http://www.prodogtivity.com/?dog=43

23:10 bitemyapp: Wild_Cat: https://github.com/noprompt/frak/blob/fraskell/hs/src/Frak.hs

23:10 alew: There is a lot of code I would rather express recursively

23:11 bitemyapp: Wild_Cat: recursion >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> imperative looping bullshit

23:11 especially once things like mutual recursion can be used safely

23:13 rovar: is there something like a get-in but with wildcards?

23:13 bitemyapp: rovar: madness.

23:14 rovar: let's say I have some heavily nested maps..

23:14 justin_smith: wow, that sounds like a complexity nightmare

23:14 bitemyapp: rovar: madness.

23:14 justin_smith: I mean you could do it...

23:14 but I am sure it is not built in

23:14 rovar: I have a good reason for it..

23:14 alew: is that haskell do the same thing as all the cljx code in the same repo?

23:14 bitemyapp: rovar: you need a different data structure

23:14 rovar: err..

23:14 bitemyapp: alew: the haskell code is the beginning of an experiment, it's not complete.

23:15 rovar: that will be almost impossible..

23:15 https://www.refheap.com/22327

23:15 these data structures need to exist mostly as-is for other purposes..

23:15 bitemyapp: rovar: this is easy. You can do it in roughly linear time

23:15 rovar: my friend, I'm going to introduce you to...

23:15 rovar: Zippers! http://clojuredocs.org/clojure_core/clojure.zip/zipper

23:16 rovar: enjoy!

23:16 seancorfield: zippers are awesome.

23:17 rovar: basically my need is to select, say all verbs named "c1" under the hierarchy of users -> items -> verbs

23:17 bitemyapp: rovar: then my suggestion is...

23:17 rovar: drumroll

23:17 ...

23:18 rovar: in light of this critically unique and troubling information I must recommend

23:18 rovar: ...

23:18 rovar: zippers.

23:18 seancorfield: bitemyapp: er, hi, yes, i'm sure zippers are great :)

23:18 bitemyapp: (inc seancorfield)

23:18 lazybot: ⇒ 9

23:18 bitemyapp: I am corrupt but gracious.

23:18 hiredman: rovar: I would check out clojure.set, what you want is to create various indices for lookups

23:19 rovar: you may also look at core.logic and pldb

23:19 bitemyapp: rovar: hiredman's first suggestion is great.

23:19 rovar: what exists on that page is the worst set of examples for any api in any programming language ever.

23:20 I mean.. wow... they pull in the zippers ns as z. then proceed to def z

23:20 this is the type of documentation created to confuse would-be invaders and keep them from sacking cities.

23:20 justin_smith: clearly they like the last letter of the alphabet

23:20 bitemyapp: rovar: http://www.haskell.org/haskellwiki/Zipper http://learnyouahaskell.com/zippers http://en.wikipedia.org/wiki/Zipper_(data_structure) http://en.wikibooks.org/wiki/Haskell/Zippers

23:21 rovar: index-y stuff related to clojure.set is a good place to look though.

23:21 alew: that makes sense

23:21 rovar: oh, I'm well aware of how zippers work

23:21 alew: the naming conventions came over from haskell

23:21 rovar: I am a haskeller

23:21 justin_smith: rovar: there was a standard protocol in the Netherlands during WWII - words they would have someone say, which they were sure no German could pronounce correctly

23:21 bitemyapp: rovar: too bad the docs don't have types :(

23:22 justin_smith: it's called a shibboleth. Genocidal semites are the first known group to utilize the concept.

23:22 justin_smith: "pronounce this properly, or die"

23:22 bitemyapp: justin_smith: in the original case, the word was shibboleth. The dirty foreigners would mispronounce it as "shibbolet" IIRC

23:22 TEttinger: it was a war not a genocide. besides god told them to do it

23:23 bitemyapp: TEttinger: it was genocide. Their god told them to kill all the women and children on pain of death.

23:23 justin_smith: http://www.prodogtivity.com/?dog=66 the cabbage barked in the wrong accent

23:23 bitemyapp: justin_smith: lollapalooza for the Japanese, Scheveningen was the word the Dutch used.

23:23 justin_smith: you're on a roll today.

23:24 (inc justin_smith)

23:24 lazybot: ⇒ 23

23:24 justin_smith: doges are always relevant

23:32 bitemyapp: shit_hn_says: Why the hell should I worry about text encoding before sending a string into a TCP socket...

23:32 gg wp

23:32 best troll #2013

23:40 alew: what's the idea behind b64 encoding?

23:41 justin_smith: alew: it doesn't use the 8th bit, so it can go over protocols like email unmolested

23:41 and has a trivial transformation to become arbitrary binary data again

23:42 probably it is mostly used for email attachments of binary data like images

23:43 or, back in the day, binary newsgroups on usenet (maybe that still exists?) would post pirated movies and music as base64 encoded usenet posts

23:45 also it gets (ab?)used to embed small images directly in the html of some web pages

23:45 alew: Interesting

23:46 seangrove: justin_smith: Also used by the old version of Selenium for taking screenshots

23:46 Might be used for the new one too, not sure

23:46 justin_smith: seangrove: so it can like put a screen shot in a log file or something?

23:46 rovar: if I define (def getvals (partial mapcat vals)) I can use it inside of a -> block.. but if I put (partial mapcat vals) inside the -> block, my result for the block is a partial function, which isn't what I was hoping for.

23:47 justin_smith: ((partial mapcat vals))

23:47 rovar: rovar then uses macroexpand, and he is enlightened

23:47 thanks.

23:47 justin_smith: np

23:48 TimMc: bitemyapp: I'll bite, what's wrong with that quote?

23:49 justin_smith: TimMc: well if you don't care about text encoding, you may as well ignore endianness too. And if you don't care about that, you could just request that the client generate some random numbers filling up the requisite amount of space and save bandwidth.

23:50 TimMc: Oh, character encodings, OK.

23:50 For some reason I was thinking about escaping/quoting.

23:51 justin_smith: on an abstract level these are similar things :)

23:51 TimMc: Like... certain characters that you couldn't transmit raw, or something (which didn't make sense to me.)

23:52 Yes, they are all concepts of embeddings.

23:52 justin_smith: and utf8 could be seen as using a reader macro on the byte stream level

23:53 everything is just regular 7 bit ascii until you hit the magic stuff then the rules change momentarily

23:54 rovar: (apply (partial merge-with list) (-> (get-in bar [:users "root" :items]) vals ((partial mapcat vals))))

23:54 bam

23:54 zippers.. pssh

23:54 justin_smith: nice

23:54 rovar: I guess I could partial the apply and put it into the ->

23:55 sometimes I miss auto-currying

23:56 (-> (get-in bar [:users "root" :items]) vals ((partial mapcat vals)) ((partial apply (partial merge-with list))) )

23:56 heh..

23:58 tpope: at that point just use ->>, no?

23:59 alew: you could just use as->

Logging service provided by n01se.net