#clojure log - Dec 14 2014

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

0:22 arrdem: do we have a function (app f fs) -> g | (g y) = true iff ∀h∈fs (h y) = true

0:23 so a function that returns a function returning the logical conjunction of the argument functions over input

0:24 every-pred

2:02 justin_smith: &(apply str (sort (str (java.util.UUID/randomUUID))))

2:03 ,(apply str (sort (str (java.util.UUID/randomUUID))))

2:03 clojurebot: "----000011223445555777888bbcccddeeff"

2:46 sveri: Hi, I am trying to offer binary downloads from my ring application. However, I am doing an async request with cljs-ajax and all I get is the content of the file, but not an option to download it

2:48 justin_smith: try :headers {"Content-Description" "File Transfer" "Content-Type" "application/octet-stream"}

2:49 you may also want "Content-Disposition" "attachment; filename=\"foo.jpg\""

2:50 also, it may be that you can only get the download popup if you provide the content via a link the user clicks...

2:50 this may be a "security" thing

2:53 sveri: thats what I am afraid of too

2:54 adding your headers produces the same result

2:56 Ah, It's not easily achievable from javscript side

4:25 hydo: Is there something special I need to do to reference the .class made with gen-class from another class made with gen-class? The lib I'm writing is a plugin to a larger java program, and I'm gen-class'ing its entry point and in it trying to attach an event listener which is another gen-classed class. heh

4:26 so.. many.. classes.

4:43 After more research a better question is: Is there something special I need to do to use a class literal that references a gen-class'ed class - inside a class that will itself be gen-classed?

4:44 SagiCZ1: hydo: what problem do you have_

4:44 ?

4:46 hydo: Class A is an event listener that subclasses a java class. I seems to build just fine. The project is a plugin to a larger java program - Class B is its entry point and is itself gen-classed. Inside Class B's init method, I need to use a class literal to point to Class A. Upon compilation, it can't find Class A's .class. It is being compiled first, so there's that.

4:46 SagiCZ1: are you using leiningen?

4:46 hydo: Yes

4:47 SagiCZ1: did you specify in project.clj that the classes should be :aot ?

4:47 hydo: I've got :aot :all

4:47 just in case. heeh

4:47 SagiCZ1: ok

4:47 hydo: From the repl, I can (compile the.class)

4:48 SagiCZ1: and in classes A, B you have (ns ... (:gen-class)) correct?

4:48 hydo: err, the event listener in question.

4:48 Correct.

4:49 SagiCZ1: i would maybe try to isolate the problem by quickly making a toy project with just those two classes without being run as a the plugin..

4:50 hydo: Ok, I'll get some more coffee and do that. Thanks!

4:50 SagiCZ1: hydo: np

5:11 hydo: SagiCZ1: One last question: is there anything I need to do to make a class literal or is it as easy as (.registerEvent "event-name" my.class.literal.class)?

5:12 ie. the bare my.class.literal.class

5:19 Glenjamin: hydo: it's just my.class.literal

5:19 ,String

5:19 clojurebot: java.lang.String

5:20 hydo: Hah... I tried that and it built. was just about to test it.

5:20 Thank you, Glenjamin :)

5:55 marrrk: Can you combine kioo and hiccup? I mean generate the html for use with kioo from hiccup?

6:16 lxsameer: hey guys, Lein complain about network is unreachable. here is my lein output http://dpaste.com/3JB34JZ

6:16 how can i fix it ?

7:28 bitcrusher: can't get clj-webdriver to click this button :x

7:41 is there a good web automate library

7:41 besides clj-webdriver

7:42 trying to make a script to turn my steam items into gems, got logged in and into my inventory, but i can't figure out how to make it click the "Turn into Gems..." button

7:46 TEttinger: bitcrusher, you could probably do it with a plain AWT robot

7:46 assuming you let it use your mouse

7:51 bitcrusher: hmm, not as cool

7:51 might as well just click it with my own fingers

7:52 gonna try it in python :/

8:03 oh this is neat.. http://sebuilder.github.io/se-builder/

9:09 zarkone: hello all. I

9:10 SagiCZ1: zarkone: whats up

9:10 zarkone: *hello all. I'm new to clojure and never used java. What i better should read about java internals?

9:10

9:11 SagiCZ1: zarkone: well some short introduction to java types could be helpful.. i dont think its completely necessary

9:12 its good to know how primitives, arrays and collections work.. dont bother reading about java inheriting, polymorphism etc

9:12 zarkone: SagiCZ1: thanks. I thought, may be some books about JVM and standart java api

9:13 SagiCZ1: the more you know the better.. but if you want to save time, i would jump straight into clojure and learn only bits and pieces of java where you feel the need

9:14 zarkone: SagiCZ1: ok, that's how i'm learning it now =)

9:14 SagiCZ1: zarkone: if you want some tips regarding learning clojure, check out 4clojure..

9:26 zarkone: SagiCZ1: ok, thanks =)

9:28 justin_smith: zarkone: the javadoc api docs are sufficient, and comprehensive

9:28 zarkone: except when it comes to primitives and arrays, it is helpful to learn how those relate to everything else

9:29 zarkone but the official java tutorials cover that stuff I think

9:29 SagiCZ1: yeah the basic tutorials usually start with the.. well basics

9:32 can swap! block the thread?

9:32 justin_smith: SagiCZ1: no, but it can cause crazy amounts of retries, in a pathological situation

9:32 I think there is a hard-coded retry limit

9:33 SagiCZ1: so yeah, that could look like blocking..

9:33 justin_smith: SagiCZ1: it does a CAS - notes the value, does it's operation, and compares, and does the set only if the value has not changed yet, otherwise it starts over as a retry

9:33 *its

9:34 I know the docs say "no side effects in the operation" but if you added a println you would see how many times the swap is retried

9:34 SagiCZ1: good idea

9:38 martinklepsch: is there a one-line way to see what files are in a given clojars dependency?

9:39 justin_smith: martinklepsch: if you have it on disk jar tf ~/.m2/repository/path/to/file.jar

9:39 martinklepsch: also, a decent editor will open the jar itself for editing

9:39 it's just a zip file with a specific format

9:40 (emacs and vi can both open jar files)

9:40 martinklepsch: justin_smith: yeah, I know about that I just wondered if it's possible to get that information potentially even w/o downloading

9:40 justin_smith: martinklepsch: oh, no idea

9:40 paying by the byte?

9:44 martinklepsch: justin_smith: hehe, luckily noy

