#clojure log - Jan 07 2013

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

0:00 dog_cat11: hey guys, I was wondering if anyone out there had experience doing text parsing in clojure

0:00 if so, what packages, clojures functions are you using for file i/o, and parsing(regex's)

0:00 TimMc: Just regexes, not CFGs?

0:00 gtrak: file i/o is easy, take a look in clojure.java.io

0:01 clojurebot: Alles klar

0:01 gtrak: what is file i/o?

0:01 clojurebot...

0:01 dog_cat11: just packages to read in and out text files

0:01 a fair amount of the programming i do is in perl

0:02 gtrak: java has those built in, clojure wraps them nicely

0:02 TimMc: dog_cat11: Have you seen slurp and spit?

0:02 dog_cat11: yeah, i've used that before

0:02 a disadvantage is if the file is huge

0:02 or at least I don't know how to load it lazily

0:02 gtrak: inputstreams and readers do that job

0:03 generally you do something like (reader (resource uri)), then you've got a java Reader to play with

0:03 TimMc: dog_cat11: If you need random access, I think the Java stdlib provides memory-mapped I/O.

0:03 but otherwise just use lazy operations

0:04 amalloy: TimMc: it does, but that's certainly not the only way to get random access

0:04 TimMc: I'm sure. I've never had to look into it.

0:06 dog_cat11: @TimMc, just regular expressions not any other finite automata

0:06 TimMc: You just need to rip through a file linearly and spit out some output, right?

0:06 dog_cat11: exactly

0:07 complications include multiline entries, and files larger than RAM

0:13 it looks like slurp runs a loop to append chars, I may write a lazy-seq version that returns line by line

0:13 gtrak: i think that exists already

0:14 &(doc line-seq)

0:14 lazybot: ⇒ "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

0:14 technomancy: ,(doc line-seq)

0:14 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

0:14 jkkramer: dog_cat11: https://www.refheap.com/paste/8167 shows the basic thrust

0:16 dog_cat11: oh, that's prime

0:17 no all I have to do is convince my boss to learn lisp...

0:24 damn, there are so many great clojure functions out there

0:24 aperiodic: i'm trying to use the http.async.client, but whenever I try to GET anything, it fails with a java.net.ConnectionException

0:24 anyone have any idea what might be going wrong?

0:32 tomoj: aperiodic: doesn't the ConnectException have a message?

0:36 aperiodic: tomoj: the message is just the URL that failed ("http://google.com")

0:36 dog_cat11: what are people using for IDE's?

0:36 bpr: emacs w/nrepl

0:39 dog_cat11: thnx

0:39 i've just been using vi and lein from the command line

0:40 aperiodic: there's good vim support

0:41 i use a combination of vimclojure (for highlighting, formatting, and paredit) and slimv (to connect to a swank server for sweet editor integration)

0:41 tpope: time to add a little foreplay.vim, my man

0:41 dog_cat11: i guess so!

0:42 aperiodic: tpope: does nrepl still only do a namespace at a time, or can i have multiple editor sessions connected to the same nrepl server with a different ns for each?

0:43 tpope: clarify multiple editor sessions

0:43 aperiodic: multiple instances of vim

0:44 tpope: I guess either way, the answer is you can have as many nses as you like

0:44 note the workflow in foreplay.vim is a bit different. the ns used is always the one for the current file

0:45 aperiodic: that's acceptable

0:45 i think

0:45 i'll give it a shot

0:47 is there no 'evaluate the toplevel form the cursor is in' command?

0:47 tpope: aperiodic: there's not. it would be easy to add. I've just been repositioning and using cpp

0:47 bbloom: what's your current thoughts on evaluating the top form?

0:48 aperiodic: i would love that

0:48 bbloom: tpope: i still use cpap more than cpp, but cpp is crazy useful when i need it

0:48 dog_cat11: ccw for eclipse can do that

0:48 bbloom: tpope: i also use cp$ and cpw quite frequently

0:48 tpope: aperiodic: actually :Eval technically defaults to the top level form

0:49 bbloom: tpope: is :Eval the same as cpap or is it actually matching braces?

0:49 tpope: but I'm sure the shift key is an ABSOLUTE DEALBREAKER

0:49 bbloom: it matches braces

0:49 parentheses only, but I could make it do braces

0:49 bbloom: tpope: parens is what i meant

0:49 tpope: and brackets

0:49 bbloom: tpope: is there a standard shortcut for :Eval ?

0:50 b/c cpap only works when i don't have blank lines

0:50 tpope: no

0:50 bbloom: but i tend to only have blank lines in my deftype or extend-protocols, in which case i need to cpr anyway

0:50 tpope: I was thinking cpo would be "outer"

0:50 bbloom: is there a cpi ?

0:50 "inner" ?

0:50 tpope: well that's what cpp is

0:50 bbloom: right, but does cpi do that?

0:51 it would be nice if cpi and cpo both worked, and i'd vote for cpp to be cpo

0:51 tpope: cpi is half a command. i is the first letter of a text object

0:52 bbloom: tpope: ah yes, dug

0:52 duh*

0:52 sometimes i forget things that my fingers know

0:53 my biggest complaint (which is admittedly a small complaint) is that cpap will move my cursor to the top of the paragraph, so i have to manually move back there

0:53 but that's just the behavior of text objects, i guess

0:53 tpope: yeah I'm really reticent to do things differently than vim does

0:54 actually, the way I was planning on implementing cpo would mandate that behavior, I think

0:54 bbloom: did you make any progress on the error window?

0:54 tpope: some!

0:54 bbloom: sweet

0:55 tpope: though I don't remember what I discussed with you

0:55 bbloom: you have no idea how much you've improved my clojure-ing

0:55 :-)

0:55 tpope: oh you mean the stacktrace parsing

0:55 I have a stacktrace parser working

0:55 bbloom: cool

0:55 tpope: I don't have a good way to get stacktraces out of nrepl

0:56 bbloom: is cemerick helping?

0:56 tpope: he said a middleware is probably the way to go

0:57 bbloom: hmmm :-/ seems like stack traces should be a common thing! did he say anything about session clones?

0:58 tpope: the main thing he said was that ccw uses .printStackTrace

0:58 bbloom: on e* ?

0:58 tpope: I assume. I didn't ask

0:58 I guess he could be wrapping all evals in a try

0:58 I am seriously considering that

1:00 bbloom: hm... part of me thinks "of course that would work" and another part of me is like "the top-level is hopeless, don't make it worse"

1:00 but i'd have to think more deeply about it

1:00 tpope: yeah I hate to change the outcome by measuring it

1:01 bbloom: tpope: well the issue is that "(do 1 2)" isn't technically the same as "1 2"

1:01 the former is a single compilation unit, the later is two compilation units

1:01 but i dunno if it would matter for the foreplay usecase

1:01 tpope: bbloom: I've already accepted that reality for the one-off runner

1:02 bbloom: i suspect that the try/catch would be fine & that if it ever isn't fine cpr would be the answer

1:02 tpope: actually, that's a good guestion

1:02 is there a good way to read / eval all forms in a file?

1:02 read gets one form

1:03 bbloom: i'm not as familiar with clojure's top level as i am with clojurescript's

1:03 but the only things i know of are basically load-file

1:04 technomancy: tpope: open a reader and repeatedly call read on it

1:04 you can tell read to give you a sentinel value when it hits EOF

1:04 tomoj: what's the recursive? param mean?

1:04 tpope: that's kind of what I figured

1:05 bbloom: :vim-foreplay/eof

1:06 technomancy: (take-while (partial not= ::eof) (repeatedly (partial read rdr)))

1:06 err: (take-while (partial not= ::eof) (repeatedly (partial read rdr false ::eof)))

1:06 tpope: I guess the only implication of this is that I could output multiple values if multiple forms were passed in

1:07 technomancy: good deal, that's not so bad

1:07 bbloom: ,(do 1 2)

1:07 clojurebot: 2

1:07 bbloom: tpope: just do with that :-)

1:07 tpope: bbloom: that's what I'm doing in the one off

1:07 tomoj: the only use of the recursive? parameter I see is that the reader will throw an exception in certain circumstances if recursive? is true

1:07 tpope: bbloom: and for symmetry, in the nrepl adapter, I drop all but the last value

1:08 technomancy: tpope: course you can just slap a () around the text you want to read and read it as a single form too

1:08 tpope: technomancy: exactly what I've been doing, with a do in there because I want to eval it

1:09 technomancy: tpope: as long as you're aware of the gilardi scenario you're probably in good shape

1:11 tpope: technomancy: oh yes, that. yes, I bumped up against it and figured it out

1:11 bbloom: gilardi?

1:11 clojurebot: the gilardi scenario is what happens when you try to require and use a var in the same block of code: http://technomancy.us/143

1:12 bbloom: holy hell. clojurebot was actually useful!

1:12 ~botsnack

1:12 clojurebot: Thanks! Can I have chocolate next time

1:12 Sgeo: Racket solves that by ... require not being a function :(

1:13 arrdem: what the shit! clojurebot answered a question!

1:13 Sgeo: Hrm, well, I think I don't understand the problem\

1:13 If I did, I could contemplate Racket's take. But Racket's being annoying in how undynamic it is

1:13 bbloom: clojurebot seems to love question marks... but that's the first time it actually was really useful

1:14 you know what i mean??

1:14 lazybot: bbloom: Definitely not.

1:14 muhoo: two bots, no waiting.

1:16 tpope: bbloom: I'd also need to come up with an elegant way to send the stack trace over the wire and pick it out on the other end

1:16 bbloom: tpope: print-str

1:17 er rather pr-str

1:17 tpope: no I mean like

1:17 bbloom: oh in vim?

1:17 arrdem: is error info not serializable?

1:17 bbloom: so you need something regex friendly? like tab delimited lines?

1:17 tpope: I could use .printStackTrace, but anyone who prints a stacktrace would then see it silently slurped up into the internals

1:18 the output of .printStackTrace is fine. I just need to recognize *my* printStackTrce

1:18 I guess I could use stderr? that seems pretty seldom used in java land

1:18 or clojure land, at least

1:18 bbloom: i wouldn't rely on that, since it's just a (binding [*out* *error] ...) away

1:19 tpope: so what should I do? I need in band signaling that's unlikely to cause a problem in practice

1:19 bbloom: http://en.wikipedia.org/wiki/Private_Use_(Unicode)

1:19 tpope: I'll still do a sanity check against a regex

1:19 bbloom: you basically need a magic sequence like JPG or something

1:20 tpope: this could work

1:20 bbloom: i'd go with a random unicode private use byte followed by FOREPLAY or something like that

1:20 arrdem: 0xBAD1D3A

1:20 bbloom: heh

1:20 arrdem: there's your magic string.

1:20 tpope: until nrepl gives me a clean way to get it back, my options are limited

1:22 bbloom: tpope: cljs makes use of some private chars for keywords and symbols encoded as strings

1:22 seems to be a pretty useful approach

1:22 presumably you're never writing such characters to stdout unless you're expecting them

1:23 tpope: okay I think I have a good-enough approach

1:23 bbloom: use a "non character"

1:23 So, noncharacters are: U+FFFE and U+FFFF on the BMP, U+1FFFE and U+1FFFF on Plane 1, and so on, up to U+10FFFE and U+10FFFF on Plane 16, for a total of 34 code points.

1:24 One particularly useful example of a noncharacter is the code point U+FFFE. This code point has the reverse binary sequence of the byte order mark (U+FEFF)

1:24 not that one :-)

1:25 tpope: so (try a b c (catch Exception e (print whatever) (throw e)))

1:25 right?

1:25 clojurebot: Equal Rights for Functional Objects is Baker's paper on equality and why it's impossible to define sensible equality in the presence of mutable data structures: http://www.pipeline.com/~hbaker1/ObjectIdentity.html

1:26 bbloom: (dec clojurebot)

1:26 lazybot: ⇒ 13

1:26 bbloom: heh, bot bashing

1:26 tpope: i think so... is that how you re-throw correctly?

1:27 do you want to re-throw?

1:27 tpope: yeah I do, I think

1:27 and no idea if that's correct

1:28 bbloom: who are you re-throwing to? some up-stream nrepl middleware?

1:28 tpope: bbloom: I guess. I still want *e to be recorded and whatnot

1:28 bbloom: ah, yes, that makes sense

1:28 i guess you need to look for your magic string and then not show the stack trace twice

1:29 tpope: bbloom: if it sent the stacktrace back, this wouldn't be an issue :)

1:29 it's deliberately omitted

1:30 bbloom: the other approach is to wait 25 years until light table is as feature rich as vim :-P

1:30 tpope: or 10 years until evil mode is a strict superset of vim

1:32 bpr: or 1 year to lear emacs...

1:32 * bpr *ducks*

1:32 bpr: :-p

1:42 ro_st: 1 year. that's optimistic

1:47 ibdknox: bbloom: hey, give me a break. 24 years.

1:53 oskarth: ibdknox: when you were using vim, how did you normally interact with the repl?

1:54 ibdknox: oskarth: vimclojure - tpope hadn't written his stuff yet :)

2:04 muhoo: ro_st: i've been using emacs for exactly 10 years now and i'm just starting to learn it

2:04 like daily, and for everything.

2:06 ro_st: muhoo: yup. do you use orgmode?

2:17 freakazoid: How do I import a class from a .java source file that has no package declaration?

