#clojure log - Dec 08 2013

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

0:00 xpe: ,(class #{})

0:00 clojurebot: clojure.lang.PersistentHashSet

0:00 xpe: igorw that's why I was looking at hash values

0:00 justin_smith: ,(= (str 4) (str 4.0))

0:00 clojurebot: false

0:01 gdev: lol

0:01 igorw: note that this is double vs float, not double vs int

0:01 justin_smith: right, but just showing that my above even works with int vs. float

0:01 while str conversion does not

0:01 xpe: ,(= 0 0.0)

0:01 clojurebot: false

0:01 justin_smith: xpe ==

0:02 igorw: so single-element sets behave differently than multi-element?

0:02 justin_smith: ,(== 0 0.0)

0:02 clojurebot: true

0:02 justin_smith: igorw: in the sense that a single element set has only one ordering, yest :)

0:02 xpe: igorw: the semantics of = are different than ==

0:02 justin_smith: ,(every? #(apply == %) (map list (sort #{3 4}) (sort #{3.0 4.0}))) ; my final answer

0:02 clojurebot: true

0:03 xpe: if you use = to compare sets, it compares its elements with =

0:03 if you want to compare set elements with ==, I think you'll need to write your own thing

0:03 but you probably don't want to mix numeric types

0:03 justin_smith: xpe: or the one I just pasted

0:03 gdev: lol at the docstring for =

0:04 compares numbers and collections in a type-independent manner

0:04 xpe: "compares numbers and collections in a type-independent manner" I don't even know what that means

0:04 justin_smith: that needs a big † with a footnote

0:05 xpe: igorw: so THAT was fun, right?

0:05 justin_smith: ,(= [1 2 3] '(1 2 3)) ; xpe

0:05 clojurebot: true

0:06 gdev: yes, numbers and collections are treated type-independent, but collections that care about type with numbers...all bets are off

0:07 igorw: apart from using doubles everywhere, it's probably easiest just to sort the sets before comparing

0:07 thanks justin_smith! :)

0:07 xpe: igorw can't you just use doubles? is this an application or a library?

0:08 igorw: yeah, in this case I can do that

0:08 deadghost: http://pastebin.com/s4nhfKMH

0:08 I'm trying to get rid of (remove nil?

0:08 xpe: ~dotsmack =

0:08 clojurebot: excusez-moi

0:08 xpe: oops

0:08 ~docsmack =

0:08 clojurebot: Huh?

0:09 justin_smith: deadghost: why?

0:09 xpe: igorw: good. mixing floats and doubles sounds like heartache.

0:09 deadghost: justin_smith, because the code just juts out

0:10 xpe: deadghost: you want to remove it because it looks bad?

0:10 deadghost: and there might be a map function that omits nil that already exists

0:10 that I am not aware of

0:10 xpe yes

0:10 bellkev: I have a really newbie question... If I have a number n, is there an easier way to get its negative than (- 0 n) or (unchecked-negate-int n)?

0:11 xpe: deadghost you could use the threading macros if that looks better to you

0:11 justin_smith: (->> url get-listings (map #(when (has-no-website? %) (collect-listing-data %))) (remove nil?))

0:11 it indents nicer

0:11 xpe: ,(let [n 2] (- n))

0:11 clojurebot: -2

0:11 justin_smith: and is arguably a bit simpler

0:11 (to read that is)

0:12 xpe: bellkev ^

0:12 justin_smith: ,(- -1)

0:12 clojurebot: 1

0:13 bellkev: ah, that'll do

0:13 thanks

0:19 xpe: ,(#(nth (iterate - %) (dec (Math/pow 2 10))) 3) ; negate 3

0:19 clojurebot: -3

0:19 xpe: bellkev: in case you want a computationally inefficient version

0:20 bellkev: yes, definitely, thank you

0:20 xpe: it has the advantage of writing values all over the heap too

0:20 actually... not sure about that

0:20 bellkev: Or, of course I could always just multiply by exp(pi * i)...

0:21 xpe: bellkev: i imagine so, yes

0:22 arrdem: gdev: got 10 to read something?

0:22 gdev: arrdem, sure

0:23 amalloy: ,(doc keep) deadghost

0:23 clojurebot: "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects."

0:26 deadghost: amalloy, perfect

0:53 gabe_hollombe: Hey folks, is the Clojure Google group an appropriate place to ask for feedback on my answers to some Clojure exercises? E.g. is my code idiomatic, how can it be improved, etc.

0:58 hyPiRion: yeah. If it's small code snippets, people tend to help out here too

1:01 arrdem: drop a refheap/gist link in channel and odds are someone'll read it and comment

1:07 gdev: gabe_hollombe, don't forget to run it through kibit first https://github.com/jonase/kibit

1:07 gabe_hollombe: thanks hyPiRion arrdem gdev

1:08 Raynes: arrdem: Clearly you ordered those in order of how much you're deeply in love with the authors.

1:09 arrdem: Raynes: what'd I do?

1:10 andyf: arrdem: Nothing, except talk when Raynes was feeling punchy.

1:11 Raynes: I wasn't... what

1:11 arrdem: I was asserting that you love me more than the gist developer.s

1:12 developers.*

1:12 arrdem: Raynes: ah. that is entirely false... I can't M-x gist-paste-buffer that I know of..

1:12 Raynes: $google defunkt gist

1:12 lazybot: [defunkt/gist · GitHub] https://github.com/defunkt/gist

1:13 Raynes: arrdem: ^ :'(

1:13 arrdem: Raynes: it's OK. I'll still spam you with stacktraces :D

1:13 Raynes: <3

1:13 But now I'm worried I've said terrible things to andyf though.

1:14 His discontent seemed pretty sincere.

1:14 andyf: Raynes: I'm not offended at all. Just (poorly) trying to inject some levity.

1:14 Raynes: Oh, good.

1:15 Well, apologies for messing up the levity with insincerity then :)

1:15 Er, insecurity*

1:15 andyf: I can mess up levity all by myself, thank you :-)

1:15 arrdem: (inc Raynes) ;; here take some karma, it helps

1:15 lazybot: ⇒ 38

1:15 arrdem: mother of god

1:16 Raynes: dear sir, with a channel karma that high how dare you feel insecure

1:16 $karma technomancy

1:16 lazybot: technomancy has karma 87.

1:16 Raynes: dat technomancy

1:16 arrdem: okay. all is still right with the world.

1:16 Raynes: My karma is proportionate to what I've contributed to Leiningen.

1:17 lein new, lein repl (well, the first lein 2 draft of it)...

1:18 lein test :only foo.bar/baz is by far the greatest feat of over-engineering that I have accomplished at the behest of technomancy in the history of time :P

1:18 I forget if anyone ever actually used that feature for anything other than :only.

1:18 I don't think so though.

1:19 mysamdog: I can't seem to find any information about events in dommy. How would I go about detecting if an element was clicked?

1:20 nvm

1:21 I found it

1:21 arrdem: Raynes: is there some awesomeness lurking there unused?

1:21 Raynes: or just code of adamantium

1:22 Raynes: arrdem: They are test selectors. You can select tests based on arbitrary function calls.

1:22 hyPiRion: $karma hyPiRion

1:22 lazybot: hyPiRion has karma 25.

1:22 Raynes: In this case :only refers to a built-in one of those functions for selecting only one test.

1:22 At least, that's how I remember it.

1:23 also: is there a way to exclude a direct dependency using a leiningen profile?

1:23 Raynes: This really was ages ago.

1:24 arrdem: also: what do you mean by that? a dependency elsewhere in the filesystem for instance?

1:24 seancorfield: Raynes: I wonder if the lein test stuff could be abstracted so it could drive Expectations and Midje through higher-order tasks? Then :only and its ilk could be more widely applicable...

1:25 Raynes: Hahaha, you want to abstract test selectors even more!?!?! Goodness, Sean, there be dragons.

1:25 also: arrdem: i have a dependency on instaparse that i want to exclude for cljs builds

1:26 so that i can use a clojurescript port of instaparse, but only for the cljs build

1:26 arrdem: also: I know vanishingly little about the tooling around cljs. I'm not your man, sorry.

1:26 seancorfield: Raynes: it's selfish - I primarily use Expectations and it seems a waste to see work duplicated across multiple lein test-ish plugins :)

1:26 also: i was thinking this wouldn't be cljs specific

1:26 seancorfield: and I know the Midje diehards would appreciate it too

1:27 Raynes: Yeah, there is certainly still room for improvement in lein test.

1:27 justin_smith: there are midje diehards?

1:27 Raynes: alexbaranosky

1:27 And presumably Brian Marick.

1:27 arrdem: I use clojure.test....

1:27 Raynes: At least. Those are two concrete examples I can think of.

1:27 seancorfield: We do use clojure.test, but only in conjunction with clj-webdriver for more procedural tests... for general tests we prefer the more declarative approach of Expectations

1:27 Raynes: seancorfield: I think people avoid touching lein test like the plague because of clojure.test being so difficult to work with and extend.

1:27 arrdem: also: there isn't a cljs port of instaparse yet.

1:28 also: you're gonna have a bad time

1:28 seancorfield: pretty sure [Neurotic] uses Midje too?

1:28 Raynes: Lots of people use it, justin_smith was being silly :p

1:28 justin_smith: Raynes: for caribou-core we use clojure.test with keyword selectors

1:28 via lein test

1:28 also: arrdem: https://github.com/Engelberg/instaparse/pull/50

1:29 seancorfield: for me, Midje has too much magic and is a whole new language to learn... but it's certainly an impressive project

1:30 arrdem: also: yeah that's a port in progress. Trying to build atop that would take a very brave individual.

1:30 also: arrdem: and fixed slightly here: https://github.com/also/instaparse/commits/cljs

1:30 Raynes: seancorfield: I use it in a few projects. Laser, notably.

1:30 clojurebot: No entiendo

1:30 Raynes: Pending a rewrite of the tests with clojure.test.

1:31 Just because I don't really have one single good reason to use midje other than to be loldifferent.

1:31 also: arrdem: brave isn't the word i'd have chosen :)

1:31 Raynes: I'm sure there are people using midje for things it is actually useful for, I'm just not one of them. :)

1:31 arrdem: also: insane and foolhardy spring to mind, but you seem to have taken on the challenge so good on ya

1:32 also: arrdem: it works for my simple parser, although generating the parser is too slow to do in clojurescript

2:56 gabe_hollombe: I'm very new to Clojure, and just finished the simple exercises from Kyle Kingsbury's _Clojure from the Ground Up_ chapter on sequences. I'm wondering if I wrote things in an idiomatic / sane fashion. If anyone would like to take a look at ~30 lines and provide feedback, I'd be totally grateful. https://gist.github.com/gabehollombe/7854417

2:59 n_b: gabe_hollombe: for line 16 I might do ,(-> "abracadabra" frequencies \c)

3:00 gabe_hollombe: n_b: I'm not familiar with the (-> …) syntax yet. Can you re-write that as an expression?

3:01 n_b: ((frequencies "abracadabra") \c)

3:02 gabe_hollombe: ahh. I was trying (\c (frequencies "abracadabra"))

3:02 =-)

3:02 n_b: It's slightly more expensive, I imagine, but it makes it clealer what you're trying to accomplish IMO

