2015-04-03
| 01:46 | mordocai | I have an error with trying to create a schema for a record from another namespace. I'm importing it but still no go. What am I doing wrong? https://github.com/mordocai/clojure-maildir |
| 01:46 | mordocai | Error shows up when compiling schemas.clj |
| 01:56 | mordocai | Ugh, laptop is way too aggressive at turning off wifi. If anyone answered my query I missed it. |
| 01:58 | mavbozo | mordocai: records initialization should be Email. or ->Email or map->Email |
| 01:59 | mavbozo | mordocai: or maybe that's how scema.core works |
| 02:00 | mordocai | mavbozo: Yeah, AFAIK when specifying a record for a schema you are supposed to give the raw record not an initialized one. It appears to actually be erroring on the import btw. |
| 02:05 | mavbozo | mordocai: what's written in the error message? |
| 02:12 | mavbozo | mordocai: i cloned your repo and change the import line to (:import [clojure_maildir.records Email]) |
| 02:12 | mavbozo | the schemas.clj compiled |
| 02:13 | mavbozo | although I got another error: No such var: records/->Email, compiling:(clojure_maildir/core.clj:22:5) |
| 02:16 | mordocai | mavbozo: Ah, just got my error in a pastebin. https://www.refheap.com/99187. Thanks for the import correction! I'll work on the next error. |
| 02:22 | mordocai | Excellent, those errors are all fixed! Thanks for your help! |
| 02:27 | justin_smith | ~next |
| 02:27 | clojurebot | It's greek to me. |
| 03:02 | guthur | Is there a way to reload a project.clj in cider/nrepl |
| 03:02 | guthur | I have added a dependency and would like it loaded |
| 03:03 | justin_smith | guthur: sure, if you use pallet/alembic |
| 03:03 | justin_smith | or even pomegranate (but alembic is easier, it has a "load-project" function that does what you want) |
| 03:03 | jonasen | guthur: I usually do M-x cider-restart |
| 03:04 | jonasen | guthur but that restarts everything I think |
| 03:04 | justin_smith | yeah, that shuts down your repl and makes a new one |
| 03:05 | guthur | yeah i figured restart would work |
| 03:05 | guthur | I will check out alembic and pomegranate |
| 03:06 | justin_smith | guthur: a good cantidate for putting in ~/.lein/profiles.clj under :user {:dependencies [ ... ]} |
| 03:06 | justin_smith | that, criterium (for benchmarking functions for speed) and tools.trace (for debugging) |
| 03:07 | guthur | justin_smith: yeah just in the process of adding it |
| 03:15 | TEttinger | hm, so, I have some questions for #clojure's masters of the immutable |
| 03:19 | TEttinger | if I were to make a new def-like macro that defines a symbol as being a "state variable" (not sure what to call it, really, but the idea is, any changes to any state variable update the same global collection that stores all state variables, increment a version number, append the new state to a list of remembered states)... |
| 03:20 | TEttinger | I basically have an append-only log of immutable historic states |
| 03:21 | TEttinger | but I want to be able to jump back to previous states, assigning the current state the value from an earlier version |
| 03:24 | TEttinger | I'm just not sure how all this will work |
| 03:39 | TEttinger | cfleming, I have a bit of confusion regarding the behavior of Cursive and lein projects with -main |
| 03:40 | TEttinger | it seems like right clicking a file or project and telling Cursive to Run a given module just does nothing and exits after a few seconds |
| 03:40 | TEttinger | I must be missing something |
| 03:40 | TEttinger | I'm on 13.1 |
| 03:49 | guthur | I'm trying to use https://github.com/xsc/ancient-clj |
| 03:50 | guthur | if i require [ancient-clj.core :as ancient] i get the following exception... |
| 03:50 | guthur | Could not initialize class com.amazonaws.ClientConfiguration |
| 03:51 | guthur | any suggestions |
| 03:53 | TEttinger | guthur, it looks like ancient-clj depends on a com.amazonaws lib https://github.com/xsc/ancient-clj/blob/master/project.clj#L10 |
| 03:54 | TEttinger | but it must be doing something as soon as it's read |
| 03:54 | guthur | TEttinger, yeah, does lein not grab those |
| 03:54 | TEttinger | a very old lein version wouldn't |
| 03:54 | TEttinger | an... ancient lein version :P |
| 03:54 | guthur | i'm pretty much upto date |
| 03:54 | guthur | Leiningen 2.5.1 on Java 1.7.0_75 OpenJDK 64-Bit Server VM |
| 03:57 | TEttinger | and the only stuff that actually is run by including ancient-clj.core seems awfully small |
| 03:57 | TEttinger | https://github.com/xsc/ancient-clj/blob/master/src/ancient_clj/core.clj#L9-L17 |
| 03:58 | TEttinger | ah, that was added fairly recently though https://github.com/xsc/ancient-clj/commit/15b508f5ee5bd6212020b434a438ecaa8086567b |
| 04:03 | guthur | maybe i will try and earlier verson |
| 04:04 | TEttinger | that was sept 2014 |
| 04:05 | TEttinger | if a version from august or earlier works, that might be an interesting issue to report |
| 04:05 | sveri | Hi, I just tried out core.typed and started annotating a namespace with two functions. I am calling a few other libraries there which are not under my control and it turns out I have to annotate each other function call I am doing into a different library? It makes sense following the logic of typing. How do people handle this? I mean, does it make sense to to collect external library annotations in a central place so I can access it |
| 04:07 | TEttinger | I'm curious about how that works in practice too, sveri, but I haven't used core.typed |
| 04:07 | sveri | TEttinger yea, I have a helper library and I think about making a namespace with just lots of annotation definitions that I need somewhere else |
| 04:08 | TEttinger | I wish there was some way to automate that, but I don't see how it could work |
| 04:08 | TEttinger | I guess some kind of type inference could be used if it had a basis of how they are used |
| 04:09 | sveri | TEttinger maybe a github repo makes sense too where people can contribute type definitions.. |
| 04:09 | TEttinger | yep |
| 04:11 | sveri | I will ask on the core.typed mailing list what people think about that and maybe start one |
| 04:14 | sveri | I just looked at some github repo and found this: (ann ^:no-check clojure.java.io/writer [Socket -> BufferedWriter]) this is exactly what I mean, I guess so many people will have this line somewhere in the code...the duplication will be immense |
| 04:18 | sveri | TEttinger In case you want to follow: https://groups.google.com/forum/?fromgroups#!topic/clojure-core-typed/nrHx_1XO9cc |
| 04:39 | expez | how do I add the character literal ( to a clj file? |
| 04:39 | expez | \( doesn't work and neither does \\( |
| 04:40 | dstockton | not sure what you mean expez |
| 04:40 | dstockton | where in a clj file? |
| 04:41 | expez | dstockton: I want to compare against the character literal (, but I can't eval the code. I thought \( was the right way to do this but cider is barfing on an unmatched delimiter |
| 04:42 | dstockton | might be a cider issue, \( works fine in the repl |
| 04:42 | oddcully | ,(= \( \() |
| 04:42 | wagjo | ,\u0028 |
| 04:42 | clojurebot | \( |
| 04:42 | clojurebot | true |
| 04:43 | wagjo | expez: you may use \u0028 as a workaround |
| 04:43 | oddcully | ,(= \( \u0028) |
| 04:43 | clojurebot | true |
| 04:44 | expez | submitted a ticket. going with workaround for now. Thanks! |
| 04:51 | TEttinger | &(map char "()[]{}") |
| 04:51 | lazybot | ⇒ (\( \) \[ \] \{ \}) |
| 04:51 | TEttinger | &(map int "()[]{}") |
| 04:51 | lazybot | ⇒ (40 41 91 93 123 125) |
| 04:51 | TEttinger | hm |
| 04:52 | TEttinger | &(map (comp #(format "%04X" %) int) "()[]{}") |
| 04:52 | lazybot | ⇒ ("0028" "0029" "005B" "005D" "007B" "007D") |
| 04:52 | TEttinger | &(map (comp #(format "\\u%04X" %) int) "()[]{}") |
| 04:52 | lazybot | ⇒ ("\\u0028" "\\u0029" "\\u005B" "\\u005D" "\\u007B" "\\u007D") |
| 04:52 | TEttinger | there you go, all the brackets that might mess cider up |
| 05:03 | cfleming | TEttinger: Hmm, I'm not sure about the autodetection there - what you want is to go to Run->Edit Configurations and create an Application configuration |
| 05:04 | TEttinger | I checked that |
| 05:04 | TEttinger | I have one made |
| 05:04 | cfleming | What happens when you run it? |
| 05:04 | TEttinger | but it isn't... doing anything. and I don't see where to call -main |
| 05:04 | TEttinger | it doesn't print anything because it is supposed to open a window, but no window opens |
| 05:04 | TEttinger | if I call -main in the repl, I get the window just fine |
| 05:05 | cfleming | In that run config, you enter your main class - that should be the class generated from your main ns |
| 05:05 | TEttinger | if I terminate the repl and try to open again, Cursive throws an exception (I submitted a bug report) |
| 05:06 | cfleming | TEttinger: You did? I don't think I saw that |
| 05:06 | TEttinger | it was less than an hour ago |
| 05:06 | cfleming | TEttinger: Oh, you mean an exception report, not an issue |
| 05:06 | TEttinger | yes |
| 05:06 | cfleming | Right, I haven't checked those |
| 05:06 | cfleming | Can you send a screenshot of your Application run config? |
| 05:07 | TEttinger | the options for the run config are "script path", where I have the file path to the clj |
| 05:07 | TEttinger | sure |
| 05:07 | cfleming | Ok |
| 05:07 | cfleming | Hang ok |
| 05:07 | cfleming | Hang on |
| 05:07 | cfleming | You're talking about a Clojure Application config |
| 05:08 | elvis4526 | Is there a way to provide a default implementation for a method when using protocols ? |
| 05:08 | TEttinger | cfleming, correct |
| 05:09 | cfleming | You use that one if you have a Clojure script to run, once you're using -main you're in Java land really |
| 05:09 | cfleming | Although that config should handle it (there's an issue in the tracker for it) |
| 05:09 | TEttinger | should I just add a call to -main at the end? |
| 05:10 | cfleming | The config you want is just called Application, it's what you'd use if you were running a Java program |
| 05:10 | TEttinger | ah! ok |
| 05:11 | cfleming | Sorry, this is old code and more confusing than it should be, I'm planning to fix it soon as I re-vamp the run config stuff |
| 05:12 | TEttinger | nope, Application doesn't recognize anything in my project as a main type |
| 05:12 | TEttinger | main class, rather |
| 05:12 | TEttinger | it's not a big issue, I should be doing more from the REPL anyway |
| 05:13 | TEttinger | but it was certainly an early stumbling block |
| 05:13 | cfleming | Are you using :gen-class? |
| 05:14 | cfleming | Yeah, it's surprising how infrequently people use -main, which is why I've never prioritised fixing it, but it's pretty nasty right now |
| 05:15 | TEttinger | yeah, I have :gen-class in the ns |
| 05:16 | TEttinger | thanks for the quick reply! |
| 05:16 | TEttinger | other than being very confused by structural editing, I've been pretty happy with Cursive so far |
| 05:16 | cfleming | Ok, so I think there' s a problem where Cursive doesn't correctly publish the main method in the class generated from the namespace |
| 05:16 | TEttinger | ah! |
| 05:17 | cfleming | Give me a sec |
| 05:17 | cfleming | Was that confusion about structural editing in Cursive specifically, or do you just not use it? |
| 05:20 | TEttinger | I've never used structural editing before, I couldn't turn a variable into a call that uses that variable, so I ended up with all this weirdness trying to stick a paren in the middle of a form... |
| 05:20 | TEttinger | I had something like, let's say (* width height), and I wanted to change it to (* (/ width 3) height) |
| 05:21 | TEttinger | it let me add the first paren, but any time I typed ), it closed a much later form |
| 05:22 | cfleming | Ok, did you figure out how to turn it off? |
| 05:22 | cfleming | (might be best until you get more used to Cursive - just learn one new thing at a time :-) ) |
| 05:23 | TEttinger | oh yes, I turned it off right away |
| 05:24 | cfleming | So I just ran a main method, here's how: I used the Application config, you're right that it doesn't find the main class, I'll fix that. But you can type in the class anyway, which is basically your namespace name with dashes replaced with underscores |
| 05:24 | cfleming | It'll warn you that the class doesn't have a main method, but you can ignore that |
| 05:24 | cfleming | Are you using Leiningen? |
| 05:24 | TEttinger | yes |
| 05:25 | TEttinger | I imported a project by finding my existing project.clj |
| 05:25 | cfleming | Ok |
| 05:25 | cfleming | One thing you should check if you're using AOT is that Cursive is set to compile your namespace - it doesn't autodetect the ones it should compile yet |
| 05:25 | TEttinger | oh, and just calling -main at the toplevel works for now |
| 05:26 | cfleming | That's under Settings->Build etc->Compiler->Clojure Compiler |
| 05:26 | cfleming | Ok. I'm actually working on a bunch of run/execution stuff right now, I'll see if I can fix this for the next build |
| 05:28 | TEttinger | great, thanks! |
| 06:56 | noncom | anyone using neo4j + neocons here? |
| 07:36 | unindented | is there a way I can run all :test assertions for my module functions when executing `lein test`? |
| 07:36 | unindented | I mean these kinds of assertions: http://clojure.org/special_forms |
| 08:03 | borkdude | I want to change something in a database and upload something to s3. this has to occur in a synchronized fashion. maybe this is where "(locking ...)" comes in |
| 08:03 | borkdude | ? |
| 08:04 | borkdude | there may be a race condition when I don't lock |
| 08:56 | guthur | is there a way to force the output of print when printing to the shell |
| 08:56 | guthur | in CL you would use terpri |
| 08:57 | guthur | I am wanting to prompt and accept an input |
| 08:57 | guthur | but unless i use println the prompt will not show |
| 09:10 | guthur | ah, the answer was (flush) |
| 09:56 | gfredericks | this thing with iterate is so complicated |
| 10:39 | justin_smith | TEttinger2: regarding your history of states: make "place in state history" one of your history-tracked states of course :) |
| 10:39 | justin_smith | TEttinger2: that way you can walk not only history, but history of backtracking history |
| 11:05 | mikerod | Why would I get UnsupportedClassVersionError Unsupported major.minor version 51.0 types of exceptions running clojure 1.6 things in Java 7? |
| 11:05 | sobel | thx to whomever turned me onto Robert.Hooke yesterday |
| 11:05 | mikerod | I was under the impression that clj 1.6 was fine in Java7 |
| 11:05 | mikerod | specifically I got this compiling cider/nrepl/middleware/util/java/parser.clj |
| 11:05 | sobel | i'm cross-cutting through orthogonal concerns like butter |
| 11:07 | justin_smith | mikerod: odd |
| 11:07 | justin_smith | mikerod: usually jvms are really good at keeping these things compatible |
| 11:08 | mikerod | justin_smith: Java 7 does have a change in class format with JSR 202 https://jcp.org/en/jsr/detail?id=202 |
| 11:08 | mikerod | however, I thought many people were running Clojure fine in this Java version (pretty sure) |
| 11:09 | mikerod | and this is JIT compiling - if it were AOT I may be more likely to understand having an issue |
| 11:09 | puredanger | clojure 1.6 works perfectly fine with java 7 |
| 11:09 | justin_smith | yes, I have used 1.6, 1.7, and 1.8 extensively and have not seen these sorts of issues |
| 11:09 | puredanger | somehow you have newer class files and an older jvm |
| 11:09 | mikerod | java.lang.UnsupportedClassVersionError: com/sun/javadoc/ClassDoc : Unsupported major.minor version 51.0, compiling: ider/nrepl/middleware/util/java/parser.clj |
| 11:09 | mikerod | Oh... that's odd |
| 11:10 | mikerod | I guess I'll look at this some more. |
| 11:10 | puredanger | looks like what you'd get with a mismatched jvm / jdk ? |
| 11:11 | mikerod | puredanger: we accidentally had a node in a distributed cluster have java7 instead of java6 - that we have developed for currently in this case |
| 11:11 | mikerod | I guess something could just be screwed up there |
| 11:12 | sobel | what's the most current 'release' quality Clojure version? |
| 11:12 | mikerod | I just can't understand how a JVM running with Java7 could cause a JIT compiled class to break during compilation. I'm sure I just am not connecting the dots here then. I just wanted to make sure I'm not crazy and Clojure is fine running on Java6 and above |
| 11:12 | puredanger | are you sure it's a java 7 jvm? |
| 11:12 | puredanger | looks like java 6 jvm and java 7 classes to me I think? |
| 11:13 | puredanger | 51.0 is the JDK7 class format iirc |
| 11:13 | justin_smith | yeah, that would be the parsimonious explanation |
| 11:14 | mikerod | So it sounds like somehow I had a com/sun/javadoc/ClassDoc compiled from Java 7 trying to run on a Java 6 JVM - ok, I think that makes sense |
| 11:14 | mikerod | which would be nothing to do with Clojure :P |
| 11:14 | justin_smith | mikerod: could be a cider bug? |
| 11:15 | puredanger | you could see this if you were running java 6 vm with the java 7 jdk jar |
| 11:16 | mikerod | justin_smith: perhaps, or potentially we really just had a very mixed up machine |
| 11:16 | mikerod | puredanger: that sounds like a likely candidate of what happened there I'd guess |
| 11:16 | justin_smith | oh, wow |
| 11:16 | puredanger | for reference, you shouldn't do that :) |
| 11:16 | justin_smith | haha |
| 11:16 | mikerod | Cider middleware parser does use com.sun.javadoc.ClassDoc so the pieces are fitting more together |
| 11:16 | mikerod | haha |
| 11:16 | puredanger | it's ok to do the reverse though if you have the right settings :) |
| 11:17 | mikerod | yes, it does sound like a bad idea. the machine was set up incorrectly - I was just trying to make sure we didn't run into a clj incompatibility since we do intend to be moving to Java7 for this stuff in the near future. |
| 11:17 | mikerod | (inc puredanger) |
| 11:17 | lazybot | ⇒ 41 |
| 11:17 | puredanger | might as well move to 8 ... |
| 11:17 | mikerod | (inc justin_smith) |
| 11:17 | lazybot | ⇒ 231 |
| 11:17 | mikerod | puredanger: yes I'm pushing for the jump from 6 to 8 |
| 11:17 | mikerod | rather than stopping at 7 |
| 11:18 | puredanger | a lot of clojure stuff I run sees ~10% improvement from 7 to 8 |
| 11:18 | puredanger | obviously, YMMV |
| 11:18 | mikerod | Especially after hearing all about lambdas from Brian Goetz at clojure/conj :P |
| 11:18 | mikerod | Java lambdas that is |
| 11:19 | puredanger | some day we'll get those in Clojure too |
| 11:19 | mikerod | any particular reasons Clojure would get a speed up from Java7? |
| 11:20 | justin_smith | mikerod: to flip that - I would be surprised if you saw any slowdown |
| 11:20 | mikerod | justin_smith: true. I'd imagine any new versions of JVM should be more perfomant |
| 11:20 | puredanger | most java releases optimize things like object allocation, locking, etc |
| 11:20 | puredanger | inlining |
| 11:20 | mikerod | I know clj isn't doing anything extreme like using invokedynamic at this time though |
| 11:20 | mikerod | I see |
| 11:21 | puredanger | we're going straight to invokehyperdynamic |
| 11:21 | puredanger | is it still april fool's? |
| 11:21 | mikerod | haha close enough |
| 11:46 | expez | Given a file is there some easier way to check if it's present on classpath than to list all stuff on classpath and check if file is either listed itself or if a parent dir is? |
| 11:46 | justin_smith | expez: do you know the expected relative path? |
| 11:47 | expez | I actually want to get all the project's clj files, perhaps there's an easy way to do that directly |
| 11:47 | justin_smith | oh, so you want to search for all clj files on the class path? |
| 11:47 | expez | ya |
| 11:47 | expez | but only the project's own, I don't want stuff from jars |
| 11:47 | justin_smith | expez: assumed you only want things on disk in that project |
| 11:48 | justin_smith | yeah |
| 11:48 | justin_smith | so I guess you could look for classpath entries that are directories on disk, under the project root |
| 11:48 | matthavard` | ,(range 10) |
| 11:48 | clojurebot | (0 1 2 3 4 ...) |
| 11:48 | matthavard` | Oh that's so cool |
| 11:48 | justin_smith | expez: once you filtered for those, you could do a file tree |
| 11:49 | justin_smith | file-seq |
| 11:49 | justin_smith | (doc file-seq) |
| 11:49 | clojurebot | "([dir]); A tree seq on java.io.Files" |
| 11:50 | expez | justin_smith: I guess that's the way to go. Given the dirs I can use find-clojure-sources-in-dir from tools.namespace |
| 11:50 | expez | (inc justin_smith) |
| 11:50 | lazybot | ⇒ 232 |
| 11:50 | expez | thanks! :) |
| 11:50 | justin_smith | np |
| 12:37 | tahmid | Has anyone tried material-ui for om ? (this repo https://github.com/taylorSando/om-material-ui) |
| 12:43 | dnolen | tahmid: probably a better question for #clojurescript |
| 13:09 | TimMc | ,(clojure.string/join " " "hello") |
| 13:09 | clojurebot | "h e l l o" |
| 13:16 | gfredericks | ,(clojure.string/join "hello" "hello") |
| 13:16 | clojurebot | "hhelloehellolhellolhelloo" |
| 13:19 | hyPiRion | ,(.trim (clojure.string/join "hello" " ")) |
| 13:19 | clojurebot | "hello hello hello" |
| 13:20 | justin_smith | ,(clojure.string/join "hello" "") |
| 13:20 | clojurebot | "hellohellohellohellohellohellohellohellohellohellohellohellohello" |
| 13:20 | justin_smith | TEttinger2: ^ |
| 13:41 | brainproxy | for new projects happy to use the latest clj alpha, is it better to get on board with the new reader conditionals or go with cljx? |
| 14:24 | noncom | how do i make cheshire generate strings like {key: value} instead of {"key": value} from my data? i.e. how to make it omit quotes from the parameter key ? |
| 14:25 | dnolen | mpenet: ping |
| 14:27 | TimMc | noncom: Like... make not-JSON? |
| 14:28 | justin_smith | noncom: yeah - see for yourself, string is required for json http://jsonlint.com/ |
| 14:28 | noncom | umm probably.. ok, i know, but neo4j does not accept it like that |
| 14:29 | noncom | it wants property names without quotes |
| 14:29 | TimMc | Does it call it JSON? |
| 14:30 | noncom | no, it does not. but the only difference from json is this |
| 14:30 | mpenet | dnolen: yes? |
| 14:31 | delaney1 | do we have any transit experts in the house? |
| 14:31 | noncom | so instead of writing a brand new stringifyer, i thought cheshire might do. esp that this kind of json can be *read* by cheshire |
| 14:31 | dnolen | mpenet: ready to move on ASYNC-120, I reviewed your patch, it looked OK but when applied it did not work as intended |
| 14:31 | TimMc | Oh weird, it can? |
| 14:31 | gfredericks | I'd hope not |
| 14:31 | noncom | yes, see https://github.com/dakrone/cheshire/blob/master/src/cheshire/factory.clj |
| 14:31 | dnolen | mpenet: if you set up go blocks to take from the promise chan and then supply it via >! in a later go block only one of the <! takers will be fulfilled |
| 14:31 | noncom | :allow-unquoted-field-names factory param |
| 14:31 | delaney1 | i'm trying to implement a transit-c# reader, but seeing what i think is a bug in one of the examples |
| 14:31 | gfredericks | woooah |
| 14:32 | noncom | i guess cheshire only allows that coz jackson allows that |
| 14:32 | TimMc | Oh, not by default, good. |
| 14:32 | dnolen | mpenet: the tests weren't translated well enough to capture this case, I'm not yet sure of the root cause |
| 14:32 | TimMc | noncom: There's a chance there's a key encoder... |
| 14:32 | mpenet | dnolen: hmmm ok, I'll have a look when I get some time, but I am on a trip at the moment, I wont be back until wed |
| 14:33 | mpenet | dnolen: feel free to take over if you find the reason behind this problem |
| 14:34 | dnolen | mpenet: however it inspired me to rip out the old hand rolled runner and rely on cljs.test testing functionality & async test support. Happy to take a rebased patch. |
| 14:34 | mpenet | noted |
| 14:34 | dnolen | mpenet: if I don't get to it before you return |
| 14:34 | noncom | hmm, yes, looks like i have to get inside the encoder.. |
| 14:35 | TimMc | delaney1: Link to example in case there is a transit expert around? |
| 14:35 | gfredericks | the best kind of json is json where the object keys are serialized json objects |
| 14:35 | delaney1 | TimMc: i'll make a gist, thanks |
| 14:36 | noncom | gfredericks: sure, standards are out best good, but here i just want to be able to give my objects to neo4j and writing a custom string generator for this is a little overkill :) |
| 14:36 | TimMc | {[object Object] 5} |
| 14:36 | danielglauser | gfredericks: That's awesome |
| 14:37 | justin_smith | noncom: (cheshire/generate-string {{:a 0} 0}) |
| 14:37 | gfredericks | noncom: I'd say this is a lot more neo4j's fault than cheshire's fault though |
| 14:37 | justin_smith | "{\"{:a 0}\":0}" |
| 14:37 | justin_smith | sorry, that really wasn't directed specifically to you, noncom |
| 14:37 | TimMc | noncom: http://jackson.codehaus.org/1.1.2/javadoc/org/codehaus/jackson/JsonGenerator.Feature.html#QUOTE_FIELD_NAMES |
| 14:38 | TimMc | If you want to use Jackson directly. |
| 14:38 | TimMc | Maybe cheshire supports that option though, or maybe it can pass through options? |
| 14:39 | noncom | TimMc: thanks for the hints, i will check this out! |
| 14:41 | TimMc | Although the phrasing "want to use Jackson directly" waas a little hard for me to type out. |
| 14:43 | noncom | yeah :D |
| 14:43 | noncom | maybe i'll just patch cheshire if i won't find another way around |
| 14:43 | delaney1 | lol, in writing the gists i reread the spec ~ "if they are longer than 3 characters cache it" |
| 14:55 | TimMc | good ol' SSCCE |
| 15:17 | zanes | What would be the most idiomatic way to apply two transducer pipelines in parallel to an input, merging the results? |
| 15:28 | puredanger | the map transducer can read two inputs |
| 15:28 | puredanger | that's the only one atm |
| 15:31 | gfredericks | puredanger: I'm apparently too timid to say this on the ML but the iterate thing Bronsa was bringing up feels pretty gross to me |
| 15:31 | gfredericks | unless it's well documented |
| 15:31 | puredanger | you mean the reduce caching aspect? |
| 15:31 | gfredericks | yeah |
| 15:32 | gfredericks | he brought up perf but I'm thinking functions with side effects |
| 15:32 | Bronsa | gfredericks: iterate's doc explicitly says f should be side-effect free, though |
| 15:32 | puredanger | iterate specifically says in the docstring that the f must not have side effects |
| 15:32 | gfredericks | the old docstring says that? |
| 15:32 | puredanger | yes |
| 15:32 | gfredericks | then maybe the answer is just to take that seriously I guess :) |
| 15:33 | gfredericks | okay I don't mind as much then |
| 15:33 | Bronsa | I still don't think the new impl is a good idea :) |
| 15:33 | gfredericks | Bronsa: just because of potential slowdown? |
| 15:33 | Bronsa | yes |
| 15:33 | puredanger | seqs cache. if you want caching, use seqs. |
| 15:34 | puredanger | the new version is faster for that too. |
| 15:34 | Bronsa | puredanger: iterate's docstring says "returns a lazy sequence" |
| 15:34 | puredanger | it is a lazy sequence |
| 15:34 | puredanger | it is also reducible NOT as a lazy sequence |
| 15:34 | gfredericks | hmm |
| 15:34 | Bronsa | it's a sequence and a generator |
| 15:34 | Bronsa | depending on how you use it |
| 15:34 | puredanger | yes |
| 15:34 | Bronsa | it's obviously not a sequence when you reduce it |
| 15:34 | Bronsa | we should document it |
| 15:35 | gfredericks | ^ that part bothers me just for being complicated to understand |
| 15:35 | puredanger | either path must produce the same values (if f does not have side effects) |
| 15:35 | Bronsa | I'd rather have it reverted, but if that's out of the question we should at least make it clear how it will behave |
| 15:36 | Bronsa | puredanger: I'll admit my ignorance, but no side effects === pure? |
| 15:37 | Bronsa | i.e. is `rand` considered side-effecty? |
| 15:37 | puredanger | well, I'm using them to mean the same thing, but I'm sure some smarter person than me has a distinction |
| 15:37 | puredanger | rand *is* side effecty |
| 15:37 | amalloy | Bronsa: "side effects" and "pure" are both vague words; in some contexts they include rand, and in others they don't |
| 15:37 | puredanger | I think maybe it would be better to say "deterministic" |
| 15:37 | gfredericks | what about (let [r (java.util.Random. 42)] #(.nextLong r)) |
| 15:37 | puredanger | same inputs = same outputs |
| 15:37 | amalloy | puredanger: no, that's super wrong |
| 15:37 | justin_smith | puredanger: see gfredericks' talk at clojure/west for a non-side-effecty rand I think |
| 15:38 | gfredericks | oh crap I just got cited |
| 15:38 | puredanger | pre-cited even |
| 15:38 | justin_smith | pre-cited |
| 15:38 | ntaylor | and now he's ex-cited! |
| 15:38 | Bronsa | puredanger: the new version of iterate is probably faster for seqs b/c it doesn't guarantee once only computation like LazySeq does |
| 15:38 | Bronsa | I don't like that either :P |
| 15:39 | puredanger | yes, that's exactly the point |
| 15:39 | justin_smith | Bronsa: seems like there are a few things in clojure that say "no side effects please" but in practice we use as if side effects were OK |
| 15:39 | justin_smith | and maybe those chickens are coming home to roost |
| 15:39 | gfredericks | yeah that's what I meant about taking it seriously |
| 15:40 | Bronsa | justin_smith: my complaints have little to do with side-effects, much more with predictable performances |
| 15:40 | puredanger | I spent a few hours looking through oss for places where someone had violated that instruction and I don't recall finding one |
| 15:40 | puredanger | Bronsa: it is predictable. it's just different. |
| 15:40 | Bronsa | I always assumed functions returning lazy seqs guaranteed caching & once-only computation |
| 15:40 | Bronsa | not the case anymore |
| 15:40 | puredanger | they do, when used as a seq |
| 15:40 | gfredericks | passing something to reduce is something you can do with a seq |
| 15:41 | Bronsa | puredanger: not if the seq is realized in two different threads at the same time |
| 15:41 | Bronsa | puredanger: it's not synchronized |
| 15:41 | puredanger | this is not feasible in all cases, just these specific functions which generate the identical sequence of values every time |
| 15:41 | puredanger | Bronsa: but the same values will be generated |
| 15:42 | puredanger | this is the same technique used lazily cache hash codes once computed |
| 15:42 | TimMc | Throwing an exception is also a side-effect by some definitions. |
| 15:43 | puredanger | cycle, repeat, and range (fudging promotion cases) never throw exceptions |
| 15:43 | puredanger | iterate can, but that is handled in the ticket CLJ-1692 |
| 15:44 | gfredericks | cycle could throw an exception while realizing a lazy seq :) |
| 15:44 | puredanger | hmmm |
| 15:44 | gfredericks | ,(cycle (map #(/ 42 %) [2 1 0])) |
| 15:44 | clojurebot | #<ArithmeticException java.lang.ArithmeticException: Divide by zero> |
| 15:45 | gfredericks | would have to examine the stack trace to verify |
| 15:45 | solussd | What’s the recommended way to rcreate a test.check generator from a generator that will have duplicates? |
| 15:45 | gfredericks | solussd: to dedupe it you mean? |
| 15:45 | solussd | yes |
| 15:45 | gfredericks | solussd: what sort of thing are you trying to generate? |
| 15:45 | solussd | strings, but the system I’m testing does a uniqueness check |
| 15:45 | gfredericks | like ids? |
| 15:46 | solussd | unique names, so, yeah, like ids |
| 15:46 | puredanger | (take 2 (cycle (map #(/ 42 %) [2 1 0]))) indeed is this problem |
| 15:46 | gfredericks | solussd: it bugs me that there seems to be no foolproof way to provide that, but there's a few less-than-ideal tactics |
| 15:47 | gfredericks | certainly you can fmap with distinct |
| 15:47 | puredanger | with the obvious memory impact :) |
| 15:48 | gfredericks | now that I think about it maybe this could be done in a not-terrible way |
| 15:48 | gfredericks | shrinking is the sticky part |
| 15:49 | solussd | fmap with distinct would just generate strings without duplicate characters, right? |
| 15:49 | gfredericks | oh I mean generating a whole collection |
| 15:49 | gfredericks | (gen/fmap distinct (gen/vector my-string-generator)) |
| 15:49 | solussd | gotcha |
| 15:49 | ambrosebs | puredanger: what difference does it make if eduction is no Seqable? |
| 15:50 | ambrosebs | maybe I'll keep reading this email chain first. |
| 15:50 | ambrosebs | ;) |
| 15:51 | lexi-lambda | Is there a clean way to map over every other element of a collection? |
| 15:51 | gfredericks | puredanger: thanks for backandforthing |
| 15:51 | gfredericks | partition can help |
| 15:51 | lexi-lambda | I.e., I want the result to contain all elements, but I only want the mapping fn to be applied to the even elements. |
| 15:51 | puredanger | ambrosebs: not much given that seq will wrap an Iterable |
| 15:51 | puredanger | lexi-lambda: take-nth ? |
| 15:52 | ambrosebs | puredanger: is there a conceptual reason? |
| 15:52 | justin_smith | ,(mapcat (fn [[x y]] [(inc x) y]) (partition 2 (range))) ; lexi-lambda |
| 15:52 | clojurebot | (1 1 3 3 5 ...) |
| 15:52 | puredanger | ambrosebs: sorry, reason for what? |
| 15:52 | amalloy | justin_smith: careful. what if the coll has 9 elements? |
| 15:52 | ambrosebs | puredanger: why is eduction no longer Seqable? |
| 15:52 | puredanger | oh, there was just no reason for it to be |
| 15:52 | justin_smith | amalloy: good point, that makes the answer trickier |
| 15:53 | amalloy | justin_smith: map-indexed |
| 15:53 | lexi-lambda | this works, but I'd be curious if there were a nicer way to do it with built-in constructs http://stackoverflow.com/a/10326400/465378 |
| 15:54 | amalloy | lexi-lambda: not really. that's how i'd write it |
| 15:54 | lexi-lambda | Alright, thanks. |
| 15:55 | amalloy | though in my many years of clojure i have never had a need for map-nth. i have trouble imagining scenarios where i'd have data in a shape that needs to be map-nth'd |
| 15:56 | justin_smith | amalloy: what if every 1000000th visitor to your site should get a free ipad? |
| 15:56 | amalloy | justin_smith: joke acknowledged |
| 15:57 | ambrosebs | puredanger: any other new data structures where similar decisions have been made? |
| 15:57 | amalloy | but seriously, map-nth still doesn't make sense there. i'd want a list of all the winners, not a list of all the guests where the millionth one has some extra data |
| 15:57 | puredanger | ambrosebs: repeat,cycle,iterate changed in alpha6. range is coming (CLJ-1515) but varies slightly b/c range is chunked where the others were not. |
| 15:58 | ambrosebs | puredanger: these are all Seqable though? |
| 15:58 | puredanger | oh, they *are* seqs |
| 15:59 | puredanger | the extend ASeq |
| 15:59 | puredanger | so they are also Seqable by returning this |
| 16:00 | puredanger | ambrosebs: keys/vals both changed somewhat as well but they only committed to returning Seqable before and still do, but also happen to be IReduceInit now |
| 16:00 | puredanger | really, all of repeat,cycle,iterate (and other seq functions as well) should preferably only commit to returning a Seqable, not a seq. but there's too much of an existing expectation to rely on that |
| 16:01 | ambrosebs | puredanger: well at least an IPersistentCOllection I hope |
| 16:01 | puredanger | ideally those functions could have done like keys/vals and just returned something that is Seqable/IReduceInit |
| 16:02 | puredanger | they are, but that's what I'm saying I wish they weren't |
| 16:03 | puredanger | too likely to break existing code if we changed that |
| 16:04 | puredanger | every flavor of this has been tried on 1603 or 1515 - tons of patches there trying different things. I feel like I've spent a ridiculous amount of time on just counting with range :) |
| 16:04 | ambrosebs | puredanger: ok I'm kind of following. |
| 16:04 | gfredericks | it seems like making things try to be collection-like and special-reducible-like gets messy |
| 16:04 | ambrosebs | puredanger: I immediately thought of using coll? to check if something is immutable. |
| 16:04 | puredanger | yeah, tons of things like that |
| 16:04 | puredanger | or seq? |
| 16:05 | puredanger | who knows what we'd break if we made the results seqable but not seqs |
| 16:06 | puredanger | there are a couple patches (referred to as the "split" impl where I tried this) that allow LazySeq to be created with a second function implementing reduce |
| 16:06 | puredanger | making this a capability that others could use |
| 16:06 | puredanger | but that's pretty dangerous without understanding all the cache tradeoffs and expectations |
| 16:07 | ambrosebs | this is interesting. we probably can't break this at runtime but I could assign less specific static types to sequence functions in core.typed to reflect what could have been. |
| 16:07 | ambrosebs | I thought the contract of seq was returns nil or Seq. |
| 16:07 | ambrosebs | ISeq |
| 16:07 | puredanger | that seems right |
| 16:07 | ambrosebs | but in a perfect world it's nil or Seqable? |
| 16:08 | puredanger | no, I'm saying functions like map, filter, etc should take a seqable and return a seqable |
| 16:08 | ambrosebs | aha |
| 16:08 | puredanger | right now they actually return a seq, which people have come to rely on |
| 16:08 | puredanger | no takebacks! :) |
| 16:08 | amalloy | funnily, usually when people say they want map to take a seqable and return a seqable, they mean they want map on a vector to return a vector |
| 16:09 | puredanger | a vector is a perfectly good seqable :) |
| 16:09 | ambrosebs | puredanger: so I should rely on map returning an *immutable* seqable? |
| 16:09 | puredanger | but I think that desire is wanting even more :) (which you can get with transducers of course) |
| 16:10 | puredanger | seqable is describing potential. I don't know what a mutable or immutable seqable would be |
| 16:10 | puredanger | sequences should always be immutable |
| 16:11 | ambrosebs | so map could return a mutable structure? |
| 16:11 | ambrosebs | theoretically :) |
| 16:11 | ambrosebs | ie. something that returned a different value for first |
| 16:12 | puredanger | once you obtain a sequence from it, I would expect it to always be the same |
| 16:12 | ambrosebs | ah so (seq (map ...)) is immutable but (map ...) is fair game? |
| 16:12 | puredanger | once you open that box with the cat, you'll know whether it's angry |
| 16:12 | puredanger | or dead |
| 16:13 | puredanger | well trying to be careful here about what expectations are now and what they might theoretically have been if we started over designing Clojure knowing what we know now... |
| 16:14 | puredanger | right now, I would say the expectation is that map returns a sequence, which is immutable |
| 16:14 | puredanger | theoretically, it could have committed only to return a seqable, that when poked will yield a sequence, which is immutable |
| 16:16 | amalloy | i feel like there's a lot of code that depends on seqable things returning the same thing when seq'd twice. like, (let [xs (map whatever ys)] (if (empty? xs) "empty :(" (first xs))) |
| 16:17 | puredanger | absolutely |
| 16:18 | puredanger | and that should always work |
| 16:18 | puredanger | but what if xs was an object that only realized itself at the first point when you asked it for a value? |
| 16:19 | puredanger | I'm not saying at all that we are or will change anything about this |
| 16:19 | puredanger | purely in thought experiment land here |
| 16:19 | puredanger | look at LazySeq for example |
| 16:20 | puredanger | it does exactly this kind of thing. when you ask for a seq, it synchronizes and builds it |
| 16:21 | Bronsa | puredanger: I reopened CLJ-1694, you just used a bad example |
| 16:24 | puredanger | thx |
| 16:33 | ambrosebs | puredanger: ah I meant map returns an observationally immutable thing wtr first/next. |
| 16:33 | ambrosebs | which sounds like what you just described. |
| 16:33 | puredanger | yes |
| 17:01 | bacon1989 | so is there a single statement equivalent to (not (nil? <expression>)) with a single form? |
| 17:01 | bacon1989 | like not-nil? |
| 17:02 | bacon1989 | i've been using it constantly, I feel like there should be a function for this already |
| 17:02 | amalloy | bacon1989: in 1.6+ there's some? |
| 17:03 | bacon1989 | amalloy: but doesn't that take a container? |
| 17:03 | amalloy | some?, not some |
| 17:03 | bacon1989 | ,(some? nil) |
| 17:03 | clojurebot | false |
| 17:04 | bacon1989 | ,(some? "value") |
| 17:04 | clojurebot | true |
| 17:04 | bacon1989 | ,(some? [1 2 3]) |
| 17:04 | clojurebot | true |
| 17:04 | bacon1989 | ,(some? []) |
| 17:04 | devn | hello friends and uncles |
| 17:04 | clojurebot | true |
| 17:04 | bacon1989 | interesting |
| 17:04 | justin_smith | devn: hello |
| 17:05 | bacon1989 | that should work, thank you amalloy |
| 17:05 | bacon1989 | i |
| 17:05 | bacon1989 | i'm confused by the name though |
| 17:05 | justin_smith | bacon1989: some as opposed to none? |
| 17:06 | bacon1989 | looking at it that way makes sense, but there's a nil? function, not-nil? |
| 17:06 | justin_smith | sure, (complement nil?) |
| 17:06 | ambrosebs | ,not-nil? |
| 17:06 | clojurebot | #error{:cause "Unable to resolve symbol: not-nil? in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: not-nil? in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: not-nil? in this context",... |
| 17:06 | bacon1989 | i'm just being picky |
| 17:07 | justin_smith | ,(map (complement nil?) [:a [] () nil false]) |
| 17:07 | clojurebot | (true true true false true) |
| 17:07 | bacon1989 | some? is fine, but it's not the first thing I think of, when i'm looking for the complement of nil? |
| 17:07 | ambrosebs | it's like an option type on something being a reference |
| 17:07 | bacon1989 | justin_smith: in that case, i'm better off just sticking with (not (nil? <expr>)) |
| 17:07 | bacon1989 | but some? appears to be a replacement |
| 17:08 | justin_smith | bacon1989: well, complement returns a function, is the difference |
| 17:08 | bacon1989 | oh right |
| 17:31 | lalaland1125 | Hi. I am trying to turn a persistent hashmap into a persistent array map. This is my current attempt "(print (type (apply array-map (flatten (seq {1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1})))))" |
| 17:31 | lalaland1125 | Is this incorrect? |
| 17:31 | lalaland1125 | It doesn't appear to work right in clojurescript. |
| 17:32 | justin_smith | lalaland1125: why do you care whether you have a persistent hashmap vs. persistent array map? |
| 17:32 | justin_smith | as far as I know, array maps above a certain size are always auto-promoted to hash-map |
| 17:32 | lalaland1125 | I am trying to hot fix a library bug. |
| 17:33 | lalaland1125 | The library itself has to be changed to work with hash maps, but a simple fix should put that off. |
| 17:34 | gfredericks | yeah looks like cljs doesn't let you do this the way clj does |
| 17:34 | gfredericks | I feel like I pointed this out to david a year ago or something |
| 17:35 | justin_smith | gfredericks: can you make an arbitrary sized array-map in clj? |
| 17:35 | gfredericks | totes |
| 17:35 | gfredericks | just call array-map |
| 17:35 | gfredericks | ,(type (apply array-map (range 100000))) |
| 17:35 | gfredericks | it's greek to me |
| 17:35 | clojurebot | eval service is offline |
| 17:35 | gfredericks | &(type (apply array-map (range 1000))) |
| 17:35 | lazybot | ⇒ clojure.lang.PersistentArrayMap |
| 17:35 | gfredericks | anyhow there's one with 500 at least |
| 17:36 | lalaland1125 | So its probably a clojurescript bug. |
| 17:36 | gfredericks | I dunno david might disagree |
| 17:36 | justin_smith | lalaland1125: a minor thing - (apply concat {1 2}) is much better than (flatten (seq {1 2})) |
| 17:36 | gfredericks | lalaland1125: what is the problem you're trying to hot fix? |
| 17:36 | justin_smith | because flatten can destroy your data (or cause an odd number of args) |
| 17:36 | lalaland1125 | https://github.com/juxt/bidi/issues/55 |
| 17:39 | justin_smith | lalaland1125: why not fork the lib and put the proper protocol in there instead of the concrete type? https://github.com/juxt/bidi/blob/master/src/bidi/bidi.cljx#L251 |
| 17:40 | gfredericks | lalaland1125: so the problem is that the protocol isn't implemented for hash-map? why not just do that? |
| 17:40 | justin_smith | oh yeah, you can extend that from outside bidi |
| 17:40 | justin_smith | d'oh |
| 17:40 | justin_smith | (inc gfredericks) |
| 17:40 | lazybot | ⇒ 132 |
| 17:41 | justin_smith | ILookup or maybe IAssociative or IMap |
| 17:41 | gfredericks | uh |
| 17:41 | justin_smith | https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L391 |
| 17:41 | gfredericks | no you'd do the concrete class right? |
| 17:42 | gfredericks | I don't think you're supposed to extend protocols to protocols |
| 17:42 | justin_smith | gfredericks: oh, is this extending a protocol to a protocol issue? |
| 17:42 | justin_smith | yeah |
| 17:42 | justin_smith | right, I keep forgetting that |
| 17:47 | lalaland1125 | gfredericks, Your solution worked very well. I am new to clojure and didn't know that you could do that sort of thing outside of the implementing class. |
| 17:49 | justin_smith | lalaland1125: yeah, you don't have to "own" the protocol or the class you are extending it to in clojure. Which would be insane in an OO situation. But hey Madness? THIS IS FPP. |
| 17:50 | justin_smith | mix that with mutation and enough magic and things can still get weird though, of course |
| 18:18 | lewix | hello guys |
| 18:18 | justin_smith | ello, you lost your L |
| 18:18 | lewix | how does clojurescript compare to typescript |
| 18:18 | expez | favorably |
| 18:19 | lewix | @justin_smith, im on my phone ^^ |
| 18:19 | yally04 | Hi all, how would you partition a seq by groups of two values? e.g. [3 4 5 6 7 8] becomes ([3 4] [4 5] [5 6] [6 7]) |
| 18:19 | lewix | expez: the talk of the town is all a out typescript |
| 18:19 | yally04 | It's been way too long since I've written any Clojure and I know this should be very simple! |
| 18:20 | justin_smith | ,(partition 2 1 [3 4 5 6 7 8 'yally04]) |
| 18:20 | clojurebot | ((3 4) (4 5) (5 6) (6 7) (7 8) ...) |
| 18:20 | yally04 | oh man, of course ... |
| 18:20 | yally04 | forgot that partition had that option. |
| 18:20 | yally04 | thank you! |
| 18:20 | lewix | about* |
| 18:20 | justin_smith | np |
| 18:21 | lewix | justin: how would you partition it with map |
| 18:21 | justin_smith | with map? |
| 18:21 | lewix | justin: yup basically reinventing the wheel |
| 18:22 | amalloy | (map list xs (rest xs)) |
| 18:22 | justin_smith | yup, that's the one |
| 18:25 | lewix | amalloy: xs (rest xs)? |
| 18:25 | justin_smith | ,(let [xs [1 2 3 4 5]] (map list xs (rest xs))) |
| 18:25 | clojurebot | ((1 2) (2 3) (3 4) (4 5)) |
| 18:26 | justin_smith | xs is a common name for more than one x in the haskell / ml world |
| 18:26 | lewix | justin can you explain the map function |
| 18:26 | justin_smith | like what it does in general, or what it did that? |
| 18:27 | lewix | i dont understand the logic |
| 18:27 | justin_smith | it takes list, and applies list to one element from xs and one element from (rest xs) |
| 18:31 | justin_smith | then it does the same thing, from the next element of each |
| 18:31 | raspasov | lewix: here |
| 18:31 | raspasov | ,(map list [1 2 3] [4 5 6]) |
| 18:31 | clojurebot | ((1 4) (2 5) (3 6)) |
| 18:31 | raspasov | you're "mapp-ing" list to first element of each collection, then to second elements of each collection, etc |
| 18:31 | lewix | dope. amalloy: how did you think about it so fast? |
| 18:31 | lewix | raspasppv: thanks |
| 18:31 | lewix | justin: thanks |
| 18:31 | amalloy | lewix: it's a very common trick |
| 18:32 | lewix | thanks guys |
| 18:48 | justin_smith | in case anyone was curious, XP table for programmers http://jimkang.com/namedlevels/#/class/programmer |
| 19:15 | mfikes | gfredericks: FWIW David fixed array-map http://dev.clojure.org/jira/browse/CLJS-1189 |
| 19:18 | justin_smith | nice |
| 19:26 | andy___ | Is there a reason (reverse ...) isn't also a transducer? |
| 19:29 | justin_smith | andy___: it needs to create a sequence of the entire input, so transducing would not really help |
| 19:30 | andy___ | I know it needs to buffer, but so does --for instance-- partition-by |
| 19:30 | justin_smith | andy___: but it needs to buffer the entire input, at which point being a transducer has zero benefit |
| 19:31 | justin_smith | I mean, I could imagine an implementation that called rseq on vectors and walked arrays backwards, but we don't even have a non-transducer version of that reverse |
| 19:31 | andy___ | but what if I want to use it for the sake of composability? |
| 19:32 | justin_smith | functions are composible, the only reason transducers are better is they avoid extra unneeded work, with reverse you cannot avoid that work |
| 19:33 | andy___ | hmm I see, I guess it'd be a tough sale since transducers also also supposed to all work with core.async |
| 19:33 | andy___ | and in that case it would just wait until that channel closes |
| 19:33 | justin_smith | right - that would kind of suck |
| 19:34 | catern | dear clojurists |
| 19:34 | andy___ | alright, fair enough. :) |
| 19:34 | catern | if I wanted to convert this object into a clojure map, how would I go about that? http://libvirt.org/sources/java/javadoc/org/libvirt/DomainInfo.html |
| 19:34 | justin_smith | catern: have you tried bean? |
| 19:35 | justin_smith | ,(bean (java.util.Date.)) |
| 19:35 | clojurebot | #error{:cause "denied", :via [{:type java.lang.ExceptionInInitializerError, :message nil, :at [java.lang.reflect.Proxy$ProxyClassFactory apply "Proxy.java" 672]} {:type java.lang.SecurityException, :message "denied", :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}], :trace [[clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69] [clojurebot.sa... |
| 19:35 | justin_smith | err... |
| 19:35 | justin_smith | that usually works :) |
| 19:35 | catern | I found http://stackoverflow.com/questions/7916199/use-java-object-as-clojure-map which suggested bean, but it just returns {:class org.libvirt.DomainInfo} |
| 19:35 | amalloy | justin_smith: this thing doesn't have getters, it has public fields |
| 19:36 | justin_smith | ahh |
| 19:36 | catern | i don't know much about Java so even obvious suggestions are helpful |
| 19:37 | noonian | just to clarify, you want to be able to use an instance of a DomainInfo as a map? or represent the same data as a map? |
| 19:37 | justin_smith | for that few fields you could do it by hand, and look for something more automated if you need to do it for a bunch more classes |
| 19:37 | catern | noonian: yes, or something like that. |
| 19:38 | justin_smith | catern: noonian offered two options |
| 19:38 | catern | justin_smith: there's a bunch of these kinds of objects in the libvirt Java API |
| 19:38 | catern | justin_smith: either of those options is acceptable |
| 19:38 | justin_smith | Ahh, yeah. I have seen reflection based macros to automate such things. |
| 19:39 | andy___ | catern: Check out https://github.com/zcaudate 's libraries. They do a bunch of java interop. Maybe you can find something there |
| 19:49 | catern | justin_smith: what kind of approach could I take there? (.getFields (class info)) and.. then what? |
| 19:52 | justin_smith | catern: a macro could turn a collection of fields to a call to hash-map with keywords named after those fields mapped to their values |
| 19:52 | justin_smith | if the fields of the class are knowable at compile time, of course |
| 19:54 | noonian | hmm, that class looks like it will be mutating constantly though |
| 19:54 | noonian | cputime - the CPU time used in nanoseconds |
| 19:55 | noonian | so that approach would only give you the values when the map is created |
| 19:55 | catern | noonian: true |
| 19:55 | catern | noonian: fortunately in practice actually no, it seems to be immutable |
| 19:55 | catern | (i.e. once I get it, it doesn't change) |
| 19:56 | noonian | if that's the case then what justin_smith is describing is probably the way to go |
| 19:59 | catern | what if instead I |
| 19:59 | catern | did |
| 20:00 | catern | (let [fields (.getFields (class info))] (map (fn [field] [(str field) (.get field info)]) fields)) |
| 20:01 | catern | (into {} that) |
| 20:02 | catern | how awful is that |
| 20:02 | catern | too awful? |
| 20:02 | noonian | not too awful if it works :P |
| 20:03 | catern | but that's heavily abusing reflection |
| 20:03 | catern | which is bad for performance |
| 20:03 | catern | innit |
| 20:03 | noonian | could do a camelCase to kebab-case conversion and turn the keys into keywords if you wanted the maps to follow clojure idioms |
| 20:03 | noonian | yeah, but depending on what you are trying to do it might not matter |
| 20:03 | catern | yeah, something like that (rather than (str field)) |
| 20:04 | catern | er |
| 20:04 | catern | rather than (str field)* |
| 20:05 | catern | yeah, (.getName field) instead |
| 20:10 | raspasov | catern: I don't know the library internals very well, but I believe Amazonica does a very neat two way conversion between Java <-> Clojure |
| 20:10 | raspasov | with the Amazon Java Library |
| 20:10 | raspasov | might be helpful to look at, not sure |
| 20:19 | noonian | heres my quick attempt: https://www.refheap.com/99213 |
| 20:53 | catern | for adding a bunch of new key-value pairs to a map, I should use assoc, right? |
| 20:53 | catern | just checking |
| 20:57 | catern | also! |
| 20:57 | catern | how best to work with XML in Clojure? |
| 20:57 | catern | this thing? https://github.com/clojure/data.xml |
| 20:58 | skelternet | What are you going to do with the XML? |
| 20:59 | catern | look through it for a specific field (or whatever it's called, <tag>the thing in here</tag>) and use the value inside |
| 21:00 | catern | (among other read-only things, possibly. no generation) |
| 21:00 | skelternet | will the target tag always be in the same place in the hierarchy? |
| 21:01 | skelternet | is the xml small? |
| 21:02 | catern | the xml is small |
| 21:03 | skelternet | You'll find a lot of choices. I asked about the size because sometimes XML sources are too large to want to load up as a dom. |
| 21:03 | catern | the target tag will always be in the same place hierarchy (if I understand what you mean. I could always use the same xpath expression) |
| 21:03 | catern | same place in the hierarchy* |
| 21:05 | skelternet | It has been a while. I'd try it with data.xml |
| 21:06 | skelternet | that should get you a clojure data structure from the xml |
| 21:07 | skelternet | ugh…I remember doing this now |
| 21:07 | skelternet | It's version of the datastructure was verbose |
| 21:07 | catern | ewwwww |
| 21:08 | catern | {:tag foo :attrs [foo bar] :content "quux"} |
| 21:08 | catern | that's pretty terrible |
| 21:08 | skelternet | let me look for what I ended up using |
| 21:08 | catern | would be appreciated |
| 21:08 | skelternet | it may have been a zipper |
| 21:10 | skelternet | http://clojure.github.io/data.zip/#toc0 |
| 21:11 | skelternet | Yes…this is what I ended up using. |
| 21:12 | skelternet | I had to scrounge for useful examples, and this was a a year ago or more. |
| 21:12 | skelternet | I'd hope there was a better library or better examples. |
| 21:12 | catern | ehhhhhh |
| 21:12 | catern | http://stackoverflow.com/questions/11215040/available-clojure-xml-parsing-libraries-that-complement-clojure-xml-parse |
| 21:12 | catern | this answer is pretty true |
| 21:12 | skelternet | Once I had the zipper, I could use tags as the predicates |
| 21:12 | catern | I'll just transform this nested thing |
| 21:13 | catern | alternatively, I could just use xpath |
| 21:14 | skelternet | I like that better than the zipper, I think |
| 21:14 | catern | which one? |
| 21:14 | catern | the stackoverflow or the xpath? |
| 21:14 | skelternet | I think I used something like |
| 21:15 | skelternet | (xml-> myxmlzip :outtertag :midtag :innertag text=) |
| 21:15 | skelternet | I like the stackoverflow idea |
| 21:16 | skelternet | seems like it should be a standard part of the xml library though, as frequently as we'd use it |
| 21:19 | amalloy | skelternet: and what if the xml looks like <outertag><midtag>...</midtag><midtag>...</midtag></outertag>? |
| 21:20 | amalloy | the standard xml interface can't really be to treat them like maps, because they can encode structure that isn't mappy |
| 21:21 | skelternet | I'm thinking back to that session with the zipper. |
| 21:22 | skelternet | Quick googling… |
| 21:22 | catern | okay |
| 21:22 | skelternet | Do we stil have xml-seq? |
| 21:22 | catern | I'm pretty sure that The Right Way is xpath |
| 21:23 | skelternet | http://blog.korny.info/2014/03/08/xml-for-fun-and-profit.html |
| 21:23 | catern | a nice, simple, standard, declarative way to navigate XML |
| 21:24 | skelternet | amalloy, I think that if you need all of them, then xml-> otherwise xml1->. |
| 21:25 | skelternet | xml-> returns a sequence of the results of the predicates. Since :outertag :midtag text= can be applied to multiple nodes, I'd expect a sequence of the text of midtags |
| 21:26 | skelternet | I remember thinking at the time I should right a library for the common task of tweaking xml files. |
| 21:26 | skelternet | I was tweaking poms then. |
| 21:27 | skelternet | right/write |
| 21:29 | skelternet | catern, are you just extracting the value and using it, or are you changing the value and hoping to write it out? |
| 21:31 | skelternet | https://github.com/kyleburton/clj-xpath |
| 21:35 | catern | skelternet: just extracting |
| 21:35 | catern | indeed, I am using that library right now |
| 21:35 | catern | and have solved my problem with it :D |
| 21:35 | catern | :) |
| 21:36 | skelternet | you kids these days…with your libraries and your xpath... |
| 21:36 | skelternet | what did the code end up looking like? |
| 21:37 | catern | http://ix.io/hiC |
| 21:43 | skelternet | doesn't seem terrible |
| 21:43 | skelternet | I remember having to review xpath then, too. |
| 21:43 | skelternet | Thanks! |
| 21:46 | skelternet | the memories… |
| 21:51 | guthur | i have a key value list (:foo 1 :bar 2), what is the idomatic way of extracting values from this |
| 21:51 | skelternet | vals ? |
| 21:52 | skelternet | '(vals {:foo 1 :bar 2}) |
| 21:52 | skelternet | ,(vals {:foo 1 , :bar 2}) |
| 21:52 | clojurebot | (1 2) |
| 21:52 | guthur | but it's a list not a map |
| 21:52 | skelternet | ohhh |
| 21:53 | skelternet | ,(into {} '(:foo 1 :bar 2)) |
| 21:53 | clojurebot | #error{:cause "Don't know how to create ISeq from: clojure.lang.Keyword", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: clojure.lang.Keyword", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.lang.ATransientMap conj "ATransientMap.java" 42] [clojure.lang.ATran... |
| 21:54 | skelternet | checking my cheatsheet…seems like I've seen that before and it seemed obvious after I saw it. |
| 21:56 | catern | is ring/compojure/hiccup still my best bet for a simple web application? |
| 21:56 | catern | or, let me put this another way |
| 21:56 | skelternet | ,(hash-map '(:foo 1 :bar 2)) |
| 21:56 | clojurebot | #error{:cause "No value supplied for key: (:foo 1 :bar 2)", :via [{:type java.lang.IllegalArgumentException, :message "No value supplied for key: (:foo 1 :bar 2)", :at [clojure.lang.PersistentHashMap create "PersistentHashMap.java" 77]}], :trace [[clojure.lang.PersistentHashMap create "PersistentHashMap.java" 77] [clojure.core$hash_map doInvoke "core.clj" 369] [clojure.lang.RestFn invoke "RestFn.j... |
| 21:56 | catern | what's the absolute simplest way I can start serving a map over the web? |
| 21:56 | skelternet | ,(apply hash-map '(:foo 1 :bar 2)) |
| 21:56 | clojurebot | {:bar 2, :foo 1} |
| 21:58 | skelternet | Will that get you there, guthar? |
| 21:58 | guthur | skelternet: yeah that looks good, cheers |
| 22:00 | skelternet | catern I think ring/compojure is the quickest I can think of for just that, given no need for REST or anything else. |
| 22:39 | catern | i'm so lazy |
| 22:39 | catern | i'd rather just convert a map directly into HTML |
| 22:39 | catern | like, a list of maps into a table |
| 22:39 | catern | ugh I wrote a function to do this before |
| 22:40 | catern | now I have to write it again (because I can't find my earlier attempt) |
| 22:40 | catern | lame |
| 22:41 | catern | alternatively |
| 22:41 | catern | i'll use something to convert to json |
| 22:42 | catern | er, an actual question instead of complaints: |
| 22:43 | catern | if one tries for a client-side web application, and serves up a bunch of stuff as JSON that is then rendered by Javascript on the front end, is it possible/natural to have this be a traditional multiple-page application or are you pretty much stuck with the single page app? |
| 22:44 | catern | (I don't really know anything about web development) |
| 22:49 | catern | (that's not actually a Clojure question though) |
| 22:59 | nuwanda_ | catern: I don't see why you would be limited to a certain architecture just based on that description |
| 22:59 | catern | OK |
| 22:59 | catern | and, another question |
| 22:59 | catern | I knew this at some point |
| 23:00 | catern | but I've forgotten it :( |
| 23:00 | catern | How should I run a Ring server while developing, so I can keep restarting it as I make changes to my application? |
| 23:00 | catern | It seems to background by default and keep the port bound... so I have to M-x cider-restart |
| 23:03 | tolstoy | catern: For what it's worth, I don't use "lein ring" and so on. I just use a function that starts the server and eval that in the repl. |
| 23:03 | tolstoy | Using http-kit, or jetty-runner, or aleph or something. |
| 23:03 | catern | tolstoy: yeah? I had the same thing, but when I interrupt it, it doesn't seem to actually stop the server. |
| 23:04 | tolstoy | How are you interrupting it? |
| 23:04 | catern | unless this function has the autoreload stuff |
| 23:04 | catern | C-c C-c |
| 23:05 | tolstoy | I just re-evaluate routes and so on, though it's tricky if the handler isn't always re-evaluated each time a request comes in. |
| 23:05 | tolstoy | For instance (run-server (fn [r] (my-routes r)) {:port 8001}) or something like that seems to work. |
| 23:06 | tolstoy | Then you can re-compile my-routes with C-c C-c and have the new functionality take effect without restarting the server. |
| 23:06 | tolstoy | Does any of that make sense? |
| 23:09 | catern | I mean, I'm specifcally using ring/run-jetty |
| 23:10 | tolstoy | You have to, uh, (.close) it, I think? |
| 23:12 | tolstoy | Oh, (.stop server). |
| 23:15 | mgaare | Also, pass your handler to jetty symbol-quoted |
| 23:28 | tolstoy | I seem to have an issue with that in that I pass in deps through there: (make-app db other-thing whatever) which then returns a handler that takes those as params. |