2:17 the class name is the same as the filename, but (import 'classname) from the repl doesn't seem to do the right thing

2:17 I get a class but it doesn't seem to be the right class - doesn't have any of the static fields on the actual class

2:22 muhoo: ro_st: i do indeed.

2:23 in fact, one of the great troubles i have after getting an android tablet, is how to do org mode on it.

2:24 freakazoid: muhoo: MobileOrg is not working for you?

2:24 muhoo: i haven't tried it. the syncing looked sketchy to me

2:24 i'm a git kind of guy.

2:24 ro_st: i reckon orgmode is one of the better ways to get hands on with emacs

2:25 i speak as someone who hasn't actually tried, of course.

2:25 muhoo: it appears from looking at clojure source, like the relevance guys use org mode

2:26 noidi: freakazoid, you can't just import things from .java source files. you have to compile them into .class files and place them on the classpath.

2:26 muhoo: gawd, one more hour of having to write stuff like EditNormalTempDialogFragmentListener, and i'm going to go insane

2:26 freakazoid: noidi: Sure, I know that... I am using a bunch of them and most of them are working fine

2:26 noidi: It's in my java source directory and I ran lein javac

2:26 muhoo: time to bust out my cljs project soon

2:27 freakazoid: noidi: I think the problem may actually be that none of the members have an access declaration, though I'm not sure how the java stuff works either in that case

2:27 noidi: the default access is "package private"

2:28 which means that only things within the same package can access the members

2:30 freakazoid: noidi: ok, that explains that part. And I got the (import) syntax. What's the :import syntax?

2:30 tomoj: freakazoid: there's no reason to import if there's no package. but put it in a package!

2:30 freakazoid: ohh

2:30 tomoj: I can add more exclamation points if necessary

2:35 freakazoid: hmm, but now I have an illegal access error

2:35 though I've declared the (static) methods I'm accessing public and the class is public

2:35 it's possible my repl is hosed

2:36 yup, that was totally it. thanks, tomoj! (i put it in a package since I had to modify the file anyway)

2:36 tomoj: you have to restart the repl every time you javac :(

2:37 freakazoid: grumble grumble

2:37 Well, now I have working ed25519 signatures in Clojure at least :)

2:38 noidi: if you do a lot of Java programming, you might want to invest in JRebel http://zeroturnaround.com/software/jrebel/

2:38 freakazoid: I do no Java programming.

2:38 And I don't plan to start.

2:38 noidi: it allows hot-swapping Java classes without restarting the process

2:39 freakazoid: Night, everyone. Thanks for your help, noidi and tomoj.

2:48 muhoo: hmm, hotswapping java classes would be useful in clojure for interop stuff

3:03 ppppaul: i'm uploading a file to my ring server... i am able to get all the details i need cept the file name, how would i do this?

3:05 ro_st: ppppaul: inspect the ring request directly. reading through the headers in that map should give you what you want.

3:07 ppppaul: i did

3:07 but i don't get a file name

3:07 i'm appending the file name onto the end of the post url for now... but it seems a bit hacky

3:09 ro_st: that's odd! i'm pretty sure the filename is included with file upload form posts?

3:09 ppppaul: i'm not using a form

3:09 i'm using curl

3:09 ro_st: :-)

3:10 bing.

3:10 ppppaul: maybe i should make it look like a form post

3:10 ro_st: the file can't know what it's own name is

3:11 ppppaul: i'm just getting a stream

3:11 i'm glad that it tells me how large it is

3:12 ro_st: appending a filename is fine. browser does the same

3:16 ppppaul: that's what i'm doing now

3:16 ro_st: good idea to mimic the form post if you plan to use that eventually

3:17 ppppaul: i have never used a form post

3:17 too sexy for forms

3:17 i'll look into using them, though.... may save me headaches

3:36 klang: Anybody using nrepl.el in a remote host setting?

3:36 ro_st: sometimes, yes

3:36 autocomplete really slow, unfortunately :-(

3:37 klang: are the two hosts of different os type?

3:37 ro_st: osx > ubuntu

3:37 klang: ok .. does M-. work for you, on buildins .. like 'map'? (regardless of speed)

3:38 ro_st: ah. i don't think so. it's a little tough to test right now, sorry

3:41 klang: ok .. I've made a setup here: https://github.com/klang/repl-tests and am trying to fix it .. autocomplete could be fixed as well, if emacs can be tricked to look at local files instead of the remote files, I suppose.

3:44 I have a clojure instance running for weeks on a CentOS machine, connecting to it via my corp isued Windows7 machine .. so I'm almost always connecting remotely (also at home where I use Suse/mac) the failing nrepl-jump can be fixed. On the positive side, slime/swank fails in the same manner..

3:44 tomoj: swank works with some tramp magic

3:47 klang: hmm, so, I guess slime/swank isn't entirely deprecated for my usecase, yet.

3:47 fmardini: Hi, is their a macro that wraps cond and prints the form that matches (for debugging)

4:12 wingy: so when using a compojure route the number is a string eg. (GET "/item-types/:item-type-id" [item-type-id] ...

4:13 is there a way to get the item-type-id as a float directly or do i have to do (let [item-type-id (read-string item-type-id)] myself

4:13 ro_st: you have to float it directly. (float str) or (read-string str) if str has "." in it

4:14 i had to do the same thing with datomic ids and (Long. str)

4:15 wingy: ro_st: should i use float or Long. ?

4:16 tomoj: is the item type id really a float?

4:16 ro_st: i used long because i had Longs. you should use float if you have floating point numbers.

4:16 wingy: yeah

4:16 tomoj: floating point ids seem.. weird

4:16 aperiodic: agreed

4:16 i mean, who would want to use the reals for ids

4:17 there's an uncountable amount of them between any two. seems odd

4:18 when i think ids i think "counter"

4:18 tomoj: I guess if you're parsing it from a short string you won't run into rounding issues?

4:20 ro_st: surely there are enough ints to go around?

4:30 tufflax: tpope: I tried with Python, it works well. The only problem is that if I have Ruby on my path, which maybe I want, vim-foreplay will go with Ruby and be slow

4:41 tpope: Maybe there could be an option I can set in my vimrc which one of Ruby and Python I prefer?

4:53 Raynes: Yikes.

4:53 Scala has macros now.

4:54 Fossi: scala has everything

4:54 Raynes: But macros. Ugh.

4:54 dbushenko: scala is way too complex

4:55 it hasn't clojure's simplicity :-)

4:55 Raynes: Macros seem like a ridiculous thing for Scala to have.

4:55 The language is already so unreadable that it's crazy.

4:55 dbushenko: :-D

4:55 even haskell is more readable :-)

5:02 snowylike: when did they add macros?

5:02 dbushenko: in 2.10

5:03 I think, its a trend now

5:04 .NET also has some facilities for metaprogramming

5:04 I mean in compile-time

5:04 clgv: mozilla implemented macros for JS ;)

5:04 dbushenko: yep, definitely its a trend

5:10 clgv: does scala have a certification program with a certificate that states you know everything about scala? ;)

5:11 dbushenko: ahahaha! :-D

5:12 I think, there should be lots of highly restrictive guidelines or best practices for Scala

5:12 like for Perl years ago

5:13 or like for C++

5:13 Fossi: i'd write my scala in this way anyway (call: foo (other: bar baz)) :>

5:14 dbushenko: btw, :> -- is a type restriction in scala ;-)

5:14 Fossi: "functionname:" is such a broken concept

5:14 changing binding according to the last letter in the methodname... i mean... srsly? -_-

5:36 wei_: how do you debug project.clj? for example, I'm getting "clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentMap" without a stacktrace, when running a lein task

5:38 kovas: wei_: you probably left out some [] around a sub clause within a :require clause

5:41 wei_: kovas: my code seems to work outside of project.clj though

5:42 would you mind taking a quick look? https://www.refheap.com/paste/8170

5:42 ro_st: does lein repl work?

5:42 you could try starting a repl from another project and using (read-string (slurp "path-to-broken-project.clj")) to possibly get a line number

5:43 wei_: yes. but "lein cljsbuild once main-dev" doesn't

5:44 andrewmcveigh|wo: wei_: just a guess... don't you need to unquote ~build-opts ?

5:45 ro_st: i'd load-file that in a repl and inspect the output of (pr-str buld-opts)

5:45 wei_: andrewmcveigh|wo: ~build-opts seems to work! why?

5:46 when referencing a value in non-project.clj code I don't need the unquote

5:46 andrewmcveigh|wo: wei_: something to do with the defproject macro, to eval forms you need to unquote

5:47 wei_: don't know anything deeper than that I'm afraid.

5:47 wei_: ah. thanks for the tip

6:01 abp: Any pointers on how to decide which server to use to deploy Clojure web apps? We will not use any cloud services. So the decision is between jetty, immutant or deployment into a servlet container like tomcat.

6:02 ro_st: we're using jetty so that we can avoid having to jar files

6:02 we'll go the jar route once it's clear that it's a performance issue

6:03 having said that, we do this on EC2 :-)

6:04 immutant is quite a big commitment, because it's a turn-key app server

6:04 so you might paint yourself into a corner down the road if you decide you want off of it, and you're now using all its apis

7:07 Rogach: Hello! Why is this not working: (clojure.set/intersection #{1 2} #{2 3}) ?

7:07 babilen: Rogach: What exactly doesn't work? I don't see a problem

7:08 #(clojure.set/intersection #{1 2} #{2 3})

7:08 Rogach: babilen: In my repl, it gives "ClassNotFoundException clojure.set java.net.URLClassLoader$1.run (URLClassLoader.java:202)"

7:09 ro_st: do you have clojure.set required?

7:09 (require 'clojure.set)

7:09 babilen: Rogach: Which repl is that and which version of Clojure? It works fine there with leiningen2 on 1.5-RC1 and 1.4.0

7:09 Rogach: babilen: Plain 1.4.0, without lein.

7:10 babilen: Rogach: I would recommend to use leiningen2's "lein repl" -- Does it make a difference if you require the namespace as suggested by ro_st ? How do /you/ get a REPL?

7:11 Rogach: babilen: Yes, ro_st's suggestion worked, thanks!

7:11 babilen: java -cp clojure.jar clojure.main

7:11 babilen: (+ rlwrap)

7:13 babilen: Rogach: Give leiningen2 a try -- You will not want to miss it

7:13 Rogach: babilen: Thanks, I'll try it.

8:36 _wingy: is immutant a platform like heroku?

8:37 Raynes: No.

8:37 sundbp: _wingy: it's self-hosted

8:37 clgv: _wingy: an application server based on jboss afair

8:37 sundbp: _wingy: and provides things like schedules jobs, messaging, queues, etc

8:37 cemerick: _wingy: see http://immutant.org/

8:38 sundbp: _wingy: and don't let the jboss bit scare you, it's a very nice clojure only api and no XML involved

8:38 :)

8:38 _wingy: so i can use heroku to serve my app that is using immutant?

8:40 sundbp: _wingy: yes, i would think so bar any heroku restrictions

8:45 _wingy: is it production ready?

8:46 jcrossley3-away: _wingy: immutant won't run on heroku just yet

8:47 jcrossley3: _wingy: there are some folks using immutant in production, but we haven't released a 1.0 yet

8:47 _wingy: how should i host my app then?

8:48 does redhat have something like heroku where u just push things up?

8:48 dbushenko: why do you need immutant at all?

8:48 jcrossley3: _wingy: http://openshift.com

8:48 dbushenko: its just a server

8:48 you may choose any

8:49 ro_st: _wingy: https://devcenter.heroku.com/articles/clojure

8:49 dbushenko: ring, tomcat, glassfish -- doesn't matter

8:49 _wingy: dbushenko: im just curious about how it can help

8:49 cemerick: dbushenko: this is like comparing languages by reference to turing completeness

8:49 dbushenko: it has some nice features like bacground job

8:49 but you still need a servlet, like ring, a routing library like compojure, etc.

8:52 tcrawley: _wingy: no, immutant is something you host yourself

8:52 ha

8:53 but you can run it on openshift http://immutant.org/news/2012/12/11/openshift-postgresql/

8:54 _wingy: can i use datomic with it?

8:54 tcrawley: (it's a bit of a hack to do so atm)

8:54 _wingy: no, immutant won't currently run on heroku

8:55 jcrossley3: tcrawley: you're kinda repetitive today ;)

8:56 tcrawley: you can get it to run on heroku, but the value is limited, since each dyno ends up being a full immutant process

8:57 jcrossley3: _wingy: you can use any clojure library with immutant, including datomic.

8:57 _wingy: ok

8:58 reading about what an app server is and how it can help me

9:00 * cemerick volunteers to be tcrawley's Anger Translator

9:01 _wingy: http://www.infoq.com/presentations/Introducing-Immutant

9:02 cemerick: "Heroku?! You people with your hippy-dippy ruby platforms. gtfo!"

9:02 ;-)

9:03 jcrossley3: cemerick: you're projecting way too much anger onto tcrawley :)

9:04 cemerick: jcrossley3: nah, just projecting what I'd be thinking if I were getting asked about heroku every day.

9:04 s/getting/being

9:04 * cemerick 'll get this English thing right someday.

9:05 ro_st: not your first language, then?

9:05 cemerick: har, har

9:08 jcrossley3: cemerick: getting sounded just as correct as being to this english speaker

9:10 Raynes: cemerick: Morning.

9:13 cemerick: Raynes: Morning. :-)

9:14 jcrossley3: It's formally incorrect IIRC. I couldn't quickly find a relevant page on english.stackexchange.com though.

9:17 Raynes: alexbaranosky: Just rewrote laser's tests with midje.

9:21 tcrawley: cemerick: thanks - I *was* angry, but not over the heroku questions. my messages where reaching the channel late, out of order, and only half of the time

9:22 ro_st: were* -hide-

9:23 tcrawley: ro_st: thanks. it's important we keep the standards high here.

9:23 uvtc: If I were asked about being asked, I'd say getting asked is better than not having been asked at all.

9:23 tcrawley: uvtc: yes indeed. I'm happy to chat about it.

9:24 ro_st: what's ridiculous is that we all know precisely what you meant, and i corrected you anyway.

9:24 tcrawley: :)

9:24 uvtc: (sorry, missed what tcrawley was talking about --- just making a joke about how much gunk the english language tends to contain)

9:25 tcrawley: ha

9:25 I think I'm going to go back to bed

9:26 jcrossley3: tcrawley: i thought you were "happy to chat about" the subtle semantic differences between getting, being, and been. ;)

9:35 jonasen: cemerick: according to https://github.com/clojure/tools.nrepl/blob/master/doc/ops.md#eval :session is _required_ in a {:op :eval ..} message. But the example at https://github.com/clojure/tools.nrepl#talking-to-an-nrepl-endpoint-programmatically it is not present in the message. Which one is correct?

9:41 cemerick: Also, in some design docs i read it says that session id's are provided by the server and message id's are for the client to create. Is this still the case?

9:43 cemerick: jonasen: Yes, any string will do for messages. Those are purely for the client's benefit, whereas session IDs correspond to a server-side resource.