3:03 gabe_hollombe: yeah. I like it. ty for the tip on frequencies =-)

3:05 n_b: If you haven't found it yet, http://clojure.org/cheatsheet is kept open on a monitor always

3:05 gabe_hollombe: n_b: Yes. I should look at it more often as I learn

3:08 * arrdem misses having three monitors and being able to give one to the cheatsheet

3:16 hydromet: hello

3:17 A friend and I are planning on learning Clojure together!

3:17 My friend is an undergrad student in math / finance and has only learned Fortran (but also has been working with MySQL databases)

3:18 I've learned more languages in the past (C, Objective-C, Ruby)

3:18 Given how much of a newbie my friend is to programming in general, I'm wondering what book we should start with for learning Clojure?

3:27 hyPiRion: I'd guess "Clojure Programming". That seems to be a solid book overall, although I don't know whether it fits for people new to programming

3:28 Finding a good book for people new to programming AND Clojure seems to be hard

3:28 (read: Noone has written a book aimed for that group of people)

3:29 arrdem: hydromet: I'd say go pick up "Structure and Interpretation of Computer Programs" if you're looking for the go-to lisp intro book

3:30 hydromet: if you're looking for a somewhat technical clojure intro "Clojure Programming" is good

3:30 hydromet: "The Joy of Clojure" really goes in depth on good design in Clojure

3:31 hydromet: arrdem: thank you for the suggestions

3:32 arrdem: I had looked at the preface / intro on "Clojure Programming" and my only concern, for my friend who only knows Fortran, the that this book apparently uses comparisons to object oriented languages such as Java, Python and Ruby

3:33 arrdem: hydromet: yeah that's gonna be a stumbling block.

3:33 well... actually...

3:34 hydromet: arrdem: in some respects my friend might have an advantage learning Clojure (since he doesn't have years of OOP which might require him to "detach" from when it comes to Clojure)

3:34 arrdem: hyPiRion: is that really gonna be an issue? Clojure hides a lot of the OOP stuff pretty well...

3:34 hydromet: arrdem: whereas for me, I might have more to "unlearn" :)

3:34 hyPiRion: arrdem: I'm not sure, I've not read a Clojure book as a beginner

3:35 arrdem: hydromet: the real mind-bender of learning clojure isn't so much unlearning OOP, it's unlearning state. That threw me for a solid loop for about two months :/

3:35 hyPiRion: But yeah, learning Clojure isn't hard, unlearning mutation is.

3:35 gabe_hollombe: hyPiRion++

3:35 arrdem: gabe_hollombe: that's (inc hyPiRion)

3:36 gabe_hollombe: aaroncm: =-D

3:36 old habits

3:36 arrdem: gabe_hollombe: heh

3:36 gabe_hollombe: I was trying to make hyPiRion's point

3:36 hyPiRion: hehe

3:37 hydromet: arrdem: and hyPiRion: good points, thank you for sharing your views ... not so much about unlearning OOP but more so about state and mutation

3:38 gabe_hollombe: hydromet: there's also sicpinclojure.com

3:38 hydromet: and for my friend, his brief experience with Fortran probably means he might get thrown for a loop at first

3:38 gabe_hollombe: it's a work in progress

3:39 hydromet: but I've read enough about Clojure at a high level and understand some of the abstracts with regard to state / mutation (and thus he idea of snapshots in time) so I think I will be able to help mentor my friend to a certain extent

3:39 arrdem: hydromet: in all seriousness, don't undervalue or underuse this channel

3:40 hydromet: these guys saved my arse a bunch of times as I was getting started. you'd be surprised what'll get a well considered answer here.

3:40 hydromet: gabe_hollombe: thank you for noting sicpinclojure.com - I just had a quick scan of it, looks really nice!

3:41 arrdem: that's great, thank you for the suggestion! I've heard great things about the Clojure community

3:41 arrdem: ~clojure

3:41 clojurebot: "[Clojure ...] feels like a general-purpose language beamed back from the near future."

3:41 hydromet: I had the pleasure of attending a presentation last year in Chicago of Rich Hickey's - he was talking about data (not Clojure) but I was very inspired by his presentation!

3:43 xpika: can someone tell me a function to covert a symbol to a string?

3:43 hydromet: Also, I was thinking my friend and I would start out playing with Clojure by using Light Table.

3:44 gabe_hollombe: hydromet: I'm learning clojure myself. also using LightTable. I'm a hardcore Vim-er, but I'm finding LT's insta-repl buffer mode pretty nice

3:45 as I get more comfortable, I suspect I'll move back to Vim and take the time to learn paredit properly

3:47 hydromet: gabe_hollombe: glad to hear you're enjoying Light Table so far. Neither my friend or I have any experience with Vim or Emacs. We can perhaps climb those tools' learning curve later, I don't want my friend to feel overwhelmed (he also has a heavy load of classes next semester)

3:49 arrdem: hyPiRion: what was the motivation for astyx? seems like tools.reader could do the same job...

3:49 not that I don't like writing parsers too, I'm just curious

3:51 john2x: xpika: ,(name :foo)

3:51 hyPiRion: arrdem: It was mainly just because I wanted to play with instaparse, and I was a bit curious finding some sort of pattern on the legal keywords/symbols