10:17 SagiCZ1: i need to separate a sequence into some subsequence.. something like take-while does, but take-while only give me the first subsequence.. how can i get all?

10:17 maybe split-with?

10:17 split-with is probably the one

10:19 stephenmac7: Does something like this exist in the standard library?

10:19 (defn comp-all [& fs] (reduce comp fs))

10:20 ,(((fn [& fs] (reduce comp fs)) #(- % 5) #(* % 5)) 6)

10:20 clojurebot: 25

10:20 SagiCZ1: no.. split-with only splits it into two colls :(

10:22 luxbock: ,((comp #(- % 5) #(* % 5)) 6)

10:22 clojurebot: 25

10:23 justin_smith: ,(partition-by #(quot % 3) (range))

10:23 clojurebot: ((0 1 2) (3 4 5) (6 7 8) (9 10 11) (12 13 14) ...)

10:23 justin_smith: SagiCZ1: like that?

10:24 SagiCZ1: justin_smith: yeah i figured group-by, but this is even cleaner.. thanks

10:24 justin_smith: group-by is a little odd

10:25 ,(group-by odd? (range 10))

10:25 clojurebot: {false [0 2 4 6 8], true [1 3 5 7 9]}

10:25 SagiCZ1: is that wrong?

10:25 justin_smith: I mean for the collection splitting, because it's totally out of order

10:25 but maybe that is OK for your usage

10:25 SagiCZ1: true

10:26 ,(partion 2 (range 10))

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

10:26 SagiCZ1: ,(partition 2 (range 10))

10:26 clojurebot: ((0 1) (2 3) (4 5) (6 7) (8 9))

10:26 SagiCZ1: what would be the most idiomatic way to get the 5 out of (4 5) <

10:26 ?

10:26 engblom`: What is Clojure doing differently than other lisp implementations running on jvm? ABCL takes ~3 seconds for REPL, Kawa <1 second and Clojure takes ~6 seconds.

10:27 SagiCZ1: engblom`: it sends a thank you e-mail to rich hickey

10:27 justin_smith: SagiCZ1: second maybe?

10:27 SagiCZ1: ,(nth '(4 5) 1)

10:27 clojurebot: 5

10:27 SagiCZ1: yeah ok

10:28 justin_smith: engblom`: If you don't use nrepl you can get startups like the others

10:28 ~faster-lein

10:28 clojurebot: Pardon?

10:29 justin_smith: engblom`: some good hints here, the biggest difference is the one made by whether you run nrepl or not, in my experience https://github.com/technomancy/leiningen/wiki/Faster

10:29 we should look into optimizing nrepl startup time

10:30 engblom`: justin_smith: Thanks!

10:30 justin_smith: fast trampoline helps a lot too

10:30 (skipping the time lein takes to build the class path, if nothing changed since last run)

10:32 SagiCZ1: ,(group-by odd? (range 10))

10:32 clojurebot: {false [0 2 4 6 8], true [1 3 5 7 9]}

10:32 SagiCZ1: how do i get the ones that are true? its not a keyword so..

10:32 ,(true (group-by odd? (range 10)))

10:32 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn>

10:32 justin_smith: ,((group-by odd? (range 10)) true)

10:32 clojurebot: [1 3 5 7 9]

10:33 SagiCZ1: wait so it works the other way?

10:33 justin_smith: ,(get (group-by odd? (range 10)) true)

10:33 clojurebot: [1 3 5 7 9]

10:33 justin_smith: both are just calling get anyway

10:33 no reason not to do get explicitly

10:33 SagiCZ1: i was taught to always use (key map) to get values from map

10:33 not the other way around

10:34 justin_smith: SagiCZ1: sets, maps, vectors, keywords, and symbols all implement get when used as a function

10:34 ,('a '{a 1})

10:34 clojurebot: 1

10:34 SagiCZ1: ,('false {false [1 2]})

10:34 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn>

10:34 justin_smith: that's not a symbol

10:35 and if it was, it wouldn't match the non-symbol in the map

10:35 just use get

10:35 ,([:a :b :c] 1)

10:35 clojurebot: :b

10:36 SagiCZ1: okay :(

10:58 justin_smith: ,(map (vec (range 20 0 -1)) (range 7 15))

10:58 clojurebot: (13 12 11 10 9 ...)

11:11 csd_: How would I express in loop/recur a mathematical function such as f(n) = f(n-1) + 2f(n-2) ...

11:14 namely, i don't know how to handle the recursive function being called multiple times. would i need mulitple loop/recurs?

11:14 SagiCZ1: csd_: you could use named recursion

11:14 without recur

11:14 if n is not big enough to blow up stack

11:15 csd_: SagiCZ1: I am trying to express this as an iterative process.. doing SICP exercises :)

11:16 maybe i need trampoline

11:16 SagiCZ1: csd_: i was thinking about it yeah

11:19 justin_smith: csd_: (nth (iterate #(* 2 %) x) y) ?

11:19 or maybe you want + and not * for that, depending on whether it is 1,2,3 or 1,2,4

11:24 csd_: trampoline is giving me an error, i think the function might be too intertwined for it :-/

11:24 justin_smith: csd_: what kind of error?

11:24 csd_: ClassCast Exception, saying I'm trying to treat a function as a number

11:25 https://www.refheap.com/94889

11:27 justin_smith: csd_: (+ (f (- n 1)) ...) - (f (- n 1)) probably returns a function

11:27 you are trampolining, remember

11:27 but self calls inside trampoline are gonna be weird

11:27 csd_: ultimately though it should return a number

11:28 I haven't used trampoline before

11:28 justin_smith: csd_: f returns a function

11:28 OK, ignore the trampoline part for now

11:28 f returns a number or a function

11:28 csd_: right

11:28 justin_smith: a self call inside f, needs to handle a number or a function

11:28 csd_: sure

11:28 justin_smith: so you can call trampoline recursively, or reorganize your code

11:29 csd_: what needs to be done to make it work with trampoline? and/or what should i do instead of using trampoline

11:29 i.e. what's easiest here

11:30 justin_smith: :else #(+ (trampoline (f (- n 1))) (* 2 (trampoline (- n 2))) ...)

11:30 if all calls to f are trampolined, you at least avoid that error, though I think your stack usage will still be bad

11:30 because by recursively calling trampoline you work around the advantage of trampoline

11:31 csd_: oh well yeah that's silly

11:31 justin_smith: right

11:31 csd_: what if i added an accumulator parameter

11:32 justin_smith: trampoline is for replacing deep call stacks with continuation passing

11:32 given that you are just passing numbers, you may want to just memoize f

11:32 similar to the classic fib

11:33 in fact, the solutions that work for fib should all be adaptable to this function

11:34 csd_: well there's a really simple solution to the fib sequence that i was trying to emulate here, where a+b is passed as a state parameter

11:40 justin_smith: I think this is wrong, but getting closer to something reasonable

11:40 (first (nth (iterate (fn [[acc [a b c]]] [(+ acc (* a 10)) [b c (inc c)]]) 2) n))

11:46 TimMc_: Haven't read backlog, what's the problem statement again?

11:46 csd_: this is what i'm trying to emulate https://www.refheap.com/94891

11:47 TimMc_: oh i'm just doing SICP exercise 1.11

11:47 TimMc_: ok

11:48 csd_: there's this mathematical function with multiple recursive calls that i'm trying to express using tail recursion

11:49 TimMc_: Wow, the bots are really in bad shape today.

11:50 TimMc: ,(first (nth (iterate (fn [[a b]] [b (+ a b)]) [1 1]) 5))

11:50 clojurebot: 8

11:51 TimMc: ,(take 10 (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1])))

11:51 clojurebot: (1 1 2 3 5 ...)

11:51 TimMc: That's the standard state-passing version in Clojure.

11:52 justin_smith: TimMc: there we go, that's what I was aiming for above

11:52 TimMc: *nod*

11:53 csd_: TimMc: The problem I'm trying to figure out is f(n) = n where n < 3; otherwise (+ f(n-1) 2f(n-2) 3f(n-3))

11:54 justin_smith: csd_: what about that * 10

11:55 csd_: oh you could have an iterator function that takes as state parameters f(n-1) f(n-2) and f(n-3)

11:55 then you start at n = 1 and increment until you get to what the original n was

11:55 justin_smith: right, that was what I was trying to aim at

11:55 csd_: i see now

11:55 justin_smith: csd_: initial state would be [0 1 2]

11:55 or maybe [2 1 0]

11:56 triss: so let's say I want to auto-generate a list of functions for a library and shove them in a name space...

11:56 how could this be done?

11:57 I'll have a list of strings to manipulate to name them...

11:58 sorely I don't need a defn for every function in the namespace?

11:58 justin_smith: triss: you could use intern, if you don't mind wrangling the metadata

11:58 (doc intern)

11:58 clojurebot: "([ns name] [ns name val]); Finds or creates a var named by the symbol name in the namespace ns (which can be a symbol or a namespace), setting its root binding to val if supplied. The namespace must exist. The var will adopt any metadata from the name symbol. Returns the var."

11:59 justin_smith: it's a function, so you can construct the args

11:59 ,(intern *ns* (symbol (str "foo" "bar")) 42)

11:59 clojurebot: #'sandbox/foobar

11:59 justin_smith: ,foobar

11:59 clojurebot: 42

11:59 justin_smith: ,(meta #'foobar)

11:59 clojurebot: {:ns #<Namespace sandbox>, :name foobar}

12:00 justin_smith: notice it takes an ns as an arg, so you don't even have to be "in" the ns to construct it

12:09 triss: splendid thanks justin_smith. I'll have a play.

12:10 myguidingstar: hi all, in core.logic, is there anyway to declare "these two clauses never succeed at the same time"?

12:10 justin_smith: triss: it might be nice to add :file and :line metadata that points to where you do the auto-generation, with a comment on how it works. That way tooling can actually help people.

12:11 triss: a common problem with auto-generated stuff is that the metadata that people's tools (like doc, source, editor specific stuff) all break

12:11 triss: gosh hadn't thought about anything like that.

12:12 justin_smith: triss: think about how you find out how libs work - what would you find looking into your own lib?

12:12 at least have some doc string!

12:12 check out the metadata that def / defn create when you load something from a file

12:13 &(meta #'+)

12:13 ,(meta #'+)

12:13 clojurebot: {:added "1.2", :ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :inline-arities #<core$_GT_1_QMARK_ clojure.core$_GT_1_QMARK_@82d300>, ...}

12:14 Glenjamin: ~ask

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

12:14 Glenjamin: (wanted the phrasing for another channel)

12:16 justin_smith: myguidingstar: I don't know your answer, but I don't want your small question to get lost in all the chatter, maybe someone else here knows core.logic?

12:18 myguidingstar: justin_smith, thanks. I've found a good foundation here http://stackoverflow.com/questions/19414335/encoding-two-out-of-three-in-clojure-core-logic

12:39 LauJensen: Quick question re Clojurescript. When building a cljs app w/o optimizations, I need to include every single .js in my .html file, so /app/om/om.js, /app/transit/transit.js, /app/domina.js, /app/domina/support.js - And so on and so on. Is this correct or due to an error in my setup ?

12:39 myguidingstar: LauJensen, it's correct

12:40 w/o optimizations, each namespace will have an equivalent js file

12:41 or you may want goog.require to load them automatically

12:47 LauJensen: myguidingstar: How can I use goog.require to do that?

12:48 myguidingstar: LauJensen, find in Om's Readme the line: "Your local development markup should look something like the following:"

12:48 LauJensen: thanks

12:56 Rhainur1: can someone explain how I can integrate friend or buddy with a luminus project?

12:56 I'm completely lost

12:57 LauJensen: myguidingstar: For something like transit, you'll need about 10 script tags just to load deps, and the order needs to be specific and this is undocumented. It makes little sense to code without optimizations turned on

12:59 myguidingstar: LauJensen, I thought goog.require will load deps in the right order?

13:00 as it infers from dependencies in ns forms

13:18 bja_: myguidingstar: that is correct

13:19 you just need to script include the initial goog closure library along with your script and then load it manually with a third script tag

13:32 arrdem: reiddraper: ping

13:33 good lord test.check.gen/symbol emits some evil shit

13:48 andyf: arrdem: out of curiosity, does it generate symbols that do not conform to the Clojure documentation, or ones that conform, but have weird chars in them that you don't normally use?

14:05 arrdem: $mail andyf they're legitimate to the clojure docs, so I guess that means my parser is broken :C

14:33 TimMc: arrdem: How can you tell they're legit?

14:33 arrdem: TimMc: (read-string (pr-str)) :P

14:33 yay implementation specification

14:34 TimMc: ...

14:34 Yeah...

14:34 "Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, and ? (other characters will be allowed eventually, but not all macro characters have been determined)."

14:34 and then clojure.core/<

14:35 arrdem: clojure.core//

14:35 :D

14:35 andyf: Vote early, vote often: http://dev.clojure.org/jira/browse/CLJ-1527

14:35 arrdem: andyf: pretty sure my vote doesn't count at this point but you still have it :P

14:36 yarp. already voted for that one.

14:36 andyf: weighted vote not so much, but Alex Miller says he looks at tickets sorted by normal vote counts sometimes, too.

14:36 which is straightforward to get from JIRA already, without my separate report.

14:37 arrdem: meh we'll see how feature expressions shake out.

14:37 andyf: plus, you are allowed to lobby :)

14:49 cfleming: Yeah, Clojure accepts pretty much any old rubbish as symbol constituents

14:49 And hence, keyword constituents too.

14:49 The doc is sadly meaningless.

14:50 Or at least, bears no relation to reality.

14:50 andyf: cfleming: I don't see your vote :)

14:50 cfleming: Oops, you're right, done :)

14:51 Although I'm sure I've voted for another similar issue.

14:51 I'm sure there's a way to see which issues I've voted for, but I can't find it.

14:52 andyf: One way is looking at the top voted ticket reports here: http://jafingerhut.github.io/clj-ticket-status/clojure-ticket-info.html

14:52 The generation code remembers how to query JIRA for it, so I don't have to.

14:53 cfleming: That is a fine goal for generation code.

14:53 My weighted vote is probably subject to floating point underflow at this stage.

14:55 Actually, according to the report I've only voted for 5? Hmm

14:56 andyf: cfleming: The number there only includes tickets that are currently open. If you voted for tickets that have since been closed, the remaining tickets you vote for get bumped up a bit.

14:56 cfleming: andyf: I feel like not many of my issue have ever been closed, but perhaps I'm just feeling petulant :)

14:57 andyf: thanks for the report link, it's very useful. I think I'll be diluting my vote a little more.

14:57 andyf: Excellent.

15:04 yedi: is there a cljs fn for getting a human readable date string from an instant

15:08 nvm, ofc the str function just works

15:09 thought it would be nice if there was a function that let you specify which info in the datetime you wanna display, like a print format option

15:09 looks like i might have to make that

15:19 dnolen_: yedi: http://docs.closure-library.googlecode.com/git/class_goog_i18n_DateTimeFormat.html

15:53 luther07: term-line-mode

18:16 kenrestivo: what's the advantage of using async/thread as opposed to just future? i kinda like using future-cancel

18:17 rhg135: kenrestivo, it returns a channel with the result

18:18 instead of IDeref

18:18 kenrestivo: right, but in a loop, i don't care about the result

18:18 i'm just while'ing for side-effect

18:19 rhg135: then you can use a future/Thread/start

18:20 justin_smith: does async/thread use a pool? future does

18:20 kenrestivo: so if i've got (future (loop [] (let [v (async/<!! some-chan)] (do-side-effecting-stuff v) (recur))), why would i need async/thread and the return value?

18:21 all i'll want to do is shutdown that loop. again, forgive me if i'm thinking like a linux sysadmin dealing with daemons, because that's what i am.

18:22 justin_smith: kenrestivo: realize that you will go into a super fast busy wait with nils if you do it that way, but if you check for nil before the recur, you can automatically cut it short

18:23 (if/when the channel closes, that is)

18:23 rhg135: he is corect

18:23 justin_smith: take on a closed channel instantly returns nil, you will peak out the CPU doing nothing

18:24 kenrestivo: good point, i actually am checking that. but i'm still not clear on why future vs async/thread

18:24 justin_smith: may as well use channel closing to control your loop

18:24 depends on whether you want to use part of the future pool I'd say

18:25 kenrestivo: when-let, not let :-)

18:25 justin_smith: frequent relatively short lived things? yeah. Something long lived? just use a future, and count on when-let stopping the loop when you get nil on the channel

18:26 kenrestivo: that's kind of what i figured. just want to make sure i'm not missing anything important, thanks.

18:28 the #clojure code review

18:29 arrdem: #clojure will review just about any code you dare link :D

18:29 halfbaked ideas are for #clojure-offtopic however

18:30 bbloom: csd_: you can't with recur, since the addition is in tail position. recur only works in tail position. you can make a normally recursive function or implement the function with an explicit accumulato

18:31 r

18:47 magicantler: Hey, has anyone here used clojure as a token-based-auth rest api?

18:48 rhg135: magicantler, i've been luck to never need authentication

18:49 magicantler: So what type of web-apps have you dealt with then?

18:49 I was looking to make a mobile back end

18:49 and I just went through the node.js train and phew...

18:50 TEttinger: I think Friend is the main lib people use in clojure for auth, but don't quote me on that

18:50 rhg135: a blog with posts metadata in datomic

18:50 i figured i can add posts locally through a repl

18:52 arrdem: To the extent that there is a Clojure auth story, Friend is the only thing I know of

18:53 magicantler: Well, if you guys don’t mind me asking, why would one choose to use clojure for a webservice, say over node.js?

18:56 rhg135: sanity

18:56 ticking: is there a proper way to match lists in core.match except for (([1 x 3] :seq) :guard list?)?

18:56 rhg135: i'm not familiar with js but i think 1 + "1" is valid

18:57 ticking: rhg135: yeah it will give you 11

18:58 arrdem: Writing the entire "wat" talk off as a low blow, I'd say that people use Clojure because they want to leverage JVM resources without dealing with Java or Scala.

18:58 rhg135: [] + {} is and i've actually seen it used

18:58 hipsterslapfight: valid yes, but known as an awful idea not to be touched

18:58 Fare: which if any is cheaper to use as a key, a :keyword, or a "string" ?

18:58 ticking: Fare: :keyword by far

18:59 Fare: ok

18:59 SagiCZ1: ticking: sauce?

18:59 ticking: Fare: they are interned strings so equality checks should be integer equality ops

18:59 arrdem: lazybot has abandoned us

18:59 ticking: they should be equally expensive

18:59 rhg135: hipsterslapfight, valid implies will be used

18:59 ticking: arrdem: really?

18:59 Fare: ok, so I'll tweak my data representation accordingly.

19:00 hipsterslapfight: rhg135: sure, it could be. i'm saying it shouldn't (and if you know what you're doing, you won't). that's not even the worse of the insane things in JS (though probably one of the top 5)

19:00 certainly a bad language for beginners though

19:02 rhg135: hipsterslapfight, everyone is a beginner

19:02 hipsterslapfight: hah

19:02 rhg135: im serious

19:02 what is the distinction

19:03 and does one ever acquire it

19:04 hipsterslapfight: hmm, i was using "beginner" to refer to the fact that js is often used as a first language for people just getting into programming; something i find very silly.

19:04 arrdem: when you've done a clean room implementation of $LANG you are no longer a beginner at $LANG

19:04 SagiCZ1: hipsterslapfigh: what would you use as a first language for beginners?

19:04 arrdem: hipsterslapfight: meh everyone has a JS REPL in their browser. ease of getting started counts for something.

19:05 that said we have Haskell and Lisp REPLs that run in browsers atop js so..

19:05 hipsterslapfight: SagiCZ1: something functional, maybe a lisp. i should think on this more

19:05 arrdem: we sure do, though not quite as easy as js is

19:05 SagiCZ1: would you say that functional programming makes more sense then imperative for a beginner?

19:06 arrdem: SagiCZ1: yes in a heartbeat

19:06 hipsterslapfight: SagiCZ1: definitely

19:06 SagiCZ1: but everyone can understand imperative sequence of steps.. its like a recipe from a cookbook

19:06 rhg135: hipsterslapfight, js is a great language for some people

19:06 hipsterslapfight: rhg135: it's a great language for me, i make my living from it :v

19:06 lachenmayer: yep... beginners have a surprisingly hard time with the imperative assign "=" operator :)

19:06 rhg135: it teaches you how NOT to program

19:07 arrdem: SagiCZ1: sure, but most of those steps turn out to be boilerplate whereas a pure function is directly and obiously derived from the problem statement.

19:07 SagiCZ1: lachenmayer: wow that is true

19:07 arrdem: (inc lachenmayer)

19:07 damnit lazybot

19:07 SagiCZ1: lazybot is too lazy

19:07 ticking: arrdem SagiCZ1 Fare: sauce, https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java#L32 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Symbol.java#L72

19:07 arrdem: Raynes: oi. kick the bot <3

19:07 rhg135: lazybot died

19:08 arrdem: it's been dead for a few hours now :C

19:08 justin_smith clearly didn't get enough stability improvement

19:10 triss: hey all. does do (comp doall map) exist in the standard lib anywhere?

19:11 arrdem: triss: no, but we have mapv

19:11 rhg135: hipsterslapfight, that doesn't make it a great language

19:11 arrdem: triss: which has eager rather than lazy semantics

19:11 ticking: arrdem SagiCZ1 Fare: there is also classloader foo in which case two keywords won't be comparable with reference comparison, regarding strings, if they are all written as literals they will be interned by the compiler afaik, so they should be equal in performance, unless you generate them dynamically

19:11 hipsterslapfight: rhg135: what?

19:11 SagiCZ1: ticking: thanks for the digging

19:11 triss: cheers arrdem. I'll take a peek

19:12 arrdem: http://conj.io/1.6.0/clojure.core/mapv

19:12 triss: ^

19:12 rhg135: it makes it a money makin gtool whereas a programing language is a creation tool

19:12 hipsterslapfight: rhg135: ":v" was to denote i was being sarcastic

19:13 rhg135: hipsterslapfight, sarcasm and interwebz do not mix

19:13 arrdem: (with-sarcasm ...

19:13 #sarasm ...

19:13 hipsterslapfight: haha

19:13 rhg135: (inc arrdem)

19:13 arrdem: *#sarcasm <form>

19:13 rhg135: dammit lazybot

19:14 ticking: no no you have to use sarcasm feature expressions because it is determined at read time

19:15 #+sarcasm <form>

19:15 bbloom: csd_: (defn fib [n] (loop [acc 0 i 0] (if (= i n) acc (recur (+ ....

19:15 arrdem: ticking: in oxlang it's determined at eval time not at parse time :P

19:15 andyf: arrdem: when did conj.io become available?

19:15 ticking: :D

19:15 rhg135: (say ... {:sarcasm true})

19:15 arrdem: andyf: as the Grimoire domain?

19:16 andyf: I've had it for two months or so now.

19:16 andyf: it's pointed to Grimoire since mid summer, I just wasn't ready to use it.

19:16 andyf: Wow, I guess I haven't been watching very closely.

19:16 arrdem: I actually need to renew it before one of you steals it from me...

19:21 magicantler: arrdem: is it easier to use than scala..?

19:22 arrdem: magicantler: is what easier than scala?

19:22 magicantler: clojure?

19:22 magicantler: indeed

19:22 rhg135: maybe

19:22 easy is subjective

19:22 arrdem: (dec Raynes)

19:22 ticking: hell yes

19:22 magicantler: I guess I’d like to know why people gravitate towards it. lol

19:22 ticking: clojure > java > scala

19:22 arrdem: rhg135: eh we have "simple" and "easy" as defined by Rich :P

19:22 magicantler: have you watched simple made easy?

19:23 rhg135: arrdem, he agrees it's relative

19:23 bbloom: justin_smith: i think the loop/recur is basically the only reasonable thing :-P

19:24 magicantler: I’ll watch it

19:24 Do you guys find your java skills being used in clojure a fair bit?

19:24 arrdem: I'd say that Java is imperically simpler than Clojure or Scala, but Clojure is simpler than Scala and leads to simpler problem solutions than either java or scala.

19:24 magicantler: arrdem: and where would you place haskell in this?

19:24 arrdem: magicantler: going on three years of Clojure for hoby work, less than 500 lines of Java actually written.

19:25 magicantler: hard to say.

19:25 rhg135: somewher off to the side i'd say

19:25 arrdem: I will refrain from commenting on Haskell because while I like it and understand some of what it does I haven't used it.

19:26 TEttinger: magicantler, I've used a small bit of Scala, but that's all I will ever use because the language is so massive that you really can't learn much of it

19:26 just the syntax is a mess

19:28 arrdem: the only scala I had to write was an implicit type cast based DSL for a school project on doing implicit type cast DSLs

19:28 magicantler: TEttinger: What do you use clojure for?

19:28 arrdem: it was disgusting, slower than the Clojure implementation I did, and I swore off Scala when I was done.

19:29 dweave: are transducers really just parameterizing a ‘conj’ operation?

19:29 is that the same problem haskell type classes solve?

19:31 magicantler: arrdem: ha wow. Sorry to hear that. I wonder why Spark is pushing scala.

19:31 Getting The Joy of Clojure now :D

19:31 rhg135: $$

19:31 it makes the world gor ound

19:32 magicantler: rhg135: elaborate please lol

19:32 rhg135: im not acquainted with the complexities of modern life

19:33 magicantler: Listen to the corporations that tell you to buy things and keep quiet ;p

19:35 rhg135: since scala might look familiar maybe companies think it may encourage ppl to think they're cool/hip and give them $$

19:37 TEttinger: there's an interesting pair of interviews with scala types here http://www.infoq.com/articles/barriers-to-scala-adoption

19:41 ticking: for me it boils down to clojure being deterministic and scala being nondeterministic

19:41 TEttinger: I use clojure for a continually-modified IRC bot originally starting as lazybot, often for small script-style projects (where if writing the code takes 300 lines of java it can be expected to be under 50 in clojure, in my experience) and also sometimes for games using play-clj.

19:41 I think it's much better suited for web apps than 1-player games, based on the presence of so many database, auth, templating, etc. libs and cljs

19:42 I also wrote a game in C# using libgdx (what play-clj wraps), then ported that to Scala and have had a hard time with Scala. the IDE support is quite lousy and it really needs an IDE, unlike clojure

19:42 ticking: I know what clojure does and can rougly estimate performance and behaviour, with scala its all luck, maybe tail call optimisation kicks in, maybe it won't, maybe the type system will be able to figure it out maybe it won't

19:43 TEttinger: I just didn't like the attitude of the scala community that I asked for help on, it was something like, "we wish we could just use haskell but we're stuck with the JVM"

19:43 ticking: hrhr

19:43 TEttinger: people actually said that though

19:45 ticking: TEttinger: yeah sounds like something scala people would say :D

19:45 rhg135: TEttinger, s/we/i/ is what bitemyapp once said

19:45 ticking: TEttinger: but I don't quite get it, because haskell strives for elegance, while scala strives for doing it sll

19:45 all

19:46 magicantler: and what does clojure strive for..?

19:47 arrdem: some balance of the two as judged by Rich

19:47 ticking: magicantler: simplicity?

19:47 dweave: so are transducers lazy?

19:47 i’m confusedd

19:47 arrdem: dweave: they _can be_ but need not be.

19:47 ticking: dweave: transducers separate the concept of lazynes from the operation on collections

19:47 dweave: right

19:47 are lists and vectors both lazy?

19:48 ticking: dweave: you can have transducers work on vectors, set, lazy seqs or even core.async channels

19:48 dweave: neither are

19:48 dweave: lazy sequences are lazy, they are their own datatype

19:48 TEttinger: magicantler, I think of clojure as making hard things easier first, and making every piece of code smaller and involve less state as another thing.

19:49 ticking: dweave: clojure does not have lazynes as a language feature, it has one construct that provides lazyness, called a seq

19:49 dweave: ok

19:49 * Fare starts working again on his pure python dialect implemented in clojure

19:49 dweave: how is fusion done?

19:49 it just isn't?

19:49 ticking: dweave: fusion?

19:49 arrdem: Fare: have you seen pixie?

19:49 Fare: I'm taking a break from the compiler, and focusing on the runtime

19:49 what's pixie?

19:49 dweave: like deforestation

19:50 ticking: Fare: dum dum dum

19:50 TEttinger: clojure-like in rpython

19:50 arrdem: tbaldridge's clojure on python

19:50 dweave: i think this is the right word

19:50 ticking: arrdem: clojure on RPython =|= clojure on Python at all

19:50 Fare: I'm doing kind of the opposite

19:50 ticking: dweave: don't fall for the syntax that seqs are printed in which is () the same as lists

19:50 dweave: for instance psudocode: filter(f, map(f, list));

19:50 TEttinger: dweave: pruning? tree-shaking? can you describe what the feature does?

19:50 dweave: that would iterate the list twice

19:50 Fare: I'm doing python in clojure

19:51 dweave: i want to iterate it only once

19:51 Fare: well, a pure python anyway

19:51 dweave: haskell solves this because lists are lazy

19:51 ticking: dweave: yeah and map and filter operate on seqs

19:51 dweave: in an eagerly evaluated language like Js that would be inefficient

19:51 ticking: dweave: so they are lazy, mapv returns a vector for example and is not

19:51 dweave: ok i see

19:51 Fare: dweave: if your compiler can deforest

19:52 TEttinger: can a transducer do that?

19:52 arrdem: Fare: wanna come write an immutable interpreter for me? :P

19:52 dweave: (map inc [1 2 3 4 5])

19:52 is that not lazy?

19:53 ticking: dweave: it is because map works on sequences

19:53 dweave: so there’s an intermediate step?

19:53 to convert that vector to a seq?

19:53 ticking: dweave: sequences are both an abstraction as well as a datatype, most clojure functions will turn a collection into a sequence first and then operate on them

19:53 dweave: basically yes

19:54 dweave: ok

19:54 ticking: dweave: with transducer you get rid of that conversion step

19:54 dweave: you will specify the operations that you want to do say (comp (filter even?) (map inc))

19:55 dweave: compose them with function composition and then run a transducing function like (into [] (comp (filter even?) [1 2 3])

19:55 dweave: ok

19:55 cool

19:55 TEttinger: ,(into [] (comp (filter even?) (map inc)) [1 2 3 4 5])

19:55 clojurebot: [3 5]

19:55 ticking: which will evaluate egaerly, yet have no intermediate steps and only allocate what is needed for a vector, or you could do (sequence (comp (filter even?) [1 2 3])

19:56 arrdem: one better (comp (map inc) (filter odd?))

19:56 TEttinger: oh right, transducers use comp in regular order

19:56 arrdem: because addition is expensive :P

19:56 ticking: which will return a lazy sequence because the final transducing function has that as it's model of evaluation

19:56 dweave: ahh

19:57 starting to make sense

19:57 ticking: dweave: so you basically separate what should be done from how it should be done

19:57 TEttinger: ,(into [] (comp (map #(* % % 3/2)) (filter #(= (mod % 3) 0))) (range 50))

19:57 clojurebot: [0N 6N 24N 54N 96N ...]

19:57 dweave: is it generally hard to ‘change’ from lazy to eager evaluation

19:58 ticking: dweave: with transducers no, currently kinda

19:58 TEttinger: but transducers should be part of clojure stable release soon

19:58 dweave: so like transducers are kind of this optional thing that haven’t made it into the core yet?

19:59 TEttinger: they'll be in 1.7

19:59 which is in alpha

19:59 dweave: i’m like completely new btw ha

19:59 cool

19:59 ticking: dweave: you have map and mapv, you can force evaluation with doall or into, and you can use reducers, but all of these are inconsistent and sometimes slow

19:59 dweave: yeah some people run the current alpha just for transducers :S

19:59 TEttinger: like clojurebot

19:59 dweave: it’s an interesting concept. I just watched one of hickey’s talks tho and it seems weird taht i have to parameterize both ‘[]’ and ‘conj’

20:00 for some reason

20:00 ticking: dweave: hm?

20:00 TEttinger: vector, vec, or nth as '[]' ?

20:00 dweave: vector

20:01 like if I have a vector wouldn’t my ‘step’ function always be conj

20:02 ticking: needs more input ;)

20:02 could you provide a code example where this happens?

20:02 dweave: i think i’m prob not fully understanding i should read more.

20:03 ticking: dweave: I'm curious though :D

20:03 dweave: lemme find

20:03 ticking: dweave: transducers have this weird inside out property

20:05 transducers always remind me of this https://www.youtube.com/watch?v=nW-NiGp1gys

20:05 dweave: oh nvm I just got confused. https://www.youtube.com/watch?v=6mTbuzafcII at 16:00 there was this intermediate step

20:05 actually no. 19:39

20:06 ticking: dweave: those are not transducers yet I think

20:06 dweave: yeah

20:06 exactly

20:07 showing how he’s arriving at them

20:07 ticking: yeah

20:07 dweave: conj is the general insertion operator btw

20:07 dweave: ah yeah i was wondering

20:07 ticking: dweave: it adds in the most efficient way to collections, for lists at the front, vectors at the back, for maps it takes pairs

20:08 sets, don't care about order

20:09 dweave: ticking: (reduce (xform conj) [] (range 10))

20:09 that function

20:09 oh wait sorry

20:09 hold on

20:09 http://pastebin.com/Njgpqe4G

20:10 ticking: dweave: that is the inside out thing I meant

20:10 dweave: so here the vactor is first mapped?

20:10 or just the first item is mapped

20:10 and then mapped again by square

20:10 i think the latter right?

20:10 ticking: yeah

20:11 you do everything in one step

20:11 and then do the next step

20:11 dweave: nice!

20:11 so this is accomplishing what i was talking about without being lazy

20:11 ticking: devils in the details, so not always for example with partition I think

20:11 dweave: ya

20:11 ticking: dweave: yeah

20:11 dweave: man this is interesting.

20:12 ticking: and the conj is there to pass the insertion function

20:12 dweave: yeah

20:12 ticking: it has to be threaeded in there

20:12 dweave: cause you could supposedly want to do something else to a vector

20:12 i guess

20:12 ticking: reducers make my head spin because of this but they seem quite usefull

20:12 dweave: yeah

20:12 ticking: dweave: well

20:12 dweave: not really, but because you could wan't something else then a vector

20:13 dweave: yeah

20:13 ticking: dweave: passing the insertion function separates the collection type from the operations

20:13 dweave: yeah

20:13 it’s just necessary

20:14 ticking: dweave: so if you provide conj, you will work on vectors, if you provide something for creating lazy sequences like cons you will get lazyness, if you want to work on CSP channels you provide a function for that like put!

20:14 dweave: gotcha

20:15 awesome

20:15 thanks. I’m sure ill be back

20:16 ticking: always welcome :)

20:18 Fare: arrdem: interpreters? what's that?

20:18 I admit I'm using state in some places, though in a monotonic way

20:18 also for caches

20:19 the python calling convention is such a pile of lose, I have to write JIT for it.

20:19 ticking: Fare: looked at pixie?

20:20 Fare: ticking: it's doing the reverse of what I want: lisp in rpython, rather than python in lisp

20:20 ticking: Fare: a python interpreter in clojure?

20:20 Fare: also, clojure is significantly different from other lisps that e.g. not much of clpython can be reused

20:21 interpreter? I said implementation

20:21 more like a compiler

20:21 ticking: Fare: why? :D

20:22 Fare: why what?

20:22 I wanted to write a compiler

20:22 for many reasons

20:23 "performance" being one of them

20:23 and getting experience another

20:23 ticking: Fare: ah, I wondered, maybe you have a python codebase that you want to put clojure underneath

20:23 Fare: yes, kind of

20:23 I do

20:24 currently using a horrible naive interpreter written in Java

20:24 Java: the COBOL of the 1990s

20:24 i.e. bureaucracy-oriented language

20:25 ticking: isn't there a python on the jvm already?

20:25 Fare: yes, but it does too much

20:25 ticking: jython

20:25 Fare: a big part of the idea is a pure, restricted python

20:25 ticking: ah

20:26 Fare: trying to sandbox jython is not a good idea

20:26 ticking: why not use clojures persistent datastructures from within jython?

20:26 Fare: and we had enough trouble failing to properly sandbox cpython

20:26 ticking: sandboxing it on the app level?

20:26 Fare: security / determinism / reproducibility

20:27 ticking: why not use peroper virtualisation?

20:27 Fare: we really really really don't want state leaks

20:27 what we had before — expensive, slow, and the sec team still found leaks

20:27 ticking: http://bhyve.org ?

20:29 Fare: sure, things like that can work, but a new VM for every single of the thousands of small proglets we write is actually too expensive, vs a slow in-memory but guaranteed hermetic language reimplementation.

20:29 not even the full language

20:29 ticking: Fare: these systems are build for thousands of virtual systems afaik

20:29 theyre pretty lightweight

20:30 app level sandboxing always feels like snakeoil to me

20:30 Fare: starting running and stopping a thousand VMs in a few seconds, for each of tens of thousands of simultaneous tasks? Nope.

20:31 language level sandboxing is what we want, hence a pure functional language.

20:32 ticking: I'd maybe trust it it was written in idris :D

20:32 Fare: transforming either cpython or jython into something pure functional... nope

20:32 ticking: I proposed a haskell dialect for the jvm, but the idea wasn't taken seriously by other team members.

20:33 ticking: Fare: to bad

20:33 Fare: yup

20:33 well, that means I get to experiment with my own pure functional compiler

20:34 (even though the runtime has a bit of state for (1) caches (for performance) and (2) tying magic knots, and (3) interfacing with the rest of the system

20:35 (2) could be done away using additional level of indirection and/or state-passing, but see (1)

20:37 I myself am both a proponent of 100% pure and 100% stateful — simultaneously, as a change of perspective in interfacing the system

20:37 problem is, no system currently allows to do that seamlessly

20:38 ticking: hrm

20:38 Fare: sandboxing is fine, it just can't be retrofitted

20:38 just like automatic pure←→stateful viewpoint switching

20:38 or security, or any deep semantic property

20:39 orthogonal persistence, etc.

20:41 lambda: .(str " " " " "b")

20:42 ,(str " " " " "b")

20:42 clojurebot: " b"

20:42 lambda: ah -ha, clojurescript issue maybe

20:44 sg2002: Gonna ask here too, since there are probably some paredit users here - how do I escape an existing character in paredit? For example <?xml version="1.0" encoding="UTF-8"?> - I want to escape double quotes here. But \ asks me to enter a character, so I end up with "" before 1.0.

20:46 amalloy: sg: C-q \

20:46 C-q is bound to "insert the following character, no matter what my dang mode says"

20:46 TEttinger: (inc amalloy)

20:46 (dec lazybot)

20:46 sg2002: amalloy: Thanks. Didn't think of that.

21:07 otti: hm i have defined a test: (deftest endpoints (another_test) (also_a_test))

21:08 now when i add a mixin that is supposed to only run once

21:08 will it only apply to the test "endpoints"

21:08 or also to any subsequent test enclosed in this test?

21:08 cause i only want to run it once for the test endpoint, to setup a database

21:09 sorry fixtures not mixinx

21:11 k the doc actually states it clearly

21:42 Fare: what is the idiomatic way to do defvar in clojure?

21:43 i.e. if some variable is already bound to some atom, I don't want a new atom but the old one.

21:45 arrdem: Fare: check out the way that defmulti works.

21:46 Fare: I seem to be having a problem with defrecord and AOT

21:46 on 1.6

21:46 is that a known issue?

21:47 a form using ->$Monotonic works at the REPL, but lein says: skylark.mop.$Monotonic cannot be cast to clojure.lang.IFn, compiling:(skylark/mop.clj:66:48)

21:51 never mind, it was improper quoting in a macro

21:52 (which doesn't explain why it was working at the REPL)

22:32 otti: hm can someone recommend a sql ddl library

22:32 the documentation of lobos is kind of horribel :/

23:13 andyf: Fare: Clojure's defonce might be close enough to Common Lisp's defvar to do what you want

23:14 Fare: thanks!

23:15 andyf: Fare: There are some known bugs related to AOT in Clojure. Some of them have gotten some attention recently and may have correct patches now, but not known whether they will be in Clojure 1.7 or not. Example: http://dev.clojure.org/jira/browse/CLJ-979

23:15 There are a handful of other AOT-related bugs.

23:16 Fare: when is 1.7 expected?

23:16 andyf: Ah, here is a recently created wiki page with a link to known issues, some of which are fixed in 1.7.0-alpha4, but several not.

23:17 I am not aware of a scheduled date for 1.7. They are working on adding some more performance enhancements related to transducers, and may add feature expressions, before releasing. Somewhere in the next 2-6 months would be my guess.

23:18 There will be more released alpha and/or betas before then, most likely.

23:33 munderwo: Anybody know how to inspect the contents of a clojurescript core.async channel?

23:40 puredanger: andyf: I'm hoping to get another alpha/beta out before the holidays

23:41 andyf: nice. I know you've been putting in a lot of hours on some of those transducer enhancements.

23:41 puredanger: feature expressions is still on the list. we go beta when all "features" are tentatively done, so we won't go beta till those are in.

23:41 virtually everything in 1.7 is ready to review at this point

23:41 I'm planning to review the AOT stuff this week so I can make a case for inclusion as well

23:42 andyf: Did the Conj unsession on feature expressions raise any new points you hadn't heard before?

23:42 puredanger: was most useful to me to hear people ask Rich questions about it :)

23:43 andyf: btw, I have a new blog: http://insideclojure.org that you might enjoy

23:44 I often build up a lot of mental knowledge around parts of Clojure while working on tickets. hoping to drop it here so maybe I'll remember some of it.

23:44 arrdem: +1

23:45 puredanger: we have a bunch of stuff queued for a core.async release too

23:45 andyf: thx for the link. I find I learn the most when digging into something deeply myself and writing about it.

23:45 puredanger: yup

23:45 andyf: Writing Eastwood linters has been an educational experience on some corner cases.

23:45 puredanger: I bet :)

23:45 presumably a linter is all corners :)

23:46 andyf: The saving grace being that I try not to double-check things Clojure already does, just the things it lets through silently.

23:46 that and it can be useful even if it doesn't catch everything :)

23:49 So hearing people ask Rich questions about feature expressions, did things end up pretty much where the current proposal is, e.g. #+cljs expr effectively becomes whitespace if feature cljs is not present?

23:50 puredanger: tbd - I haven't had a chance to talk to it about him yet

23:50 Bruce_Wayne: Does anyone know a bit about OCR?

23:50 puredanger: but I would say yes

23:50 Bruce_Wayne: I am looking to pull text from images

23:51 arrdem: Bruce_Wayne: gonna have to make that more clojure-specific if you want to get useful help here.

23:51 especially this late US/west

23:51 Bruce_Wayne: does anyone know a good clojure library for OCR

23:51 like using clojure vision

23:51 puredanger: andyf: the big questions in my mind are whether we could do less now

23:52 Bruce_Wayne: then pulling the text

23:52 puredanger: andyf: and add more later if necessary (omitting things like #-, boolean conditions, *feature-expressions*, etc)

23:52 Bruce_Wayne: would anyone know a better place to ask about OCR? better chatroom?

23:53 andyf: I didn't watch all of the videos published from the Conj, but I have a feeling Rich may have suggested Brian Goetz as a speaker, and the topic.

23:53 puredanger: andyf: I suggested him

23:54 I think Brian came up with the topic, but I know he worked with Stu on fine-tuning it quite a bit. Rich, Stu, and Brian have known each other for a long time and there is a lot of mutual respect there.

23:55 andyf: Bruce_Wayne: There are several open source programs/libs for OCR that I've heard of, and tried a few years ago. All of them I know of are accessible from a Linux scanning program called gscan2pdf. Some names are: tesseract, gocr, ocropus, cuneiform. Search for "ocr" here for a list and links to them: http://gscan2pdf.sourceforge.net

23:56 Bruce_Wayne: andyf: Do they have the ability to pull text from a jpg image per say

23:56 andyf: I'm not aware of any Java libs for it, and don't have a suggestion for an on-line forum to ask in.

23:58 Bruce_Wayne: I think all of them can pull text from an image, but they might vary in what image format they require. e.g. some might require converting to gif.

23:59 I think some/all of those programs may have already-built package for them in, e.g. Ubuntu Linux.

Logging service provided by n01se.net