9:44 jonasen: cemerick: so if I want to create a new session I should call {:op :clone}?

9:44 cemerick: right

9:44 Yeah, that eval :session doc is misleading. :session isn't strictly required, but not identifying one will use a temporary session that will be disposed of immediately once evaluation is complete

9:45 jonasen: cemerick: ok. That makes sense. Thanks!

9:46 cemerick: do message-id's have to be string or can I use a long?

9:47 cemerick: jonasen: I *think* it can be either.

9:53 thorwil: Raynes: weren't you rather skeptical of midje? what't your impression now?

9:55 tpope: tufflax: I think I will just give python priority. if_ruby has always bee a bit whack

9:55 tufflax: tpope: ok :)

10:09 xbat: is it normal that i have to re-set the Graphics2D font every frame?

10:10 otherwise it switches to er javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog

10:10 which i wasn't expecting :/

10:31 babilen: Is there a chance that an IKVRecduce and CollFold implementation for nil makes it into 1.5 ? (cf. CLJ-1098) -- I find the inconsistent behaviour regarding nil to be quite unfortunate

10:31 yogthos: Raynes: hey, what was the format for the znc password again? :)

10:46 clgv: babilen: better ask on the ML

10:46 babilen: clgv: will do

10:47 clgv: So far I am just using my wrappers for reduce-kv that handle nil gracefully, but I'd like to see consistent behaviour in upstream's reduce-kv too

10:48 clgv: babilen: the problem is when you pass nil instead of a collection?

10:49 * Sgeo wonders how RackUnit compares to the Clojure testing frameworks

10:49 babilen: clgv: exactly

10:50 clgv: Well, I never pass it intentionally, but it might sneak in - I'd just like reduce-kv to handle it gracefully (like reduce and all the other)

10:51 clgv: bablien: yeah, I understand. It is very useful to not have to care whether you have an empty coll or nil in those operations

10:52 jweiss: ,({:foo nil} {{:foo nil} :yay {:bar 1} :nooo})

10:52 clojurebot: nil

10:52 jweiss: how come this doesn't print :yay

10:53 solussd: What's the appropriate approach /alternative to response descriptors for following a 'link' in a restful webservice that provides a mime-type? E.g. If I discover the url to a resource via the links in an entity and from that I know what type of entity I need mapped

10:53 jweiss: oh wait duh

10:53 lookup was backwards

10:53 ,({{:foo nil} :yay {:bar 1} :nooo} {:foo nil})

10:53 clojurebot: :yay

10:53 solussd: wrong room..

10:55 aroemers: or is it? maybe jweiss likes it when clojurebot is joyful

10:55 babilen: clgv: I voted and there is a patch, just not sure what else can be done :)

10:57 clgv: babilen: oh try to get some of the active developers to screen that patch

10:58 * babilen offers a small bottle of Glenfarclas to anybody who tests/merges the patch

10:59 _wingy: anyone here using openshift

10:59 i cant see clojure doc for it. is it simple to use it with a clj app?

11:01 uvtc: _wingy: I think jcrossley3 and tcrawley are using it, IIRC.

11:04 clgv: babilen: the bug I found had two people commenting that the patch from christophe grand worked for them. then rich hickey accepted and merged it

11:04 bablien: but its priority was "Major"

11:05 babilen: clgv: I guess that not /that/ many people run into this issue (or simply work around it by explicitly checking for nil) and that consistency is not that much of a priority

11:06 clgv: but it took almost a month

11:06 babilen: clgv: Maybe I should simply write to the mailing list again and ask for somebody to take another look

11:06 clgv: babilen: if it is just trivial adding the nil cases returning the init value. then that should be done quikcly

11:07 balien: you got a CA? then you could write it to the dev ML

11:08 babilen: clgv: Well, there is the hack approach (check for nil, return sensible default) or the good approach (implement CollFold and IKVReduce for nil) -- The patch does the latter and it is the right approach to be taken in the language itself. The hack works for me, but is IMHO ugly and checking for nil? should /never/ be necessary

11:08 clgv: I don't have it -- The patch is already there rotting away :)

11:08 http://dev.clojure.org/jira/secure/attachment/11648/0001-CLJ-1098-Implement-IKVReduce-and-CollFold-for-nil.patch

11:12 clgv: then normal ML ;)

11:13 phuff: So, I'm trying to write a string to a ZipOutputStream (I'm making a zipfile and I have some strings to use as the contents of the files)

11:13 But ZipOutputStream requires you to write a bytearray to it

11:13 So I did this:

11:14 (defn writeZipOutput [zip-output filename content]

11:14 (let [contentBytes (.getBytes content "UTF-8")]

11:14 (.putNextEntry zip-output (new ZipEntry filename))

11:14 (.write zip-output contentBytes (.length contentBytes))))

11:14 clgv: phuff: use refheap.com or similar for multiline code

11:14 phuff: but clojure is saying that contentBytes doesn't have a length method?

11:14 uvtc: phuff: fyi, check out https://refheap.com/ for pasting.

11:14 phuff: Thanks

11:14 Sorry. :) some places are more tolerant with 3-4 lines of code

11:14 clgv: phuff: you want `alength` for arrays

11:15 phuff: Ah interesting.

11:15 Why can't it pick up the .length member of the java array?

11:15 clgv: phuff: but better wrap the zip stream in a dataoutputstream

11:15 uvtc: Raynes: re. refheap, "this connection is untrusted". Cert expired.

11:15 clgv: phuff: there is no such member since arrays are no objects in the jvm

11:15 phuff: clgv: Yeah, java i/o stuff gives me fits anyway.

11:15 clgv: phuff: thats compile magic

11:15 phuff: clgv: Ahhh I didn't know :)

11:16 Makes more sense

11:16 clgv: "compiler magic" I meant

11:16 phuff: I understood :)

11:16 So the problem with wrapping the outputstream with dataoutpustream or something is that I need to call methods on the zipoutputstream for each new file I write to the zipfile

11:16 clgv: butter better wrap that stream since you probably want to write other data in there as well soon ;)

11:17 phuff: Each time you add a new file you have to call putNextEntry which dataOutputStream won't have.

11:17 I suppose I could repeatedly wrap it

11:17 inside the wrapper function

11:17 clgv: I dont recall the zip api. you got the javadoc link at hand?

11:18 phuff: http://docs.oracle.com/javase/6/docs/api/java/util/zip/ZipOutputStream.html

11:19 clgv: well you can keep bindings to both streams and call putNextEntry when needed maybe you need to call "flush" before

11:19 I mean on the dataoutputstream

11:20 phuff: So go from this: https://gist.github.com/4476119

11:20 To something like this:

11:20 https://gist.github.com/4476128

11:20 ?

11:21 Or maybe trade let for with-open?

11:21 clgv: better not if you want to continue writing to that stream ;)

11:22 but you will need a (.flush dataOutputStream) there

11:22 phuff: I'd try to do the wrapping only once though.

11:22 phuff: Yeah just seems like a pain to pass around _two_ references to the same thing everywhere, in different guises.

11:22 Seems logically wrong I guess

11:23 clgv: do you have to pass it along that often?

11:24 phuff: Well I call it from like 4 different functions

11:24 clgv: I'd do the whole zip-creation in one function

11:24 phuff: So the problem is that I'm making an ebook :)

11:24 So I have one top level function

11:24 but then I've split the logic down into a lot of helper functions

11:24 Because to write ebooks you have to write 3 different files in addition to the content

11:25 clgv: you can create the content before the writing of the zip file if it fits in memory (and memory is no QoS requirement)

11:25 phuff: So it logically makes sense to me to pass on the outputstream to a helper function to write each of the metadata files and then map a function across each chapter of the ebook

11:25 clgv: Yeah, memory's not _really_ a problem.

11:25 Especially since this is just a quality of life program :)

11:26 k, I really appreciate the tutoring, clgv :)

11:26 It's been most helpful.

11:26 clgv: even if it were you create the whole zip content in a lazy-seq and have no memory problem ;)

11:26 phuff: :)

11:47 gfredericks: how does the clojure compiler avoid reflection generally?

11:49 TimMc: gfredericks: Can you refine that question?

11:49 ohpauleez: gfredericks: Like sspecifically when you type-hint, what happens in the compiler?

11:53 gfredericks: how does the compiler make type-hinting not necessary?

11:53 in non-obvious cases

11:53 like calling methods on a string literal

11:54 I can't imagine why it wouldn't need a hint 99% of the time

11:54 so there must be a trick I don't know about

11:54 clgv: gfredericks: there is local type inference, e.g. to detect usage of primitives

11:55 gfredericks: and there is :tag metadata on functions.

11:56 TimMc: gfredericks: What's complicated about it? (.foo "bar" 5) is clearly the String.foo method.

11:58 gfredericks: TimMc: yes, those are the obvious ones

11:58 I assume most interop calls aren't on a literal

11:58 nDuff: gfredericks: ...sure, but if you know a call, you know what its return type is, so you can attach that.

11:59 gfredericks: so this :tag stuff gets added automatically?

11:59 clgv: gfredericks: (let [s "bar"] (.foo s)) works because the compiler infers that s is a string binding

12:00 gfredericks: no. you have to do it manually like (defn ^String create-user-string [param1 param2] ...)

12:01 gfredericks: so (fn call-string-methods [x] (.substring x 1 2)) will _always_ reflect?

12:01 nDuff: gfredericks: Yup.

12:01 gfredericks: oh. maybe it just reflects a lot more often than I expected

12:02 nDuff: (now, if it's defmacro, then not so much)

12:02 gfredericks: ...are you using *warn-on-reflection*?

12:02 gfredericks: I don't ever use warn-on-reflection, so my expectations could be way off. I just thought I would hear about type-hinting a lot more than I do if it were that bad

12:03 TimMc: gfredericks: Oh, I thought you were giving that as an example of non-obvious, not obvious!

12:03 nDuff: *shrug*. "that bad" isn't very.

12:03 gfredericks: TimMc: hwhoops!

12:03 odie5533: Is clojure fun?

12:03 gfredericks: nDuff: speculating wildly, I would think most of my interop calls would reflect

12:04 TimMc: odie5533: Quite.

12:04 nDuff: gfredericks: I can believe that, but that's because you've done basically no attempts at hinting. It doesn't take that many hints, if they're well-placed and your calling convention permits.

12:04 TimMc: gfredericks: I think reflection-avoidance is limited to where you have a chain of method calls starting with a hinted expression or a class.

12:05 clgv: gfredericks: use *warn-on-reflections* and you'll see that it happens quite often in interop ^^

12:05 gfredericks: speaking of warn-on-reflection, is the normal way to set that at the top of each file you're interested in?

12:05 nDuff: gfredericks: Yup.

12:05 TimMc: I've used :warn-on-reflection true in lein, I think

12:05 gfredericks: and the compiler pops that off the binding stack at the end of the file?

12:05 TimMc: oh nice

12:05 TimMc: top level?

12:06 clgv: `set!` works locally

12:06 gfredericks: clgv: sure but that doesn't imply it will be different in the next file

12:06 TimMc: For instance, I'm pretty sure that (.. (System/getenv) (get "foo") (indexOf "hi")) doesn't involve reflection.

12:06 clgv: if you set it to true once it will stay that way

12:07 but the leiningen approach is better if you want to check the whole project

12:07 TimMc: clgv: Only if the compiler doesn't rebind for every file. I don't see why it would, though.

12:07 gfredericks: haha look at those 60 reflection warnings

12:07 clgv: TimMc: I often use it once at repl and then it stays on ;)

12:08 gfredericks: clgv: the "it will stay that way" part seems kind of lame to me, since you're setting it for multiple files but it's not quite clear which files those are; depends on require order

12:08 clgv: gfredericks: well, there might be some performance gains burried in there ;)

12:08 TimMc: Only bother with the tight loops, obviously.

12:08 gfredericks: clgv: I want a performance gain!

12:10 clgv: TimMc: I wont ever start performance tweek without a profiler run before ;)

12:10 once suffices ^^

12:11 gfredericks: dynamic vars have a stack built-in, don't they?

12:13 clgv: usin tools.logging how can I redirect all those ssl log messages (in debug mode) to a different file?

12:20 no7hing: i'am kinda torn wether this macro is ok or not: https://www.refheap.com/paste/8182

12:20 it expects people to know the arguments if they want to use them in the body

12:20 any opinions?

12:21 gfredericks: I think that's atypical

12:21 you could have the args provided by the caller

12:21 (def-property-change-listener FooClass [this ob pr v st] ...)

12:22 no7hing: yeah, makes the use slightly more verbose, but definitely more clear

12:22 dnolen_: no7hing: and avoid horrible unintended variable capture

12:22 avoids

12:22 S11001001: no7hing: it's known as "anaphoric", and is generally discouraged

12:22 * gfredericks was just googling to find that word

12:23 no7hing: ditto - but to get what it actually means

12:23 thanks guys

12:27 pjstadig: http://blog.fogus.me/2010/08/10/monkeying-with-clojures-defmethod-macro/

12:33 no7hing: thanks for that too

12:36 TimMc: I feel like I've run into this problem a lot... I have data like {:foo :a, :bar :b, :baz :b} and I want to produce {:a [:foo], :b [:bar :baz]}.

12:37 (My input is actually the [k v] pairs of the map.)

12:43 lsdafjklsd: Favorite resources for thinking functionally?

12:43 I completely flamed out in the recursion section of clojure koans

12:44 and passing map to reduce is insane

12:44 AimHere: SICP might be a place to begin

12:44 lsdafjklsd: ok