3:51 john2x: (name 'foo) :P

3:51 hyPiRion: It's not meant to be something you consume, I just dumped it up on github for convenience reasons really

3:52 m0g: I'm trying to generate a pom from a project.clj file and I can't get the plugin syntax straight. Any hint? https://gist.github.com/m09/7854791

3:52 Specifically it doesn't nest manifest into archive

3:53 arrdem: hyPiRion: gotcha.

4:04 m0g: hum the syntax doesn't allow my use case atm actually.

4:04 clojurebot: Titim gan éirí ort.

5:26 cYmen: morning

5:36 d11wtq: Is there any convention with regards to the prefixes "new-" and "create-" for functions that return specialized data-structures? A quick check with apropos shows both variants are used.

5:38 Actually, scratch that. "create-" seems to be the convention for initializing a data structure.

6:06 tufflax: http://stackoverflow.com/questions/20448448/can-this-clojure-code-be-optimized

8:38 foobar27: hi, are there any experts of cc.qbits/hayt hanging around here? (the CQL library used in alia, cassaforte and casyn)

8:48 deadghost: say I have '(1 2 3)

8:48 and I wanted to pass 1 2 3 into a function

8:49 is there an easy way to strip the list

8:52 oriig: deadghost: use apply

8:52 foobar27: deadghost: you probably want (apply f '(1 2 3))

8:52 Okasu: deadghost: (apply #'f '(1 2 3))

8:54 deadghost: hmm ok

8:54 works for me

8:56 hmm wait no, no it doesn't

8:58 foobar27: deadghost: can you post a short failing example?

8:58 (e.g. on refheap.com)

8:58 deadghost: not so much failing as I don't think apply would be appropriate here

8:59 foobar27: what to you want to do?

8:59 deadghost: http://pastebin.com/5K3QMsvu

8:59 so I'm passing in an arbitrary number of selectors

9:00 :ul.colors :li :a for example

9:00 and since it's & it gets packed into a list

9:00 when I want it to look like [:ul.colors :li :a html/text-node] in the body

9:01 foobar27: I don't fully understand the situation yet

9:01 but does the following work? (html/select node (concat selector [html/text-node]))

9:02 justin_smith: deadghost: can you show the erroneous output? I think what you want is mapcat

9:02 instead of map, but I can't know that until I see the output you don't like

9:18 deadghost: foobar27, works with (html/select node (into [] (concat selector [html/text-node])))

9:18 more verbose than I'd like but at least it's working

9:37 justin_smith: (def concatv (comp #(into [] %) concat))

9:37 that will make it less verbose

9:37 and you will likely find other places to use it

9:49 deadghost: justin_smith, will do though I still suspect there are cleaner ways

9:50 justin_smith: the cleaner way would be for the function you call not to require a vector - but if it needs one then why not have a strightforward way to construct it

9:56 deadghost: justin_smith, that's how it is from the library I nabbed

9:56 I'm thinking macro usage might be warranted here

9:58 actually that's probably overkill for some verbosity

10:07 pepijndevos: hmmm, dorothy, rhizome and lacij seem like very similar projects. any recommendations?

10:10 justin_smith: pepijndevos: first glance, rhizome is likely better, because the author writes good stuff

10:11 pepijndevos: lol

10:11 justin_smith: maybe someone has a more informed opinion, but that is my hunch

10:29 pepijndevos: whats the deal with this pedestal thing?

10:37 justin_smith: it is an end to end webapp stack with an unusual / experimental design

10:37 from what I hear it is cool if you want to do a one page webapp and do every part of it in clojure

11:36 logic_prog: is there a way to change the way atoms are displayed

11:36 i.e. I'd like to have atoms show up as #atom ... rather than have clojure de-ref the atom and print it

11:38 bbloom_: logic_prog: you can redefine the print-method, but be aware that affects all other code that may print something, so you should only do it in your local repl & not in library code

11:38 logic_prog: actually, what I want is:

11:38 (set *print-level* 10)

11:38 since the real problem (which I did not mention in my question) is cycles in atoms

11:38 i.e. I had problem X, but asked about problem Y.

11:39 sorry about that.

11:39 coventry: logic_prog: Have a look at the print-method defmethods in https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj#L104

11:39 bbloom_: logic_prog: alternative advice: get rid of your cycles

11:39 use an extra indirection, such as an id number or symbol

11:39 logic_prog: I can't

11:40 I have "objects" and "listeners"

11:40 objects need a list of listeners that are listening to the object; and listeneres need a list of objects they're listening to

11:40 boom, cycle!

11:40 I'd love to kill this cycle

11:40 bbloom_: further advice: don't do that at all :-)

11:40 but i can't provide an alternative b/c this is an open research problem heh

11:40 logic_prog: bbloom_: how should I solve this problem instead?

11:40 bbloom_: step waaaay back, what are you trying to accomplish?

11:41 logic_prog: real time shared objects in clojure+clojurescript

11:41 I have websockets set up, when a user makes a change, I want all other clojurescript clients to get updates

11:41 thus, I have an "object" and "listenres" (which are websocket + clojurescript)

11:42 objects need a list of listeners (so that when an object changes, it can tell all websockets "hey, dude, update shit")

11:42 listeners need a list of objects, so that when they close, I can tell it to unregister

11:43 seangrove: Why do objects need a list of their listeners?

11:43 Why not use a third-party queue?

11:43 bbloom_: so worth pointing out: once you attach listeners to objects, you've added a ref-counting scheme

11:43 logic_prog: so taht when I send an dojbect a "update" message, it can send it to all listeners

11:44 bbloom_: so if you're already doing manual memory management, you might as well store listeners in external state (such as a top level atom)

11:44 seangrove: Yeah, I was basically going to build up to the idea bbloom_ is proposing

11:44 justin_smith: logic_prog: you could add a level of indirection, a map of unique id to object, another mapping of unique id to listener, and have each store the id and manually look up the value when needed

11:44 classic cycle-flattening technique

11:44 bbloom_: however, let's go further back: why do you want to do this at all?

11:44 logic_prog: bbloom_; I'm writing a real time svg editor

11:44 client side = clojurescript, server ide = clojure

11:45 bbloom_: what data is being synchronized between client and server?

11:45 logic_prog: the "svg document" is a "shared object", so taht when a client updates it, all clients get updates

11:45 things like "add this rectagnle; move that rectangle; delete this circle"

11:45 "diffs" to the svg document

11:45 bbloom_: yeah, don't use mutable/synchronized objects

11:46 use a queue. read about http://en.wikipedia.org/wiki/Operational_transformation

11:46 logic_prog: okay

11:46 what shoudl I be using isntead?

11:46 holy shit

11:46 I should read about that

11:46 it evenworks for google docs

11:46 probably good enough for me

11:47 seangrove: hah

11:47 bbloom_: then also read this: http://awelonblue.wordpress.com/2012/07/01/why-not-events/ -- then ignore its aguments, b/c anything beyond what he's saying is an open research problem. it's just worth understanding the shortcomings

11:47 entertainingly i just linked that on twitter too. i find myself thinking about that post pretty frequently :-P

11:47 anyway, cycles are pretty much 100% of the time a bad thing

11:47 sorry, i mean POINTER cycles

11:48 you may have cyclic relationships in your data, but if you have a pointer cycle you've got aproblem

11:48 you need an extra indirection so that you can make incremental, structural sharing changes to an object w/o having to copy the complete pointer graph

11:48 haskell allows cyclic lazy objects & they are prod of that, but it's a major anti-feature

11:48 s/prod/proud

11:49 justin_smith: bbloom_: that's what I was getting at with the map of id to listener / map of id to object suggestion

11:49 there is probably a name for that transformation

11:49 bbloom_: it sounds like he has only one object tho: the SVG document

11:49 which might have a change log on it too

11:49 justin_smith: svg has g in it

11:50 seangrove: bbloom_: Interesting that the author points out pi-calculus and csp as failures as well

11:50 bbloom_: seangrove: i don't think he said they are failures, he said we can do better

11:51 seangrove: also if you look at the comments, you'll see that i argue in favor of event systems in non-distributed contexts

11:52 seangrove: bbloom_: Still reading through. Interesting points, but I certainly hope he proposes something mind-blowing

11:52 jtoy: can I just do lein install of a project I hav and then from another repo how would I install it?

11:53 bbloom_: seangrove: he proposes many many different ideas over the course of many future rambling blog posts of varying value

11:59 logic_prog: okay fuck it

11:59 cycles are dead

11:59 bbloom_: w00t

11:59 logic_prog: and now, my code also no longer works :-)

12:00 jtoy: it seems like that doest work, i need to do something else to use a locally installed jar

12:02 logic_prog: okay, works now :-)

12:08 justin_smith: jtoy: you should be able to declare it like any other dependency

12:08 check that what you put in the dependencies in the project using it exactly matches the project / version in the one you lein installed

12:08 amak: cider is not in marmelade

12:09 justin_smith: the latest version is broken in marmelade, there is a discussion of this on the clojure-emacs github

12:09 you can package-install out of a git repo

12:25 jtoy: justin_smith: I tried a few different ways, I did lein install for my library A then added the same dependency name as what i had in library A into app B and I see that it fails to find the library, then I also tried uplpoading jar A and pom A to an s3 repository and then just try to start B and it fails

12:25 coventry: amak: Just use nrepl.el for now.

12:25 amak: coventry: why?

12:27 justin_smith: jtoy: weird, I use lein install followed by requiring the resulting lib very frequently

12:27 to double check things are good before lein push

12:28 or to make a temporary replacement for a lib to check a bug fix

12:28 are you sure the name and version strings are an exact match?

12:29 jtoy: justin_smith: do you need to modify the dependencies in project to do this? yes, they are the same string, jst double checked: toy-app "0.0.1" and [toy-app "0.0.1"]

12:30 justin_smith: no group string

12:30 like group/toy-app

12:31 and this is all on the same machine?

12:31 jtoy: justin_smith: what do you mean by group? I need to change my app to be in a group?

12:31 yes, all on the same machine

12:31 justin_smith: just double checking it wasn't jtoy/toy-app on one side and just toy-app on the other

12:32 amak: ella loads all the packages in .emacs.d/elpa/?

12:32 *elpa*

12:32 justin_smith: jtoy: because if those things match you should be able to require the other lib and access its code

12:32 just like any other dep

12:33 because lein install puts things in the same place it would put a remote dep, the resolution method is identical

12:34 jtoy: I think I found the issue, im still investigating

12:34 justin_smith: also double check the pom.xml in ~/.m2/... and be sure that it reflects what you would expect to find

12:37 jtoy: justin_smith: yes, I did find the error, but I just found anohter issue, in my library A, i referencea class C, that C exists in project B which I am trying to run, i cant do this?

12:38 it looks like I cant creat a lib A that references C and in my project B have a dependency for A while having the soruce for B in my project

12:39 I mean "having the source for C in my project"

12:41 is it possible to use libraries in clojure that have functions that can call functions from your own code?

12:42 AimHere: jtoy: if you're having to write that, you're probably not structuring your code properly

12:44 jtoy: AimHere: for instance I have some generic data-creation functions, I want to add a callback so I can add some customizations, before I just had my library call src/templates/callbacks.clj and I would customize only that for each project

12:44 how can I achieve this while being able to keep all the library code seperate ?

12:55 justin_smith: jtoy: define a protocol or interface

12:56 have the underlying code call the methods of the protocol/interface and get an instance passed in

12:56 jtoy: justin_smith: how would the library code know what to call though?

12:56 justin_smith: the calling code defines the class implementing it

12:56 because you passed it in so it could be bound

12:56 (lib/init-<whatever> my-instance)

12:56 for example

12:57 better yet, never let the underlying code create or store the instance, only let it be passed in

12:57 because the caller should own the object anyway

12:57 jtoy: do you know of any good tutorials on this? I havve read a lot about protocol/interfaces but hav not used them

12:58 I thiml the way I structured my code is completely wrong

12:58 justin_smith: http://blog.josephwilk.net/clojure/isolating-external-dependencies-in-clojure.html

12:59 jtoy: it takes a while to get the design of user / lib interaction exactly right without globals or dependency loops

13:01 he is mostly talking about testing in that article above, but the same concerns apply for lib / user dependency isolation too

13:01 jtoy: justin_smith: I agree! thanks, I am reading it all in detail, I think I see how to modify my stuff

13:04 justin_smith: http://tech.puredanger.com/2010/03/01/dependency-injection-clojure/ also see the comments on this post (and enough of the post to see the context)

13:07 coventry: amak: So you don't have to deal with those kinds of failures.

13:07 amak: coventry: i was able to install cider

13:07 melba has the pakage

13:07 melpa

13:08 jtoy: justin_smith: can I turn a whole namespace into a defprotocol and then override a couple of functions?

13:08 it seems like I just need good old fashioned OOP :)

13:09 justin_smith: jtoy: one sec, I have a recent example

13:10 https://github.com/caribou/caribou-plugin/blob/master/src/caribou/plugin/protocol.clj I have the protocol, then I define make, which merges the overrides the user wants with the default / identity / null versions

13:11 jtoy: justin_smith: excellent, I can implement it similiar to this

13:12 thx

13:12 justin_smith: np

13:13 arrdem: (inc justin_smith)

13:13 lazybot: ⇒ 17

14:08 gfredericks: does test.generative offer anything over simplecheck?

14:09 bbloom_: gfredericks: <insert standard comparison instead of competition comment>

14:10 "how do test.generative and simplecheck differ?"

14:10 not that i have an answer for you :-)

14:11 gfredericks: I'm curious now that simplecheck is getting contribb'd

14:12 seems weird if one lib is a superset of another

14:21 bellkev: has anyone had issues with lein-cljsbuild just hanging for a long time when running a build task?

14:23 oh, nvm! Looks like it wasn't compiling anything because all I did was stop the auto building, change the optimization settings, and restart, and none of the source files changed so it wasn't rebuilding....

14:23 dnolen: bellkev: yeah easy to get tripped up by that one

14:23 seangrov`: bellkev: Yeah, I always do `lein cljsbuild clean; lein cljsbuild whatever` because of that

14:23 bellkev: Either an "all files up-to-date" message on startup, or settings changes triggering rebuilds could be nice...

14:35 gdev: I'm so confused by Quil's random function. couldn't figure out why I was getting an NPE, then I look at source and realized it tries to pass in the current applet. since i was just testing from the repl i had no applet

14:35 explains the NPE, but not the reason why it requires an applet just to give me a random number

14:36 seangrov`: gdev: Maybe some Java interop artifact?

14:41 gdev: seangrov`, that's what I thought too. first place I looked was the javadoc for the processing library. Even the java version doesn't require an applet

14:47 seangrov`: Hrm, what's the straightforward way do a depth-first travesal of a datastructure and pull out the first element? clojure.walk?

14:53 jonasen: seangrov`: If you want the leftmost leaf then maybe (first (tree-seq ...))

14:53 coventry: Something like (->> [[[[[[[1]]]]]]] (iterate first) (take-while sequential?) last first)?

14:54 seangrov`: jonasen coventry: I think I may be missing a better approach. I'm actually trying to transform/expand a datastructure out https://www.refheap.com/21603

14:55 I'd like to work from the leaves inward, expanding each tag until it reaches a terminal state

14:55 Seems like I might want clojure.walk/postwalk here....

14:55 jonasen: seangrov`: yes, I think so too

14:58 (postwalk #(if (number? %) (inc %) %) widget) will inc the two numbers

15:04 seangrov`: Strangely, it seems like postwalk will visit a hashmap twice - once as a vectory, and then once as a map

15:04 Ah, I guess that's not strange, it's just recursively walking the map as well

15:05 Would be nice to know if the value I'm transforming is inside a map though....

15:09 ihvjfb8a74htkgbi: YOU MAY BE WATCHED





15:10 coventry: seangrov: I think the vectors you're seeing are MapEntries.

15:11 In which case you can tell by inspecting the type.

15:12 seangrov`: coventry: Interesting, let me check

15:13 Loosk like (type ...) just returns a clojure.lang.PersistentVector

15:13 Not too worries about it though, just prototyping something that can be dirty for now

15:16 coventry: Oh, right, I'm mostly using clojure.walk2. That will give you MapEntries, clojure.walk just gives you PersistentVectors.

15:21 * seangrov` goes off and checks walk2

15:22 logic_prog: in core.async, alts! claims to be _non-deterministic_ when multiple channels are ready. However, I don't want it to be non-deterministic. I want it to be a FIFO -- I want to merge the channels based on the time when they're ready. (i.e. imagine two channels, one = key_down events, two = key_up events) -- I wnat the two channels to be mixed based on the time the events happen

15:23 bbloom_: logic_prog: if you add a buffer, it will be FIFO until the buffer is full

15:23 logic_prog: wait, sorry

15:24 suppose I have key_down_A key_up_A keydown_B

15:24 what prevents the mixin from giving me: "key_downA key_down_B key_up_A" ?

15:24 bbloom_: logic_prog: but you actually DO want non-determinism, even when the underlying mechanism is deterministic. core.async injects added randomness to preserve the non-determinism b/c the precise mechanical evaluation order of co-occurring message sends is an implementation detail of the ordering of your code

15:24 logic_prog: i dunno what you mean by "mixin"

15:24 logic_prog: channels are like queues: they are FIFO

15:24 logic_prog: sorry, by mixin I mean alt!

15:24 seangrov`: coventry: That switch worked, thanks

15:24 bbloom_: the nondeterminism only occurs when multiplexing

15:25 logic_prog: so I'm using clojurescript, and I'm using listeners, so I have channel1 = listen :keydown, channel2 = listen :kenup

15:25 and now, I want to merge channel1 and channel2 into one channel that has all key-events

15:25 bbloom_: why two different channels?

15:25 logic_prog: because goog.listen

15:25 bbloom_: they can put on to the same channel

15:26 logic_prog: hmm

15:26 also: if you need them in separate channels, split them out later

15:26 bbloom_: you're using put! with a listen?

15:26 logic_prog: I'm a dumbass

15:26 seangrov`: logic_prog: I just use a little (utils/relay target-ch event-name) as my callback handler

15:27 bbloom_: a put! will essentially create an unbounded buffer, but internally in all realistic js engines, the events will be processed internally in the correct order, so you're ok

15:27 logic_prog: does put! never block?

15:28 bbloom_: put! is the non-blocking primitive underlying >! -- it will use a setTimeout-like mechanism to enqueue in to the system event bus

15:28 (if it has to)

15:29 logic_prog: suppose I do (let [out (chan 100)]

15:29 what happens to a put! if there is already 100 elements

15:29 does it not block?

15:30 coventry: seangrov`: NP. The only drawback I've run into with walk2 is that there's no canonical jar for it.

15:40 justin_smith: https://github.com/caribou/clojure.walk2 we track the upstream, though upstream took all their jars back

15:41 seangrov`: justin_smith: took their jars back?

15:41 justin_smith: clojure.walk2 decided to unpublish all extent jars, but we have a caribou jar of it with the same code

15:42 https://github.com/caribou/clojure.walk2/compare/stuartsierra:master...master

15:43 coventry: Yeah, I use the caribou one. Not much of a drawback.

15:52 rovar: ArityException Wrong number of args (1) passed to: core$fn--666$fn clojure.lang.AFn.throwArity (AFn.java:437)

15:52 anyone have any ideas as to how I could discover what core$fn--666$fn is?

15:53 justin_smith: in core, name your anonymous functions

15:53 TEttinger: rovar, it's an anonymous fn. such as one created with #()

15:53 justin_smith: (fn what-this-does [arg]...)

15:53 rovar: yea..

15:53 justin_smith: and replace #() with the above too :)

15:53 the optional name arg to fn makes that so much easier to track down

15:53 TEttinger: yep.

15:54 goraci: hi is there something like update in datomic )? we store facts usually, so update is the new fact it appears

15:54 TEttinger: it sounds like it's the kind of error I have gotten using #() with no % in it with map

15:54 rovar: https://gist.github.com/anonymous/7863679

15:55 oh.. i just found the answer..

15:55 actually.. nevermind

15:55 that gist doesn't include me already fixing that bug

15:57 https://gist.github.com/rrichardson/7863716

15:57 there isn't much in the way of anonymous functions there.. though I don't know how multimethod is implemented

15:58 the pieces all seem to wor..

15:58 work

15:59 TEttinger: try naming the fn on line 1

15:59 (defmulti send-multi (fn is-this-the-problem [msg] (-> msg :action keyword)))

15:59 amalloy: rovar: i bet if you restart your repl it will work

16:00 or just (def send-multi nil) and then re-eval it

16:00 defmulti has defonce semantics, so you probably have a stale dispatch function from earlier

16:00 rovar: oh interesting..

16:00 amalloy: yes, it's horrible

16:00 rovar: i guess that makes sense

16:02 cYmen: When should I use letfn over let?

16:02 rovar: the def nil fixed it

16:02 cYmen, when you have a list of inner functions to define

16:02 and are too lazy to type (let [myfn (fn [foo] ...

16:04 ticking: cYmen, rovar afaik, letfn has the additional property of making the functions available in all other function bodies

16:04 justin_smith: rovar: cYmen: it allows mutual recursion

16:04 which does not work with let

16:06 cYmen: ah okay

16:06 ticking: Am I the only one feeling that lighttable does more harm than good to the clojure ide ecosystem? Nobody starts something similar because it is always looming on the horizon.

16:07 rovar: ticking, I dunno, I like lighttable, but frankly I prefer vim with tim pope's clojure plugins

16:07 logic_prog: not emacs?

16:07 I used vim for 15 years.

16:07 clojure converted me to emacs.

16:07 bja: ticking: lighttable + plugins seems interesting

16:07 rovar: haven't needed it so far

16:08 logic_prog: emacs is like flying

16:08 bja: vim + vimux + vim-sexp has been good enough for me

16:08 logic_prog: those on land are happy with traveling on land

16:08 but those that have flown can never go back to land again

16:08 bja: for cljs, clj, python, etc

16:08 rovar: I started on emacs, but in my work I always seem to be ssh'ing to a machine that only has vi/vim

16:08 so I don't fight it

16:09 ticking: bja, yeah but it looks like LT looses more and more clojure background, plugin maps are json instead of edn, most plugins are written in js not cljs

16:09 amalloy: rovar: tramp?

16:10 cljr: is anytone here familiar with alpeh?

16:10 bja: ticking: why does it matter though? I can write my plugins in cljs if I want

16:10 amalloy: ~anyone

16:10 bja: and it has nrepl support

16:10 clojurebot: anyone is anybody

16:10 amalloy: clojurebot: forget anyone |is| anybody

16:10 clojurebot: I forgot that anyone is anybody

16:10 amalloy: ~anyone

16:10 clojurebot: anyone is anybody

16:10 amalloy: ugh

16:10 cljr: umm ha?

16:11 i dont know what just happpened :)_

16:11 rovar: amalloy, I'm rarely ssh'ing over just to edit files..

16:11 I've not needed repl in vim, I have a screen full of repls in a tiling wm

16:11 amalloy: cljr: i was trying to evoke the clojurebot factoid that tells you not to ask "does anybody know about _____", but instead just ask your real question

16:11 rovar: I can evaluate expressions if I need to..

16:11 seangrov`: ask?

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

16:11 amalloy: not bad

16:12 ticking: bja, yeah, but it seems that instead of becoming a good clojure ditor first, they choose to become a mediocre general pupose one, the BOT stuff is also hard to see in recent lugin developments

16:13 rovar: maybe I'll muck about with tramp

16:14 bja: writing stuff in clj/cljs only really matters for doing clj development though. like, it's a lot easier to write code to edit/modify clojure in clojure than in something else. That said, it doesn't matter a whole lot since you probably want to just be writing most of that kind of stuff as nrepl middleware and just calling it from your editor.

16:14 ticking: bja, the entire LT-Mailinglist is always enthusiastic and dreams of the highest goals, yet nobody takes the time to implement something, there are top 10 wishlists for plugins, but only 1 person who wrote one (in js)

16:15 bja, if it had een open source from the start people could have participated but now all it does is binding resouces trhough anticipation of greener grass

16:16 bja, yeah doing most of the stuff as middleware makes sense, yet something for the general editing chores, that is a little more modern than emacs would be nice

16:17 amalloy: rovar: you can tramp over, and M-x shell opens a remote shell instead of a local one

16:18 justin_smith: more modern than emacs is a low bar - emacs still thinks windows are inside frames (all for historical reasons)

16:18 rovar: amalloy, yea, that is useful.

16:18 amalloy, I need to figure out how to just boot into emacs

16:19 to hell with the rest of the useless operating system.

16:19 ticking: rovar, unix haters handbook?^^

16:20 bja: ticking: I can't say that I really want/need more than vim+vimux and something like Hy to let me write vim plugins

16:21 which is what I use now. LT is still missing too much stuff (git and diffing being huge) for me to want to use it

16:21 ticking: bja, yeah but the inital light table concepts looked nice, structural editing would be cool

16:21 bja: ticking: it has structural editing

16:22 ticking: bja, real structural editing or pseudo?

16:22 cljr: is there a "reload" to compliemtn require or does require do reloadin?

16:22 bja: ticking: it seems real enough to me. I only play with LT, but you can bind the paredit stuff to whatever you want

16:23 it still pales in comparison (as does paredit mode) to vim-sexp plus vim motions

16:23 ticking: bja, yeah paredit is pseudo mode

16:23 bja, there are no real nodes, everything is done on text

16:30 amalloy: cljr: (require '[foo.bar :reload])

16:36 cljr: amalloy: thanks you

16:38 avishai: hi

16:38 lazy-seq question

16:38 cljr: im sorry to ask so many questions, but im just not used to the clojure workflow....i started up a repl and it seems to be in my projects namespace project.core > ..., however, i can't seem to access anything defined within that namespace, which I assumed i would be able to, for example, the -main functiopn doesn't seem to work

16:39 i tried (-main), (project.core/main), and 0 luck

16:39 avishai: if i want something like `for` that forces evaluation but returns the seq, (doall (for )) is the way to go?

16:40 hyPiRion: yes

16:42 avishai: cljr, you could try browsing the namespace to see what's loaded

16:43 also you could try using (load) to force load the clj file

16:44 cljr: avishai: how do you browse the namespace?

16:45 avishai: you could use (ns-aliases)

16:45 (ns-publics)

16:45 etc

16:45 or better yet, use ayler

16:45 cljr: well, im clearly an idiot, file wasn't loaded due to a syntax error.....

16:46 ticking: cljr, if your main is named -main you have to do project.core/-main

16:47 cljr: ticking: yeah, i figured that much, just working tghrough newbie pitfallas

16:47 ticking: cljr, there are plenty, but the reward is quite worth it ^^

17:03 cYmen: I think this is the fourth time that I have done something like this (fn [p] (let [p (rest p) f (first p)]...

17:05 justin_smith: ,((fn [[f p]] [(+ f f) p]) [1 2 3]) ; cYmen

17:05 clojurebot: [2 2]

17:05 justin_smith: ,((fn [[f & p]] [(+ f f) p]) [1 2 3]) ; actually more like this

17:05 clojurebot: [2 (2 3)]

17:06 danielcompton: Building on cljr, is there a guide for how to work with Clojure at the repl, move around namespaces, that kind of thing? I have found that part quite confusing

17:08 justin_smith: danielcompton: I think you can find everything else if you master - apropos, source, doc, in-ns, require

17:08 cljr: danielcompton: im not positive this is accurate or even what you mean, but you can change namespaces with (ns '...)

17:08 justin_smith: ,(clojure.repl/apropos "vec")

17:08 clojurebot: (vector-of vec vector vector? subvec)

17:08 justin_smith: cljr: if you are not creating a new one in-ns is better

17:09 danielcompton: I was wondering if there is a written guide somewhere explaining the overall workflow and how the different pieces work together

17:09 rovar: Joy of Clojure has some good bits on experimenting in the repl

17:09 cYmen: justin_smith: my point was actually not about destructuring but that my bad variable names lead to clashes and hence weird errors

17:09 justin_smith: I am sure there is, but all the info is available in the repl itself with the above commands

17:09 cYmen: ahh, ok

17:09 danielcompton: I see

17:09 cljr: amalloy: i notced your name on the docs, so Im gonna shoot a question at you, if you are busy no problem.....

17:10 amalloy: im following the client part here https://github.com/ztellman/aleph/wiki/TCP

17:10 justin_smith: ,(apropos "ns") ; another good set of leads

17:10 clojurebot: (ns-aliases booleans the-ns instance? gensym ...)

17:10 coventry: danielcompton: The workflow is very flexible, but Stuart Sierra has put a lot of thought/writing into his approach.

17:11 danielcompton: coventry: do you mean http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

17:12 coventry: danielcompton: Yes. Also, with good editor integration you don't necessarily end up doing a lot directly in the repl. You just send forms via emacs.

17:12 danielcompton: So this is worth a read http://clojure-doc.org/articles/tutorials/emacs.html#using-the-repl

17:12 danielcompton: Similar for vim?

17:13 I've been holding out on Emacs but maybe I just need to take the plunge

17:13 cljr: amalloy: ive done everything b4 enqueue, and i can see something in the channel, however, when i enqueue, i do not see that inside the channel, too....it is my understanding that is a bidirectional channgle?

17:13 coventry: danielcompton: Yes, do it. Vim has many strengths, but it is definitely the poor step child in this regard.

17:14 justin_smith: another thing to remember is that there are very few things that work differently between a repl and a loaded file, so you can think less about "how the repl works" and more about "how clojure works"

17:18 danielcompton: Would behaviour of loaded namespaces be one of those differences?

17:23 justin_smith: nope

17:23 if you require the namespace into the working namespace, it works the same in a repl as in a file

17:26 coventry: The main difference between at-the-repl and other contexts is that the print stage forces evaluation of lazy structures.

17:28 You could write a function which behaved differently at the repl by having it depend on its stack trace, I guess.

17:32 justin_smith: and there are different design considerations

17:32 I only call use in the repl

17:32 I only rebind things in namespaces I didn't write in the repl

17:32 but that isn't different functionality, just best practices

17:33 avishai: is there a function which is equivalent to #(or (seq? %) (coll? %))

17:33 e.g. to check i can iterate on param

17:40 shriphani: hi everyone. Is is possible to make enlive retain the path from root to a node when I use a selector? i.e. delete the subtrees that don't fit the selector ?

17:43 justin_smith: avishai: seq

17:43 it will be truthy if iterable

17:43 falsey if not

17:43 avishai: justin_smith, seq?

17:44 justin_smith: no, seq

17:44 wait...

17:44 sorry

17:44 that doesn't work since seq fails on thing that are not iterable with an exception

17:44 $source seq

17:44 lazybot: seq is http://is.gd/detxmL

17:45 justin_smith: but the source to seq shows what you would need to do to canonically make that check

17:45 avishai: 10x

17:46 justin_smith: hmm - need to check the java code for that one actually

17:49 coventry: Why would it be bad to be able to take the value of a macro?

17:50 justin_smith: macros only do their thing at compile time

17:51 if you passed one at runtime, how would you know what to do with it?

17:51 how would the compiler know what to expand?

17:53 coventry`: Was thinking it could be useful to return a convenience macro at the repl some times. There are workarounds, though.

17:54 justin_smith: you can pass the var it is bound to

17:54 ,#'or

17:54 clojurebot: #'clojure.core/or

17:54 justin_smith: that is different from the macro, of course

17:54 but it points to it

17:56 coventry: Is there a simple way to get the repl to recognize it as a macro at that point? E.g. (defmacro t []) (@#'t) seems to call t as a straight function.

17:58 arrdem: unless you use eval somewhere, the concepts of "return" and "macro" are fundimentally incompatible. you should probably look at your "workaround" options, because this is sketchy to say the least.

18:00 cljr: in c/python you can include \x as an escap seq to encode hex values in strings, what is directly equivalent in clojure?

18:01 "\xf9\xbe\xb4\xd9" for example

18:02 hyPiRion: It's the same as in Java afaik

18:03 So you got either unicode escape or octal escaping, although I don't think hex escaping like in python possible

18:04 ,"\u0063"

18:04 clojurebot: "c"

18:04 cljr: hmm, alright

18:05 mercwithamouth: is anyone working through web development in clojure?

18:05 justin_smith: why does this give me an npe: (satisfies? clojure.lang.ISeq [])

18:06 is that not the right way to refer to the ISeq protocol?

18:08 also: ISeq is a protocol?

18:08 justin_smith: https://github.com/clojure/clojure/blob/clojure-1.4.0/src/jvm/clojure/lang/ISeq.java looks like it to me

18:08 actually I am having trouble using satisfies at all...

18:11 also: i thought that satisfies for was protocols, not interfaces, and that ISeq was an interface.

18:11 justin_smith: OK

18:11 how would I check if something implements the interface? is there a method for that?

18:11 dnolen: justin_smith: instance?

18:12 ,(instance? clojure.lang.ISeq ())

18:12 clojurebot: true

18:13 mercwithamouth: problem solved =P

18:13 justin_smith: nice, that is what I was looking for

18:13 but sadly, it still doesn't help me answer the "can you call seq on this without getting an exception" question

18:14 do I really need (try (seq x) true (catch Exceptione e false))

18:14 that seems silly

18:18 AeroNotix: what arey ou trying to do?

18:18 I came in late

18:18 justin_smith: someone had a question

18:19 he wanted to know how he could tell if he could iterate on something

18:19 AeroNotix: seq?

18:19 justin_smith: exception for some things that don't implement ISeq

18:19 but not for others (like strings)

18:19 AeroNotix: (seq? 'not-a-seq)

18:20 justin_smith: ,(seq? {:a 0 :b 1})

18:20 clojurebot: false

18:20 justin_smith: you can iterate on that

18:20 AeroNotix: ah

18:20 justin_smith: ,(seq? "hello")

18:20 clojurebot: false

18:20 justin_smith: you can iterate on that too

18:20 etc.

18:20 there seems to be no reliable check, other than attempt to call seq, and catch the exception

18:20 but that seems weird

18:20 I am hoping I am just ignorant of the right answer

18:21 pragmatically you either know whether the thing coming in should be a collection, or you know the specific collection types to check for, almost always

18:21 but as a general question it is still interesting

18:22 AeroNotix: You can never be sure about stuff like this in languages which don't have very strong type systems.

18:22 Them's the breaks

18:22 rads: justin_smith: https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj#L83

18:22 seqable?

18:22 justin_smith: oh, cool

18:23 so that is his answer, thanks

18:23 oh, that is from a future clojure version

18:23 lol

18:43 xpe: so I'm trying to think of a decent name for a Clojure program that is pretty much just a "event loop" that waits for time to pass

18:44 part of it is clearly an http service, that's easy. I just want to think of a better name than "loop" or "event-loop" but I guess that would do

18:44 (part is the HTTP service, part of it is totally separate)

18:44 clojurebot: You don't have to tell me twice.

18:45 xpe: hi clojurebot you work in mysterious ways

18:46 ,(clojure.java.shell/sh "shutdown now")

18:46 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.java.shell>

18:47 xpe: ,(use '[clojure.java.shell :only [sh]])

18:47 clojurebot: nil

18:47 xpe: ,(sh "echo hello")

18:47 clojurebot: #<SecurityException java.lang.SecurityException: denied>

18:56 justin_smith: xpe: that would look for a command called "echo hello", you probably want (sh "echo" "hello")

18:57 xpe: ,(sh "echo" "thanks") ; justin_smith

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

18:57 xpe: ,(use '[clojure.java.shell :only [sh]])

18:57 clojurebot: nil

18:57 xpe: ,(sh "echo" "thanks") ; justin_smith

18:57 clojurebot: #<SecurityException java.lang.SecurityException: denied>

18:57 mudge: what is the clojure idiomatic way to get the last 4 characters of a string as a string?

18:58 amalloy: &(doc subs)

18:58 lazybot: ⇒ "([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."

18:58 xpe: ,(apply str (take-last 4 "arstdhne"))

18:58 clojurebot: "dhne"

18:58 justin_smith: ,(#(subs % (- (count %) 4)) "hello")

18:58 clojurebot: "ello"

18:59 xpe: but `subs` looks better

18:59 andyf: mudge: Also depends a bit on whether you care about UTF-16 Unicode encoding, and your definition of character, but that might be further down the rabbit hole than you need to go

19:00 mudge: hmm.... I wonder why subs doesn't take a negative index to indicate number of characters from the end of the string

19:00 andyf: mudge: It has been proposed, but never implemented in Clojure yet.

19:00 justin_smith: yeah, that bugs me, but count is constant time, because the string is immutible and the size is stored

19:01 mudge: andyf: my guess is that at this point it hasn't been added to Clojure because Rich and/or others don't want to add it to the language, and I wonder why

19:01 just_smith: good to know

19:01 andyf: mudge: I have not heard a reason given that I can recall at this moment. Such a fn is not difficult to write yourself if you want one.

19:02 mudge: yea

19:02 thanks guys for the input

19:04 I actually need to see if the last four characters of a string = "html". Is it clojure idiomatic to resort to interop like so: (.endsWith "mystringhtml" "html") ?

19:04 or is it more idomatic to avoid introp?

19:04 andyf: mudge: I have seen .endsWith and .startsWith frequently in Clojure/JVM code.

19:05 also: is there a way with ring to write directly to the OutputStream?

19:06 mudge: thanks andyf

19:10 justin_smith: ,(.endsWith "foo.html" "html")

19:10 clojurebot: true

19:10 justin_smith: interop is usually idiomatic, unless it mutates something

19:11 mudge: justin_smith: good to know, thanks

19:28 john2x: what's the quickest way to double each character in a string? e.g. "ABC" => "AABBCC"

19:31 cljr: has anyone here used gloss much?

19:31 justin_smith: ,(apply str (mapcat #(list % %) "hello")) ; mudge

19:31 clojurebot: "hheelllloo"

19:32 justin_smith: I would usually avoid the string -> seq -> string thing, but it may be the easiest way to do something like that

19:32 but a way to do it just as a string is welcome

19:32 also: ,(.replaceAll "ABC" "(.)" "$1$1")

19:32 clojurebot: "AABBCC"

19:32 justin_smith: (inc also)

19:32 lazybot: ⇒ 1

19:32 justin_smith: much better

19:32 john2x: nice. thanks!

19:34 also: clojure.string/replace to avoid the interop form

19:40 john2x: ,(clojure.string/replace "ABC" "(.)" "$1$1")

19:40 clojurebot: "ABC"

19:40 also: ah, i think that needs a regex argument

19:40 john2x: ,(clojure.string/replace "ABC" #"(.)" "$1$1")

19:40 clojurebot: "AABBCC"

19:40 also: ,(clojure.string/replace "ABC" #"(.)" "$1$1")

19:40 clojurebot: "AABBCC"

20:01 l4u: is dev compilation time a design goal of clojure?

20:01 dnolen: l4u: dev compilation time?

20:02 cljr: If anyone has any experience with gloss, any pointer on how you would handle this: https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer would be amazing help....

20:04 l4u: dnolen: em.. compilation speed in development mode. do I have to wait for a long time like in java for compilation? or is it relatively fast (like in golang)

20:04 cljr: it has never been particularly slow for me

20:04 dnolen: l4u: interactive development is pretty much how people work in Clojure, so it's not really a pain point

20:05 l4u: dnolen: cool

20:05 dnolen: l4u: the development work flow is very unlike golang - you don't edit your files and compile

20:05 l4u: you write some functions and test them as you go at the REPL

20:07 shriphani: Hi, if someone is familiar with the clojure source, can you tell me why there is more than 1 definition of invoke here? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java

20:08 algernon: cljr: you probably want some trickery with (header)

20:08 dnolen: shriphani: perormance

20:08 er performance

20:09 shriphani: ah. TIL. Thanks.

20:10 dnolen: shriphani: not specific to keywords, but how functions work in Clojure

20:11 gdev: dnolen, no blog post about reactjs or tagged literals in cljs? just waiting for the code samples to be feature complete?

20:11 algernon: cljr: header takes a frame for the header (in this case, :byte), a function that takes that, and returns the codec for the body, and another function that takes a body and returns the header value

20:11 l4u: dnolen: thanks. lemme try the REPL workflow with vim-fireplace

20:12 amalloy: dnolen: wait, performance? IFn requires all of those arities

20:12 dnolen: amalloy: but the IFn encoding is for performance, you could think of a lot slower ways that involve less typing

20:12 algernon: cljr: so you can have a function that checks the header, if it's < 0xfd, body is nil, header is identity. if it's <= 0xffff, body is header + :byte

20:13 abp: Hi dnolen, you said libs like jquery aren't nescessary with ClojureScript, or something like that. Is it because we have better ways to abstract with cljs or more recent browsers not requiring much smoothing over API-glitches etc.?

20:13 algernon: though I'm not exactly sure how you'd combine the two, but it should be possible, I think.

20:13 dnolen: gdev: still working on it - it's going to be serious doozy of post - perhaps even more so than the CSP ones

20:13 gdev: basically that immutable representation for UI is just better always - hopefully that turns some head ;)

20:14 gdev: dnolen, that virtual DOM =)

20:14 dnolen: abp: because Google Closure provides much of same functionality and it's optimizable instead of being a giant blob of JS that you have to take wholesale.

20:15 petehunt:

20:16 abp: dnolen: Ah ok. Does that even apply when using jquery with externs? I don't know much about how the closure-compiler behaves when externs are present.

20:16 dnolen: abp: externs doesn't magically make random JS libs optimizable by Closure, it just prevents renaming

20:17 abp: dnolen: Too bad ;)

20:18 cljr: algernon: good call, i had just started considering a solution using header, too, thanks

20:19 petehunt: abp: one of the big issues is polymorphism, at least when it comes to jit-ing

20:22 technomancy: mudge: I added a patch for negative subs, but it got rejected as "goofy"

20:23 mudge: technomancy: hmm... I wonder why it is goofy, seems simpler and better than having to do it these other ways

20:23 technomancy: well it was a patch

20:24 mudge: I could do (.endsWith "stinghtml" "html") but what if I want my code to work in ClojureScript too?

20:24 technomancy: the default state of a patch is rejection

20:24 mudge: meaning that most patches are rejected?

20:24 technomancy: right

20:24 mudge: but did someone say your patch was goofy? that's not a very enlightening reason

20:25 technomancy: I think rich said it was goofy

20:25 maybe it was silly

20:25 mudge: ok, i really wonder what Rich would do if he need a substring that contained the last 4 characters of a string

20:25 andyf: mudge: The quote from Rich was "IMO its' goofy"

20:26 gdev: is this on Jira?

20:26 technomancy: gdev: I think so, but search isn't working for me ATM

20:26 andyf: gdev: https://news.ycombinator.com/item?id=2053908

20:27 That link is from JIRA

20:27 mudge: i don't want to do (subs "somethinghtml" (count "somethinghtml") - 4) every time

20:27 gdev: andyf, thanks

20:27 mudge: that seems more goofy

20:28 andyf: mudge: So write your own version of subs that works the way you want.

20:28 technomancy: oh nice; I'm not the only one to submit the exact same patch http://dev.clojure.org/jira/browse/CLJ-1042

20:28 andyf: mudge: I am not saying it should not go into Clojure, I am saying that waiting for it to go into Clojure before you start doing it yourself is an exercise in futility.

20:29 technomancy: The only JIRA hit while searching for the word "goofy" :-)

20:30 mudge: andf, the thing is that some things belong in the core of the language or in the standard library -- things that could be used very frequently in many places. But you are right Andy, perhaps I should make a library with random functions that I use frequently that aren't in the core or standard library

20:30 SegFaultAX: That's basically what contrib used to be.

20:30 andyf: mudge: There is a library useful by amalloy and others that has some thing like this (but maybe not negative indices), and someone else recently came out with another library with similar intentions.

20:30 SegFaultAX: Also, flatland/useful

20:31 andyf: Anyone remember the name of that other one?

20:31 mudge: oh that sounds good

20:31 technomancy: andyf: that's me; the goofy guy

20:31 mudge: I just wonder how rich would get a substring at the end of a string

20:31 what would he do?

20:31 andyf: technomancy: I am not saying you are goofy, and I don't think Rich is, either. He thinks the idea of negative indices is goofy.

20:32 He is usually pretty specific in discussing the ideas, not the people, at least in public conversations I have read.

20:32 maravillas: andyf: was it prismatic's plumbing? https://github.com/Prismatic/plumbing/blob/master/src/plumbing/core.clj

20:33 mudge: where's riche's email address, I"m just too curious why he thinks it is goofy and what he would do.

20:33 andyf: Here it is: https://github.com/weavejester/medley

20:33 At least, that is the one I was trying to remember.

20:33 maravillas: ah, nifty

20:33 andyf: mudge: Um, you can send him private email if you want on that topic, but I wouldn't recommend it.

20:34 mudge: thanks andyf, why don't you recommend it?

20:34 andyf: mudge: If you want a function like that, check flatland/useful and medley to see if it is already there, and if not, create an issue there or submit a patch.

20:34 mudge: Because I think it would be a waste of both of your times.

20:35 mudge: andy, sounds good, i doing that now, thank you

20:35 dnolen: mudge: I think he pretty much stated all the relevant reasons on the HN post

20:35 mudge: where is the HN ost?

20:35 andyf: https://github.com/weavejester/medley

20:35 Woops. I meant this: https://news.ycombinator.com/item?id=2053908

20:35 danielcompton: And an email to the clojure mailing list would benefit everyone, not just you

20:35 dnolen: mudge: ^

20:39 bbloom_: technomancy: i just searched JIRA for "goofy"

20:39 was not disappointed

20:39 bitemyapp: technomancy: friend of mine and I are hacking on grom, we were looking at the Async stuff in client.ml and complaining ;)

20:40 technomancy: OCaml needs a do-syntax.

20:45 gdev: how did we end up talking about something from 1074 days ago?

20:45 andyf: gdev: Because mudge asked why there weren't negative indices for subs, and technomancy was remembering the good old days :-

20:46 gdev: andyf, oh, thanks again =)

20:50 andyf: mudge: If you have the patience, I'd recommend making your negative-index handling version throw errors in the same conditions that either Perl or Python do, whatever those conditions might be. And documenting what those boundary conditions are, and writing unit tests for them.

20:52 pdk: nah

20:52 people love array indexing functions that loop around when you go out of range

20:52 be bold

20:52 be daring

20:55 gfredericks: use mod and allow any index whatsoever

20:56 convert doubles to ints with floor

20:56 mudge: thanks andyf

20:56 gfredericks: if you get a string try to parse it as a number

20:56 andyf: gfredericks: I can't tell whether to laugh or cry at your suggestions.

20:56 gfredericks: anything else just call .intValue on it and see what happens

20:57 mudge: sounds very dynamic

20:57 gfredericks: put it in a lib and name it "goofy"

20:57 in the technomancy vein of literary character themed libs

20:58 andyf: IMO that would be goofy :-)

20:59 also: ,(#(+ %0.123e1) 1)

20:59 clojurebot: 1

20:59 also: slightly goofy

20:59 andyf: also: Yeah, I might submit some patches for things like that in the next month or three.

20:59 gfredericks: most of clojure's goofy is by omission, not design :)

21:00 gdev: noway I wanted to use the library name goofy for a lein plugin. it scans your code and adds any files that have goofy code to gitignore so you can push it

21:01 err *can't push it

21:01 andyf: First one to Clojars wins?

21:02 gfredericks: it's still available

21:02 technomancy: andyf: oh, yeah understood.

21:03 gfredericks: is there a ticket for %1.2?

21:04 andyf: gfredericks: None that I recall, and I recall way too many (but not all)

21:04 justin_smith: gdev - or joker, if your commit contains a .DS_Store, silently replace a random file with the contents of that .DS_Store file - they would learn their lesson fast

21:08 gdev: now thats just mean =p

21:09 JoelMcCracken: I'm looking to build a website as my first "real" clojure project. I think pedestal seems a little much for me; is there something better? I have lots of experience in lisp and web development, but almost none on the jvm

21:10 compojure seems popular, but its hard to get a feel for the ecosystem from google alone

21:10 ticking: JoelMcCracken, yeah I would go with the lightweight web stack

21:11 mudge: dnolen: I don't argue that negative indexes should be added to subs --- I just want to know why rich thinks it is goofy and what would he do

21:11 ticking: JoelMcCracken, Pedestal has the framework approach similar to ruby on rails, all in one box, but I prefer to pick and choose the libraries I like

21:11 andyf: I am not an authority on these matters but this book seems like a good intro from my going through it: http://pragprog.com/book/dswdcloj/web-development-with-clojure

21:12 gdev: JoelMcCracken, have you looked at Dmitri Sotnikov's book

21:12 andyf: I think it is by the same authors as the luminus web framework.

21:12 amalloy: i think negative indexes are a bad idea because either you have to make every collection type (importantly, including user-created types) support them, or let the language feel inconsistent

21:12 andyf: Luminus is: https://github.com/yogthos/luminus

21:12 JoelMcCracken: gdev: i haven't

21:13 gdev: JoelMcCracken, I think its the one andyf linked

21:13 andyf: gdev: JoelMcCracken: It is the same book we are mentioning

21:13 JoelMcCracken: oh oh. good

21:14 ticking: Luminus is basically the stack I was going to propose in one package ^^

21:14 gdev: JoelMcCracken, there is also Caribou http://caribou.github.io/caribou/docs/outline.html

21:14 ticking: I would go with ring as the webserver adapter, compojure for routing, and on top of that laser for templating

21:16 seangrov`: justin_smith: Any idea if walk2 works with clojurescript?

21:16 justin_smith: seangrov`: no clue

21:18 ticking: JoelMcCracken, if you want to do interactive webapps I'd even take a look at clojurescript and enfocus :)

21:18 JoelMcCracken: i'm mostly worried about jvm stuff =-\

21:18 i've always been confused/scared by the inpenetrable javaspeak

21:19 technomancy: http://copperthoughts.com/p/clojure-io-p1/ will get you through the most common JDK classes required for basic clojure

21:19 mudge: How to use doseq with ->> ?

21:19 technomancy: mudge: no can do

21:20 JoelMcCracken: thanks for the advice! ill probably be buying this book

21:20 technomancy: JoelMcCracken: none of the crazy dependency injection or factory junk actually matters from clojure unless you're stuck with a specific library that hasn't been wrapped

21:20 pretty rare these days

21:21 ticking: JoelMcCracken, tbh encounters with java are rare in clojure, leiningen shields you pretty well from the tool world, and clojure is so powerfull you almost never have to call java stuff

21:21 mudge: technomancy: I tried wrapping doseq in #( ) but doesn't work

21:21 I want to thread some values through some functions and then pass the value into a doseq

21:23 technomancy: mudge: (let [xs (->> y f1 f2 f3)] (doseq [x xs] ...))

21:23 JoelMcCracken: ticking: yes well, i'm worried about deployment

21:23 mudge: thanks technomancy

21:24 also: JoelMcCracken: where will you be deploying?

21:24 JoelMcCracken: for now, ubuntu

21:24 ticking: JoelMcCracken, scale?

21:24 JoelMcCracken: initially im just developing for myself

21:25 ticking: JoelMcCracken, do you need websockets?

21:25 JoelMcCracken: no

21:25 ticking: lein-ring

21:26 you declare your handler in your project.clj, and can also put optional init and teardown functions in there

21:26 justin_smith: http-kit does websockets and is compatible with ring

21:26 JoelMcCracken: am I understanding correctly that the above book web-development-with-clojure is complete?

21:26 ticking: and then call lein ring serve

21:26 justin_smith, yeah but not with lein-ring ^^

21:26 JoelMcCracken: ticking: on production?

21:27 technomancy: JoelMcCracken: uberjar with ring-jetty-adapter is the easist way to deploy

21:27 mudge: why can't ->> work with doseq?

21:27 technomancy: mudge: because ->> places the element in the last position

21:28 mudge: the last position of doseq is where side-effects go, not inputs

21:28 ticking: JoelMcCracken, like technomancy said, lein ring uberjar will give you a jar you can run, lein ring uberwar will give you a war for tomcat and the like but that would be overkill

21:30 mudge: technomancy: I see, but I tried wrapping doseq in a function with #(doseq [file-path %] body)

21:31 maybe I am using #( ) incorrectly?

21:31 technomancy: mudge: easier for you just to macroexpand than for me to explain =)

21:31 mudge: Okay, I will do that

21:32 ticking: JoelMcCracken, so you should probably go with https://github.com/weavejester/lein-ring and the default ring jetty adapter, some people like to run http-kit in production (as justin_smith mentioned) but that requires some (3 line) setup, vs 0

21:38 justin_smith: mudge: (#(doseq [file-path %] body))

21:38 mudge: justin_smith: that's it thanks

21:39 well I will try that

21:40 technomancy: I am just starting to use cider in emacs, not sure how to macroexpand the part that you expect me to

21:41 technomancy: mudge: nothing cider-specific required

21:41 ,(macroexpand-1 '(->> [123] (doseq [x %] (prn x))))

21:41 clojurebot: (doseq [x %] (prn x) [123])

21:41 JoelMcCracken: ok =)

21:41 i'll try it

21:42 technomancy: cider has fancy ways of doing that, but start with the repl when in doubt

21:43 coventry: In the cider-specific department, there is C-c M-m, nrepl-macroexpand-all (I guess cider is the same, anyway.)

21:43 mudge: okay

21:45 ,(macroexpand-1 '(->> [123] #((doseq [x %] (prn x)))))

21:46 clojurebot: (fn* [p1__61#] ((doseq [x p1__61#] (prn x))) [123])

21:47 mudge: that looks like it should work

21:47 justin_smith: mudge: you have the # in the wrong place

21:47 not #(( but (#(

21:47 mudge: ah

21:48 danielcompton: JoelMcCracken I found https://devcenter.heroku.com/articles/clojure-web-application to be a good starting point for understanding how all of the pieces fit together

21:49 mudge: justin_smith, yes that works

21:53 i understand, thanks technomancy

21:54 technomancy: mudge: I'm in the middle of playing learn.code.org with my kids, so I'm very much in the "ask the right questions; don't give the answer" mode now =)

21:56 mudge: haha

22:08 gdev: technomancy, lol I did hello.processing.org with my kids today and by the end of the hour I was totally in a "okay, here's the bloody answer" mode

22:08 technomancy: gdev: well iirc processing is just simplified Java, right?

22:10 gdev: "simplified" java

22:10 technomancy: that's actually one of the things that bugged me most about quil; it's still super imperative =\

22:11 ticking: and buggy^^

22:12 gdev: yeah I'm wondering if the same techniques that were used to make seesaw could be used to improve quil

22:13 ticking: I think generating svg with clojurescript could be rea,,y functional and nice

22:13 technomancy: I'm hoping to work my way up to racket

22:14 but the lowest-level racket stuff I've found targets middle school

22:14 justin_smith: ticking: this lib may not be far from clojurescript compatibilityhttp://liebke.github.io/analemma/

22:14 it does a nice nested map / svg conversion, and supports animation

22:14 nkozo: there is a way to disable the chunked behaviour of the sequences?

22:15 justin_smith: nkozo: if the precise timing of the realization matters so much you probably want something more imperative - loop is not chunked

22:16 ticking: justin_smith, I was thinking among the lines of enfocus style transformatations, but convertig the entire document at once might also work ^^

22:17 technomancy, for you or your kids?^^

22:18 nkozo: justin_smith: the timing is not the problem, but the realizations of the elements are expensive

22:19 technomancy: ticking: for my kids

22:19 ticking: technomancy, maybe there should me more clojure learning games, I wanted to do a mars rover game for some time now

22:19 nkozo: justin_smith: I already used a loop but I had the doubt if was possible to make more elegant approach using sequences... but the chunked behaviour is my main obstacle

22:20 technomancy: ticking: clojure is pretty newbie-hostile

22:20 I wouldn't put my kids on it till they had a solid start in racket

22:21 newblue: is this a reasonable way to handle a boolean state in a closure? https://www.refheap.com/21610

22:21 technomancy: there's a 15-year old at seajure who's presented on optimizing puzzle-solving algorithms, but he started around 8 in racket iirc

22:22 ticking: technomancy, could be, but I think the method is more important than the language

22:22 technomancy: if I dropped clojure on my kids I would just be constantly apologizing for the stack traces and stuff; it would be awful

22:23 ticking: technomancy, I would start with a core.async channel you can shove :forward :left :right :pick and :drop in, so you had to do everything by hand

22:23 and then gradually automate on top of that

22:25 technomancy, controlling a roomba that way could be fun ^^

22:26 justin_smith: nkozo: you can generate a lazy-seq from loop. The performance penalty is a side effect, if you need to control it you want something more imperative than the standard lazy functions.

22:27 actually strike using loop, if you are recurring to a lazy tail you don't need to use optimized recursion, a self call suffices

22:29 emaphis: technomancy: look at Logo, a lisp for kids. has recursion and higher order functions

22:30 nkozo: justin_smith: thanks, will research that.

22:30 gdev: technomancy, funny that you mention quil, I was just playing with it today. this was a direct port from the java version, but still kinda awful https://gist.github.com/gdeer81/7866927

22:30 emaphis: technomancy: then a look for "The Great Logo Adventure", on the net, IttTeaches recursion and higher order fucntions to kids.

22:32 ticking: emaphis, I love logo for the fact that it is the oldest lisp still in use today

22:32 emaphis: technomancy: then graduate to Brian Harvey's "Computer Schience Logo Style" kind of a SICP for kids.

22:32 ticking: :-)

22:33 s/Schience/Science.

22:33 zerokarmaleft: technomancy: what are you teaching them in the meantime?

22:34 justin_smith: newblue: you can use reset! if you don't care what the original value was

22:35 newblue: and :active? can be redefined as deref

22:36 (fn [] @active) = #(deref active)

22:37 also, why do activate and deactivate take an arg? the code as is won't work

22:37 newblue: justin_smith: just plugged in deref and it definitely looks cleaner

22:38 and reset! is totally what I was looking for, too - I was most worried about the double parenthesis and whether is a code smell

22:38 Zerker: Wait logo is immutable?

22:39 newblue: *it is

22:39 Zerker: variables are*

22:39 justin_smith: newblue: double parens just means you are looking somthing up in order to call it

22:41 technomancy: emaphis: racket actually implements logo =)

22:41 emaphis: but having a curriculum to work through would help; I'll take a look. thanks.

22:42 zerokarmaleft: technomancy: ah, read the scrollback...learn.code.org looks cool...like a web version of scratch

22:42 justin_smith: if it is a code smell it is only because it indicates you were doing data hiding (with your closure), and with immutibility data hiding is less useful and more annoying

22:42 technomancy: zerokarmaleft: it's a lot more focused; I feel like they're much less distracted

22:42 newblue: justin_smith: I don't mind 'em at all, just trying to use "proper style" where I can. Speaking of, is there an upper limit to how much you should cram into a closure?

22:42 justin_smith: the limit is readability

22:43 but consider using a function that returns an updated state, rather than a clojure that changes a hidden state

22:43 *a closure that

22:43 technomancy: zerokarmaleft: you can do scratch on the web (but in flash; ick) but the main draw of code.org is that it's guided tutorials instead of free-form play

22:43 (there's a place for both IMO, but right now they are learning a lot more from the tutorials)

22:45 zerokarmaleft: technomancy: the fact that it uses assets from familiar games will help me keep their interest too, I think

22:45 technomancy: there's a book for scratch that has some guided activities, but it's still too free-form for my 5 year-old

22:45 ticking: yeah but I wonder how long it takes to undo the imperative damage done

22:46 technomancy: ticking: =\

22:46 Matthew Flatt (of racket fame) had that same complaint and suggested http://www.bootstrapworld.org/

22:46 gdev: technomancy, i have that book too. was a total waste

22:46 ticking: I remember that it took me years to unlearn OO

22:47 technomancy: but there's no way you could start a 5-year-old on that

22:47 ticking: yeah they even lost me after not having something running after 5 clicks and 21 seconds ^^

22:48 technomancy: I think bootstrap is designed for a classroom

22:49 (which is a pretty hostile environment for learning)

22:49 ticking: the problem is though, functional programming in a learning environment is uber hard

22:49 I agree

22:49 coventry: nkozo: https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L178

22:49 technomancy: ticking: eh... what about 4clojure?

22:49 gdev: minikanren4kids.org is an available domain

22:49 ticking: technomancy, they are the worst

22:49 technomancy: you just need to frame things in terms of values

22:50 ticking: technomancy "solve this problem without using the idiomatic simple solution"

22:50 musicalchair: need not a computer to teach the programmer's mind. I think a lot could be taught by acting thingss out physically. Say, your kid could dictate a logo program and you act it out on the floor

22:50 technomancy: it's a bit less obvious than scratch/code.org, but just because no one's done it doesn't mean it's inherently difficult

22:50 musicalchair: http://www.robotturtles.com/ =D

22:50 emaphis: technomancy: "The Great Logo Adventure" is a curiclulum for children but it might be a little heavy for a 5 year old. :-) but there is a reference to it on this page: http://www.softronix.com/logo.html

22:50 technomancy: emaphis: thanks

22:50 musicalchair: technomancy: =)

22:50 newblue: justin_smith: I have a semi-bloated closure already, and am just tacking on active/not active. It has a few GUI items and their bindings...I dunno, it seems the best way to quarantine the all the state

22:51 technomancy: my 5-year-old is reading at a 3rd-grade level, so it might work

22:52 ticking: technomancy I think having no mutable world makes it difficult, because there is nothing to interact with really

22:52 coventry: I've was tutoring some people in python this semester, and the biggest problem was the course instructor, but wow it was hard to lead them to the right answer without just telling them.

22:52 musicalchair: separately, I'm not convinced functional programming needs to be the first thing taught to avoid "imperative damage" The CPU is imperative, after all

22:52 technomancy: ticking: true; it forces you to be more abstract, which is objectively more difficult for early-stage childhood development

22:52 part of the point of logo is to be the bridge between the abstract and concrete

22:53 so at that developmental stage, reaching FP through imperative ideas might be necessary

22:53 ticking: musicalchair, yeah but not because it is such a nice programming model ^^

22:54 technomancy: coventry: pick up some tips from reading socratic dialogues

22:54 he seemed to have a knack for it =)

22:55 musicalchair: ticking: just a supremely practical one. most cookbooks I've seen are imperative. something about the real world...

22:55 technomancy: IIRC Meno deals with imparting mathematical knowledge

22:56 coventry: Oh, I've got it down pretty well, and they were happy with the results, but it took far more iterations of question/attempt-at-answer than it usually does when teaching math (it was the first time I'd tried to teach people programming.)

22:56 ticking: musicalchair, I'm not saying that there shouldn't be imperative concepts, I just don't think javascript is a good start

22:56 technomancy: https://en.wikipedia.org/wiki/Meno#Dialogue_with_Meno.27s_slave

22:57 coventry: ah gotcha

22:57 musicalchair: ticking: agreed. I was getting a little rambunctious =X

22:57 ticking: musicalchair, which is what code.org does basically

22:58 musicalchair, btw I think that teaching assembly is actually better than say java

22:58 gdev: musicalchair, cookbooks are imperative, but restaurant menus are more declarative. select cheesecake from dessert menu

22:58 ticking: musicalchair, because you can see all the state at once, (at leasf the registers)

22:59 emaphis: gdev: unless you think of a recipe as a fucntion. :-)

23:00 *function

23:00 cljr: i imagine this is a really stupid quesiton, but clojure.contrib is built in, correct?

23:00 coventry: I learned assembly about two years after I learned BASIC, and it was WAY harder. I suppose it might have been the quality of the tools, though.

23:00 ticking: cljr, contrib is dead

23:00 mheld: ok. the next version of lein needs to be able to figure out what to do with git repos

23:00 just... fyi

23:00 seangrove: coventry: Yeah, that's a pretty huge gap

23:00 ticking: cljr, it was spitted up into different clojure projects and the core

23:00 musicalchair: ticking: yes, I might agree. I think you would want a "friendly" assembly. I guess that is pretty much logo

23:01 emaphis: mheld: source control without setting your hair on fire.

23:01 justin_smith: mheld: what do you mean?

23:02 technomancy: ticking: because no one programming assembly would actually do it by choice beyond a week or two =)

23:02 ticking: musicalchair, yeah, one line per instruction, single side assignment, looks like llvm for kids ^^

23:02 cljr: ticking: well, that explains a lot actually

23:02 musicalchair: gdev: perhaps, but I'm not sure what you learn about the process of cooking from a menu. I should probably have not made the analogy, it's better to be direct

23:02 justin_smith: forth is a good choice for assembly-like while still teaching about abstraction and design

23:02 technomancy: "your first programming language can be anything, as long as your second makes you wonder what the hell was wrong with the first"

23:02 ticking: technomancy, yeah but by then you will have the deeps satisfaction of knowing what is really going on and can then move to higher abstractions ^^

23:03 mheld: justin_smith: [clj-time "0.6.0" :git "URL_TO_REPO_TO_CLONE_FROM"]

23:03 or something

23:03 musicalchair: technomancy: now that's a solid way to teach; by comparison

23:03 technomancy: musicalchair: already been bitten by the lack of function arguments in scratch =)

