2015-03-26
| 01:46 | wefwef | attempting to run lein repl results in the following: Could not transfer artifact org.clojure:tools.nrepl:pom:0.2.6 from/to central (https://repo1.maven.org/maven2/): java.lang.RuntimeException: Unexpect |
| 01:46 | wefwef | ed error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty |
| 01:47 | wefwef | on OpenJDK Runtime Environment (build 1.8.0_31-b13) |
| 01:47 | wefwef | |
| 01:49 | wefwef | not currently behind proxy, any jvm type settings to check? |
| 02:19 | Kneiva | wefwef: http://stackoverflow.com/questions/4764611/java-security-invalidalgorithmparameterexception-the-trustanchors-parameter-mus ? |
| 02:21 | Kneiva | wefwef: here's one with openJDK http://architecturalatrocities.com/post/19073788679/fixing-the-trustanchors-problem-when-running |
| 03:24 | hamid | hello there :) Would anyone help me solve this one? :P http://clojurescriptkoans.com/#destructuring/7 |
| 03:26 | kungi | hamid: yes I would. I always have a look at this tutorial when I'm not sure about destructuring: http://blog.jayfields.com/2010/07/clojure-destructuring.html |
| 03:27 | hamid | ka2u, awesome thanks. |
| 04:55 | sveri | "Working on siwf in clojure and clojurescript" just went live!, check it out here: http://www.twitch.tv/sveri80 |
| 06:03 | ane | wtf watching people code is now a thing? |
| 06:03 | the_frey | it is? |
| 06:04 | justin_smith | evidently, but hey if people want to watch, why not |
| 06:11 | clgv | half-pair-programming? :P |
| 06:12 | clgv | ane: did you spot plenty of videos being uploaded? |
| 06:18 | justin_smith | clgv: sveri just posted a link |
| 06:23 | clgv | justin_smith: too early for me ;) |
| 06:29 | elvis4526 | Where are static files served when running lein run with http-kit ? |
| 06:30 | justin_smith | elvis4526: whereever you tell ring to look for them (via wrap-static) |
| 06:30 | justin_smith | elvis4526: though generally wrap-resources is better, because it allows serving files from inside an unexploded jar |
| 06:30 | elvis4526 | I use compojure |
| 06:31 | justin_smith | that doesn't change things |
| 06:31 | justin_smith | compojure uses ring |
| 06:31 | justin_smith | ring uses the wrap-static or wrap-resources middleware |
| 06:31 | elvis4526 | sorry i didn't finish what I wanted to say lol |
| 06:31 | elvis4526 | I did (files "/public") in my routes |
| 06:31 | elvis4526 | this is relative to where when running lein run ? |
| 06:32 | justin_smith | I've never used that "files" thing, I've always used wrap-resources or wrap-static, and those are relative to the classpath |
| 06:33 | elvis4526 | classpath = where you're clj file are ? |
| 06:33 | elvis4526 | when deploying into a jar, /public really refer at the root of the jar |
| 06:33 | elvis4526 | (if this is any help) |
| 06:33 | justin_smith | really? that seems like a terrible idea |
| 06:34 | justin_smith | classpath is the set of places where the jvm looks for resources at runtime |
| 06:34 | elvis4526 | where does static file should live ? |
| 06:34 | justin_smith | the primary job for lein is to set up your classpath |
| 06:35 | justin_smith | they can be whereever is convenient, but I typically put them is resources/ and then use wrap-resources to point to the folder they are in |
| 06:35 | justin_smith | eg if I put them in resources/public/ then I use (wrap-resources "public") |
| 06:35 | elvis4526 | so there are available at localhost/public/blabla.js ? |
| 06:35 | justin_smith | right |
| 06:35 | elvis4526 | that's what I did |
| 06:55 | justin_smith | elvis4526: actually, I take that back - if you do (wrap-resources "public") and had the file resources/public/bla.js, you would access it as "localhost/bla.js" |
| 06:59 | sveri | ane clgv justin_smith I tried that a few times now and, the funny thing is, it really helps me concentrate and not get distracted (coding for private things always suffer my procrastination wishes), it's an interesting concept and, at the same time, you can get people attracted to clojure :-) |
| 07:12 | justin_smith | heh, it was interesting to see intellij in action |
| 07:13 | sveri | I was never able ti get productive with emacs, tried it three times for severl hours, but... |
| 07:23 | laurio | justin_smith: wow, didn't know that |
| 07:25 | laurio | i started to use cond instead in order to avoid hard coding values more than once |
| 07:26 | elvis45261 | Is there a way to speed up lein run ? |
| 07:26 | elvis45261 | it's crazy slow. |
| 07:27 | justin_smith | elvis45261: https://github.com/technomancy/leiningen/wiki/Faster |
| 07:27 | justin_smith | LEIN_FAST_TRAMPOLINE is good |
| 07:28 | elvis45261 | that's what I was about to ask |
| 07:28 | elvis45261 | it seems the only "okay" solution |
| 07:28 | justin_smith | another trick is to not use lein at all |
| 07:29 | justin_smith | lein cp > "class_path.txt"; java -cp $(cat class_path.txt) clojure.main -m your.ns |
| 07:30 | justin_smith | but that's only going to be marginally faster than LEIN_FAST_TRAMPOLINE - remember that that only works when you do "lein trampoline run" - "lein run" is not affected by the LEIN_FAST_TRAMPOLINE setting at all |
| 07:39 | agarman | I tried nailgun before, but it becomes convoluted as soon as you have multiple projects or change dependencies or etc. |
| 07:40 | borkdude | ordnungswidrig I'm unsure how to combine existing? and put! or post! I want to enfore that someone can only put! or post! when :exists? is true. but when I set put-to-existing? to true, a normal get responds with a 201.. |
| 07:51 | zoldar | borkdude: you hardcode put-to-existing? to true? |
| 07:53 | borkdude | never mind, it seems to be a glitch because of code reloading in the repl |
| 07:54 | zoldar | borkdude: ok |
| 07:54 | zoldar | borkdude: I suppose that you are aware of this: http://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg |
| 07:54 | borkdude | zoldar yes |
| 07:55 | zoldar | just making sure |
| 09:09 | borkdude | ordnungswidrig I'm still not sure how I must do this with liberator: someone puts!, but if the thing doesn't exist? it should return a 404 |
| 09:10 | borkdude | ordnungswidrig I have implemented :exists? and set :can-put-to-missing? to false, but that doesn't work |
| 09:10 | justin_smith | borkdude: I thought the idea with PUT is that it creates a resource where there wasn't one previously |
| 09:10 | borkdude | justin_smith I thought that was post |
| 09:11 | borkdude | justin_smith maybe I'm wrong |
| 09:11 | justin_smith | borkdude: the relevant rfc http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html |
| 09:12 | justin_smith | "The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line." |
| 09:12 | justin_smith | "The PUT method requests that the enclosed entity be stored under the supplied Request-URI." |
| 09:17 | justin_smith | borkdude: so maybe you don't want PUT requests at all, and actually want only POST to be allowed? |
| 09:18 | borkdude | justin_smith in plain english: I want to store an attribute/column in an existing record. which should I use then? |
| 09:18 | justin_smith | post |
| 09:18 | justin_smith | put is for making new records |
| 09:18 | justin_smith | post is for adding details to something that is already there |
| 09:19 | borkdude | ok |
| 09:20 | justin_smith | like, if this were eg. reddit, "put" would be for creating a new link, and "post" would be for adding a comment to that link |
| 09:20 | borkdude | justin_smith so put for a new "top level" thing |
| 09:20 | justin_smith | yeah |
| 09:21 | sveri | borkdude: idempotent is the word you are looking for here, if your operation adds something and is idempotent, make it a PUT. Otherwise make it a POST |
| 09:21 | justin_smith | sveri: it's not just that though. He wants a 404 for a non-existing URL, which is something POST would do, but not PUT |
| 09:22 | justin_smith | PUT would just create the new thing |
| 09:22 | justin_smith | (if PUT is accepted at the route targeted, of course) |
| 09:22 | sveri | justin_smith: ok, sry, I joined to late I guess and misunderstood the question |
| 09:24 | borkdude | for sake of understanding, it's this resource I'm talking about: https://www.refheap.com/98907 |
| 09:24 | borkdude | I would expect a POST to listen to existing?, but that's not what's happening |
| 09:26 | sveri | borkdude: "listen to existing?" what do you mean exactly? |
| 09:28 | borkdude | ehm, I mean: it will return a 404 when exists? is nil or false |
| 09:29 | sveri | hm, just shooting blindly here, what does (if-let return? maybe try an if statement instead of if-let? |
| 09:29 | justin_smith | sveri: if-let returns the same as if would |
| 09:29 | borkdude | (if-let [a nil] a) is nil |
| 09:29 | sveri | kk |
| 09:29 | justin_smith | it just adds a convenient let binding |
| 09:30 | justin_smith | borkdude: and I assume you have verified that answers/read-by-invitation isn't returning () |
| 09:30 | justin_smith | since () is truthy of course |
| 09:30 | borkdude | ah, I should set can-post-to-missing? to false |
| 09:31 | borkdude | https://www.dropbox.com/s/0inkfr1wwsqqpm2/Screenshot%202015-03-26%2014.30.00.png?dl=0 |
| 09:31 | justin_smith | that sounds applicable. I've been meaning to try liberator. |
| 09:31 | borkdude | thanks for thinking along guys |
| 09:32 | justin_smith | so that fixed it? |
| 09:32 | sveri | yea, that looks nice |
| 09:32 | sveri | borkdude: do you handle authentication / authorization with liberator? |
| 09:32 | borkdude | sveri authentication no, authorization yes |
| 09:33 | sveri | is your code publicy available? I'd like to have a look at it |
| 09:33 | borkdude | sveri I'm using lib-noir for authentication |
| 09:34 | borkdude | sveri but I wouldn't go there anymore, since it's deprecated by luminus |
| 09:34 | sveri | hm, I see |
| 09:34 | borkdude | sveri just look at the luminus website how to do authentication and then use :authorized? (fn [ctx] .... (-> ctx :request :session ...)) etc to authorize whatever you like |
| 09:35 | sveri | Ok, so no fancy wrapper / abstraction stuff like friend |
| 09:35 | borkdude | sveri no. I tried friend, but I never got the hang of it |
| 09:36 | sveri | I dropped friend in favor of buddy, which seems pointless after I finally grasped friend :D |
| 09:36 | borkdude | sveri buddy is also used in luminus |
| 09:36 | borkdude | sveri I kind of fall back on luminus for standard web stuff, so my colleagues can look at that if they have to work on my project in the future. nice references |
| 09:37 | sveri | Yea, he really put a lot of effort into the documentation. I used it as a reference for my own template |
| 09:53 | dxlr8r | hello. small question. how do I join/concat regex patterns? |
| 09:53 | clgv | dxlr8r: you dont. |
| 09:53 | dxlr8r | I have a usecase where I need it to not repeat myself |
| 09:53 | clgv | dxlr8r: you can concat strings to a single string and convert that to a regex |
| 09:54 | dxlr8r | hmmm |
| 09:54 | dstockton | use re-pattern and combine the patterns as strings |
| 09:54 | justin_smith | dxlr8r: ##(re-seq (re-pattern (str #"a" #".")) "bananananana") |
| 09:54 | lazybot | ⇒ ("an" "an" "an" "an" "an") |
| 09:54 | clgv | maybe you can get the string representation back from the regex |
| 09:54 | justin_smith | clgv: yup |
| 09:54 | justin_smith | and then create a new regex from that |
| 09:55 | dxlr8r | justin_smith: thx :) |
| 09:55 | dxlr8r | will use re-pattern. how could I overlook that? :) |
| 09:57 | catern | dear #clojure |
| 09:57 | catern | is there a way I can easily get my incanter data into my LaTeX document? |
| 09:58 | catern | like, for R there is something (I think) where you can just put R variables or something into your LaTeX, and they will get filled in at pdflatex time |
| 09:58 | catern | is there anything clever I could do to get that for Incanter...? |
| 09:59 | dxlr8r | justin_smith: I get "unsupported escape character" when I try to store my regex |
| 09:59 | dxlr8r | \d that is |
| 09:59 | dxlr8r | need to use \\ :/ stupid :P |
| 10:00 | justin_smith | dxlr8r: or you can do what I did above (str #"\d" #"whatever") |
| 10:00 | justin_smith | #"" requires less escaping |
| 10:00 | dxlr8r | hmmm |
| 10:02 | dxlr8r | nice :) thanks for having patient with a total clojure idiot... come to think of it, not that good on programming in general :) |
| 10:08 | clgv | catern: sure 3-4 lines of clojure get that done |
| 10:08 | catern | clgv: er, how? |
| 10:08 | clgv | catern: just write out the columns then iterate over the rows |
| 10:08 | catern | what |
| 10:09 | catern | think you're answering someone else's question :) |
| 10:09 | clgv | (str/join " & " column-values) will do the table stuff for altex |
| 10:09 | clgv | catern: nope yours |
| 10:09 | catern | I don't want to do table stuff |
| 10:09 | catern | I have no tables, just single values |
| 10:10 | clgv | catern: what is "incanter data"? just values? |
| 10:10 | catern | yes |
| 10:10 | catern | I mean |
| 10:10 | clgv | well just copy them over then |
| 10:10 | catern | I have table data as well |
| 10:10 | catern | clgv: :/ |
| 10:10 | catern | uh |
| 10:10 | catern | no? |
| 10:10 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 10:11 | justin_smith | clojurebot: you're weird. |
| 10:11 | clojurebot | excusez-moi |
| 10:11 | catern | clgv: i'd rather not? |
| 10:11 | clgv | catern: I guess I dont understand what your problem is. |
| 10:11 | catern | nevermind |
| 10:11 | catern | clgv: have you ever used R and LaTeX together? |
| 10:12 | clgv | you found out that your p-value is 0.031 and want to have that in latex - then just copy the 0.031 over there. |
| 10:12 | ticking | lol |
| 10:12 | catern | clgv: I want that value to update when I re-run the analysis |
| 10:12 | catern | which you can do with R and LaTeX, http://en.wikipedia.org/wiki/Sweave |
| 10:12 | clgv | catern: well then you maybe want some kind of templating |
| 10:12 | ticking | catern: an you want it in what context? |
| 10:12 | catern | clgv: yes, agreed |
| 10:15 | clgv | catern: the sweave approach looks frightening |
| 10:15 | ticking | catern: sorry I mist most of the discussion what is the tool you want to use? gorilla repl, clojure ipython? plain html? |
| 10:15 | clgv | how do you plan to submit latex sources to a journal? |
| 10:15 | catern | clgv: I plan to make a PDF? |
| 10:15 | clgv | catern: I guess having a latex file with place holders for the computed values, is probably the best approahc |
| 10:16 | catern | clgv: are you telling me to copy them in again? |
| 10:16 | clgv | catern: journals almost always want your latex ;) |
| 10:16 | catern | again, would rather not copy this stuff in manually |
| 10:16 | clgv | catern: no. your program can readin the latex file and fill in the values automatically |
| 10:16 | catern | so templating |
| 10:16 | catern | yes |
| 10:16 | clgv | so you use the latex file as template |
| 10:16 | catern | suggestions? |
| 10:17 | clgv | catern: we have used selmer for html templating |
| 10:17 | clgv | should work with latex as well |
| 10:17 | ticking | http://www.tetrisrockstar.com/dynamic-latex-documents-with-clojure-and-fleet/ |
| 10:18 | catern | ticking: thank you but I have already googled and seen that |
| 10:18 | ticking | catern: k |
| 10:18 | clgv | ticking: interesting |
| 10:19 | clgv | catern: looking at fleet, I'd stick with selmer for your requirements |
| 10:34 | irctc__ | Can someone point me in the right direction? I'd like to idiomatically turn a sequence of hash-maps with keys :a :b :c to a new sequence of hash-maps with only keys :a and :c |
| 10:34 | irctc__ | so ({:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}) becomes ({:a 1 :c 3}{:a 4 :c 6}) |
| 10:35 | tatut | (map #(dissoc % :b) coll) |
| 10:35 | justin_smith | &(map (partial select-keys [:a :c]) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}]) |
| 10:35 | lazybot | ⇒ ({} {}) |
| 10:35 | Bronsa | ,(map (partial dissoc :b) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}]) |
| 10:35 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentMap> |
| 10:35 | irctc__ | ahh dissoc |
| 10:35 | Bronsa | ,(map #(dissoc % :b) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}]) |
| 10:35 | clojurebot | ({:a 1, :c 3} {:a 4, :c 6}) |
| 10:35 | justin_smith | &(map #(select-keys % [:a :c]) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}]) |
| 10:35 | lazybot | ⇒ ({:c 3, :a 1} {:c 6, :a 4}) |
| 10:35 | irctc__ | without looking it up, can it handle multiple keys to dissoc at the same time? |
| 10:35 | Glenjamin | (doc select keys) |
| 10:35 | clojurebot | #error{:cause "Wrong number of args (2) passed to: core/eval54/fn--55/my-doc--56", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: core/eval54/fn--55/my-doc--56", :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6628]}], :trace [[clojure.lang.Compiler macroexpand1 "Compiler.java" 6628] [clojure.lang.Compiler macroexpand "Compiler.java" 6694] [clojure.lang.Compiler eval "Compiler.java" 676 |
| 10:35 | clgv | irctc__: or select-keys depending on the exact use case ;) |
| 10:35 | irctc__ | aah |
| 10:36 | Bronsa | irctc__ yes |
| 10:36 | justin_smith | irctc__: dissoc is varargs, but select-keys is closer to what you want I think |
| 10:36 | irctc__ | thanks all! select-keys/dissoc |
| 10:36 | Glenjamin | hrm, no response to my doc request :( |
| 10:36 | justin_smith | Glenjamin: you had a typo |
| 10:36 | Glenjamin | oh |
| 10:36 | Glenjamin | haha |
| 10:36 | Glenjamin | that stack trace makes sense now |
| 10:47 | clgv | oh clojurebot changed to string-serializable exceptions? |
| 10:47 | stuartsierra | No, Clojure did! |
| 10:47 | dysfun | why can't i (defn [f & fs :as all-fs] all-fs) ? |
| 10:47 | clgv | ,(clojure-version) |
| 10:47 | clojurebot | "1.7.0-master-SNAPSHOT" |
| 10:47 | clgv | stuartsierra: for real? is there some blog post or similar about that? |
| 10:48 | clgv | stuartsierra: is it just a printmethod impementation? |
| 10:48 | patrickgombert | clgv: https://github.com/clojure/clojure/commit/692645c73c86d12c93a97c858dc6e8b0f4280a0b |
| 10:48 | stuartsierra | dysfun: Because function arity is not the same thing as destructuring, although they share the same syntax. |
| 10:49 | clgv | patrickgombert: thanks |
| 10:49 | dysfun | okay. is there something cleaner than do what i've done and just use a let underneath and a precondition to assert length is pos? |
| 10:50 | patrickgombert | clgv: it’s a nice change, really useful for quickly scanning |
| 10:51 | clgv | hopefully nil-safe ;) |
| 10:52 | clgv | uhh there is a (set! *warn-on-reflection* true) i it... :P |
| 10:53 | justin_smith | dysfun: how about (defn [& [f & fs :as all-fs]] all-fs) |
| 10:53 | dysfun | ewww :) |
| 10:54 | justin_smith | it does what you want though |
| 10:54 | dysfun | yeah, not denying it :) |
| 10:54 | dysfun | still need the precondition |
| 10:55 | dysfun | obviously i could write a macro, |
| 10:56 | clgv | a (set! *warn-on-reflection* true) in core_print.clj is going to be fun ;) |
| 10:59 | catern | hmmm |
| 10:59 | catern | clgv: Actually I asked in #latex and have a somewhat better idea |
| 10:59 | catern | you can generate them in the form \def\foo{val} from within the clojure (or whatever else you use) script and then \input{|"script"} |
| 11:00 | catern | (where "script" is something that outputs \def\foo{val} on stdout) |
| 11:00 | catern | and \input includes that into the document |
| 11:00 | clgv | catern: yeah, pretty similar approach but limiting the document generation to the external file |
| 11:01 | catern | clgv: to the external file? |
| 11:01 | catern | it seems like a really good approach - at first I was hesistant because I'd need to define all my variables that I wanted to include in advance |
| 11:01 | clgv | you do not include an external file ? |
| 11:02 | catern | clgv: oh, no no, \input{|"script"} executes script and includes its stdout into the document |
| 11:02 | clgv | you want to actually run a clojure program from the \input statement? |
| 11:02 | catern | very unixy :) |
| 11:02 | catern | clgv: definitely! |
| 11:02 | catern | some lein task, probably |
| 11:03 | clgv | haha, your editing will suck due to the much longer latex compilation duration ;) |
| 11:03 | catern | clojure startup times :( |
| 11:03 | catern | the worst thing about clojure |
| 11:04 | clgv | better use \include{constants.tex} and generate that file via a manual call to your clojure program |
| 11:04 | justin_smith | catern: what about if "script" was "curl localhost/clojure-server/get-data" |
| 11:04 | justin_smith | then you don't have to wait for startup |
| 11:04 | clgv | justin_smith: woah, complexity is exploding! :P |
| 11:04 | catern | justin_smith: hey, that's smart and also a TERRIBLE HACK |
| 11:04 | catern | but I like it |
| 11:04 | justin_smith | hehe |
| 11:05 | justin_smith | grench is similar |
| 11:05 | justin_smith | but maybe less hackish |
| 11:05 | justin_smith | you just have one clojure process running, and use grench to get a result from it |
| 11:05 | clgv | catern: whats wrong with generating the "constants.tex" - it's like the suggested apporach from #latex but without the high costs of running the clojure program on every latex compilation |
| 11:06 | catern | clgv: that's good too I suppose |
| 11:06 | catern | I actually like justin_smith's suggestion |
| 11:06 | clgv | tikz has a similar approach by using "externalization" as they call it |
| 11:06 | catern | I mean all of these are small layers around the central functionality of generating some LaTeX |
| 11:06 | catern | maybe I will write a library to generate LaTeX from Clojure values |
| 11:07 | justin_smith | catern: you could call it 'org mode' |
| 11:07 | catern | justin_smith: :) |
| 11:07 | catern | justin_smith: hey, not really though |
| 11:07 | justin_smith | I know |
| 11:07 | clgv | catern: with the implementation of (format "\def\%s{%s}" (sanitize name) (value)) ? ;) |
| 11:08 | dysfun | clgv: from that paste above, i'm intuiting that in clojure 1.7 they're making the core better behaved. is that something they're trying to do? |
| 11:08 | catern | clgv: well, what if you have a seq you want to include, or a seq of seqs? (for some reason..) |
| 11:08 | justin_smith | clgv: for scalars, but what about structured types? |
| 11:09 | catern | maybe it should just be part of Incanter, because I can't see much use in including a dict in LaTeX |
| 11:09 | justin_smith | catern: it's just the kind of thing that org mode does - it can do both (embedding clojure code / results, generating latex) |
| 11:10 | catern | justin_smith: org-mode does embedding clojure code? |
| 11:10 | catern | then I have no need for this! |
| 11:10 | clgv | justin_smith: he definitely needs to specify some strucutre of what is supposed to be rendered to latex .. |
| 11:10 | catern | justin_smith: please, tell me more |
| 11:10 | justin_smith | catern: http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-clojure.html |
| 11:11 | catern | oh |
| 11:11 | catern | yes |
| 11:11 | clgv | dysfun: not sure to what you refer exactly |
| 11:11 | catern | I see that |
| 11:11 | catern | pretty nice |
| 11:11 | justin_smith | "org-babel-clojure allows Clojure code to be executed directly within embedded code blocks in Org-mode documents. These code blocks and their results can be included in an exported document." -- export options include latex |
| 11:11 | dysfun | is there a reliable way to get an empty version of a given collection? |
| 11:11 | zerokarmaleft | catern: it's a rabbit hole, but check out https://github.com/thi-ng/geom and other repositories for org-mode+babel+clojure literate craziness |
| 11:11 | catern | justin_smith: yeah, I've been writing all this in org-mode anyway :) |
| 11:12 | dysfun | clgv: setting warn on reflection is presumably attempting to tighten up the behaviour of the core to be a bit higher quality and eliminate performance defects. is this an intended goal for 1.7? |
| 11:12 | justin_smith | dysfun: ##(map empty ["a" {:a 0} [1 2 3] #{:a}]) |
| 11:12 | lazybot | ⇒ (nil {} [] #{}) |
| 11:12 | clojurebot | Titim gan éirí ort. |
| 11:12 | dysfun | justin_smith: oh brilliant, thanks! |
| 11:12 | clgv | dysfun: I guess it ended up there by accident |
| 11:12 | justin_smith | dysfun: as you see, it might not do what you want for strings, (which aren't really collections I guess) |
| 11:13 | clgv | dysfun: enforcing reflections warnings is not a good idea in general - that has generated a lot of noise already with some libraries where it ended up in a release by accident |
| 11:15 | justin_smith | catern: haha, nice, looking at clojure-babel in more detail, they actually include an example of using incanter inside clojure inside org-mode to generate latex |
| 11:15 | justin_smith | ~emacs |
| 11:15 | clojurebot | emacs is finicky to configure and often broken |
| 11:15 | catern | justin_smith: yeah, I saw that, which is great |
| 11:16 | catern | clojurebot: hey! :( |
| 11:16 | clojurebot | No entiendo |
| 11:16 | clgv | ,(print "catern: :P") |
| 11:16 | clojurebot | catern: :P |
| 11:26 | catern | such emacs bashing |
| 11:27 | catern | you'll drive people to worse things |
| 11:27 | catern | they'll think you're being serious! |
| 11:27 | catern | keep emacs bashing to #emacs |
| 11:28 | J_Arcane | :( I am bombing the extra credit in the UofH Clojure course. :P |
| 11:28 | BinaryResult | A reminder: Disco Melee is currently hiring clojure devs https://docs.google.com/document/d/1GvnrSCUbYgbY9XdFs_DUx-0QZG2bIYT8Mbr0zdpTeew/edit?usp=sharing |
| 11:29 | bacon1989 | they have a clojure course? |
| 11:29 | bacon1989 | that would be awesome |
| 11:30 | J_Arcane | http://iloveponies.github.io/120-hour-epic-sax-marathon/index.html |
| 11:36 | borkdude | in liberator, when someone uploads a file I consider too big, what should I respond with? |
| 11:37 | jonathanj | all my dependency versions are hardcoded in project.clj, which is great because nothing magically updates them underneath me breaking all my code. but is there a way to find out if any of my project deps have a newer version? |
| 11:37 | borkdude | jonathanj lein ancient |
| 11:37 | justin_smith | jonathanj: lein ancient |
| 11:37 | jonathanj | guess that's a lein plugin i need to depend on |
| 11:37 | ordnungswidrig | borkdude: valid-entity-length? => false |
| 11:39 | borkdude | ordnungswidrig ok. I was thinking of returning a 413. I'll try valid-entity-lenght? and see what happens |
| 11:40 | ordnungswidrig | borkdude: liberator will return a 413 if valid-entity-length? returns false |
| 11:40 | borkdude | ordnungswidrig cool. I didn't see it in the decision graph, so I wondered |
| 11:40 | clgv | ~emacs |
| 11:40 | clojurebot | emacs is finicky to configure and often broken |
| 11:41 | ordnungswidrig | borkdude: it comes after `known-content-type` |
| 11:41 | borkdude | ordnungswidrig you're right. I see it now. A bit blind I guess :) |
| 11:42 | justin_smith | borkdude: I think Control-f works in svg |
| 11:42 | ordnungswidrig | borkdude: well, there's always the list of decisions which is search-able. But you need to know what to search for |
| 11:42 | sritchie | hey all - I’m looking at shadow build and seeing something about lein run I hadn’t known |
| 11:42 | borkdude | justin_smith yes, I done that, but I could not find 413. It seems in the decision graph the arrow goes to 415 |
| 11:42 | clgv | borkdude: that monster graph might need an interactive search ;) |
| 11:42 | sritchie | if you provide a keyword like :project/cljs to lein run, does that fetch that entry in the project map? |
| 11:43 | justin_smith | borkdude: oh, OK |
| 11:43 | borkdude | ordnungswidrig the arrow at false goes to 415. https://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg |
| 11:43 | borkdude | ordnungswidrig I searched for 413, that's why I could't find it :) |
| 11:43 | justin_smith | borkdude: I just found it under 413 |
| 11:44 | justin_smith | https://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg |
| 11:44 | justin_smith | on the left side, right under 503 |
| 11:44 | ordnungswidrig | justin_smith: oh, I guess that is outdated *grr* |
| 11:44 | justin_smith | ordnungswidrig: oh, the one I linked to is outdated? |
| 11:44 | ordnungswidrig | oh no, that's the right one but there' a 413 left of 422 for me?! |
| 11:45 | borkdude | ah dude, I'm really blind today :) |
| 11:45 | borkdude | ordnungswidrig justin_smith you're right, sorry |
| 11:45 | justin_smith | yes, and under 503, or se of it :) |
| 11:45 | ordnungswidrig | hahaa |
| 11:45 | justin_smith | ordnungswidrig: perhaps I miscommunicated |
| 11:46 | ordnungswidrig | borkdude: so we're fine? |
| 11:46 | borkdude | ordnungswidrig absolutely. |
| 11:46 | sritchie | anyone know about passing :project/key args in lein? |
| 11:46 | sritchie | to lein run |
| 11:47 | ordnungswidrig | ,anyone |
| 11:47 | stuartsierra | When did org-clojure get CIDER support? |
| 11:47 | clojurebot | #error{:cause "Unable to resolve symbol: anyone in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: anyone 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: anyone in this context", :at [... |
| 11:47 | ordnungswidrig | stuartsierra: CIDER support?! |
| 11:47 | stuartsierra | http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-clojure.html |
| 11:47 | justin_smith | sritchie: args to lein run will be the args passed to -main, and all be strings, right? |
| 11:47 | sritchie | except for this cryptic comment: https://github.com/technomancy/leiningen/blob/master/src/leiningen/run.clj#L146 |
| 11:48 | sritchie | justin_smith: and the examples in shadow-build have you passing :project/cljs |
| 11:48 | ordnungswidrig | stuartsierra: sweeeeet |
| 11:48 | sritchie | which I think grabs that entry out of project.clj |
| 11:48 | stuartsierra | Haven't tried it yet; I rolled my own org-clojure a while ago. |
| 11:48 | sritchie | justin_smith: trying to find the piece of code that handles that though |
| 11:48 | justin_smith | sritchie: wow, that's a weird feature |
| 11:48 | sritchie | yup, undocumented as far as I ca tell |
| 11:53 | borkdude | I just noticed that a method call also works in thread-first: (-> ctx :tempfile .length) |
| 11:54 | justin_smith | borkdude: also works with doto |
| 11:54 | ordnungswidrig | borkdude, justin_smith: did that change recently? I'm pretty sure that there was a time where that would not work |
| 11:54 | clgv | justin_smith: but borkdude is probably interested in that value of .length ;) |
| 11:55 | justin_smith | clgv: yes, related fact |
| 11:55 | clgv | ordnungswidrig: no always worked since 1.2.1 |
| 11:55 | Bronsa | ordnungswidrig: always worked afaik |
| 11:55 | justin_smith | ordnungswidrig: I don't ever remember it not working |
| 11:55 | clgv | ordnungswidrig: you might get problems with typehints depending on the concrete form |
| 11:59 | _kardan | Anyone familiar with Bidi? I'm trying to use redirects but can't get it to work https://gist.github.com/kardan/8758aa14ca8c90970bcc what am I doing wrong? |
| 12:00 | sritchie | justin_smith: boom: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/main.clj#L251 |
| 12:00 | ordnungswidrig | _kardan: I think you must not wrap the #".*" in brackets. |
| 12:01 | justin_smith | sritchie: there it is. Still think it's a weird feature :) |
| 12:01 | sritchie | yeah, definitely |
| 12:01 | sritchie | especially because you can’t nest - |
| 12:02 | sritchie | I was looking into this because I wanted to provide shadow with a config for each of two profiles |
| 12:02 | sritchie | the fact that you can only pull top level keys is odd |
| 12:02 | justin_smith | sritchie: and because ideally lein shouldn't even be present at production run time |
| 12:03 | sritchie | yeah, the “prod” build would be more for building the production version of clojurescript |
| 12:08 | _kardan | ordnungwidrig true, but didn't fix my issue. Thanks anyway |
| 12:08 | borkdude | is is possible to get the reponse's status with Google Closure iframeIo? |
| 12:09 | nullptr | borkdude: you can know it failed but i don't think you can get the specific response code/status |
| 12:10 | borkdude | nullptr ok |
| 12:10 | nullptr | actually -- that's just from the event |
| 12:10 | nullptr | looks like it has getLastErrorCode and getLastError |
| 12:13 | borkdude | nullptr in the case of a 413 response, the success is still true. but I can just use the innerHTML to see if the file was too big |
| 12:14 | nullptr | borkdude: it looks like there's a setErrorChecker hook there so you could probably inject your check there to influence isSuccess |
| 12:15 | borkdude | nullptr it does not even reach the error state |
| 12:15 | borkdude | nullptr oh wait, sorry, my bad |
| 12:15 | borkdude | nullptr I'll try it |
| 12:16 | anti-freeze | Hey everyone. Does anyone know how I add a custom if statement in selmer? I want to add an if-authenticated block |
| 12:18 | anti-freeze | Maybe just a function or something to check if the user is authenticated? |
| 12:19 | clgv | anti-freeze: cant't you just use an authenticated property? |
| 12:19 | anti-freeze | clgv: You mean passing it as a parameter after every render? |
| 12:19 | anti-freeze | before* |
| 12:19 | anti-freeze | so (render-file "auth.html" {:authenticated false}) |
| 12:20 | clgv | yeah, just include that property to your property map |
| 12:22 | anti-freeze | clgv: I would, but this is needed for every single render, as its in the base template. I found something in the selmer source, maybe it could help. https://github.com/yogthos/Selmer/blob/master/src/selmer/tags.clj |
| 12:24 | borkdude | nullptr thanks for that suggestion. works great :) |
| 12:25 | clgv | anti-freeze: so? there might be other properties you also need in the base template sooner or later |
| 12:26 | anti-freeze | clgv: I do, but passing the same thing around to every template seems a little annoying, considering I can just check that value against the session :identity key |
| 12:26 | clgv | anti-freeze: ah, right, I'd have a central function for rendering which takes care of such properties |
| 12:26 | clgv | anti-freeze: humm, a tag could be possible solution, not entirely sure |
| 12:30 | noncom | how do i set charset for a post request in clj-http? |
| 12:30 | noncom | (for a multipart post request) |
| 12:30 | anti-freeze | clgv: I'll give it a shot and report back |
| 12:45 | anti-freeze | clgv: Still no luck. I get compiler errors |
| 12:46 | anti-freeze | clgv: https://www.refheap.com/98909 |
| 12:48 | clgv | anti-freeze: I did not implement a tag myself so far... |
| 12:49 | anti-freeze | clgv: This is beginning to annoy me. See, I need it for base.html which is where all other templates extend from. It would be horrible if I had to pass it as a parameter with every request |
| 12:50 | clgv | anti-freeze: can't you implement the single render function (render-template url, prop-map) that adds the auth property to prop-map before rendering with selmer? |
| 12:50 | clgv | anti-freeze: pretty easy fix ;) |
| 12:51 | anti-freeze | clgv: Maybe. I'll give selmer another go and then I'll just do that. Not the best fix however |
| 12:51 | clgv | anti-freeze: why? |
| 12:51 | anti-freeze | clgv: I don't know. I used selmer because of its "extensibility" |
| 12:52 | clgv | anti-freeze: ah ok. well, read up on the docs - maybe you overlooked some info on custom tags |
| 12:56 | supersym | you know what I love about Clojure? Every time I think "Hey, let's try and see if this or that works....", it actually does. |
| 12:57 | supersym | contrary to my recent php experiences which were the exact opposite ... lol |
| 12:57 | clgv | haha :D |
| 13:01 | borkdude | just checking, but would processable? be the correct decision point to check wether an upload is an image? |
| 13:02 | borkdude | in liberator that is |
| 13:02 | supersym | erh depends I guess? sometimes client side but you mention upload, as in its on the server already? |
| 13:02 | supersym | ah |
| 13:04 | borkdude | supersym yes, I don't trust my clients ;) |
| 13:19 | sritchie | anyone here using shadow-build, or its live reload feature? |
| 13:21 | borkdude | cool library: pantomime. (-> picture :tempfile mime-type-of image?) |
| 13:28 | timvisher | poll: Clojure version of 'pythonic'? |
| 13:28 | timvisher | i tend to say 'clojurey' but that both looks and sounds a little dumb to me (^_^) |
| 13:28 | timvisher | 'clojury'? |
| 13:28 | timvisher | :\ |
| 13:29 | justin_smith | I tend to just call it "OK" as in "that code's OK" or "that isn't actually OK" |
| 13:29 | justin_smith | but perhaps there should be a clojure flavored version of that |
| 13:29 | justin_smith | :clojure/acceptable? |
| 13:31 | Glenjamin | "simple" |
| 13:31 | justin_smith | (inc Glenjamin) |
| 13:31 | lazybot | ⇒ 17 |
| 13:31 | clgv | O_o |
| 13:32 | Glenjamin | although knowing to use (next) over (rest), (seq) over (empty?) etc |
| 13:32 | Glenjamin | i guess that's more what we're talking about |
| 13:42 | sritchie | tomjack: hey, are you https://github.com/tomjakubowski by any chance? |
| 13:43 | bendlas | timvisher: I'd have to say 'idiomatic' |
| 13:43 | bendlas | even though that can be used in other languages as well, it's particularly idiomatic to call something 'idiomatic' in clojure |
| 13:44 | dnolen | sritchie: tjakubow is who you're looking for |
| 13:44 | sritchie | dnolen: you might be interested in this “bug” I found, as it might come up - |
| 13:44 | sritchie | dnolen: shadow-build implements live-reloading with goog.isProvided_ |
| 13:44 | sritchie | https://github.com/thheller/shadow-build/blob/fe129c26d68572991ef1ccdbd1da8e4dfbdb6277/src/cljs/shadow/cljs/live_reload.cljs#L26 |
| 13:44 | dnolen | sritchie: I don't use shadow-build |
| 13:45 | dnolen | sritchie: and I'm becoming less interested in what other tools are doing, it's too hard to follow now |
| 13:45 | sritchie | dnolen: for sure. just wanted to thank you, since I think your patch here fixed that issue https://github.com/tomjakubowski/weasel/pull/54/files |
| 13:45 | dnolen | sritchie: that logic also incorrect |
| 13:46 | dnolen | sritchie: see cljs.browser.repl/bootstrap |
| 13:46 | dnolen | anything else is not going to work |
| 13:46 | sritchie | thanks, I’ll get a patch up |
| 13:46 | dnolen | sritchie: just load that ns and call it, it's meant to be reused |
| 13:47 | sritchie | dnolen: you mean in weasel |
| 13:47 | dnolen | sritchie: that's right, there's already a PR for this, or comment about it |
| 13:48 | dnolen | hrm or I thought there was ... |
| 13:49 | sritchie | https://github.com/tomjakubowski/weasel/blob/master/src/cljs/weasel/repl.cljs |
| 13:49 | sritchie | dnolen: looks like you handled it already |
| 13:49 | sritchie | 5 days after that other commit I sent |
| 13:50 | dnolen | sritchie: heh |
| 13:50 | dnolen | sritchie: yeah cemerick has been fixing up piggieback pretty good, it should just work if you're willing to go bleeding edge |
| 13:50 | timvisher | all of these suggestions are generic though |
| 13:51 | sritchie | dnolen: anyway, this “only reload required things” is a busted optimization, since you might want to redefine multimethods that never get explicitly required |
| 13:51 | dnolen | otherwise, wait till he announces this stuff, we're releasing a version of ClojureScript just for nREPL users |
| 13:51 | timvisher | as in they'd be just as applicable in any community |
| 13:51 | timvisher | i would always want my code to be 'simple', 'idiomatic' etc. |
| 13:51 | dnolen | sritchie: I don't follow |
| 13:52 | timvisher | but it sounds like no one has a phrase that does that :) |
| 13:52 | timvisher | how can i reload a defrecord that implements a protocol at the repl? |
| 13:52 | sritchie | dnolen: was referencing two things - 1 is that I’ve got a multimethod based system for defining client side and server side page state data. Some of the client side multimethod definitions are in cljx files that aren’t required by cljs, |
| 13:53 | sritchie | dnolen: but their multimethod implementations are still registered under simple or advanced compilation, since they get jammed into the final loaded file |
| 13:53 | cemerick | sritchie: piggieback 0.2.0-SNAPSHOT is looking pretty decent with the latest CLJS; just check the "installation" note in piggieback's readme |
| 13:53 | sritchie | dnolen: in :none mode, they get ignored, so I have to explicitly require those namespaces to get the multimethod registrations |
| 13:53 | sritchie | dnolen: 2nd pt was that shadow tries to optimize by only reloading files that have been required by some namespace: https://github.com/thheller/shadow-build/blob/fe129c26d68572991ef1ccdbd1da8e4dfbdb6277/src/cljs/shadow/cljs/live_reload.cljs#L23 |
| 13:54 | sritchie | dnolen: which 1) will always fail in :none mode if you’ve got a repl running, and 2) will cause the files containing those multimethods I mentioned above to never reload |
| 13:54 | sritchie | dnolen: sorry, getting into details you just said you wanted to avoid :) |
| 13:54 | dnolen | sritchie: right I don't care about this stuff at all :) |
| 13:55 | dnolen | sritchie: to the 1st point, that's just not going to change, :simple and :none just pull everything in the src directory in which is pretty obnoxious |
| 13:55 | dnolen | sritchie: you have to use the classpath to get customized builds which is outrageous in my opinion |
| 13:56 | dnolen | in the future :simple and higher will take :main to control what's in a build |
| 13:56 | sritchie | dnolen: yup, that’s what I’m doing, and agreed |
| 13:56 | sritchie | dnolen: psyched for the modules stuff, btw - |
| 13:57 | sritchie | dnolen: btw - racehubhq.com launched, full client side, written in Om |
| 13:57 | dnolen | sritchie: yeah, it's pretty awesome if you're building a big app |
| 13:57 | sritchie | dnolen: still some rough edges. modules are important for hiding a bunch of the admin-only stuff, like the timing app |
| 13:57 | dnolen | sritchie: 502 :(, but awesome! |
| 13:57 | sritchie | dnolen: Om baby! nice. so much for the change I just pushed. |
| 14:21 | sritchie | dnolen: fixed https://racehubhq.com/ |
| 14:22 | dnolen | sritchie: looks real sweet :) |
| 14:23 | sritchie | working on writing up the routing stuff I built for this + sente |
| 14:23 | sritchie | thanks again for Om! the transition to client side’s been really fun because of it. |
| 14:24 | dnolen | sritchie: np, glad to hear it! Looking forward to getting back to it, got some goodies planned in the near future once the ClojureScript REPL stuff is behind us. |
| 14:27 | sritchie | cemerick: did that piggieback issue, or tools.nrepl issue, with resetting to cljs.user every time ever get fixed? |
| 14:28 | sritchie | I upgraded to piggieback 0.1.5 and tools.nrepl 0.2.7, but still no dice |
| 14:29 | cemerick | sritchie: not aware of the issue, but you should be using 0.2.0-SNAPSHOT & nREPL 0.2.10 if you're running the newest CLJS stuff |
| 14:29 | sritchie | https://github.com/tomjakubowski/weasel/issues/26 |
| 14:29 | sritchie | you’ve commented on the issue, I believe |
| 14:29 | sritchie | “latest cider on melpa” is probably the issue |
| 14:30 | bendlas | sritchie: I had that issue, but it went away a couple of weeks ago |
| 14:31 | cemerick | sritchie: oh, that. I think that was always a cider issue; nothing related changed in piggieback/nREPL |
| 14:32 | sritchie | cool |
| 14:32 | cemerick | sritchie: in any case, 0.2.0 is basically a rewrite to support the latest CLJS REPL bits |
| 14:32 | sritchie | nice |
| 14:32 | cemerick | So any issues reported < 4 days ago are obsolete :-P |
| 14:32 | sritchie | compatible w/ the latest weasel etc? |
| 14:33 | cemerick | sritchie: should be? Works well w/ nashorn, rhino, node, brepl, and ambly. Haven't gotten a weasel report either way yet. |
| 14:33 | sritchie | okay, cool |
| 14:33 | sritchie | thanks! I’ll try the upgrade after locking down this shadow-build live reload thing |
| 14:37 | dah | dnolen: been thinking an osascript ClojureScript REPL backend could be fun for OS X automation |
| 14:38 | dah | .. or even building full blown Cocoa applications i guess |
| 14:39 | dnolen | dah: sounds like a reasonable idea to me, mfikes has already done a ton of this work in Ambly/Shrimp |
| 14:41 | dah | dnolen: cool, thanks for the pointer |
| 14:44 | anti-freeze | dah: Haha, pointers... |
| 15:06 | mikerod | are there any good sources out there to explain what `print-dup` is? |
| 15:06 | mikerod | I sort of get it. |
| 15:06 | mikerod | but I just would like to read something more "official" |
| 15:06 | mikerod | I saw some ancient mailing list stuff where Rich briefly discussed it (no link at the moment). |
| 15:07 | mikerod | what does "dup" even stand for? |
| 15:07 | mikerod | duplicate I think |
| 15:07 | profil | is there a way to get index when using for? (for [x [1 2 3 4 5]] (prn x "is at index: " x-index)) |
| 15:07 | patrickgombert | mikerod: my understanding is that it is for serialization |
| 15:08 | mikerod | patrickgombert: yes |
| 15:08 | mikerod | it allows more objects to have a reader-friendly print |
| 15:09 | ro_st | profil: no, you'll need to use map-indexed |
| 15:09 | joegallo | profil: (for [[i x] (map-indexed vector [:a :b :c])] ...) |
| 15:09 | joegallo | not exactly what you wanted, but it works |
| 15:09 | ro_st | or do what joegallo says. nice one |
| 15:09 | mikerod | by reader-friendly, I mean they can be read back in and eval'ed back to life |
| 15:10 | profil | I'm thinking that I could change the for into a map-indexed instead.. |
| 15:10 | joegallo | ah, that's only if you absolutely *must* use for -- alternatively you could fold your for's body into the fn arg to map-indexed |
| 15:10 | joegallo | profil, yes, exactly :) |
| 15:10 | mikerod | I guess it is just a hook to make arbitrary ways to represent data to be serialized and then read back in later - I think it requires read with eval enabled. |
| 15:12 | amalloy | mikerod: right. also, it tends to get sorta out of date because nobody uses print-dup |
| 15:12 | amalloy | i know there were some cases in the past where print-dup on some kind of uncommon data structure (maybe treemap?) printed a call to a constructor that doesn't exist anymore |
| 15:13 | dyba | I'm reading Let Over Lambda and noticed some interesting difference between Common Lisp and Clojure when defining the nif macro: |
| 15:13 | dyba | (defmacro nif [expr pos zero neg] `(cond (pos? ~expr) ~pos (zero? ~expr) ~zero :else ~neg)) |
| 15:14 | dyba | Clojure expands it to: (if (clojure.core/pos? 0) "Pos" (clojure.core/cond (clojure.core/zero? 0) "Zero" :else "Neg")) |
| 15:14 | dyba | But CL expands it to the result "Pos", "Zero" or "Neg" |
| 15:14 | amalloy | dyba: no it doesn't. you are using the macroexpander in CL wrong, or defining the macro wrong |
| 15:15 | dyba | amalloy: perhaps I did, I used CL's macroexpand function |
| 15:16 | dyba | Are they different? |
| 15:16 | amalloy | no. but perhaps you forgot to quote the expression to expand, for example |
| 15:16 | dyba | Hm, good catch. Let me try it again |
| 15:18 | amalloy | dyba: also, try using macroexpand-1 |
| 15:19 | amalloy | i'm trying it in clisp, and it looks like the macroexpander is smart enough to elide checks that it knows will be true or knows will be false |
| 15:19 | amalloy | so you want to expand only your own macro, not the further macro that it expands to |
| 15:19 | amalloy | [10]> (macroexpand-1 '(nif -1 1 2 3)) ;=> (COND ((< 0 -1) 1) ((EQUALP 0 -1) 2) (T 3)) |
| 15:19 | amalloy | where i basically never use CL so i don't remember if equalp is the right predicate to use or what |
| 15:22 | dyba | amalloy: yup it works with macroexpand-1 |
| 15:22 | dyba | macroexpand gives me the evaluated result |
| 15:23 | dyba | And I am using a quote in front of the expression I'm passing to macroexpand |
| 15:25 | amalloy | dyba: yeah, i was surprised to discover that = and < have uh...compiler macros, i guess, associated with the functions for them |
| 15:25 | amalloy | so like if you expanded '(nif x 1 2 3), you'd get the full cond tree |
| 15:25 | amalloy | but '(nif 0 1 2 3) it knows how to evaluate at compile time |
| 15:27 | dyba | amalloy: Ah, I see what you mean |
| 15:29 | dyba | amalloy: so what you're saying this behavior in CL suggests that = is likely built with a compiler macro? |
| 15:29 | dyba | saying is that* |
| 15:29 | amalloy | well, = is a built-in function, and appears to have a compiler macro as well |
| 15:30 | amalloy | in theory it could be special-cased by the macroexpander, but probably it is just a compiler macro |
| 15:34 | danlentz | if you are interested in CL compiler macros, there is a short presentation given my arthur lemmens floating around out there |
| 15:34 | danlentz | http://www.pentaside.org/paper/compilermacro-lemmens/compiler-macros-for-publication.txt |
| 15:36 | amalloy | danlentz: i understand the idea of compiler macros, but i don't know whether = uses one, or how i would confirm my expectation that it does |
| 15:37 | danlentz | can’t you call (compiler-macro-function ‘=) |
| 15:38 | amalloy | danlentz: apparently not. but i wouldn't have known to try that; i never use CL |
| 15:39 | danlentz | compiler-macros are somewhat heady stuff. I worked in CL for a number of years and pretty rarely came into contact with them. |
| 15:40 | amalloy | danlentz: rarely noticed coming into contact with them, anyway |
| 15:40 | danlentz | yes, you’re right. |
| 15:41 | dyba | danlentz: that presentation helped with having a better understanding of the idea of compiler macros |
| 15:41 | dyba | thanks! |
| 15:41 | danlentz | reading through this paper again, the use-case of translating n-ary to binary functions is interesting. |
| 15:42 | danlentz | yeah, im just rereading it and thinking the same thing. |
| 15:42 | amalloy | danlentz: clojure has its own version of compiler macros too, mostly for the primitive math stuff |
| 15:42 | danlentz | arthur lemmens is really an iconic common-lisper. I spent my first year or so of CL studying his persistent object-store called Rucksack |
| 15:43 | dyba | I don't use CL but reading Let Over Lambda requires having some basic understanding of that language |
| 15:43 | danlentz | shit yeah it does |
| 15:43 | dyba | Which is why I asked the question originally |
| 15:43 | danlentz | that is a hard book |
| 15:43 | amalloy | eg, see the definition of nil?, which has in its metadata {:inline (fn [x] (list 'clojure.lang.Util/identical x nil))} |
| 15:44 | dyba | danlentz: you're telling me! ;) Definitely not an easy read |
| 15:44 | danlentz | if you look in my CL-CTRIE project I have a dlambda, plambda |
| 15:44 | dyba | I haven't read that chapter yet; I'm currently on ch. 3 |
| 15:44 | danlentz | https://github.com/danlentz/cl-ctrie/blob/master/ctrie-lambda.lisp |
| 15:44 | dyba | The once only macro |
| 15:45 | dyba | Sweet! |
| 15:45 | danlentz | dyba: did you read paul graham first? |
| 15:45 | dyba | I'm bookmarking that and coming back to it when I get to that chapter |
| 15:45 | dyba | danlentz: You mean On Lisp? |
| 15:45 | danlentz | y |
| 15:45 | dyba | I'm reading that one too |
| 15:45 | dyba | Just got past the first chapter |
| 15:45 | danlentz | its good to read that first — its mostly about macros |
| 15:46 | danlentz | LoL is on the edge of the discovered macro universe. On Lisp covers the stuff that may come in more handy day to day. |
| 15:47 | danlentz | but I love that book, awesome to see clojurians reading it! |
| 15:50 | danlentz | however, I have to warn you, anytime I show a client code with “pandoric-lambda” in it they make a scrunchy face like I just fed them lemons |
| 15:50 | dyba | danlentz: I'll keep that in mind. I'm reading LoL first because I have a hard copy of it. On Lisp is out of print last I checked. And it sells for hundreds of dollars on Amazon. |
| 15:50 | danlentz | its free |
| 15:50 | dyba | I downloaded the free PDF, but I still like to have the book on my hand |
| 15:50 | danlentz | oh |
| 15:51 | dyba | danlentz: lol |
| 15:51 | danlentz | i do understand. I print stuff out and bind it nicely with a stiff paperboard backing (cut from a heavy duty binder) and poly cover |
| 15:51 | dyba | (the popular lol) ;) |
| 15:52 | dyba | I think I will do that with On Lisp, so that I can write on the margins of the pages |
| 15:52 | danlentz | dyba: what I love is the pandoric-lambda from LoL though |
| 15:53 | danlentz | and the entire concept of “sub-lexical scope” |
| 15:53 | dyba | what chapter are those topics on? |
| 15:54 | danlentz | dont remember offhand. the entire first part of the book builds up to pandoric-lambda |
| 15:54 | dyba | Ah I found them |
| 15:54 | danlentz | then he goes back and does other stuff like a forth interpreter |
| 15:56 | danlentz | I think clojure macros are quite a bit easier to work with than in common-lisp, just because the gensyms are so easy syntactically |
| 15:57 | danlentz | I might be slow, but it took me a couple of years to work though LoL |
| 15:58 | danlentz | because it wasnt continuous. I’d read until I was thoroughly baffled, then put the book down for 6 months and try again. |
| 16:00 | dyba | danlentz: "Should you experience headaches or other discomfort through the course of this book, I recommend that you immediately execute a garbage collection cycle (get some sleep), then return with a fresh and open mind" |
| 16:00 | danlentz | usually until I saw something in the outside world that I connected with the book and somehow made something “click” — then I’d get 10 pages further until baffled again. |
| 16:27 | danlentz | dyba: if you do cut and paste the code, at line 133 there is a (defun/inline …) form that is just syntactic sugar to define a function and declare it ‘inline’ all with one form. |
| 16:28 | dyba | danlentz: I'll keep that in mind |
| 16:28 | danlentz | you would need to change that or copy the defun/inline macro: https://github.com/danlentz/cl-ctrie/blob/master/common-macro.lisp#L38 |
| 16:30 | danlentz | there are some other useful examples of macros in that file, if you are interested |
| 16:30 | danlentz | like, you were talking about “once only” |
| 16:31 | danlentz | https://github.com/danlentz/cl-ctrie/blob/master/common-macro.lisp#L74 defines a defmacro/once macro |
| 16:35 | edbond | how to get matched value from map of regexp => value? (<somefns> { #"a" 42, #"b" 99 } "bbb") ;; 99 |
| 16:36 | edbond | possible direction, what fns to look at? |
| 16:36 | gfredericks | some could probably help |
| 16:36 | gfredericks | ,(doc some) |
| 16:36 | clojurebot | "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)" |
| 16:36 | chouser | or keep, depending on if you want more than one result |
| 16:37 | edbond | just first result |
| 16:37 | chouser | and of course re-find |
| 16:37 | edbond | thanks |
| 16:37 | edbond | ,(inc gfredericks) |
| 16:37 | clojurebot | #error{:cause "Unable to resolve symbol: gfredericks in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: gfredericks 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: gfredericks in this ... |
| 16:37 | gfredericks | ,(def gfredericks 41) |
| 16:37 | clojurebot | #'sandbox/gfredericks |
| 16:37 | edbond | ,(inc gfredericks) |
| 16:37 | clojurebot | 42 |
| 16:37 | edbond | nice |
| 16:38 | edbond | (inc gfredericks) |
| 16:38 | lazybot | ⇒ 129 |
| 16:39 | danlentz | ,danlentz |
| 16:39 | clojurebot | #error{:cause "Unable to resolve symbol: danlentz in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: danlentz 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: danlentz in this context",... |
| 16:40 | danlentz | ,(def danlentz Math/PI) |
| 16:40 | clojurebot | #'sandbox/danlentz |
| 16:40 | gfredericks | ,(inc danlentz) |
| 16:40 | clojurebot | 4.141592653589793 |
| 16:40 | gfredericks | $google zip code 41415 |
| 16:40 | lazybot | [41415 Rayburn Dr, Northville, MI 48168 is Recently Sold | Zillow] http://www.zillow.com/homedetails/41415-Rayburn-Dr-Northville-MI-48168/88392796_zpid/ |
| 16:41 | danlentz | wow |
| 16:41 | danlentz | $google clj-uuid |
| 16:41 | lazybot | [danlentz/clj-uuid · GitHub] https://github.com/danlentz/clj-uuid |
| 16:42 | danlentz | cool! |
| 16:46 | ben_vulpes | yo so cider is eating print statements in my http-kit webapp :( |
| 16:46 | ben_vulpes | lein repl commits no such crime |
| 16:46 | ben_vulpes | halp wat do |
| 16:46 | danlentz | ,(java.util.UUID/randomUUID) |
| 16:46 | clojurebot | #uuid "a296e782-0372-4a7b-996d-9ef25a5437d2" |
| 16:48 | danlentz | ben_vulpes: check other window |
| 16:48 | danlentz | ? |
| 16:48 | ben_vulpes | other...window? |
| 16:48 | ben_vulpes | cider-error? |
| 16:48 | ben_vulpes | nrepl-connection? |
| 16:49 | ben_vulpes | danlentz: |
| 16:50 | danlentz | well, there are a limited number of them, check them all |
| 16:51 | danlentz | i mean, what I am asking is if maybe you are doing IO on a background thread and it is directed to the console rather than cider |
| 16:51 | danlentz | but ive never done anything with http-kit so that is just a stab in the dark on general principle |
| 16:52 | ben_vulpes | danlentz: the only relevant buffers i have at hand are nrepl-server and cider-repl |
| 16:52 | ben_vulpes | what would be different in execution between cider via emacs and lein repl? |
| 16:52 | ben_vulpes | i'm way out of my depth on this one. |
| 16:52 | ben_vulpes | iirc i've seen this in ring as well |
| 16:52 | justin_smith | ben_vulpes: it's an old bug |
| 16:53 | justin_smith | ben_vulpes: cider rebinds *out* but that does not propagate to your ringer server's threads |
| 16:53 | ben_vulpes | aha that sounds right |
| 16:53 | justin_smith | ben_vulpes: so any printing from them go to the initial value of *out*, which is either an *nrepl-server* buffer, or the terminal where you started up from, or whatever |
| 16:55 | ben_vulpes | agh fuck |
| 16:55 | ben_vulpes | https://github.com/clojure-emacs/cider/pull/818 |
| 16:56 | ben_vulpes | dude |
| 16:56 | ben_vulpes | can i just use slime? |
| 16:56 | ben_vulpes | and mebbe nrepl? |
| 16:56 | danlentz | things work like this in CL/slime as well |
| 16:57 | justin_smith | ben_vulpes: the bug doesn't come up in inferior-lisp, if you don't mind doing things caveman style |
| 16:57 | danlentz | I never thought of it as a “bug" |
| 16:57 | ben_vulpes | you never thought the dropping of print statements on the floor was a bug? |
| 16:57 | justin_smith | danlentz: the difference is that with slime, the process buffer (default root *out*) is also the repl buffer |
| 16:57 | justin_smith | danlentz: this is not the case in cider |
| 16:58 | danlentz | the behaviour of special variables between/among thread I mean |
| 16:59 | justin_smith | yeah, that's slightly orthogonal to the UI disaster in cider |
| 16:59 | justin_smith | last comment in that thread: "I submit that having the application's standard output, including log output, in a buffer separate from interactive REPL output is desireable. I would go so far as to call it a feature." |
| 17:00 | justin_smith | there you have it, cider author has declared that not outputting to the cider repl buffer is a feature |
| 17:01 | danlentz | well that is bizarre |
| 17:01 | danlentz | but I agree with the idea of not having *out* bound to the cider-repl in all threads |
| 17:03 | justin_smith | I think separating output between buffers, defaulting to a buffer that never pops to the front, should be an opt-in thing |
| 17:04 | justin_smith | As a naive new user, I'd rather deal with messy output cluttering a buffer, than output that I expect never being visible |
| 17:05 | ben_vulpes | especially since it's such a radical divergence from how the time tested and battle hardened tools elsewhere in the lisp universe behave in my limited experience. |
| 17:05 | danlentz | it seems normal to me |
| 17:05 | danlentz | well, the default output from the foreground should go to the repl. background threads all go to the console. |
| 17:06 | danlentz | i’ve been donating $10 a week to the cider project |
| 17:06 | justin_smith | I long ago ditched cider for inferior-lisp |
| 17:07 | ben_vulpes | justin_smith: i think i'll have to hit you up for a crash course on inferior lisp here shortly |
| 17:07 | danlentz | i want it to get better, but it didnt happen overnight with slime either — thats for sure. |
| 17:08 | ben_vulpes | what would be the cider-y solution? |
| 17:08 | justin_smith | hehe, just to warn you it is seriously feature deprived. But it isn't constantly broken, and is never surprising to me. |
| 17:08 | ben_vulpes | i don't need much by way of features |
| 17:08 | ben_vulpes | i've got helm |
| 17:08 | justin_smith | ben_vulpes: another option is monroe |
| 17:09 | ben_vulpes | "simple installation without any dependencies, except Emacs" |
| 17:09 | ben_vulpes | ahahaha |
| 17:09 | ben_vulpes | i guess theoretically emacs could be just a single dep |
| 17:12 | danlentz | i think the reason is that output to the CIDER nrepl buffer is very slow. Even a modest amout of printing is going to “freeze” things up a bit. |
| 17:13 | justin_smith | danlentz: do you mean the cider-nrepl (aka console) or cider repl (aka the repl) |
| 17:13 | danlentz | the cider repl in my emacs window |
| 17:14 | justin_smith | danlentz: the reason I ask is that the hidden console output (not a repl) is actually called *cider-nrepl* or something very close to that |
| 17:14 | justin_smith | the buffer that most people never see, and they think prints that end up there never happened |
| 17:15 | danlentz | I gave up keeping track of what things were being called a while ago…. :) |
| 17:15 | Frozenlock | justin_smith: it's really aggravating when it occurs... |
| 17:15 | Frozenlock | "Where is my print? I'm sure I added a print somewhere..." |
| 17:15 | justin_smith | Frozenlock: yes, I would disagree with the official stance and call it a bug actually. |
| 17:17 | danlentz | if you are doing a lot of that, might it make sense to consider a logging package, which in many cases will be much faster than printing to console and light years faster than printing to Cider repl |
| 17:17 | danlentz | buffered output and so forth |
| 17:17 | justin_smith | danlentz: the logger will end up printing to the console, unless you set up a log file |
| 17:17 | danlentz | right' |
| 17:17 | danlentz | i mean, just a suggestion |
| 17:18 | danlentz | and then tail -f the log file, I mean |
| 17:18 | justin_smith | danlentz: M-x auto-revert-tail-mode |
| 17:19 | Frozenlock | M-x butterfly |
| 17:21 | Frozenlock | I used to have plenty of problems with Cider, but I don't anymore. I also don't live on the edge. I found a stable version and I stick with it (for now). |
| 17:21 | danlentz | y i pulled back from the edge a few months ago myself |
| 17:21 | Frozenlock | The only bad thing I can think of is connecting to a remote repl with a poor connection: the autocomplete is sloooow |
| 17:22 | danlentz | the edge is rather pointy these days |
| 17:24 | Frozenlock | I wonder if we could find a correlation between the number of issues opened at any point and the expected user experience. |
| 17:25 | danlentz | my opinion is that the lack of willingness to cooperate by the SLIME developers hurt the clojure tooling (cider) and it is taking a while to draw even. But I think the result is that also cider may wind up to be the cleaner and more modern tool |
| 17:25 | danlentz | at some point. |
| 17:25 | danlentz | i miss the debugger |
| 17:26 | Frozenlock | danlentz: by what I understood, slime was a horrible mess. I would ask technomancy to chip in, but I don't think he's here. :-/ |
| 17:27 | danlentz | i probably put off working with clojure for at least a couple of years just because it was problematic to use at the same time Slime for Clojure and Slime for CL |
| 17:27 | Frozenlock | danlentz: http://technomancy.us/163 |
| 17:27 | danlentz | interesting |
| 17:29 | danlentz | i think he’s not saying that the SLIME developers were actively belligerent towards the idea |
| 17:29 | danlentz | which, having watched, was my impression |
| 17:30 | Frozenlock | About the debugger https://github.com/clojure-emacs/cider/issues/694 |
| 17:31 | danlentz | there were actually many contributed patches to the SLIME effort that the maintainers simply threw on the floor |
| 17:32 | danlentz | and they made it very difficult, as he said, for any project to fork and extend |
| 17:34 | danlentz | I really feel like the approach they took did more to harm the CL community than slow Clojure down all that much. |
| 17:35 | danlentz | attila lemdvai did some awesome patches that allowed you to use SLIME basically as a text-gui interface for your own app |
| 17:36 | danlentz | all that was required was that a couple of hooks be added into the trunk, and the use-case of SLIME could have really expanded to provide a sorely lacking facility: any sort of common front-end interface among lisps |
| 17:37 | p_l | danlentz: back in the day i always felt it had more to do with all yhe clojure patches I've seen being for a version considered outdated (but last tarballed) |
| 17:39 | danlentz | that would be a good sugestion for the Cider project: customizable “inspector” that allows you to design arbitrary CRUD layout |
| 17:40 | justin_smith | danlentz: hmm, what about something using GUD mode with jdb instead of the usual gdb? |
| 17:40 | danlentz | might be gud |
| 17:40 | danlentz | :) |
| 17:41 | justin_smith | GUD UI example http://tuhdo.github.io/static/c-ide/gdb-many-windows.gif |
| 17:41 | justin_smith | one window with stack frames, another with breakpoints, another showing locals, etc. |
| 17:41 | justin_smith | and threads |
| 17:42 | justin_smith | jdb provides all of that, I wonder how well elisp could extract sensible clojure info from all of it |
| 18:03 | xemdetia | gdb-many-windows the best friend |
| 18:03 | Lewix | why is that clojurist don't have an awesome newsletter like gooist |
| 18:03 | Lewix | or rubyist |
| 18:04 | amalloy | Lewix: you haven't written one yet |
| 18:04 | justin_smith | Lewix: we have one, we just decided not to invite you |
| 18:04 | om | eval is evil! |
| 18:04 | Lewix | amalloy: im not a clojurist yet |
| 18:04 | danlentz | what is that lambda-love newsletter |
| 18:04 | xemdetia | I mean clojure has a useful irc channel why do you need a newsletter |
| 18:04 | om | I have Enlive selector code (with fns) that I load from a config file. |
| 18:04 | Frozenlock | Lewix: the #clojure channel is like the official doc and the mailing list. All in one. |
| 18:04 | justin_smith | Lewix: we have (def newsletter) and the clojure gazette |
| 18:04 | Lewix | xemdetia: well to keep up to date in an efficient way? To promote clojure ? |
| 18:05 | om | Selectors are vectors. But at some point the fns (from enlive ns) have to be resolved. |
| 18:05 | bja | if I want to a map as a JSON value for HoneySQL, do i have to override the ToSql implementation for IPersistentMap (thus giving up subqueries)? |
| 18:05 | Lewix | justin_smith: i see. I'll google that |
| 18:05 | justin_smith | Lewix: http://defnewsletter.com/ http://www.clojuregazette.com/ |
| 18:05 | om | I thought that the eval being done in the processing ns, I could call my function in another ns without requiring enlive there too. But this is where the eval happens indeed. |
| 18:05 | om | so it seems, eval is really evil! |
| 18:06 | justin_smith | om: also, eval is also very bad for performance |
| 18:07 | om | justin_smith: how would you proceed then, to have the fns is selectors being resolved? |
| 18:08 | danlentz | lewix: http://reborg.tumblr.com |
| 18:08 | danlentz | another “clojure weekly” |
| 18:08 | justin_smith | om: if possible, a simple mapping (via hash map) from symbols or keywords to the functions that are valid. This also prevents the "run arbitrary code" issue, or at least improves that situation. |
| 18:08 | danlentz | I endorse Clojure Weekly because he mentioned me last week :) |
| 18:09 | om | to give an idea : https://www.refheap.com/98916 |
| 18:09 | om | justin_smith: this is exactly what I do |
| 18:09 | Lewix | danlentz: thanks |
| 18:09 | om | but I some point they have to be resolved? don't they? |
| 18:10 | justin_smith | om: well, if you use a hash map from symbol to function, then you don't need eval |
| 18:10 | justin_smith | it's a whitelist |
| 18:10 | om | justin_smith: really? |
| 18:11 | om | justin_smith: if I have, say, [[:table (left :table)] :> [:tr (left :tr)]] how do I get it resolve |
| 18:11 | danlentz | can you use “resolve” rather than eval? |
| 18:11 | om | left or enlive/left |
| 18:12 | danlentz | I mean, isnt a ns basically a hash map from symbol to function? |
| 18:12 | om | danlentz: I don't think so, I'll try again |
| 18:13 | justin_smith | om: (clojure.walk/post-walk #(if (symbol? %) (get {'left enlive/left} %) %) selector) |
| 18:13 | justin_smith | where you would selectively add the valid functions to the hash map |
| 18:13 | danlentz | oh i see |
| 18:13 | om | justin_smith: sure, but this doesn't give me a fn that I can pass to enlive: this is the problem |
| 18:13 | justin_smith | it's easier if the structure is more predictable, but post-walk will do the job |
| 18:15 | om | if you look to the few lines of code I posted, you will see remove-nodes to which I pass bunches of selectors taken from a vector |
| 18:15 | justin_smith | oh right, left is being called with args |
| 18:16 | om | the pb being that when remove-nodes is called from another ns, the later should have enlive required |
| 18:17 | justin_smith | om: this is the thing I am saying is fixed by inserting the actual functions into the form. |
| 18:17 | justin_smith | but I'm unfamiliar with this part of enlive |
| 18:17 | justin_smith | and some weird stuff is going on there |
| 18:17 | justin_smith | where clearly eval is the easy way to handle it |
| 18:18 | pandeiro | what is the idiomatic way to go from record -> plain map? |
| 18:18 | justin_smith | pandeiro: (into {} rec) |
| 18:18 | amalloy | pandeiro: don't define the record type to begin with is easiest |
| 18:18 | om | justin_smith: thanks a lot, maybe I misunderstood what you meant with postwalk here (because I use it a lot too) |
| 18:18 | amalloy | i think om is trying to run user-specified code at runtime, not just do some simple lookup to plug into an already-defined function |
| 18:19 | bja | can I temporarily extend-protocol something (i.e. in a thread-local way)? |
| 18:19 | justin_smith | amalloy: yeah, I think it's some enlive specific idiom going on too |
| 18:19 | amalloy | eval seems easier than trying to invent an entire interpreter for enlive selectors |
| 18:19 | dnolen | bja: you cannot |
| 18:19 | pandeiro | justin_smith: ok that works; amalloy: yeah neocons did it, not me |
| 18:20 | amalloy | pandeiro: why do you need it to be a map anyway, if you have a record already? |
| 18:20 | pandeiro | amalloy: serializing it to edn |
| 18:20 | om | amalloy: but then how do you avoid requiring the ns where the fns are defined (in my case enlive), in the ns calling my function (not sure I am clear)? |
| 18:21 | om | amalloy: I guess you can't |
| 18:21 | justin_smith | om: what about a post-walk and resolving all symbols? |
| 18:21 | amalloy | you don't. eval happens in a clean environment, usually in clojure.core or something, so if you want more names accessible you need to make them accessible in the code you're evaluating |
| 18:21 | amalloy | justin_smith: and then what? you still need to eval the result |
| 18:21 | om | because eval happens at "eval" time, hence my calling it evil |
| 18:21 | justin_smith | amalloy: right, but then they are fully qualified |
| 18:21 | om | oh, right |
| 18:22 | justin_smith | amalloy: wouldn't fully resolving any symbols make sure eval works? |
| 18:22 | amalloy | meh. just (eval `(do (require [enlive.whatever :refer :all]) ~the-user-code))) |
| 18:22 | om | I mean I do not eval in my function, but the eval happens when my function is called, right? |
| 18:23 | om | oh, seriously? |
| 18:23 | om | thanks |
| 18:23 | amalloy | om: that's what i'm saying. if you want the user code to have a specific environment set up, you just change the user code to set up that environment itself |
| 18:24 | om | I see, thanks to both of you |
| 18:24 | calhinshaw | I'm not sure this is the right place to ask, so let me know if it's not. I'm new to clojurescript webapps and having trouble getting routing working. I made a new luminus project with the +cljs option and added the goog.history code at http://yogthos.net/posts/2014-08-14-Routing-With-Secretary.html, but I can't get get the back button to work or get the urls i'm dispatching to display in the url bar. Does anyone have any suggest |
| 18:24 | calhinshaw | ions? Thanks. |
| 18:24 | om | pretty neat explanation (I did not get eval was happening in a 'clean' env) |
| 18:27 | sobel | so.. i'm having odd probles with floats (Float/parseFloat) |
| 18:27 | sobel | what type is a 'naked' decimal number? that may be my trouble |
| 18:28 | danlentz | that is the special “exhibitionist primitive” type |
| 18:28 | sobel | hah. i don't know if unboxed is the right term in clojure. |
| 18:29 | sobel | i lack words. that makes this (and google) harder. |
| 18:29 | danlentz | you have to watch out for contagion :) |
| 18:29 | justin_smith | sobel: float and double are unboxed, Float and Double are boxed |
| 18:29 | justin_smith | sobel: when the compiler gets the right hints, it can figure out when it doesn't need to box things |
| 18:29 | sobel | i have a vector of floats i parsed with Float/parseFloat, and when i try to filter one, it's not found. but when i filter for (Float/parseFloat "0.0943") it'sfound |
| 18:29 | danlentz | http://clojure.org/java_interop#Java%20Interop-Type%20Hints |
| 18:30 | sobel | aha, that settles it |
| 18:30 | sobel | justin_smith: thx |
| 18:30 | justin_smith | sobel: with clojure 1.7, there is a *warn-on-boxed* value for the unchecked-math setting |
| 18:30 | justin_smith | sobel: floating point equality is your problem |
| 18:30 | sobel | i suppose i don't really want Float/parseFloat. what's a better way to get numeric out of string? |
| 18:31 | justin_smith | ,(= 0.0943 (Float/parseFloat "0.0943")) |
| 18:31 | clojurebot | false |
| 18:31 | justin_smith | sobel: ^^ that's your issue |
| 18:31 | sobel | justin_smith: yes, that was basically my isolated problem |
| 18:31 | justin_smith | sobel: read-string |
| 18:31 | justin_smith | or Double/parseDouble |
| 18:32 | justin_smith | ,(= 0.0943 (Double/parseDouble "0.0943")) |
| 18:32 | clojurebot | true |
| 18:32 | justin_smith | but floating point equality is always going to be problematic |
| 18:32 | sobel | yeah, i'm familiar with the built-in problem on that |
| 18:33 | sobel | fwiw, 0.0 doesn't suffer the fp inequality issue at hand ;) |
| 18:33 | justin_smith | heh, I'd hope not |
| 18:34 | sobel | is there a simpler numeric conversion that doesn't involve eval? |
| 18:34 | justin_smith | sobel: parseDouble doesn't involve eval |
| 18:34 | justin_smith | read-string doesn't either |
| 18:34 | sobel | e.g. untrusted sources |
| 18:35 | sobel | is this doc outdated? Note that read-string can execute code (controlled by *read-eval*), |
| 18:35 | justin_smith | parseDouble is your safest bet if you know that will be the expected type |
| 18:35 | sobel | and as such should be used only with trusted sources. |
| 18:35 | justin_smith | right |
| 18:35 | justin_smith | so use parseDouble |
| 18:35 | justin_smith | or edn/read-string |
| 18:35 | danlentz | ,(= (float 0.0943) (Float/parseFloat "0.0943")) |
| 18:35 | clojurebot | true |
| 18:35 | sobel | that'll be a boxed Double right? |
| 18:35 | justin_smith | sobel: absolutely |
| 18:35 | justin_smith | boxing was not your issue here |
| 18:36 | danlentz | ,(= 0.0943 (Double/parseDouble "0.0943")) |
| 18:36 | clojurebot | true |
| 18:36 | danlentz | your issue is the default representation |
| 18:36 | sobel | ah ok |
| 18:37 | justin_smith | sobel: unboxed doubles can't be stand alone values, they can only be members of a double-array or arguments / return values of methods. Maybe they can be fields of some class too? |
| 18:37 | justin_smith | but they aren't objects |
| 18:37 | sobel | that's only a slight bit weird. i think i can digest it. |
| 18:38 | justin_smith | sobel: unboxed numerics exist so code can be fast |
| 18:38 | justin_smith | sobel: objects have overhead, sometimes we really don't want that overhead |
| 18:38 | sobel | mostly it's just a foible i hit on at the repl. the code that needs to care is actually ok, it's just obnoxious trying to validate it with tiny tests and hand-picked data. |
| 18:39 | yotsov | Hello. Is there a clojurescript equivalent of environ? Any way to pass build env variables to the code? |
| 18:40 | sobel | justin_smith: oh yeah, totally understood on boxing vs performance. i think my trouble was just expecting a cut & paste value to let me test my code when it was full of boxed values. |
| 18:40 | justin_smith | sobel: boxing was not your issue here |
| 18:41 | justin_smith | sobel: your issue was that 0.0943 as a literal, is a double in clojure |
| 18:41 | justin_smith | but you were creating floats from strings |
| 18:41 | justin_smith | floats and doubles have different resolution |
| 18:41 | om | amalloy: interestingly enough, doing a require in the eval raises a class not found exception |
| 18:41 | justin_smith | so they compare oddly |
| 18:41 | amalloy | om: oh sure, it needs to be quoted better |
| 18:41 | justin_smith | om: make sure to get your quoting right |
| 18:41 | amalloy | my example wasn't right |
| 18:42 | amalloy | (eval `(do (require ['~'enlive.whatever :refer :all]) ~the-user-code))) |
| 18:42 | om | well, syntax quoting should be enough no, why dequote |
| 18:42 | catern | yikes |
| 18:42 | catern | clojure gets pretty ugly with the quoting |
| 18:43 | om | thanks, amalloy, justin_smith |
| 18:43 | om | amalloy: why is the tilde "quoted"? |
| 18:43 | catern | thamalloy. |
| 18:44 | justin_smith | catern: sadly thjustin_smith just doesn't have the same ring to it |
| 18:44 | catern | thustin_smith! |
| 18:45 | sobel | justin_smith: i know, and i was looking right at it, thinking eh, should be ok at least to the ten-thoundths place! |
| 18:46 | sobel | anywho, thanks all |
| 18:47 | om | amalloy: got it to work (still did not fully catch the '~') |
| 18:47 | om | (inc amalloy) |
| 18:47 | lazybot | ⇒ 243 |
| 18:47 | amalloy | om: '~' is not a compound thing, it is just a combination of ', then ~, then ' |
| 18:47 | sobel | this is my first commercial clojure project. being able to conveniently manipulate data is saving me numerous trips to the database. my input design seems to assume that you can't sort or merge data without sql. |
| 18:48 | justin_smith | (inc group-by) |
| 18:48 | lazybot | ⇒ 1 |
| 18:48 | om | amalloy: oh, you quote the unquote |
| 18:48 | amalloy | you want to emit 'enlive.whatever, with a quote in front of it, so you start with '. then, you want to not namespace-qualify enlive.whatever, so you write ~ to leave the ` context, and ' to enter a normal quoting context |
| 18:49 | catern | guys |
| 18:49 | catern | I need to write some clojure |
| 18:49 | catern | it's amazing |
| 18:49 | catern | some more* |
| 18:49 | catern | I did some trivial programming with it earlier |
| 18:49 | catern | and it was great |
| 18:49 | om | amalloy: excellent, thank you |
| 18:49 | catern | what trivial project should I do next? |
| 18:49 | justin_smith | jeapordy app |
| 18:49 | catern | what is clojure good at besides web apps and statistics? |
| 18:49 | justin_smith | (wrong kind of trivial) |
| 18:50 | sobel | justin_smith: once i can write the clojure-equivalent of sql exprs involving group by, order by, rank over, partition over, and having... there will be no more utility-trips to the db :) |
| 18:50 | justin_smith | sobel: well, group-by alreayd works at least, it would be nice to build a lib that has all of them |
| 18:50 | amalloy | justin_smith: pls, pronounce it like "gee-pordy" next time someone is talking about jeopardy |
| 18:50 | justin_smith | amalloy: uh, OK |
| 18:51 | justin_smith | my spelling is shit |
| 18:51 | amalloy | (the misspelling leads to a funny-sounding pronunciation) |
| 18:51 | justin_smith | yes |
| 18:51 | amalloy | although i guess the right spelling should be pronounced pretty funny too, if english made any sense |
| 18:51 | sobel | justin_smith: i'm new at this, but i'd hope all the basics (order by, group by, having) are available |
| 18:51 | justin_smith | sort-by, group-by, filter |
| 18:51 | sobel | i mean.. i used sort-by earlier today |
| 18:52 | sobel | i'd just need to figure out how to replace rank over and partition |
| 18:52 | catern | what's a good clojure library for simple geometry and drawing? Say I wanted to draw one of these: http://en.wikipedia.org/wiki/Voronoi_diagram |
| 18:53 | justin_smith | catern: I'd check out analemma if svg output is acceptable |
| 18:53 | catern | what about quil? |
| 18:54 | justin_smith | quil is kind of weird, but sure |
| 18:54 | catern | weird? |
| 18:54 | justin_smith | quil has its own main loop thing, and does a few things in ways that are not conventional |
| 18:54 | sobel | Swing is always quick & dirty |
| 18:54 | justin_smith | it wants to be like the clojure processing |
| 18:55 | jaen | Just trying some macro shenanigans and I can't figure out a way to refer to a some-gensym# that's outside a ~(expr) from inside it. Any way to do that? (I need to conditionally emit code in macro that uses this gensym) |
| 18:55 | amalloy | jaen: you can't |
| 18:56 | jaen | Damn, I suspected that : X |
| 18:56 | amalloy | you need to generate your own gensym by hand, if you want to use it in multiple contexts |
| 18:56 | jaen | amalloy: you mean like (gensym "name")? |
| 18:57 | amalloy | (let [x (gensym "x")] `(let [~x 1] ~(if whatever `(+ 1 ~x) `(- ~x 1)))) |
| 18:57 | jaen | Ok, thanks : ) |
| 18:57 | justin_smith | (inc `~'amalloy) |
| 18:57 | lazybot | ⇒ 1 |
| 18:58 | amalloy | ,`~`~`~`~1 |
| 18:58 | clojurebot | 1 |
| 18:59 | amalloy | tip: to make your code more confusing, just sprinkle some `~ into it at random |
| 18:59 | amalloy | it's like a 2-character identity function |
| 18:59 | sobel | soaking up excess readability |
| 19:00 | sobel | this language has everything, i swear |
| 19:00 | sobel | (pony) |
| 19:00 | justin_smith | ,(`~`~get `~`~`~`~get `~`~`~`~`~`~`~get `~`~`~`~`~`~`~`~`~`~`~get) |
| 19:00 | clojurebot | #object[clojure.core$get "clojure.core$get@40007a3a"] |
| 19:00 | amalloy | *chuckle* |
| 19:02 | sobel | and today, my big milestone was making intuitive sense out of the idiom (apply map vector [[ ... ]]) |
| 19:02 | justin_smith | that's much more useful |
| 19:03 | sobel | starting to get some opinions on how this should be learned |
| 19:22 | irctc_ | Would like to convert [{:year "2015" :grp "foo" :name "A"} {:year "2015" :grp "foo" :name "B"} {:year "2014" :grp "bar" :name "C"} {:year "2014" :grp "bar" :name "D"}] to.. |
| 19:22 | irctc_ | {"2015" {"foo" [{:year "2015" :grp "foo" :name "A"} {:year "2015" :grp "foo" :name "B"}]} "2014" {"bar" [{:year "2014" :grp "bar" :name "C"} {:year "2014" :grp "bar" :name "D"}]}} |
| 19:24 | oddcully | group-by? |
| 19:24 | irctc_ | trying to use successive calls to group-by with a function signature like: (group-by-nest coll [:year :grp]) |
| 19:25 | justin_smith | wait, where does the :grp part come in? they aren't grouped by it |
| 19:26 | amalloy | irctc_: http://stackoverflow.com/q/25480674/625403 looks like your question |
| 19:26 | justin_smith | maybe you just want to sort by it? |
| 19:26 | justin_smith | irctc_: oh, now I see, never mind |
| 19:26 | chouser | (into {} (for [[year v2] (group-by :year v)] [year (group-by :grp v2)])) |
| 19:27 | justin_smith | (inc chouser) |
| 19:27 | lazybot | ⇒ 19 |
| 19:27 | amalloy | chouser: works, but i like cgrand's version on stackoverflow better. avoids traversing the whole input multiple times |
| 19:27 | irctc_ | amalloy: that looks like the one.. thanks. |
| 19:28 | chouser | though you rebuild the root map once for every element instead. |
| 19:29 | irctc_ | chouser: thank you. will check that out too! |
| 19:29 | chouser | neither is cleanly parameterized on the set of keys to be extracted. bit of a shame. |
| 19:30 | hiredman | with some work you can turn cgrand's approach in to a transformation of a reducing function, and etc etc |
| 19:30 | hiredman | http://aphyr.github.io/tesser/tesser.core.html#var-group-by |
| 19:30 | amalloy | chouser: it's pretty easy to do that for cgrand's, though. yours isn't obviously possible to do that with |
| 19:31 | chouser | well, yes, generally if you have a solution from cgrand I'd go with that. |
| 19:31 | amalloy | wow how has cgrand's answer been there for so many years and the parens don't even balance |
| 19:32 | amalloy | oh i guess it's only last year |
| 19:34 | danlentz | should I just always use (defn foo ^Thing [] …) instead of (defn ^Thing foo [] …) ? |
| 19:34 | hiredman | no |
| 19:34 | danlentz | only primitives? |
| 19:35 | hiredman | you shouldn't do either until you've yelled at someone who can get patches in for a while |
| 19:35 | danlentz | in reading lein-eastwood I found out that all of my (defn ^long foo [] …) were not correct |
| 19:35 | hiredman | yeah |
| 19:35 | hiredman | for primitives that is correct |
| 19:35 | danlentz | so that is a pisser |
| 19:35 | amalloy | https://www.refheap.com/4d7acc00d8cbdf6e67afe77c2 - cgrand's answer, parameterized for the keys to index on |
| 19:36 | hiredman | ,(doc clojure.set/index) |
| 19:36 | clojurebot | Huh? |
| 19:36 | hiredman | clojurebot: jerk |
| 19:36 | clojurebot | you cut me deep, man. |
| 19:36 | justin_smith | ,(require 'clojure.set) |
| 19:36 | clojurebot | nil |
| 19:37 | justin_smith | (doc clojure.set/index) |
| 19:37 | clojurebot | "([xrel ks]); Returns a map of the distinct values of ks in the xrel mapped to a set of the maps in xrel with the corresponding values of ks." |
| 19:37 | danlentz | but (defn foo ^x.y.Thing [] ….) is correct, according to the eastwood page on :wrong-tag |
| 19:37 | hiredman | :/ |
| 19:37 | danlentz | so wouldnt it be best to always just use type hints in that position and to just fully qualify them if needed? |
| 19:37 | danlentz | for consistency? |
| 19:38 | hiredman | danlentz: I am looking at the page for wrong tag, it says (defn foo ^x.y.Thing [] ….) is incorrect |
| 19:39 | hiredman | is that what you meant? |
| 19:39 | hiredman | danlentz: hilariously it was an attempt to bring consistency that left us in this state |
| 19:40 | danlentz | i’m kind of more bothered by this than most other rought edges ive run into |
| 19:40 | danlentz | i mean, this seems actually crazy |
| 19:41 | amalloy | danlentz: a lot of totally crazy things are explained by "historically x was true, so this crazy thing y made sense at the time" |
| 19:41 | danlentz | ;; no warning for this since it is fully qualified |
| 19:41 | danlentz | (defn linklist3 ^java.util.LinkedList [coll] (java.util.LinkedList. coll)) |
| 19:42 | danlentz | which one came first? putting the return type on the var? |
| 19:42 | amalloy | yes |
| 19:42 | danlentz | is the history of this written up somewhere? |
| 19:42 | hiredman | danlentz: I think you are confusing two different warnings about tags there |
| 19:43 | danlentz | well, two warnings but i dont think i have them confused |
| 19:43 | hiredman | danlentz: eastwood may warn about them in the same linter, but the full qualified classname is an entirely distinct issue from where the tag goes |
| 19:43 | danlentz | no not exactly |
| 19:43 | amalloy | hiredman: is it? |
| 19:43 | danlentz | because if the fully qualified classname is not supplied |
| 19:44 | danlentz | for meta on argument vecotr, then it will cause an error when used in another namespace |
| 19:44 | amalloy | my understanding is that if you put a fully-qualified classname on the arglist, it works "as intended", but an unqualified classname throws exceptions or something later |
| 19:44 | irctc_ | amalloy: many thanks for the rewritten function on refheap! |
| 19:44 | hiredman | Oh of course, and that is the mess left by the attempt to unify them |
| 19:44 | danlentz | using fully qualified classname as tag on the argument vector resolves the issue |
| 19:44 | amalloy | right |
| 19:45 | danlentz | it is something that at very least would be really helpful to do a better job pointing out n the official clojure docs |
| 19:45 | danlentz | warn you that something unexpected is lurking |
| 19:45 | justin_smith | this reminds me of the repo I made to try to disambiguate this stuff |
| 19:46 | justin_smith | I should work on that again soon |
| 19:46 | danlentz | i kind of like the dunaj syntax approach myself |
| 19:48 | danlentz | so, type hints on the argument vector — are they |
| 19:49 | danlentz | so when I type hint an argument vector to indicate return value — is that “first class” metadata? If it is not associated with a var, would it be possible to introspect back out the return value type hint of a function? |
| 19:49 | danlentz | i can’t get at it with (meta var) obviously |
| 19:55 | qqq | !hello |
| 19:55 | qqq | !list |
| 19:58 | oskarkv | Hey! I just pushed this https://github.com/oskarkv/map-regexps Feel free to critique and comment about anything, it's my frist public lib |
| 20:00 | dnolen | inf-clojure can be made to work w/ ClojureScript, https://github.com/clojure/clojurescript/wiki/Emacs-%26-Inferior-Clojure-Interaction-Mode |
| 20:01 | TEttinger | that looks handy, oskarkv |
| 20:01 | dnolen | with a couple of tweaks to ClojureScript and couple of tweaks to inf-clojure could probably be made to work great |
| 20:01 | oskarkv | TEttinger I'm glad you think so :) |
| 20:01 | danlentz | oskarkv: this is interesting, nice work! |
| 20:01 | oskarkv | thanks |
| 20:01 | TEttinger | one odd quirk: {} has a meaning in textual regexps that could be useful to have an analogue to |
| 20:02 | TEttinger | ,(re-find #"a{3}" "aardvark? aaaaaagh!") |
| 20:02 | clojurebot | "aaa" |
| 20:02 | oskarkv | Yeah |
| 20:02 | danlentz | what school are you doing clojure at, if you dont mind me asking |
| 20:02 | TEttinger | yeah, I'm also curious |
| 20:02 | gfredericks | TIL inf-clojrue |
| 20:03 | oskarkv | Royal institute of technology, sweden |
| 20:03 | bendlas | oskarkv: does it nest? like, can keys and values be regexp? |
| 20:03 | TEttinger | that's a good question, bendlas, since regular text regexps don't have a concept of nested strings |
| 20:04 | oskarkv | bendlas No, but maybe one could make it so |
| 20:05 | bendlas | oskarkv, TEttinger, yeah, I think it's kind of curious to have a grammar of concatenative (regexp) over context-free (maps) |
| 20:05 | TEttinger | oskarkv, yeah I think if this handled more than just sequences of maps, it could be more generally useful, but already it's a fairly novel technique to what previously was an annoyance in clojure code |
| 20:05 | TEttinger | *to solve what |
| 20:06 | bendlas | oskarkv: I like that you expose run-single-step. too many parsers overlook the need for incremental parsing |
| 20:06 | oskarkv | Right now keys are compared with =, but it would be easy to check if the key is a fn, it could instead apply that fn as a predicate |
| 20:06 | danlentz | so, I could use this to specify a path grammar over a graph? |
| 20:07 | oskarkv | danlentz I'm afraid I'm not sure what you mean |
| 20:08 | TEttinger | it could be useful to support just plain ol sequences of non-collection values. |
| 20:08 | oskarkv | TEttinger yes, that would probably be farily easy to do |
| 20:09 | oskarkv | But for [] and {}, maybe we need new metacharacters if they are clojure literals instaed |
| 20:10 | bendlas | oskarkv: a non-string based DSL might also be an option, since in clojure you already have powerful data literals |
| 20:10 | TEttinger | true |
| 20:10 | bendlas | IIRC, cgrand has done a regexp parsing dsl in clojure |
| 20:12 | danlentz | i dont purport to fully grok why, but I seem to recall reading on clojars that the org.clojars.oskarkv group recommended for private forks? |
| 20:12 | oskarkv | Hm, non-string based DSL, what kind? |
| 20:12 | oskarkv | danlentz oh, maybe |
| 20:13 | amalloy | org.clojars.yourname is for you; use it however you want |
| 20:13 | bendlas | oskarkv: https://github.com/cgrand/regex |
| 20:14 | danlentz | “Personal groups are designed to hold things like throwaway alpha versions and forks of other projects. They’re long and ugly on purpose to encourage official releases to use canonical groups.” |
| 20:15 | danlentz | https://github.com/ato/clojars-web/wiki/Groups |
| 20:17 | bendlas | oskarkv: you can do that kind of dsl pretty easily in any functional language, based on applicative/monadic parsing, but I'm not entirely sure how that ties in to the notion of a vm-based model of regexps |
| 20:18 | oskarkv | bendlas If I understand correctly, with cgrand's lib I can make REs out of data, but then use them on text as with regular regexps? |
| 20:19 | bendlas | oskarkv: yes |
| 20:19 | amalloy | bendlas: what does all this have to do with virtual machines? (which i think is what you mean by vm) |
| 20:19 | oskarkv | Anyway I imagined that my lib would be used to search for patterns in logs, etc |
| 20:20 | danlentz | state machine |
| 20:20 | danlentz | ? |
| 20:20 | oskarkv | amalloy I based my implementation on this http://swtch.com/~rsc/regexp/regexp2.html |
| 20:21 | bendlas | that's what I'm not sure about, but my I guess so |
| 20:22 | bendlas | you mentioned the Russ Cox paper "the virtual machine approach" and my intuition was, that this must be the alternative to doing a monadic parser |
| 20:22 | danlentz | related, have you looked at clj-rpe? |
| 20:22 | bendlas | erm, amalloy, oskarkv mentioned it on the gh readme |
| 20:23 | oskarkv | Hm, I'm not sure what a monadic parser is. But the parsing step is already done by the time that VM stuff comes along |
| 20:23 | oskarkv | ...in my lib |
| 20:23 | danlentz | vm = state machine, though. |
| 20:24 | oskarkv | Yes, more or less |
| 20:24 | bendlas | in a monadic parser, you define a parser monad which holds you parser state, like read ahead, and then your parsers are monadic values. monadic bind usually means concatenation |
| 20:24 | danlentz | this is a good article, thanks for pointing it out |
| 20:25 | bendlas | then you build up your grammar with combinators |
| 20:26 | bendlas | oskarkv: what's the vm stuff that comes along in your parser? |
| 20:26 | danlentz | bendlas: your explaination reminds me of: “Wadler tries to appease critics by explaining that "a monad is a monoid in the category of endofunctors, what's the problem?" |
| 20:27 | danlentz | http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html |
| 20:27 | oskarkv | bendlas the parser just parses the RE into an AST. But after that you need to make some machinery to actually use it on the input string to match stuff |
| 20:27 | bendlas | danlentz: not every functional language, though ;-) |
| 20:29 | bendlas | danlentz: I see your point, I guess the beauty of it is, how a really generic operation like m-bind can mean parser concatenation |
| 20:29 | oskarkv | bendlas so the VM stuff is like a NFA that you read about in automata theory |
| 20:29 | bendlas | kind of like how matrix multiplication can mean translation/rotation/scaling/shearing in one |
| 20:32 | creese | Can someone comment on the advantages of macros over code generation? |
| 20:33 | bendlas | oskarkv: I see, so I guess in a (m-word) parser, the AST is already given by the source language but I really have to read up on some theory, to get a grasp on how an NFA maps over |
| 20:33 | justin_smith | creese: macros can use the higher level facilities of the language for operating on collections, while code generation is typically limited to string munging |
| 20:34 | justin_smith | creese: for example, we don't need to make any special effort to prevent adjacent symbols in a macro combining to form an erroneous third symbol |
| 20:35 | oskarkv | bendlas I'm not sure about monadic parsers, but I always thought that a parser parses the input text (source code, regexp, etc) into an AST, according to a given grammar. But, just as in compilers, you are not done after parsing. You have code generation left. |
| 20:36 | amalloy | oskarkv: a parser doesn't have to use characters as its input type. bendlas is talking about a "parser" whose input type is the maps you're trying to match |
| 20:36 | creese | justin_smith: makes sense |
| 20:37 | bendlas | oskarkv: do you mean in this case, parsing the definition of the parser and then generating code to actually parse the input language? |
| 20:37 | creese | justin_smith are macros in clojure evaluated at run-time or compiled? |
| 20:37 | justin_smith | creese: compiled only |
| 20:37 | bendlas | amalloy: that. characters are just the sole input type for a subset of parsers |
| 20:38 | justin_smith | creese: though in jvm clojure the compiler is always present at runtime, if that's really needed |
| 20:39 | creese | I'm wondering how I can have a macro fed by params from a config file and not pay any penalty for that at run-time |
| 20:40 | creese | does it recompile when I change the config parameter and reload? |
| 20:40 | justin_smith | creese: if the config file is available at compile time, it should just work |
| 20:40 | creese | it isn't |
| 20:40 | creese | it's read at run-time |
| 20:40 | creese | when the app starts |
| 20:40 | justin_smith | creese: no, there is no automatic recompilation in clojure |
| 20:40 | amalloy | creese: you can't. how could a macro run at compile time modify your source code based on the information available in config files at runtime? |
| 20:40 | justin_smith | creese: app start is compile time, if you haven't loaded all your namespaces yet |
| 20:41 | justin_smith | but yeah |
| 20:41 | bendlas | oskarkv: so in a monadic parser, you basically try to reuse as much of you host language as possible. meaning you define the parser syntax in terms of the host syntax and then try to get the host compiler doing the parser generation for you. Then the input language can consist of a stream of characters, or whatever it is you are trying to parse. |
| 20:41 | oskarkv | bendlas Well in my case, I have a grammar for the REs. And I use a parser generator (once) to generate a parser for the REs. Then from the AST of a particular RE, I construct a VM that does the matching. The input map sequence does not need a parser, because they are not arranged in any special way. |
| 20:42 | justin_smith | creese: also, there's nothing a macro can do that a function can't, except for syntax (including "not evaluating some arguments" as syntax here) |
| 20:44 | catern | argh |
| 20:44 | catern | argh argh |
| 20:44 | catern | argh |
| 20:44 | catern | argh |
| 20:44 | catern | okay, so, if I want to do something that is really comfortable in Clojure |
| 20:44 | catern | and I don't want to write a web app |
| 20:44 | oskarkv | bendlas ok, I see. |
| 20:44 | catern | what should I do? |
| 20:44 | raspasov_ | justin_smith: yea I was always wondering, how is passing a fn1 to a fn2 for fn1 to be executed later different from a macro? (except for the syntactic nicety about it) ? |
| 20:44 | justin_smith | raspasov_: exactly |
| 20:44 | catern | (i.e. what is something else really comfortable in Clojure) |
| 20:45 | catern | (inb4 nothing) |
| 20:45 | bendlas | catern: logfile processing |
| 20:45 | catern | bendlas: is that a joke? |
| 20:45 | justin_smith | catern: graph / data analysis. |
| 20:45 | raspasov_ | justin_smith: I mean, yea there might be some perf overhead, but that would be the passing of a fn pointer to a fn |
| 20:45 | catern | justin_smith: as in, graph algorithms? |
| 20:45 | raspasov_ | which probably nears zero |
| 20:46 | catern | I could do more incanter stuff I guess |
| 20:46 | justin_smith | catern: as in working on a bunch of data in a graph. |
| 20:46 | catern | justin_smith: ok |
| 20:46 | justin_smith | so yeah, partially graph algorithms, sure |
| 20:46 | catern | er |
| 20:46 | catern | ok |
| 20:47 | justin_smith | anything server oriented with a long uptime |
| 20:47 | raspasov_ | justin_smith: not being a macro expect myself, I have been preferring passing a fn to a fn instead of writing a macro, I feel it makes the code easier for me to understand, and for people later on I hope |
| 20:47 | bendlas | oskarkv: ok and how do you tie in the once-generated RE parser into a particular VM? |
| 20:47 | raspasov_ | justin_smith: and more composable |
| 20:47 | bendlas | (inc raspasov_) |
| 20:47 | lazybot | ⇒ 1 |
| 20:47 | justin_smith | raspasov_: yes, this is all true |
| 20:48 | justin_smith | (inc raspasov) |
| 20:48 | lazybot | ⇒ 2 |
| 20:48 | justin_smith | bendlas: lazybot doesn't know that raspasov_ and raspasov are the same person |
| 20:48 | bendlas | justin_smith: yeah, that's the problem with pointer based equality ;-) |
| 20:49 | justin_smith | bendlas: it's string based actually, mongodb |
| 20:49 | raspasov_ | justing_smith: thanks, I'm glad I got something right :) |
| 20:49 | bendlas | justin_smith: well, all pointers are strings in memory |
| 20:49 | oskarkv | bendlas The parser (a function in my case) returns the AST. Then I have a function `compile-re` that takes it and returns a set of instructions for the VM. But the VM is pretty simple (just a few functions) that take those instructions and run them on the input map seq. |
| 20:50 | raspasov | corrected nickname :) |
| 20:51 | bendlas | (inc raspasov) |
| 20:51 | lazybot | ⇒ 3 |
| 20:51 | bendlas | there you go |
| 20:52 | raspasov | bendlas: thanks, I didn't do much :) |
| 20:52 | bendlas | yay for (fn [a] (fn [b] )) |
| 20:52 | bendlas | that's exactly the point. I hate it, when programmers do too much to solve a simple problem |
| 20:53 | raspasov | bendlas: haha, that's very true |
| 20:54 | raspasov | all that being said, macros definitely have their place, I mean a lot of Clojure is written in it, it's just that I think you really need to be sure that the macro that you're writing has value beyond your own few namespaces, otherwise it would just be there to confuse people I feel like |
| 20:54 | creese | justin_smith: thankx |
| 20:54 | raspasov | written in them* |
| 20:54 | bendlas | oskarkv: cool, I'll have a look at the instruction set of your VM and will definitely read the paper.. interesting stuff |
| 20:58 | bendlas | raspasov: sure, some of my best friends use macros ;-) |
| 20:59 | bendlas | joking aside, the latest case where I needed them was, when the alternative was writing a hundred little wrapper functions, by hand, based on some documentation, where I could just generate them with a macro based on reflection |
| 20:59 | raspasov | bendlas: haha |
| 21:00 | raspasov | bendlas: yea that's a good example |
| 21:00 | bendlas | and boy was I glad to have them then |
| 21:29 | oskarkv | bendlas_mobile https://www.refheap.com/98920 |
| 21:47 | bendlas | oskarkv: ok, that instruction sequence looks like a code generator could optimize the living hell out of it. OTOH, from just glancing, I find it kind of hard to get a grip on the various magic numbers |
| 21:47 | bendlas | but I guess that's the way of things with low-level representations |
| 21:55 | oskarkv | bendlas optimize how? The numbers are just indices into the sequence of instructions itself |
| 21:56 | oskarkv | except for the save ones :P |
| 21:57 | justin_smith | oskarkv: it's like the difference between an interpreter and a compiler - the same info that you use in the form of numeric indexes, could be converted to remove a level of indirection and get put directly on the execution stack |
| 21:59 | oskarkv | justin_smith yeah |
| 22:02 | bendlas | justin_smith: well put |
| 22:03 | oskarkv | I'm not sure how I would do that. Do you know something I could read? |
| 22:05 | bendlas | not sure, maybe documentation of your target byte code: x86? llvm? |
| 22:05 | justin_smith | oskarkv: hmm... not sure what the best resource for that would be. Probably not the asm.java docs (though this is the tool clojure uses to accomplish that task) |
| 22:05 | oskarkv | Or, maybe I just don't understand exactly what you mean. Converted how exactly? |
| 22:05 | bendlas | or yeah, jvm |
| 22:06 | oskarkv | Ok |
| 22:06 | justin_smith | oskarkv: it's the concept of compilation, instead of writing code that looks up the next step, then executes it, you generate bytecode representing the series of steps, and the program just executes them one after another |
| 22:06 | justin_smith | you could also convert the state machine into a function, and let clojure do the compilation part |
| 22:07 | justin_smith | by lifting out the variables to be args, and then putting the steps in sequence |
| 22:07 | bendlas | partial evaluation might also be a worthwile avenue |
| 22:08 | oskarkv | Ah, I see |
| 22:08 | oskarkv | Will have to think about it |
| 22:22 | bendlas | oskarkv: also, if you implemented nesting (regexes as keys/values), I suspect there were some deep insights to be had from how { and } would correspond to push and pop on the execution stack |
| 22:24 | oskarkv | bendlas perhaps ;) |
| 22:25 | oskarkv | But right now I'm looking for some problems that people even just might solve with my lib, so that I can claim it's useful. I really need it to get this school thing done :P |
| 22:26 | oskarkv | Opimizing by compiling more seems fun though |
| 22:28 | amalloy | if you want to optimize by compiling, in a lisp it's a lot easier than generating bytecode directly with asm. you can just generate the sexprs for a function body, and then eval the function |
| 22:28 | oskarkv | Yeah |
| 22:29 | justin_smith | yeah, that's what I meant by letting clojure do the compilation part |
| 22:29 | bendlas | yup, IMO that's the real use case for eval |
| 22:30 | bendlas | (apart from repl) |
| 22:36 | justin_smith | bendlas: speak for yourself, I find the rpl perfectly useful |
| 22:36 | justin_smith | (aka "cat") |
| 22:38 | bendlas | yeah, nothing like going from lazy-seq to transducer and back ;-) |
| 22:39 | bendlas | justin_smith: maybe we should call it ripl: read-identity-print-loop |
| 22:43 | bendlas | just as long as nobody starts going full circle and call it a 'disruptor' |
| 22:44 | justin_smith | mace of disruption, most powerful weapon against undead |
| 22:44 | bendlas | :-) |
| 22:45 | bendlas | ring of fire, baby |
| 23:58 | chr15m | hello, this is probably a stupid question, but does anyone know how, in vim, to gather any loose closing parentheses in a block onto the end of the last line? |