12:48 TimMc: &(->> {:foo :a, :bar :b, :baz :b} (map #(array-map (val %) [(key %)])) (apply merge-with concat))

12:48 lazybot: ⇒ {:b (:bar :baz), :a [:foo]}

12:50 lsdafjklsd: TimMc: nice!

12:51 uvtc: Is there any convention you know of where you start a keyword name with a hash mark? As in `:#foo`?

12:51 TimMc: uvtc: Writing Enlive selectors. :-P

12:52 I have no reason to believe it's supported syntax, actually.

12:52 uvtc: Hm. Now that you mention enlive, I recall seeing it in hiccup.

12:52 Sgeo: In Racket, I need to stop interjecting with Racket talk on a Clojure channel

12:53 uvtc: Where I just saw it is in the seesaw tutorial/gist.

12:54 There's also a `:.foo` in there.

12:54 Which is certainly reminiscent of css id/class

12:54 .

12:55 Oh. Sorry. I think it may be explained in the tut/gist but I skimmed.

12:58 clgv: is there any clojure dsl to configure file appender for tools.logging?

13:02 uvtc: Sgeo: wait a second ... certainly there's no top-secret classified back-room skunkworks unaffiliated Clojure implementation in Racket afoot, is there?

13:12 technomancy: dnolen: hey, does clojurescript-mode.el make sense to keep around any more?

13:12 dnolen: technomancy: I don't know I never used it :)

13:12 technomancy: oh, my bad; must be misremembering.

13:14 I think with piggieback etc it's no longer needed

13:14 Sgeo: uvtc, there's a partial broken implementation of some ideas

13:14 And also vague contemplation of something more thorough

13:15 uvtc: Sgeo: Oh? Neat. Link?

13:15 Sgeo: https://github.com/takikawa/racket-clojure

13:15 uvtc: Sgeo: thanks.

13:15 Sgeo: You're welcome

13:16 TimMc: "takikawa", is that toki pona, or Japanese?

13:17 Sgeo: Note that it does its [] and {} interpretation in a sucky way

13:18 It replaces function application (not macro application) with a macro that, if it's given [] or {}, does the right thing

13:18 But macro application won't be affected, as far as I can tell

13:24 clgv: Am I right that `dosync` blocks until the transaction was successfull completed?

13:34 gtrak: anybody figured out how to get jump-to-definition in cljs in emacs yet?

13:34 clgv: that's not what dosync does

13:35 clgv: gtrak: yeah. I found the real error a few minutes ago

13:36 sometimes late in the evening you start to doubt basic wisdom when struggleing with strange errors

13:38 gtrak: yea, the "I've been doing it wrong for a very long time" feeling? I hate it :-)

13:38 ice cream helps

13:39 SegFaultAX: gtrak: It's a mixed bag for me because yes, I've been Doing It Wrong (tm) for a long time, but now I have a better way.

13:39 (Hopefully)

13:42 gtrak: I just add dithering to my code style in order to randomize my classes of errors... provides a seemingly higher resolution result.

13:54 clgv: gtrak: I should add a derandomizer on my errors ;)

13:54 borkdude: "The Passion of the Clojurist"?

13:55 https://twitter.com/tpope/status/288148128958382080

13:55 gtrak: clgv: too random? that's an issue of SNR :-)

13:59 gfredericks: marginalia doesn't touch mid-function comments blocked off with ;;

13:59 is there some other way to format comments so that they get included?

13:59 or does marg want me to refactor until none of my functions need comments aside from docstrings?

14:00 algernon: marg will happily link ;; comments above the function to it, that may be a workaround in some cases

14:01 gfredericks: that kind of separates the comments from the thing they apply to

14:02 I imagine if I dedented them to the beginning of the line it would also catch them

14:02 but that's sooper ugs

14:02 algernon: as far as I remember, that confuses marg badly

14:02 as in, it will place the comments after the function

14:02 gfredericks: time to look at the marg source

14:02 algernon: let me know if you find a solution or workaround :)

14:03 gfredericks: sure

14:03 woah a defrecord

14:04 technomancy: has the "you can't do jack in a newly-opened file in nrepl.el until you compile it" problem been fixed in git master?

14:07 clgv: why do I get a 1 in the hour part with this: (format "%1$tH:%1$tM:%1$tS,%1$tL" 0) ???

14:07 lazybot: clgv: Oh, absolutely.

14:07 clgv: &(format "%1$tH:%1$tM:%1$tS,%1$tL" 0)

14:07 lazybot: ⇒ "16:00:00,000"

14:08 clgv: oooh

14:08 (format "%1$tH:%1$tM:%1$tS,%1$tL" (* 3600 1000))

14:08 &(format "%1$tH:%1$tM:%1$tS,%1$tL" (* 3600 1000))

14:08 lazybot: ⇒ "17:00:00,000"

14:08 clgv: seems to add the time zone...

14:09 TimMc: clgv: Using format for date formatting seems like a pretty bad idea.

14:10 clgv: TimMc: thats a duration and I want it formatted in hours minutes seconds millisecs

14:10 gfredericks: woah man

14:10 marg does some spooky stuff

14:12 TimMc: clgv: I dunno, anythign to do with time, I reach for a library.

14:13 amalloy: my solution to "time problems" is to think about all the edge cases and then throw my hands up in the air: no library could possibly be well-thought-out enough to solve any such problem

