#clojure log - May 02 2015

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

0:24 Fare: how do I tell clojure how to print my objects?

0:26 bitcycle: Hey all. Is there a Leiningen template for clojure console applications?

0:27 crocket: TEttinger, Do you think scala is a good language?

0:27 In my mind, scala is complex and difficult to get right.

0:28 Fare: Scala looks good on paper. I know people who love it and others who hate it in practice. Doesn't tell much.

0:29 most complain about the tooling.

0:29 crocket: Scala syntax is very complex

0:29 It takes a 1000 page book to explain its syntax.

0:29 Fare: :-(

0:29 I'm struggling with the finer points of the python syntax right now.

0:30 The treatment of variables is horribly subtle.

0:30 crocket: Fare, It's not difficult.

0:30 Python tutorial is not complex.

0:30 Fare: could certainly be worse

0:30 the fact that a global declaration can come after the use...

0:30 crocket: What is so subtle about python variables?

0:32 Fare: nonlocal vs global

0:32 crocket: Fare, I don't use global variables.

0:32 Fare: so there

0:33 when you implement it, you have to support the weird corner cases.

0:33 crocket: You just need to memorize some default global variables

0:33 I haven't met such corner cases.

0:35 Fare: I'm back to implementing a python subset

0:35 even sanitizing things for the chosen "subset", it's a bitch.

0:37 crocket: Fare, You mostly don't meet corner cases.

0:37 Fare: you need to implement them anyway

0:37 or at least detect them and throw an error saying you aren't implementing them.

0:39 crocket: Fare, What are you doing?

0:39 Are you writing a python interpreter?

0:39 Fare: I admit I'm making my life slightly harder in a way (and easier in other ways) by implementing macros for python.

0:39 crocket: I never heard of macros for python.

0:39 Fare: I've resurrected my project of a pure python to clojure compiler in clojure.

0:40 there exist some package that implements them already. It's ugly, but it works.

0:41 I'm also using macros and other things to desuga the language into a simpler one

0:41 crocket: Fare, Why are you torturing yourself?

0:42 Fare: I'm rewriting the desugaring pass right now to allow for macros. Dealing with retroactive global declaration after you already expanded an inherited macro binding... yuck. I punt.

0:42 many reasons

0:43 one of them: $work has a naive interpreter for an even smaller subset of python

0:43 crocket: Many reasons to torture.

0:43 Fare: I'd like to replace it with this compiler

0:44 crocket: $work

0:44 If it wasn't your job, would you do it?

0:44 TEttinger: crocket: i am not a fan of scala. i used it for an app, and its performance is good, but it is too complex for my taste

0:44 Fare: I'd also like to write my first non-trivial compiler for a non-trivial language

0:44 crocket, I would do something somewhat different — it wouldn't have python syntax.

0:44 crocket: TEttinger, So, is clojure viable on android?

0:44 Fare: but I'd also be writing a compiler

0:44 I probably would be using racket instead of clojure

0:45 crocket: Is racket better than clojure?

0:45 Fare: for writing compilers, yes

0:45 for interfacing with the jvm, no

0:45 crocket: Is racket better than clojure as a general purpose language?

0:46 Fare: maybe

0:46 I'd say yes, though clojure does have goodies.

0:46 crocket: Why is clojure getting so much hype, then?

0:46 Just because it's a good interface to JVM?

0:46 Fare: crocket: because it leverages the java environment

0:47 crocket: How typical

0:47 Fare: because it provides a relatively simple yet elegant data model and concurrency model.

0:47 tomjack: "This project is written in a literate programming format and requires Emacs & Org-mode to generate usable source code in CLJX form."

0:47 https://github.com/thi-ng/geom/blob/master/src/index.org

0:48 I am simultaneously intrigued and horrified

0:48 Fare: because it's written by someone who cares about making practical things simple and elegant — though he obviously cares less about theory or power.

0:48 crocket: Is clojure viable on android right now?

0:48 Fare: crocket, last I heard it wasn't, or barely so, but that was many months ago.

0:50 looks like something's working now:

0:50 http://clojure-android.info/

0:50 crocket: Fare, Of course, working...

0:50 " Please, expect not every feature to be present, and those that are to have bugs. It is hard to keep up with Android platform evolution and to track down all problems that may arise, but we are doing our best."

0:50 What feature

0:50 It's just a language.

0:52 Fare: I expect the language to be there, but the interface to the system to be somewhat rough.

0:52 slow startup

0:52 crocket: You mean the API binding?

0:54 Fare: probably. I don't know anything

1:22 tomjack: huh.. (defn transduce ([xform f coll] (transduce xform f (f) coll)) ...)

1:23 I wonder why not (transduce xform f ((xform f)) coll) ?

1:26 I see, cus that's wrong..

2:40 zol_: If I have a map like: {:a 1 :b 2 :c ({:d 3, :e 4}, {:d 5 :e 6})}, and I would like to assoc for example each value in [{:f 4 :g "foo"}, {:f 6 :g "bar"}] inside each map in :c respectively, how would I do that? I am actualling fetching values from an SQLite database and building my own map. So imagine that :e is a primary key and that :f is used to lookup the correct map in :c, and :g is the actual data.

2:40 So I want it to look like {:a 1 :b 2 :c ({:d 3, :e 4 :g "foo"}, {:d 5 :e 6 :g "bar"})} in the end.

2:55 ben8: hello

2:56 tomjack: ,(clojure.set/join #{{:d 3 :e 4} {:d 5 :e 6}} #{{:f 4 :g "foo"} {:f 6 :g "bar"}} {:e :f})

2:56 clojurebot: #error{:cause "clojure.set", :via [{:type java.lang.ClassNotFoundException, :message "clojure.set", :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}], :trace [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366] [java.net.URLClassLoader$1 run "URLClassLoader.java" 355] [java.security.AccessController doPrivileged "AccessController.java" -2] [java.net.URLClassLoader findClass "UR...

2:56 tomjack: :(

2:56 the answer is #{{:d 3, :e 4, :f 4, :g "foo"} {:d 5, :e 6, :f 6, :g "bar"}}

2:56 ben8: I have a small problem with vectors and functions

2:56 http://stackoverflow.com/questions/29999316/append-to-a-vector-in-a-function

2:57 tomjack: zol_: that's one way.. note you need sets of maps on both sides

2:58 I guess your case may be easier than the generality of join

2:58 ben8: anyone an idea?

2:59 basically I try to manipulate two vectors

2:59 with different length. should I first filter them to make them the same length?

3:02 tomjack: ben8: helpful to give small example inputs and outputs you want

3:05 ben8: yes. e.g.

3:05 (rowMaker ["A1"] ["B1" "B2"])

3:05 ; => [["A1" "B1“] [“" "B2"]]

3:14 tomjack: I see

3:15 so, umm

3:15 you don't do things that way in clojure :)

3:16 I can give you the answer to your problem, but not sure how helpful it will be towards understanding this point

3:16 ,(map vector ["A1"] ["B1" "B2"]) ; not quite

3:16 clojurebot: (["A1" "B1"])

3:17 tomjack: not sure what the easiest way to fix the problem is, but what you suggested can work:

3:18 ben8: yes. I understand map, apply, filter etc

3:18 where functions work on each element

3:18 but here I need a more complex expression

3:19 tomjack: I see. what you suggested can work, though: https://www.refheap.com/0ee3934217782dbac0036fe3a

3:19 er, except there's a bug

3:19 of course the second (- c ca) should be (- c cb)

3:20 as for fixing your attempt: doseq is not appropriate

3:20 all of the functions you use are pure, so there are no side-effects and your function is equivalent to (defn rowob [colA colB] [])

3:21 ben8: cool. thx a bunch

3:22 trying to understand "(map vector colA colB)"

3:25 tomjack: ,(map (fn [x y z] (cons 'got x y z)) [1 2 3] [4 5 6] [7 8 9 10])

3:25 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core/cons--4081>

3:25 tomjack: hrmph

3:25 ,(map (fn [x y z] (list 'got x y z)) [1 2 3] [4 5 6] [7 8 9 10])

3:25 clojurebot: ((got 1 4 7) (got 2 5 8) (got 3 6 9))

3:26 ben8: great. so what would be a case where doseq would be appropriate?

3:27 tomjack: for it to make sense the body should contain side effects

3:27 ben8: after writing procedural code for so long, it does take time to switch one's thinking

3:27 tomjack: swap!, reset!, println or other io... lots of stuff

3:29 all of the data structures clojure gives you are immutable, so you never use side effects to change them, with at least one minor exception which is not important to you right now :)

4:33 crocket: Is clojure slow to start on android?

4:33 otwieracz: s/ to start on android//

4:33 yes

4:34 crocket: otwieracz, Whut

4:34 Wut

4:35 I heard skummet compiles clojure into a fast binary

4:48 I think clojure is generally fast enough...

4:48 http://benchmarksgame.alioth.debian.org/u64q/clojure.html is the benchmark

4:51 otwieracz: I'm sad there's no Common Lisp

5:01 crocket: Is skummet going well?

5:02 Clojure, clojure, clojure

5:02 It is becoming platform independent.

5:03 Is it a good choice to use ClojureCLR on mono?

5:03 Or, is it just better to run clojure on JVM?

5:03 To be honest, windows feel awkward.

6:19 Why does clojure's dynamic typing get in the way?

6:19 When does clojure's dynamic typing get in the way?

6:26 TEttinger: crocket, when you're faced with unusual errors, mainly. that's the best thing typed clojure does -- it has better error messages and can detect certain things at compile time

6:26 crocket: TEttinger, static error detection.

6:27 TEttinger: yeah, it reduces the amount of JVM stacktraces, while still being optional as a typesystem

6:27 crocket: TEttinger, Where does scala or any other statically typed functional JVM language win over clojure?

6:29 TEttinger: scala wins on performance at runtime on certain types of code (oddly I think idiomatic scala tends to suffer from not having any kind of traditional for loop, only iterator for loop and the nasty while with counter), scala has somewhat faster startup and can benefit from proguard...

6:30 both clojure and scala can be optimized into performing well if you know what you're doing

6:31 clojure is very concise and tends to be clear IMO

6:31 crocket: TEttinger, Isn't scala more reliable than both java and clojure due to functional programming and strong static typing?

6:31 TEttinger: that's a hell of a loaded phrasing

6:31 crocket: When you build things that shouldn't crash, reliability matters.

6:31 things like a general library

6:31 TEttinger: scala isn't necessarily more reliable, it still ends up calling java code at its heart

6:32 crocket: What about kotlin?

6:32 TEttinger: if you're building things that shouldn't crash, Ada

6:32 not even kidding

6:32 crocket: Scala catches errors with static typing.

6:32 TEttinger: Ada is meant for keeping planes in the air.

6:32 crocket: hmm....

6:32 TEttinger: if you don't care about that, anything else is fine

6:32 crocket: Why don't people use Ada?

6:32 TEttinger: because if you thought java was verbose...

6:33 ada is typically much more

6:33 it's a painful language to write, partly by intent. it's meant to be read not written

6:33 crocket: If you want to build a stable library on JVM, a statically typed language might come in handy.

6:33 TEttinger: it has pretty much mandatory documentation so you can see who was responsible for that plane crash instead of firing the whole division

6:34 crocket: Whut

6:34 TEttinger: yeah Ada has really heavy requirements for documenting code

6:34 crocket: TEttinger, In most cases, planes crash because of humans.

6:34 TEttinger: yep

6:34 because the machines are pretty damn reliable

6:35 crocket: Humans haven't evolved to fly things.

6:35 I read "In Bini's inverted pyramid, he suggests using more-static languages at the bottommost layers, where reliability is the highest priority."

6:35 TEttinger: (like when that plane over hawaii had part of the roof tear off mid-flight, but the thing still was able to land with no fatalities)

6:35 crocket: http://www.ibm.com/developerworks/library/j-jn16/index.html

6:35 sobel: if $deity meant for us to fly, she'd have given us loads of aluminum ore, strong winds, and millenia to figure out the physics

6:36 TEttinger: sobel, heh I just implemented sobol sequences, your nick reminded me

6:36 crocket: "Next, he suggests using more-dynamic languages for the application layers, using simpler syntax for building things like user interfaces."

6:36 sobel: :)

6:37 TEttinger: i'm more used to being an edge detection alg

6:37 crocket: Ok

6:37 I think resiliency comes from functional programming more than static typing.

6:37 TEttinger: yeah

6:37 immutable data is a big aid

6:38 crocket: So, I'm going to learn clojure and build android apps in clojure.

6:38 Yay

6:38 But, what about iOS?

6:38 TEttinger: lein-fruit

6:38 crocket: How do I use clojure to build an iOS app?

6:38 TEttinger: there's something called RoboVM

6:38 crocket: TEttinger, Is clojure mature on iOS?

6:39 TEttinger: nothing on the JVM is on iOS

6:39 sobel: thanks for that article, crocket. i think i have to publish that to my team @ work. they really need to see Bini's inverted pyramid.

6:39 TEttinger: but it has been used in app store apps

6:39 sobel: clojure or clojurescript?

6:40 TEttinger: RoboVM is, IIRC, a set of APIs that let you run android-style code on iOS

6:40 any JVM lang, it could in theory do clojurescript but it would be silly to use Rhino for it :)

6:40 sobel: i've read about several apps that used clojurescript to do hybrid apps (part native, part browser)

6:40 under ios

6:40 crocket: sobel, I think Bini's inverted pyramid is obsolete.

6:40 TEttinger: yeah you could do that

6:41 sobel: crocket: i do too, but this team needs to see it before they can overcome it

6:41 crocket: I want to use the same clojure codebase to compile an app for iOS and android.

6:41 What do I do?

6:41 sobel: crocket: i have to convince them the design patterns they have are basically functional programming decayed over way too many java classes

6:42 crocket: sobel : What the hell is that?

6:42 sobel: crocket: a mess

6:42 crocket: sobel : functional programming over java classes sounds weird.

6:43 sobel, Why don't you just move to a better company?

6:43 sobel: crocket: ever work with Spring based projects heavy on the IoC?

6:43 crocket: Spring, yuck.

6:43 abomination

6:44 sobel: crocket: they didn't hire me to tell them how busted their tools are. ;)

6:44 crocket: sobel, They are probably under nonsensical deadlines.

6:44 Quit

6:44 sobel: that's adorable

6:45 crocket: At least, go to a company where deadlines are absent or sane.

6:45 sobel: 10 years ago i would have

6:45 crocket: Whut

6:45 sobel, Have you become a wage slave?

6:45 sobel: i like to think i'm compensated a bit better than that

6:45 crocket: ok

6:46 sobel, As long as the workhours are short and you're financially well compensated...

6:46 sobel: how do you suppose anything gets better, anywhere?

6:46 crocket: sobel, Your own startup

6:46 sobel, Or, my startup

6:46 sobel: startup code quality! legendary!

6:46 crocket: sobel, My startup won't impose deadlines at all...

6:47 sobel: what about your startup's clients?

6:47 crocket: There would be rare deadlines that come up once a year or two, but I'll put bounties on them to make people step up voluntarily.

6:47 sobel, just people who say little money.

6:47 sobel: that's brilliant. you wouldn't even need employees.

6:47 crocket: sobel, just people who pay little money from now and then.

6:47 sobel: you could just bounty all the work

6:47 crocket: sobel, The problem is that I want to implement open allocation.

6:48 noncom: how do i add a classpath in runtime on android? (either clojure or java)

6:48 i use clojure in a java android app through java->clojure interop and (require) evals fail to find the namespaces on the classpath

6:48 crocket: If people could depend on my bounties for their living, why not?

6:48 sobel: anywho. they did all these patterns where FP would have made it a lot simpler, even Spring would have made it a lot simpler, but instead they shoved square pegs into round holes using reflection

6:48 noncom: yeah. why do they do that?

6:48 crocket: sobel, Why do you use spring in the first place?

6:49 It's a giant framework.

6:49 sobel: <blink>

6:49 crocket: ah

6:49 you didn't

6:49 They did

6:50 "Don't get a job where spring is used"

6:50 Don't forget that.

6:50 sobel: that's ok, i don't think you understand my job or career

6:50 crocket: sobel, I don't think I do

6:51 However, I'd avoid bad practices...

6:51 sobel: i'm not a developer by trade anymore. i'm a contributor but i'm not part of the core team, there.

6:52 i might make around double what the developers are making, as a consultant. and i use a much more diverse tool set, including clojure, spring, or any of the tools i've learned over the years of my (now lengthy!) career

6:53 and i have the ear of management because i was hired by the software dev management group to work as the sole dev in professional services

6:54 so think of my role as that of a beloved uncle who flies in once in a while to give advice based on meeting with the extended family

6:54 crocket: sobel, Do you mean a bad family?

6:54 A sour family

6:55 sobel: a realistic one. you don't quit, do you?

6:55 crocket: sobel, I quit my job.

6:55 sobel: did you know all software has bugs, and none of the programming languages are perfect?

6:55 crocket: sobel, I knew

6:55 sobel: you might bring that reality a bit closer to your conversantional context

6:55 crocket: If you mean a company by extended family, my insight is correct.

6:56 Most companies are families gone bad.

6:56 sobel: this one hasn't gone bad (yet) and business is solid

6:56 crocket: sobel, ok

6:57 sobel: i can also walk to work, it's so close. and my kids' school is close. i have every reason to reinvest in this job.

6:58 crocket: Is https://github.com/oakes/lein-fruit mature enough for production?

6:58 I want to use the same clojure codebase on iOS and android!

6:59 sobel: that looks like a trust-but-verify to me

6:59 crocket: Meh..

6:59 I guess I'll have to use PhoneGap for cross-device development.

6:59 Maybe not?

7:00 God...

7:00 Robovm has fee

7:01 sobel, Have fun with your job....

7:02 Bronsa: crocket: this is getting OT

7:02 crocket: Bronsa, What is OT?

7:02 Bronsa: off topic

7:03 crocket: Bronsa, Are you a moderator of some sort?

7:03 sobel: he is, and i am, too

7:04 crocket: Probably, I should quit asking questions and just learn clojure and scala myself.

7:04 sobel: crocket: there is an official OT channel and i might be willing to engage the career topic further there but it's played out in here

7:04 Bronsa: crocket: i'm not but a scrollback full of you talking about sobel's job is not what this channel is for. there is #clojure-offtopic or irc queries for that

7:04 crocket: ok

7:05 sobel: crocket: scala keeps crossing my radar but someone in here pointed me to a video from one of the core scala contributors in which he explained why he left the language/project

7:05 i think it was enough to keep me from investing in scala for anything new

7:05 crocket: sobel, There could have been political reasons for quitting rather than technical reasons.

7:05 sobel: let me see if i can dig it out of history

7:06 oh no, they were entirely technical and he went into technical detail

7:06 crocket: better than political problems

7:06 Bronsa: I think you're talking about one of paul philips' talks

7:07 https://www.youtube.com/watch?v=TS1lpKBMkgg this one maybe?

7:07 sobel: https://www.youtube.com/watch?v=uiJycy6dFSQ

7:07 er, now i'm not sure which one

7:08 gotta watch to figure out which one was the big FU

7:08 pretty sure it's the one i posted; 3:30 in he's on the "never gonna be the language i want" topic

7:08 crocket: the language I want.

7:09 Some programmers want C.

7:09 sobel: we don't want to hear what they think

7:09 please don't confuse or conflate programming with democracy

7:10 crocket: Programming is about freedom

7:10 sobel: hahahahaha

7:10 crocket: Democracy != freedom

7:10 sobel: you are adorable. are you interested in learning to program?

7:10 crocket: sobel, I have been learning to program for a while.

7:11 I have extensive experiences with nodejs and web browsers.

7:11 javascript is not worth my career.

7:11 sobel: do you have preferences for front-end (browser) or back-end (everything else) work?

7:11 e.g. are you hoping to get into server-side development?

7:12 crocket: clojurescript, purescript, haskell, clojure, etc...

7:12 sobel, I'm going to become a mobile app dev for funding bills and a startup founder.

7:12 I'm already a good web dev.

7:12 That said, I already know how to make server programs with 'java'.

7:12 java yuck

7:13 sobel: what do you dislike about java?

7:13 crocket: sobel, It's excessively verbose, and its exceptions are annoying

7:13 Its type system is not good

7:13 sobel: can you be more specific?

7:14 crocket: java inheritance is like modern GOTO.

7:14 sobel: tell me a fact that convinces me they are annoying, don't make the judgement for me

7:14 crocket: If you inherit many times, your code becomes difficult to understand.

7:14 Java interface is not really helpful, either.

7:14 sobel: so far you've convinced me you don't understand interfaces or the hazards of multiple inheritance

7:14 Pupeno: How can I see all the options a lein template has?

7:14 crocket: sobel : I understand interfaces grammatically.

7:15 sobel: crocket: this should go to to the OT channel; we're off in the weeds

7:15 crocket: ok

7:16 Pupeno: Particularly, I want to see all the options for building a luminus app.

7:26 sobel: Pupeno: i usually google for examples at github. usually there's an app or sample that has used and documented them all.

7:36 profil: is (first (filter ...)) cheap? I thought so because filter returns a lazy seq, anyone who can confirm?

7:49 hyPiRion: profil: yes

7:50 profil: hyPiRion: great, thanks

8:01 geekyvin: hey guys, hope you are well. I am stuck with a recursive program that is suppose to traverse a graph until it finds a path back to the start node. the code is here, https://gist.github.com/geekyvin/7ac37e68a739d354e80d there is something wrong with the way I accumulate the result I couldnt find what exactly.

8:12 jack0: Hi, how many got in gsoc this year?

8:12 Any clue who they are??

8:12 lazybot: jack0: Definitely not.

8:12 jack0: lazybot: What do you mean definitely not?

8:21 hyPiRion: jack0: lazybot just responds to 2 or 3 ? at the end of a line. Right, lazybot???

8:21 lazybot: hyPiRion: Yes, 100% for sure.

8:24 jack0: I did not get you, hyPiRion

8:25 hyPiRion: jack0: lazybot is a bot. It just does (.endsWith "your message" "??|???") and replies based on that

8:26 jack0: Is that so, lazybot ???

8:26 lazybot: jack0: Yes, 100% for sure.

8:26 jack0: Haha! Thanks for pointing that out hyPiRion :)

8:29 hyPiRion: jack0: no problem, people may assume lazybot is sarcastic or arrogant sometimes because of those replies, heh. As for GSoC this year, I believe 5 got accepted: https://www.google-melange.com/gsoc/projects/list/google/gsoc2015

8:29 search for Clojure in organization there

8:31 jack0: 2 from typed , hyPiRion

8:31 Cool :)

8:31 Do you know any of these people? hyPiRion ?

8:32 hyPiRion: jack0: not any of the students, no. I've talked briefly with some of the mentors though.

8:33 jack0: Oh ok :)

8:33 Do these students become mentors next year?

8:33 and does clojure have a policy of choosing a person only once?

8:35 hyPiRion: jack0: https://groups.google.com/d/msg/clojure/phVQcZMXkLI/64lldl0d1-QJ – so afaik you can become a mentor if you'd like to, and I think you can be chosen multiple times

8:35 jack0: :)

8:37 puredanger: Correct on both counts

9:18 crocket: Is http://www.braveclojure.com/ a comprehensive material for clojure?

9:21 bcn-flor: I used it in conjunction with The joy of clojure, some things are clearer in brave clojure, but the Joy of clojure goes deeper into the language. It's also funny at times, especially the examples with zombies :)

10:30 sobel: TEttinger2: heh, so, i was just looking at sequences similar to Sobol the other day via an HN article about randomly covering a sphere with discs

10:30 rather, randomly distributing discs on a sphere

10:31 e.g. why you don't warp a plane with evenly-distributed discs around the sphere and call it good

10:54 tsunny: (println "helloroom")

10:55 hellothere: Println ("helloroom")

10:55 Not work

10:57 whodidthis: ((PrinterSingletonFactory.getInstance()).println("helloroom");

10:58 oddcully: ,(prn "makeemstop")

10:58 clojurebot: "makeemstop"\n

11:00 hellothere: whodidthis: how that string works?

11:50 Confusionist: Can someone explain the following observation: in a 'lein repl', when loading a file that contains (defmacro reverse-m [s] (list reverse s)) (println (macroexpand '(reverse-m "Hello"))), the result is the expected expansion. When I paste the same in a lein repl, I just see #'app.core/reverse-m (reverse-m Hello).

11:51 (expected expansion is a reference to the reverse function, a la (#<core$reverse clojure.core$reverse@676dbc3a> Hello))

12:45 justin_smith: that isn't a macro expansion though, that's avar resolution

12:50 Confusionist: In the first case, the the result is, effectively, (reverse "Hello")) (with a resolved 'reverse') . In the second case, the result is (reverse-m "Hello")

12:51 justin_smith: reverse isn't the resolution, it's the expansion

12:52 macroexpand doesn't do any resolution, only expansion

12:52 well, it does just enough resolution under the hood to look for macros, sure

12:53 but it doesn't want to show you the vars (or the functions they resolve to), just the symbols generated by the macros, recursively

12:59 Confusionist: I don't understand. Let's go through this step by step. I have a file with the previous macro definition and a line (println (macro-expand '(reverse-m "Hello"))). My expectation was that it would print (reverse "Hello"). When I (load "file") in the lein repl, it indeed prints what I expected. If I subsequently say enter (println (macroexpand '(reverse-m "Hello")) into the repl, I expect to see the same. That is not the case: it prints (rev

12:59 erse-m Hello). Is my second expectation wrong?

13:00 justin_smith: is reverse-m in scope?

13:00 ,(println (macroexpand '(reverse-m "Hello")))

13:00 clojurebot: (reverse-m Hello)\n

13:00 justin_smith: if it can't find the definition, it can't expand it

13:01 Confusionist: Ah

13:14 OK, thanks, that explains. Unfortunately I'm now puzzled about the scoping issue that causes this. If I simply copy paste (defmacro my-first-macro [] (list reverse "Hello World")) (my-first-macro) from a tutorial into this repl, I get an "Attempting to call unbound fn: #'app.core/my-first-macro".

13:14 justin_smith: that shouldn't happen

13:15 ,(do (defmacro my-first-macro [] (list reverse "Hello World")) (my-first-macro))

13:15 clojurebot: #error{:cause "EvalReader not allowed when *read-eval* is false.", :via [{:type java.lang.ExceptionInInitializerError, :message nil, :at [sun.reflect.NativeConstructorAccessorImpl newInstance0 "NativeConstructorAccessorImpl.java" -2]} {:type java.lang.RuntimeException, :message "EvalReader not allowed when *read-eval* is false.", :at [clojure.lang.Util runtimeException "Util.java" 221]}], :trace [...

13:16 justin_smith: evalreader?

13:16 hmm

13:16 Confusionist: Hmm.. ok, I'll have to throw out dependencies, plugins and user.clj code to find out what's causing it

13:16 I'll be back :)

14:12 profil: How do I use leiningen without a project.clj? I dont want to create an entire project, just need some dependencies. How do I add them to the classpath when running a standalone lein repl?

14:12 justin_smith: profil: perhaps the lein-try plugin?

14:13 or you could use a vanilla repl with clojure.core and pallet/alembic as the classpath, and use alembic to load deps. Maybe that would work.

14:13 seancorfield: I'll +1 lein-try

14:30 darthdeus: guys, how can I use extend on this protocol? https://github.com/clojure/data.json/blob/master/src/main/clojure/clojure/data/json.clj#L286-L288 I'm trying (extend org.httpkit.server.AsyncChannel json/JSONWriter (-write [ch out] (json/-write (str ch) out))) but I get "unable to resolve symbol -write"

15:22 Reefersleep: Hey everyone. Haven't been on IRC in ages, but I figured it'd be neat to talk to someone about the obstacles I come upon when trying to delve into Clojure in my spare time, and I don't know anyone who does Clojure in my area. So hi!

15:25 Anyone here who uses Clojure in their day job? :)

15:37 Everyone always mentions the brackets whenever I show them Clojure code. I can see it in their eyes before they even say anything. "My god, it's full of parens"

15:38 Fare: did I mention that clojure has fewer parens than java? Because Java involves 4 times as many function calls...

15:47 oddcully: Fare: but 50% if your code i autogenerated from your ide, so at least those don't count ;P

15:48 s/if/of/

15:52 Reefersleep: yes, in this channel are regulars, that (claim to) have jobs doing clojure or doing it anyway (programming anarchy)

15:56 whodidthis: clojure replaces parens, brackets, semicolons and colons with beautiful rainbows

16:15 sidharth1: how can i get ring to not add a charset to the content-type in the html headers ?

16:19 hiredman: ring doesn't do that

16:20 jetty does, and different servers may do it differently

16:21 apparently it is part of the servlet spec, so any server you use via a ring-servlet adapter is going to have that

16:22 if you add your own charset then that will be used

16:37 michaelr`: hi

16:43 Anyone interested in a remote Clojure/ClojureScript job?

16:55 justin_smith: michaelr`: I'd ask again during work week hours, I bet someone is

16:56 michaelr`: ah, it's weekend ;)

16:56 justin_smith: thanks

16:58 oddcully: can we deduce some work-life-ballance from this? ;P

16:58 justin_smith: :)

16:58 michaelr`: justin_smith: sent you my email

16:58 oddcully: i bet justin is now doing the life part of the balance

16:59 dfletcher: hi I wrote this neat little chunk to launch my javafx based app http://pastebin.com/b27RHWJX . it requires doing a gen-class because javafx's launch() function takes a class arg and does the construction. anyone know a nice way to pass a configuration argument to myapp-desktop-start ?

17:01 I could rebind a def of course but every tut says it's bad form :)

17:04 speaking of not knowing what alternatives there are to rebinding defs, a second question I have is how would one go about doing user modifiable preferences in a UI app? don't want to pass around prefs everywhere and have references to possbily outdated ones in a closure or callback or so. help me OB1 Kenobe I'm so confused :>

17:07 oddcully: michaelr`: you accept more work-part offloading?

17:08 justin_smith: dfletcher: for a lib, use explicit args, for a frontend, use a global mutable state, preferably in edn so it is easy to read, manipulate, store, restore etc. from clojure

17:12 dfletcher: thanks for giving me some keywords to search for justin_smith

17:13 justin_smith: putting all user-controlled app config in a single map in an atom is a pretty natural choice

17:13 dfletcher: I was thinking along similar lines but was contemplating just a Java map. this seems much better.

17:14 justin_smith: advantage over java map is you get very good concurrency control, and clojure can output it to a human readable /a editable form very similar to json

17:14 hell, we even have good two-way json conversion :)

17:14 dfletcher: nice that's what I was thinking of using to store it heh

17:17 plus i'm sure the syntax will be nicer in clojure this way with keyword lookups and destructuring instead of .get

17:17 ok so this leaves this little jerk :) http://pastebin.com/b27RHWJX

17:17 javafx wants to construct my class, don't see a way around it

17:18 guess I could put the window state into the prefs and query it from inside there but that seems weird. UI saved state is separate from prefs.

17:19 justin_smith: yeah, it should be

17:25 dfletcher: ah wait I have an idea. what I actually really need inside there is mostly just the location of the user's data dir. if I made that a preference I could read *that* off global prefs and then just do all read/write ops inside my application class. that seems decent.

17:26 justin_smith: yeah, much cleaner

17:26 and data dir could come in via arg, or env, or a default, or a global config dir, or whatever

17:26 system property...

17:26 dfletcher: yeah when I first init the prefs

17:26 or user could override it in the UI even :)

17:27 justin_smith: and persist that to a config - but how do you find it next time!

17:27 PARADOX

17:29 dfletcher: heh right good point. command line config then, or user.home

17:50 bobpoekert: core.match has “wildcard” (match one occurrence of anything) but not kleene star (match any number of things), right?

17:50 has anyone tried to add kleene star?

17:50 I’m thinking of using core.match as an xpath replacement and being able to do the equivalent of // is important

17:55 tomjack: (no, but curious:) suppose you write a ([x y] :*) pattern and match against [[1 2] [3 4]]. what would x and y be bound to, [1 3] and [2 4]?

17:57 bobpoekert: I wasn’t thinking of having the star be capturing, so it would just be [1 2]

17:58 if it were capturing maybe it would return a seq of the body evaluated for each capture?

18:00 I was thinking more: {:children [:* {:tag “div” :class #”price” :value price}]}

18:00 which would be equivalent to //div[@class~=price]/value() in xpath

20:35 crocket: Can anybody recommend a good clojure learning material for a layman?

20:35 I actually am a programmer, and I want to learn clojure.

20:44 blkcat: crocket: perhaps clojure for the brave and true?

20:45 crocket: blkcat, Where is it?

20:45 blkcat: http://www.braveclojure.com/

20:49 crocket: blkcat, Isn't it a work in progress?

20:53 blkcat: crocket: my understanding is that it's largely completed, though it may receive some updates once he's done working on the print version

20:57 crocket: blkcat, like fixing typos?

21:01 blkcat: presumably

21:01 you'd have to ask him :) but i think you'd be perfectly safe using it as a learning tool.

22:52 dpathakj: ojure

Logging service provided by n01se.net