23:03 musicalchair: you don't know what you have until it's gone, etc

23:03 coventry: mheld: Do you know about checkout dependencies?

23:05 gdev: in the end our kids will just grow up to be project managers anyway -_-

23:05 emaphis: technomancy: BYOB is a version of scratch with functions, recursion and higher order funtions.

23:05 mheld: coventry: I'm unfamiliar with this

23:05 ticking: musicalchair, technomancy, but wouldn't then clojure be ideal? you could start out with imperative core async (basically "actors") , then functional clojure, then core.logic ^^

23:05 coventry: mheld: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies

23:05 emaphis: technomancy: http://byob.berkeley.edu/

23:06 mheld: coventry: I guess that works, too

23:06 still think the way that bundlr does it is awesome

23:07 bundler

23:09 also, boo on the name of the folder checkouts

23:10 now when I checkout branches on git it'll ask me "zsh: correct 'checkout' to 'checkouts' [nyae]?"

23:10 ticking: I have to say, zuckerberg on code.org creeps me out

23:11 emaphis: more than Bill Gates?

23:11 musicalchair: ticking: it might be promising in some ways but I think programming is far from any ideals both in pedagogy and practice. Who knows what programming will be like in 20 years, anyway?

23:12 ticking: musicalchair, same as every year, some shitty language like php