14:14 clgv: I just want to pretty print a time duration, so that should be pretty easy. but instead it is interpreted as a date by `format` :(

14:14 gfredericks: amalloy: like you just don't care?

14:15 ppppaul: i want to take an input stream that is a string and realize it as a string, how do?

14:15 gfredericks: sorry that joke was not worth anybody's attention

14:15 amalloy: gfredericks: thanks for saving me the trouble of letting you know

14:15 ppppaul: i use clojure.java.io for things like this, but i've never needed to go further than passing around streams

14:15 technomancy: all of the time libraries I've investigated fail to take into account the wibbly-wobbly nature of time

14:15 gfredericks: amalloy: I try to be helpful when it's not too much effort

14:15 technomancy: they all assume it's a linear progression from cause to effect

14:16 xeqi: ppppaul: slurp ?

14:16 ppppaul: slurp will do this?

14:16 ^_^

14:16 i'll try

14:16 gfredericks: "In what manner is it wobbly?" "In a wibbly manner."

14:16 amalloy: technomancy: have you read about the tardis monad? someone's joke on this theme

14:16 djwonk: tardis?

14:17 * technomancy rushes immediately to the googles

14:17 gfredericks: "A Tardis is the combination of the State monad transformer and the Reverse State monad transformer."

14:18 * gfredericks is glad there is always much weirder stuff left to learn in CS

14:19 technomancy: fails to address the fact that you can't interfere with your own personal time stream

14:19 then again, so do several canonical episodes, so I can't really fault them

14:20 gfredericks: woah guys #! is valid single-line comment syntax

14:21 hiredman: of course

14:21 amalloy: gfredericks: wasn't this discussed yesterday?

14:22 there was someone who really hated semicolons and was looking for any excuse not to use them

14:22 gfredericks: amalloy: I wasn't here

14:22 amalloy: well, see what you miss? shape up

14:23 djwonk: amalloy: haha, that was me

14:23 gfredericks: I just happen to be reading LispReader.java

14:23 * gfredericks likes "new UnreadableReader()"

14:24 * djwonk likes LeVarBurtonReader

14:25 Bronsa: the problem with UnreadableReader is that ###<foo>

14:25 dang.

14:25 ,#<foo>

14:25 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unreadable form>

14:25 technomancy: huh; so apparently nrepl.el fixed M-. on fresh buffers but not C-x C-e?

14:25 the heck

14:25 Bronsa: mhm, it's not going to work on clojurebot

14:26 gfredericks: ,(read-string "###<foo>")

14:26 clojurebot: #<RuntimeException java.lang.RuntimeException: Unreadable form>

14:26 Bronsa: w/e, just try it on the repl

14:26 gfredericks: multiple excetions?

14:27 Bronsa: #< is just throwint at "#<", everything else gets evaluated

14:27 technomancy: ah, no false alarm; it hasn't been fixed

14:28 amalloy: uhhhh, i see no evidence of this, Bronsa. what should i try?

14:28 Bronsa: so if you try to read "#<Object java.lang.Object@5ab8b24>" it will read "Object", "java.lang.Object", it will try to deref "5ab8b24>" failing with a NumberFormatException

14:30 djwonk: technomancy I'm having trouble with M-. too in nrepl.el master -- but with namespace issues

14:30 amalloy: that doesn't happen to me in a slime repl

14:30 it does happen in lein repl, and probably also in nrepl.el but i don't have that installed

14:31 technomancy: djwonk: https://github.com/kingtim/nrepl.el/issues/138 <- looks like he's going to take a fix, but it hasn't been applied yet

14:31 djwonk: gfredericks: re: #1 see (defn skip-whitespace … "Does not interpret #! as comment to end of line"

14:31 re: #1 I mean

14:32 aarg. #!

14:32 gfredericks: djwonk: see that where?

14:32 djwonk: clojure source: main.clj

14:33 so, I'm not sure that #! is a "full" replacement for ;

14:34 gfredericks: I certainly wasn't going to start using it for anything

14:34 djwonk: haha

14:34 gfredericks: other than replacing ;

14:34 also of course replacing ;; with #!#!

14:35 * djwonk groans

14:36 * djwonk thought that Le Var Burton Reader deserved some groans

14:37 Bronsa: amalloy: no idea how slime is hiding it, but trust me on that, you can see here how it just throws as soon as it gets to the "<" and does nothing to prevent further reading https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L1111-L1115

14:37 gfredericks: djwonk: I didn't get it. was that a reading rainbow thing?

14:38 djwonk: gfredericks: yes, but also "le" is "the" in french. so it is a pun of "the var reader". anyhow. if you have to explain it, then it probably wasn't very funny

14:38 amalloy: Bronsa: slime is probably sending the whole line and aborting the read once it gets an error, rather than attempting to find more readable chunks in the line

14:38 Bronsa: yeah, probably

14:38 amalloy: which seems like a better approach to me

14:38 gfredericks: djwonk: I guess I got distracted by geordi laforge (sp?)

14:41 djwonk: gfredericks: https://gist.github.com/4477682

14:42 * djwonk is making a t-shirt that will be awesome for Clojure / Star Trek / Reading Rainbow fans

14:43 egghead: hah

14:44 TimMc: :-D

14:44 gfredericks: Well I think I see the manner in which marg discards the sub comments. Also how to patch it to add them to the left column docs; but removing them from the code would be a bit more involved maybe

14:44 * TimMc throws money at djwonk

14:45 gfredericks: also lining them up well :/

14:48 oh my coworker has had an issue open for this for 5 months

14:51 and nobody's committed to the project in 7 months

14:51 TimMc: Marginalia?

14:51 gfredericks: yeah

14:52 * gfredericks considers forking and renaming "marginalio"

14:52 algernon: gfredericks: fogus was looking for someone to take it over a couple of weeks (months?) back

14:53 TimMc: gfredericks: Congratulations on your new project!

14:53 *maintainership

14:53 * arrdem claps

14:54 gfredericks: oh I see he has a separate branch with a single commit for inner comments

14:54 Sgeo: Hmm. Advantage of Scheme over Clojure: Oleg cares about Scheme

14:54 gfredericks: Sgeo: what does that result in?

14:55 Sgeo: gfredericks, it results in being able to read and sometimes more directly use Oleg awesomeness

14:56 * gfredericks tries to do something phonetically with "Oleg awesomeness" and fails

14:56 Seba51: What's the advantage to run an application with jetty-run instead of lein ring server

14:56 hiredman: you mean jetty-runner?

14:57 Seba51: ring.adapter.jetty (run-jetty (get-handler) {:join? false :port port})

14:57 hiredman: you should use lein ring server for developement

14:58 and generate a war or uberwar and deploy it via jetty or jetty-runner or tomcat or …

14:58 djwonk: ,(min [1 2 3])

14:58 clojurebot: [1 2 3]

14:58 abp: hiredman, so basically it doesn't matter?

14:58 hiredman: ,(doc min)

14:58 clojurebot: "([x] [x y] [x y & more]); Returns the least of the nums."

14:58 djwonk: personally, I think ^^^ is a weird way to do min

14:58 hiredman: abp: who said that?

14:58 gfredericks: min is the identity function!

14:59 djwonk: ,(min 1 2 3)

14:59 clojurebot: 1

14:59 gfredericks: $findfn 42 42

14:59 lazybot: [clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/time clojure.core/dosync clojure.core/long clojure.core/short clojure.core/+ clojure.core/* clojure.core/doto clojure.core/unchecked-long clojure.core/+' clojure.core/unchecked-short... https://www.refheap.com/paste/8188

14:59 abp: hiredman, your last statement seemed to imply that. ;)

14:59 hiredman: abp: no, you definitely should be be call run-rutty

14:59 djwonk: woah coal https://github.com/Raynes/findfn

15:00 abp: hiredman, I meant the servers.

15:00 hiredman: abp: should not be calling run-jetty

15:00 abp: depends what you want

15:00 abp: run-jutty? :D

15:00 Seba51: Lumius and mostlikely webnoir are doing this in the main the template creates

15:01 correction: in the main method the template creates

15:01 hiredman: I typically create uberwars and use jetty-runner

15:01 Seba51: so? just because a library does it, that does not make it good

15:02 abp: hiredman, hard work to compare all the servers and servlet containers

15:03 hiredman, blame yogthos :)

15:03 hiredman: noir has fallen short on just about every point

15:03 djwonk: ^ticker DJIA

15:03 Seba51: I am learning and just state my observervations

15:03 yogthos: abp: what am I getting blamed for? :P

15:04 Seba51: When there is a good reason, I could write a patch for Luminus

15:04 yogthos: Seba51: patches are very much welcome :P

15:04 djwonk: ticker DJIA

15:04 hiredman: Seba51: /win 15

15:04 whoops

15:05 gtrak: does lein-ring suck less with AOT on lein2?

15:05 yogthos: one thing to note is that there's two ways to run apps, one is as a standalone and another as a war deploy

15:05 djwonk: $findfn [1 2 3] 1

15:05 yogthos: for stuff like heroku you actually have to have a main

15:05 lazybot: [clojure.core/first]

15:06 djwonk: $findfn [2 3 4 5 6 7 8 1 9 10] 1

15:06 lazybot: []

15:06 djwonk: I stumped lazybot

15:06 Seba51: I run into this, when trying to get a context listener running to start up background jobs. I expected this to be simple but found org.lpetit.ring plugin, the ring documentation which seems to work only for uberwar and couldn't get it run in development mode in luminus.

15:07 SegFaultAX: djwonk: No you didn't. You asked it to find something that doesn't exist in its classpath.

15:07 hiredman: I can't say I particular care for herku's model

15:07 but at least they don't just deploy from git, they build a slug or whatever

15:08 yogthos: hiredman: the luminus template supports both approaches though

15:08 djwonk: SegFaultAX min is in core

15:08 yogthos: hiredman: if you run lein ring uberwar it'll make the deployable war, and it uses a separate handler than the one running in the main

15:08 hiredman: djwonk: have you read the docs for min?

15:09 djwonk: hiredman: yes

15:09 I don't know how to '

15:09 technomancy: yeah, building a single uberjar from your CI server is my recommended way of deploying

15:09 hiredman: yogthos: I know nothing about luminus and have not heard of it before today

15:09 djwonk: I don't know how to unwap [1 2 3] into parameter args

15:09 SegFaultAX: djwonk: Are you sure?

15:09 technomancy: but if you like uberwars for whatever reason that's fine too

15:09 SegFaultAX: ,(min [1 2 3])

15:09 metellus: $findfn2 3 4 5 6 7 8 1 9 10 1

15:09 clojurebot: [1 2 3]

15:09 SegFaultAX: ,(apply min [1 2 3])

15:09 clojurebot: 1

15:10 technomancy: using lein in production takes special care not to pull in changes in your deps accidentally

15:10 yogthos: hiredman: ah well let me know what you think of it ;)

15:10 Seba51: Reloading does not work with Luminus, if you use lein ring server. :init or :destroy in the ring configuration does not work with you run Luminus with lein run

15:10 djwonk: SegFaultAX: thanks, apply is what I'm looking for

15:10 SegFaultAX: djwonk: So I'll say it again, you asked it to find something that doesn't exist in its classpath (or clojure.core if that's what it's searching)

15:11 yogthos: SegFaultAX: you can just call init method at the start of the main, but destroy I have no good option for

15:11 SegFaultAX: yogthos: Huh?

15:11 yogthos: SegFaultAX: err that was aimed at Seba51

15:11 SegFaultAX: yogthos: Oh. :D

15:12 hiredman: yogthos: unlikely, lein-ring and compojure when required have me covered

15:12 djwonk: SegFaultAX right, the 'issue' is that findfn did not find the answer, because there is no single function that combines apply and min

15:12 Seba51: It is a good idea to close down connections on tear down. This is not an option.

15:12 yogthos: hiredman: no problemo ;)

15:12 Seba51: I guess once your main exits, everything will be torn down in any case

15:13 Seba51: but if you had to persist something on exit for example, then that wouldn't happen

15:13 djwonk: SegFaultAX my point was simply that both apply and min are on the classpath -- findfn is designed to explore composite functions

15:13 err, *not* designed

15:14 SegFaultAX: djwonk: That's not really stumping lazybot is it? Asking it to do something you already know it isn't capable of doing?

15:14 djwonk: /pedantry :)

15:14 djwonk: SegFaultAX it was a joke

15:14 I didn't know how much searching it might be able to do

15:14 Seba51: At least you can disconnect connections to queues etc.

15:14 SegFaultAX: djwonk: Read the sauce, yo.

15:20 Seba51: @Yogthos I am playing with using this (def get-handler2 (get-handler)) as ring handler. It seems to work.

15:21 yogthos: Seba51: what are you doing with the get-handler2? :)

15:22 Seba51: I use it in the project.clj: :ring {:handler clearlight.server/get-handler2 :init clearlight.application/startup :destroy clearlight.application/shutdown }


15:22 yogthos: Seba51: I already provide the (def war-handler (middleware/war-handler app)) for that though

15:23 Seba51: it should get hookup with the template in the project already too, so you can just add :init and :destroy

15:23 Seba51: I think I've already got :init setup actually

15:24 Seba51: Init and destroy are servlet context listener

15:25 yogthos: Seba51: yeah they aren't part of the handler itself

15:26 Seba51: but you need to wrap-resource, wrap-file-info, and wrap-base-url to get proper behavior in a war

15:26 Seba51: and wrap-resource wraps a different folder in main and war deployments

15:26 Seba51: hence the war-hanlder

15:32 pmonks: G'day gurus!

15:32 Is the fact that the code "(seque 3 (seque 3 (range 10)))" livelocks considered a bug?

15:32 (note: only tried on 1.4.0)

15:33 hyPiRion: mh

15:34 ,(doc seque)

15:34 pmonks: I'm looking at a case where I want to chain together 3 process via 2 queues, but I think this behaviour torpedoes "seque" as part of the solution…

15:34 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

15:35 Seba51: I cannot see a solution. If I want to build a uberwar and not create a custom web.xml, I need to rely on :init and :destroy of the ring configuration. If I do so, I have to use lein ring server and stay away from lein run. As long as I do not use Heroku or deploy a war to heroku it should not be a problem.

15:35 jkkramer: pmonks: there was a seque related fix that went into 1.5 master. not sure if it's for the same thing

15:35 weavejester: Seba51: You can use lein ring server on Heroku

15:35 jkkramer: pmonks: https://github.com/clojure/clojure/commit/0e3a535711044c68c34c34caa26c8cb05e10a346

15:36 amalloy: jkkramer: no, doesn't fix it

15:36 weavejester: And the latest snapshot of lein-ring allows you to create an executable uberjar for deployment to a linux/nginx environment

15:36 pmonks: @jkkramer: ta - looking now

15:44 Seba51: Thanks weavejester, I have never seen this before.

15:53 cemerick: weavejester: did I see you mention something about a compojure release soon?

15:53 weavejester: cemerick: A Ring release

15:53 cemerick: ah, ok

15:53 weavejester: cemerick: There's not much to add to Compojure

15:54 cemerick: weavejester: I am, as always, self-interested ;-P

15:55 weavejester: cemerick: Is there anything you wanted to add to Compojure?

15:55 Oh… wasn't there something to do with Friend?

15:55 cemerick: no, it's already in master

15:55 related, yeah

15:55 weavejester: Oh, I can cut a point release.

15:55 ivan: http://www.flickr.com/photos/lindseykuper/3023329529/ <- heh, 2nd edition of Reasoned Schemer coming real soon now for 4 years

15:55 cemerick: weavejester: you are the man :-)

15:56 AimHere: They'd have to wait until I bought the book before putting out the next edition

15:56 ivan: yes

15:58 egghead: what do you guys do when you have a transformation you want to do over a list, where the transformation is dependent on previous or subsequent elements

15:58 just a big reduce job?

15:58 AimHere: reduce or loop over it

15:59 S11001001: egghead: you can also move a window over a seq, I forget what function in core it is though

15:59 takes seq, window size, step size

15:59 egghead: interesting

15:59 gtrak: looks like partition is used for that

16:00 egghead: I basically have a bunch of 'holes' in my data that I want to fill in based on the context of the closest not-empty siblings

16:00 S11001001: for simple cases it can be even clearer to just do it yourself, e.g. adjacent elements, stepping 1: (map f xs (rest xs))

16:00 egghead: guess I'll just do a reduce, was wondering if there was some prettier pre-baked solution

16:00 AimHere: sHow would partition work for that?

16:00 gtrak: egghead: http://stackoverflow.com/a/1428436/244235

16:00 AimHere: *how

16:00 S11001001: egghead: your problem is what does "closest" mean

16:00 egghead: ya

16:01 AimHere: I mean, I could see some ways of doing it with partition, but they'd be pretty unwieldy

16:01 abp: Hm, how does liberator

16:01 ups

16:01 liberator doesn't work with Ring middleware to convert to json for example, does it?

16:15 svedubois: How I can avoid to write the "/path/project/"?

16:15 (java.io.File. "/path/project/image.png")

16:15 (java.io.File. "image.png")

16:17 pmonks: @jkkramer: just tried the seque example with 1.5.0-RC1, and the same thing happened (it livelocks).

16:17 (seque 3 (seque 3 (range 10)))

16:46 So is it a bug, do you reckon?

16:47 amalloy: pmonks: of course. but it's sorta hard to fix

16:47 i have a version of seque that uses futures instead of agents, which fixes this issue but comes with its own problems

16:48 pmonks: I (probably naively) thought that each seque would return a distinct queue & thread pool.

16:48 Or is the issue to do with coordination between the queues?

16:49 s/return/use

16:49 amalloy: coordination. clojure is a bit weird about agent sends

16:50 pmonks: ah ok (Clojure n00b nods his head) ;-)

16:51 I guess my real question is - is it worth raising?

16:52 amalloy: pmonks: http://dev.clojure.org/jira/browse/CLJ-823

16:52 pmonks: Question answered - thanks!

16:54 Anyone else out there looking to do SEDA style apps in Clojure?

16:54 * pmonks dislikes reinventing wheels...

16:55 mklappstuhl: hey

16:56 I'm writing some kind of parser with clojure for fun and I wonder a little how I can produce beautiful functional code without downloading a site twice

16:56 ohpauleez: pmonks: that's a very typical domain for Clojure systems

16:56 highly concurrent, highly parallel, event systems

16:56 mklappstuhl: (do-something (fetch "url"))

16:56 ohpauleez: usually driven by message queues

16:56 pmonks: Yeah seems like a really good fit.

16:57 My current case is real simple - no distribution or anything needed. Just have an IO-intensive task followed by a CPU-intensive task followed by another IO-intensive task (to a different IO system, so minimal IO contention between tasks 1 & 3). Would love to be able to wire it all up with something as simple as seque!

16:58 (by distribution I mean "distributed systems stuff")

16:59 arrdem: ~paste

16:59 clojurebot: paste is not gist.github.com

17:00 pmonks: I'd love to separate those phases with queues, so I can better utilise the machine's IO and CPU capacity.

17:01 gtrak: pmonks: agents are useful for ordering, they each have their own queue, and they share a threadpool. Dataflow variables can be fulfilled with promise/deliver and futures.

17:02 mklappstuhl: I want to do multiple things on that fetched page... basically the goal is to create one single hash from it

17:03 bpr: pmonks: of course there's also the java.util.concurrent package. It's got some very nice abstractions. You also might find lamina (https://github.com/ztellman/lamina) useful. Though, IMO it's fairly complicated.

17:04 mklappstuhl: anyone some input regarding my question? (build single hash from one website in a functional way without loading the page twice

17:04 gtrak: pmonks: here's an interesting use of promises http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/

17:05 mklappstuhl: not sure what you want? save off the value of a slurp? need a way to tell how long it's valid?

17:07 huh, christophe's thing looks a lot like seque

17:10 mklappstuhl: gtrak: basically I'm looking for a pattern to build a parser I guess.. In my mind I do things like (get-author (fetch "url")) & (get-title (fetch "url")) but this would download the content twice, right?

17:11 gtrak: what's fetch? something you wrote?

17:11 mklappstuhl: gtrak: a fictional function that returns some html it downloaded from the given url

17:12 gtrak: (let [a (fetch "http://myurl")] (do-something1 a) (do-something2 a))...

17:14 replace fetch with slurp and you've got yourself a string... replace fetch with clojure.java.io/reader or inputstream and you've got a stream to work with

17:21 jro_: is there there a lazy sort in clojure's core libraries?

17:21 similar as in Joy of Clojure's example

17:21 amalloy: no

17:22 gtrak: what's a lazy sort? :-)

17:23 jro_: (take 10 (sort coll)) computes only required work

17:27 bbloom: jro_: with immutable data structures, you want to search for a merge sort

17:27 i believe that there's one on contrib somewhere

17:27 clojurebot: contribute is http://clojure.org/contributing

17:28 bpr: pmonks: check http://clj-me.cgrand.net/2010/04/02/pipe-dreams-are-not-necessarily-made-of-promises/ it's what I would use in production rather than the pipe built on promises

17:29 pmonk: that said, the promises implementation was neat as hell

17:30 hiredman: o/win 15

17:35 ravster: hello everyone

17:55 pmonks: Thanks @pbr, @gtrak et al!

17:59 Apparently my brain isn't large enough to understand anything cgrand does on first (or often even Nth!) pass… :-(

18:06 ian_: noob here. I'm trying to run an init fn when starting my ring server. I'm typing 'lein server-headless' from the command line, and I've specified the following in my project.clj ':ring {:handler myapp.handler/app :init myapp.handler/init}'

18:06 gtrak: pmonks: this is the worst thing I've ever tried to understand of his: https://github.com/cgrand/moustache/blob/master/src/net/cgrand/moustache.clj#L151

18:06 ian_: What should the init fn return?

18:06 weavejester: ian_: Nothing, it's side effectful

18:07 ian_: weavejester: Thanks!

18:07 * pmonks 's head just exploded.

18:07 ravster: eeeeeeeeeewwwwww

18:08 oh, moustache. nvm. I feel you.

18:08 ian_: did I specify the :init fn correctly? :init myapp.handler/init

18:10 Raynes: alexbaranosky: ping

18:10 ian_: It seems to be trying to call what I return from the myapp.handler/init as a fn

18:13 sorry. nevermind

18:14 arrdem: general design quesiton: when should I be implementing a "real" object as opposed to documenting a standard structure for a map and some transformations thereof?

18:15 gtrak: a record's useful for polymorphism

18:15 bbloom: arrdem: for most tasks, you should prefer one of clojure's types

18:15 even with polymorphism, multimethods are generally preferable as they are more flexible

18:15 technomancy: arrdem: almost never?

18:16 bbloom: you should create a new concrete type when you're implementing a new abstraction, or implementing an existing abstraction in a new way

18:16 gtrak: arrdem: https://github.com/cemerick/clojure-type-selection-flowchart/blob/master/choosingtypeforms.png

18:16 Raynes: arrdem: No.

18:16 arrdem: Okay. so yall wouldn't call me batshit insane for taking the structured map approach almost everywhere.

18:16 technomancy: only when required for Java interop pretty much

18:16 Raynes: arrdem: No.

18:16 bbloom: heh

18:16 arrdem: not bat shit insane. simply uninitiated :-)

18:16 Raynes: bbloom: I think you misread what he said.

18:16 bbloom: but i'm nicer than Raynes .... apparently

18:17 Raynes: bbloom: Structured map is good.

18:17 arrdem: bbloom: I'm new here. I can live with uninitiated, but I just need to hear that I'm on the right track... ish.

18:17 gtrak: &(defrecord EATME [])

18:17 lazybot: java.lang.ClassNotFoundException: clojure.core.EATME

18:17 technomancy: gtrak: the thing that's missing from that chart is the part where it's like "I need to define a type" and it's like "no you don't"

18:17 Raynes: Using records for no particular reason is not.

18:17 gtrak: technomancy: it does say "just use a map" in one section

18:17 bbloom: technomancy: yes.

18:18 technomancy: gtrak: one section is not enough =)

18:18 bbloom: it needs like a "are you really really really sure?"

18:18 and if no, the use a map

18:18 if yes, then "you should probably use a map... but"

18:19 technomancy: bbloom: "rule 1: don't optimize. rule 2: (for experts only) don't optimize yet."

18:19 Raynes: technomancy: I can see that 138 people have downloaded conch from maven central. Can we get stats like that in clojars?

18:20 technomancy: Raynes: I think xeqi might be brewing something?

18:20 bpr: Raynes: btw, thanks for conch. very nice

18:20 technomancy: we have access logs for 100 days only unfortunately

18:20 Raynes: xeqi: I want to taste your brew.

18:20 bpr: You're welcome, kind sir.

18:20 technomancy: Raynes: you should write a log file analyzer for clojars =)

18:20 Raynes: You should stop telling me to write things. :P

18:21 technomancy: Raynes: but it sometimes works!

18:21 bbloom: technomancy: heh yes

18:21 gtrak: yea, it's also weird to prefer deftype for anything but low-level code

18:21 Raynes: Sometimes

18:21 technomancy: Raynes: inconsistent reward for actions leads to addictive behaviour patterns

18:21 amalloy: deftype is nice if you want to define a new type of sequence or collection that participates in clojure's collection interfaces

18:21 gtrak: "do you need it to have a hash-code"? I guess not...? says the noob

18:22 bbloom: heh, i always forget hashCode until it bites me :-)

18:22 Raynes: technomancy: Why does it have to be like 10 steps to release something to central? :(

18:22 technomancy: Raynes: why do you care?

18:22 Raynes: Why would I want to 'stage'? I've already bloody staged. I ran `lein test`, for Christ's sake!

18:22 technomancy: Because it's annoying.

18:22 technomancy: Raynes: then don't do it =)

18:23 Raynes: technomancy: I do it because some guy said he couldn't use clojars in his work and wanted to use conch.

18:23 I'm a real people pleaser, you see.

18:23 technomancy: there's your problem

18:24 Raynes: technomancy: I'd probably release to his personal maven repository if he asked me to. Moar users, man.

18:25 technomancy: curious, did he say why he can't use clojars?

18:25 Raynes: technomancy: Know what's craziest? Apparently lots of people use conch, but I've never actually used the non-low-level portion of it in a real project. Nobody has reported any bugs. At all.

18:25 He didn't say.

18:25 technomancy: heh

18:25 he might be able to use the clojars releases repo

18:26 Raynes: I can't even remember who it was now.

18:26 arrdem: (inc gtrak) ; belated but still counts

18:26 lazybot: ⇒ 4

18:28 xeqi: technomancy, Raynes: _ato has preliminary work at https://github.com/ato/clojars-web/pull/76 , I'll see about it after cleanup / better search

18:29 Raynes: xeqi: o/

18:29 technomancy: yeah, search seems more important

18:29 xeqi: download stats will hopefully make search better too

18:29 technomancy: true

18:34 jlewis: is there a version of apply whose last argument isn't a list? e.g. something like #(apply % %&) ?

18:37 gtrak: jlewis: pass in an empty vec as the last arg

18:37 technomancy: jlewis: that's called funcall, but clojure doesn't have it

18:37 TimMc: trampoline

18:37 technomancy: unless you have only one arg, in which case you can (ab)use deliver

18:37 TimMc: (no, don't use that)

18:38 systemfault: What are examples of well-written clojure?

18:38 jlewis: weird, deliver really just does that doesn't it

18:39 TimMc: &(trampoline + 2 3)

18:39 lazybot: ⇒ 5

18:39 technomancy: TimMc: nice

18:39 TimMc: $findfn + 2 3 5

18:40 amalloy: man, using trampoline for that is even worse than using deliver

18:40 lazybot: []

18:41 TimMc: 80% of the time it works 100% of the time!

18:41 jlewis: heh so you can have an uncurry function that uses deliver. that's kind of yuck. (reduce deliver f args)

18:41 TimMc: holy what

18:42 Oh, cute.

18:42 jlewis: assuming each of your functions only take 1 arg that is

18:43 gtrak: trampoline seems like a close-cousin to apply in spirit, more than deliver anyway

18:44 jlewis: i spose so

18:44 gtrak: the IFn-ness of a promise is an implementation detail

18:44 Raynes: There is a notable lack of brehaut in this channel today

18:45 ohpauleez: systemfault: Take a look at Ring, ClojureScript, and Leiningen

18:45 systemfault: ohpauleez: Thank you

18:45 dnolen: systemfault: ring, compojure, refheap, laser

18:45 ohpauleez: totally welcome

18:45 systemfault: dnolen: Thank you also :)

18:46 Raynes: dnolen: o/ for rockin' the laser.

18:46 ohpauleez: I know, and the heap

18:47 that was basically saying "You should model yourself after weavejester and Raynes"

18:47 :)

18:47 systemfault: Because right now… I feel like having a toolbox but I don't know what tools are the best for any job :/

18:47 Raynes: Haha

18:47 systemfault: I read the clojure-doc tutorials and the documentation on the official website

18:47 ohpauleez: Raynes: Can laser only do content swaps?

18:47 gtrak: systemfault: the nice thing about macros is you can hide the fact you're hammering that screw

18:47 systemfault: :)

18:47 ohpauleez: or does it do the full cascading class stuff? Like can I look up by class and then attach attributes

18:48 (you can also tell me to go look at the source)

18:48 Raynes: ohpauleez: It can do lots of stuff. I haven't really formally announced it yet, because I wanted to write a big tutorial and get refheap's views using it first, but cats been out of the bag for a while because I talk about it in here all the time.

18:48 ohpauleez: If Enlive can do it, laser can probably do it too.

18:48 dnolen: jlewis: I would just write your own funcall (defn funcall [f & args] (apply f args))?

18:48 ohpauleez: cool

18:49 Raynes: ohpauleez: You can definitely look up by class and attach attrs.

18:49 ohpauleez: solid

18:49 jlewis: dnolen: sure, just thought i'd throw it out there first to see if it already existed.

18:49 Raynes: ohpauleez: Something like (document (parse (resource "your.html")) (class= "myclass") (attr :foo "bar")) or with defdocument, fragment, defragment, etc.

18:50 But yeah, I want to write a really great tutorial on all of it.

18:50 ohpauleez: cool, exactly what I was curious about

18:50 Raynes: That's the biggest next step besides refheap (for a real world example usage).

18:52 ohpauleez: Note that (attr ..) is just a function that returns a function that takes a node, modifies it, and returns a new node or a sequence of nodes. You can do anything you want. Could replace it with #(assoc-in % [:attrs :foo] "bar")

18:52 Selectors are just functions that return a function that take a location in the html zipper and return truthy or falsey.

18:53 ohpauleez: cool

19:03 bpr: does anyone know of a pallet crate for datomic?

19:03 zilti: Hmm I just typed (join #clojure) ...

19:04 Then wondered why it doesn't work.

19:04 technomancy: it's because you're not doing IRC from Emacs

19:05 s'ok; nobody's perfect

19:05 SegFaultAX: Does that acutally work?

19:05 zilti: Well I use ERC, but... probably "the wrong way"?

19:05 SegFaultAX: I mean, isn't # still a dispatch character in elisp?

19:05 technomancy: yeah, it'd have to be a string =\

19:06 it would be more like (erc-join-channel "#clojure")


19:06 systemfault: I don't use emacs, do I deserve immolation?

19:06 :(

19:06 amalloy: just set up reader macros for all the alphanumeric characters that read the form as a string


19:07 zilti: systemfault: Emacs is in good mood today, so you might be lucky.

19:07 systemfault: I might ask her out when I'll be more familiar with clojure

19:08 I guess that elisp must be very different than clojure though...

19:08 arrdem: eh... it's still a lisp... so you use an arguments list instead of a vector. whop de frikkin do.

19:09 hyPiRion: systemfault: Well, you're not setting up much anyway when using emacs.

19:09 technomancy: it's only mildly brain damaged

19:09 hyPiRion: Maybe some stuff people already have done in you init.el file, which you just copypaste

19:09 technomancy: what's the trick to reverse a sort-by by changing its comparator instead of reversing after the fact?

19:09 zilti: &(let [coll '([:!f (fn [x] (inc x)) :data])] (fn? (-> coll first second)))

19:09 lazybot: ⇒ false

19:09 systemfault: I tried emacs once… a few years back. It was basically copy/pasting snippets from everywhere.

19:10 gtrak: technomancy: minus?

19:10 zilti: Why is this returning false? Did I forget something?

19:10 systemfault: And emacs has weird names for obvious functionalities.. like syntax highlighting which is called IIRC font-lock

19:10 gtrak: comparators return -1 0 or 1

19:10 zilti: yes, font-lock... I wondered who came up with that name

19:11 TimMc: &(sort-by (comp - identity) (range 5))

19:11 lazybot: ⇒ (4 3 2 1 0)

19:11 hyPiRion: zilti: '(fn [x] (inc x)) is not a function, it's a list evaluating to a function

19:11 AimHere: I'd guess it was an ancient TECO- or PDP-ism

19:11 systemfault: And the clojure mode for emacs is good?

19:11 technomancy: gtrak: of course

19:11 systemfault: Right now, I'm practicing with that IntelliJ IDEA plugin (La Clojure)

19:11 TimMc: systemfault: You won't get flamed in here for using a particular editor.

19:11 AimHere: systemfault, we can't say. The guy who wrote it is here, and if we complain, he'll get offended

19:12 systemfault: Haha

19:12 I love AimHere's answer :)

19:12 TimMc: Well, you won't get flamed in here for *not* using a particular editor.

19:12 I can think

19:12 systemfault: But I will sure try it when I'll retry emacs

19:12 AimHere: So who's going to be first to admit writing clojure in Windows notepad?

19:12 zilti: systemfault: What's particularly awesome is the nREPL-integration and paredit mode, both of which IntelliJ lacks.

19:12 gtrak: TimMc: sort-by - works too

19:12 systemfault: TimMc: I use MS Word

19:12 hyPiRion: The most important thing, I think, it trying stuff out and figuring what you prefer

19:12 gtrak: which I find odd

19:12 technomancy: systemfault: emacs has odd terminology because it predates all the "standard" WIMP conventions by many years

19:12 systemfault: zilti: Good

19:13 TimMc: gtrak: "identity" stands in here for the original comparator.

19:13 technomancy: so it's kind of a "why should I change my name; he's the one that sucks" situation

19:13 gtrak: TimMc: yea, I figured, it happens to work for numbers :-), but nothing else

19:13 technomancy: anyway, I only brought it up for IRC, not for editing clojure

19:13 use whatever you like for clojure

19:13 gtrak: &(sort-by - (range 6))

19:13 lazybot: ⇒ (5 4 3 2 1 0)

19:14 systemfault: Right :) Thanks for the feedback though

19:14 TimMc: technomancy: I don't understand. If you use Emacs for one thing, don't you use it for everything?

19:14 technomancy: TimMc: there are still a few things I need a browser for, to my great shame

19:14 TimMc: &(sort-by / (range -3 3))

19:14 lazybot: java.lang.ArithmeticException: Divide by zero

19:14 TimMc: awww

19:15 gtrak: haha

19:15 TimMc: &(sort-by / (range -3.0 3.0))

19:15 lazybot: java.lang.ArithmeticException: Divide by zero

19:15 gtrak: TimMc: wait... first arg is keyfn, second is comparator

19:15 I think we're doing it wrong

19:16 jlewis: you're just negating the integer and using the default comparator, heh

19:16 hyPiRion: gtrak: right.

19:16 TimMc: ,(doc sort-by)

19:16 clojurebot: "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

19:16 AimHere: &(sort-by #(Math/pow %1 %2) (range -3 3))

19:16 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox7657$eval178244$fn

19:16 TimMc: oh shi--

19:16 hyPiRion: ,(doc sort)

19:16 clojurebot: "([coll] [comp coll]); Returns a sorted sequence of the items in coll. If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

19:17 gtrak: &(sort-by identity (comp - compare) (range 5))

19:17 lazybot: ⇒ (4 3 2 1 0)

19:17 gtrak: how's that?

19:17 hyPiRion: ,(sort (comp - compare) (range 6)) ; better.

19:17 clojurebot: (5 4 3 2 1 ...)

19:17 TimMc: Oh, of course... why did I expect identity to be a comparator? >_<

19:17 arrdem: can I define one macro that expands into two top-level forms?

19:17 gtrak: ah, tricky

19:17 TimMc: arrdem: Nope, but there's do.

19:17 gtrak: TimMc: and you almost got away with it too

19:17 AimHere: arrdem, you mean like two defns?

19:18 arrdem: AimHere: da

19:18 AimHere: arrdem, what TimMc said

19:18 wrap them in 'do'

19:18 hyPiRion: Though I don't understand.

19:18 Why not just

19:18 ,(sort > (range 6))

19:18 clojurebot: (5 4 3 2 1 ...)

19:18 gtrak: hyPiRion: not just numbers

19:18 jlewis: the question was about negating some other comparison

19:18 comparator*

19:18 zilti: hyPiRion: lol

19:18 hyPiRion: o right. better stay in this channel all the time then

19:18 gtrak: (sort (comp - compare) ["a" "b" "c" "d" "e"])

19:19 &(sort (comp - compare) ["a" "b" "c" "d" "e"])

19:19 TimMc: hyPiRion: I would expect no less of you.

19:19 lazybot: ⇒ ("e" "d" "c" "b" "a")

19:19 TimMc: &(/ 0.0)

19:19 lazybot: java.lang.ArithmeticException: Divide by zero

19:19 TimMc: &(/ 1 0.0)

19:19 lazybot: ⇒ Infinity

19:19 TimMc: o\__/o

19:19 zilti: huh?

19:19 gtrak: &(/ -0.0)

19:19 lazybot: java.lang.ArithmeticException: Divide by zero

19:19 zilti: HUH?

19:19 arrdem: her der (do) works magic as always.

19:19 gtrak: &(/ 1 -0.0)

19:20 lazybot: ⇒ -Infinity

19:20 arrdem: thanks all

19:20 gtrak: there ya go

19:20 apparently clojure knows calculus

19:21 hyPiRion: Whut.

19:21 gtrak: &(/ 1 (+ 0.0 -0.0))

19:21 lazybot: ⇒ Infinity

19:21 gtrak: &(/ 1 (- 0.0 -0.0))

19:21 lazybot: ⇒ Infinity

19:22 gtrak: ha.. how the heck are you supposed to get negative-zero

19:22 hyPiRion: ##(/ 0.0) expands into (/ 1 0.0) though.

19:22 lazybot: java.lang.ArithmeticException: Divide by zero

19:23 gtrak: hyPiRion: perhaps the boxing screws up the polymorphism

19:24 devth: given a nested map: {:foo {:bar {:baz {:qux "hi"}}}}, how can I extract just :qux's val if I don't know/care about the keys foo/bar/baz?

19:24 gtrak: devth: tree-seq

19:25 hiredman: devth: you have to do a tree walk

19:26 depending on your exact requirements you can use tree-seq or zippers or …

19:26 mattmoss: &(/ 1 (/ 1 -0.0))

19:26 lazybot: ⇒ -0.0

19:26 amalloy: maps are optimized for lookup by fixed/known key though, so if you have a situation like that you should reconsider whether you really want a totally unstructured map

19:26 devth: thanks gtrak + hiredman. first i've heard of tree-seq.

19:27 TimMc: gtrak: -0.0 is easy.

19:27 devth: amalloy: it's a json response from an api

19:27 TimMc: &-0.0

19:27 lazybot: ⇒ -0.0

19:27 amalloy: &(keep :qux (tree-seq map? vals {:foo {:bar {:baz {:qux "hi"}}}}))

19:27 lazybot: ⇒ ("hi")

19:27 devth: amalloy: nice :)

19:28 TimMc: gtrak: What's surprisingly hard is telling whether a double has the negative bit set.

19:28 amalloy: it's a bit rubbish but could work

19:28 mattmoss: &(< -0.0 0.0)

19:28 lazybot: ⇒ false

19:28 amalloy: &(neg? -0.0)

19:28 lazybot: ⇒ false

19:28 arrdem: mattmoss: ololololol

19:28 TimMc: &(Math/signum -0.0)

19:28 lazybot: ⇒ -0.0

19:28 mattmoss: I tried.

19:28 arrdem: oh gods I hate floating point...

19:29 TimMc: Here's the answer I came up with: ##(neg? (Math/copySign 4.0 -0.0))

19:29 lazybot: ⇒ true

19:29 TimMc: &(neg? (Math/copySign 4.0 0.0))

19:29 lazybot: ⇒ false

19:29 bpr: $(.signum (BigDecimal. -0.0))

19:30 &(.signum (BigDecimal. -0.0))

19:30 lazybot: ⇒ 0

19:30 gtrak: god, I always forget about keep

19:31 remove nil? is just so intuitive

19:43 bpr: /join #pallet

19:43 lol

19:49 zilti: Is it still a stack if one can "peek" the topmost n values (but only at once)?

19:50 * arrdem now deeply regrets using structured vectors not structured maps

20:06 bpr: does anyone know why running (require 'my.namespace) in the repl would work but typing C-c C-l in nrepl.el would fail with: "Namespace not found."?

20:06 and by "nrepl.el" i mean the buffer with the my.namespace's source in it

20:25 tomoj: what's the deal with IKeywordLookup/ILookupThunk?

20:26 bbloom: tomoj: it's about statically compiling fast (:foo a-map) call sites

20:27 hiredman: ILookupThunk is the interface for the inline caches created by the compiler created for keyword lookups in records

20:27 tomoj: so one ILookupThunk per record field is automatically emitted?

20:28 djwonk: zilti IMO, if data structure acts like a stack, consider it a stack … unless it breaks the expectations for performance

20:28 hiredman: tomoj: they are per callsite, I believe

20:29 djwonk: zilti adding additional functions to a stack-like API is not a necessary condition for saying it is no longer a stack

20:29 tomoj: so every time you write (:foo x), an ILookupThunk gets emitted, even though the compiler doesn't know x is a record?

20:30 guess I can try digging in to the compiler to understand

20:30 hiredman: oh, no, they would be per record, the call site for (:foo x) just emits a check "is this a record, if so get the thunk and install it and call it"

20:31 tomoj: ah, and then next time you (:foo x) on a record of the same type (or the same record?), the thunk is already there?

20:31 hiredman: hmmmm

20:31 I am not sure

20:31 zilti: Lol why is that called a thunk?

20:32 hiredman: they are per callsite

20:32 amalloy: $google functional programming thunk

20:32 lazybot: [Thunk (functional programming) - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Thunk_(functional_programming)

20:33 tomoj: oh, right, only at that callsite

20:34 zilti: amalloy: Thanks, but I just wondered about the funny name.

20:34 hiredman: well the object per callsite knows how to look up the real thunk in the record

20:34 amalloy: zilti: the name is explained right in the article

20:36 zilti: amalloy: Oh, yes now I see it. That's funnier than I expected.

20:36 djwonk: I was going to lookup what thunk meant, but I decided to wait until later to do it.

20:37 Actually… wait until someone asked me what it meant.

20:37 zilti: "thunk" means a muffled sound according to my dictionary

20:38 But "thunk" as 2-o'clock-in-the-morning-passive of "think" is way better.

20:39 djwonk: zilti: yes, it is pretty funny if you thunk about it

20:40 zilti: djwonk: It's even funnier because here at me it is actually 2 o'clock in the morning.

20:40 djwonk: zilti: did you figure out your stack question?

20:41 zilti: djwonk: I thunk about the advice and decade that I'll call it a stack

20:42 djwonk: zilti: did you notice the note on http://clojure.org/data_structures that says "Treat a list like a stack: peek pop"

20:43 zilti: djwonk: Yes, I did. But usually you can only look at the topmost element of a stack, not at the second-topmost, without removing the topmost, so I wasn't sure

20:44 djwonk: want to share a code snippet? what are you doing with it?

20:44 zilti: djwonk: Stay tuned a few more minutes ;)

20:47 djwonk: I need it to "keep track of results" in my data flow library: https://github.com/zilti/visuflow

20:48 I bet something like that exists already, but better... But I couldn't find it.

20:49 djwonk: colonbangs might be an unfortunate choice of terminology

20:50 zilti: But... but... hashbang...

20:52 djwonk: that looks interesting

20:53 kovas: lol

20:56 zilti: djwonk: I hope so, the concept took me hours to figure out ;) I thought, after decoupling data from functionality when switching from OO to Functional, why not also decoupling functions and the order of calling them?

20:56 Ok now, good night... Argh, working tomorrow will be hard...

21:03 arrdem: herm... any ideas on why this is giving me a Duplicate Key error on :rzero? https://www.refheap.com/paste/8197

21:05 hiredman: ,(set [1 1])

21:05 clojurebot: #{1}

21:06 bbloom: arrdem: works for me

21:06 hiredman: what version of clojure?

21:06 bbloom: arrdem: restart your repl?

21:06 i'm on 1.4.0

21:07 arrdem: yeah I'm (supposedly) 1.4.0 also

21:08 hiredman: there have been changes around how and when duplicate keys are checked for sets and maps recently

21:08 arrdem: repl restart didn't help either.

21:08 hiredman: arrdem: well, uh, are you or aren't you on 1.4.0?

21:08 bbloom: arrdem: i just pasted your code into my repl and it worked, are you able to reproduce the issue with the same exact code you shared?

21:09 (not in context, via copy paste to a non-project repl)

21:09 arrdem: lemme try on a fresh repl

21:10 bpr: arrdem: you can check what version of clojure you're running by evaluating: *clojure-version*

21:10 hiredman: defining a protocol then calling the impl method like that is pretty gross, so is using _ for a parameter name when you use the parameter

21:10 arrdem: ... wtf works in a clean repl

21:10 hiredman: by convention _ means "not used"

21:10 or don't car

21:10 care

21:11 arrdem: hiredman: the theory here is that this record replaces a structured vector I was previously using

21:11 porting from that to this has given me pain all day

21:11 so the theory is that I define an interface that insulates me from such changes in future.

21:12 thanks for the _ correction, that'll get fixed.

21:12 hiredman: arrdem: I would really recommend just using regular functions and a map instead of a protocol and a record

21:13 arrdem: after `lein clean` it works like a charm.

21:13 (in context)

21:13 bpr: that's b/c you're using a record and a protocol

21:13 (the need to lein clean)

21:13 arrdem: bpr: right. I cleaned out the old :aot

21:15 hiredman: when I'm doing structured map work like this, I should just define top-level functions left and right, then use :require :as to keep everything straight when I use it elsewhere?

21:16 tomoj: what is a structured map? alternatively, what is an unstructured map?

21:17 arrdem: when I say "structured map" I really mean that I'm using a map with a programmer defined set of keys in a way that other languages would tell me to use an object.

21:18 djwonk: arrdem: so, a map :)

21:18 arrdem: djwonk: XP I got that

21:20 djwonk: arrdem if your API works with only the functions 'left' and 'right' more power to you

21:21 arrdem: djwonk: ... so I should be designing for clojure.zipper?

21:22 djwonk: arrdem: sure, it sounds like you are mostly there :)

21:25 arrdem I'm doing a 'practice' project using all maps and namespaces.

21:26 I looked at the data structures flowchart whenever I got tempted to try the fancier things

21:28 arrdem: djwonk: you'd like what I'm doing right now... it's a purely functional (but eager) simulator for an out of order processor. my top-level loop is just (-> state (fetch) (decode) (issue) (alu) (commit))

21:29 but no good arbitrary trees for the zipper library to play with

21:29 just a lot of update-in

21:31 djwonk: arrdem: I was joking around earlier… you said "I should just define top-level functions left and right" … I took that literally for fun … not thinking anything about zippers

21:31 arrdem: -_________-

21:31 djwonk: arrdem: yes, I do like simulations

21:34 dnolen: core.logic 0.8.0-rc1 going out

21:36 djwonk: arrdem: what does that mean?

21:37 arrdem: djwonk: the flat face?

21:37 I use it as an "are you kidding me" expression.

21:38 djwonk: haha, I thought you were joking around too

21:39 arrdem: haha.. if only I could get away with (left) and (right)...

21:40 jweiss: ok i'm confused. I want to override print-method so that I get "#<FooClass \"bar\">" instead of #<FooClass bar> when I print it (so the reader can read it if necessary). so I overrode it, calling (.write w (str o)) thinking that calling str will escape the quotes. it doesn't.

21:40 bbloom: ,((juxt pr-str str) "foo")

21:40 clojurebot: ["\"foo\"" "foo"]

21:40 bbloom: ,((juxt print-str pr-str str) "foo")

21:40 clojurebot: ["foo" "\"foo\"" "foo"]

21:40 bbloom: jweiss: ^^

21:41 djwonk: arrdem: small thing, you know you can write (-> state fetch decode issue alu commit)

21:41 jweiss: bbloom: hm, but doesn't pr-str also call print-method under the covers?

21:41 gfredericks: ,((juxt print println pr prn print-str println-str pr-str prn-str) "foo")

21:41 clojurebot: foofoo

21:41 "foo""foo"

21:41 [nil nil nil nil "foo" ...]

21:41 arrdem: djwonk: rly? I've had all kinds of pain from not ()ing my #()s when I put them in ->

21:41 gfredericks: haha weird

21:41 bbloom: jweiss: yes, but print-method is defined for Strings, so you can (pr-str (str foo))

21:41 jweiss: bbloom: ok i'll try that, thanks

21:42 gfredericks: arrdem: not for #()'s though :)

21:42 alexbaranosky: Raynes: pong

21:42 djwonk: arrdem: yeah? I've been trying it out in my REPL. I could be wrong though

21:42 Raynes: alexbaranosky: Can you look over laser's tests for me when you get a chance and see if I'm using midje properly?

21:42 jweiss: ,((juxt pr-str pr) "foo")

21:42 clojurebot: "foo"

21:42 ["\"foo\"" nil]

21:42 Raynes: alexbaranosky: No hurry.

21:42 jweiss: oh yeah

21:42 djwonk: ,(-> 42 identity inc (identity) (dec))

21:42 clojurebot: 42

21:43 arrdem: gfredericks: because #() -> (fn []), which is a list not an Ifn?

21:43 gfredericks: arrdem: yep

21:43 alexbaranosky: Raynes, something's fishy with my IRC client. I didn't see your response

21:43 Raynes: alexbaranosky: What do you mean>

21:43 ?

21:44 gfredericks: &(macroexpand-1 (-> foo #(* % 2)))

21:44 lazybot: ⇒ #<sandbox7657$eval178946$foo__178947 sandbox7657$eval178946$foo__178947@1bf2d06>

21:44 gfredericks: &(macroexpand-1 '(-> foo #(* % 2)))

21:44 lazybot: ⇒ (fn* foo [p1__178950#] (* p1__178950# 2))

21:44 alexbaranosky: it's only showing about 5 lines at a time, so youre message scrolled off the page too fast. Not sure what's up with that. Will have to investigate soon

21:44 jweiss: bbloom: yeah, as i suspected, i get StackOverflowError if i try to call pr-str from my print-method override.

21:44 Raynes: Peculiar...

21:44 bbloom: jweiss: what type of object are you trying to print

21:44 what is the dispatch value for your print-method ?

21:45 alexbaranosky: Raynes: you're better of messaging me

21:45 jweiss: bbloom: example, (AssertionError. "foo \"bar\"")

21:45 bbloom: it dispatches to the default, but i overrode Object.

21:45 bbloom: jweiss: yeah, um, don't do that

21:46 why are you overriding the default print method?

21:46 or the object one?

21:46 jweiss: bbloom: how else can i guarantee that my prn output won't contain #< ... > ?

21:46 bbloom: jweiss: you can't

21:46 jweiss: well, i am gonna :)

21:46 bbloom: #< ... > is intentional for non-readable objects

21:47 jweiss: i just want a string instead of the unreadable object.

21:47 bbloom: if you have a non-readable object that you want to make readable, then define a print-method for that object

21:47 jweiss: instead of breaking the reader

21:47 bbloom: i have no control over what classes will be in that output.

21:47 it has to be for anything.

21:47 bbloom: jweiss: you're only supposed to define a polymorphic method if you own the method or protocol. or if you own the type you're defining it on

21:47 you'll break print-method for all other clojure clients

21:48 jweiss: bbloom: i made a flag that only prints my way if the flag is on, otherwise uses the vanilla dispatch.

21:48 perhaps a paste would help here. one sec

21:49 bbloom: what good does it do you to have a non-readable object be printed readably?

21:49 unless, of course, you are making the object readable

21:49 jweiss: https://www.refheap.com/paste/8198

21:49 bbloom: which you shouldn't do for other people's types anyway...

21:49 devn: bbloom: readability is not binary

21:49 clojurebot: Ik begrijp

21:49 TimMc: haha

21:49 jweiss: bbloom: i'm tracing functions and i want to be able to navigate the trace after serializing it to disk and reading it back.

21:49 devn: :)

21:49 TimMc: bbloom: Makes sense to me. You can read in the whole thing without trouble and just ignore those pieces that you can't use anyway.

21:50 bbloom: ok, well bind your flag to false (binding [*print-all-readably* false] (pr-str (str obj)))

21:50 jweiss: yeah what TimMc said :)

21:50 bbloom: jweiss: that would short circuit the recursion and your stack won't overflow

21:50 still doesn't seem like a great idea tho...

21:51 jweiss: bbloom: is there not a function that does the escaping that i can call directly?

21:51 bbloom: if this is for debugging purposes, i do think we need something for that... but co-opting print-method probably isn't a good plan

21:51 jweiss: not public

21:51 you can also try print-dup to see if that gets the job done for you in any way

21:52 jweiss: bbloom: no, i'm not interesting in recreating the objects.

21:52 *interested

21:52 just want to go from "reader chokes" to "reader reads it and gives me some clue what the object was"

21:52 bbloom: i think you'd be better off defining a multimethod transform-to-readable-only

21:52 and then print the result of that

21:53 gfredericks: what is the state of cljs source maps?

21:53 jweiss: bbloom: and then do what for things like vectors, maps, etc? defer to print-method?

21:53 bbloom: jweiss: yes

21:54 jweiss: i considered doing that, and i seem to recall i couldn't, but now can't remember why.

21:54 bbloom: the rule is: only define methods for protocols (or multimethods dispatched by type) for either A) protocols you control or B) types you control

21:54 jweiss: something i was doing required print-method.

21:54 bbloom: otherwise, delegate

21:54 jweiss: maybe it was pprint. but i don't really require pprint anymore.

21:54 i think that was it.

21:54 bbloom: pprint is a mess lol

21:54 pprint is on my hit list :-P

21:55 jweiss: yeah i tried to write a custom dispatch, that did not go well. no docs. unless you count the docs for common lisp's pprint.

21:55 (custom dispatch wasn't for this - it was to properly indent trace output)

21:55 bbloom: jweiss: it's also just an old algorithm and a stateful approach. i've been working on a new pprint for my own needs & i'll probably make it work on clojure data for the hell o fit

21:56 TimMc: jweiss: Is this something that will be published and combined with other people's code?

21:56 jweiss: TimMc: ideally, yes

21:56 but if it doesn't work that way, i could live with it

21:58 bbloom: oh you're the guy who did Facjor. nice.

21:59 factjor rather

21:59 bbloom: jweiss: apparently people think that thing is super cool :-)

21:59 i submitted a proposal to give a talk about it at clojure west

22:03 djwonk: hmm. clojure.core has `every?` `not-every?` `not-any?` but not `any?` -- just `some`.

22:05 bbloom: djwonk: any? is just (comp boolean some)

22:05 generally, 'some is preferrable

22:05 preferable*

22:06 djwonk: bloom: thanks, I was looking at comp just now. it is asymmetrical

22:06 bbloom: djwonk: the real asymmetry is that there is no 'every without the ?

22:06 ,(and 1 2)

22:06 clojurebot: 2

22:06 bbloom: ,(every? identity [1 2])

22:06 clojurebot: true

22:06 arrdem: ,(reduce #(or %1 %2) [false false false true false])

22:06 clojurebot: true

22:07 bbloom: ,(last (filter identity [1 2]))

22:07 clojurebot: 2

22:07 gfredericks: ,((constantly 2))

22:07 clojurebot: 2

22:08 bbloom: hmmm there should also be a no-predicate version of 'some as well

22:08 and every? etc

22:09 gfredericks: bbloom: and then we need versions where only nil is falsy

22:09 bbloom: ,(some (complement nil?) [nil nil 2 nil 3 nil])

22:09 clojurebot: true

22:09 bbloom: *shrug*

22:10 amalloy: bbloom: bet you a dollar any? isn't (comp boolean some)

22:10 arrdem: why is 0 truty?

22:10 djwonk: bbloom: interesting. `any?` seems like a no-brainer.

22:10 amalloy: because it ain't nil or false

22:10 bbloom: amalloy: heh, whoops

22:10 * jweiss surprised that (some (complement nil?) [nil nil 2 nil 3 nil]) didn't return 2

22:10 bbloom: (doc some)

22:10 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

22:10 arrdem: ,(boolean `())

22:10 clojurebot: true

22:11 arrdem: wat

22:11 amalloy: arrdem: is () false or nil?

22:11 jweiss: oh wait no i'm not

22:11 bbloom: it claims logical true...

22:11 jweiss: it's wahtever the pred returns.

22:11 arrdem: amalloy: in any other lisp `() = nil....

22:11 but no it isn't

22:12 djwonk: jweiss: some returns the value *if* the predicate is true

22:12 gfredericks: clojure just be diffrent

22:12 * djwonk thinks the wording of (doc some) is a little tricky

22:12 amalloy: bbloom: i think i was wrong actually. send me a self-addressed stamped envelope to collect your dollar

22:12 bbloom: amalloy: heh

22:13 gfredericks: that's a net of several dimes

22:13 totally worth it

22:13 amalloy: i confused the issue with #{x} returning a different truthiness from #(= % x)

22:15 bbloom: ah yes

22:17 djwonk: bbloom: any? discussion: https://groups.google.com/forum/?fromgroups=#!searchin/clojure/any?$20every?/clojure/CxxkO9rBZKg/rLgv_4PvNQ0J

22:19 the downsides to adding any? would be: a little more code, a little extra documentation. gains: symmetry. I guess symmetry loses in this case?

22:19 i'm adding it to my bag of utilities though

22:20 I mean, if you have not-any? you gotta have any? ! think about someone refactoring or tweaking. this is a no brainer

22:26 amalloy: djwonk: if you have not-any?, you already have any?. it's just (complement not-any?)

22:26 djwonk: amalloy: LOL

22:26 amalloy: or (comp boolean some), as bbloom suggests

22:27 djwonk: I know I can make it, I'm saying it is CRAZY that core doesn't have it. Oh, why do I care?

22:27 I have some but I don't have any?

22:27 haha

22:29 bbloom: djwonk: even if core had any? it's doc string would be similar to #(doc empty?)

22:29 er ##(doc empty?)

22:29 lazybot: ⇒ "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

22:29 bbloom: since some is generally more useful than any?

22:29 although, occasionally, you want to return a boolean even if you use some since you want your public api to promise true/false and not some extra bit of data, in case you ever change your implementation

22:30 djwonk: bbloom: exactly. this is about *people* *reading* code

23:02 tpope: bbloom: surprise!

23:02 * bbloom skillfully dodges

23:03 bbloom: tpope: what' sup?

23:03 tpope: it's a surprise!

23:03 bbloom: heh ok

23:04 github just ruined the surprise...

23:05 tpope: what would be really cool (and almost completely worthless) would be if I could get the source for the java parts of clojure into my classpath

23:05 bbloom: tpope: wouldn't be useless to me, i look at the java source frequently :-P

23:05 tpope: find a way

23:06 bbloom: tpope: i think you'd need src jars

23:06 tpope: yes

23:06 bbloom: or at least a checkout synced to the right version

23:06 tpope: I gathered that much

23:06 I was hopefully for something transparent

23:06 like a one liner in my project.clj

23:06 bbloom: tpope: https://oss.sonatype.org/content/repositories/snapshots/org/clojure/clojure/1.5.0-master-SNAPSHOT/

23:06 there are source jars there

23:06 so in theory.... lein could grab them

23:07 presumably that's where it gets clojure in the first place

23:07 technomancy: ?

23:08 amalloy: i think you can depend on org.clojure/clojure :classifier "source" or something like that

23:08 technomancy: bbloom: sure?

23:08 bbloom: :classifier "sources"

23:08 technomancy: ritz does that

23:08 systemfault: Lulz http://www.satlug.org/pipermail/satlug/2013-January/067023.html

23:08 bbloom: cool

23:09 tpope: bbloom: does it work for you? I get Could not find the main class: clojure.main. Program will exit.

23:09 bbloom: tpope: playing with the location list now... neat!

23:10 tpope: you need both with and without the classifier

23:10 you added a dependency on the sources, but eliminated a dependency on the binaries

23:10 tpope: bbloom: I tried both ways

23:10 bbloom: (i'm guessing)

23:10 hmmm

23:10 dunno then

23:10 tpope: do I need a version number with the :classifier variant? (I included one)

23:11 hugod: ritz automatically adds source jars if they are in the local repo

23:11 bbloom: not sure, but my brain is extremely pre-occupied, so i'm gonna get back to you on this :-P

23:12 hugod: `lein pom; mvn dependency:sources;` will get them there

23:14 tpope: I'm not really up to speed on ritz

23:15 that is, it's a word that seems to usually appear in sentenes involving emacs, so I haven't yet paid it much notice :)

23:17 hugod: it starts an nrepl server, so can be used with any nrepl client

23:17 bbloom: tpope: i dunno anything about ritz either, but my understanding is that it's available both in nREPL and SWANK forms

23:17 i suspect the later is the emacs specific part

23:18 tpope: I'll give it a try

23:23 bpr: hugod: do you have your emacs dotfiles online anywhere? I can never get ritz working (nrepl or swank).

23:23 tpope: hugod: so I'd add ritz-nrepl to my lein profile as instructed?

23:23 then run ... lein ritz-nrepl?

23:25 hugod: tpope: lein ritz-nrepl will start an nrepl - which client are you using?

23:25 tpope: hugod: foreplay.vim

23:25 hugod: bpr: I have an old gist I should update - what problems were you having?

23:25 tpope: I can pretty much guarantee I'm the first person to try it

23:26 hugod: I shalln't be betting against that

23:28 tpope: I see I haven't added the option to run without the debugger to ritz nrepl - should still work though

23:30 bpr: hugod: i can't give very precise descriptions of the problems, but it doesn't launch a debugger on exceptions (when configured to do so) and nrepl-javadocs doesn't work (it opens a browser tab with a non-url) etc.

23:30 tpope: hugod: it wasn't working on this machine, but it is on my mac. how do I tell what port it's on?

23:30 devth: tpope: i've used ritz a bit with slimv. start the swank client with: lein ritz 4005

23:31 bpr: i could try setting everything up again and give you more precise error descriptions.

23:31 tpope: oh look, it finally reported a port

23:31 devth: s/client/server

23:32 hugod: bpr: https://gist.github.com/1934037

23:32 tpope: whatever it is, it's behaving differently enough from vanilla nrepl that foreplay.vim is confused

23:32 bpr: hugod: thanks

23:33 technomancy: hugod: could ritz be made a higher-order task that could then launch an nrepl server or a ring server or whatever?

23:35 hugod: technomancy: not sure exactly what you mean there

23:35 technomancy: hugod: well the ritz task does the double-jvm setup and then launches a repl in the project JVM, right?

23:35 why not parameterize the "launches a repl" part?

23:37 hugod: (in swank it can run without the double jvm too)

23:38 technomancy: so just have a single lien task, and not one for swank, one for nrepl, one for hornetq, etc

23:38 tpope: hugod: I am getting ERROR: Unhandled REPL handler exception processing message {:code 1, :op eval} java.lang.NullPointerException whenever I try to eval anything in the usual nrepl manner

23:39 TimMc: My excuse for not writing code tonight: Helicopter hovering ~150 ft over my house. >_<

23:39 tpope: this is not an urgent matter

23:39 hugod: tpope: um - I wonder if it relies on having a session

23:40 tpope: hugod: actually my first attempt was with a session

23:41 technomancy: hugod: exactly; it seems like a good fit for a higher-order task

23:41 admittedly I haven't taken a close look, but just from what I've heard

23:42 also: higher-order tasks are basically the coolest thing in leiningen =)

23:43 or if you don't want to break compatibility you could say `lein ritzfully repl` =)

23:43 * technomancy o O ( what's the adverb form of ritz? )

23:44 TimMc: ritzily

23:46 hugod: technomancy: I'll have to think about that...

23:46 tpope: hugod: the tracking-eval middleware appears to require an id

23:46 not a session, just a regular id

23:47 hugod: tpope: right - I guess nrepl.el must provide that

23:48 tpope: it's an optional parameter to the eval operation

23:48 https://github.com/clojure/tools.nrepl/blob/master/doc/ops.md#eval

23:49 hugod: "It is generally the case that request messages should contain a globally-unique :id." from the nrepl readme

23:50 tpope: well, I guess there's no harm in adding one

23:50 hugod: a request can have more than one reply

23:50 and the id is used to match them up

23:50 tpope: yes

23:51 but I'm forced into a single threaded, synchronous workflow

23:51 thus it doesn't really solve anything for me

23:51 hugod: ah - if you add an issue to ritz I can remove the need for it

23:52 tpope: will do

23:52 hugod: thanks

23:53 bpr: hugod: your config seems to work well. I'll have to look over this and see what I have that's conflicting

23:53 hugod: thanks

23:53 hugod: bpr: glad to hear it is working

Logging service provided by n01se.net