2015-09-05
| 01:14 | reutermj | How do you add metadata to a macro with a def? `(def ^{:some-meta 4} ~name 4) doesn't work. |
| 01:19 | amalloy | reutermj: http://stackoverflow.com/a/11920022/625403 |
| 01:23 | reutermj | amalloy: ok so when I set *print-meta* and change the macro to `(def ~(vary-meta name assoc :some-meta 4) 4) it prints the correct meta data. But, calling (meta some-name) returns nil |
| 01:24 | amalloy | (meta #'some-name) |
| 01:25 | reutermj | ok that was mentioned earlier. What exactly does that reader macro do? |
| 01:30 | amalloy | ,'#'x |
| 01:30 | clojurebot | (var x) |
| 01:31 | reutermj | thanks |
| 01:31 | reutermj | (inc amalloy) |
| 01:31 | lazybot | ⇒ 300 |
| 02:42 | TEttinger | (identity amalloy) |
| 02:42 | lazybot | amalloy has karma 300. |
| 02:42 | TEttinger | congrats |
| 03:58 | Quasimodem | I have experience with programming, java, c++, Pascal(good intro for me). I think what essentially is true in programming, is that it's more based on mindset, and how you use the language to benefit you. |
| 06:21 | ashwink005 | can I convert a list of HashMaps, to a vector of HashMaps? |
| 06:24 | Rurik | ashwink005, yes, wrap the list in vec |
| 06:24 | Rurik | ,(vec ()) |
| 06:24 | clojurebot | [] |
| 06:27 | mavbozo | ,(vec '({:a 1} {:b 2})) |
| 06:27 | clojurebot | [{:a 1} {:b 2}] |
| 06:42 | irctc | Hello everyone, is there any reason why clojure is not implemented in clojure? |
| 06:42 | Rurik | irctc, it is implemented in clojure |
| 06:43 | Rurik | irctc, https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj |
| 06:43 | irctc | but why does 60% of the code base is written in java ? |
| 06:44 | luxbock | Rurik: it's only partly implemented in Clojure, though there is a separate projects that can read, analyze and emit JVM bytecode |
| 06:45 | luxbock | I wonder why the Clojure jar doesn't include the java files btw |
| 06:45 | luxbock | it would be nice if I could jump to the Java source location from my editor |
| 07:00 | sobel | there may be a distribution that includes source in the same jar but typically sources are omitted for brevity |
| 07:05 | clj-beginner | Hello. |
| 07:06 | clj-beginner | Can try take multiple expressions? |
| 07:06 | clj-beginner | Most of the examples that I have seen uses only one expression before catching |
| 07:06 | clj-beginner | is it possible to use multiple? |
| 07:07 | clj-beginner | I tried experimenting but I kept on getting a class cast exception error |
| 07:07 | luxbock | sobel: looking here I see that such a .jar exists https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0/ |
| 07:08 | luxbock | but using [org.clojure/clojure "1.7.0-sources"] doesn't seem to work, nor does it mention sources in the pom file |
| 07:08 | amalloy | http://central.maven.org/maven2/org/clojure/clojure/1.7.0/clojure-1.7.0-sources.jar |
| 07:08 | amalloy | luxbock: it's not a differently-named artifact |
| 07:08 | amalloy | it's the same artifact with a different qualifier - look up how to get sources from maven in general |
| 07:08 | amalloy | or maybe classifier? i forget |
| 07:09 | luxbock | amalloy: ok thanks |
| 07:09 | mavbozo | ,(try (inc 1) (inc 2)) |
| 07:09 | sobel | luxbock: sorry, i don't have the details, and i actually don't hope to step into Clojure code if I can help it :) |
| 07:09 | clojurebot | 3 |
| 07:19 | luxbock | I think :classifier "sources" is right, but I get the following stacktrace when I try to start my REPL: https://gist.github.com/luxbock/b78272185608adb6b7b8 |
| 07:20 | luxbock | No matching method: unsignedShiftRight, compiling:(clojure/core.clj:1337) |
| 07:21 | luxbock | I feel like it's taunting me |
| 07:23 | luxbock | it did download the clojure-1.7.0-sources.jar though |
| 07:27 | luxbock | so I guess the -sources .jar only includes the sources and not the class files |
| 07:29 | luxbock | so you can't even start a REPL with it via clojure.main |
| 10:40 | ashwink005 | can anyone give me a simple example how return a string containing "foo" x number of times |
| 10:40 | ashwink005 | *how to |
| 10:42 | Rurik | ,(apply str (repeat 3 "foo")) |
| 10:42 | clojurebot | "foofoofoo" |
| 10:42 | rhg135 | (apply str (repeat 10 "foo")) |
| 10:42 | Rurik | ashwink005, this works? ^ |
| 10:42 | ashwink005 | Rurik: this can be done without loop? |
| 10:43 | ashwink005 | cool |
| 10:43 | ashwink005 | yup thanks |
| 10:48 | tomjack | should there be a "confirm before running a template you just downloaded" option for lein? |
| 10:59 | sobel | why? |
| 10:59 | clojurebot | sobel: because you can't handle the truth! |
| 10:59 | sobel | ...guess i asked for that |
| 11:00 | sobel | tomjack: it's a CLI development tool. i'm thinking, probably not. |
| 11:01 | justin_smith | I could imagine a "delete this code that breaks the project to prove you've read the code the template generates" |
| 11:02 | justin_smith | but that would be weird |
| 11:05 | tomjack | I'm imagining camping in clojars on many distance 1 edits of popular templates.. |
| 11:06 | justin_smith | oh, template-name typos |
| 11:06 | sobel | the correct way to manage that is to stop it at the source so the fewest number of people would be affected. beyond that, my strategy is don't take risks on precious machines. my code has been unpredictable in the past... |
| 11:07 | justin_smith | so "lein new rung" would send all your private ssh keys to my obfuscated email |
| 11:07 | sobel | the threat is within, i guess, is the lesson i take to security. there are also external threats but they are less likely to really mess things up for me. |
| 11:07 | justin_smith | tomjack: the problem is that a template can do arbitrary code at creation time - just cloning is enough to be screwed |
| 11:08 | justin_smith | s/cloning/using the template/ |
| 11:08 | justin_smith | really, there should at least be an easy way to browse and approve a template before using (especially since versions are implicit...) |
| 11:08 | tomjack | right, in the lein new code it's "download, then immediately (require 'leiningen.new.whatever)" |
| 11:09 | sobel | this is perfect timing, as i contemplate converting a config file reader from to eval so i can put more interesting expressions in it |
| 11:09 | sobel | slurping edn, as it were |
| 11:10 | justin_smith | there's definitely room for an alternate, non-turing-complete template tool in the clojure ecosystem |
| 11:10 | sobel | think i'm gonna run with it, dangerous as it is. but i wonder what more cautious developers would do here, before exposing eval to essentially random files |
| 11:10 | sobel | i used to like the Velocity template language but most impls let you call into the host language from its ECMA-like macro language |
| 11:10 | sobel | other than that, i think it had a long of things right |
| 11:11 | justin_smith | sobel: my preference would be to let the user supply a function explicitly to be run |
| 11:11 | justin_smith | without having to just evaluate file contents - let them provide some implementation of a configuring protocol |
| 11:12 | sobel | so basically whitelist some functions |
| 11:12 | justin_smith | that's not what I said at all |
| 11:12 | sobel | figured. i don't exactly follow what you said. |
| 11:12 | justin_smith | if they want to run arbitrary code, use a code oriented interface, not eval on a text file |
| 11:13 | justin_smith | define a protocol that is used for config, and let them provide an implementation of that protocol |
| 11:13 | patrkris | does anyone here know how to specify an optional keyword in a map that includes a ? character in herbert? |
| 11:15 | sobel | er, "dependency injection in clojure" just crossed my search results. of all the things i am pretty damn sure i don't need in clojure, that tops my list. |
| 11:16 | justin_smith | sobel: running eval on a config file is dependency injection. In fact it is the worst kind of dependency injection. |
| 11:17 | sobel | that's one way to look at it |
| 11:17 | sobel | degenerate DI |
| 11:17 | sobel | maybe it's the DI framework i don't need. obviously i employ the concept liberally. |
| 11:18 | sobel | or non-obviously |
| 11:18 | justin_smith | sobel: I think with higher order functions available, DI is trivial |
| 11:18 | justin_smith | no more special than a loop |
| 11:18 | sobel | exactly |
| 11:19 | sobel | everything i used DI for in java is obviated by clojure |
| 11:19 | mavbozo | i call it Devilish Injection |
| 11:19 | justin_smith | I agree that we don't need frameworks in order to do it, but I still think it's better to define a protocol that a user can implement and pass to your code, rather than running an eval on a special file |
| 11:19 | sobel | it's a valuable practice in Java |
| 11:20 | sobel | justin_smith: fortunately i can get by with read rather than eval, but agreed |
| 11:21 | oddcully | patrkris: does adding two ? work (:lerl??) |
| 11:22 | patrkris | oddcully: it does. should've tried it. that's the obvious way :D thanks. |
| 11:38 | ashwink005 | whats the clojure way of getting all rows in a db WHERE column example "contains" a substring |
| 11:38 | ashwink005 | the best way I mean |
| 11:40 | ashwink005 | anyone? someone knows mysql/sqlite? |
| 11:41 | mavbozo | ashwink005, what's wrong with select * from user where name LIKE '%jure%' |
| 11:42 | ashwink005 | actually I have many such columns and many such values |
| 11:42 | ashwink005 | was wondering if there was a cleaner way |
| 11:43 | mavbozo | cleaner way to generate the query? |
| 11:44 | mavbozo | or the fastest query? |
| 11:53 | sdegutis | Wouldn't (defn ^:memoize foo [bar] ...) be so cool? |
| 11:54 | ashwink005 | mavbozo: nope a shorter way |
| 12:03 | mavbozo | ashwink005, i usually create a function that generates the query string |
| 12:04 | ashwink005 | mavbozo: yeah actually now I'm doing the same :) |
| 12:04 | ashwink005 | thanks |
| 12:05 | sdegutis | Is there a more condensed or idiomatic way to do this? (set! (. Stripe apiKey) secret-key) |
| 12:06 | mavbozo | ashwink005, it's the same thing i did in other prog-langs. I still haven't found the idiomatic clojure way. |
| 12:06 | ashwink005 | mavbozo: hmmm |
| 12:16 | ashwink005 | one small doubt, how do I change the value of a string in its lexical scope? |
| 12:17 | ashwink005 | (str symbol "something") returns the concatenated string but doesn't append "something" to the beginning of symbol |
| 12:18 | ashwink005 | some help please |
| 12:19 | ashwink005 | google can't |
| 12:22 | RedNifre | maybe (str (str symbol) "something") ? |
| 12:22 | RedNifre | nvm I think I missunderstood what you are trying to do. |
| 12:23 | justin_smith | RedNifre: fyi (str (str x) y) is the same as (str x y) |
| 12:23 | mavbozo | ,(let [c "c"] (str s "=me")) |
| 12:24 | clojurebot | #error {\n :cause "Unable to resolve symbol: s in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: s in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: s in this context"\n ... |
| 12:24 | justin_smith | ashwink005: strings are immutable |
| 12:24 | mavbozo | ,(let [c "c"] (str c "=me")) |
| 12:24 | clojurebot | "c=me" |
| 12:24 | justin_smith | ashwink005: if you want something you can mutate, consider a functional restructuring using recursion perhaps, or you can use a StringBuilder |
| 12:24 | mavbozo | ashwink005, do you want the value of c becomes "c=me"? |
| 12:24 | justin_smith | $javadoc StringBuilder |
| 12:24 | lazybot | http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuilder.html |
| 12:24 | ashwink005 | mavbozo: yes |
| 12:25 | ashwink005 | justin_smith: so I'll have to use a stringbuilder |
| 12:25 | ashwink005 | or I can create a new variable? |
| 12:26 | justin_smith | ashwink005: sure, that too |
| 12:26 | ashwink005 | okok got it strings are imutable.. like in java |
| 12:26 | justin_smith | ,(let [a "c" b (str a \= a) c (str b \& b)] c) |
| 12:26 | clojurebot | "c=c&c=c" |
| 12:26 | justin_smith | ashwink005: in fact... ##(type "") |
| 12:26 | lazybot | ⇒ java.lang.String |
| 12:26 | justin_smith | they are java strings :) |
| 12:27 | ashwink005 | justin_smith: yeah I reckoned |
| 12:27 | ashwink005 | thanks! |
| 12:33 | tmtwd_ | , (list 'if true (cons 'do (println "yay"))) |
| 12:33 | clojurebot | yay\n(if true (do)) |
| 12:34 | tmtwd_ | why is there the (if true (do)) there? |
| 12:34 | hyPiRion | because (println "yay") prints yay and returns nil |
| 12:34 | justin_smith | tmtwd_: that's the return value of he expression |
| 12:34 | justin_smith | ,(cons 'anything nil) |
| 12:35 | clojurebot | (anything) |
| 12:38 | tmtwd_ | oh |
| 13:20 | thesaskwatch | Hi .. I'd like to run some i/o tasks - a lot of them. Is there a way to partition them and run in let's say n threads at once? |
| 13:24 | thesaskwatch | Ok ... I guess it's just a partition, map and run a future |
| 13:27 | skeuomorf | So, I need to get the skinny on Clojure's concurrency story, from threads to core.async, any resources? Terseness with examples preferred |
| 13:33 | skeuomorf | Terseness and examples along with it* |
| 13:36 | justin_smith | skeuomorf: start with the docs on http://clojure.org/documentation for refs, agents, and atoms, then check out the relevant functions on http://conj.io |
| 13:37 | justin_smith | conj.io has more examples, but clojure.org is the better big-picture |
| 13:38 | justin_smith | also note that refs, agents, and atoms are three different strategies for managing concurrency, and each has their use cases (see also core.async, which is a whole other can of worms and also has its use cases) |
| 13:39 | skeuomorf | justin_smith: I read all these docs yesterday, haven't read the core.async ones |
| 13:39 | skeuomorf | justin_smith: They didn't mention any "threads", most of the talk was about how to "share" or "not share" resources in a sense |
| 13:39 | justin_smith | it's a whole other parallel system - you can use them together, but each (refs, agents, atoms, core.async) are usable on their own |
| 13:40 | justin_smith | skeuomorf: the simple way to make a thread is via future |
| 13:40 | justin_smith | skeuomorf: also, agents use a pool of threads for all operations - with agents the way to use a thread is hand a task to the agent |
| 13:40 | skeuomorf | Will take a look at that as well as the core.asyync docs |
| 13:40 | justin_smith | the agent will find and use a thread |
| 13:41 | skeuomorf | I see |
| 13:41 | justin_smith | skeuomorf: most of the time in my code, the threads are started by an http request (new client gets allocated a thread) |
| 13:41 | justin_smith | or a websocket connection |
| 13:41 | justin_smith | etc. |
| 13:42 | skeuomorf | Yeah, what I have in mind is something close, I will be using UDP though |
| 13:42 | skeuomorf | I am mostly trying to formulate my ideas in term of clojure abstractions instead of "objects" interacting with each other |
| 13:43 | justin_smith | UDP doesn't have connections though - so I guess it's more a thread per message |
| 13:43 | skeuomorf | Yeah, I will "fire off" multicast messages and occasional single destination ones |
| 13:43 | justin_smith | skeuomorf: you might want to check out aleph if you are listening for messages as well |
| 13:44 | skeuomorf | I stumbled upon that and it seemed interesting, will check it out |
| 13:45 | skeuomorf | When should one use defrecord instead of making a (defn make-record [] {:myid id :whatever 1}) |
| 13:46 | justin_smith | skeuomorf: once you go so far as having a special constructor, use a defrecord |
| 13:46 | justin_smith | skeuomorf: if you are creating maps ad-hoc, maybe you don't need a record |
| 13:46 | justin_smith | of course the real clincher is if you want to use protocols so that clients can provide behaviors in some system - then you really want defrecord |
| 13:47 | skeuomorf | nah, I am kinda making "instances" of a certain map structure |
| 13:47 | skeuomorf | Yeah, I will mostly define a protocol |
| 13:47 | justin_smith | skeuomorf: "instances" is enough reason to make a defrecord. If you are formalizing it, go ahead and formalizing it. |
| 13:47 | justin_smith | skeuomorf: for a protocol you need a defrecord because protocols dispatch by type, not keys |
| 13:48 | skeuomorf | Yeah, I figured that much |
| 13:48 | justin_smith | records are pretty lightweight, and mostly maps in every way that is useful, so I would jump over to using one as soon as you would give it a special name or constructor |
| 13:48 | skeuomorf | I see |
| 13:49 | justin_smith | skeuomorf: but the other thing you were talking about was being less OO |
| 13:49 | justin_smith | I think the key to that is think less about data types, and more about flows of data |
| 13:49 | justin_smith | *one key, at least |
| 13:49 | skeuomorf | Well,, |
| 13:50 | skeuomorf | I am thinking in flows of data alright, my problem is that I will have multiple "instances" and each one will affect the other in the same function |
| 13:51 | skeuomorf | so, 2 instances > function > 2 new instances |
| 13:51 | justin_smith | skeuomorf: I have a middleware that attaches a creation time, unique id, and client id to messages. This is fp because I ignore the type of the thing coming in (it just needs to be a type that lets me assoc). This is in contrast to expecting message senders to use my constructor which attaches that data. |
| 13:51 | justin_smith | skeuomorf: counting instances of things - so these things are tied to side effects and/ or state? |
| 13:52 | skeuomorf | well, both |
| 13:52 | skeuomorf | I am implementing SCAMP |
| 13:52 | skeuomorf | Which is a probabilistic gossip protocol |
| 13:52 | skeuomorf | re: http://research.microsoft.com/pubs/67296/ieee_tocs.pdf |
| 13:52 | justin_smith | OK - this is a different sense of "protocol" than I was using earlier |
| 13:53 | skeuomorf | oh, I know, don't worry |
| 13:53 | skeuomorf | :) |
| 13:53 | justin_smith | just making sure signals aren't getting crossed |
| 13:53 | skeuomorf | Yeah yeah, I got you |
| 13:53 | justin_smith | skeuomorf: a great idea I picked up from stuartsierra is that you should use FP for logic and computation and use OO for state. |
| 13:54 | justin_smith | and clojure has various ways of helping bring those together |
| 13:54 | justin_smith | a consequence of that, is the OO part of your code will often be singletons |
| 13:54 | justin_smith | (and of course in pure FP the concept of a singleton makes no sense) |
| 13:55 | joncol | Is there any way of having "lein new app" create a Mercurial repository instead of Git? |
| 13:55 | skeuomorf | well, let me tell you the mutable state "behavior" in this protocol |
| 13:55 | justin_smith | anyway - stepping away from the keyboard, but will be around later |
| 13:55 | justin_smith | go ahead and describe, I just can't reply right away |
| 13:55 | skeuomorf | justin_smith: Ok, nvm then, thanks for helping :) |
| 13:55 | justin_smith | maybe someone else here is interested too |
| 13:55 | skeuomorf | I will mess around anyways |
| 13:56 | skeuomorf | maybe will do an impl tonight |
| 13:58 | oddcully | joncol: lein new does not create a git repo (at least not for me) |
| 13:58 | oddcully | joncol: but it creates a .hgignore file (beside a .gitignore one) |
| 13:58 | joncol | oddcully: Oh, missed that :) |
| 14:07 | sineer | Hey hey! I got a question about CPU load averages |
| 14:08 | sineer | when running inside a KVM my server is idle yet I see varying CPU load averages... Is it that I somehow see the load average of a CPU that I'm sharing with another KVM instance? |
| 14:09 | sineer | I have the same idle server image running on two different KVM host and the load averages are always very much diferent, one can be at 0.95 while other is at 0.10 for instance |
| 14:09 | kitallis | I get a "java.lang.ClassNotFoundException: jsr166y.ForkJoinPool" when running lein repl, anyone know what that means? |
| 14:10 | Rurik | kitallis, are you running it in a project dir? |
| 14:10 | kitallis | yeah |
| 14:11 | kitallis | don't understand, this was fine a while back, not sure what I changed |
| 14:12 | Rurik | google says jsr166y is some concurrency library |
| 14:12 | oddcully | kitallis: bisect it |
| 14:12 | kitallis | yeah it says "java.lang.ClassNotFoundException: jsr166y.ForkJoinPool, compiling:(clojure/core/reducers.clj:56:21)" |
| 14:13 | kitallis | it's happening on all projects |
| 14:13 | oddcully | kitallis: same as here maybe? http://grokbase.com/t/gg/clojure/12c9wa1haj/exception-when-loading-clojure-core-reducers |
| 14:13 | kitallis | I think it's some global thing I messed up |
| 14:13 | oddcully | java version then? |
| 14:37 | dfens | If I have a map {:a 1} why do both (:a {:a 1}) and ({:a 1} :a) work? Isn't it confusing to have two ways to get the value of :a? |
| 14:39 | amalloy | dfens: why does (+ 1 5) work as well as (+ 5 1)? that's gotta be confusing too, right? |
| 14:40 | amalloy | keywords and maps are both functions, because it may be convenient to use either of them as functions in different contexts |
| 14:41 | dfens | amalloy: Ok sure thing. I guess I'll have a better grasp of that when I come across these different contexts :) |
| 14:42 | amalloy | dfens: well, examples are easy: ##[(map {:a 1, :b 2} [:a :b]) (map :a [{:a 1 :b 2} {:a 2 :b 1}])] |
| 14:42 | lazybot | ⇒ [(1 2) (1 2)] |
| 16:00 | cryptack | looking for some understanding between just deffn inside a function and using letfn? |
| 16:01 | justin_smith | cryptack: defn inside a function makes a top level binding |
| 16:02 | justin_smith | cryptack: letfn makes multiple functions, with only local bindings, which can refer to each other recursively without declarations needed |
| 16:03 | cryptack | so if I were to do (defn f1 [x] (defn f2 [y] y) (f2 x)) then that means that f2 can be called from outside of f1? |
| 16:03 | justin_smith | ,(letfn [a ([x] (b (b x))) b ([x] (+ x 21))] (a 0)) |
| 16:03 | clojurebot | #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Symbol"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.RT first "RT.java" 661]\n [clojure.core$fi... |
| 16:03 | justin_smith | cryptack: yes |
| 16:03 | cryptack | got it |
| 16:03 | cryptack | I’m assuming the same with just fn then? |
| 16:03 | justin_smith | ,(letfn [(a [x] (b (b x))) (b [x] (+ x 21))] (a 0)) |
| 16:03 | clojurebot | 42 |
| 16:03 | cryptack | like an named fn |
| 16:04 | justin_smith | cryptack: (let [a (fn [x] (b (b x))) b ([x] (+ x 21))] (a 0)) |
| 16:04 | justin_smith | err |
| 16:04 | justin_smith | ,(let [a (fn [x] (b (b x))) b ([x] (+ x 21))] (a 0)) |
| 16:04 | clojurebot | #error {\n :cause "Unable to resolve symbol: b in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: b in this context"\n ... |
| 16:04 | justin_smith | cryptack: unlike fn and let, letfn lets you forward reference |
| 16:04 | justin_smith | eg. for mutal recursion |
| 16:05 | cryptack | ok |
| 16:05 | justin_smith | notice the let version of my prior letfn fails because of the binding order |
| 16:05 | cryptack | justin_smith: okay |
| 16:06 | cryptack | justin_smith: |
| 16:06 | cryptack | justin_smith: thanks! |
| 16:41 | irctc | hello |
| 16:43 | irctc | is there a way to replace the current process with an other one in clojure |
| 16:43 | irctc | pretty much like exec() in C |
| 16:44 | irctc | i'd like a clojure script to ... just become a python script :p |
| 16:55 | skeuomorf | irctc: I don't know about "replace the current process" but checkout https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html |
| 16:55 | skeuomorf | irctc: You'd access that via the Clojure Java interop facilities |
| 16:56 | irctc | hmmm |
| 16:56 | irctc | but i don't know any clojure :/ |
| 16:56 | skeuomorf | Then, what are you doing writing clojure? |
| 16:57 | irctc | it's for a code golf achievement |
| 16:58 | irctc | i need to find a solution to a problem in clojure |
| 16:58 | irctc | i solved the problem in python |
| 16:58 | irctc | want to write a clojure script that would call my python scipt |
| 16:58 | irctc | :P |
| 16:58 | irctc | just did that with the bash achievement |
| 17:01 | justin_smith | (do (clojure.java.shell/sh "your-script.sh") (shutdown-agents) (System/exit 0)) |
| 17:02 | justin_smith | that exits after the script instead of before though |
| 17:02 | justin_smith | there's no way in java to do a normal exec because windows sucks |
| 17:59 | xzilend | Hi there, I'm relatively new to clojure/functional/declarative programming, and was wondering if anyone could suggest improvements to this gist (https://gist.github.com/adairdavid/f7983b15f63773340151) to better follow a functional/declarative style? |
| 18:03 | justin_smith | xzilend: instead of nested if you could try cond - I'm not sure if that is more functional, but I find it easier to parse |
| 18:05 | neoncontrails | Could someone help me understand the control flow of a function that evaluates serially, but rebinds in parallel? |
| 18:05 | neoncontrails | ,(doc recur) |
| 18:05 | clojurebot | No entiendo |
| 18:06 | justin_smith | neoncontrails: well, you can't do what you are describing with recur |
| 18:06 | neoncontrails | recur |
| 18:06 | neoncontrails | (recur exprs*) |
| 18:06 | neoncontrails | Special Form |
| 18:06 | neoncontrails | Evaluates the exprs in order, then, in parallel, rebinds the bindings of the recursion point to the values of the exprs. |
| 18:06 | justin_smith | recur only works in the tail position, so can't be invoked in parallel |
| 18:06 | neoncontrails | Execution then jumps back to the recursion point, a loop or fn method. |
| 18:06 | justin_smith | err, oh that's a different kind of parallel... |
| 18:07 | justin_smith | neoncontrails: what it means is that the recur bindings are not applied in series the way let bindings are |
| 18:07 | justin_smith | neoncontrails: in let, you can refer to the value of other bindings in the same let binding block, because they are evaluated in series |
| 18:07 | neoncontrails | I thought I understood this, but I'm getting some funny outputs which might be explained by semi-arbitrary ordering of variable rebindings on the recursion |
| 18:07 | justin_smith | ,(let [a 0 b (inc a) c (inc b)] c) |
| 18:07 | clojurebot | 2 |
| 18:08 | justin_smith | neoncontrails: the bindings inside recur don't refer to the values of other bindings in the recur |
| 18:08 | justin_smith | they refer to the values in scope when recur is called |
| 18:09 | neoncontrails | I see. Gotcha. So no referring to the (first s) of some sequence that's getting repeatedly dropped on the recursion, then |
| 18:10 | neoncontrails | Within the recur statement, that is |
| 18:10 | justin_smith | ,(loop [a 0 b 10] (if (> a b) (+ a b) (recur (* a b) (* b 0.9))) |
| 18:10 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 18:10 | sg2002 | Hello. Anyone having any problems with the latest cider? I get No active nREPL connection even though there is one. |
| 18:10 | justin_smith | neoncontrails: well you can refer to first s, just be aware of which s it binds to |
| 18:11 | justin_smith | neoncontrails: inside the recur it will be whatever s was bound when this recursive call started |
| 18:11 | justin_smith | inside the loop declaration, it is only the initializer and doesn't effect future values when recurring |
| 18:11 | justin_smith | sg2002: I find that when cider does that I need to clean up my elc files, restart emacs, then reinstall cider |
| 18:12 | neoncontrails | Hmm. Let me pastebin my function, maybe you can tell me if I'm doing something illegal inside the recur statement |
| 18:12 | justin_smith | sg2002: #clojure-emacs might be able to offer more help, I stopped using cider because of how often it broke backward compatibility. |
| 18:13 | sg2002 | justin_smith: Oh, never knew about that channel. Thank's for the tip, there are some weird byte-compile bugs that happen once in a blue moon. |
| 18:14 | justin_smith | sg2002: in my experience what was happening is that they were breaking api compatibility with their old code versions, which made the byte compiled code break |
| 18:14 | justin_smith | and like every release would do this |
| 18:16 | neoncontrails | justin_smith: http://pastebin.com/4dtCrL7G |
| 18:17 | justin_smith | neoncontrails: those bindings should work... |
| 18:17 | neoncontrails | It's perfectly likely there's just a bug in the logic, I just want to make sure I'm using the primitives correctly |
| 18:17 | justin_smith | yeah, that looks like a perfectly cromulent usage of recur |
| 18:17 | neoncontrails | Okay, cool. I'll treat it as a bug in the logic then. :) |
| 18:17 | neoncontrails | Thanks! |
| 18:17 | neoncontrails | (inc justin_smith) |
| 18:17 | justin_smith | the thing about parallel vs. serial bindings is a bit of a finicky point |
| 18:17 | lazybot | ⇒ 294 |
| 18:17 | sg2002 | justin_smith: That's pretty weird, since package.el generally recompiles that stuff every time. |
| 18:18 | justin_smith | sg2002: maybe they don't describe their dependencies properly... |
| 18:18 | justin_smith | because I definitely fixed my problems by wiping out my package managed elisp code |
| 18:18 | neoncontrails | Yeah, what... precisely does it mean, exactly? |
| 18:18 | neoncontrails | I understand the difference between serial and parallel |
| 18:19 | amalloy | neoncontrails: (= (count s) < 3) ?? |
| 18:19 | justin_smith | what it means is that in eg. let one let binding can refer to the value of the one right before it |
| 18:19 | lazybot | amalloy: What are you, crazy? Of course not! |
| 18:19 | neoncontrails | I am not sure what it means to interleave them |
| 18:19 | justin_smith | oh, yeah that is super weird! |
| 18:19 | justin_smith | (inc amalloy) |
| 18:19 | lazybot | ⇒ 301 |
| 18:19 | justin_smith | I missed that one |
| 18:19 | justin_smith | you likely want (< (count s) 3) |
| 18:20 | justin_smith | what you did was test if (count s), <, and 3 are all the same |
| 18:20 | justin_smith | which of course is trivially false |
| 18:20 | justin_smith | (unless someone is doing bad bad things to your comparison operators) |
| 18:20 | amalloy | and the (second uncompressed) looks like it ought to be (first compressed) |
| 18:21 | amalloy | neoncontrails: you know there is a much easier way to implement RLE, right? you are just doing it this way as a loop/recur exercise? |
| 18:21 | neoncontrails | amalloy: Do tell! |
| 18:22 | neoncontrails | I am doing this as an exercise, but I'm always interested in learning efficient, better ways to solve problems. :) |
| 18:22 | amalloy | look at ##((fn rle [s] (apply str (mapcat (juxt count identity) (partition-by identity s)))) "aaabddcejkkeddddddd") |
| 18:22 | lazybot | ⇒ "3(\\a \\a \\a)1(\\b)2(\\d \\d)1(\\c)1(\\e)1(\\j)2(\\k \\k)1(\\e)7(\\d \\d \\d \\d \\d \\d \\d)" |
| 18:22 | amalloy | er |
| 18:22 | amalloy | ##((fn rle [s] (apply str (mapcat (juxt count first) (partition-by identity s)))) "aaabddcejkkeddddddd") |
| 18:22 | lazybot | ⇒ "3a1b2d1c1e1j2k1e7d" |
| 18:23 | justin_smith | you clojure wizards and your fancy repl tricks |
| 18:23 | justin_smith | I tell ya what |
| 18:23 | neoncontrails | Too cool. I'm going to meditate on that one for a bit, brb |
| 18:24 | justin_smith | neoncontrails: many of those functions are worth a very deep meditation and practice and mastery |
| 18:24 | justin_smith | (inc juxt) |
| 18:24 | lazybot | ⇒ 23 |
| 18:24 | justin_smith | (inc comp) |
| 18:24 | lazybot | ⇒ 2 |
| 18:25 | neoncontrails | Wait what's going on. Are you giving the language primitives karma |
| 18:25 | oddcully | we give even rubber ducks karma |
| 18:25 | justin_smith | yes, it's a tridition here |
| 18:25 | justin_smith | (inc rubberduck) |
| 18:25 | lazybot | ⇒ 6 |
| 18:25 | justin_smith | *tradition |
| 18:26 | justin_smith | while I'm at it |
| 18:26 | justin_smith | (dec flatten) |
| 18:26 | lazybot | ⇒ -7 |
| 18:26 | neoncontrails | Hahahahaha. Clojurians, you crack me up. :) |
| 18:26 | amalloy | RIP flatten. never forget |
| 18:26 | oddcully | boo flatten |
| 18:26 | amalloy | (dec tridition) |
| 18:26 | lazybot | ⇒ -1 |
| 18:27 | justin_smith | amalloy: sometimes I also pronounce things atrociously, it's like I have a gibberish demon trying to crawl its way out |
| 18:28 | amalloy | i spell concise right about one time in three |
| 18:28 | amalloy | got it wrong here, before backspacing |
| 18:29 | justin_smith | also my handwriting is very bad (though I have been trying to improve that lately because it's a nice break from screen/keyboard oriented stuff) - so all methods of conveying words have an added noise layer |
| 19:18 | Matachines | hey guys, new-ish to clojure/cljs, was wondering what the commonly used library for generating statistics is (stuff like mean/standard deviation, etc) |
| 19:19 | bacon1989 | interesting, I don't even know what scientific libraries there are |
| 19:19 | justin_smith | Matachines: yeah, there's incanter for that http://incanter.org/ |
| 19:19 | Matachines | thanks justin_smith |
| 19:19 | Matachines | ! |
| 19:19 | justin_smith | it does graphing too |
| 19:19 | Matachines | perfect |
| 19:20 | justin_smith | I do graph analysis for my day job, we've been intending to start adding statistical analysis to our bag of tools for making metrics |
| 19:21 | bacon1989 | justin_smith: you ever use gorilla repl for fast sketches? |
| 19:21 | justin_smith | bacon1989: no, I've intended to try it but haven't yet |
| 19:21 | justin_smith | bacon1989: and there's another similar one, the name is escaping me... |
| 19:21 | bacon1989 | i've used it before, and found it pretty awesome |
| 19:21 | bacon1989 | especially when working with people who don't know clojure |
| 19:22 | justin_smith | seems like it would be a kickass learning tool |
| 19:22 | bacon1989 | ya def, I agree |
| 19:23 | justin_smith | though my tried and true is to only do things that work when you run "java -jar clojure.jar" because eliminating tooling problems from teaching is so nice |
| 20:20 | justin_smith | neoncontrails: ##(let [m (java.util.HashMap.)] (.put m :a 0) (.put m :b 1) m) |
| 20:20 | lazybot | ⇒ {:b 1, :a 0} |
| 21:06 | justin_smith | ,@(reify clojure.lang.IDeref (deref [this] "OK")) |
| 21:06 | clojurebot | "OK" |
| 22:36 | justin_smith | woohoo, just got my delivery estimate for "Clojure Applied" - I guess that means they have an official book release date. |
| 23:17 | neoncontrails | How would you express this logic more beautifully? http://pastebin.com/5C8sMp9i |
| 23:17 | neoncontrails | I know I'm making it about 4 times more complicated than it needs to be |
| 23:23 | bacon1989 | oh neat function |
| 23:24 | neoncontrails | Thanks -- just a little exercise from 'Cracking the Coding Interview' |
| 23:25 | TEttinger | ,((fn [v colls] (map #(if (some #{v} %) (repeat (count %) v) (seq %)) colls)) 5 [[1 2 3] [4 5 6] [7 0 8]]) |
| 23:25 | clojurebot | ((1 2 3) (5 5 5) (7 0 8)) |
| 23:25 | amalloy | (defn if-any-then-all [x colls] (for [coll colls] (if (some #(= % x) coll) (map (constantly x coll)) coll))) |
| 23:26 | amalloy | TEttinger: you have to be careful with #{x}: what if someone calls this with x=nil? |
| 23:26 | TEttinger | ah, I was wondering which was preferred |
| 23:26 | neoncontrails | nice! I like the comparison of your approaches |
| 23:26 | TEttinger | (inc amalloy) |
| 23:26 | lazybot | ⇒ 302 |
| 23:27 | neoncontrails | (inc amalloy) |
| 23:27 | lazybot | ⇒ 303 |
| 23:27 | neoncontrails | (inc TEttinger) |
| 23:27 | lazybot | ⇒ 65 |
| 23:27 | TEttinger | I haven't seen (constantly x coll) before |
| 23:27 | TEttinger | (doc constantly) |
| 23:27 | clojurebot | "([x]); Returns a function that takes any number of arguments and returns x." |
| 23:28 | TEttinger | ... possibly for good reason |
| 23:28 | TEttinger | ,(constantly 5 [1 2 3]) |
| 23:28 | clojurebot | #error {\n :cause "Wrong number of args (2) passed to: core/constantly"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/constantly"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [sandbox$eval76 invokeStatic "NO_SOURCE_FILE" 0]\n [sandb... |
| 23:30 | neoncontrails | I was *just* about to ask about that |
| 23:31 | neoncontrails | I understand it at each step of the way, but there |
| 23:31 | TEttinger | ,(defn if-any-then-all [x colls] (for [coll colls] (if (some #(= % x) coll) (map (constantly x)) coll))) |
| 23:31 | clojurebot | #'sandbox/if-any-then-all |
| 23:31 | TEttinger | ,(if-any-then-all 5 [[1 2 3] [4 5 6] [7 0 8]]) |
| 23:31 | clojurebot | ([1 2 3] #object[clojure.core$map$fn__4537 0x29a1cd66 "clojure.core$map$fn__4537@29a1cd66"] [7 0 8]) |
| 23:31 | TEttinger | ugh |
| 23:31 | TEttinger | ,(defn if-any-then-all [x colls] (for [coll colls] (if (some #(= % x) coll) (map (constantly x) coll) coll))) |
| 23:31 | clojurebot | #'sandbox/if-any-then-all |
| 23:31 | TEttinger | ,(if-any-then-all 5 [[1 2 3] [4 5 6] [7 0 8]]) |
| 23:31 | clojurebot | ([1 2 3] (5 5 5) [7 0 8]) |
| 23:32 | TEttinger | it was a misplaced paren is all |
| 23:33 | amalloy | ah, indeed. i'm just mashing stuff out in irc |
| 23:33 | amalloy | hm, maybe it's time to look back into erc |
| 23:33 | neoncontrails | Constantly works in an interesting way, I notice |
| 23:33 | neoncontrails | ,(map #(constantly %) (range 10)) |
| 23:33 | clojurebot | (#object[clojure.core$constantly$fn__4371 0x432ae0b5 "clojure.core$constantly$fn__4371@432ae0b5"] #object[clojure.core$constantly$fn__4371 0x3406ad86 "clojure.core$constantly$fn__4371@3406ad86"] #object[clojure.core$constantly$fn__4371 0x226a5319 "clojure.core$constantly$fn__4371@226a5319"] #object[clojure.core$constantly$fn__4371 0x72759ff5 "clojure.core$constantly$fn__4371@72759ff5"] #object[clo... |
| 23:34 | bacon1989 | man, what other channels let's you mess around with the language in them? |
| 23:34 | bacon1989 | fucking clojure |
| 23:34 | TEttinger | ,(map constantly (range 10)) |
| 23:34 | clojurebot | (#object[clojure.core$constantly$fn__4371 0x28b15282 "clojure.core$constantly$fn__4371@28b15282"] #object[clojure.core$constantly$fn__4371 0x119fe9ad "clojure.core$constantly$fn__4371@119fe9ad"] #object[clojure.core$constantly$fn__4371 0x19a665e5 "clojure.core$constantly$fn__4371@19a665e5"] #object[clojure.core$constantly$fn__4371 0x7b6baa8a "clojure.core$constantly$fn__4371@7b6baa8a"] #object[clo... |
| 23:34 | amalloy | bacon1989: a lot of them |
| 23:34 | bacon1989 | like what? |
| 23:34 | amalloy | haskell, python, java are a few i know of |
| 23:34 | TEttinger | haskell has lambdabot |
| 23:34 | amalloy | probably ruby, i would be very surprised if not |
| 23:34 | bacon1989 | oh right |
| 23:35 | bacon1989 | I guess they're all interpreted |
| 23:35 | TEttinger | (lambdabot is apparently very hard to change by anyone who didn't write it, despite being open source) |
| 23:35 | amalloy | no, java isn't |
| 23:35 | amalloy | neither is clojure really, we just have eval |
| 23:35 | TEttinger | haskell is compiled, but it does have a REPL |
| 23:35 | TEttinger | scala has a bot |
| 23:36 | TEttinger | multibot IIRC, it can do multi-line output to a certain limit |
| 23:36 | bacon1989 | interesting |
| 23:36 | amalloy | anyway, an irc bot is a pretty standard thing for a programming language, because programmers want it so badly |
| 23:36 | TEttinger | perl6 has camelia and glrelia, the latter of which is meant to show changes made in the GLR branch of the code |
| 23:36 | bacon1989 | also, isn't Java9 supposed to have a repl soon? |
| 23:37 | amalloy | plot twist: java 9 is groovy |
| 23:37 | neoncontrails | Heh, cute |
| 23:37 | neoncontrails | ,(reduce + (map (constantly 1) [:a :b :c])) |
| 23:37 | clojurebot | 3 |
| 23:37 | bacon1989 | amalloy: haha |
| 23:37 | TEttinger | you can compile java 9 today, it actually isn't as hard as 7 or 8 |
| 23:37 | TEttinger | (and yes, it starts up faster) |
| 23:37 | bacon1989 | TEttinger: that is exciting |
| 23:37 | TEttinger | they reorganized a lot of stuff, and still are, so it only loads core modules at startup |
| 23:38 | bacon1989 | so that should mean clojure will start faster? |
| 23:38 | bacon1989 | I wonder if i'll ever see the day when clojure can be used for command-line tools |
| 23:38 | TEttinger | somewhat yes. clojure still has its own lib to run, but less overhead from the JVM itself should help |
| 23:38 | TEttinger | pixie or an SSD :) |
| 23:39 | bacon1989 | been looking at pixie |
| 23:39 | bacon1989 | also, been looking at racket |
| 23:39 | bacon1989 | (since John Carmack seems to like it) |
| 23:39 | TEttinger | I'm looking at None, which has unfortunately less clojure influence, more traditional scheme (no immutable stuff that I can tell) |
| 23:41 | TEttinger | it's very early in development it seems, but if you're targeting specifically the things that clojure doesn't (real-time low-level stuff), then None seems like a decent Lisp to use? https://bitbucket.org/duangle/none/overview |
| 23:43 | bacon1989 | neat, i'll check it out |
| 23:44 | TEttinger | I suspect None will be more usable in a few months |
| 23:46 | bacon1989 | personally I find it interesting because i've done a lot of work in lua |