23:13 coventry: mheld: just use magit for basic git tasks. Less typing. :-)

23:14 ticking: musicalchair, it's shitty langs until the AI singularity ^^

23:14 gdev: yeah I'm sure 20 years ago people said the same thing and those people were probably shocked to find out we'd be optimizing around the same constraints we had 20 years ago

23:14 ticking: gdev, to be fail paralellism has taken of in our gpus

23:14 fair

23:15 but we still throw c at it ^^

23:15 deadghost: there's some hype with that thing wolfram is working on

23:16 emaphis: deadghost: isn'

23:16 he inventing Lisp?

23:17 ticking: that stuff is so great

23:17 did you read that article?

23:18 deadghost: I think I did

23:18 ticking: "in the past programming languages have been modular and chopped up, we solve this problem by having one monolythic language that integrates everything"

23:18 cljr: hmm, there used to bea nice repeat function in clohjure.contrib.,string, but that isn't in clojure.string, is there somewhere else i should be looking?

23:19 ticking: cljr, what does it do?

23:19 cljr: ticking: http://clojuredocs.org/clojure_contrib/clojure.contrib.string/repeat

23:19 ticking: cljr, as a general guide see this http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

23:21 cljr, it seems to have gotten lost, but no worries

23:21 `(apply str (repeat 5 "hi"))

23:22 cljr: ticking: very cool, thank you

23:22 ticking: ,(apply str (repeat 5 "hi"))

23:22 clojurebot: "hihihihihi"

23:25 bitemyapp: today was a good day :D

23:25 gdev: bitemyapp, you didn't have to use your AK?

23:26 bitemyapp: gdev: good reference, used to own one, they're nice but not very accurate.

23:26 gdev: actually because I pair-programmed some Haskell with a buddy of mine for 4 or 5 hours, had some good food, and got a silk scarf.

23:28 you can accurize or upgrade an AK, but realistically, there are more accurate 7.62x39mm rifles out there. The only thing "special" about them is the brand cachet and extreme reliability.

23:28 gdev: I haven't had a silk scarf since my deployment to Chile

23:29 bitemyapp: gdev: deployment?

23:29 gdev: with the Navy

23:29 ticking: as a war file?

23:29 bitemyapp: gdev: ahhh, my company has a lab in chile.

23:29 gdev: apparently the food in Chile is *terrible*.

23:30 ticking: bitemyapp, but the wine is goow

23:30 gdev: bitemyapp, I wouldn't know, I always ate dinner on the ship so I could save my money for the bar

23:30 the wine was goow, that is true

23:30 ticking: hrhr

23:31 seangrove: bitemyapp: Seems the wrong weather for a silk scarf - is it warm enough?

23:31 bitemyapp: gdev: supposedly the default meal for the people there is a boiled hot dog wrapped in wonder bread.

23:31 ticking: I'm in keyboard limbo, between qwerty and workman

23:31 bitemyapp: seangrove: that's the point, I need a cover, not to be suffocated with heat.

23:32 seangrove: also, I say silk, but it's quite fuzzy. 100% silk though.

23:32 seangrove: sale at Macy's, 25-50% off.

23:32 seangrove: bitemyapp: Ah, ok, fuzzy silk scarf sounds good.

23:32 gdev: bitemyapp, so tell us more about this...Haskell, is it?

23:32 bitemyapp: seangrove: I didn't go in intending to get silk, it was the only non-acrylic scarf I could find.

23:32 seangrove: I'd rather bitemyapp talked to Crockford about it

23:32 gdev: I've heard some interesting things about it on the intertweets

23:32 bitemyapp: seangrove: what's this about Crockford and Haskell lately?

23:33 oh, my RT?

23:33 seangrove: bitemyapp: His "monads and gonads" talk :P

23:33 bitemyapp: Crockford has given talks on monads lately, yeah.

23:33 that's not his only one that mentions monads.

23:33 It's not strictly correct, but close enough anyway.

23:33 he's trying to approximate the concept for muggles.

23:33 it's easier to just write the code.

23:34 gdev: if you have a question, ask :P

23:35 gdev: bitemyapp, actually, I'll take my chances in the #haskell channel =b

23:36 seangrove: bitemyapp: I suppose, but was pretty surprised by some of his remarks about js leading the way.

23:37 bitemyapp: seangrove: yeah, that was a lie.

23:37 functional and useful implementations of monads in untyped languages doesn't make a ton of sense.

23:37 you need type deduction for it to provide any real leverage or be nice to use.

23:38 seangrove: bitemyapp: In any case, he's done a lot of work with spreading some knowledge, that's good for something.

23:38 bitemyapp: not that you *can't* use monads outside of that context, it's just that it will be very rare for it to make much sense, which means you're back to smashing rocks together like a fuckin' neanderthal

23:39 emaphis: At any rate, functional programming in javascript: http://shop.oreilly.com/product/0636920028857.do

23:40 Zerker: twisted: just learn steno already

23:40 ticking: *

23:40 coventry: I came across this recently, it's an interesting perspective. http://marijnhaverbeke.nl/monad.html

23:41 Zerker: \me has fallen victim to http://xkcd.com/604/

23:46 cljr: is there a better way to get debugging output? when i run a function in console and an erroer ppops up, it only tells me some area way down in the stack where the problem occured, it doesn't tell where in my file is causing the error

23:50 justin_smith: cljr: is the function defined in a file or in the repl?

23:51 cljr: if you load it for a file you will get line number info, you can do (require '[my.ns :as my] :reload)

23:56 cljr: justin_smith: im not totally following, it is defined in a file and im just opening up a repl and runnning one of the fcuntions within that namespace, but only line number information is related to functions that my function is calling

Logging service provided by n01se.net