#clojure logs

2010-11-19

00:00technomancyrata_: the example on that page actually is a leiningen plugin; you just have to add it to :hooks in project.clj to activate it
00:00technomancyI've been thinking about a function that would abstract away the messiness of being able to add-hook inside eval-in-project, but haven't written anything yet
00:00rata_yes, I got that part
00:02rata_the part I don't imagine how to implement is how to show the return value of a function call and all its locals
00:02rata_I thought that had to be implemented in swank-clojure
00:05technomancyhmm... lemme think
00:07technomancyif you don't mind args being a single vector instead of being named, this would do it: http://p.hagelb.org/break.clj.html
00:07technomancyit would be possible to make break-hook's args match those of the target function with a severe macro, but I don't think I'm up for the task right now
00:10rata_yes, that's close to what I want, but I'd like to see the locals, not just the args
00:10rata_that's the most complicated part probably
00:11technomancythe macro would have to construct the hook function based on the :arglists in the metadata of the target function
00:12rata_it'd have to insert the body of target there to have all the locals
00:13rata_but the hook can't be a macro
00:13technomancyno, not necessarily. you could construct a wrapper function which has the same argument list as the target function and simply pass the arguments on to the target function
00:13technomancyright, the hook can't be a macro, but the hook function could be generated by a macro
00:14rata_yes... but the locals... even if you has the same argument list, you can't see the locals of target
00:14technomancywell, the way hooke works is that the target function is replaced by the wrapper function
00:15technomancyso as long as the wrapper function passes the same args into the target, a break point in the wrapper will be equivalent to a break point inside the target
00:15technomancyas long as the wrapper has the same names for all its arguments
00:15technomancythe only difference is the first argument of the wrapper *is* the target
00:16technomancyit's a juicy problem... if you don't do it then maybe we can tackle it at the next Seajure meeting
00:16rata_so, you are saying that with that break.clj, if you have a (let [x ...] ...) inside target, you could see the value of x?
00:17technomancyoh no not like that; just the function parameters
00:17technomancyI see what you mean
00:17rata_=)
00:18rata_that's the difficult part I think
00:18technomancyI thought you meant you'd rather see (defn my-target [a b c]) as a b c rather than & args
00:18rata_no... I mean all the locals of the function
00:18rata_not the args
00:18technomancyI don't know if it's possible to get even the let-bound stuff
00:19technomancyon a regular defn anyway, you could do it with a defn-debug... which is what you suggested in the first place. =)
00:20technomancyit still might be tricky to traverse the body find all the tail positions in order to insert breakpoints
00:20rata_if you just want to see the locals, it's easy, you put a (swank.core/break) just before the expression that returns the value of the function, in the most nested let (don't care about let "branches")
00:20rata_yes, it might be tricky
00:22rata_but in addition to have the value of all the locals, it'd be great if you could see along them the return value of the fn
00:23technomancythat shouldn't be too hard; just replace the final value with (let [return-value# ~v] (swank.core/break) return-value#)
00:23rata_because it happens to me all the time that to see just the return value of one fn is difficult, because I normally put it inside a form, so I don't bound it directly to a local
00:23technomancyof course with pure functions once you have the locals it's easy to calculate the return value =)
00:24rata_it involves to write (or copy-paste) a lot of code to the repl
00:24rata_and it's annoying when you have to do it for many fns
00:24rata_to find where the bug is
00:25KirinDaveIs there a clever way of invoking protected methods on instances from clojure?
00:26rata_that's why I suggested something like defn-debug that puts a (let [return-value# ~v] (swank.core/break) return-value#) at the right place
00:26rata_=)
00:27technomancyrata_: yeah, I think you have the right idea.
00:28rata_I find (swank.core/break) immensely useful when debugging, so I'm sure having something like defn-debug would be very useful as well =)
00:28rata_the first name I thought about was defn*, but then remembered that the asterisk is mainly used by the compiler
00:29rata_*thought of
00:31technomancynot just used by the compiler, but it does indicate an internal function
00:31technomancydefn-debug is better
00:34hiredmanKirinDave: clojure.contrib.reflect I believe
01:10rata_if "lein compile" with :warn-on-reflection true doesn't warn about anything, does it mean that type hints wouldn't help the performance?
01:12tomojneed to actually run the program, no?
01:13KirinDavehiredman: Thank you, btw
01:13amalloytomoj: i don't think so. the reflection warnings are only at compile time
01:19tomojhow can clojure know at compile time whether there's reflection?
01:20amalloytomoj: um, because if it can't resolve the method calls at compile time, it has to generate code that uses reflection to resolve them at runtime
01:21rata_so what about my question?
01:21amalloyrata_: i don't know. i don't use lein compile or warn-on-reflection
01:21rata_ok
01:23rata_methods are compiled as anon fns right? that is, they are compiled as fn__xyz?
01:23amalloyyou mean, anon fns are compiled as methods?
01:24amalloyeither way it's not correct. functions, anonymous or not, are compiled as classes with an invoke(args) method
01:26rata_yes... I mean that methods are compiled to classes like fn__148
01:27rata_is there a way to give names to methods, like (fn name [...] ...)?
01:29dnolen(letn [f (fn foo [])] f)
01:29dnolen,(letn [f (fn foo [])] f)
01:29dnolenerg
01:29dnolen,(let [f (fn foo [])] f)
01:29amalloy&(fn name [] 1)
01:29sexpbot⟹ #<sandbox8506$eval10166$name__10167 sandbox8506$eval10166$name__10167@184dc98>
01:29amalloy,(fn name [] 1)
01:29clojurebot#<sandbox$eval104$name__105 sandbox$eval104$name__105@de04cd>
01:29amalloysexpbot: kill
01:29sexpbotKILL IT WITH FIRE!
01:29amalloyhuh. sexpbot is dead. Raynes, you around?
01:29amalloyanyway rata, that's exactly how you do it
01:30clojurebotjava.lang.Exception: Unable to resolve symbol: letn in this context
01:30clojurebot#<sandbox$eval109$foo__110 sandbox$eval109$foo__110@260829>
01:30amalloyah, good morning sexpbot
01:31amalloy&(fn quetzacoatl [x] (+ 10 x))
01:31sexpbot⟹ #<sandbox8506$eval10175$quetzacoatl__10176 sandbox8506$eval10175$quetzacoatl__10176@11a7733>
01:39trybeingarun Hey guys
01:39trybeingarunhow do you write a recursive function when you use #(function) format?
01:40trybeingarunletfn here also?
01:40amalloytrybeingarun: you could do it with recur. but usually, "don't do it" is a good answer
01:40trybeingarunyou do you recommend against doing it? Readability issues or anything else specific?
01:41amalloywell, rolling your own recursion is usually unnecessary - you get better and more readable code by using HOFs like reduce, iterate, map, etc
01:41amalloyand if you want to, it's usually complicated enough to merit a (defn) or at least a (fn)
01:42trybeingarunhm
01:42trybeingarunAm currently trying to write all the code in "The Little Schemer" in clojure
01:42_atoyou can't do non tail recursion with #(...)
01:42_atoyou can with fn though
01:42_ato(fn foo [x] (when (pos? x) (foo (dec x))))
01:42trybeingarunThere is a specific chapter on lambda functions
01:43dnolentrybeingarun: #(f ..) is for simple stuff, easy abused, I avoid it now mostly.
01:43trybeingarunso I was wondering how to write recursion in such scenarios
01:43amalloytrybeingarun: (fn) is lambda
01:43dnolentrybeingarun: use fn
01:43amalloy#() is shorthand
01:43trybeingarun_ato: u mean 'recur' can't be used??
01:43mister_robotodnolen: how is #() easily abused? curious what kind of scenario you're thinking of
01:43_atorecur can't be used to solve all problems
01:43amalloy&(macroexpand '#(inc %))
01:43sexpbot⟹ (fn* [p1__10198#] (inc p1__10198#))
01:44dnolenmister_roboto: any scenario where the inside is complex, %1 %2 etc carries little meaning.
01:44trybeingarunamalloy & dnolen: currently I am using (fn ...). Just wanted to find out if the same can be done with %()
01:44mister_robotodnolen: so when it's complicated enough that you want the args to have real names
01:44amalloy&'#(inc %)
01:44sexpbot⟹ (fn* [p1__10206#] (inc p1__10206#))
01:45_ato,(#(when (pos? %1) (recur (dec %1))) 10)
01:45clojurebotnil
01:45amalloytrybeingarun: not always
01:45dnolenmister_roboto: I do, plus #() is just weak, no destructuring arguments
01:45dnolen&(map #(* % 2) [1 2 3 4])
01:45sexpbot⟹ (2 4 6 8)
01:45trybeingarunhm
01:45amalloy#() really is shorthand for simple cases of (fn)
01:46_ato,(#(when (pos? %1) (2 + (recur (dec %1)))) 10)
01:46clojurebotjava.lang.UnsupportedOperationException: Can only recur from tail position
01:46mister_robotodnolen: I use it all the time to map or apply something relatively small. normally don't care about destructuring in such cases.
01:46pppaul&(#(% %) #(% %))
01:46sexpbotjava.lang.StackOverflowError
01:46amalloyfor complicated cases, there's a reason you can't use #() :P
01:46_ato,(#(fn foo [x] (pos? x) (2 + (foo (dec x)))) 10)
01:46clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: sandbox$eval121$fn
01:46_ato,((fn foo [x] (pos? x) (2 + (foo (dec x)))) 10)
01:46clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
01:46trybeingarunamalloy: :P
01:46_ato,((fn foo [x] (pos? x) (+ 2 (foo (dec x)))) 10)
01:46clojurebotjava.lang.StackOverflowError
01:46_atoheh
01:46_atobrain not working well today
01:47_atonevermind
01:47_ato;-)
01:47pppaulmy code is better for stack overflows
01:47dnolen&(map (fn [[k v]] (* k v)) {1 2 3 4})
01:47sexpbot⟹ (2 12)
01:48amalloy&(map #(apply * %) {1 2 3 4})
01:48sexpbot⟹ (2 12)
01:48pppauldnolen, that's the sexy destructuring i like
01:48amalloydefinitely less efficient, though arguably more readable for such a simple case
01:49dnolen&(map (fn [[k v]] (* k (/ v 2))) {1 2 3 4})
01:49sexpbot⟹ (1 6)
01:49LauJensendnolen: Thanks for fighting the good fight on HN, I just read the comments :)
01:49dnolenLauJensen: ugh
01:49amalloydnolen: there you go, that's one that cries out for (fn)
01:49dnolenamalloy: ;)
01:50dnolenLauJensen: sometimes HN really lets you down. BTW, I'm really blown away by ClojureQL!
01:50dnolenLauJensen: just add multi table joins :D
01:50LauJensendnolen: I was quite happy to see that the majority of comments were positive actually, but its super sweet that you like it :)
01:50amalloy&(map #(/ (apply * %) 2) {1 2 3 4}) ; i guess?
01:50sexpbot⟹ (1 6)
01:50LauJensendnolen: multi table joins will be in 1.0.0 final, I just didnt have time before now
01:50dnolenLauJensen: also, do you do any SQL sanitizing?
01:51LauJensendnolen: like what?
01:51pppaulmapping over hashmaps is ugly
01:52dnolenLauJensen: does ClojureQL ever take raw strings for substition into the final query?
01:53LauJensendnolen: You can supply raw strings as column specs if you need. We also have an option to append a string to the final query
01:54dnolenLauJensen: so don't those need to be sanitized for SQL injection?
01:54LauJensendnolen: You mean parameterized?
01:54dnolenLauJensen: sure, I'm no SQL expert.
01:55LauJensenAh ok. Paramterization is on the chart for 1.0.0 final, its an important feature in guarding against injection attacks
01:56pppaulbut i love injection attacks
01:56dnolenLauJensen: nice. As an aside I love how little code it ended up being. 700 LOC, less than Enlive ;)
01:56LauJensendnolen: I was quite blown away by it myself. The old ClojureQL was thousands and thousands of lines in 10 different files. Arel is 4600+ lines in 30 something files. Also doing this in about 2 weeks was quite an experience
01:56LauJensenShred + Rewrite FTW :)
01:59dnolenLauJensen: I have strong disgust for SQL syntax, not the tech. Like Clojure, ClojureQL puts a better interface on great technology.
01:59LauJensendnolen: True. And I think Relational Algebra has always been the right way to do it. I dont know who dreamed up SQL92 instead :)
02:03LauJensenBut its great to see how much elegance you get for free from Clojure, if you comepare Arels syntax to sexps there's quite a difference
02:06dnolenLauJensen: so is the idea to have ClojureQL be very focused on querying? leave transactions to clojure.contrib.sql and modeling to libraries like carte ?
02:07LauJensendnolen: I would say that querying is such a huge part of our interactions with databases that it was just the natural place to start, however I will definitely introduce a (dosync) like semantic into it. Right now it automatically promotes inserts/updates to transactions when there are multiple rows involved
03:00harishtellaanyway to import everything from a java package (like processing.core.*) ?
03:00LauJensennope
03:01harishtellaaww, why not?
03:05_atopossibly because it's not possible to get a list of all classes in a package, due to custom class loaders
03:06_atomy guess would be that javac's import foo.* doesn't actually search out all classes in the foo package, it instead just sets a search path for unqualified class names
03:07_atoClojure's namespaces work differently to Java's, when you import something in Clojure it actually creates an entry in the namespaces
03:07harishtellaah, I see, thanks
03:41cphang_ /join #clojure
03:41auscompgeekcphang_: You are already here.
03:41cphang_yap :)
03:41cphang_didn't realized it
09:04fliebelmorning
09:04tonylmorning
09:08fliebelThere is a neat Twitter lib in Python that generates urls from method calls dynamically so that it requires little maintenance and supports all Twitter methods. How would I do such magic in Clojure? I'm talking about the second point: http://mike.verdone.ca/twitter/#why
09:12fliebelI could do a macro that just converts function calls to strings, but I'm not sure that's the cleanest way to do it.
09:12ChousukeI don't think you can do that directly, since clojure doesn't have methods that you can create on the fly :P
09:13Chousukebut you could always have some function that takes a bunch of keywords and returns a function that fetches the url
09:13Chousukeor a macro
09:14fliebellike (twitter :statuses :user-timeline)?
09:14Chousukefliebel: something like that
09:15Tordmor"you won't have to update your version of the API (though you may have to update your code" WTF?
09:15Chousukeor if you want to be fancy, (twitter :statuses.user-timeline)
09:15TordmorAs if that were something good.
09:16fliebelTordmor: Kind of. Twitter wont just remove an url, but they might add one.
09:49pivahey there!
09:51pivacould someone please clarify a newbie mind towards this problem: I need to count words found in a given string, I thought that I could do that by splitting the string by whitespace and iterating over the resulting vector, create a map with the word as key and increase the value... I researched it vastly for over 4 hours yesterday and as a good newbie I stil don't have a clue to how to do it properly ://
09:53chouserpiva: consider 'reduce'
09:53tonylor split and count
09:54cemerickchouser: I see shades of Rich in you as time goes on ;-)
09:54pivachouser: I started to consider it only today, haha
09:54tonyl(count (clojure.string/split "my string of words" #"[:whitespace:]"))
09:54Raynescemerick: He *is* rich. Just wearing a mask.
09:55pivatonyl: ah, I need to count every different word that appears
09:55Raynescemerick: When they have to appear in public together, Rich get's Tom to wear the mask.
09:55tonyloh so unique words?
09:55pivatonyl: that's why I thought in creating a map where each unique word is the key and increase the counting for each occurrence
09:55Chousukepiva: when you "increase the value" you actually need to create a whole new map :)
09:55Raynesforces*
09:55tonylok
09:55tonylyeah
09:56pivaChousuke: yeah, that's what is forcing my mind, ahha, coming from non-functional programming is a big step to think in immutability and etc
09:57Raynescemerick: Did you see my indirect getting started post? I only mentioned maven in passing so as to make the hair on the back of your neck stand on end.
09:57pivaI really started to play a little with functional about 3 days ago, before that I'd only heard about... so it's been a challenge
10:00tonylpiva: I am starting too
10:00tonylyou are going to need reducing
10:00pivauhmm, great, I will get to study it so, thanks again :D
10:01cemerickRaynes: I looked at it briefly :-)
10:02cemerickDespite popular opinion, I actually don't care about maven one way or the other. It's just the only thing that does all of what I need.
10:02cemerickpiva: would you like a working solution, or are you content to pick at the problem?
10:03pivacemerick: I think that would be better as a learning experience to pick at the problem, my real problem is to redefine my way of thinking
10:04pivacemerick: as such, looking at reduce I see a light, but it still I think about mapping and increasing values and etc :/
10:04cemerickyeah, you still need to keep counts
10:04tonylpiva think of associating the values to the map
10:04cemerickthat doesn't impact the utility of reduce, etc
10:04Raynescemerick: I just like toying with you. <3
10:06cemerickpiva: In any case, don't kill yourself trying to derive idioms on your own. :-)
10:06pivatonyl: I'm at that, but I'm thinking something like this: "ok, I've got to count every word occurrence and when each one is done then I associate it to the map" but that would need many lookups over the vector
10:06cemerickA naive impl is here for when you want to peek. https://gist.github.com/706621
10:06cemerickRaynes: It's appreciated. :-)
10:07cemerickit's just such a boring topic to me at this point (build-y things, that is)
10:07pivacemerick: thank you! I will pick at it some more and (as nothing is really gonna roll, lol) I'll look it
10:07RaynesUnderstandable. I have some vested interests in cake and the like though. I occasionally contribute things and write plugins.
10:09cemerickSure. We all have our investments.
10:09tonylpiva: yeah you have to instert into map and update every time in the function that map is using
10:09RaynesPlus, ninjudd is just so darn awesome in person. <3
10:09tonylit is hard to come around, at least was for me. and it still is sometimes
10:11stuartsierra,(frequencies (seq (.split "The quick brown fox jumped over the lazy dog." " ")))
10:11clojurebot{"jumped" 1, "quick" 1, "fox" 1, "The" 1, "the" 1, "dog." 1, "over" 1, "lazy" 1, "brown" 1}
10:12cemerickdammit, frequencies!
10:12cemerick:-P
10:12pivalol!
10:12tonyl*facepalm* I need to learn my functions
10:13cemericktonyl: don't we all
10:13cemerickThere goes stuartsierra, makin' me look like a dope again ;-)
10:13stuartsierraIt's nice no feel needed. :)
10:13stuartsierra*to
10:14tonylwell, it was an exercise of the mind :P
10:14pivahaha, thank you all very much, now I can see some light in how functional can be great :DD
10:14pivaand well, I'll try to continue my lil program, haha
10:14tonyl$source frequencies
10:14sexpbotfrequencies is http://is.gd/hqiDv
10:18fliebelsexpbot at least gets the https thing right, line number are gone from core docs :(
10:20fliebelcemerick: Your implementation could use fnil ;) Man, I read the whole core doc yesterday :)
10:21cemerickfliebel: heh -- see, I'm stuck with a 1.1 mindset still. fnil has always only ever been in contrib.core…
10:22fliebelcemerick: me, to. I'd still be using defstruct if it wasn't for chouser ;)
10:22Raynesfliebel: sexpbot is always right.
11:23mjg123Hi - how do I prevent this kind of thing: java.lang.IllegalArgumentException: Value out of range for int: 10315434503
11:24tonyltry bigInt
11:24tonylmaybe
11:24raekmjg123: which version of clojure?
11:24mjg1231.2.0
11:24mjg123I found it though, my mistake
11:24raekhow do you construct it?
11:24tonylwhat was it?
11:25mjg123I was calling (int x) with x as a very large number
11:25mjg123changed it to (num x)
11:25raekif you parse a number from a string, you might want to use long in this case
11:25raekah
11:26jkndrknhey folks. i've defined a protocol using defprotocol and two types that use that protocol in the namespace foo.bar
11:26jkndrknhow do i then use those types elsewhere?
11:26chouserdeftype produces a class, so to use it directly you need to 'import' it
11:26jkndrkni've tried using (:use [foo.bar]), (:import [foo.bar type1 type2]), and neither work
11:27raekjkndrkn: very often, you make a constructor function to create instances
11:27raekyou should be able to import them, though
11:27jkndrknyes, i do have a constructor function. however, said function is not located in the namespace foo.bar and needs to be able to make use of it.
11:27jkndrknhm.
11:28raekby constructor function, I meant something like (defn make-foo [x] (Foo. x))
11:28chouseryou probably need to require and then import
11:28jkndrknok, i'll try requiring too.
11:29raekif you expose the type directly, you will have to change all callers if you add a field
11:29raekor rearrange them
11:30raekI think types and records are often regarded as low-level and are kept as an implementation detail
11:30samxis there some simple way through the Java API to determine is a specific Var has been defined ? I'm currently using the following, but just thinking there might be a simple way: return clojure.lang.Compiler.eval(RT.readString("(true? (some (fn [x] (= (key x) '" + varName + ")) (ns-publics '" + namespace + ")))"));
11:31jkndrkni've tried requiring as well, and that does not work either
11:32jkndrknis this import form correct? (:import [foo.bar Type1 Type2])
11:32cemericksamx: look at Var.find(Symbol).
11:32tonyljkndrkn: i think you need to actually use the import form instead of the ns form
11:32jkndrkni'm getting "error: java.lang.ClassNotFoundException: foo.bar.Type"
11:33jkndrknah, i siee
11:33samxcemerick, thx
11:33tonyli've had problems like that and using import worked for me before
11:34raekjkndrkn: the docs says you should write (:import (foo.bar Type1 Type2)), but sometimes vecors instead of lists happens to work
11:35raekwell, lists for prefix lists is the only documented way...
11:35raekhrm, ok. looks like vectors worked in that case.
11:37cemerickwas there a create-temp-directory fn floating around somewhere?
11:39jkndrknok, so i added an "(import [foo.bar.Type1])" under my ns form
11:40tonylcemerick: not as far as I know, maybe sh (shell fn)
11:40tonyljkndrdkn: did that work for you?
11:40jkndrknnow i'm getting java.lang.IllegalArgumentException: Unable to resolve classname: Type1
11:40jkndrknboth the ns form and the import form compile fine
11:41jkndrknthe form that actually creates an instance of the type fails
11:41mjg123cemerick: you can use java.io.File#createTempFile() then delete the file & create a dir with the same name
11:41cemerickyeah
11:42tonylonce you imported can you create a Type1 object
11:42cemerickI wonder how many times I've written that in my life
11:42jkndrkntony1: nope
11:42tonylthen it is the importing
11:43tonylthat is weird, let me test it
11:43jkndrkni'm using (:require foo.bar) in my ns form, and (import [foo.bar.Type1]) and then trying to compile a defn that creates an instance of Type1 using (Type1.)
11:44jkndrknthe import form is free-standing and outside of the ns form
11:45tonylok, i'll test for both
11:50KirinDavejkndrkn: So you made a deftype in another file an you're trying to use it in this file?
11:51mjg123cemerick: (str (System/getProperty "java.io.tmpdir") (System/getProperty "file.separator") (.toString (java.util.UUID/randomUUID)))
11:53cemerickmjg123: heh, sure. I can never remember which one is which between file and path.separator. :-P
11:53mjg123No, I had to look it up, too. If that clashes with something you ought to buy some lottery tickets.
11:53jkndrknKirinDave: that's right
11:54KirinDavejkndrkn: So one of two things needs to happen
11:55KirinDavejkndrkn: You either need to explicitly make sure the file saying deftype is loaded into the vm. (Alternatively, you need to :use or :require a symbol from the namespace that includes the deftype)
11:55cemerickmjg123: Yeah, I'd never dispute UUID. (doto (File/createTempFile …) .delete .mkdir) is a little more readable though :-)
11:55KirinDavejkndrkn: Or, you need to lein compile and make sure :aot includes that namespace
11:55jkndrknk, i'll try that
11:55KirinDavejkndrkn: When you go for the final jar, it won't matter.
11:56KirinDaveBut during dev, I usual use slime and C-c C-l to load the module again.
11:56tonylso for importing types they have to be compiled?
11:58KirinDavetonyl: for using import, I think they either have to be loaded or compiled. Things like gen-interface and deftype will doing the loading at the time of their evaluation
11:58KirinDavetonyl: But you have to make that evaluation happen
12:00tonylok
12:00cemerickKirinDave: I've suggested doing an implicit require on import before, but that's not gone very far.
12:00tonylthat is good to know
12:00KirinDavecemerick: I think the safest way is to compile. it's what I have to do for scala interop.
12:00KirinDaveIt's onerous, but...
12:01KirinDavecemerick: One of the nice parts of having a make-* function is that you can :use :only [make-*] and be pretty sure your class gets loaded.
12:01cemerickAgreed.
12:01cemerickRe AOT compilation, there are maintenance downsides, e.g. binary compatibility between different revs of clojure.
12:02tonylso if you do a make-mytype fn for the type in the same ns the type was declared then you can just require that make-mytype fn and use it to make the type?
12:03KirinDavetonyl: That's how it's explained to me.
12:03tonylok, if I don't want to go the compilation route, i'll try this.
12:06tufflaxI'm trying out Vim for clojure, but one feature I miss from Emacs is the indentation; that I can just select a whole function and press tab and every row gets indented correctly, and that if I'm on a row and press tab that row get indented correctly even if that means moving backwards. Does anyone know if I can get something similar to work with Vim?
12:06dakronetufflax: use = when selecting a visual block, or == to indent the current line
12:07dakronegg=G to indent the entire file
12:07tufflaxOk, thanks I'll try
12:10tufflaxHm, I'm very new to vim, when you say "use =", what do you mean? Cause when I select the text and type = in normal mode I just replace the text :P
12:11tufflaxOr, I was in select mode
12:11dakroneare you using v or V to select things in visual mode?
12:12tufflaxvisual mode? :P I'm in select mode :P maybe I should study vim some more first :P
12:13dakroneso, from normal mode, hit V to enter visual line mode, move up and down to select some lines, then press = to indent them
12:13tonyltufflax: have you try the vimtutor?
12:13tufflaxI did some of it :P gonna continue soon :P
12:14tufflaxBut I was very eager to see what vimclojure had to offer
12:15tufflaxAh, now it works, very nice. Thanks!
12:32amalloyanyone know of a good intro to fnparse?
12:37aoeu256i saw a youtube video and clojure looks like a fun language (i program a little python). Im starting out, whats a good way to figure out which methods belong to a (Java) object. right now I am using clojure's lispbox
12:38amalloyaoeu256: there are a few ways. are you familiar with java, or is clojure your first java?
12:38tonylaoeu256: you can use the class function
12:41amalloyaoeu256: https://gist.github.com/b12371be35213c7ff4a9
12:42amalloytonyl: this seems more friendly than (.getMethods (class x))
12:43mroesslerif we partition on a pattern and emit like : (let [pairs (partition 2 1 tuples)] (for [[today todays_value] [yesterday yesterdays_value]] pairs] [today (- todays_value yesterdays_value)])) we necessarily have dropped the first tuple [today todays_value]. Is there a common method to add it back in? Like [today nil]?
12:43tonylyeah true, i assumed he new java
12:44aoeu256i know a little java
12:44amalloythere's a (show) function somewhere that's supposed to do this in the repl, but since 1.2 i haven't been able to find it
12:44tonylamalloy's would be more helpful though, class you just give you the full class name only
12:45chouserclojure.contrib.repl/show
12:45chouserclojure.contrib.repl-utils/show
12:45chouserI think
12:45chouserit will be replaced by something better in 1.3
12:45amalloychouser: damn you. i looked in repl-utils, and it wasn't there until you told me to look again
12:46tonylmroessler: what do you mean dropped the first tupple (vector) isn't [today todays_value] still there?
12:47tonylc.c bows to chouser
12:47chouseramalloy: heisenfunction
12:48mroesslertonyl: Thanks. I don't think it is, because my for is [today todays_value] [yesterday yesterdays_value], so the output is only emitted once there is a yesterday.
12:50amalloymroessler: is that real code you pasted? i don't think that's a legal binding-form you used in your for
12:51amalloy&(for [[[a a1] [b b1]] (partition 2 1 [1 2 3 4])] [(- a b) (-a1 b1)])
12:51sexpbotjava.lang.Exception: Unable to resolve symbol: -a1 in this context
12:51tonylyou are missing a bracket
12:51amalloy&(for [[[a a1] [b b1]] (partition 2 1 [1 2 3 4])] [(- a b) (- a1 b1)])
12:51sexpbotjava.lang.UnsupportedOperationException: nth not supported on this type: Integer
12:51amalloymutter
12:52tonyl&(for [[[a a1] [b b1]] (partition 2 1 [[1 2] [3 4]])] [(- a b) (- a1 b1)])
12:52sexpbot⟹ ([-2 -2])
12:52amalloythanks tonyl
12:52tonylnp
12:52tonylhe was missing a third bracket
12:53mroessleramalloy: well surely I'm inhibited by this being my third day with Clojure, but yes that code is running for me. This is a common issue when dealing with things such as moving averages. If we compute a 30 period moving average, the first 29 are nil, but we don't really want to drop them from the data.
12:53tonylfor never drops data as far as i know
12:54mroessleramalloy: the code I pasted is inside a let
12:54amalloymroessler: you're missing a [ in your for
12:54amalloybut whatever
12:54amalloytonyl: right, it never drops data, but if you have 30 data points there are only 29 pairs
12:55amalloyi'm not really clear on what mroessler wants to do to invent the first pair
12:55tonyloh i see
12:55amalloymroessler: it seems to me that your issue is with partition, not for
12:55mroesslerI want [today nil]
12:56amalloy&(partition 1 2 [[1 2] [3 4] [5 6]])
12:56sexpbot⟹ (([1 2]) ([5 6]))
12:56amalloyer
12:56amalloy&(partition 2 1 [[1 2] [3 4] [5 6]])
12:56sexpbot⟹ (([1 2] [3 4]) ([3 4] [5 6]))
12:57amalloy&(partition 2 1 (repeat [nil nil]) [[1 2] [3 4] [5 6]])
12:57sexpbot⟹ (([1 2] [3 4]) ([3 4] [5 6]) ([5 6] [nil nil]))
12:57amalloymroessler: ^^?
12:58mroesslerLikely I'm insufficiently clear: I'm emitting a date: today, matched by (- todays_value yesterday's value). Clearly I can't emit (- today_value yesterdays_value) until there is a yesterday, which drop the first [today todays_value].
13:01amalloymroessler: what about computing the diff with tomorrow instead of with yesterday?
13:01amalloythen you can use the little padding scheme i show above
13:04mroessleramalloy: I'll look into that, thanks.
13:14orpheHi, i'm beginning with clojure and trying to find the best way to set it up. Should i get the downloads the site or take the source from github
13:14technomancy~getting started
13:14clojurebotgetting started is http://www.assembla.com/wiki/show/clojure/Getting_Started
13:15amalloyorphe: Raynes made a blog post about this just yesterday: http://blog.raynes.me/?p=48
13:15orphetechnomancy, amalloy : thanks
13:19dnolenso what are people using for string templating again?
13:26orpheamalloy: wow that cljr installer does everything
13:27amalloyorphe: heh. i haven't used cljr myself, but i imagine it's using maven to download the required packages, just like cake or lein
13:27hugoddnolen: recently came across this http://alliance.seas.upenn.edu/~harmony/ which looks like it could be turned into an enlive type approach for general text
13:28hugodprobably overkill as string templating though
13:28orpheamalloy: yeah its using maven, i had tough already compiled clojure ,and was wondering how to set it up correctly , but if that does everything ... its looks like gems for ruby or npm for node
13:29dnolenhugod: interesting, saved for later reading :)
13:30amalloyorphe: yeah, i compiled clojure myself too, the first time. it turns out to not really be worth the bother, especially as all the tools fetch their own copy of clojure anyway (you can point them at your local copy if you want, i guess)
13:30jjidofreemarker is good for templating on the jvm
13:31dnolenjjido: I really want something idiomatic
13:32dnolen((tmpl "Foo ~{keya} bar ~[keyb}') {:keya "blah" :keyb "argh"})
13:32orphednolen: i used in js and ruby http://mustache.github.com/ , maybe the clojure port is good too
13:33dnolenorphe: ah seems close to what I want, will check it out.
13:34orphednolen: don't know how it works in clojure since im starting but in js/ruby you can pass lambda functions , direct values...
13:37hugoddnolen: https://github.com/hugoduncan/pallet/blob/master/src/pallet/strint.clj does this based on c.c.strint
13:38tomojhmm
13:38dnolenhugod: tried it, seems I cannot use strings in first class manner w/ it (please correct me if I'm wrong)
13:38fliebelhugod: That boomerang thing is very interesting! Would be awesome the have a Clojure DSL to do that kind of stuff.
13:38dnolen(let [s some-str m some-map] (<< s m)) ; FAIL
13:40hugodfliebel: I have a good use case for it in pallet, but no time to implement at the moment :(
13:41fliebelSo many cool stuff to build… :(
13:41amalloy$sed -fliebel s/\(/)
13:41sexpbot<fliebel> So many cool stuff to build… :)
13:42amalloyno being sad about having cool stuff
13:42fliebelOkay, "So much cool stuff to build… :) but only one lifetime :("
13:43amalloyfliebel: that's better
13:50amalloyre-ping: anyone know of a decent intro to fnparse?
14:08dnolenamalloy: you might have to write one, eh ? ;)
14:08amalloydnolen: oh noes
14:09edwHey guys, I was wondering how one should approach transforming a hash like this {0 :a 2 :b 3 :c 8 :d} into an array like this [:a 0 :b :c 0 0 0 0 :d 0 0].
14:09dnolen,(flatten {0 :a 2 :b 3 :c 8 :d})
14:09clojurebot()
14:09mrBliss,(apply concat {0 :a 2 :b 3 :c 8 :d})
14:09clojurebot(0 :a 2 :b 3 :c 8 :d)
14:10dnolen,(into [] (apply concat {0 :a 2 :b 3 :c 8 :d}))
14:10clojurebot[0 :a 2 :b 3 :c 8 :d]
14:10amalloyedw: what do you mean with all your zeros? you don't seem to want just flip_map
14:11amalloydnolen: (into [] foo)? i would think (vec foo) makes more sense
14:11chouser& (reduce (fn [v [x y]] (assoc v x y)) (vec (repeat 10 0)) {0 :a 2 :b 3 :c 8 :d})
14:11sexpbot⟹ [:a 0 :b :c 0 0 0 0 :d 0]
14:11edwMy Q was about a 1-dimensional output structure, but I want to convert a list of triples into a matrix, with the un-specified elements set to a default value.
14:12edwI'm using Incanter.
14:12chouseredw: I think mine solves it for you
14:12chouseredw: though you left out the "length of the vector" parameter. I used 10
14:12chouserBut I don't know anything about Incanter. Maybe it has a better way.
14:12edwchouser: 1) Thanks, 2) you are correct, and 3) thanks again.
14:13chouseryw
14:13amalloychouser: wut. i don't even understand the problem, how can you have solved it already
14:13mjg123wtf?
14:13chouseramalloy: the map keys were to be used as indexes into the output vector
14:13edwI've looked around Incanter's docs, and I don't think there is.
14:13amalloyoh i see
14:13chouserthe map values are the vector values at those indexes
14:14chouserheh, not sure that helps
14:14amalloyyeah, actually it totally explains it. wild
14:14tonyloh i see
14:14KirinDaveSometimes clojure is so ugly it pisses me off
14:14KirinDaveStill love it but... an unruly child
14:14amalloyKirinDave: you can't blame evolution just because you made an ugly baby
14:15KirinDaveamalloy: Oh I _can_.
14:15KirinDaveI am just unreasonable enough to.
14:15tonyllol yeah
14:15chouserKirinDave: which bit is ugly today?
14:15fliebelKirinDave: That's explicit complexity, rather than accidental ;)
14:15KirinDavechouser: All this fucking date handling I am doing.
14:15chouseroh
14:15chouseryeah
14:15KirinDavechouser: e.g., https://gist.github.com/706981
14:16chouserdates are deeply unhappy to work with
14:16edwThanks everyone. The only place forgoing mutation in moving from Scheme to Clojure is in this sort of data structure initializion code.
14:16amalloyKirinDave: fun fact: java's DateFormat objects aren't threadsafe either
14:16KirinDaveamalloy: I'm using joda
14:16amalloyare those threadsafe?
14:16KirinDaveamalloy: Well, the immutable ones are.
14:16KirinDaveTHey have immutable versions of all their time stuff.
14:17amalloyKirinDave: sure? i never mutate my DateFormats and i still ran into problems because the parse() methods aren't threadsafe
14:17KirinDaveamalloy: Please tell me that's not true
14:17amalloyKirinDave: scout's honor. took me a day and a half to discover
14:17KirinDaveIf JodaTime's parse isn't thread safe I'm going to sprout horns and a tail
14:17amalloyeven though it's right in the javadoc
14:18KirinDaveamalloy: "DateTimeFormat is thread-safe and immutable, and the formatters it returns are as well."
14:18KirinDaveWhew
14:18KirinDavehttp://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html
14:18amalloyhurrah
14:18KirinDaveYeah
14:18dnolenKirinDave: can date handling be made pretty? That code is at least clear.
14:19fliebelCan anyone name me a core function I might not know about?
14:19amalloyfliebel: fnil
14:19amalloyincidentally, writing memoize in java looks disgusting
14:20amalloyeven with apache commons to help out
14:20fliebelamalloy: Know that one, replaces nil with a given value for fn.
14:20chouserfliebel: var-set
14:20fliebelchouser: Now you got me :(
14:20chouserfliebel: underive,
14:20fliebel&(doc var-set)
14:20sexpbot⟹ "([x val]); Sets the value in the var object to val. The var must be thread-locally bound."
14:20amalloyfliebel: reductions. group-by
14:20chouserupdate-proxy
14:21fliebelchouser: I know that one, but the derive tree stuff is still magic to me.
14:21chouserprobably know trampoline. If not, worth looking at.
14:21fliebelyea
14:21KirinDaveWoah didn't know fnil
14:22fliebelupdate-proxy is some sort of java interop helper, right?
14:22chouserfliebel: allows you to change on the fly the implementation of an object created via proxy
14:22chouserso, yes
14:23chouserrestart-agent is newish
14:23chouserooh, rsubseq
14:23fliebelOh, I am so going to make myself a Clojure quiz...
14:23chouserseque
14:23tonyli would take that quiz! good learning tool i quess
14:23tonyl*quess
14:23amalloyKirinDave: fnil works together especially well with update-in
14:23chouserrelease-pending-sends
14:23fliebelI know all of those, though I can;t remember what rsubseq is for.
14:24fliebelis there deseque as well? I guess not :(
14:24mjg123&(doc rsubseq)
14:24sexpbot⟹ "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a reverse seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"
14:24KirinDaveamalloy: Can I see an example?
14:24chouserpvalues
14:24amalloy&(update-in {} [:a :b] (fnil inc 0))
14:24sexpbot⟹ {:a {:b 1}}
14:24fogus`Are we playing the "name the obscure Clojure function game"?
14:24chouserfogus`: yup!
14:24amalloy&(update-in {:a {:b 2}} [:a :b] (fnil inc 0))
14:24sexpbot⟹ {:a {:b 3}}
14:24KirinDaveamalloy: Damn that's fantastic
14:25KirinDaveamalloy: I can change code _right now_ :)
14:25fliebelpvalues gets you a vector of values computed in paralel.
14:25amalloyKirinDave: i forget if i got that trick from chouser or raek, but it's magic
14:25KirinDaveYeah that's quality.
14:25KirinDaveActually fnil seems like a pretty nice tool in general
14:26chouser,(rationalize 4.234)
14:26clojurebot2117/500
14:26fliebelchouser: Now in reverse, what's the name of the function that behaves like seq but gives an empy seq instead of nil?
14:27chouserfliebel: sequence
14:27fogus`,(syntax-symbol-anchor '&)
14:27clojurebotfn
14:27fliebelwhoo
14:27amalloyfliebel: not-empty
14:27ossareh"Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: "Unparsable namespace form:" :reload" <- I get that when I run lazytest in watch mode on a brand new project - any thoughts on why this might be? (perhaps because I have 0 tests?)
14:27chouserfogus`: I have a patch in to make that go away
14:27ossarehclj 1.2 fwiw
14:27fliebelI'm leaving now, I'll show you guys the quiz later :)
14:27amalloy&(map not-empty [{} [:a]])
14:27sexpbot⟹ (nil [:a])
14:29Raynesorphe: Was my post helpful? Just curious, as AFAIK, you're the first actual new person who might have read it. :>
14:30fogus`,(namespace-munge 'foo.bar-baz)
14:30clojurebot"foo.bar_baz"
14:30orpheRaynes: lol, Yeah pretty helpful , tough i just used the cljr part! Would be nice to have a followup to what cljr does... (clojars and things like that)
14:31Raynesorphe: Yeah, that post wasn't meant to go into serious depth on any of them. A series of introductions to the various tools might be a nice series of articles to write sometime.
14:32ossarehRaynes: and critically required for the community to grow ihmo
14:32ossareh*imho
14:32amalloyossareh: I Hate My Opinions
14:32ossareh;)
14:33Raynes(;
14:34orpheRaynes: I'm gettin myself a blog in a week or two , just finishing writing the engine , maybe if i like really much clojure i will write about it
14:34RaynesYou're writing your own blogging engine?
14:35orpheRaynes: yeah , static site generator , like Jekyll
14:35RaynesNeat.
14:36orphei'm trying to write usefull things, tired of only doing school labs and doing nothing with it
14:36orphesolution : write open-source
14:37ossarehorphe: or better still, once again imho, help other projects
14:37ossarehdamn.. I'm just all opinionated today
14:37orpheossareh: yeah, that was included in "write open-source"
14:38rata_hi
14:38rata_what's the most convenient (and hopefully fastest) way to get something like rand-nth in a set?
14:40mjg123Raynes: good blog post, I'm pretty new so it's good to read about the various tools & such as well as the language
14:41tonylrata_: with rand-int maybe
14:41RaynesThanks! Glad you enjoyed it.
14:41amalloyrata_: (comp rand-nth seq) is the best i can think of
14:42rata_tonyl: but sets doesn't support nth
14:42rata_amalloy: does seq copy the set?
14:42tonylthey support get
14:42amalloyrata_: not exactly. i don't understand seq, but i believe it returns an iterator-type thing that uses the set as its backing collection
14:42tonyl&(get u (rand-int (count (apply sorted-set (range 17))))
14:43sexpbotjava.lang.Exception: EOF while reading
14:43tonyl&(get u (rand-int (count (apply sorted-set (range 17)))))
14:43sexpbotjava.lang.Exception: Unable to resolve symbol: u in this context
14:43tonyl&(get u (rand-int (count (apply sorted-set (range 17)))))
14:43sexpbotjava.lang.Exception: Unable to resolve symbol: u in this context
14:43tonyl&(let [u (apply sorted-set (range 17))] (get u (rand-int (count u))))
14:43sexpbot⟹ 12
14:43tonylthere it is
14:43amalloyrata_: it won't be very fast, because it will be traversing the whole set. but anything else would be biased in some way
14:45rata_amalloy: why would it be traversing the whole set? once you apply seq to a set, isn't it randomly accessible?
14:46amalloyrata_: seq will have to traverse the set once to make that happen
14:46rata_ah ok
14:46amalloyeg, suppose you knew the set were stored as a hash-table. you could use a random number as the hash key, then randomly select from the list of things that hash into that bucket. but some buckets will be larger than others, and some may be empty, so the results you get back won't be uniformly distributed
14:47amalloyso i think the best you can do is convert the set to a seq, and use rand-nth, which will be uniform
14:48rata_in that case, it's better to store the thing as a vector, not a set
14:48amalloy&(counted? (seq (set (range 1000))))
14:48sexpbot⟹ false
14:48rata_sets are implemented in clojure usign hash-tables then?
14:49jarpiain&(class #{1 2 3})
14:49sexpbot⟹ clojure.lang.PersistentHashSet
14:49amalloy&(map (comp class set range) [1 10 1000])
14:49sexpbot⟹ (clojure.lang.PersistentHashSet clojure.lang.PersistentHashSet clojure.lang.PersistentHashSet)
14:49technomancyyeah, sets are maps where the keys point to themselves.
14:50amalloyi thought the small one would be an array-set. or does that only exist for maps?
14:50amalloyrata_: yeah, sets and maps are implemented as hash tables (trees, if sorted) in both java.util and clojure.lang
14:51rata_if they'd implemented as trees, I think it would be easy to make an analogous of rand-nth for them
14:51rata_aha... trees if sorted
14:51rata_maybe that's what I need
14:52amalloyrata_: no, rand-nth will be biased for trees too
14:52chouserI suppose counted-sorted-set might do it
14:52amalloyeg, suppose your tree is poorly balanced: one element in the left subtree of the root, and four in the right sub-tree
14:52amalloyif you randomly choose a direction to go from each node, you'll return the left element four times as often as any other
14:53rata_counted-sorted-set? is that in clojure.core?
14:53amalloywhich is why you'll have to seq it first
14:53rata_amalloy: and what about balanced trees?
14:53rata_well, it can't be perfectly balanced all the time
14:54amalloyrata_: well, of course clojure uses self-balancing trees. but they're very rarely 100% perfectly balanced, just balanced "enough"
14:54rata_yes
14:54rata_I just realized that after I asked you
14:54amalloyif you want uniformly random selection you'll have to traverse the whole set to get something you can random-access
14:54amalloyno matter how the underlying set is stored
14:56rata_well... what I really need is a vector, but with less than O(n) for removal of an item
14:56ossarehrata_: more on the data structures: http://clojure.blip.tv/file/707974/
15:00fogus`,(let [p (-> (get-proxy-class Object) (construct-proxy))] (init-proxy p {}) (update-proxy p {"toString" (fn [this] "blah")}) (str p))
15:00clojurebot"blah"
15:00rata_http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html
15:01rata_incredible... vector supports disj and is O(log n)!
15:01rata_I didn't know about that
15:01rata_&(disj [1 2 3] 2)
15:01sexpbotjava.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentSet
15:02rata_mmmm... I think that site is wrong
15:03KirinDaverata_: Um
15:03KirinDaverata_: http://idisk.me.com/dfayram/Public/Pictures/Skitch/Clojure_Performance_Guarantees_-_Stefan_Tilkov_s_Random_Stuff-20101119-120625.jpg
15:03rata_it's also wrong in that lazy-seqs are O(n) for count
15:03KirinDaverata_: I don't see vector having disj
15:03rata_KirinDave: did you see the link I wrote?
15:03KirinDaverata_: I clicked the last link you posted
15:04rata_yes, that link
15:04KirinDaveAnd screenshotted the table contained within
15:04KirinDaveAnd between vector and disj, there is a -
15:04fogus`rata_: the columns are shifted in Chrome
15:04tonyli think the header row in the table is shifted
15:04tonylwhat fogus said
15:04KirinDaveHaha. Womp womp.
15:04KirinDaveChrome: wins again
15:04rata_yes, that was
15:04rata_it
15:05fogus`I mean it's is a very complicated table. so it makes sense that Chrome might choke
15:06KirinDavefogus`: Ha
15:10rata_mmm... so the best way to do it is probably to just (remove ...) from the vector and use (rand-nth ...)
15:11rata_or would it be better to (disj ...) the set and then use (rand-nth (seq ...))?
15:14devinusanybody know of SQL databases writtein in Java?
15:14mister_robotoIf I want to write some clojure to plug into a spring app as an interface impl, do I just use defprotocol to create an interface usable by java?
15:14devinus*slightly off-topic question, but im curious about connecting to clojure*
15:15mister_robotoDevinus, hsqldb
15:16tonylmister_roboto: I would do that and compile the protocol so that java can use it
15:18mister_robotoThanks! I haven't yet played with the deftype family
15:18tonylI am starting too
15:20rickmodeWhat's the best way to test if a map is empty? (empty? m) vs (= 0 (count m)) vs (zero? (count m))
15:20tonylI would go for (zero? (count m))
15:20rickmodeI don't trust timing in the REPL, but empty? appears to be faster
15:21rickmodetonyl: thanks
15:21tonylI don't know what would be faster, though
15:25rickmodetonyl: the docs doesn't give speed guarantees for seq on a map, though I suspect it isn't O(1). Seems like empty? should be implemented by map directly, which would be O(1). count is supposed be O(1), so I guess (zero? (count m)) will be good.
15:25chouserseq, count, and empty? are all O(1) on a clojure map.
15:26chouser(if (seq m) ...) is most idiomatic, or if you need the inverse (if (empty? m) ...)
15:27rickmodechouser: i this case I wouldn't use the result of seq, however I am testing in an if and using the else clause
15:27mjg123for speed of comprehension, (empty? m) has it, imho
15:27rickmode(empty? m) would be the clearest ... I agree with mjg123
15:28chouseryes, it is normal, even preferred, to use 'seq' to test that there is something in the collection.
15:28chouserempty? is fine, but please avoid (if (not (empty? m)) ...)
15:29rickmodein this case it's something like (if (empty? error-map) (do-success) (do-failure error-map))
15:29chousersounds good to me
15:30mjg123because (empty? m) just calls (not (seq m)) , so you don't want to waste time with (not(not(seq m))) - is that why, or is there another reason?
15:31chousermjg123: HotSpot will likely make all that 'not'ing free anyway. It's more about clarity.
15:31mister_robotoNegative logic is harder to read too
15:31chouserright, why use "if not empty" when you can use "if something's here"
15:32chouserthe way to say "if something's here" in Clojure is (if (seq m) ...)
15:32rickmodeindeed: (if (not (empty? error-map)) (do-failure error-map) (do-success)) %(
15:32mister_robotoEven rickmode's formulation is irritating to me . Why not just do the failure if something in the map?
15:32mister_robotoRather than do success if failure map is empty
15:33mjg123as a beginner, I'd go to the doc to check what (if (seq m)) is trying to say. (if (not (empty? m))) is self-evident.
15:33chouseryou still need both cases, and there are valid stylistic reasons for doing the success branch first.
15:33rickmodeTo my eye, this obfuscates the meaning a bit. But at this become a minor style issue. (if (seq error-map) (do-failure error-map) (do-success))
15:33chousermjg123: the standard response to that is, do you want all your code written for beginners in the language?
15:34mjg123chouser: no :)
15:34mjg123but I can totally see why someone might write it like that.
15:34chousersure
15:34mister_robotoIt doesn't obfuscate anything if u understand what seq does
15:34chouseruntil you talk him out of it
15:35rickmodeWhereas this is more clearly good style: (when (seq error-map) (do-failure error-map))
15:35Chousukethe seq idiom will be confusing the first time you see it
15:35Chousukethen you learn it and it becomes non-confusing :P
15:36dnolenmjg123: heh wait till you learn about contains?
15:36rickmodeChousuke / chouser: it does give me the ick creating a seq on a map then tossing away the result, even if it's O(1). But I'll get over it.
15:36mister_robotoU could just throw an exception ;) (kidding!)
15:36dnolenit actually drives me insane now that other langs don't have it.
15:39chouserrickmode: don't worry about it. if it actually becomes the performance bottleneck in your app, bring it up with rhickey and he may just solve it for you
15:39ossarehif (:use some-ns) from some-other-ns are defrecords in some-ns visible ? it seems like they're not, but I didn't see anything in the docs that says that is the case.
15:39amalloyossareh: no
15:39chouseryou have to keep in mind the difference between the current implementation of Clojure, and the fullness of the language that is promised.
15:39amalloythey're classes: you have to (:import) them
15:39ossarehahh
15:40ossarehamalloy: thx
15:40chouser'seq' is the primitive for testing if a collection has contents. Use it. :-)
15:41ossarehamalloy: and I assume that they are some-ns.RecordName ?
15:41amalloyossareh: indeed
15:42amalloy(ns myproj.stuff) (defrecord Things [data])...(import myproj.stuff.Things)
15:42fogus`Does anyone see a reason why this patch would be problematic? https://gist.github.com/707137
15:43rickmodeI'm getting used the idea that seq means "give me a sequence on this collection if possible". It feels unlikely that (seq [1]) yields (1) (a chunked seq on the vector) and yet that's O(1). I guess the point is that this chunked seq is trivial to create.
15:43tonylreturning the proxy
15:44chouserfogus`: do they currently return nil?
15:44fogus`tnoyl: ?
15:44fogus`chouser: yes
15:44amalloyrickmode: the chunked seq doesn't traverse the whole vector all at once
15:44tonylI don't see a problem, but then again, I don't know what that method from proxy returns
15:44chouserfogus`: looks good to me
15:44Chousukerickmode: the sequences are also lazy
15:44Chousukerickmode: so they're pretty easy to create in constant time .P
15:44ossarehamalloy: cheers, worked a charm.
15:45rickmodeChousake / amalloy: and thus having a dedicated empty? implementation would be minor optimization at best
15:46ossarehwow, lazytest's watching is very very nice
15:47chousercan I point a pom.xml at a lein-generated jar in clojars?
15:47stuartsierrachouser: sure
15:48stuartsierraadd clojars.org/repo as a repository
15:48chouserI want [congomongo "0.1.3-SNAPSHOT"] ...what's the groupId?
15:49stuartsierragroupId and artifactId are the same when lein has a symbol with no / in it
15:49chouserok, thanks.
15:49stuartsierranp
15:50chouserworks. it's like magic.
15:50stuartsierrachouser: XML Magic (™)
15:50chousernobody complains about the ugliness of the toad warts and bat ears required to make fantasy magic
15:50stuartsierraIt's Mavelicious
15:50chouserso who am I to complain about XML?
16:00fogus`,(doc get-proxy-class)
16:00clojurebot"([& bases]); Takes an optional single class followed by zero or more interfaces. If not supplied class defaults to Object. Creates an returns an instance of a proxy class derived from the supplied c...
16:00fogus`Lies! :p
16:00fogus`,(get-proxy-class)
16:00clojurebotjava.lang.NullPointerException
16:02tonylanother fn that is not returning the proxy it creates?
16:03tonyllooking at the source code I am guessing it returns a boolean
16:04chouserI think it returns the class ok, but the docstring is wrong about the args
16:04chouser,(get-proxy-class java.util.Map)
16:04clojurebotsandbox.proxy$java.lang.Object$Map$ad8bc39c
16:05fogus`chouser: So the behavior is right, but not the doc?
16:06dnolenfogus: have you used your unifier much in macros? curious where you're putting it to work.
16:07fogus`dnolen: sorry, I need to run. drop me an email if you please
16:35rata_it seems something like this is what I need: http://sourceforge.net/projects/avl-array/
16:36rata_I'll need to learn how to write clojure types =)
17:05mjg123Is there a fn which counts the number of operations performed by a function call?
17:05mjg123like (time (...)) but for complexity
17:08tonyluff that is a tough one
17:10mjg123for comparing two different implementations of a function
17:11tonylcomparing results and time performance is not enough
17:11mjg123yes - probably
17:11tonylthis reminds me of php declare construct and ticks
17:11mjg123I'm just curious
17:11mjg123looking at P38 from here http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html
17:12mjg123that "logical inferences" business is a Prolog thing, I suppose
17:12tonylyeah... read about prolog, but never used it
17:13mjg123OK I'll just time it & see what I get
17:13tonylmaybe posting it in the group, more people would help that are more knowladgeable
17:13rata_amalloy: is it possible to know how many elements there are in each bucket?
17:24amalloyrata_: externally? not as far as i know
17:25dnolenhow can I get core.unify? do I need run mvn package from inside a clone of the repo?
17:25rata_there are so many containers out there, how isn't there at least one that is optimized for those three operations (remove by value, insertion and random-access)?
17:25amalloydnolen: cake install?
17:26amalloyif it's a clojure project
17:26tonylrata_: you can make your own if you want
17:27amalloyrata_: because it's not really possible? you can't optimize for everything all at once; each goal has different kinds of bookkeeping to do, and sometimes they conflict
17:28rata_amalloy: I just think I don't know enough about different containers and their trade-offs, not that it isn't possible
17:28dnolenamalloy: will cake use a pom.xml ?
17:28amalloyrata_: could you expand on what you mean by "remove by value, insertion, and random access"?
17:29dnolenamalloy: yeah that doesn't work
17:29dnolenamalloy: mvn package does build the 4k jar that I can copy into my project lib directories tho
17:29amalloydnolen: mvn install
17:30amalloyi think
17:30amalloyputs it in your local repo, and maven/ivy look there before looking externally if you specify it as a dependency in project.clj/pom.xml
17:30rata_amalloy: fast random-access is that it can access an element by index in O(1), remove by value is like (disj set key) and insertion is just that (no constrains for that operation)
17:31rata_I must read more... but I'll do that at another time
17:31dnolenamalloy: yeah that seems to work, thx
17:32amalloyrata_: it can't be done. fast lookup by index, fast lookup by value, and fast insertion at an arbitrary point?
17:32rata_the last one isn't mandatory
17:33amalloyokay. then it's no problem. you can build as many indexes as you want, and update them every time you insert
17:33amalloy(or remove)
17:34rata_I don't get it
17:35amalloyrata_: use an array as the backing store (fast lookup by index). keep a hashmap of {data, index-in-array} pairs. on every insert or delete, modify the backing array and adjust all of the keys in the hashmap
17:36amalloyit makes insertion and deletion O(N), but access very fast, whether by index or by value
17:37rata_good idea =)
17:38amalloyrata_: but don't write it yourself :P. someone's done this already, probably even in clojure
17:39rata_don't worry, it's a good idea but not what I need
17:58pppaulamalloy, got a link for the object you are talking about?
17:58pppauli want my bloated collection object
18:00pppaulsounds like a sorted hash-map
18:00pppaulor double hashmap?
18:02amalloypppaul: no, i've no idea where you can find one
18:03amalloybut eg sql does basically this
18:04pppaulso, make a database
18:04amalloysure. use Lau's clojureql, even
18:04amalloyhe'll love you forever
18:04pppaula simple variation being a set of hashmaps
18:04amalloypppaul: if your needs are modest, clojure.set/index might be good enough
18:05pppaulsets are sorted hashmaps?
18:05pppaulor regular hashmaps?
18:05amalloypppaul: sorted [set/map] is a tree, unsorted [set/map] is a hashmap
18:07pppauli think databases has a lot of overhead
18:07pppaulbut, i could probably do an in-memory DB using clojureQL
18:08pppaulguess it wouldn't be much of a DB
18:08pppaulwill lau still love me forever?
18:12LaPingvinouse SQLite :)
18:12LaPingvinoor fake SQLite ;)
18:14pppauli'm thinking of doing everything with tuples and sets. tutorialD still
18:15pppaulstyle*
18:15pppaulbut, if lau will love me for using clojureQL, then that is a big motivation to use clojureQL
20:01Lajla&(symbol? (first '#(+ % 1)))
20:01sexpbot⟹ true
20:02Lajla&(first '#(+ % 1))
20:02sexpbot⟹ fn*
20:02Lajla&(string (first '#(+ % 1)))
20:02sexpbotjava.lang.Exception: Unable to resolve symbol: string in this context
20:02Lajla&(set 'a-random-symbol)
20:02sexpbotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
22:26cemerickchouser: FYI, I've got a patch in for CLJ-432.
22:45chousercemerick: nice.
22:45cemerickchouser: I hope :-)
22:45rathwellis there an easy way to create a stub java class? looks like there used to be gen-and-load-class, any way to do something like that?
22:47cemerickchouser: I suspect there's still a bug lingering with the generated classname given to reify classes; according to laurent's original writeup, the IBM JDK doesn't allow dashes in package names when loading classes from byte[]s either.
22:47cemerickBut then, I don't have an IBM JDK. :-P
22:47chouserrathwell: gen-class is still there, but you must use AOT compilation.
22:48hiredmanyou can use ASM...
22:48rathwellchouser: no way to do it dynamically though?
22:51hiredmanthere is always a way
22:51cemerickrathwell: is this class going to be used from Java, by name?
22:54rathwellcemerick: yes, it is referenced as a return type in a third party lib i'm using, but that class is no longer there, causing exception. i can just create the class in java and get it on the classpath, but would be easier if i could do it in clojure.
22:54cemerickso you need to match an existing API's package, name, signatures, etc?
22:54rathwellyes
22:56cemerickIf it fits into deftype or defrecord's constraints, then one of it plus a definterface will work.
22:56cemerickOtherwise, gen-class is the most swiss-army-knife-esque thing Clojure has to interop'ing with the java object model, etc.
22:56cemerickone of them*
22:57cemerickhiredman's ASM approach is generally a little to 133t for most. ;-)
22:58rathwellcemerick: I will try defrecord first then, if not, then have to figure out which of gen-class or just doing it in java will work best with deployment, thanks
22:59rathwellyeah, dont think i'm there ;) (ASM)
22:59hiredmancemerick: it's only 133t the first time, the second time you can just copy and paste
23:00cemerickhiredman: True enough. Probably not very kind to the next fellow to look at the code though…
23:01danlarkinnice unicode ellipsis
23:02hiredmanthey sure are
23:02technomancysurely ellipsis isn't plural?
23:02cemerickdanlarkin: no excuse for plebian typography – even in irc ;-)
23:03danlarkintechnomancy: it's not, "ellipses" is the plural
23:03danlarkin<3 em dash
23:03pppaul-
23:03technomancyIIRC em dashes are supposed to be surrounded by narrow spaces; is that right?
23:03pppaul
23:03technomancyI guess monospaced fonts kinda make that a non-starter
23:04cemerickwhat do the linuxes use for inputting extended characters like these?
23:04danlarkinM-x ucs-insert :)
23:04cemerickuh-huh :-O
23:04technomancyback when I was doing a lot of web work I avoided learning about typography because you end up just agonizing over how limited you are, but I guess things are improving
23:05technomancycemerick: the right alt is usually mapped to "compose", which is a bit like option on Macs, I think
23:05cemericktypography geeks are always pissed at the web
23:05cemericktechnomancy: Right -- but is there a defined extended keymap for these things?
23:06cemerick(I assume by "compose", you mean diacriticals: é, û, à, etc)
23:06technomancycemerick: it might be locale-dependent... I mostly stick with Emacs input modes myself
23:06hiredmancompose takes multiple characters and turns it into a single character
23:07technomancyhaving tab completion with M-x ucs-insert really helps for things like KANNADA LETTER TTHA ಠ_ಠ
23:07cemerickApparently, there's a bit of OS X lockin that'll keep me there for a looong time.
23:07hiredmanso it's not just diacriticals
23:08technomancynot to mention MUSICAL SYMBOL SIXTEENTH NOTE 𝅘𝅥𝅯 and HEXAGRAM FOR DARKENING OF THE LIGHT ䷣
23:08krumholthi. i want my datastructures to implement some clojure interfaces like IFn and ISeq can i do that?
23:08hiredmanyes
23:09cemericktechnomancy: still keeping your catalog of unicode death metal names? ;-)
23:09technomancycemerick: always on the lookout; let me know if you spot any good ones.
23:10cemerickkrumholt: They're just like any other interfaces: implement the semantics, and you're in.
23:10Raynestechnomancy: I've been thinking, and I think we should rewrite Leiningen in Scala for shock value. Any objections?
23:11technomancyRaynes: the hardest part would be coming up with a good name.
23:11technomancyports are always tricky like that
23:11technomancyunless you're porting the Kelley project to Ruby; in that case the name kinda falls into your lap.
23:12danlarkinmy suggestion: wasteOfTime
23:12RaynesNow there is a fine name to be had.
23:12cemericktechnomancy: You could probably get a decent side biz going doing product positioning consulting. Firms score 7 figures to come up with a product name and a logo.
23:13technomancyhttp://tenderlovemaking.com/category/rkelly/
23:13technomancyI didn't name that one.
23:13technomancycemerick: the public domain is a rich, rich resource.
23:13cemericktechnomancy: OK, but jeez, don't tell the clients that! :-P
23:15cemerick1. Consume Project Gutenberg. 2. ??? 3. PROFIT!
23:15technomancywasn't one of the characters in Mona Lisa Overdrive employed checking names of potential projects for obscenity overlap in various languages?
23:15hiredmanfun cooker!
23:16cemerickmmm, Gutenberg has a slick mobile app-ish site.