2012-07-31
| 00:47 | muhoo | ordnung, eh? |
| 00:51 | nkkarthik | in clojurescript to connect to repl from a page I need to add 'repl/connect' code to the page |
| 00:51 | nkkarthik | but this I cannot check-in... into production I mean |
| 00:52 | nkkarthik | is there some conventional way that you guys follow? |
| 00:52 | emezeske | nkkarthik: (when config/debug (repl/connect)) |
| 00:54 | nkkarthik | emezeske: ah where do I set this?... is config/debug automatically available at compile time? |
| 00:55 | emezeske | nkkarthik: No, I just assumed that your app has some kind of configuration to tell it to e.g. use minified/plaintext assets, verbose logging, etc |
| 00:56 | nkkarthik | emezeske: ok... is there a conventional way to set these properties (or specify a file)... in cljsbuild options or somewhere? |
| 00:57 | nkkarthik | or do your own way |
| 00:58 | emezeske | I'm not sure if there's much of a standard convention at this point |
| 00:59 | emezeske | I tend to put my configuration stuff in a crossover .clj file, personally |
| 00:59 | emezeske | I don't know if that scales well or not, though |
| 01:00 | nkkarthik | emezeske: oh a config.clj file... not config.cljs?... so that this 'connect' code gets compiled out altogether? |
| 01:01 | emezeske | nkkarthik: The crossovers allow you to share .clj code with .cljs; I use that for my config so that both clojure and clojurescript have access to the config variables |
| 01:01 | emezeske | nkkarthik: You could use a macro to compile out that code altogether if you wanted |
| 01:02 | emezeske | nkkarthik: If you are just using cljs, and no clj, then crossovers don't buy you anything |
| 01:03 | nkkarthik | emezeske: yeah I just started out with cljs and going through the quick start... and had this question... I thought maybe we use clojure to compile it to javascript and so we can use a clj file to compile it out |
| 01:03 | nkkarthik | emezeske: the macro idea sounds good too |
| 01:03 | emezeske | nkkarthik: That's definitely an option. If you're just starting out, though, I recommend staying away from advanced features like crossovers until you feel comfortable with the basics |
| 01:03 | emezeske | nkkarthik: They are kind of a hack, and are tricky to get right |
| 01:04 | nkkarthik | emezeske: yeah I will keep out then :) |
| 01:07 | nkkarthik | emezeske: I will stay with the config.cljs file for now then |
| 01:07 | nkkarthik | emezeske: by the way... thank you for the plugin |
| 01:08 | emezeske | nkkarthik: Yeah, I'm glad you've found it useful! |
| 01:30 | mk | can I change part of a function defined using defn, or must I use a second defn to redefine the function? |
| 01:33 | mk | ,(defn f [n] (* 2 n)) (f 2) |
| 01:33 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 01:34 | mk | if I'm on the repl, and there's a thread executing a loop within f, how can I change the 2 to a 3 without interrupting that thread? |
| 01:44 | emezeske | mk: The defn macro takes a list of forms, makes a fn, and then puts it into a Var |
| 01:44 | emezeske | mk: The list of forms is definitely immutable |
| 01:44 | emezeske | mk: And I think the fn is too |
| 01:44 | emezeske | mk: Meaning that if you want to change things, you need to change the "f" Var, which you could do by, as you said, another defn |
| 01:45 | emezeske | mk: If you want to change the "2" by itself, you'd have to do some work up front |
| 01:45 | mk | how do I go about mutating it? |
| 01:45 | emezeske | You could make 2 an atom |
| 01:45 | emezeske | (defonce multiplier (atom 2)) |
| 01:45 | emezeske | (defn f [n] (* 2 @multiplier)) |
| 01:46 | emezeske | Then, somewhere else, (swap! multiplier (fn [old] new-value ...)) |
| 01:46 | emezeske | That would mutate multiplier in a thread-safe manner |
| 01:47 | mk | what does defonce do? the doc's "root value" is confusing |
| 01:47 | emezeske | It just ensures that if you reload the namespace the atom doesn't get redefined |
| 01:47 | mk | or, what is a "root value"? |
| 01:47 | emezeske | It's not strictly necessary, but it can avoid some confusion |
| 01:48 | emezeske | I probably shouldn't try to explain the root value, etc -- I would probably not get it right |
| 01:48 | emezeske | You can read the docs on Vars if you want to understand that |
| 01:48 | mk | oh, I see. Does it redefine if the value has later been removed from the namespace? |
| 01:48 | emezeske | I'm not sure, I would guess so, though |
| 01:50 | mk | I want to mutate the multiplier while programming via the repl... is atom appropriate for that? |
| 01:53 | emezeske | Yep! |
| 01:53 | mk | then why don't we use atoms even for definitions? |
| 01:54 | emezeske | Well, Vars and atoms have different concurrency properties |
| 01:54 | emezeske | Like when you mutate a Var, it's usually done in a thread-local context |
| 01:54 | emezeske | Vars are not good for sharing state across threads |
| 01:54 | Raynes | emezeske: I think fs's cwd mechanism is a good example of it. |
| 01:54 | Raynes | (of how vars work) |
| 01:55 | emezeske | Raynes: Yeah, it does, IIRC |
| 01:55 | emezeske | Raynes: cwd is a dynamic var, right? |
| 01:55 | Raynes | But I don't know, since I might have force pushed a branch at some point. I damaged the universe like that once, much like Walter's crossing over in Fringe. |
| 01:55 | emezeske | Fringe, that show with Spock? |
| 01:56 | Raynes | emezeske: Haha |
| 01:56 | Raynes | Yes. |
| 01:56 | emezeske | :) |
| 01:56 | Raynes | emezeske: But yes, it is a dynamic var. The fun bit is that you can set it with set!. |
| 01:56 | mk | what is a dynamic var? |
| 01:56 | Raynes | The pot of gold at the end of the rainbow. |
| 01:58 | emezeske | mk: It's a Var created like (def ^:dynamic x 5) that can be changed in a thread-local dynamic scope via things like (binding ...) |
| 01:58 | emezeske | mk: But for more detail, the docs are king :) |
| 01:58 | mk | when I mutate a var using the repl, and there's a thread busy crunching data, isn't that out of thread-local? |
| 01:59 | emezeske | Yeah, although if you set the root binding (as you mentioned) I do believe it would affect other threads |
| 01:59 | emezeske | But really, that is what atoms are for |
| 02:00 | mk | so in cases where we suspect that we might end up modifying code in this way, we should use atoms throughout? |
| 02:01 | mk | this seems strange |
| 02:02 | mk | if we're both writing the same code, and you do it in one go, while I do it interactively using the repl, my code now has atoms everywhere while yours doesn't... |
| 02:02 | emezeske | Well, if you reload a namespace with (require ... :reload), all the Vars get changed |
| 02:02 | emezeske | And if you really want to, you can set! a Var |
| 02:03 | emezeske | I suggest you do some more reading on clojure's concurrency primitives and make an informed decision |
| 02:06 | mk | if you look at the first example, with the multiplier - if I've chosen to use the repl to fine-tune the value of multiplier, I end up making it an atom. But if you know what you want the multiplier to be, you'd just (def multiplier 7.23), without using an atom. This doesn't seem strange? |
| 02:07 | mk | we end up with the same code, but many of my values are wrapped in atoms. Do I then just remove all of the atom definitions, when I'm done messing via the repl? |
| 02:08 | emezeske | This would be a good place to start: http://clojure.org/concurrent_programming |
| 02:09 | ro_st | anyone know of a pubsub impl in cljs that isn't the shoreleave one? |
| 02:09 | ro_st | it's broken and ohpauleez is AWOL :-) |
| 02:10 | mk | emezeske: is there something particular there that I should read? |
| 02:10 | ro_st | also, does anyone use enfocus? i'm curious as to whether i can use it to focus a textfield |
| 02:11 | emezeske | mk: I would start with reading about Vars and Atoms, to see what the differences/similarities are. |
| 02:12 | emezeske | mk: There's no clear answer about which is "better" -- they are different, and which one you want depends a lot on context |
| 02:21 | meenal | Hi, can someone please point me to a good example of slingshot ex-info/ex-data in clojure? |
| 02:21 | meenal | I am trying to use slingshot to avoid writing custom exceptions |
| 02:24 | emezeske | meenal: I happen to know that https://github.com/cemerick/friend/blob/master/src/cemerick/friend.clj uses throw+ and try+ |
| 02:24 | emezeske | meenal: It's not meant to be an example, but that was the first place I saw slingshot in action |
| 02:26 | michaelr` | Is there a way to destructure in one compojure route definition all of the following: a paramter from params with an aliased name, user-agent header, all headers, all session? Something like this: https://www.refheap.com/paste/3914 |
| 02:27 | meenal | thanks emezeske. i will try to read thro' the code |
| 02:34 | michaelr` | ok |
| 02:34 | michaelr` | that's the way you do it: https://www.refheap.com/paste/3915 |
| 02:34 | michaelr` | (money for nothing and chicks for free) |
| 02:36 | muhoo | the fun thing about slingshot is it shows the local variables at play when the exception happened |
| 02:38 | ro_st | michaelr`: i think destructuring is clojure's MVP |
| 02:38 | ro_st | it is insanely useful |
| 02:46 | y3di | do the prismatic guys ever stop by this channel? |
| 02:46 | ro_st | you also want their data store abstractions? :-) |
| 02:47 | ro_st | really enjoyed that guy's talk |
| 02:47 | emezeske | ro_st: at clojure/west? |
| 02:48 | ro_st | yes, that's the one |
| 02:48 | ro_st | http://www.infoq.com/presentations/Why-Prismatic-Goes-Faster-With-Clojure |
| 02:48 | emezeske | ro_st: yeah, that was great |
| 02:48 | emezeske | Those guys are using the #&*? out of clojure |
| 02:49 | ro_st | it rocks. i wish more big guys would talk about how they use it |
| 02:49 | emezeske | aye |
| 02:49 | ro_st | convince the fence sitters to take a look |
| 02:49 | michaelr` | ro_st: minimal viable product? |
| 02:49 | ro_st | most valued pfeature -grin- |
| 02:49 | emezeske | *pheature |
| 02:50 | michaelr` | oh, we add those all the time to our applications ;) |
| 03:12 | ro_st | contains? checks if a key is in a collection. how do i check for the presence of a value in a collection? in this case, a vector? |
| 03:13 | DaoWen | I think you can use (.indexOf v element) |
| 03:13 | ro_st | whoa. didn't think i'd have to use java! |
| 03:13 | DaoWen | of you could use (some #{element} vector) |
| 03:13 | emezeske | ro_st: Maybe some? |
| 03:14 | emezeske | Hah, DaoWen beat me to it :) |
| 03:15 | DaoWen | :) |
| 03:16 | djcoin | Is there a problem using .indexOf (besides "it's java") ? |
| 03:16 | ro_st | some does the trick. just found it weird that i'd have to drop to java to find that index. of course, i don't have to, because (some) does the job |
| 03:21 | DaoWen | ro_st: if you need to check for the presence of a value in a vector, you might think about switching to a set |
| 03:21 | DaoWen | it depends on what you're doing of course |
| 03:21 | DaoWen | how big your vector is, how often you need to check, etc |
| 03:22 | ro_st | i could use a set, but in this case i want the order items were added to remain in place |
| 03:22 | DaoWen | one thing I've done in the past is keep a vector AND a set |
| 03:25 | emezeske | ro_st: There is a sorted-set if you need it |
| 03:26 | DaoWen | emezeske: I think he's trying to maintain things in the order they were added, which isn't necessarily a sorted order |
| 03:26 | emezeske | Oh, quite right! |
| 03:26 | ro_st | yup |
| 03:26 | emezeske | There might or might not be some beer in me |
| 03:27 | ro_st | as long as you don't drunk-commit -grin- |
| 03:27 | emezeske | I have had to revert drunk commits before, I'm sad to admit |
| 03:30 | ro_st | oh dear :-) |
| 03:41 | muhoo | wow, nrepl in the hizzy |
| 03:41 | muhoo | successfully upgraded to emacs24, latest nrepl.el, and pdo is working |
| 03:46 | muhoo | lein2 pdo cljsbuild auto, repl :headless |
| 03:46 | ro_st | sounds awesome |
| 03:46 | ro_st | what's pdo? :) |
| 03:46 | muhoo | ro_st: github.com/raynes/lein-pdo |
| 03:46 | ro_st | ok so you have cljsbuild running, and a headless repl, so that you can nrepl in from emacs? |
| 03:46 | muhoo | a nifty plugin that lets one lein process handle multiple tasks in parallel. like, a cljsbuild, and a headless repl |
| 03:46 | muhoo | ya |
| 03:46 | ro_st | i would love to see your emacs and project.clj config for this |
| 03:46 | ro_st | please :-) |
| 03:46 | muhoo | ro_st: https://www.refheap.com/paste/3918 |
| 03:46 | ro_st | that looks straightforward |
| 03:46 | ro_st | i guess i'm more curious about nrepl.el and how it works with clojure-mode |
| 03:46 | muhoo | there's no .emacs , i just manually am loading nrepl.el for now, from github.com/kingtim/nrepl.el |
| 03:46 | ro_st | i'm using emacs-live which has swank-clojure and clojure-mode all glommed together |
| 03:46 | muhoo | M-x load-file RET /home/clojure/src/nrepl.el/nrepl.el RET |
| 03:47 | ro_st | *reads nrepl.el issues* |
| 03:47 | muhoo | easy enough to just read nrepl.el, it's about 1200 lines |
| 03:48 | ro_st | i'll make time to play with it this afternoon |
| 03:48 | ro_st | it looks great |
| 03:48 | muhoo | i find it a lot more approachable than swank, then again, i'm not an old-skool swank user |
| 03:48 | muhoo | seems like the keybindings are the same though |
| 03:54 | ro_st | cool |
| 04:12 | ro_st | i guess if i want a vector sorted, i should use sorted-set or sorted-map, and then (vec) afterwards? |
| 04:13 | ejackson | or just call sort ! |
| 04:18 | amalloy | if you want a vector sorted, you probably don't want a vector |
| 04:22 | ro_st | ejackson: i don't see the fn you refer to on http://clojuredocs.org/quickref/Clojure%20Core |
| 04:23 | ro_st | amalloy: i actually want a sorted-map, but sorted-map sorts on the key, not on the value, and i need to sort on a field in the map that makes up the values in my map |
| 04:23 | amalloy | ro_st: that's a heap |
| 04:23 | ro_st | this map is an atom, which makes using a sorted-set problematic (ito updating values in this data) |
| 04:26 | ro_st | amalloy: are you referring to heap-sorting? |
| 04:26 | ejackson | ,(sort [12 4 8 23 1]) |
| 04:26 | clojurebot | (1 4 8 12 23) |
| 04:26 | amalloy | http://en.wikipedia.org/wiki/Heap_%28data_structure%29 |
| 04:27 | ejackson | but amalloy is correct, |
| 04:28 | ro_st | ok, this is well out of my comfort zone. i never did compsci :-) can i use a heap/heap sort in cljs? |
| 04:29 | ro_st | in this case, i don't need lazy, as it's to sort a series of models in preparation for displaying a list of html nodes |
| 04:30 | ro_st | so the full collection will be realised. so i'll start with (sort comp coll) for now |
| 04:59 | ro_st | sort fns usually return 1 0 −1 based on whether A is less than, equal to, or greater than B |
| 04:59 | ro_st | i see clojure's sort uses true and false. what do i return for the equality case? i won't have this case now, just curious. |
| 05:14 | DaoWen | ro_st: I know tis is a bit late, but you might want to use sort-by rather than sort since it sounds like you're sorting on a specific field in a data structure. that will keep your comp function simpler. |
| 05:15 | ro_st | yeah, i found that :-) |
| 05:15 | ro_st | thanks |
| 05:37 | ro_st | surely there's a better way to print vectors and maps to the js console than cljs.core.ObjMap and cljs.core.PersistentVector trees? |
| 05:38 | ro_st | *reads himera again* |
| 05:48 | ejackson | ro_st: I just log em to the the console |
| 05:49 | ro_st | yeah but having to drill down into PersistentVectors is sucky compared to plain js arrays |
| 05:50 | DaoWen | ro_st: what do you mean by "drill down?" |
| 05:51 | ro_st | http://rationalist.co.za/uploads/Screen%20Shot%202012-07-31%20at%2011.50.38%20AM-rS07Grmbqs.PNG |
| 05:52 | ro_st | i guess i could augment my log fn to dig into these and show the internal items i'm interested in |
| 08:44 | lotia | greetings all. new projects, relative noob to clojure. nrepl or swank for new projects. |
| 08:44 | lotia | whats better? |
| 08:44 | ro_st | nrepl is still brand new |
| 08:45 | ro_st | that said, it's probably better for you to learn that and grow with it than take swank on and switch |
| 08:45 | lotia | i ask because i'm starting a new pallet project using lein2 and want to be able to eval forms from within my files. |
| 08:45 | ro_st | i believe nrepl does that no problem |
| 08:45 | lotia | so using emacs, i'd need to get the nrepl client |
| 08:46 | lotia | ro_st: thanks. anywhere there's a list of advantages, disadvantages of either? or are the roughly equivalent for most use cases? |
| 08:47 | ro_st | swank is about to be deprecated, once the guys doing nrepl get it to the point they're happy with it |
| 08:47 | ro_st | coupla weeksish |
| 08:47 | lotia | ro_st: thanks |
| 08:48 | lotia | anyone using el-get for their emacs here? |
| 08:54 | ro_st | i'm using emacs24 for osx |
| 08:54 | ro_st | comes with package-install.. i just added the marmalade repo |
| 09:01 | lotia | thanks ro_st |
| 09:04 | cshell | does anyone know how to pretty print to a file in clojure? |
| 09:04 | XPherior | Anyone ever seen the error message "Incorrect table name ''" in Korma? |
| 09:05 | XPherior | I darn sure specified a name. |
| 09:10 | gfredericks | cshell: at the very least you could (spit "foo.cljj" (with-out-str (pprint data))) |
| 09:10 | gfredericks | and improve from there for any needed perf |
| 09:10 | gfredericks | there might be a pprint-str also, not sure |
| 09:17 | cshell | gfredericks: cool, i'll give that a shot - thanks! |
| 09:20 | ro_st | XPherior: what does the sql dry-run look like? |
| 09:20 | XPherior | ro_st: I just noticed that my usage of create-db is returning a PersistentArrayMap. That can't be right, heh. |
| 09:21 | ro_st | haha, um, no, probably not :-) |
| 09:23 | XPherior | ro_st: Have a look. https://gist.github.com/eecf4c8857596c73b72f |
| 09:23 | XPherior | Line 3 is still returning an array map. Weird. |
| 09:25 | ro_st | XPherior: db contains an execution result, where i think you actually want a defdb definition |
| 09:26 | XPherior | ro_st: I need to create the connection dynamically. I don't know what the DB name is at compile time. |
| 09:27 | ro_st | i get that. i speak under correction, but as far as i know korma uses static defdb definitions. |
| 09:27 | ro_st | you can probably overcome this by doing what defdb does yourself |
| 09:28 | XPherior | I basically am. Check it out. https://github.com/ibdknox/Korma/blob/master/src/korma/db.clj#L60 |
| 09:33 | ro_st | ah |
| 09:33 | ro_st | weird |
| 09:35 | ro_st | so, presumably there's something different about the spec there and the one you're providing? |
| 09:40 | XPherior | Looks like it, yeah. |
| 09:43 | antoineB | hello, how can i construct a list from 2 list? |
| 09:43 | antoineB | (apply list '(1 2 3) '(1 2 3)) => ((1 2 3) 1 2 3) where i expect (1 2 3 1 2 3) |
| 09:44 | xeqi | $findfn [1 2 3] [1 2 3] [1 2 3 1 2 3] |
| 09:44 | lazybot | [clojure.set/union clojure.core/lazy-cat clojure.core/concat clojure.core/into] |
| 09:44 | xeqi | I'd use concat there |
| 09:47 | antoineB | simply concat, thanks |
| 09:51 | leafw | what is the current authoritative repository for clojure monads? Used to be part of clojure-contrib |
| 09:51 | leafw | but now clojure-contrib is fragmented |
| 09:53 | xeqi | ~contrib |
| 09:53 | clojurebot | Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 09:54 | xeqi | leafw: looks like https://github.com/clojure/algo.monads/ |
| 09:55 | leafw | xeqi: thanks. So does that mean that it is included in the main clojure repository? |
| 09:55 | leafw | I see, no |
| 09:55 | leafw | it is in its own |
| 09:56 | xeqi | leafw: no, you'll need something like [org.clojure/algo.monads "0.1.0"] as a dependency |
| 09:57 | leafw | thanks |
| 09:57 | mk | how do I get lein repl started using 1.3? |
| 09:59 | mk | or, does anyone's lein repl start using (clojure-version) 1.3 by default? |
| 10:00 | xeqi | mk: make a project using 1.3 and then run `lein repl` in it |
| 10:02 | mk | I was running it in a random dir to get access to a repl. I suppose I can just run clojure instead of lein repl? |
| 10:02 | mk | is there any difference between the two? |
| 10:03 | ToxicFrog | mk: 'lein repl' sets up the CLASSPATH and stuff appropriate to your project, and I think also uses jline automatically |
| 10:04 | ToxicFrog | If you don't have a project and just want a Clojure repl, 'clojure' (if your distro comes with it) or 'java -cp ...jline.jar:...clojure.jar jline.ConsoleRunner clojure.main' if it doesn't should do the trick. |
| 10:05 | ToxicFrog | Or just 'java -jar /path/to/clojure.jar' if you don't care about readline support. |
| 10:07 | mk | yeah, just clojure seems to work. I was under the impression that lein repl was enhanced in some way, though I'm not sure what way that would be since it's about as bland as it gets |
| 10:11 | mk | is the only difference between bigint and biginteger the hashcode? |
| 10:12 | leafw | how does one specify a local jar in the project.clj? |
| 10:12 | leafw | as in, where does one put it so that it ends up in the classpath and it is read as a dependency? |
| 10:13 | ifesdjeen | leafw: pretty much the same way as you would do with maven |
| 10:13 | ifesdjeen | leafw: you can add :repositories {"local" ... |
| 10:13 | leafw | ifesdjeen: I have no idea how to use maven |
| 10:13 | ifesdjeen | point to (.toUri (java.io.File. "maven_repository_path")) |
| 10:13 | leafw | lein is supposed to shelter us all from maven |
| 10:13 | ifesdjeen | :) |
| 10:13 | ifesdjeen | yeah, it certainly does |
| 10:14 | leafw | so the .toUri you add in the project.clj? |
| 10:14 | ifesdjeen | yup |
| 10:14 | leafw | ok |
| 10:14 | leafw | thanks |
| 10:14 | leafw | wouldn't need to if org.clojure/algo.monads "0.1.3-SNAPSHOT" existed. |
| 10:14 | ifesdjeen | leafw: hm, people say that you can just say :repositories {"local" "path" } |
| 10:15 | leafw | the git repos pom.xml says that's the current. |
| 10:15 | leafw | ok |
| 10:15 | ifesdjeen | oh my, there's even plugin for that :D |
| 10:15 | ifesdjeen | https://github.com/kumarshantanu/lein-localrepo |
| 10:15 | leafw | lein is as complicated as it gets, mostly from lack of documentation. |
| 10:16 | ifesdjeen | so far didn't get much issues with that... |
| 10:16 | leafw | the default project.clj could have, commented out, all possible examples with a one-liner explaining what they are for. Like for the "local" |
| 10:16 | leafw | thanksf or the help ifesdjeen |
| 10:17 | ifesdjeen | leafw: npnp |
| 10:17 | ifesdjeen | hope it does it's job :) |
| 10:17 | leafw | ever since the break down of contrib, I have not been able to use any contrib projects. |
| 10:17 | leafw | so trying again |
| 10:18 | uvtc | leafw: jumping in to the middle of this, but if you're looking for a project.clj with all possibilities, see https://github.com/technomancy/leiningen/blob/master/sample.project.clj . |
| 10:18 | DaoWen | mk: no, the difference between bigint and biginteger is not just the hashcode |
| 10:18 | leafw | thanks uvtc |
| 10:19 | uvtc | leafw: y/w. Also, if you're new, you might find this useful: http://www.unexpected-vortices.com/clojure/brief-beginners-guide/ |
| 10:19 | mk | DaoWen: what are the main differences? |
| 10:19 | DaoWen | sorry, I was looking up a URL |
| 10:19 | DaoWen | http://grepcode.com/file/repo1.maven.org/maven2/org.clojure/clojure/1.3.0-alpha5/clojure/lang/BigInt.java |
| 10:20 | DaoWen | that's the BigInt class |
| 10:20 | DaoWen | you can see right at the top that it wraps both a long and a BigInteger |
| 10:21 | leafw | uvtc: thanks, not new to clojure, but haven't used it for 2 years |
| 10:21 | leafw | and now it's all different. Still no good IDE unfortunately. |
| 10:21 | DaoWen | mk: BigInt will use the native operations for long when possible |
| 10:22 | DaoWen | but if the number gets to big then it uses the arbitrary-precision BigInteger methods to do operations like add, multiply, etc |
| 10:23 | ifesdjeen | leafw: not sure what would make it for a good ide for you, i use it with emacs + paredit + clojure-mode + autocomplete-mode + swank |
| 10:23 | leafw | lein is full of magic that I find hard to grasp. For example, a function defined in core.clj, how do I refer to it from project.clj? core.main having written (defn main ..) doesn't do it. |
| 10:23 | ifesdjeen | works really really well for me |
| 10:23 | leafw | core/main ? |
| 10:24 | leafw | ifesdjeen: emacs destroys my hands. vim, eclipse, or a plain text editor I prefer. |
| 10:24 | ifesdjeen | ah |
| 10:24 | ifesdjeen | well, only problem with vim I have is that it's not playing with lips as well as emacs does |
| 10:24 | DaoWen | leafw: I use lein with vim |
| 10:24 | mk | DaoWen: I see, thanks |
| 10:24 | ifesdjeen | but i do feel very comfy with it, so dunno) |
| 10:25 | leafw | DaoWen: I am at the moment. |
| 10:25 | DaoWen | nice :) |
| 10:25 | DaoWen | do you use slime.vim? |
| 10:25 | leafw | DaoWen: so how does one refer to a fn named "main" in core.clj from project.clj? |
| 10:25 | leafw | it's not core.main |
| 10:25 | leafw | and not core/main |
| 10:25 | xeqi | projectname.core/main ? |
| 10:26 | DaoWen | try that ^ |
| 10:26 | DaoWen | you need the fully-qualified namespace |
| 10:26 | DaoWen | leafw: what does the (ns) declaration look like at the top of your core.clj file? |
| 10:26 | leafw | project is parse-bib, so parse_bib.core/main fails, and parse_bib.core.mains fails too |
| 10:26 | DaoWen | try |
| 10:27 | DaoWen | parse-bib.core/main |
| 10:27 | DaoWen | (hyphen instead of underscore) |
| 10:27 | DaoWen | if that doesn't work |
| 10:28 | DaoWen | did you :require it in your ns declaration in the current file? |
| 10:28 | leafw | DaoWen: the default |
| 10:29 | DaoWen | leafw: what exactly are you trying to do? are you trying to declare the main method in project.clj for a runnable jar or something? |
| 10:29 | leafw | DaoWen: parse-bib.core |
| 10:30 | antoineB | how could i do a recursive call without a named function? |
| 10:30 | leafw | I am doing the simplest thing possible: (ns parse-bib.core) (defn main [] (println "ok")) |
| 10:30 | DaoWen | and you just want to call that function from another file? |
| 10:30 | leafw | no, I want to define main as the main function in project,clj |
| 10:30 | DaoWen | (another namespace) |
| 10:30 | DaoWen | ok |
| 10:30 | leafw | so either lein doesn't like hyphens |
| 10:31 | leafw | in the project name |
| 10:31 | leafw | or I don't get it |
| 10:31 | Cheiron | How to get the name of a called function? for logging purpose |
| 10:31 | leafw | tried all combinations |
| 10:31 | DaoWen | yeah, it's weird |
| 10:31 | DaoWen | you actually have to declare it as (defn -main [& args] ...) in core.clj |
| 10:31 | leafw | that's my experience with lein always: can't get over the simplest things. There is a set of expectations that are not written anywhere about how lein works. |
| 10:31 | leafw | trying that |
| 10:32 | DaoWen | I guess that's the clojure magic for defining a java main method |
| 10:32 | leafw | (reads like static public final void main(String[] args) ....) |
| 10:33 | DaoWen | but then in your project.clj you just give the class |
| 10:33 | DaoWen | parse-bib.core |
| 10:33 | leafw | still doesn't work. So, removing the hyphen from the project name ... |
| 10:33 | DaoWen | also, in parse-bib.core you need to tell it to :gen-class |
| 10:33 | leafw | I see: so :main is not the function, but the name of the file |
| 10:33 | DaoWen | (ns parse-bib.core (:gen-class)) |
| 10:33 | DaoWen | :main is the name of the class |
| 10:34 | xeqi | :main is the namespace |
| 10:34 | leafw | finally, it worked |
| 10:34 | leafw | thanks |
| 10:34 | uvtc | leafw: re. "set of expectations that are not written anywhere about how lein works" ... if you find that lein is making an assumption and not telling you about it, and it's not documented, I'd suggest filing a bug. |
| 10:34 | leafw | so lein does respect hyphens in the project name |
| 10:34 | leafw | it is :main in project.clj that asks not for the main function but for the class in which a function named -main exists ... |
| 10:34 | Cheiron | I'm passing a function to another function, i want to print the name of the passed function. how to do it? |
| 10:34 | DaoWen | I don't think these are so much lein quirks as just clojure-java interop quirks |
| 10:35 | leafw | uvtc: doing so |
| 10:35 | DaoWen | leafw: I think :main is kind of like the class manifest in a JAR file |
| 10:35 | DaoWen | it asks for a "main" class |
| 10:35 | leafw | because the sample.project.clj doesn't say anything about it in :main |
| 10:36 | DaoWen | you could have any number of classes in a JAR with a main method with the legal signature, but you specify one as the "main" class |
| 10:36 | antoineB | i get it i just set a name to a fn: (fn f[a] (+ 1 (f a))) |
| 10:36 | leafw | DaoWne: the point here is, how is a novice user of lein ever to find out? |
| 10:36 | DaoWen | I've only been using lein for a couple of weeks |
| 10:36 | DaoWen | I googled how to make a runnable JAR |
| 10:37 | DaoWen | there are lots of blog posts on the subject :) |
| 10:38 | uvtc | leafw: Note, there's also a #leiningen channel. |
| 10:39 | Cheiron | when passing a function and parameters to macro, how to call it? ~(func ~@params) ? |
| 10:39 | leafw | uvtc: I hope not to have to use it, thanks |
| 10:43 | DaoWen | leafw: https://github.com/technomancy/leiningen/blob/preview/doc/TUTORIAL.md#uberjar |
| 10:43 | DaoWen | leifw: that section on the uberjar option explains everything on making a runnable jar |
| 10:44 | leafw | DaoWen: the point here is to use a jar from the file system |
| 10:44 | leafw | not to export the project to a jar |
| 10:44 | leafw | turns out the :repositories is only for looking for dependencies |
| 10:44 | leafw | what a game of guessing. Second guessing the maven developer/superuser that wrote lein |
| 10:45 | leafw | lein is wonderful, if one doesn't want to do something out of the ordinary |
| 10:45 | leafw | I was hoping referring to a jar would be that |
| 10:46 | leafw | maybe :javac-options would let me add a -cp |
| 10:46 | DaoWen | leafw: http://stackoverflow.com/questions/2404426/leiningen-how-to-add-dependencies-for-local-jars |
| 10:47 | leafw | uvtc: so I am moving to #leiningen, looks like the wall is high |
| 10:47 | xeqi | ~repeatability |
| 10:47 | clojurebot | repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability |
| 10:47 | leafw | DaoWen: thank you. The top answer is a hack. |
| 10:47 | xeqi | that explains why lein doesn't want to just include jars from the file system |
| 10:48 | uvtc | leafw: looks like the author of lein (technomancy) is not around right now. I'd suggest bringing up your questions again next time he's around. |
| 10:48 | DaoWen | leafw: the second answer seems better, but I don't know how to make a private maven repo.... but it looks like the third post explains how |
| 10:48 | leafw | I take note. Surely there are good reasons not to depend on a jar but on a repository instead. It's just baffling to a newcomer. |
| 10:49 | leafw | there is room for a book on how to create leinigen projects. |
| 10:50 | uvtc | A book? Maybe a booklet. Or a pamphlet. Or a leaflet. :) |
| 10:50 | DaoWen | leafw: I agree with you there. what if I want to use a JAR that's not in the maven repository? what if I'm using a proprietary JAR that can't be included in the repository? it seems like setting up a local repository just for one JAR in one project is a little bit overkill. |
| 10:50 | leafw | uvtc: no, a book, with 10-pgae chapters: a project with jars, why is (defn -main [& args]... needed, and so on. |
| 10:50 | Cheiron | Hi, would you please take a look to my with-try macro attempt: http://pastie.org/4365552 |
| 10:51 | DaoWen | leafw: https://github.com/kumarshantanu/lein-localrepo |
| 10:51 | leafw | DaoWen: the "hack" of ptting the jar in /lib should do it |
| 10:51 | leafw | so there is way |
| 10:51 | leafw | it is just not elegant |
| 10:51 | leafw | neither explained anywhere |
| 10:51 | DaoWen | leafw: looks like that plugin goes and make the local repo for you, and then you can add jars with a simple command |
| 10:51 | uvtc | leafw: writing good documentation is tricky. If you have any specific feedback on how to reorganize the lein docs to improve clarity, I'm sure technomancy would be all ears. |
| 10:52 | leafw | uvtc: indeed, complaining is not useful beyond a point. |
| 10:52 | TimMc | leafw: Don't put things in lib. |
| 10:52 | TimMc | It won't work, that's why it's not mentioned. |
| 10:53 | leafw | TimMC: it didn't work, likely because the algo.monads-0.1.3-SNAPSHOT.jar doesn't work with clojure-1.4.0. Just found that out |
| 10:53 | Cheiron | ah, ok. e# :) |
| 10:54 | uvtc | Cheiron: e#? |
| 10:54 | leafw | I am looking forward to join the priesthood of being able to use lein. Can't be that hard to use algo.monads in a clojure project. |
| 10:54 | Cheiron | (catch Exception e#) |
| 10:54 | TimMc | leafw: No, it won't work (at least in 1.x) because lib gets cleared. |
| 10:54 | TimMc | Are you using the 2.x preview? I came in late. |
| 10:55 | leafw | TimMc: using lein from 2 years ago, updated it self to 1.6 or so |
| 10:55 | TimMc | Yeah, ./lib is a local cache. Lein 1.x will delete the contents when updating deps. |
| 10:56 | uvtc | leafw: Yeah, I'm not sure I'm following exactly what the problem you're having is, but if you want to use a contrib library, I put up some basic notes at http://www.unexpected-vortices.com/clojure/brief-beginners-guide/libs-management-and-use.html#using-contrib-libraries . |
| 10:56 | dgrnbrg | hello clojurians |
| 10:56 | leafw | so algo.monads-0.1.1-SNAPSHOT exists, but can't run with 1.2, 1.3 or 1.4: error is Exception in thread "main" java.io.FileNotFoundException: Could not locate clojure/tools/macro__init.class or clojure/tools/macro.clj on classpath: |
| 10:56 | mk | Cheiron: why does e# work? |
| 10:56 | dgrnbrg | i'm having an issue getting a namespace that uses a macro for doing dynamic codegen to compile efficientyl |
| 10:56 | dgrnbrg | is there a way to get the macroexpansion to occur at AOT time? |
| 10:57 | Cheiron | i think because it generates a name, e could be bind somewhere else |
| 10:57 | leafw | uvtc: the program I am writing depends on algo.monads. I thought it would be nice to use lein to aleviate the dependency issues, but it is resulting in me wasting your time |
| 10:57 | Cheiron | mk: variable capture issue of other Lisps |
| 10:57 | uvtc | leafw: Oh, no waste of time. :) Sorry if that came out wrong. |
| 10:58 | leafw | sorry, didnt mean to make it sound harsh on you, rather on me (I am fumbling with lein when I expected a smooth ride) |
| 10:58 | leafw | so does anybody know what clojure version would work with algo.monads? |
| 10:59 | DaoWen | Cheiron: you are right, the e# syntax helps to avoid variable capture |
| 10:59 | leafw | uvtc: I see in your tutorial that the right approach is to query first maven central |
| 10:59 | mk | what is that syntax called? |
| 10:59 | TimMc | gensyn |
| 10:59 | TimMc | *gensym |
| 11:00 | TimMc | "generate (unique) symbol" |
| 11:00 | leafw | a pity maven central has 0.1.0 and not 0.1.3 for algo.monads |
| 11:00 | TimMc | &[`[e# e#] `[e# e#]] |
| 11:00 | lazybot | ⇒ [[e__18236__auto__ e__18236__auto__] [e__18237__auto__ e__18237__auto__]] |
| 11:01 | uvtc | DaoWen: what is "variable capture"? |
| 11:01 | xeqi | leafw: looks like the algo.monads test suite passes on >=1.2.0 http://build.clojure.org/job/algo.monads-test-matrix/ |
| 11:01 | DaoWen | uvtc: name capture |
| 11:01 | uvtc | DaoWen: what is "capture"? :) |
| 11:02 | DaoWen | uvtc: it happens with macros. Cheirion was trying to make a try/catch-like macro |
| 11:02 | leafw | xeqi: thanks |
| 11:02 | uvtc | DaoWen: Ah. Will research further next time I'm reading about macros. Thanks. |
| 11:02 | mk | I'm looking at clojure.org/reader, and it has nothing about # suffix. Where are the docs on this? |
| 11:02 | DaoWen | uvtc: what are you reading? |
| 11:03 | TimMc | mk: It's really the syntax-quote that does it. |
| 11:03 | leafw | xeqi: maven central has 0.1.0 for algo-monads, but setting it as dependency and then "lein run" doesn't download the jar into /lib, and fails with "Could not locate clojure/algo/monads__init.class or clojure/algo/monads.clj on classpath" |
| 11:04 | uvtc | DaoWen: I mean that I wanted to know what the term "capture" meant, and you pointed out that it has to do with macros, and at the moment I've only skimmed the documentation on macros. |
| 11:04 | leafw | ok "lein deps" did it |
| 11:04 | leafw | would have expected that to hppen as fallback from lein run |
| 11:05 | xeqi | leafw: that would be my expectation too, we try to make sure all reuired tasks are run in lein2 |
| 11:05 | mk | TimMc: thanks, I see that in the docs now, where it says ends with '#' |
| 11:05 | DaoWen | uvtc: "capture" happens when a name declared in a macro conflicts with a name already declared in the scope where it's used, so the macro "captures" the user's attempts to reference the binding they declared--and bad stuff happens |
| 11:05 | xeqi | not sure how well that was done in lein1, esp not if you have n older version |
| 11:05 | leafw | xeqi: nice to hear there is a better version of lein in the works |
| 11:06 | leafw | xeqi: using lein 1.6.1.1 |
| 11:06 | uvtc | DaoWen: Thanks. :) |
| 11:07 | leafw | finally ready to go; thanks uvtc, xeqi and DaoWen. |
| 11:15 | TimMc | uvtc: There are two kinds of capture (maybe one has a different name): 1) Macro introduces a binding that shadows an existing lexical binding, 2) macro's introduced binding is shadowed by an internal lexical binding in the expansion. |
| 11:15 | TimMc | I'd be hard-pressed to come up with a good example of the second. |
| 11:18 | jsabeaudry | Is it new that cljsbuild triggers a compilation when a clj file changes and not only when a cljs file changes? |
| 11:20 | uvtc | TimMc: thanks for the info. Added to my own notes for when I dig into macros. :) |
| 11:21 | DaoWen | TimMc: (fn [x] (let [loop #(apply prn %&)] (loop 1))) |
| 11:22 | uvtc | TimMc, DaoWen : Previously, I'd used the term "capture" to refer to pieces of regexes that matched. Like \1 and $1. |
| 11:24 | uvtc | s/I'd used/I'd only used/ |
| 11:24 | DaoWen | uvtc: this is a big problem in computer science--we re-use words way too much and give them way too many different meanings. I believe the "name capture" idea originally comes from the Lambda Calculus. |
| 11:25 | uvtc | Yeah. Trouble is, if you invent too many new words, you end up with too much jargon. :) |
| 11:25 | TimMc | It's a problem everywhere. |
| 11:26 | DaoWen | haha, good point. |
| 11:27 | DaoWen | oh wow, I just realized my example was totally messed up |
| 11:28 | entel | has anyone got the noir plugin to work with leinengen 2? is it even possible? |
| 11:29 | DaoWen | entel: you might want to try #leiningen |
| 11:30 | entel | DaoWen: ok thanks |
| 11:37 | m0smith | Any clojurescript gurus around? I am getting this not too helpful error: Exception in thread "main" java.lang.AssertionError: Assert failed: Only :refer-clojure, :require, :require-macros, :use and :use-macros libspecs supported |
| 11:37 | m0smith | (#{:use-macros :require-macros :require :use} k) |
| 11:37 | nDuff | m0smith: Can you gist (or otherwise pastebin) your ns declaration? |
| 11:38 | m0smith | (ns crossfire.board (use [crossfire.protocol.location :only [display open?]])) |
| 11:38 | melipone | hello |
| 11:38 | nDuff | m0smith: ...so, first, that should be :use |
| 11:39 | melipone | how do a get a list of rows from an Incanter matrix? |
| 11:39 | m0smith | nDuff: you are a genius, thanks |
| 11:40 | TimMc | melipone: Try seq. |
| 11:41 | melipone | I tried seq but it still gives me a matrix back not a list of rows |
| 11:43 | melipone | timmc: sorry, appearances are deceiving. it does behave like a list of rows |
| 11:43 | m0smith | nDuff: now I get SEVERE: crossfire.board:4: ERROR - required "crossfire.protocol.location" namespace never provided |
| 11:44 | m0smith | I am using cljsc, where does it expect to be compiling from? |
| 11:48 | goodieboy | Anyone know of a leiningen plugin that would provide the ability to download *resources* from s3, by looking at a config map in project.clj? |
| 11:48 | goodieboy | ... s3, or some other url |
| 11:49 | DaoWen | meliphone: I think the Incanter Matrix class supports the .toArray method, which returns a double[][] -- which may or may not be helpful |
| 11:52 | uvtc | Just added an example to http://clojuredocs.org/clojure_core/clojure.core/some-fn . |
| 11:53 | uvtc | Incidentally, it would be pretty cool if there were a way for the site to send an automated message every time someone added an example. |
| 11:53 | uvtc | I mean, an irc message to this channel. |
| 12:10 | nDuff | m0smith: I'd have to look at the source for the file containing crossfire.protocol.location. |
| 12:16 | augustl | when I stop and restart my "lein ring server-headless", the :session key is not present in the first request, even though the :cookies entry is there. How come? |
| 12:16 | augustl | in subsequent requests, the :session works fine |
| 12:17 | augustl | correction: the :session key is present, but is empty |
| 12:17 | augustl | a minor annoyance, but still an annoyance :) |
| 12:18 | technomancy | https://twitter.com/gghhzz/status/230335904097656833 woo go clojure.org |
| 12:18 | hiredman | augustl: the defalut session store is an in memory store, you kill the process you lose it |
| 12:18 | augustl | hiredman: I'm using the cookie store |
| 12:18 | augustl | so the full session is present in the cookie |
| 12:20 | augustl | technomancy: Google Closure is similar (not only in name): you basically need to buy a book |
| 12:20 | augustl | the docs on the Google Closure site are abysmal |
| 12:21 | hiredman | *shrug* |
| 12:22 | hiredman | I've gotten most of what I needed from the google closure api docs |
| 12:22 | hiredman | the real pain is often the css for the ui widgets is not really documented |
| 12:23 | mabes | ,(doc realized?) |
| 12:23 | clojurebot | "([x]); Returns true if a value has been produced for a promise, delay, future or lazy sequence." |
| 12:23 | mabes | ,(realized? (iterate inc 1)) |
| 12:23 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IPending> |
| 12:24 | mabes | I am misunderstanding what the realized? doc string is telling me... |
| 12:24 | hiredman | ,(realized? (next (iterate inc 1))) |
| 12:24 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IPending> |
| 12:24 | hiredman | fuh |
| 12:24 | hiredman | ,(realized? (rest (iterate inc 1))) |
| 12:24 | clojurebot | false |
| 12:25 | hiredman | mabes: basically iterate doesn't produce it's fist item lazily, so it is not a lazy seq, but its rest is |
| 12:26 | mabes | hiredman: ah, got it.. ok, I can work with that. Thanks! |
| 12:26 | technomancy | wooooo eldoc in nrepl.el |
| 12:27 | m0smith | nDuff: https://github.com/m0smith/crossfire/blob/master/src/crossfire/protocol/location.clj |
| 12:29 | nDuff | m0smith: ...so that's .clj, not .cljs |
| 12:29 | m0smith | nDuff: yes I was hoping to make a cross-compatible code base |
| 12:29 | nDuff | ahh. |
| 12:32 | m0smith | would that confuse the cljs compiler? |
| 12:32 | nDuff | m0smith: Yes. lein-cljsbuild will automate making .cljs copies of the .clj files you want to use in both worlds for you. |
| 12:32 | nDuff | m0smith: ...I do suggest using it. |
| 12:33 | m0smith | nDuff: many thanks |
| 12:33 | technomancy | mmm... taste the rainbow: https://github.com/kingtim/nrepl.el/network |
| 12:34 | eggsby | hey technomancy have you had problems with large output from nrepl.el ? |
| 12:35 | technomancy | eggsby: no, but I can't say I've used it on projects with lots of output |
| 12:36 | pbostrom | augustl: when you restart the server, the session is not intialized until after you make the first request, the server looks at the cookie, recognizes it, then sticks something in the session for all subsequent requests |
| 12:36 | eggsby | technomancy: for me, something as simple as: (for [x (range 0 1000)] (println x " | hi")) results in "error in process filter: could not decode object 1" |
| 12:37 | technomancy | eggsby: no problem here. are you on Emacs 24 and nrepl.el master? |
| 12:37 | eggsby | ya :( |
| 12:37 | eggsby | actually just marmalade nrepl |
| 12:38 | technomancy | there's been a fair bit of activity since then; might try the latest |
| 12:38 | eggsby | will do, thanks |
| 12:40 | mk | is there a swap! that returns the old value? |
| 12:47 | nDuff | m0smith: Pull request pending. |
| 12:48 | augustl | pbostrom: so even if I have a cookie session, it puts stuff in memory? |
| 12:48 | nDuff | Oof. |
| 12:49 | nDuff | ...ignore that, please... |
| 12:51 | nDuff | (...so, the "ignore that" was in reference to the first rev of the pull request) |
| 12:51 | augustl | I assumed the :session values were added as soon as the middleware sees the cookie |
| 12:52 | TimMc | mk: Not anything in core. |
| 12:53 | TimMc | You could do something fancy with a side-effecting fn and another atom... |
| 12:57 | mk | I see. It looks like a watch might work too, at least for some purposes |
| 12:57 | m0smith | nDuff: I'll pull it now |
| 13:06 | m0smith | nDuff: that seems to have done the trick. Thanks again |
| 13:10 | pbostrom | august1: you should think of the cookie and session as two separate entities, if your app/service puts some key-value pair in the cookie, it will persist in the browser when you restart the server (depending on how the cookie is configured), if you put something into the session, it will persist in the server's memory by default (although I believe you can configure alternate session stores) |
| 13:11 | technomancy | question for anyone familiar with proxies: does it make sense to have one setting for HTTP proxies and a separate one for HTTPS? |
| 13:11 | Hodapp | technomancy: 'setting' in what sense? |
| 13:12 | technomancy | Hodapp: say you'd want to use a different proxy host for HTTPS? |
| 13:12 | technomancy | I'm ... not really sure |
| 13:12 | technomancy | basically I get all these feature requests for proxy support in Leiningen and I have no idea how proxies work or how people would expect them to be set =) |
| 13:13 | nDuff | technomancy: ...for a SOCKS proxy, it's typically the same one for all protocols |
| 13:13 | TimMc | (defn swap2! [a f & args](defn swap2! [a f] (let [old (promise)] |
| 13:13 | TimMc | (let [oldp (promise) |
| 13:13 | TimMc | f* (fn [oldv] (deliver oldp oldv) (apply f oldv args))] |
| 13:13 | TimMc | (swap! a f*) @oldp)) |
| 13:13 | technomancy | Apache's HTTP client uses separate http.proxyHost vs https.proxyHost settings, so presumably there's a reason for that |
| 13:13 | nDuff | technomancy: ...but some shops _do_ have protocol-specific proxies rather than using SOCKS. |
| 13:13 | TimMc | mk: crud, I thought I had the one liner in my clipboard, but... there you go |
| 13:13 | technomancy | nDuff: that's what I was wondering; thanks |
| 13:14 | TimMc | mk: Rather: https://gist.github.com/3218623 |
| 13:22 | m0smith | nDuff: One last question I hope. When I copy the resulting .js file to my webserver directory, it is looking for a deps.js but I can't see where that is supposed to come from |
| 13:29 | pbostrom | m0smith: I think it's a GClosure compiler thing, I get rid of it by putting this inline in the html: <script type="text/javascript"> var CLOSURE_NO_DEPS = true; </script> |
| 13:30 | nDuff | m0smith: set CLOJURE_NO_DEPS=true in your javascript before including it. |
| 13:30 | pbostrom | m0smith: before loading your .js file |
| 13:30 | nDuff | Ahh. |
| 13:31 | tufflax | Is it sane to want letmulti---local multimethods in a function? |
| 13:31 | m0smith | Thank you both. That got rid of that error. |
| 13:32 | m0smith | Now I just have to figure out how to get JS to call my code |
| 13:33 | rplevy | is jetty-util incompatible with ring-jetty-adapter, and if so does anyone know a version combination (or something) that is compatible? |
| 13:35 | rplevy | the stack trace is especially unhelpful here, but I get a classnotfound for org.eclipse.jetty.util.component.Destroyable |
| 13:35 | weavejester | rplevy: What's jetty-util? |
| 13:37 | emezeske | m0smith: (defn ^:export my-fn [] ...) |
| 13:37 | nDuff | emezeske: last I knew, m0smith wasn't using advanced compilation (yet). |
| 13:37 | emezeske | m0smith: That tells the google closure compiler to make that function available to JS even when advanced optimizations are on |
| 13:37 | emezeske | nDuff: Well, good to get in the habit now |
| 13:37 | nDuff | *nod* |
| 13:38 | nDuff | m0smith: ...so, it should just be your.module.name.your_function(args), that is, completely normal javascript calling convention |
| 13:40 | eggsby | hey thanks technomancy using the master branch fixed the problem |
| 13:40 | m0smith | nDuff: I look in the .js file and none of my code, namespaces, etc is in there. At least a naive search does not find it |
| 13:47 | nDuff | Hmm -- there's an error in the source, and cljsbuild is only reporting it once, silently failing on subsequent passes. That's annoying. |
| 13:48 | rplevy | nm I was just had the name of a class wrong because they changed it recently |
| 13:48 | rplevy | and jetty-utils is included already |
| 13:49 | m0smith | nDuff: Should I use require instead? Use is slightly more convienent is all |
| 13:50 | emezeske | nDuff: If you can reproduce this "only reporting an error once" problem, open a bug |
| 13:52 | nDuff | emezeske: Can, but not sure I have the time to build a minimal reproducer right now. Also, likely a lein-cljsbuild thing rather than a cljs thing proper. |
| 13:53 | m0smith | nDuff and emezeske: I was :use to include a file that defined a protocol. That would cause the error. Swtiching to :require fixed the error and makes more sense anyway |
| 13:54 | technomancy | m0smith: whaaaaat? |
| 13:54 | technomancy | I don't think that's possible |
| 13:54 | emezeske | nDuff: Well, if you aren't willing to make a repro, it's not getting fixed, because I have never seen that problem. |
| 13:57 | m0smith | technomancy: Debuggin a cljs problem. |
| 13:57 | technomancy | oh, ok; I know nothing about cljs |
| 14:13 | mk | is a var (setting aside dynamic scope) simply an atom but with only the reset! change semantic? |
| 14:14 | gtrak` | mk: vars are namespaced |
| 14:14 | gtrak` | I guess that's the dynamic-scoped bit |
| 14:15 | gtrak` | but they're also carry a thread-local stack for mutation, atoms are synchronous between all threads |
| 14:15 | gtrak` | s/they're/they |
| 14:16 | cemerick | saying "X is like an atom, but without the atomicity" is a curious comparison to try to make :-) |
| 14:16 | amalloy | cemerick: i don't think vars are missing any atomicity |
| 14:17 | amalloy | alter-var-root behaves like swap, and binding can't ever have contention/races |
| 14:17 | mk | isn't the stack only used in dynamic scope? |
| 14:17 | gtrak` | mk: stack is used on lookup |
| 14:18 | mk | but if there's nothing put on the stack using binding, or the var isn't defined dynamic in the first place (do I have that right?), then it's simply an atom, and it's not thread-local |
| 14:18 | gtrak` | it's not an atom... |
| 14:19 | mk | gtrak`: right, I mean that it might as well be |
| 14:19 | gtrak` | so... why would I prefer to use (def a (atom 0)) instead of (def a 0)? |
| 14:20 | mk | I have no idea, at the moment |
| 14:20 | foodoo | changing of (def a 0) is only intended for development purposes. Isn't that the issue? |
| 14:21 | Gnosis- | How does one decide whether to use an atom or a ref? |
| 14:21 | gtrak` | it might be more a statement of intent I guess |
| 14:21 | gtrak` | convention |
| 14:21 | amalloy | Gnosis-: use a ref if an atom lacks a feature you need |
| 14:21 | Gnosis- | ah, okay |
| 14:22 | mk | foodoo: I don't know. It's a bad idea to confused def with assignment, so perhaps that convention is there to avoid misleading those new to clojure |
| 14:22 | amalloy | the only features i can think of are: coordinating with other refs; being able to return something other than the current value from a swap! (that one can be worked around, but it's easier to just use a ref) |
| 14:23 | mk | but really, it seems like (def v ...), used to assign a new value to v, isn't that much different from (swap! ...) |
| 14:23 | gtrak` | swap! takes a function and does a compare-and-swap |
| 14:23 | gtrak` | spin-loops if it has to |
| 14:23 | mk | gtrak`: you're right, I meant reset! |
| 14:23 | gtrak` | right |
| 14:25 | pbostrom_ | there may also be a time when you want to coordinate side effects with a single ref |
| 14:26 | gtrak` | looks like var roots follow volatile semantics, JLS only guarantees 32-bit reads to be atomic |
| 14:26 | mk | and yes, like amalloy said, alter-var-root covers swap! (and therefore compare-and-set!) |
| 14:27 | gtrak` | probably not a real issue if you use boxed numbers |
| 14:27 | mk | I was under the impression that atoms offered something in addition to vars, but really, vars are effectively atoms, and in addition they provide dynamic scope |
| 14:28 | gtrak` | mk: it's misleading to keep saying that |
| 14:28 | gtrak` | atoms and vars are implemented totally differently |
| 14:28 | mk | gtrak`: I welcome correction :) |
| 14:28 | gtrak` | and have different use-cases |
| 14:28 | cemerick | amalloy: Of course; s/atomicity/CAS, but that wouldn't have rolled off the keyboard as nicely. |
| 14:28 | gtrak` | well, you know, for these things I like to just look at the source code |
| 14:29 | hiredman | vars are interned, they are linking construct, not a state management construct |
| 14:29 | mk | gtrak`: it doesn't matter if something is implemented + 4 1 or + 1 4, it's still the same result, unless one is faster. Vars seem to offer all of the features that atoms do, and then some |
| 14:30 | mk | hiredman: they seem to have everything you need in order to manage state |
| 14:30 | gtrak` | vars are volatiles... atoms are AtomicReferences under the hood |
| 14:30 | mk | gtrak`: I'm not saying that one extends the other |
| 14:31 | mk | gtrak`: what do you mean by volatiles? |
| 14:31 | gtrak` | there's a java keyword 'volatile' that offers particular memory semantics |
| 14:31 | hiredman | mk: the semantics of swap! are clearly a compare and swap, alter-var-root's semantics are not really defined |
| 14:32 | gtrak` | I think even if semantics were the same, the argument is the same as using a global vs a local... don't |
| 14:32 | hiredman | multiple alter-var-root's from different threads can stomp on each other |
| 14:32 | hiredman | vars are a linking construct |
| 14:32 | mk | hiredman: I don't think swap! does comparison unless you implement that in the function (which you can) |
| 14:32 | hiredman | clojurebot: vars? |
| 14:32 | clojurebot | http://www.slideshare.net/mudphone/fun-with-vars |
| 14:33 | hiredman | clojurebot: vars |are| a linking construct |
| 14:33 | clojurebot | You don't have to tell me twice. |
| 14:33 | hiredman | mk: swap! is a CAS |
| 14:33 | hiredman | e.g. if the value of atom changes it reruns the functions on the new value |
| 14:34 | augustl | how do you call a Java constructor that takes varargs? Just passing (MyThing. foo bar baz) doesn't seem to work. |
| 14:34 | gtrak` | augustl: into-array |
| 14:34 | gtrak` | varargs are arrays in java |
| 14:34 | hiredman | at the jvm level vargs don't exist, the java compiler turns java varargs in to an array |
| 14:35 | mk | hiredman: I'm pretty sure alter-var-root does the same. "atomically alters the root binding by applying f..." |
| 14:35 | augustl | gtrak`: looking it up, thanks |
| 14:36 | hiredman | mk: incorrect |
| 14:36 | mk | what happens if the value changes? |
| 14:37 | gtrak` | turns out alterRoot is synchronized anyway, that's slower than a CAS generally |
| 14:37 | hiredman | mk: if you aren't going to read what I type I will also put you on ignore, I told you what happens already |
| 14:38 | TimMc | nDuff: map vector |
| 14:38 | mk | hiredman: sorry, it's possible that I missed what you said among the other messages, or didn't understand you. I'll read up |
| 14:38 | TimMc | nDuff: Possibility of infinite seq? |
| 14:39 | nDuff | TimMc: Not necessarily infinite, but big enough that memory use is a relevant concern. |
| 14:39 | mk | hiredman: I still don't see where you answered my question |
| 14:40 | nDuff | mk: I do. |
| 14:41 | nDuff | mk: <hiredman> e.g. if the value of atom changes it reruns the functions on the new value |
| 14:41 | mk | I'm not talking about atoms, I'm talking about vars |
| 14:41 | nDuff | ... |
| 14:41 | nDuff | mk: you were given an example of a behavior atoms have that vars don't. That's pretty relevant. |
| 14:42 | mk | we're talking about alter-var-root. Doesn't that restart, in exactly the same way as atoms do? |
| 14:43 | mk | I could be wrong, but that's what I'm taking the documentation to mean when it says "atomically" |
| 14:43 | hiredman | no, it locks, unlike atoms |
| 14:43 | aphyr | What's the canonical way to do exponentiation in 1.3? add clojure.math.numeric-tower? |
| 14:45 | foodoo | clojure.math is not an official library, is it? |
| 14:46 | gtrak` | mk: CAS is a processor instruction, much more fine-grained than locking on the var object, you might get a similar result, but the semantics and implementation aren't the same |
| 14:46 | amalloy | aphyr: (reduce * (repeat n b)) is pretty easy if your exponent is an integer |
| 14:47 | mk | I see. So vars offer all the functionality of atoms, but in some cases atoms offer better performance at the cost of potentially executing (hopefully pure) functions repeatedly |
| 14:47 | aphyr | Yeah, kinda floored that this isn't builtin, haha |
| 14:47 | foodoo | I usually do (Math/pow a b) |
| 14:47 | gtrak` | yea, that's the whole point of CAS |
| 14:47 | aphyr | (need something that supports the rational types) |
| 14:47 | amalloy | aphyr: it is built in, you are on the jvm |
| 14:47 | zerokarmaleft | how large would a set of bindings in a let be before being considered non-idiomatic or bad style? |
| 14:47 | gtrak` | it's a case of cpu manufacturers pandering to software implementers |
| 14:48 | hiredman | ~vars |
| 14:48 | clojurebot | vars are a linking construct |
| 14:48 | technomancy | zerokarmaleft: it depends on whether you're using them all in the body or using them to construct further bindings |
| 14:48 | amalloy | but seriously the core lib is so huge there's no reason to pollute it with operations that are easily constructed by composing existing stuff |
| 14:48 | mk | it should be added to that that vars offer all the same functionality as atoms |
| 14:48 | zerokarmaleft | technomancy: to construct further bindings, but the last set of bindings are also used in the body...for readability |
| 14:49 | aphyr | amalloy: just weird that there's +, -, *, /, but expt requires changing project.clj. First language I've ever used where that was the case, haha. |
| 14:49 | zerokarmaleft | it just smells...imperative, in a way |
| 14:49 | technomancy | zerokarmaleft: in that case I'd be comfortable letting it get pretty big, but consider whether you can't rewrite it using -> |
| 14:49 | foodoo | aphyr: well, you can still use (Math/floor x y) |
| 14:50 | foodoo | if you are on the JVM |
| 14:50 | mk | whenever vars and def are brought up, people suggest that they shouldn't be changed at runtime, hinting that the reason for this is some sort of concurrency issue ("use atoms instead when you want concurrency") |
| 14:51 | mk | but vars are as safe as atoms. Potentially more safe, since they block instead of repeatedly executing. |
| 14:51 | nDuff | mk: If nothing else, rebinding is going to make it hard on people reading your code. |
| 14:51 | hiredman | ~vars |
| 14:51 | clojurebot | vars are a linking construct |
| 14:51 | technomancy | no |
| 14:51 | technomancy | they're less safe because they don't have to be dereferenced, so you can have mutability sneak into a function that looks pure |
| 14:52 | technomancy | don't do it |
| 14:52 | nDuff | (inc technomancy) |
| 14:52 | lazybot | ⇒ 34 |
| 14:53 | mk | technomancy: not sure that I follow how that might happen |
| 14:54 | amalloy | mk: (defn f [x] (+ x config/batch-size)) |
| 14:54 | amalloy | is (f 10) always the same value or no? |
| 14:55 | joly | not referentially transparent if the var value is going to change |
| 14:55 | joly | that's bitten me before |
| 14:56 | technomancy | technically it's very difficult to write clojure functions that are guaranteed referentially transparent exactly because of alter-var-root and runtime-def, but for most purposes "referentially transparent unless someone does something completely daft" is perfectly fine. |
| 14:57 | aphyr | How do you feel about the use of dynamically bound vars for IO, though? |
| 14:57 | aphyr | e.g. print-dup, out, etc? |
| 14:58 | technomancy | aphyr: the presence of *earmuffs* in a function makes it obvious that a function isn't referentially transparent, so there's not much room for confusion |
| 14:58 | mk | I think I see. We want to make sure that we have an explicit @ (or deref) at the start of all such values |
| 14:58 | technomancy | well, and the whole IO thing of course |
| 14:58 | aphyr | Yeah, like (prn) is definitely not referentially transparent, not even in the fixed IO sense. ;-) |
| 15:00 | mk | I was initially worried about what was happening when I defn'd using the repl. I was under the impression that this might put the entire program into an invalid state |
| 15:00 | technomancy | mk: that happens in some other languages (ML-based ones in particular) since they don't have the concept of vars, your changes do not apply retroactively. |
| 15:01 | technomancy | different parts of the program will have access to a different version of your function |
| 15:01 | technomancy | (this is true of some Clojure constructs like defmacro and defprotocol, which is one of many reasons you should always use defn if you can) |
| 15:02 | mk | is this still the case in clojure, in some rare cases? for example, a thread in a long-term recurring function |
| 15:02 | technomancy | if it goes through a var, it's safe |
| 15:02 | technomancy | if it dereferences the var and holds on to the raw fn, then it will retain the old value |
| 15:04 | mk | ok, all of this is very good to know. I take it that the problems with mutation don't apply if I'm mutating things intentionally using the repl? |
| 15:04 | technomancy | right; the primary reason (possibly only reason?) vars are mutable is to support interactive development. |
| 15:05 | foodoo | they do, because you may have suprising results. But when in doubt, restart the repl |
| 15:06 | mk | foodoo: I'd like to try to know about those surprises, because if I'm using the repl to crunch a few hours of data, restarting isn't practical |
| 15:06 | foodoo | if you have some old functions that still exist in the repl but don't exist in your code |
| 15:07 | foodoo | and you accidentally invoke them again for whatever reason |
| 15:07 | mk | I take it that we covered the main ones (not going through a var, and defmacro/defprotocol) |
| 15:08 | technomancy | in web apps you often see stuff like (run-jetty #'myapp {:port 8080}) in order to pick up dev-time reloads of myapp |
| 15:11 | mk | the way I'm thinking of it now, atoms are for the program to modify, while vars are there for the programmer; keeping in mind that changing a var might make a transparent-looking function no longer transparent, they're both safe in that changing them usually won't break clojure |
| 15:18 | dnolen_ | mk: also if you use a def to change the value of something that should be an atom the likelihood of another Clojure programmer using your lib will diminish to zero ;) |
| 15:18 | dnolen_ | someone should ad that case to kibit. |
| 15:18 | dnolen_ | add |
| 15:19 | ohpauleez | dnolen_: It's a good idea |
| 15:19 | dnolen_ | Raynes: even better if reheap got kibit support :) not sure if you've tried that yet. |
| 15:19 | technomancy | kibit-as-a-service |
| 15:19 | dnolen_ | Raynes: it would give refheap the oneup over all the other Clojure paste services. |
| 15:19 | technomancy | does kibit require eval? |
| 15:20 | dnolen_ | technomancy: no. |
| 15:20 | technomancy | cool |
| 15:20 | ohpauleez | technomancy: no |
| 15:20 | ohpauleez | it's totally static |
| 15:21 | technomancy | oh gross, it tells you to replace single-clause if with when |
| 15:21 | danlarkin | yesssssssssssssssssss |
| 15:21 | amalloy | technomancy: i told you, you're hugely in the minority in preferring it the other way |
| 15:21 | mk | dnolen_: that should never happen, assuming that the programmer knows to only use def manually, right? |
| 15:21 | mk | (via source, or repl) |
| 15:21 | danlarkin | amalloy technomancy: agreed |
| 15:22 | ohpauleez | technomancy: Why would you want it another other way? |
| 15:22 | technomancy | ohpauleez: because use of when indicates side-effects |
| 15:22 | ohpauleez | You're ticket still sits in the kibit repo for that haha |
| 15:23 | dnolen_ | kibit (technomancy remix) ? |
| 15:23 | technomancy | huh... Kibit's reader crashed; see kibit.check/read-file:java.lang.RuntimeException: Invalid token: ::friend/unauthorized-uri |
| 15:23 | technomancy | I guess that is a pretty weird keyword |
| 15:24 | ohpauleez | technomancy: because of a bug in clojure you can't do scoped keywords |
| 15:25 | ohpauleez | technomancy: I can *sort of* see your point about `when`, but I personally don't think of side effects when I see `when` |
| 15:25 | ohpauleez | I think of a clause where this is only a true branch, and nothing more |
| 15:25 | qerub | Is there an any? function somewhere in clojure.core? It should work like (defn any? [f seq] (reduce #(or %1 %2) (map f seq))). |
| 15:25 | pjstadig | don't worry technomancy i've got your back |
| 15:25 | ohpauleez | hahaha |
| 15:25 | aphyr | (some?) |
| 15:26 | technomancy | ohpauleez: so you think it's a design flaw that you can call if with only two args? |
| 15:26 | dnolen_ | qerub: some, but note it doesn't return true/false |
| 15:26 | uvtc | ohpauleez: My understanding is `when` has an implied `do`, therefore you use it when you want side-effects. |
| 15:26 | pjstadig | the battle lines are drawn! |
| 15:26 | ohpauleez | hahah |
| 15:26 | qerub | dnolen_: Thanks! |
| 15:26 | danlarkin | pjstadig: you and technomancy are clearly wrong and you know it |
| 15:26 | ohpauleez | everyone, place your bets |
| 15:26 | technomancy | it's not like this is a thing I made up; it's a long-standing convention even from older lisps |
| 15:26 | pjstadig | i know only that you are wrong, danlarkin |
| 15:27 | technomancy | even used in CL, which is famous for not giving a crap about FP and side-effects |
| 15:27 | aphyr | (when) is easier to debug with print statements. :-P |
| 15:27 | technomancy | aphyr: which are (wait for it) side-effects =) |
| 15:27 | amalloy | technomancy: ::foo/bar is a token that can only be read if you're eval'ing as you go :P |
| 15:27 | technomancy | if you need to debug in an if, use (doto x prn) |
| 15:27 | amalloy | which seems like a pretty terrible choice for clojure's reader |
| 15:27 | aphyr | Yeah, but it's not like (if is free of side effects either. :/ |
| 15:28 | ohpauleez | technomancy: I totally recognize the convention, and I don't think two arg if is a design flaw |
| 15:28 | technomancy | aphyr: of course; if is more general |
| 15:28 | aphyr | if/when only clues you in as to whether the *immediate lexical scope* has side effects |
| 15:28 | aphyr | not a very useful distinction in my mind :/ |
| 15:28 | ohpauleez | I think two arg if leads to unintential bugs at times, and I think when is more readable. Implicit do or not |
| 15:28 | danlarkin | ohpauleez +1 |
| 15:29 | danlarkin | I think we won |
| 15:29 | technomancy | pft |
| 15:29 | ohpauleez | haha |
| 15:29 | pjstadig | how is when more readable than a single branch if |
| 15:29 | pjstadig | they're like practically the same thing |
| 15:29 | technomancy | I've never seen a bug come from if; what would be an example of that? |
| 15:29 | pjstadig | except that a when can have side-effects |
| 15:29 | qerub | Hey technomancy! Long time no see. Do you still do any Ruby nowadays? |
| 15:29 | amalloy | technomancy: you probably haven't read the ten thousand SO questions on (defn ! [n] (if (zero? n) 1) (* n (! (dec n)))) |
| 15:30 | mk | the reason you use when instead of if is the same reason for using for ( : ) in java instead of for (int i=0;i...). By using when, you save readers having to decide each time they look at the word whether or not the branch has an else or not. |
| 15:30 | technomancy | amalloy: ok, how about a mistake that someone who actually knows the language would make? |
| 15:30 | technomancy | qerub: whoa; hi. long time. |
| 15:30 | mk | as a convention, neither when nor if guarantee that something will or won't have side effects |
| 15:30 | technomancy | qerub: I'm actually picking back up a bit of ruby for my work at heroku |
| 15:31 | pjstadig | mk: that would be true, except that if can have one or two branches |
| 15:31 | pjstadig | so it's not exactly a single/double branch split |
| 15:31 | xeqi | heh, I use `when` without side effects all over the place for lein's pom generation |
| 15:32 | ohpauleez | technomancy: minimal. But I still think only-true-branching is more readabe as when - especially when you're tracing through code and debugging |
| 15:32 | ohpauleez | for a similar reason stated by mk |
| 15:32 | ohpauleez | haha I'm also amazed at how everyone is jumping in the pit here |
| 15:32 | ohpauleez | :) |
| 15:32 | ohpauleez | That said, I come from CL and Python, so I'm a convert |
| 15:32 | mk | pjstadig: sure, so use when. Then in all cases where readers see your code, they won't wonder. And if they run into an if with one arg, they can change it to a when |
| 15:33 | technomancy | I don't know java, so that example doesn't make sense to me |
| 15:33 | pjstadig | i guess the thing is that "when can have have side-effects" is more objective than "readability" arguments |
| 15:33 | wingy | what do you think about backends-as-a-service such as Parse? |
| 15:34 | pjstadig | if all it boils down to is "readability" then is seems more sensible not to make rules couched in absolute language |
| 15:34 | technomancy | there's nothing more readable about it. it's a two-character token vs a four-character token |
| 15:34 | mk | technomancy: using an iterating construct versus manually iterating over the array yourself. Each time you look at the latter, you have to decide if it's doing the former. |
| 15:34 | ohpauleez | pjstadig: I'll agree with that |
| 15:34 | danlarkin | the way I read "if" is ok here comes a choice of two things |
| 15:34 | danlarkin | and if there aren't two things it messes up my read-flow |
| 15:34 | pjstadig | danlarkin: but that's just not true |
| 15:34 | technomancy | danlarkin: so you're ignoring the fact that it works with one |
| 15:35 | ohpauleez | but does the implicit do really make you feel that strongly about the side-effects. it's not like when is HIDING the side-effect |
| 15:35 | qerub | technomancy: Will it be frustrating to code Ruby again? I'm flirting with Clojure because it isn't a joy to code functionally in Ruby. |
| 15:35 | technomancy | ohpauleez: it turns when into a more specific form |
| 15:35 | technomancy | ohpauleez: if you can use that extra specificity to communicate something to the reader, you should |
| 15:35 | ibdknox | dnolen_: are there thoughts on the changes needed to use the cljs analyzer on JVM Clojure? (i.e. allowing unaliased :require and naked :use) |
| 15:35 | mk | pjstadig: the point is that tons of people aren't even familiar with this convention. You'll have whens without sf, and lone ifs with them. So unless you already know the code, you'll have to verify anyway, so what's the use? |
| 15:35 | pjstadig | technomancy ohpauleez: and objectively so |
| 15:35 | ibdknox | dnolen_: and :import |
| 15:35 | ohpauleez | technomancy: So intent. Sure, I can see that |
| 15:36 | pjstadig | readability is a bit more subjective |
| 15:36 | technomancy | mk: that's why it's good to raise awareness of the convention, because people are confused about it. |
| 15:36 | technomancy | qerub: it's definitely frustrating on the tooling side; things have gotten so much more complicated |
| 15:36 | ohpauleez | so you're objectivity about "side-effects" is really just readability based on intent |
| 15:36 | technomancy | and I don't even have to deal with rvm |
| 15:36 | ohpauleez | You see when and you think "here come the side effects" |
| 15:37 | ohpauleez | danlarkin sees when and he thinks, "he comes the truth" |
| 15:37 | pjstadig | i don't have heart burn over the fact that there's an if somewhere and i should be expecting to see a else clause...and oh no! it's not there! my world is crashing down! as some people seem to think |
| 15:37 | qerub | technomancy: What are you thinking of in particular? Bundler…? |
| 15:37 | technomancy | qerub: yeah, mostly that. I get a lot of bug reports coming from rvm, so even though I don't use it myself I still have to deal with it =\ |
| 15:38 | qerub | technomancy: Oh, right; rvm and company. |
| 15:38 | dnolen_ | ibdknox: related, stuarthallowy has brought up conditional reading ... I'm not sure exactly how the analyzer should be improved to deal w/ full Clojure ... worth figuring out |
| 15:38 | pjstadig | ohpauleez: but when you're talking about someones thoughts you're talking about subjectivity |
| 15:38 | mk | technomancy: I agree that marking sf is useful, but I think that should be marked in the function itself, not by using when to say "here come side effects... trust me" |
| 15:38 | qerub | technomancy: I like what you have done with Leiningen. It's a joy to use. Thanks! |
| 15:38 | dnolen_ | ibdknox: also, ambrosebs has got something as well. |
| 15:38 | technomancy | qerub: also this tendency to just overcomplicate things; I'm working on a test suite that has a define_method inside an instance_eval just to allow for slightly more declarative test definitions, but just causes trouble down the road |
| 15:38 | pjstadig | it is an objective that if cannot have a then clause with a side-effect, unless you use a do |
| 15:38 | technomancy | qerub: thanks |
| 15:38 | ibdknox | dnolen_: his is still using the JVM analyzer though, right? |
| 15:38 | pjstadig | or just use a when with an implicit do |
| 15:39 | qerub | technomancy: Haha, I feel your pain. |
| 15:39 | technomancy | mk: that's a valid desire, but it entails changes to the language itself. I'm talking about working with what we've currently got. |
| 15:40 | ibdknox | dnolen_: yeah, and he's making it look like the CLJS output |
| 15:40 | dnolen_ | ibdknox: perhaps, I haven't looked at it closely. If you want to lead the discussion on this please do, as you really need this stuff, I'll definitely chime in and chip in where I can. |
| 15:40 | ibdknox | dnolen_: k, I'll start up a thread later tonight |
| 15:40 | dnolen_ | ibdknox: standardizing analyzer output, getting column data are two big things. I think column data isn't going to go anywhere without some one spending sometime to write up rationale. |
| 15:41 | ohpauleez | &(if true (println 1)) |
| 15:41 | lazybot | ⇒ 1 nil |
| 15:41 | mk | technomancy: you're right about that, but I still worry about bugs due to trusting a misleading lone if. The convention seems to be there for the sake of efficiency, but ensuring a lack of side-effects in critical places shouldn't be made "efficient" |
| 15:42 | mk | (programmer efficiency) |
| 15:42 | technomancy | "If the value of the if form is important in this situation, then the and construct may be stylistically preferable, depending on the context. If the value is not important, but only the effect, then the when construct may be stylistically preferable." - http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html |
| 15:42 | ohpauleez | I'm fine reading both forms, and personally I think both things when I read `when` |
| 15:42 | ohpauleez | "Only true branch, implicit do" |
| 15:42 | technomancy | mk: seeing an if means you can't infer anything |
| 15:42 | technomancy | because if is more general, and when is more specific |
| 15:43 | mk | technomancy: oh, well in that case you're probably right |
| 15:44 | scgilardi | that's "and" vs "when" and I agree with it |
| 15:44 | technomancy | and is only for return values, when is only for side-effects, if is somewhere in between due to being more general |
| 15:45 | mk | on the other hand, if you mislead some people into fearing sf when there really aren't any by using (when), then not much harm is done |
| 15:45 | pjstadig | "As a matter of style, when is normally used to conditionally produce some side effects, and the value of the when form is normally not used." |
| 15:45 | qerub | Bye for now! |
| 15:45 | pjstadig | ibid. |
| 15:45 | ohpauleez | nice to see scgilardi ringing in :) |
| 15:45 | pjstadig | what clojure needs is an 'unless' macro |
| 15:46 | scgilardi | :) |
| 15:46 | ohpauleez | pjstadig: (the-real-when ...) |
| 15:47 | ohpauleez | to discourage more sideffects |
| 15:47 | technomancy | I think the readability argument only flies if you don't indent properly |
| 15:47 | pjstadig | i always found it confusing the way people used if and unless suffix conditions in ruby |
| 15:47 | pjstadig | especially when the conditions were negative |
| 15:47 | ohpauleez | pjstadig: same |
| 15:48 | pjstadig | something unless !notFooBar |
| 15:48 | technomancy | pjstadig: the one place I can see that making sense is "raise IOError if disconnected" |
| 15:48 | ohpauleez | technomancy: I disagree, but I also have a greater tolerance for when abuse |
| 15:48 | ohpauleez | even for its return values |
| 15:48 | pjstadig | well sure with an if suffix |
| 15:48 | technomancy | because having a non-conditional raise makes absolutely no sense |
| 15:48 | pjstadig | but unless especially with complex conditions with ands and ors is confusing |
| 15:49 | technomancy | agreed |
| 15:49 | pjstadig | i think if suffixes can actually read better sometimes |
| 15:50 | pjstadig | or more naturally |
| 15:50 | uvtc | In Perl, I think `unless` works well for unlikely events: print "things went well, as expected." unless $catastrophe |
| 15:51 | uvtc | Also, Clojure has `if-not` to use if you want `unless` ... (though, there's no implied `do` with `if-not`, fwict) |
| 15:52 | ohpauleez | uvtc: `when-not` |
| 15:52 | Gnosis- | it would be pretty simple to write an 'unless' macro... |
| 15:52 | mk | right, unless is for when you want to make the code seem like it's a normal part of the block, and not a special case |
| 15:52 | uvtc | ohpauleez: Hahah. Missed that. Thanks. :) |
| 15:53 | pjstadig | that's true |
| 15:53 | pjstadig | when-not is basically the 'unless' macro |
| 15:54 | arohner | I use 'when' all the time in non-side-effecting code |
| 15:55 | mk | for similar reasons, in c-syntax languages I end up converting long ifs which trail down to the bottom of a method or loop into if ( not condition) {... return, or break} |
| 15:55 | arohner | but IMO, one-armed ifs should be a syntax error |
| 15:56 | pjstadig | arohner: i would actually support that |
| 15:57 | Raynes | dnolen: There is an open issue for that. |
| 15:57 | pjstadig | let's end all the senseless violence |
| 15:57 | mattmoss | Everytime I see someone address ohpauleez, it sounds in my head like someone sighing, rolling their eyes and saying, "Oh, puh-lease..." |
| 15:57 | ohpauleez | mattmoss: That's the idea :) |
| 15:58 | Raynes | arohner: technomancy hates your guts. |
| 15:58 | ohpauleez | it's how most people address me |
| 15:58 | mattmoss | I am Master of Obviousness. :| |
| 15:58 | aphyr | (if [float? x) (write-float sock x) (write-int sock x)) etc |
| 15:58 | ohpauleez | :) |
| 15:58 | uvtc | pjstadig: Yes. Can't we all just get along ... ... ... and agree to rename `not=` to `!=`. ;) |
| 15:59 | aphyr | While we're at it, rename set! to =! |
| 16:00 | ohpauleez | uvtc: `!` implies stateful change :) |
| 16:00 | mattmoss | (with-perl-noise (=! (!= ...))) |
| 16:03 | uvtc | ohpauleez: interesting way to look at it, even though it's a leading and not a trailing `!`. Semi-related, I'd always thought that the single-quote mark implied quoting, but just yesterday learned of +' |
| 16:04 | uvtc | Any idea why the trailing single quote mark was chosen for that? |
| 16:04 | Bronsa | mathematic notation? |
| 16:04 | Bronsa | f, f', f'' etc |
| 16:04 | uvtc | Ahhhh..... prime. |
| 16:04 | augustl | how do I add Java interop return type metadata when I already have a ^{:private true} metadata there? Normally I use #^TheReturnType |
| 16:04 | uvtc | Heh. Nice. |
| 16:05 | Bronsa | , (let [a'a'a'a' 1] a'a'a'a') |
| 16:05 | clojurebot | 1 |
| 16:05 | Bronsa | :D |
| 16:07 | Gnosis- | that's an acceptable name? |
| 16:08 | uvtc | Gnosis-: acceptable to whom? :) |
| 16:08 | amalloy | if you're tarzan |
| 16:08 | mk | Gnosis-: by the compiler, but maybe not by humans |
| 16:08 | Gnosis- | I meant acceptable to the compiler, haha |
| 16:10 | pjstadig | augustl: ^{:tag TheReturnType :private true} |
| 16:10 | amalloy | pjstadig: or just use both; metadata tags stack iirc |
| 16:10 | mk | Gnosis-: technically any chars are allowed, except for a few reserved ones, and it's not clear what the reserved ones will actually be, so... most are disallowed |
| 16:10 | amalloy | &(meta ' ^String ^:private x) |
| 16:10 | lazybot | ⇒ {:tag String, :private true} |
| 16:11 | augustl | pjstadig: is this documented somewhere? :) |
| 16:11 | aphyr | augustl: seem to recall it's on the java interop page |
| 16:11 | augustl | nothing about #^ on the java interop page |
| 16:11 | Gnosis- | mk: how can they be reserved if the current compiler accepts them without complaining? |
| 16:11 | mk | I don't see any reason that unicode shouldn't already be allowed, since there's little chance that anything reserved by clojure will come from there |
| 16:11 | pjstadig | ,(meta '^String x) |
| 16:11 | clojurebot | {:tag String} |
| 16:12 | augustl | where is the ^foo ^bar meta type syntax documented btw? |
| 16:12 | mk | Gnosis-: :: and // etc. are reserved. +'- and many others are explicitly not reserved. Most symbols will eventually not be reserved. |
| 16:12 | pjstadig | stacking works too |
| 16:12 | pjstadig | ,(meta '^String ^:private x) |
| 16:12 | clojurebot | {:tag String, :private true} |
| 16:12 | mk | Gnosis-: more details http://clojure.org/reader |
| 16:12 | pjstadig | augustl: #^ is deprecated syntax |
| 16:12 | Gnosis- | pjstadig: what does '^ mean? |
| 16:12 | pjstadig | i guess the question is where you read that :) |
| 16:13 | augustl | pjstadig: ah |
| 16:13 | augustl | I should read the entire doc some day.. |
| 16:13 | augustl | no idea what # actually is :) |
| 16:13 | Gnosis- | mk: ah, thanks |
| 16:14 | pjstadig | Gnosis-: ' just means quote the next that is coming and in this case the next thing happens to be a type tag and you don't need a space after the quote |
| 16:14 | pjstadig | ,(meta ' ^String ^:private x) |
| 16:14 | clojurebot | {:tag String, :private true} |
| 16:14 | pjstadig | adding a space works too |
| 16:14 | pjstadig | or |
| 16:14 | pjstadig | ,(meta (quote ^String ^:private x)) |
| 16:14 | clojurebot | {:tag String, :private true} |
| 16:14 | uvtc | Bronsa: Gnosis- : now that you mention it, what's the opinion on using a single-quote/apostrophe in symbols, like `ted's-room` or `it's-looking-good`? |
| 16:14 | pjstadig | which is kinda what it becomes |
| 16:14 | pjstadig | ,''^String ^:private x |
| 16:14 | clojurebot | (quote x) |
| 16:14 | augustl | I suppose this is a symptom of reading code instead of reading docs to figure out how stuff works |
| 16:15 | uvtc | ,(let [it's-looking-good true] (when it's-looking-good (println "happy day"))) |
| 16:15 | clojurebot | happy day |
| 16:15 | pjstadig | ITYM, 'if' :) |
| 16:15 | mk | the various special symbols are there for lazy programmers. Instead of always having to type and look at (deref a), we can write @a, and the reader replaces it |
| 16:18 | tufflax | I want to implement my own data structure that shall support conj and pop. I'm using defrecord and I must specify which interface/protocol I'm implementing. So which protocol/interface supports conj and pop? Seq? Is that the name I'm looking for? |
| 16:23 | mk | tufflax: https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang probably ipersistentcollection or something |
| 16:25 | tufflax | mk thanks |
| 16:28 | technomancy | is it just me, or is it ironic that the clojure source uses "jvm" for its java code despite repeated insistence that the JVM and Java are not the same thing? |
| 16:28 | technomancy | I mean, I understand it's a hold-over from when the clr implementation was kept in the source tree, but I'm still amused by it |
| 16:29 | pjstadig | technomancy: just rename it...patches welcome |
| 16:29 | mk | maybe "stuff for targetting the jvm"? |
| 16:29 | gfredericks | s/clojure/lava/ while you're at it |
| 16:29 | pjstadig | haha |
| 16:29 | pjstadig | personally i think Sybilant is a better name than Clojure |
| 16:29 | pjstadig | but who am i to say |
| 16:30 | hiredman | lava is really hot right now |
| 16:30 | Raynes | technomancy: You'll be sorry when they start adding scala source code. |
| 16:31 | technomancy | Raynes: someone is actually using lein-scalac to avoid sbt |
| 16:31 | mk | are agents guaranteed to execute things in order of sending? |
| 16:31 | technomancy | makes me happy |
| 16:32 | pjstadig | mk: for the 'things' sent from the same thread, yes |
| 16:33 | llasram | maybe best to say that agents execute things in the order received? :-) |
| 16:33 | mk | llasram: perhaps, though a send and receive is presumably the same thing :) |
| 16:34 | mk | pjstadig: will things sent from different threads be queued out of order? |
| 16:35 | llasram | If that's your definition, then definitely yes -- the purpose of agents is to serialize asynchronous updates to a identity |
| 16:37 | mk | llasram: ok, good. I was thinking that the spec might have left open that the actions are placed in a set rather than a queue, or that one might create an agent with a priority queue |
| 16:37 | mk | I guess that can't be done |
| 16:37 | acheng | ,(let [a 1] (eval (read-string "a"))) |
| 16:37 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 16:38 | acheng | "Unable to resolve symbol: a in this context" |
| 16:38 | tufflax | Hm, IPersistentCollection specifies that cons is part of the interface but not conj, what's up with that? |
| 16:39 | tufflax | I don't see any interface mentioning conj |
| 16:39 | llasram | mk: Ah, not that I'm aware of. You'd probably need to create your own new reference type to support that sort of thing |
| 16:41 | gtrak` | mk: that kind of goes against the state-change aspect of an agent, yea? sounds like you just need the worker pool part |
| 16:41 | llasram | To the `future`! |
| 16:42 | mattmoss | ,(class 'a) |
| 16:42 | clojurebot | clojure.lang.Symbol |
| 16:42 | mk | acheng: interesting - same thing for ,(let [a 1] (eval 'user/a)) I'm not sure why that happens |
| 16:42 | mattmoss | ,(class #'a) |
| 16:42 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: a in this context, compiling:(NO_SOURCE_PATH:0)> |
| 16:42 | mattmoss | ,(let [a "a"] (class #'a)) |
| 16:42 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: a in this context, compiling:(NO_SOURCE_PATH:0)> |
| 16:42 | mattmoss | Hmm. |
| 16:42 | dnolen | tufflax: the names in Clojure don't always reflect the names used for the Java Interfaces - look at RT.java. fwiw, the naming between fns & protocols is more consistent in ClojureScript. |
| 16:43 | gfredericks | mattmoss: ##(class #'clojure.core/nth) |
| 16:43 | lazybot | ⇒ clojure.lang.Var |
| 16:44 | tufflax | dnolen so my original problem: what should I put as interface in my defrecord when implementing conj? |
| 16:44 | mk | gtrak`: well, one might want a construct that doesn't care about the order of incoming actions, but does care about preserving state. This is different from a worker pool |
| 16:44 | mattmoss | thanks, g |
| 16:44 | dnolen | tufflax: whatever is in IPersistentCollection - cons + whatever else. |
| 16:45 | dnolen | I mean cons + whatever that interface defines |
| 16:46 | amalloy | tufflax: you can't have a special impl of conj in a defrecord, only a deftype, afaik |
| 16:46 | tufflax | dnolen I think you misunderstood me. When I'm implementing a function in a record, I must state the interface. |
| 16:47 | gtrak` | mk: yea, looks like agents don't guarantee execution order either |
| 16:47 | tufflax | amalloy hm why not? |
| 16:47 | dnolen | tufflax: in records you can implement methods on interfaces, and fns on protocols. |
| 16:47 | dnolen | tufflax: and amalloy is right. |
| 16:47 | amalloy | because records are maps. defrecord comes with implementations of all the map interfaces, including conj |
| 16:47 | dnolen | tufflax: you're not allowed to customize the map behavior of records |
| 16:48 | acheng | hm... if i have a value and a string, is it possible to let-bind the value to a variable named in the string, and then eval the string? |
| 16:48 | tufflax | oh i see |
| 16:48 | mattmoss | If I do (defn foo [] ...) and (def f #'foo) ... both (f) and (@f) both work. Why? Is it an implicit deref without the @ ? |
| 16:48 | Bronsa | vars are implicitly dereffed |
| 16:48 | tufflax | Ok then. Say I' |
| 16:48 | tufflax | ops, pressed enter too early :p |
| 16:49 | Bronsa | (during function call) |
| 16:49 | tufflax | Ok then. Say I'm using deftype, what interface should I state as the interface I'm implementing when I'm defining conj? |
| 16:49 | mk | gfredericks: regarding varless symbols, mapped directly to values without an intermediary var, I think part of the problem is that you would no longer have an explicit construct for safely working with concurrency, like (alter-var-root) |
| 16:49 | mattmoss | Bronsa: thanks |
| 16:50 | gfredericks | mk: alter-var-root is for NOT working safely with concurrency |
| 16:50 | mk | gtrak`: interesting - do you have a link to where it talks about that? (agent execution order) |
| 16:51 | gfredericks | I thought all sends from the same thread should execute in the same order |
| 16:51 | mk | gfredericks: in that case you could just use def, no? alter-var-root has a potential verification function attached |
| 16:51 | Bronsa | mattmoss: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Var.java#L391-412 |
| 16:52 | acheng | mk: ya, alter-var-root is heavy-handed to the max. i found the only valid use case. it's all mine |
| 16:52 | gtrak` | mk: I was looking at this: http://stackoverflow.com/questions/5669084/is-clojures-send-asynchronous |
| 16:52 | gfredericks | mk: you could still do changes atomically; namespaces as a whole could be implemented as atoms |
| 16:53 | mk | gfredericks: if that's the case for the same thread, then why not for other threads? Don't they all use the same queue? |
| 16:53 | pepijndevos | why do zippers use metadata instead of a protocol? |
| 16:53 | tufflax | dnolen amalloy: What should I put in my deftype instead of some-interface? (deftype MyDataStructure [data] some-interface (conj [this element] ...)) |
| 16:54 | gfredericks | mk: I don't know why that wouldn't be the case; it's just non-deterministic when things happen more or less at the same time |
| 16:54 | mk | gfredericks: I think you're correct, and I think that I like the idea of namespaces as atoms substantially more than what we have now. I think it might be much easier to understand and think about. |
| 16:55 | Bronsa | tufflax: you should put clojure.lang.IPersistentCollection, and replace conj with cons |
| 16:56 | tufflax | Bronsa ok. Will I be able to use conj then or just cons? |
| 16:56 | Bronsa | cons of clojure.core has nothing to do with cons on the IPersistentCollection interface |
| 16:56 | mk | gfredericks: well... things can happen more or less "at the same time" in the same thread. Shouldn't change for extra threads, if a proper concurrent queue is used... |
| 16:56 | gfredericks | how do things happen at the same time in the same thread? |
| 16:56 | tufflax | bronsa ok |
| 16:57 | tufflax | So how does cons become conj then? |
| 16:57 | gfredericks | the source of conj calls RT.cons I think |
| 16:57 | gfredericks | or RT.conj calls #cons |
| 16:57 | tufflax | ah ok |
| 16:57 | mk | is there any reason that namespace maps weren't implemented as atoms? |
| 16:57 | pandeiro | does cljs not have clj->js anymore??? |
| 16:57 | lazybot | pandeiro: Yes, 100% for sure. |
| 16:57 | Bronsa | yes |
| 16:58 | gfredericks | mk: atoms didn't exist initially |
| 16:58 | tufflax | thanks for clearing that up |
| 16:58 | Bronsa | RT.conj calls #cons |
| 16:58 | mk | gfredericks: how do they happen at the same time in different threads, assuming we've got a concurrent queue? |
| 16:58 | gfredericks | mk: I mean the sends are done at the same time; obviously they go into the queue in some order but it's hard to say anything interesting about it |
| 16:59 | pandeiro | ah oops, i am a moron, sorry |
| 16:59 | pandeiro | i was wanting js->clj |
| 17:00 | mk | gfredericks: right. But if we have that guarantee, then logging agents become much more useful, to take one example |
| 17:02 | mk | and if we don't have that guarantee, then priority queues can be added to agents |
| 17:05 | tufflax | If anyone have the time, please take a look at this longish question http://pastebin.com/iHGwgf6i |
| 17:06 | kaoD_ | hi |
| 17:06 | tufflax | hi |
| 17:06 | kaoD_ | do multimethods support overloading by arity? |
| 17:06 | hiredman | multimethods support everything |
| 17:06 | kaoD_ | (through overloaded dispatch fn, of course) |
| 17:06 | kaoD_ | hiredman: that's good news then, I was afraid arity was fixed |
| 17:07 | tufflax | has* :P |
| 17:12 | kaoD_ | tufflax: has? |
| 17:15 | tufflax | correction of my previous message |
| 17:16 | kaoD_ | oh, I thought you were correcting me :P |
| 17:20 | mk | the reason agents don't guarantee ordering except in a single thread is that sends are only queued in the agent's queue at the end of a transaction, not at the actual logical time that the send occurs |
| 17:27 | cmajor7 | does korma (transaction …) rollback on the exception? |
| 17:29 | pandeiro | how could i do the Array.prototype.slice.call(someArrayLikeObject, 0) trick with cljs? syntax? |
| 17:30 | pandeiro | nm, got it: (.call js/Array.prototype.slice thatArrayLikeObj 0) |
| 17:31 | cmajor7 | I would think it does: http://dev.clojure.org/jira/browse/JDBC-11 but I am not sure whether I can use a "is-rollback?" to detect that.. |
| 17:40 | kaoD_ | is there any way to slurp stdin until EOF? |
| 17:41 | kaoD_ | slurp itself seems to stay there waiting for more input (or maybe it's windows' fault) |
| 17:45 | mk | (def foo) is equivalent to (intern *ns* foo) ? |
| 17:46 | S11001001 | kaoD_: yep it's windows's fault; how are you sending eof? |
| 17:47 | kaoD_ | S11001001: not sending EOF, I expected Windows to append EOF after piping from an echo |
| 17:47 | kaoD_ | though I'm probably wrong |
| 17:48 | S11001001 | who really knows; it's windows |
| 17:51 | goodieboy | technomancy: hey, i'm thinking about writing a leiningen plugin. Are there directions somewhere to do it properly for the latest leiningen? |
| 17:53 | goodieboy | ok, i think this must be the place to look: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 17:53 | kaoD_ | goodieboy: I was just going to point you there |
| 17:53 | technomancy | yup |
| 17:53 | kaoD_ | it's unbelievably easy |
| 17:54 | goodieboy | kaoD_: good to know :) |
| 17:54 | goodieboy | thanks |
| 17:55 | emezeske | Once you know about technomancy, though, it becomes believably easy |
| 17:55 | Raynes | goodieboy: https://github.com/Raynes/lein-tag Here is a very simple example you can look at too. |
| 17:55 | goodieboy | Raynes: awesome thanks |
| 17:56 | cgray | technomancy: is writing a lein plugin for any jvm-based language essentially the same difficulty? |
| 17:58 | technomancy | cgray: for any compiler that has an ant task (which hopefully should be all of them), yes |
| 17:59 | cgray | technomancy: ok, good to know, then I've gotta write an ant task first :) |
| 17:59 | Raynes | technomancy: I thought we didn't use ant these days? |
| 17:59 | technomancy | Raynes: not for any of the core stuff |
| 17:59 | technomancy | Raynes: but lein-scalac uses it |
| 18:00 | Raynes | cgray: Did you invent a JVM language? |
| 18:00 | cgray | Raynes: I didn't but there is one being invented at my work |
| 18:00 | Raynes | technomancy: You should use uncle. |
| 18:00 | technomancy | har har |
| 18:00 | Raynes | cgray: Make them stop. |
| 18:01 | Raynes | technomancy: https://github.com/flatland/uncle |
| 18:01 | Raynes | technomancy: I was serious. |
| 18:01 | technomancy | oh |
| 18:01 | technomancy | lancet is a bit weird |
| 18:01 | technomancy | but I don't have any plans to develop lein-scalac further, so whatevs |
| 18:02 | Raynes | Dude. You should totally turn lein into a complete Scala sy… oh, wait. I guess that's all there is to it, really. Just compiling Scala. |
| 18:02 | Raynes | It's cool how little is necessary to make Leiningen an <insert jvm lang here> build tool. |
| 18:03 | technomancy | well the problem with scala specifically is the compiler is so slow that everyone ends up using the incremental compiler, and that's not hooked up to lein |
| 18:03 | technomancy | but it's not my problem =) |
| 18:03 | Raynes | technomancy: You're a pretty cool chap. |
| 18:04 | eggsby | Raynes: I had to leave the office before I got a chance to thank you last friday -- Thank you! |
| 18:04 | Raynes | eggsby: What did I do? |
| 18:05 | eggsby | hmm, LA clojure meetup about cljs... wonder if I should go |
| 18:05 | Raynes | Besides my normal awesome level which doesn't necessitate thank yous. |
| 18:05 | eggsby | Raynes: fixed a retarded thing I did w/ refheap :p |
| 18:06 | Raynes | Oh. |
| 18:06 | Raynes | Oh, right. Forgot about that. |
| 18:06 | Raynes | You're lucky refheap has terrible traffic. :p |
| 18:30 | muhoo | what's the trick for debugging lein2 plugins? how does one get an in-lein repl to interactively work with the plugin? |
| 18:30 | muhoo | i.e. not the project, but lein itself. |
| 18:30 | technomancy | muhoo: if you have :eval-in :leiningen in project.clj, then `lein repl` in the plugin project will put you in the right place |
| 18:31 | muhoo | fantastic, thanks! |
| 18:32 | technomancy | huh; I realized I added shorthand for forcing a repl to eval-in lein without changing the project.clj in lein1 |
| 18:32 | technomancy | oh, but you can do it with lein-assoc in 2.x |
| 18:33 | muhoo | whut? |
| 18:33 | technomancy | `lein assoc :eval-in :leiningen repl` |
| 18:33 | technomancy | it's a plugin that gives you a higher-order assoc task |
| 18:33 | llasram | Ooooh |
| 18:33 | technomancy | you can add arbitrary project.clj keys on the command line |
| 18:33 | llasram | Now *that* is fancy |
| 18:33 | muhoo | oh https://github.com/technomancy/lein-assoc |
| 18:33 | technomancy | =D |
| 18:34 | muhoo | there is so much fancy stuff in lein these days. it's kind of disorienting |
| 18:34 | technomancy | tempted to merge that into lein proper |
| 18:34 | technomancy | muhoo: higher-order tasks open up a lot of possibilities |
| 18:34 | muhoo | ya, i was stunned by how quickly raynes put together lein-pdo. |
| 18:35 | Raynes | muhoo: I was stunned at how long it took me, actually. |
| 18:35 | Raynes | It was harder than I thought it'd be. |
| 18:35 | technomancy | there's always https://github.com/technomancy/leiningen/wiki/Plugins |
| 18:35 | technomancy | but it's not exhaustive |
| 18:35 | technomancy | for instance, Raynes forgot to add lein-pdo = |
| 18:35 | technomancy | ) |
| 18:36 | mk | how are symbols resolved? As far as I can tell, there's a special map from symbols to vars in each namespace. But is there some sort of secondary map for aliases, and requires? Are aliased symbols added to this map? Is there a separate map for vars that have been set to private? |
| 18:37 | technomancy | ,(take 10 (ns-map *ns*)) |
| 18:37 | clojurebot | ([sorted-map #'clojure.core/sorted-map] [read-line #'clojure.core/read-line] [re-pattern #'clojure.core/re-pattern] [keyword? #'clojure.core/keyword?] [unchecked-inc-int #'clojure.core/unchecked-inc-int] ...) |
| 18:38 | technomancy | not sure if that includes aliases |
| 18:38 | technomancy | oh, there's a separate ns-aliases |
| 18:38 | mk | does that mean there's a second map, or is it just a filter? |
| 18:39 | technomancy | pretty sure it's a separate map |
| 18:39 | technomancy | since an alias by itself isn't a first-class thing afaik |
| 18:41 | mk | hmm. When the reader hits a symbol (it is the reader that does this, right?), how many and which maps does it check before finding the var that it will assign inside the form? (it assigns the var, and not e.g. a fully qualified symbol, correct?) |
| 18:42 | mk | presumably for fully qualified symbols, the answer is two maps: the global map of namespaces containing the namespace, and then the namespace itself (which is a map) for the name |
| 18:43 | wingy | could someone provide datomic hosting? |
| 18:44 | muhoo | heh, (pprint (ns-map *ns*)) caused java to go to 99% cpu and nrepl to lock up |
| 18:45 | muhoo | *nrepl-connection* up to 38644 lines |
| 18:45 | mk | ,(ns-map 'doesntexist) |
| 18:45 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.Exception: No namespace: doesntexist found> |
| 18:46 | mk | ,(in-ns 'extant) |
| 18:46 | clojurebot | #<Namespace extant> |
| 18:46 | mk | ,*ns* |
| 18:46 | clojurebot | #<Namespace sandbox> |
| 18:46 | muhoo | C-x C-k, problem solved |
| 18:46 | mk | ,(in-ns 'extant) (ns-map 'extant) |
| 18:46 | clojurebot | #<Namespace extant> |
| 18:47 | mk | ,(do (in-ns 'extant) (ns-map 'extant)) |
| 18:47 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ns-map in this context, compiling:(NO_SOURCE_PATH:0)> |
| 18:47 | mk | ,(do (create-ns 'extant) (ns-map 'extant)) |
| 18:47 | clojurebot | {ProcessBuilder java.lang.ProcessBuilder, Enum java.lang.Enum, SuppressWarnings java.lang.SuppressWarnings, Throwable java.lang.Throwable, InterruptedException java.lang.InterruptedException, ...} |
| 18:48 | amalloy | mk: do you not own a repl? |
| 18:49 | TimMc | amalloy: Don't make fun of the poor! |
| 18:49 | mk | amalloy: publicly checking how the bot handles namespaces |
| 18:50 | muhoo | wow, soon there will be more lein plugins than there are apps in the apple app store. |
| 18:50 | mk | ...and making a mistake or two |
| 18:51 | muhoo | and yet, rhickey uses ant :-/ |
| 18:52 | Frozenlo` | o_O |
| 18:53 | muhoo | nice, a way to use heroku without having to deal with ruby: https://github.com/technomancy/lein-heroku |
| 18:53 | Frozenlo` | Any recommendation regarding tests plugins? |
| 18:53 | technomancy | muhoo: keep in mind that's very unofficial =) |
| 18:53 | Raynes | I didn't find dealing with Ruby much of an issue. |
| 18:54 | technomancy | yeah, actually you don't even need to have rubygems installed anymore |
| 18:58 | kaoD_ | is there any way to slurp piped stdin in windows and not wait forever for more input? |
| 19:02 | technomancy | kaoD_: on unix EOF results in a nil return value from read-line iirc |
| 19:02 | technomancy | not sure about slurp |
| 19:03 | kaoD_ | technomancy: I'm interested in stdin as a whole, not line by line... I know I can fake it but it just feels hacky |
| 19:03 | technomancy | yeah, but you could try it and see if it has the same problem |
| 19:03 | kaoD_ | you're right, I'll try |
| 19:25 | amalloy | is there a clever way to take from a sequence up to, and including, the first item that satisfies a predicate? i think i've written that function before, but not well |
| 19:30 | mk | amalloy: source for take-while http://clojuredocs.org/clojure_core/clojure.core/take-while |
| 19:32 | metellus | amalloy: the best I can find is split-with or partition-by and then grabbing the first element from the second seq |
| 19:34 | gfredericks | amalloy: if nothing satisfies it returns the original? |
| 19:34 | amalloy | gfredericks: yeah, that's the plan |
| 19:34 | mk | in that source I linked, put the cons in front of the when |
| 19:35 | gfredericks | (fn f [pred coll] (if (empty? coll) coll (let [[x & xs] coll] (if (pred x) [x] (cons x (lazy-seq (f pred xs))))))) |
| 19:36 | amalloy | gfredericks: never use [x & xs] destructuring when consuming/producing a lazy seq, btw |
| 19:36 | amalloy | & xs uses next, not rest |
| 19:36 | gfredericks | amalloy: now I know |
| 19:37 | amalloy | i'm always tempted, and usually remember not to |
| 19:38 | gfredericks | amalloy: using core.logic for a while made writing that ^ code feel really weird |
| 19:41 | mk | (defn take-while' [pred coll] (lazy-seq (when-let [s (seq coll)] (cons (first s) (when (pred (first s)) (take-while' pred (rest s))))))) |
| 19:41 | mk | seems to work, and mimics take-while |
| 19:42 | gfredericks | maybe name it take-until |
| 19:43 | kaoD_ | I'm having a hard time realizing when to use macros or when to stick with code... (which probably means I don't understand the subject enough) any quick tips/references? |
| 19:43 | mk | or take-along (...the non-matching value) |
| 19:43 | rbxbx | kaoD_ avoid macros until it's no longer feasible to do otherwise. |
| 19:45 | rbxbx | kaoD_ they're a sharp (and valuable) tool which one should exercise caution in using. As to learning when it's no longer feasible to do otherwise... I guess that just comes with experience? |
| 19:45 | kaoD_ | rbxbx: that's what I suspected |
| 19:45 | kaoD_ | thanks |
| 19:45 | technomancy | the best way to learn is to try to consume a codebase that uses too many macros |
| 19:46 | kaoD_ | technomancy: what do you mean consume? |
| 19:46 | mk | kaoD_: you don't need to worry that you're missing out on the magic of lisp if you're not spending time defining macros. Clojure has many constructs that set it apart as a much higher-level language, and macros are only a minor part of all that |
| 19:46 | technomancy | kaoD_: I mean use it as a library or something |
| 19:46 | rbxbx | kaoD_ better yet try to fix a bug in the project's issue-tracker :) |
| 19:47 | kaoD_ | technomancy: oh, as in "product consumer" |
| 19:47 | kaoD_ | been there |
| 19:47 | kaoD_ | (many times with my own macros, haha) |
| 19:48 | kaoD_ | thanks for the insight |
| 19:48 | technomancy | I guess the key is you need to try to use the macros in ways that the original author didn't intend |
| 19:50 | emezeske | technomancy: One of the biggest gripes I have with macro-heavy libraries is that they basically force the user to write macros to deal with them |
| 19:50 | emezeske | technomancy: E.g. if you have repetition in your use of a macro that you'd like to factor out, you have to write a macro |
| 19:51 | technomancy | heh; yeah, infectious macros |
| 19:51 | emezeske | exactly |
| 19:51 | kaoD_ | and then... why macros? I mean, in which case are they useful? it all comes down to experience or is there any sort of pattern/well-suited task for macros? |
| 19:52 | arohner | in core.logic, if I have a logic variable that is a map, how do I write the expression "(== 3 (:foo q))"? |
| 19:52 | arohner | I tried the naive way and I'm getting NPE |
| 19:53 | technomancy | kaoD_: usually if you write a macro you should do it after writing the macroless way first |
| 19:53 | amalloy | arohner: i don't think that's possible yet. as of recently it wasn't, anyway |
| 19:53 | technomancy | so people can pick which way is appropriate for their circumstances; maybe they don't care about composability and want the extra convenience |
| 19:54 | kaoD_ | technomancy: ugh, that means double mainteinance |
| 19:54 | benedikt | I'm using lein and emacs (+ clojure-mode) for clojure. starting the swank server with "M-x clojure-jack-in" makes it bind to 0.0.0.0. I want to bind to localhost. |
| 19:54 | arohner | amalloy: really? seems like it should be possible to build a fn that does that, even if it isn't built in |
| 19:54 | benedikt | I ws discussing this here the other day but I never managed to change the bind address. |
| 19:54 | technomancy | kaoD_: not really, the macro version needs the function version to exist anyway |
| 19:54 | amalloy | kaoD_: wat. write the macro to use the function |
| 19:55 | kaoD_ | lol, so obvious |
| 19:55 | benedikt | technomancy: i belive you said that this is no longer the default behavior, but this is the default behavoir with the current lein. |
| 19:55 | amalloy | arohner: it needs hooks into the unification code |
| 19:55 | technomancy | benedikt: the version of lein is immaterial; it's the version of lein-swank that matters |
| 19:55 | technomancy | but you might want to try https://github.com/kingtim/nrepl.el instead |
| 19:56 | benedikt | technomancy: right. so lein is using an outdeted version of swank? |
| 19:56 | hyPiRion | You should keep the amount of macros to a minimum though, they're not first class citizens. |
| 19:56 | technomancy | benedikt: right |
| 19:56 | benedikt | technomancy: one might argue this is an issue. |
| 19:57 | benedikt | technomancy: thanks for the link, this seems useful. |
| 19:57 | technomancy | if you have a solution for how to retroactively fix old versions I would be glad to hear it =) |
| 19:57 | benedikt | technomancy: actually, i'm working on this time machine... |
| 19:57 | technomancy | sweeeet |
| 19:58 | benedikt | so if one uses this nrepl.el, one isn't dependent on lein any more? |
| 19:59 | benedikt | scratch that |
| 19:59 | technomancy | no, you still need lein, but you don't need any lein plugins |
| 19:59 | benedikt | as long as it doesn't listen to 0.0.0.0 i'm happy. |
| 20:04 | arohner | amalloy: looks like (pred) works, as a worst case |
| 20:04 | arohner | (logic/pred q #(= 3 (:foo %))) |
| 20:04 | arohner | what does "non-relational" mean, in a core.logic docstring? |
| 20:05 | amalloy | it's not a two-way function |
| 20:05 | amalloy | you can't, eg, use that pred to *build* the map {:foo 3}, only to check that it fits after someone else has built it |
| 20:06 | arohner | ah, right |
| 20:11 | benedikt | technomancy: this one also seems to listen to 0.0.0.0 |
| 20:14 | technomancy | ugh; crap |
| 20:14 | technomancy | Raynes: what the heck, man? |
| 20:14 | arohner | more stupid core.logic questions. How can I write "q is not a member of [x y z]"? |
| 20:15 | gfredericks | arohner: "not" is not very natural |
| 20:15 | gfredericks | but you can definitely say (!= q x) (!= q y) (!= q z) |
| 20:16 | benedikt | technomancy: i'm leaning towards using iptables --- but thats not really a fix for the problem. Personally, I think this is the wrong default, and a dangerous one. |
| 20:17 | technomancy | benedikt: it definitely is. it was fixed years ago in swank, but I've only started using `lein repl` a couple weeks ago, so I didn't notice. |
| 20:17 | technomancy | working on a fix |
| 20:17 | benedikt | so lein uses a version of swank that is outdated by years? |
| 20:17 | arohner | gfredericks: thanks |
| 20:18 | technomancy | no, lein uses whatever version of swank you tell it to |
| 20:18 | benedikt | the is a messy swamp of tools. then why am *I* using an outdated swank version? |
| 20:18 | benedikt | and what baout nrepl.el |
| 20:19 | technomancy | nrepl.el is just using the built-in `lein repl` task, which I'm fixing right now |
| 20:19 | technomancy | I don't know how you installed lein-swank, so it's hard to say anything about that |
| 20:19 | benedikt | technomancy: "lein self-install" |
| 20:20 | technomancy | that doesn't install lein-swank |
| 20:20 | benedikt | .. |
| 20:20 | benedikt | then I dont know either! |
| 20:20 | technomancy | you would have had to either put it in your user profile, a project.clj, or run `lein plugin install` |
| 20:20 | benedikt | most likely lein plugin install |
| 20:21 | technomancy | though that would only work for lein 1.x |
| 20:21 | technomancy | if you're using 2.x, check ~/.lein/profiles.clj |
| 20:21 | benedikt | i am |
| 20:22 | benedikt | [lein-swank "1.4.3"] |
| 20:23 | technomancy | so does just regular `lein swank` start on localhost or 0.0.0.0? |
| 20:23 | technomancy | maybe it's specific to the elisp launcher? |
| 20:23 | mk | the namespace can map directly to classes without first putting them in a var? |
| 20:24 | technomancy | hm; actually that's not right; jack-in is hard-coded to localhost |
| 20:25 | benedikt | yes and no. |
| 20:25 | benedikt | it opens 33804 on * and 4005 on localhost |
| 20:25 | benedikt | "Listening for transport dt_socket at address: 33804. \n Connection opened on localhost port 4005" |
| 20:25 | technomancy | oh, ok... that is cdt then |
| 20:26 | technomancy | I have no idea what's going on with that code =( |
| 20:26 | technomancy | lemme see if it's easy to disable |
| 20:26 | benedikt | why is that listening on all interaces? |
| 20:26 | benedikt | interfaces* |
| 20:26 | benedikt | (cdt, that is) |
| 20:27 | technomancy | I'm sure it's just an oversight |
| 20:27 | benedikt | sounds like a bug :) |
| 20:27 | technomancy | definitely |
| 20:27 | technomancy | I got all the cdt support submitted as a big pull request without any real explanation of how it works =( |
| 20:27 | benedikt | I have to leave now, i'll happily continue when i get back |
| 20:28 | mk | where is the clojure code that resolves a var by looking things up in the namespace? |
| 20:28 | technomancy | ok, you should be able to disable it by putting :swank-cdt false in project.clj |
| 20:28 | technomancy | or in your user profile |
| 20:28 | casion | how would one evaluate something like '(+ 1 2) |
| 20:28 | benedikt | technomancy: is my user profile ~/.leun/profiles.clj? |
| 20:29 | technomancy | benedikt: yeah, under the :user section of the map |
| 20:29 | mk | ,(eval '(+ 1 2)) ;? |
| 20:29 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 20:29 | technomancy | benedikt: thanks for catching this and the repl issue |
| 20:30 | adu | ,(first [1 2 3]) |
| 20:30 | clojurebot | 1 |
| 20:30 | casion | mk: thank you |
| 20:30 | adu | ,(first '(1 2 3)) |
| 20:30 | clojurebot | 1 |
| 20:31 | paxan | Has anybody been able to run JUnit tests via lein successfully? I am trying lein-junit, but I must be missing some important tip in its documentation regarding how to make it work. It simply succeeds very quietly with zero regard for failing tests |
| 20:31 | benedikt | technomancy: :) |
| 20:32 | adu | paxan: there should be a test for that |
| 20:32 | paxan | adu, got that plugin's src cloned. It passes its own tests :) |
| 20:33 | adu | :) |
| 20:38 | technomancy | benedikt: just pushed a fix to make the repl task bind to localhost only by default |
| 20:40 | Raynes | technomancy: What did I do? |
| 20:40 | technomancy | Raynes: benedikt just pointed out that `lein repl` listens on 0.0.0.0 by default |
| 20:41 | Raynes | Pretty sure I didn't have anything to do with anything related to that, technomancy. |
| 20:41 | technomancy | well I had to blame someone |
| 20:43 | amalloy | technomancy: it's my fault: i heard someone complain about it and was like "whoa that's awful" instead of "technomancy: ^ awful" |
| 20:48 | technomancy | hah |
| 20:49 | technomancy | it could be cemerick's fault since that's what nrepl defaults to, but arguably in the context of nrepl-as-a-library it's a decent default |
| 20:55 | xeqi | technomancy: what did you use to record your clojure screencast? |
| 21:01 | guns | Hello, I am trying to determine if Unicode characters are explicitly valid in symbols. LispReader.java is very liberal, but clojure.org/reader says "alphanumeric" |
| 21:01 | guns | Does this mean [A-Za-z0-9] or POSIX [:alnum:]? |
| 21:05 | guns | Further confusing the issue is that Clojure 1.3+ allows ' in symbols |
| 21:08 | mk | ,(defn ↬ [a] a) |
| 21:08 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 21:08 | gfredericks | ,(let [↬ :foo] ↬) |
| 21:08 | clojurebot | :foo |
| 21:08 | guns | mk: the actual pattern for symbols is "[:]?([\D&&[^/]].*/)?([\D&&[^/]][^/]*)" |
| 21:09 | guns | But that includes quite a bit more than "alphanumeric" |
| 21:09 | mk | guns: the only reason any characters would be prohibited is because clojure reserves them |
| 21:10 | guns | I've been freely using Unicode in my personal Clojure code, but someone mentioned that it is not part of the spec |
| 21:10 | guns | from clojure.org/reader: "(other characters will be allowed eventually, but not all macro characters have been determined)" |
| 21:10 | gfredericks | I can't imagine there being non-ascii macro characters |
| 21:11 | gfredericks | maybe because I have no imagination |
| 21:11 | mk | or because it might reserve them in the future. Since I doubt that ↬ and the rest would ever be reserved by clojure, I really don't see why they would be prohibited even now |
| 21:11 | guns | Well, I'm happy with the status quo |
| 21:11 | gfredericks | #+ and #- might be coming |
| 21:11 | guns | just having a discussion about whether it's "legal" clojure code |
| 21:11 | mk | it's nice to see that they aren't, when it comes to code |
| 21:12 | mk | if someone knows a good reason not to use unicode now and assume that it won't be prohibited, I'd love to hear it |
| 21:13 | guns | Even ASCII symbols like as->zs are commonly used, but don't adhere to the published definition |
| 21:14 | gfredericks | -> is used in clojure itself |
| 21:14 | amalloy | mk: the main reason would be portability of your source files. if you save a file as UTF-8 (say), and someone reads it as if it were Latin-1 (say), you might have issues if one of your multi-byte characters contains a 0x20 |
| 21:15 | amalloy | i think the clojure reader always reads files as UTF-8 now, but that's just an implementation detail; no promises about the character encoding |
| 21:15 | guns | I guess if we just continue to use Unicode, clojure/core will be forced to support it indefinitely |
| 21:15 | guns | :) |
| 21:16 | mk | it's strange that > isn't listed among the permitted symbols in http://clojure.org/reader |
| 21:16 | gfredericks | those docs aren't very maintained |
| 21:17 | gfredericks | somebody was complaining about it not mentioning \' the other day |
| 21:17 | mk | I think the main problem is people saving their files in non-utf8... I don't have much sympathy for that |
| 21:21 | mk | guns: what are you using unicode for? I've always wanted to replace -> with →, but I'm not sure that'd go over well |
| 21:22 | guns | mk: λ α β Σ, and so on for concision. |
| 21:22 | gfredericks | how do those get munged? |
| 21:23 | guns | I wouldn't do it in a team environment, but for myself, I have a very nice multibyte input setup |
| 21:23 | guns | gfredericks: what do you mean? in the clojure symbol table? |
| 21:23 | gfredericks | no in class names and other java things |
| 21:24 | gfredericks | &((fn λ [] (fn [] :no))) |
| 21:24 | gfredericks | ,((fn λ [] (fn [] :no))) |
| 21:24 | clojurebot | #<sandbox$eval27$??__28$fn__29 sandbox$eval27$??__28$fn__29@3984d9f6> |
| 21:24 | gfredericks | ,((fn fooλbar [] (fn [] :no))) |
| 21:24 | clojurebot | #<sandbox$eval57$foo??bar__58$fn__59 sandbox$eval57$foo??bar__58$fn__59@4684c5b4> |
| 21:24 | goodieboy | technomancy: we're using leiningen < 2, can we still use the ".lein-classpath" feature for testing plugins? |
| 21:25 | gfredericks | the ?? is rather disturbing there |
| 21:25 | guns | That's true |
| 21:25 | mk | gfredericks: my repl shows the lambda, might be clojurebot bug |
| 21:25 | gfredericks | oh okay; so java must allow it |
| 21:26 | guns | Java identifiers explicitly allow unicode; I'm not sure if this impacts clojure in any way |
| 21:26 | guns | http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.8 |
| 21:26 | gfredericks | so clojure must only munge a few reserved symbols |
| 21:28 | goodieboy | technomancy: well dang, it works :) |
| 21:28 | mk | eclipse doesn't like ↬ in method names |
| 21:29 | mk | it doesn't complain when given non-english alphabets, though |
| 21:29 | arohner | with core.logic, how do I say "all elements of seq x are members of seq y"? |
| 21:30 | gfredericks | (everyo #(membero % y) x) |
| 21:30 | gfredericks | after writing everyo |
| 21:30 | gfredericks | and that only works if you don't mind it succeeding multiple times for repeats |
| 21:30 | arohner | how do I write everyo? :-) |
| 21:30 | arohner | I'm still uncertain about how core.logic is implemented, and what is possible |
| 21:31 | gfredericks | (defn everyo [goalo coll] (matche [coll] ([[]]) ([[x . xs]] (goalo x) (everyo goalo xs)))) |
| 21:32 | arohner | gfredericks: awesome. thank you. Is there something I should have read? I've read the primer on the wiki, but I still have lots of questions |
| 21:32 | mk | why do namespaces map directly to classes, instead of classes wrapped in vars? |
| 21:32 | gfredericks | arohner: The Reasoned Schemer |
| 21:33 | gfredericks | arohner: what are your questions? I'm right this second preparing a talk on core.logic so I'm interested in that sort of thing above and beyond the normal |
| 21:33 | gfredericks | I should probably even take notes on your questions :) |
| 21:34 | arohner | the main thing I'd like to understand is, enough of the implementation so that it I have an intuitive understanding of how to extend it |
| 21:34 | arohner | i.e. I didn't know that goals were functions, or how to compose new goals |
| 21:34 | arohner | i.e. I don't know what's "magic" and what's "user code" |
| 21:34 | gfredericks | by "extend it" do you mean writing your own goals, or really really extending it? |
| 21:34 | gfredericks | maybe you don't know what you mean yet |
| 21:35 | arohner | right, I don't know which kinds of extension are easy, and which take serious work |
| 21:35 | gfredericks | k cool |
| 21:36 | arohner | an hour ago I was wondering, if I have a logic variable q, and q is a map, how do I write the goal "q has a key named :foo, with value 3" |
| 21:36 | gfredericks | holy crap |
| 21:36 | gfredericks | afaik you can't |
| 21:36 | casion | maan, functional programming still maakes no sense to me :( |
| 21:36 | arohner | (pred q #(== 3 (:foo q)) worked for me |
| 21:37 | gfredericks | well if your map is ground you can do that |
| 21:37 | arohner | though as amalloy pointed out, that's non-relational |
| 21:37 | gfredericks | core.logic doesn't have good support for logic-variables-as-maps; you basically have to match all the keys at once which isn't very useful |
| 21:38 | gfredericks | that's partly because there's not a clear way for it to solidify a partially-specified map |
| 21:38 | gfredericks | i.e., if you said (run 1 [q] (q-has-value :foo 12)), what should it return? |
| 21:38 | gfredericks | (has-value q :foo 12) I should have said |
| 21:39 | arohner | {:foo 12} might be reasonable |
| 21:39 | arohner | in my particular case, I was selecting a map from a seq of maps |
| 21:39 | gfredericks | :/ |
| 21:40 | gfredericks | also what about (run 1 [q] (fresh [x] (has-value q x 12))) |
| 21:40 | arohner | It appears I don't have goalo |
| 21:40 | gfredericks | that was an argument |
| 21:41 | arohner | oh, right |
| 21:42 | xeqi | gfredericks: couldn't that use the same value of x that (run1 [q] (fresh [x] (== q [x 12]))) would? |
| 21:42 | gfredericks | xeqi: it could; all these things feel a little icky though |
| 21:43 | gfredericks | the former because it doesn't distinguish between "this map might have had more keys" and "this map couldn't have more keys" |
| 21:44 | arohner | does it need to? that seems like a separate constraint |
| 21:44 | gfredericks | I mean the value returned from run |
| 21:46 | gfredericks | (run 2 [q] (conde ((firsto q 7)) ((== q [7])))) return two different things |
| 21:46 | muhoo | emezeske: it looks to me like lein-cljs plugin somehow manages to pull in support, but i can't figure out where it actually gets that or how it finds it or where it gets it from |
| 21:47 | gfredericks | while (run 2 [q] (conde ((has-key q :foo 7)) ((== q {:foo 7})))) wouldn't |
| 21:49 | muhoo | emezeske: nm, i found it, cljsbuild (without the lein-) |
| 22:04 | arohner | gfredericks: I'm getting stackoverflows when I use your everyo |
| 22:04 | arohner | (l/run* [q] (everyo #(l/membero % [4 5 6]) q)) |
| 22:04 | amalloy | Raynes: lazybot seems to have passed out |
| 22:05 | muhoo | ,(l/run* [q] (everyo #(l/membero % [4 5 6]) q)) |
| 22:05 | clojurebot | #<CompilerException java.lang.RuntimeException: No such namespace: l, compiling:(NO_SOURCE_PATH:0)> |
| 22:06 | muhoo | bot appears to be alive, alhough it doesn't seem to do core.logic :-) |
| 22:06 | amalloy | muhoo: does that look like lazybot to you? |
| 22:06 | muhoo | it looks like a bot to me |
| 22:07 | muhoo | ,are you a bot? |
| 22:07 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: are in this context, compiling:(NO_SOURCE_PATH:0)> |
| 22:07 | gfredericks | arohner: that gives you a stack overflow? |
| 22:07 | muhoo | ,guards |
| 22:07 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: guards in this context, compiling:(NO_SOURCE_PATH:0)> |
| 22:07 | arohner | gfredericks: yes, running c.l 0.7.5 |
| 22:07 | muhoo | ,"foo" |
| 22:07 | clojurebot | "foo" |
| 22:07 | muhoo | ah, clojurebot |
| 22:07 | muhoo | #"foo" |
| 22:08 | muhoo | which one is ##"foo" |
| 22:09 | gfredericks | arohner: it might just be that's how the infinite-answers thing manifests itself |
| 22:09 | gfredericks | (run 5 ...) works fine for me |
| 22:09 | muhoo | &"alive?" |
| 22:10 | arohner_ | ah, yes |
| 22:10 | arohner_ | run* .. gives stackoverflow, run 5 terminates immediately. thanks |
| 22:11 | mk | gfredericks: namespace's map actually is implemented as an atom, for what it's worth |
| 22:11 | gfredericks | mk: cool |
| 22:14 | goodieboy | technomancy: is it possible to use .lein-classpath when the plugin requires dependencies that the project doesn't have? |
| 22:15 | goodieboy | ... my plugin is using the "fs" library, but when testing in my project, "fs" can't be found |
| 22:17 | casion | as I don't think I have a proper grasp of functional programming yet, can someone look at this http://ideone.com/JUDLG and give me some clues on how to do it better? |
| 22:18 | casion | it's just a small simulation of aa very simple game i suppose |
| 22:18 | casion | it looks awful to me but I can't think of how else to approach it |
| 22:20 | Raynes | The variety of pastebins people use in here never ceases to amaze me. |
| 22:20 | Raynes | :p |
| 22:21 | casion | heh, yeah |
| 22:22 | Raynes | I think it'd be fun to write a pastebin. |
| 22:22 | casion | I wrote that on my ipad while out on the porch, so it was already there |
| 22:22 | Raynes | I'd want it to look like https://www.refheap.com |
| 22:22 | casion | convenient |
| 22:22 | xeqi | I think it'd be fun to break a pastebin |
| 22:23 | cmajor7 | what is the use of "#{::user}"? it evaluates to a current namespace, e.g. #{current.ns/user}, but what is the purpose? |
| 22:24 | Raynes | cmajor7: Sometimes you need there to be a difference between the :foo from the bar namespace and the :foo from the baz namespace. |
| 22:24 | Raynes | It isn't particularly common though. |
| 22:24 | cmajor7 | I am looking at "friend" roles |
| 22:25 | cmajor7 | they are defined as #{::user ::admin ::etc}, and was wondering on how to store them in DB |
| 22:25 | cmajor7 | I guess I can just store them as user, admin and such.. |
| 22:26 | cmajor7 | do you know the "friend"'s purpose? thx |
| 22:26 | gfredericks | ,(name ::admin) |
| 22:26 | clojurebot | "admin" |
| 22:27 | cmajor7 | gfredericks: but ,(name :admin) |
| 22:27 | cmajor7 | is also "admin" |
| 22:27 | gfredericks | yep |
| 22:29 | cmajor7 | mm… do you know why "friend" for example uses "::"? |
| 22:29 | gfredericks | nope |
| 22:30 | cmajor7 | e.g. https://www.refheap.com/paste/3951 |
| 22:30 | gfredericks | it's used as a value rather than a key? |
| 22:30 | cmajor7 | it is a set.. |
| 22:31 | cmajor7 | what do you mean "rather than a key"? |
| 22:31 | gfredericks | a key in a map |
| 22:31 | xeqi | cmajor7: in order to use `derive` to make a heirarchy the keywords need to be namespaced |
| 22:31 | gfredericks | I guess I can imagine a justification |
| 22:31 | gfredericks | ooh that |
| 22:32 | gfredericks | that sounds by far the most likely |
| 22:32 | xeqi | you can actually have the roles be anything if I remember correctly |
| 22:32 | xeqi | you just don't get the ability to `derive` a heirarchy then |
| 22:35 | cmajor7 | xeqi: I see.. reading about it now. thank you |
| 22:56 | muhoo | cmajor7: :: is a fully qualified symbol, no? |
| 22:56 | muhoo | ,::foo |
| 22:56 | clojurebot | :sandbox/foo |
| 22:57 | cmajor7 | right, "it" is just a "current name space forward slash it" |
| 22:58 | gfredericks | &(identical? (keyword "foo/bar") (keyword "foo" "bar")) |
| 22:58 | gfredericks | ,(identical? (keyword "foo/bar") (keyword "foo" "bar")) |
| 22:58 | clojurebot | true |
| 23:03 | muhoo | emezeske: if you're around, i'm trying to figure out exactly how lein-cljsbuild pulls in cljsbuild, so i can do some checkouts stuff to work on it |
| 23:03 | muhoo | actually, it'd be great to hear what your workflow is for working on lein-cljsbuild, i might as well start with that |
| 23:05 | muhoo | actually, in general how to use a plugin from checkouts, might be an interesting question |
| 23:09 | Raynes | amalloy: You have access to the VPS too btw. |
| 23:15 | amalloy | yeah, but you do weird shit with lazybot and if i touch him you get annoyed |
| 23:16 | technomancy | is anyone still seeing the bug where C-c C-k with nrepl.el would occasionally take a few tries to go all the way through? |
| 23:16 | Raynes | amalloy: Dude. All I do is run ./lazybot |
| 23:16 | Raynes | Seriously, that's precisely all I do. |
| 23:16 | technomancy | I can't repro, but I can't tell if I'm just getting lucky or if the bug is gone |
| 23:16 | Raynes | I mean, I do it in a tmux session, but that isn't required. :P |
| 23:17 | technomancy | dude, at least nohup it |
| 23:17 | Raynes | Why? |
| 23:17 | clojurebot | why not? |
| 23:17 | Raynes | I stick it in a tmux session so I can attach and watch over my world. |
| 23:18 | technomancy | I guess if everyone has access to the tmux session it's fine |
| 23:18 | Raynes | Why would anyone else need access to my tmux session? |
| 23:18 | technomancy | I dunno; it's fine; disregard |
| 23:18 | Raynes | amalloy doesn't care about lazybot's output unless it stops doing it in which case he just wants to restart it which doesn't involve my tmux session at all. |
| 23:18 | Raynes | :P |
| 23:19 | technomancy | but if you do run it outside a tmux, then you should use nohup |
| 23:19 | amalloy | for what it's worth i nohup 4clojure, but i don't know why |
| 23:19 | technomancy | from seeing how clojars is deployed I found upstart to be surprisingly simple |
| 23:19 | technomancy | it is nice if everything works via familiar /etc/init.d scripts |
| 23:20 | Raynes | technomancy: What does nohup do? Apparently I don't understand. |
| 23:21 | Raynes | I thought it was to make it run in the background. |
| 23:21 | technomancy | it prevents it from exiting when the parent process (bash in this case) terminates |
| 23:21 | Raynes | Which is what tmux does for me in the first place. |
| 23:21 | Raynes | But tmux never terminates. |
| 23:21 | technomancy | right, I meant if you run it outside tmux you need it |
| 23:21 | Raynes | Oh, reading comprehension. |
| 23:22 | technomancy | but upstart is much nicer |
| 23:22 | Raynes | I thought you said 'inside'. |
| 23:22 | amalloy | technomancy: i've also never seen a process end when my bash ends |
| 23:22 | amalloy | so i wonder if perhaps nohup is a relic of simpler times, when that happened? |
| 23:22 | Raynes | I sure have. |
| 23:22 | Raynes | amalloy: As a matter of fact, I've killed 4clojure like that before. |
| 23:22 | technomancy | it happens |
| 23:23 | technomancy | http://groups.google.com/group/clojars-maintainers/browse_thread/thread/d4149ec96316d5b1/4c66317ac3ecd9bb?lnk=gst&q=upstart#4c66317ac3ecd9bb <- nice description of clojars' upstart usage from _ato |
| 23:25 | technomancy | I'm going to go out on a limb and say that particular nrepl.el bug is gone |
| 23:28 | muhoo | technomancy: nrepl.el is very very cool, thanks, i'm now switched over to using it |
| 23:29 | Raynes | muhoo: Welcome to the resistance. |
| 23:29 | muhoo | technomancy: sorry for so brutally whacking the popups, but all the popups had turned my sessions into an experience not unlike browsing porn sites. |
| 23:29 | technomancy | muhoo: oh, haha; irc/github nick mismatch =) |
| 23:29 | Raynes | You would know. |
| 23:30 | technomancy | I think you're right about the repl experience, but the fix in that pull request was just a bit too far-reaching |
| 23:30 | muhoo | agreed, i was just in a hurry |
| 23:31 | technomancy | muhoo: so you actually prefer just seeing the message going to stdout vs the whole trace? |
| 23:31 | muhoo | actually, what i've come to really enjoy is the way lein does it: a single-line clj-stacktrace summary |
| 23:31 | muhoo | and (pst) to get the rest if needed |
| 23:32 | muhoo | though, a hotkey in emacs to pop up the (pst) would be slick, so as not to pollute the repl buffer with a huge stacktrace |
| 23:32 | technomancy | what if clj-stacktrace omitted irrelevant frames by default? |
| 23:32 | muhoo | i think it does already, or at least shortens them |
| 23:32 | hiredman | as always, I object, who decides what is irrelevant? |
| 23:33 | technomancy | hiredman: I know you object =) |
| 23:33 | technomancy | I'm asking muhoo because it never occurred to me that the behaviour of only showing .getMessage was actually preferred by anyone |
| 23:33 | muhoo | well, look. i type (ns 'foobar) too many times |
| 23:33 | hiredman | removing stack traces is optimizing for ignorance, it makes a better experience for people who can't read them |
| 23:34 | muhoo | and, a whole host of errors i make constantly in a repl, like (require foo.bar.baz) instead of (require 'foo.bar.baz) |
| 23:34 | muhoo | do i really need a 2-page stacktrace every time? |
| 23:34 | technomancy | muhoo: I'm just wondering if you're objecting to their length or their presence at all |
| 23:35 | technomancy | I think reply must have some magic to auto-refer clojure.repl into every ns or something... interesting |
| 23:35 | muhoo | i'm objecting to (1) popups in general, they disorient me, and (2) huge spews when i just made a typo |
| 23:35 | technomancy | muhoo: sure, I'm saying what if the trace went to stdout instead |
| 23:36 | technomancy | and if they were shorter |
| 23:36 | muhoo | i actually wrote a hack for noir where it sends the stacktrace to /tmp/noir-error.clj, and then i auto-revert-mode a buffer that has taht in it |
| 23:37 | muhoo | so when i blow something up, i just go to the buffer (or have it open in another window) and look at it, and the most recent error to occur is right there looking at me, with the top frame at the top, etc. (and some context and ring-request at the bottom too) |
| 23:38 | muhoo | i like full stacktraces, and i enjoy the way clj-stacktrace cleans them up. |
| 23:39 | muhoo | but i also like not *having* to look at them, when often the first line is all i need. |
| 23:39 | muhoo | (also nice not to have to scroll around to find the top of them, which is why i wrote that hack for noir/ring) |
| 23:39 | technomancy | sure |
| 23:40 | technomancy | I think you can actually set :caught in :repl-options in project.clj if you want to tweak it |
| 23:40 | muhoo | cool, i'll take a look at that. |
| 23:40 | technomancy | at least you could in 1.x; hopefully that's still possible |
| 23:40 | technomancy | anyway, that would let you swap between prn and pst |
| 23:41 | muhoo | well, i'm fully converted over to lein2 now, so i'd have to find a way that works with it |
| 23:42 | technomancy | I actually didn't even know that the default was just to show the exception message |
| 23:42 | muhoo | really? wow. you've been using swank i presume |
| 23:43 | technomancy | only started paying attention to lein repl now with nrepl.el |
| 23:46 | muhoo | i see no :caught in leiningen/sample-project.clj |
| 23:47 | technomancy | it might not be documented; try putting it in :repl-options |
| 23:49 | muhoo | i'll try, but the word "caught" appears nowhere in the lein2 source |
| 23:49 | technomancy | yeah, it would get passed through to reply |
| 23:55 | amalloy | technomancy: oh, is reply the one responsible for me no longer getting reasonable exception messages in swank? |
| 23:55 | amalloy | or are those not related? |
| 23:56 | technomancy | hrm |
| 23:56 | technomancy | unrelated |
| 23:56 | technomancy | you may be getting bit by a clj-stacktrace bug? |
| 23:57 | amalloy | maybe. i've never included clj-stacktrace on purpose |
| 23:57 | technomancy | it comes for free |
| 23:57 | technomancy | because it's too awesome not to |
| 23:58 | amalloy | how can i disable it? i've had nothing but grief anytime i've had a project that uses it |
| 23:58 | technomancy | ... what? |
| 23:58 | technomancy | how ... I mean |
| 23:59 | technomancy | why would you want gross normal stack traces? |
| 23:59 | amalloy | stacktraces coming from inside clj-stacktrace's processing code, instead of from my code |
| 23:59 | technomancy | oh, right |
| 23:59 | amalloy | so that i can't track down any damn thing |
| 23:59 | technomancy | first thing would be to bug chouser to make his clj-stacktrace changes public so I stop procrastinating on the project |
| 23:59 | technomancy | second thing would be to switch to nrepl.el |