2015-07-09
| 00:17 | shiranaihito | elvis4526: there are only stupid answers :) |
| 00:19 | currentoor | Has anyone built a datomic backed application and deployed to heroku? |
| 00:26 | currentoor | I was wondering what's the right way to deploy a datomic backed app for a beginner? |
| 00:31 | namra | hm there's something i don't understand with atoms: http://pastebin.com/iGYyF7M9 |
| 00:31 | namra | it'll throw a nullpointer exception at the places (not (nil? kh @heartbeat-counter)) and (< (kh @heartbeat-counter)) |
| 00:31 | namra | and i don't understand why |
| 00:32 | namra | someone an idea? |
| 01:29 | andyf_ | namra: still there? |
| 02:03 | namra | clojuredocs.org down? |
| 02:14 | kwladyka | when should i use sets? |
| 02:14 | kwladyka | if i need unique values it mean i should sets or not necessary? |
| 02:26 | namra | kwladyka: "Sets are collections of unique values. |
| 02:26 | namra | " |
| 02:26 | namra | so yea if you want a collection with no duplicates |
| 02:27 | namra | (doc #{}) |
| 02:27 | clojurebot | #error {\n :cause "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.Symbol"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassCastException: clojure.lang.PersistentHashSet cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6644]}\n {:type java.lang.ClassCastException\n :message "clojure.lang.PersistentHas |
| 02:27 | namra | (doc #) |
| 02:27 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 02:27 | namra | (doc sorted-set) |
| 02:27 | clojurebot | "([& keys]); Returns a new sorted set with supplied keys. Any equal keys are handled as if by repeated uses of conj." |
| 02:27 | namra | (doc set) |
| 02:27 | clojurebot | "([coll]); Returns a set of the distinct elements of coll." |
| 02:30 | kwladyka | do you have idea what will be the best way to save coordinates on 2-dimension board with description what is there? For example #{[[1 1 :king][1 3 :king][3 2 :rookie] [[1 1 :king][2 3 :rookie][3 1 :king]]} <- but i am not satisfy with that... i need something in more order like... i could read give-me-all-positions-with-order-and-what-is-there |
| 02:34 | kwladyka | in other word: i am looking the best way to write/read coordinates on 2-dimension board to later draw this board |
| 02:36 | aztak | kwladyka: hehe, I'm doing something similar to render a maze :) |
| 02:36 | aztak | I actually use a hash where keys are the coordinates: |
| 02:37 | aztak | {[0 0] {:some-content 123}, [0 1] {:another-content 345}} |
| 02:37 | aztak | Lookup is then simply ([0 0] map-ref) |
| 02:38 | aztak | Not sure if it's the best approach - another alternative would be nested vectors (a 2-d array). |
| 02:38 | kwladyka | mmm now it looks like obviously solution :) |
| 02:38 | kwladyka | aztak, thx |
| 02:41 | kwladyka | aztak, did you miss #? {[0 0] {:some-content 123}, [0 1] {:another-content 345} or #{[0 0] {:some-content 123}, [0 1] {:another-content 345} ? |
| 02:42 | kwladyka | how do you solve only one thing can be in one place? |
| 02:43 | aztak | No - '#{}' is a Set, right? I have a Hashtable '{:key1 value :key2 value}' |
| 02:43 | aztak | kwladyka: I don't - it isn't needed for my maze hack :/ |
| 02:44 | aztak | (but unique coordinates is enforced since the coordinates [x y] is the key of the Hashtable) |
| 02:46 | kwladyka | aztak, i think i need something like #{{[1 1] :king, [1 3] :king, [3 2] :rookie} {[3 3] :king, [1 3] :king, [1 2] :rookie} {[3 3] :king, [1 3] :king, [2 1] :rookie} {[2 3] :rookie, [1 1] :king, [3 1] :king}} |
| 02:47 | kwladyka | yeah but i have to remeber all possible unique configurations of figures on the board |
| 02:47 | kwladyka | so i think i should use sets of maps :) |
| 02:50 | kwladyka | *rookie -> rook :) |
| 03:40 | celwell | Hi, is there a prettier way to write this, since it's using the 'o' so repetively: |
| 03:40 | celwell | (defn valid-price? |
| 03:40 | celwell | "Is the stated 'total_price' accurate?" |
| 03:40 | celwell | [db-conn o] |
| 03:40 | celwell | (= (:total_price o) |
| 03:40 | celwell | (calculate-cost db-conn |
| 03:40 | celwell | (:gas_type o) |
| 03:40 | celwell | (:gallons o) |
| 03:40 | celwell | (:time-in-minutes o) |
| 03:40 | celwell | (:coupon_code o) |
| 03:40 | celwell | (:vehicle_id o) |
| 03:40 | celwell | (:user_id o) |
| 03:40 | celwell | (:referral_gallons_used o)))) |
| 03:40 | justin_smith | celwell: don't do that |
| 03:41 | celwell | oops, should have used a gist I guess |
| 03:42 | celwell | Here is the code: https://gist.github.com/celwell/08aa26dade2550d92631 |
| 03:42 | justin_smith | celwell: (apply calculate-cost db-conn ((juxt :gas_type :gallons :time-in-minutes :coupon_code :vehicle_id :user_id :referral_gallons_used) o)) |
| 03:43 | justin_smith | celwell: alternately (apply calculate-cost db-conn (map o [:gas_type :gallons :time-in-minutes :coupon_code :vehicle_id :user_id :referral_gallons_used])) |
| 03:44 | justin_smith | it might also make sense to define calculate-cost to take a hash-map as an arg |
| 03:44 | celwell | Hmm... thanks. How would you personally do it? |
| 03:44 | celwell | the last suggestion? |
| 03:44 | justin_smith | I think so, unless I had a strong case not to use a hash, I usually use a hash-map arg if there are that many individual parameters |
| 03:45 | justin_smith | the calls are just more readable that way usually |
| 03:45 | Bronsa | don't forget about destucturing |
| 03:46 | justin_smith | yeah, I'd be destructuring on the impl side :) |
| 03:46 | celwell | sorry, how would destructing work? |
| 03:47 | justin_smith | (defn calculate-cost [db {:keys [gas_type gallons time-in-minutes ...]}] ...) |
| 03:47 | justin_smith | then you call (calculate-cost db o) |
| 03:47 | celwell | interesting route to go |
| 03:48 | justin_smith | I'd do it that way if the args usually all come from the same place |
| 03:48 | justin_smith | I'd likely even do it if they didn't for readability's sake... |
| 05:08 | expez | If you give me a new file path, how can I construct a matching ns name? Is this even possible without asking boot or leiningen about the project layout? |
| 05:16 | expez | What I'm doing now is given a path I list all the dirs on classpath and use those to drop a prefix from the path, that should leave me with a relative path which I can turn into a ns. If there's more than one hit I grab the shortest path :/ |
| 05:28 | Thoocei1 | Hello. I have a rather minor question regarding reader conditionals. It seems to me that clojure used to use vector literals for the cases where there is key-value pairs the order of which does matter. Reader conditionals, though, use list literal. Is there any meaning to it or is it just a random choice? |
| 06:16 | fikusz | (type (int 10)) gives me java.lang.Integer: how can I get a primitive int type? |
| 06:28 | Pupeno | Does anybody have a recommendation on libraries to do http requests (get, posts, cookies) and parsing the resulting html? |
| 06:30 | arrdem | $mail andyf great that sorting function worked perfectly and is live as of now. bug fixed. |
| 06:30 | lazybot | Message saved. |
| 06:32 | dstockton | Pupeno: clj-http and enlive? |
| 06:33 | Pupeno | Thanks. |
| 06:45 | Pupeno | Do you use envile for parsing HTML? it looks like a templating engine. |
| 06:47 | tdammers | it's both, in a way |
| 06:47 | tdammers | although that might not be immediately obvious from skimming the documentation |
| 07:55 | Pupeno | Is there a more idiomatic way to do two assoc-ins other than nesting them? |
| 08:07 | aztak | Pupeno: assoc supports multiple key-values |
| 08:07 | aztak | ,(def a-map {:foo "bar"}) |
| 08:07 | clojurebot | #'sandbox/a-map |
| 08:07 | Pupeno | aztak: but I'm not using assoc, I'm using assoc-in. |
| 08:08 | aztak | ,(assoc a-map :zip "zap" :zap "zip") |
| 08:08 | clojurebot | {:foo "bar", :zip "zap", :zap "zip"} |
| 08:08 | aztak | ah :) |
| 08:08 | aztak | read that too fast, sorry :) |
| 08:08 | Pupeno | np |
| 08:27 | hyPiRion | Pupeno: Depends on the keys you pass to assoc-in. (-> (assoc-in m [:foo :bar] "bar") (assoc-in [:foo :baz] "baz")) = (update-in m [:foo] (assoc :bar "bar" :baz "baz)) = (update m :foo (assoc ...)) |
| 08:28 | hyPiRion | Though I tend to thrush my update-ins sometimes without issues, and I don't think it's unidiomatic. |
| 08:38 | aztak | hyPiRion: ah, yeah - threading makes the assoc-in slightly less verbose ... I tried using reduce and a vector of vectors - but that's too obfuscated imo. |
| 08:40 | aztak | something like (multi-assoc-in m [:foo :baz "bar"] [:foo :bar "baz"]) |
| 08:49 | crocket | How do I traverse a list recursively for side effects in a clojure macro? |
| 08:49 | crocket | clojure.walk.walk doesn't seem to fit my need. |
| 08:50 | crocket | I want to collect the list of symbols in a list and return it. |
| 09:10 | snowell | crocket: Do you mean get only the values that are symbols? |
| 09:10 | snowell | Either way it doesn't sound like a side effect |
| 09:12 | justin_smith | crocket: in a list, or a nested list? |
| 09:14 | crocket | (get-symbols (+ 1 2 3 (- 1 2 3))) == ("+" "-") |
| 09:14 | crocket | I want to write get-symbols macro) |
| 09:15 | crocket | justin_smith, snowell ^^ |
| 09:15 | snowell | ,(filter symbol? (flatten '(+ 1 2 3 (- 1 2 3)))) |
| 09:15 | clojurebot | (+ -) |
| 09:15 | justin_smith | ,(map name (filter symbol (tree-seq '(+ 1 2 3 (- 1 2 3))))) |
| 09:15 | clojurebot | #error {\n :cause "Wrong number of args (1) passed to: core/tree-seq"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/tree-seq"\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" 32]\n [sandbox$eval49 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Co... |
| 09:15 | justin_smith | :P |
| 09:16 | crocket | ,(map name (filter symbol? (tree-seq '(+ 1 2 3 (- 1 2 3))))) |
| 09:16 | clojurebot | #error {\n :cause "Wrong number of args (1) passed to: core/tree-seq"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/tree-seq"\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" 32]\n [sandbox$eval73 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Co... |
| 09:16 | justin_smith | ,(map name (filter symbol (tree-seq seq seq '(+ 1 2 3 (- 1 2 3))))) |
| 09:16 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.String> |
| 09:16 | justin_smith | ,(map name (filter symbol? (tree-seq seq seq '(+ 1 2 3 (- 1 2 3))))) |
| 09:16 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol> |
| 09:16 | snowell | (apply str (filter symbol? (flatten '(+ 1 2 3 (- 1 2 3))))) |
| 09:16 | justin_smith | ugh |
| 09:17 | snowell | ,(apply str (filter symbol? (flatten '(+ 1 2 3 (- 1 2 3))))) |
| 09:17 | clojurebot | "+-" |
| 09:17 | crocket | Clojure compiler is rejecting your errors. |
| 09:17 | snowell | grr |
| 09:17 | snowell | ,(map str (filter symbol? (flatten '(+ 1 2 3 (- 1 2 3))))) |
| 09:17 | clojurebot | ("+" "-") |
| 09:17 | crocket | ,(doc flatten) |
| 09:17 | clojurebot | "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns an empty sequence." |
| 09:17 | justin_smith | ,(map name (filter symbol? (tree-seq seq? seq '(+ 1 2 3 (- 1 2 3))))) |
| 09:17 | clojurebot | ("+" "-") |
| 09:18 | crocket | ,(doc tree-seq) |
| 09:18 | clojurebot | "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree." |
| 09:18 | snowell | justin_smith's answer is probably better or more elegant. Usually is :D |
| 09:18 | crocket | I think snowell's solution is more concise. |
| 09:19 | crocket | ,(filter symbol? (tree-seq seq? seq'(+ 1 2 3 (- 1 2 3)))) |
| 09:19 | clojurebot | #error {\n :cause "Unable to resolve symbol: seq' in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: seq' in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: seq' in this co... |
| 09:19 | crocket | ,(filter symbol? (tree-seq seq? seq'(+ 1 2 3 (- 1 2 3))))) |
| 09:19 | clojurebot | #error {\n :cause "Unable to resolve symbol: seq' in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: seq' in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: seq' in this co... |
| 09:20 | crocket | ,(filter symbol? (tree-seq seq? seq '(+ 1 2 3 (- 1 2 3)))) |
| 09:20 | clojurebot | (+ -) |
| 09:20 | crocket | ,(doc flatten) |
| 09:20 | clojurebot | "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns an empty sequence." |
| 09:20 | musty | :( |
| 09:20 | crocket | ,(flatten (+ 1 2 3 (- 4 5 6 (+ 7 8 9) 10 11 12))) |
| 09:20 | clojurebot | () |
| 09:20 | crocket | ,(flatten (+ 1 2 3 (- 4 5 6 10 11 12)))\ |
| 09:20 | clojurebot | () |
| 09:20 | snowell | crocket: You have to quote the list |
| 09:21 | justin_smith | ,(flatten {:a 0 :b [1 2 3]}) |
| 09:21 | clojurebot | () |
| 09:21 | crocket | ,(flatten '(+ 1 2 3 (- 4 5 6 10 11 12))) |
| 09:21 | clojurebot | (+ 1 2 3 - ...) |
| 09:21 | crocket | ,(flatten '(+ 1 2 3 (- 4 5 6 ))) |
| 09:21 | clojurebot | (+ 1 2 3 - ...) |
| 09:21 | justin_smith | ,(flatten #{[:a :b :c] [[:d :e] :f]}) |
| 09:21 | clojurebot | () |
| 09:22 | crocket | ,(flatten '#{[:a :b :c] [[:d :e] :f]}) |
| 09:22 | clojurebot | () |
| 09:22 | crocket | Is set a sequence? |
| 09:22 | justin_smith | ,(seq? #{:a}) |
| 09:22 | clojurebot | false |
| 09:22 | justin_smith | ,(coll? #{:a}) |
| 09:22 | clojurebot | true |
| 09:22 | crocket | ,(seq? [1 2 3]) |
| 09:22 | clojurebot | false |
| 09:23 | crocket | (seq? '(1 2 3)) |
| 09:23 | crocket | ,(seq? '(1 2 3)) |
| 09:23 | clojurebot | true |
| 09:24 | crocket | ,(list? '(1 2 3)) |
| 09:24 | clojurebot | true |
| 09:24 | justin_smith | ,(list? (list 1 2 3)) |
| 09:24 | clojurebot | true |
| 09:24 | crocket | ,(coll? '#{1 2 3}) |
| 09:24 | clojurebot | true |
| 09:24 | justin_smith | you don't need the ' there |
| 09:24 | crocket | I think clojure will be complemented well by pixie. |
| 09:25 | crocket | clojure is a lot more elegant than java, javascript, python, C, and C++. |
| 09:25 | tdammers | that's not a very high standard to compare yourself with :x |
| 09:26 | crocket | Those are the languages I learned in the past, |
| 09:26 | crocket | I can't compare clojure with languages I haven't learned. |
| 09:26 | tdammers | obviously :D |
| 09:26 | crocket | I retired as a commercial programmer, and now I learn at home. |
| 09:27 | tdammers | cool |
| 09:27 | crocket | Most commercial programming environments are degrading. |
| 09:27 | tdammers | tell me about it |
| 09:27 | crocket | Most companies prevent you from learning. |
| 09:27 | tdammers | I'm lucky enough to have found one where at least the technical side of things is pretty awesome, and we can mostly ignore the business shenanigans |
| 09:28 | crocket | tdammers, Which company do you work for? |
| 09:28 | tdammers | tiny one in the netherlands |
| 09:28 | crocket | Is it a lab? |
| 09:28 | tdammers | nope |
| 09:28 | crocket | It's typically a corporate lab. |
| 09:28 | tdammers | well, not really... we're not sure yet |
| 09:28 | crocket | Can you tell me the name? I want to see the website. |
| 09:28 | tdammers | we don't really have a website |
| 09:29 | crocket | ok |
| 09:29 | tdammers | working on that |
| 09:29 | crocket | What do you do? |
| 09:29 | crocket | What does the company do? |
| 09:29 | tdammers | government-related stuff |
| 09:29 | tdammers | we're operating on the edge between government IT and the corporate world |
| 09:29 | crocket | Anyway, good luck with maintaining a high degree of autonomy once your company grows beyond 20 people. |
| 09:29 | tdammers | oh, the parent company is larger than that |
| 09:30 | vas_ | Hi everyone.. |
| 09:30 | tdammers | but our team is currently 5 people |
| 09:30 | vas_ | What does "Don't know how to create ISeq from: java.lang.Long" usually mean o_O |
| 09:30 | tdammers | with a bit of commercial support from "outside" |
| 09:30 | tdammers | (in the form of marketing, sales, profitability research, etc.) |
| 09:30 | justin_smith | vas_: it means numbers are not sequential collections |
| 09:30 | crocket | A good thing about learning at home is you get to learn and work on things as you see fit. |
| 09:30 | tdammers | (and also money) |
| 09:30 | justin_smith | vas_: eg. ##(first 1) |
| 09:30 | lazybot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long |
| 09:30 | tdammers | crocket: absolutely, and clojure is a wonderful playground for these things |
| 09:31 | crocket | No company would pay me for what I want to do for now. |
| 09:31 | tdammers | me neither, but this is close enough for now |
| 09:32 | crocket | I plan to learn several languages and AIs. |
| 09:32 | vas_ | justin_smith: Oh thank you that is very clear. |
| 09:32 | crocket | It's going to take 3-4 years to finish learning and start working on AIs. |
| 09:32 | crocket | However, the learning doesn't stop there. |
| 09:32 | tdammers | nah, I wouldn't look at it that way |
| 09:32 | crocket | It will take about 3-4 years to start working on AIs. |
| 09:32 | tdammers | you never finish learning, you just do things as well as you can, and you learn along the way |
| 09:33 | crocket | tdammers, I was about to say that I never stop learning. |
| 09:33 | tdammers | and no, I don't think you need to spend 3 years before you can write a simple AI |
| 09:33 | copycat | how does clojure compare with racket? |
| 09:33 | crocket | tdammers, The kind of AIs that I want to write takes years of learning. |
| 09:33 | crocket | tdammers, I'm learning it from a mentor. |
| 09:33 | tdammers | I believe you could probably learn enough clojure to write something like a state transition diagram based AI within a month or so |
| 09:34 | crocket | tdammers, His AI design requires knowledge of semiotics, turing ordinal, and so on... |
| 09:34 | tdammers | just do a bunch of simple ones first, and you'll stumble upon the relevant language features |
| 09:34 | tdammers | ah, but then the bottleneck is more in the realm of grokking the theory |
| 09:34 | tdammers | not so much implementing it in a programming language |
| 09:35 | crocket | tdammers, Right now, I don't even know the relevent theories. |
| 09:35 | tdammers | exactly |
| 09:35 | tdammers | I bet once you do, and have gotten your feet wet a bit, the implementation part isn't going to be the biggest problem |
| 09:35 | crocket | Meanwhile, I want to build some useful web services that I use personally. |
| 09:35 | crocket | I also want to write some simple CLI apps in clojure-like pixie. |
| 09:36 | crocket | I'd definitely use clojure for any non-trivial apps... |
| 09:39 | crocket | copycat, You can compare runtime performance characteristics of clojure and racket. |
| 09:39 | crocket | Racket runtime doesn't require a lot of RAM, and it starts up fast. |
| 09:39 | crocket | But, after loading, racket is slower than clojure. |
| 09:39 | copycat | i don't think i'm programming at a level where i need to care about the run time performance |
| 09:39 | crocket | Runtime performance matters if you want to write simple CLI apps. |
| 09:40 | crocket | clojure doesn't fit small CLI apps. |
| 09:40 | tdammers | ^ |
| 09:40 | crocket | For any CLI app that needs to be executed repeatedly, startup time needs to be small. |
| 09:40 | copycat | what are examples of CLI apps? |
| 09:40 | r4vi | there's also hy which allows you to use the python interpreter |
| 09:40 | tdammers | exactly. if you want to use it in a script, we're talking milliseconds here |
| 09:40 | copycat | i've only made GUIs for fun |
| 09:40 | crocket | copycat, DDNS clients, ntp clients |
| 09:41 | tdammers | the DDNS client could be written as a daemon though |
| 09:41 | copycat | to be honest |
| 09:41 | copycat | i've never heard of those terms |
| 09:41 | tdammers | the NTP clients *should* be written as a daemon, even, so that you can nudge instead of jump |
| 09:41 | crocket | If you want to run a DDNS client daemon on Raspberry Pi, clojure won't cut it. |
| 09:41 | copycat | like i said, i'm new to the world of software |
| 09:41 | copycat | GUIs are all i'm familiar with |
| 09:41 | tdammers | well, JVM in general on a Pi sounds like a bad idea to me |
| 09:42 | crocket | If you want to run daemons on OpenWrt and RaspBerry Pi, clojure will not make it. |
| 09:42 | copycat | which is why racket was so good for me, all i had to do was download an installer and everything worked out of the box on windows |
| 09:42 | copycat | with a simple easy-to-use ide |
| 09:42 | crocket | While Racket is a good language, it has multiple languages. |
| 09:42 | tdammers | idk, the IDE and how everything assumes that you want to use it somewhat turned me away from racket |
| 09:43 | tdammers | not my style at all |
| 09:43 | crocket | And, clojure has one style. |
| 09:43 | crocket | one langauge, one stgyle |
| 09:43 | copycat | i guess it's aimed for easing newbies into software development |
| 09:43 | crocket | tdammers, You can use emacs istead of DrRacket. |
| 09:44 | tdammers | crocket: more of a vim man myself |
| 09:44 | crocket | vim works well on terminals. |
| 09:44 | crocket | emacs doesn't. |
| 09:44 | copycat | what programs did you guys work on when you started learning programming? |
| 09:44 | copycat | CLI apps? |
| 09:44 | tdammers | MS-DOS 4 batch scripts |
| 09:44 | copycat | i thought most people begin by creating GUIs and games |
| 09:45 | zimablue | for me - yes, tiny c++ programs that calculated the movements of pendulums at uni, this was about 6 years ago |
| 09:45 | zimablue | I think the next generation will probably be straight in with guis and javascript |
| 09:46 | tdammers | the current generation already is |
| 09:46 | tdammers | mobile apps and all that |
| 09:47 | digiorgi | c++ data structures in the university |
| 09:52 | copycat | i have a couple of newbie questions |
| 09:54 | copycat | i know this sounds dumb, but what's so good about a question about being hosted on the jvm? |
| 09:54 | copycat | the website doesn't offer much in the way of information |
| 09:54 | justin_smith | copycat: existing corporate infrastructure |
| 09:54 | copycat | what does that mean in concrete examples? |
| 09:55 | justin_smith | both in terms of libs that connect to just about anything, and tooling and platforms that larger companies already have set up |
| 09:55 | tdammers | one advantage is that it's easier to sell to management |
| 09:55 | justin_smith | it means that if you need aes encryption, a cross-platform gui, UDP messaging using the OSC protocol etc. then the libs all exist |
| 09:55 | tdammers | you don't need to hire new IT staff, you don't even have to train them |
| 09:55 | tdammers | the deployment procedure is pretty much the same - "here's a jar, do your thing" |
| 09:56 | justin_smith | it also means that if you need to deploy to servers, the tooling for deploying for the jvm is already out there |
| 09:56 | justin_smith | exactly |
| 09:56 | justin_smith | it also means, in terms of optimizing the resulting code, we can just re-use the runtime optimizations of the jvm |
| 09:56 | tdammers | it also means that if you have one team in the organisation doing interesting stuff with clojure, while the rest does boring business CRUD things in Java, you can still interface with each other pretty seamlessly |
| 09:56 | copycat | could you elaborate on - the deployment procedure is pretty much the same - "here's a jar, do your thing" |
| 09:56 | justin_smith | instead of inventing that from scratch |
| 09:57 | justin_smith | copycat: in order to run a clojure uberjar, all you need is java |
| 09:57 | justin_smith | that's literally the only thing that needs to be installed on the server |
| 09:57 | tdammers | and yes, from the language implementation point of view, it means that you only need to invent the "front-end" part |
| 09:57 | tdammers | it was an important factor in getting clojure the traction any new language needs |
| 09:58 | tdammers | I think that if it hadn't been for the jvm, clojure wouldn't have made it |
| 09:58 | copycat | what other things does clojure has going for it? |
| 09:58 | justin_smith | copycat: compare this to ruby or python, where you need to have the right runtime versions installed for your app, and the right libs, and versions of all your libs that play well together, and these are all exclusive global installations |
| 09:58 | tdammers | not because other lisps are necessarily better, but because they would have had a more complete set of libraries available |
| 09:58 | blkcat | ^ strongly agree. jvm was clojure's trojan horse |
| 09:59 | justin_smith | copycat: pervasive immutability without having to deep copy all your data |
| 09:59 | tdammers | justin_smith: that comparison isn't entirely fair though, because clojure is compiled and python isn't |
| 09:59 | justin_smith | tdammers: sure, I am just talking about the relative complexity of setting up a server to host jvm vs. python or ruby apps |
| 09:59 | tdammers | yes |
| 09:59 | tdammers | ofc |
| 09:59 | justin_smith | tdammers: lots of unfair comparisons there :) but we have unfair advantages |
| 10:00 | copycat | being able to plug in clojure code into enterprise software does sound amazing |
| 10:00 | copycat | of course, i have no idea about both |
| 10:00 | tdammers | but if you compare it to, say, C, or Haskell, the only difference I can think of is that your jar will work on any host platform unchanged |
| 10:00 | justin_smith | copycat: yeah, lots of people host clojure on apache tomcat or jboss or wildfly, it just works |
| 10:00 | copycat | but it does that have that "real world use" that would compell me to learn a language |
| 10:00 | tdammers | but if you know the platform, the only thing you need for deploying Haskell code is libc and libgmp |
| 10:01 | justin_smith | tdammers: dependency management to set up a server for c or haskell programs that are not statically compiled can be insane |
| 10:01 | copycat | how does one manage a huge clojrue codebase? |
| 10:01 | justin_smith | tdammers: private scope of installation and automatic version resolution without conflicts are not to be lightly dismissed as advantages |
| 10:01 | tdammers | justin_smith: well, that's why people usually static-link everything except libc and libgmp in haskell ;) |
| 10:01 | justin_smith | tdammers: heh, sure |
| 10:02 | justin_smith | tdammers: but then you still have dependency hell on the dev and build machines |
| 10:02 | justin_smith | tdammers: compare getting someone set up with all the right tool versions to do haskell or c, with getting lein installed |
| 10:02 | tdammers | haskell is pretty straightforward |
| 10:02 | tdammers | C, ugh |
| 10:02 | justin_smith | another way to put it: think of all the vm images and docker containers that clojure doesn't need :) |
| 10:03 | justin_smith | tdammers: even haskell has cabal hell |
| 10:03 | tdammers | it's an unsolvable problem though |
| 10:03 | justin_smith | tdammers: clojure (with the help of maven) solves it pretty nicely |
| 10:03 | tdammers | easiest way out is to use fixed versions for everything |
| 10:03 | justin_smith | I mean there are dep conflicts, but in a project, not an OS level |
| 10:04 | tdammers | oh, but Haskell works just the same, as long as you follow common advice and build in a cabal sandbox |
| 10:04 | justin_smith | tdammers: I can switch versions of deps in a project without hosing my .m2 |
| 10:04 | copycat | is there a C FFI for clojure? |
| 10:04 | justin_smith | tdammers: switching deps inside a cabal sandbox can hose things, bad |
| 10:05 | copycat | i don't see an official link with google search results |
| 10:05 | justin_smith | tdammers: because things are compiled against impl details of the compiled deps |
| 10:05 | tdammers | that's why it's sandboxed :D |
| 10:05 | justin_smith | tdammers: so you throw it all away and rebuild -- rather than just compiling to interfaces |
| 10:05 | justin_smith | there's a difference there, is all I am saying |
| 10:05 | tdammers | oh, sure |
| 10:05 | tdammers | but then, the interfaces tend to be a lot stricter in Haskell |
| 10:06 | tdammers | kind of the point of the whole thin |
| 10:06 | justin_smith | right, but Haskell doesn't compile to interfaces, so that's moot |
| 10:06 | justin_smith | otherwise the previously mentioned problem wouldn't be happening |
| 10:07 | tdammers | but that reduces the problem to "build times are sometimes longer" |
| 10:07 | justin_smith | copycat: there are FFI libs for the jvm that clojure can use (and even some clojure bindings), but that's hairy territory, it leads to platform dependent code and can break in lots of ways |
| 10:08 | copycat | jvm libs, ok |
| 10:08 | copycat | how does one manage a huge clojure codebase? |
| 10:08 | justin_smith | tdammers: sure, but compare OCaml, where things compile to the interface, and build times are orders of magnitude better, with the same type strictness |
| 10:09 | justin_smith | copycat: same as any other language I think, make and use libraries, use git, use unit tests |
| 10:09 | wasamasa | copycat: one simplifies until oblivion |
| 10:09 | tdammers | I'm not extremely familiar with OCaml, but wasn't there something about typeclasses and open universes that makes this a no-go in haskell? |
| 10:09 | justin_smith | copycat: stuartsierra's component lib is good for dep injection style stuff |
| 10:09 | copycat | "dep injection style stuff" |
| 10:09 | copycat | you've lost me :( |
| 10:09 | justin_smith | tdammers: yeah, they have different models (ocaml's is more pragmatic, while still being strict like haskell) |
| 10:10 | copycat | how mature is typed clojure? |
| 10:10 | justin_smith | copycat: "my lib requires a logger, but I'll let the end user decide which logger gets used" |
| 10:10 | tdammers | my impression is that ocaml has less abstractive power |
| 10:10 | tdammers | could be wrong though |
| 10:10 | justin_smith | tdammers: yes, it's simpler and less abstract in the type system |
| 10:11 | tdammers | so in a way, part of haskell's problem is that it allows for more holes to be punched into the type firewall (excuse the metaphor) |
| 10:11 | copycat | mind if i ask what you guys use/do at work and for leisure? |
| 10:12 | copycat | programs and applications |
| 10:12 | justin_smith | tdammers: if OCaml were simply better than haskell more people would be using it - it just makes different (generally more pragmatic) design decisions, while coming from the same language family. But both have strict hindley-milner inferred typing in the generally ml style, and ocaml compiles so much faster its kind of amazing |
| 10:13 | snowell | copycat: Work = Clojure/Clojurescript, Java, Javascript, groovy currently. Leisure = Clojure :) |
| 10:13 | tdammers | justin_smith: well, yeah, ocaml is definitely on my bucket list... I'm thinking it might be a good candidate to fill my needs for a high-level language with slightly more predictable performance characteristics |
| 10:14 | snowell | Almost entirely for web apps, though my company also does some product development |
| 10:14 | digiorgi | When i try to run "lein trampoline cljsbuild repl-rhino" i get Exception in thread "main" java.io.FileNotFoundException: Could not locate cljs/repl__init.class or cljs/repl.clj on classpath: , compiling:(cljsbuild/repl/rhino.clj:1:1) |
| 10:14 | tdammers | copycat: work: clojure, clojurescript, python, JS; projects on the line between gov't and the corporate world. Leisure: go-to languages currently Haskell, C++, C, JS, occasionally Python |
| 10:15 | justin_smith | tdammers: there's a reason the next haskell will be strict http://www.cs.nott.ac.uk/~gmh/appsem-slides/peytonjones.ppt |
| 10:15 | tdammers | oh, I have no doubts about that |
| 10:15 | justin_smith | (that's a presentation by one of the primary authors of haskell, if you don't recognize the name) |
| 10:15 | tdammers | I do |
| 10:16 | tdammers | uncontrolled laziness has always struck me as a blatant oversight in Haskell's design |
| 10:16 | wasamasa | justin_smith: .ppt? |
| 10:17 | wasamasa | justin_smith: seriously? |
| 10:17 | copycat | snowell: would it be possible to do everything in clojure/clojurescript? |
| 10:18 | justin_smith | wasamasa: it's the format peyton-jones chose, there's a reason to refer to him rather than another author (any other really) on this subject |
| 10:18 | wasamasa | damn these ms researchers |
| 10:18 | justin_smith | wasamasa: and damn ms for having the money to buy all the best researches :) |
| 10:18 | snowell | copycat: Possible? Maybe. Allowed by management? No way |
| 10:19 | wasamasa | justin_smith: oh, I'm pretty sure he went there on his own |
| 10:19 | tdammers | pffff, "allowed by management"... |
| 10:19 | wasamasa | justin_smith: I just find it slightly ridiculous how he's using comic sans and powerpoint for his slides |
| 10:19 | justin_smith | wasamasa: agreed |
| 10:19 | snowell | copycat: Lots of this stuff is legacy code/interfaces (gov't work). And the product dev is a giant java codebase :) |
| 10:19 | tdammers | management should allow whatever choices you make, but you should make choices that are good for the business as a whole |
| 10:19 | wasamasa | COMIC SAAAANS |
| 10:19 | tdammers | oh, the comic sans thing |
| 10:19 | tdammers | I think he does that on purpose |
| 10:19 | wasamasa | yes he does |
| 10:20 | wasamasa | something about the font getting too much hate |
| 10:20 | snowell | tdammers: In contracting, the customer may not always be right, but he does have the money |
| 10:20 | tdammers | snowell: yes, and if the customer's business case is "please build something that my in-house people can maintain", then "we'll use this language your people have never heard of" is not the right decision |
| 10:21 | snowell | tdammers: Won't stop me from trying ;) |
| 10:21 | tdammers | still don't see why management needs to be involved |
| 10:21 | tdammers | heh, sure |
| 10:21 | tdammers | best way IMO is to get to the point where you can afford to sell "NO" to the customers who want such a thing |
| 10:21 | tdammers | and take on only those who are open to whatever tech you pick |
| 10:22 | tdammers | and I think that's something you need to earn, in a way |
| 10:22 | copycat | would management know if you ported the java codebase to clojure? |
| 10:22 | snowell | copycat: They'd figure it out once somebody else had to come in to maintain it |
| 10:23 | copycat | i guess the bad thing for them is that java programmers are more plentiful? |
| 10:25 | tdammers | fwiw, as painful as that is, for many of these things, java *is* the right tool, somehow |
| 10:26 | tdammers | as programmers, we sometimes forget that technical superiority is just one of many factors |
| 10:26 | tdammers | my sale manager's daughter being in the same hockey club as your sales manager's daughter is just as important a factor, from a business perspective |
| 10:27 | tdammers | and an expensive IT consulting firm saying "use java, that's what we know" is also a very important factor |
| 10:29 | copycat | could you expand on the last part? |
| 10:29 | copycat | you mean the consulting firm will influence management? |
| 10:32 | mk | copycat: your software needs to be maintainable. If you rely on a consulting firm either a) for present maintenance, or b) as a safety net in case the project goes south, and that firm says "we can't work with that", then you won't want to use that |
| 10:36 | mk | copycat: you need both social and technical infrastructure (or lack thereof) for certain languages to make sense. If the majority of the programmers you hope to recruit use C#, or if your customers are invested in Microsoft products, you'll end up using C# over Java or Clojure |
| 10:38 | wink | I don't think the "developers already know language X" is a valid point really |
| 10:38 | copycat | mk: how do software shops introduce/integrate new languages into their legacy codebase? |
| 10:38 | copycat | not start-ups |
| 10:39 | snowell | band-aids and duct tape :) |
| 10:39 | Frozenlock | tdammers: I don't know if it's really 'forgetting', rather than seeing what should be optimized for one's own benefit. For example, suppose I work in an enterprise where everyone is using Excel as databases. Now, if I do what's currently best for the enterprise, it would be to suck it up and also use Excel. However, the value I can bring to the table is greatly reduced if I constantly bang my head on Excel, which should also be |
| 10:39 | Frozenlock | reflected on my salary. I would expect most people to try to set themselves in an environment where they can maximize their productivity, even if for the enterprise at large it can be a net negative. |
| 10:40 | copycat | i mean the social process of convincing management/colleagues :) |
| 10:42 | tdammers | Frozenlock: maybe... but my strategy for that is to quietly go find a job where I am more useful and more valued |
| 10:42 | Frozenlock | Of course, but before going through all this trouble, you try to optimize locally. |
| 10:42 | tdammers | yes |
| 10:43 | tdammers | but they way to get there is to convince the environment that maximizing your productivity is a net gain |
| 10:43 | Frozenlock | There lies the difficulty :-p |
| 10:44 | mk | copycat: slowly. If you mean socially, you need buy-in from well-established programmers at that company. They'll have a record of making reasonable decisions. So... you could propose something, but it's not up to you, unless you establish yourself as a top programmer |
| 10:47 | copycat | mk: have you worked in a bigco before? |
| 10:52 | noncom | what is the character literal for backslash ? |
| 10:52 | noncom | ,\\ |
| 10:52 | clojurebot | \\ |
| 10:52 | noncom | this? |
| 10:52 | clojurebot | this is an outrage! |
| 10:54 | mk | copycat: like Microsoft or Google? No, but I don't expect the process to be anything but more formal. If you're still curious, you might ask at something like programmers.stackexchange |
| 10:54 | copycat | i prefer interactive chats with irc people :) |
| 10:57 | digiorgi | Hi i cant start any clojurescript repl, lein trampoline cljsbuild repl-rhino |
| 10:57 | digiorgi | or repl-listen, fails |
| 10:58 | digiorgi | with java.io.FileNotFoundException: |
| 11:06 | mk | digiorgi: which file is not found? |
| 11:18 | digiorgi | java.io.FileNotFoundException: Could not locate cljs/repl__init.class or cljs/repl.clj on classpath: , compiling:(cljsbuild/repl/listen.clj:1:1) |
| 11:19 | digiorgi | mk: or java.io.FileNotFoundException: Could not locate cljs/repl__init.class or cljs/repl.clj on classpath: , compiling:(cljsbuild/repl/rhino.clj:1:1) |
| 11:23 | chomwitt | ,(str [\u2620]) |
| 11:23 | clojurebot | "[\\☠]" |
| 11:23 | chomwitt | is that logical? |
| 11:24 | chomwitt | a vector with one character will become string with 3 characters? |
| 11:26 | hyPiRion | ,(map (juxt str pr-str) [[1 2 3] ["1" "2" "3"] [\1 \2 \3]]) |
| 11:26 | clojurebot | (["[1 2 3]" "[1 2 3]"] ["[\"1\" \"2\" \"3\"]" "[\"1\" \"2\" \"3\"]"] ["[\\1 \\2 \\3]" "[\\1 \\2 \\3]"]) |
| 11:27 | chomwitt | didnt get it |
| 11:27 | hyPiRion | ,(println ["foo" "bar"]) |
| 11:27 | clojurebot | [foo bar]\n |
| 11:28 | vas_ | Someone give me a high five I just found this error xD |
| 11:28 | hyPiRion | chomwitt: You'd like to have the property that (= (read-string (pr-str thing)) thing) |
| 11:59 | {blake} | I've been trying to upgrade my lein-ring from 8.13 to 9.6 and I find that when I WAR it up and deploy it (via Wildfly) Wildfly chokes with a Java servlet error. I've had a dependency of [javax.servlet/servlet-api "2.5"] all along so I feel like I need to change that somehow. |
| 12:00 | justin_smith | {blake}: "a java servlet error" isn't very helpful |
| 12:02 | {blake} | Yeah, I know. :-/ It's a pretty expansive error message. I had a wan hope that someone would say "Oh, yeah! I know that 8->9 upgrade problem!" |
| 12:03 | blkcat | pastebin it? :) |
| 12:03 | {blake} | Well, here's what I'm looking at: => Attempting to call unbound fn: #'myapp.servlet/service-method |
| 12:03 | {blake} | I'm thinking that's the problem. |
| 12:04 | jcrossley3 | {blake}: wildfly uses version 3 of the servlet spec. i wouldn't think you'd need to make that dep explicit anyway. |
| 12:06 | {blake} | jcrossley3: I think I tried taking out that servlet dependency, but let me verify. |
| 12:07 | {blake} | And I think one doesn't need the ring-jetty-adapter any more, either? |
| 12:08 | jcrossley3 | {blake}: uh, not if you're running on wildfly, no :) |
| 12:10 | {blake} | jcrossley3: Yeah, but we don't even need it for running locally, I think... (lein ring server) |
| 12:11 | jcrossley3 | {blake}: i think that's the only time you *do* need it, but ring should pull that in for you without declaring the dep |
| 12:12 | {blake} | jcrossley3: Oh, yeah, okay. =) |
| 12:16 | gfredericks | what is the goodest reload-my-code-when-files-change thing, where I really mean "when files change" and not "when an http server gets a request and files have changed" |
| 12:17 | gfredericks | I'm a fan of the tools.namespace refresh function, but I'd also probably need to restart my component system, and tie it to the filesystem watcher somehow |
| 12:20 | Pupeno | Does anybody know how to find input[name=blah] with enlive? I know (attr= :name “blah”) can filter by the attribute name, but not how to compose it with filtering only inputs. |
| 12:50 | csd_ | i have a static anonymous class Foo$Bar where Bar extends Foo. is it possible for me to access a field on Foo through Bar? I'm not seeing it being available as an inherited property, even though its constructor calls super() |
| 12:51 | gfredericks | csd_: how are you creating the class? |
| 12:51 | gfredericks | is this java code? |
| 12:51 | csd_ | yeah java interop |
| 12:51 | gfredericks | but Bar is defined in java? |
| 12:51 | csd_ | yes |
| 12:51 | gfredericks | and you want to write (.fooThing my-bar)? |
| 12:52 | csd_ | yes |
| 12:52 | gfredericks | and you get an error about fooThing not existing? |
| 12:52 | csd_ | yeah, because its a static anonymous class |
| 12:52 | gfredericks | the error message says that? |
| 12:52 | csd_ | no i mean, Bar is a static class defined in Foo.class |
| 12:53 | gfredericks | and we're talking about instance variable, not a static variable? |
| 12:53 | csd_ | instance variable on Foo |
| 12:54 | gfredericks | sounds like it should work |
| 12:54 | csd_ | idk i'm using timmc's handy `show` function and none of the parent fields are available |
| 13:01 | Bronsa | csd_: can you show an example of the java code? |
| 13:02 | Bronsa | csd_: not sure if this is the case but javac compiles some code using internal field to get around mismatches between jvm's access policies and java ones |
| 13:04 | TimMc | csd_: Pass {:inherit true} as a second arg. |
| 13:05 | TimMc | oslt |
| 13:15 | justmytwospence | silly question here: is clojure's substitution model such that parallelization is or could be automatic? It seems like the syntax tree is so explicit in clojure that this should be possible. |
| 13:16 | justmytwospence | hm perhaps this is a question for #clojure-beginners? |
| 13:17 | chouser | justmytwospence: clojure currently promises to evaluate fn parameters in order, so making it automatically parallel would be a breaking change in the semantics of the language. |
| 13:17 | chouser | ...I don't know if that answers your question or not. |
| 13:21 | TimMc | I have relied on eval order. |
| 13:21 | justmytwospence | i see |
| 13:22 | justmytwospence | is anyone aware of a particular language that do behave that way? |
| 13:23 | TimMc | I know some Schemes do specifically say "no guarantees", one even going so far as to use a very strange eval order (evens first, then odds in reverse order?) but I don't know if any take advantage of that opportunity. |
| 13:23 | chouser | the "lazy evaluation" languages do not promise particular evaluation order, so auto-parallelization should be possible. Haskell is one of these. |
| 13:24 | hiredman | https://en.wikipedia.org/wiki/Automatic_parallelization may be a good place to start |
| 13:25 | hiredman | (I would start at https://en.wikipedia.org/wiki/Automatic_parallelization#Difficulties, but that ruins the surprise) |
| 13:26 | Thomas` | Is nginx the only way to handle a compojure app that is accessed via subdomain? e.g., "sd.example.com". |
| 13:28 | TimMc | Thomas`: No, you could have the subdomain's A record point to your host and compojure listens on port 80... but I have a feeling that's not exactly what you're asking about. |
| 13:29 | wasamasa | Thomas`: should be able to do with some ring hackery |
| 13:29 | TimMc | Do you mean vhost stuff? |
| 13:31 | Thomas` | Last time (months ago) it didn't work. I'll try again and see what happens. |
| 13:32 | hiredman | https://github.com/weavejester/clout |
| 13:32 | hiredman | ^- |
| 13:32 | hiredman | (read the docs, that is the library compojure uses for routes) |
| 13:32 | tmtwd | I put (run-jetty handler {:port 3000}) in the repl, how do start a new cider repl to interact and/or how do I break out of this process? |
| 13:37 | justmytwospence | thanks chouser TimMc hiredman |
| 13:38 | justmytwospence | I was using process substitution at the command line the other day and was just curious why I've never heard of a language operating the way it does |
| 13:39 | justin_smith | tmtwd: I I think there is a way to tell jetty to run in a new thread, otherwise you can just do (future (run-jetty ...)) instead |
| 13:39 | justin_smith | tmtwd: also, you can use M-x cider to connect to the same open port |
| 13:39 | justin_smith | (whichever port the existing cider repl was using) |
| 14:12 | bitts | r/fold works great for processing large collections in parallel. Now I have a small collection (2-10) of somewhat longer running tasks (1-2 seconds) that r/fold decides to execute on a single thread. |
| 14:12 | bitts | Is there anyway to force it to use N cores, Or is there something totally different, like an explicit thread pool? |
| 14:13 | Bronsa | bitts: IIRC you can supply an `n` parameter to r/fold to tell it into how many groups to partition your coll |
| 14:14 | Bronsa | I just looked it up actually. you probably want the [n combinef reducef coll] arity |
| 14:16 | hiredman | bitts: you aren't doing io using fold are you? |
| 14:17 | bitts | Bronsa: thanks. Right I remember now 512 is the default. |
| 14:19 | bitts | hiredman: doing some CPU only and I'm inserting 1.5M rows into the DB using fold. I tried with and without fold. With it uses all 8 cores with the default size of 512. Much faster with 8 cores inserting. |
| 14:19 | hiredman | uggh |
| 14:19 | hiredman | don't do that |
| 14:19 | hiredman | http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html |
| 14:20 | hiredman | http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html |
| 14:20 | hiredman | etc |
| 14:22 | bitts | hiredman: I saw that too. "Work to be performed is computation (not I/O or blocking)" at the bottom http://clojure.org/reducers |
| 14:22 | hiredman | fold uses a forkjoin threadpool, those are designed for compute bound tasks |
| 14:22 | bitts | hiredman: why? |
| 14:22 | hiredman | why what? |
| 14:23 | bitts | hiredman: Why not use fold for i/o. The docs simply say don't and you're daying don |
| 14:23 | bitts | dont'. but why what's the issue. |
| 14:25 | hiredman | because there are different trades offs for blocking tasks and compute heavy tasks for scheduling work on a threadpool and forkjoin is designed for compute heavy tasks and fold is built on forkjoin |
| 14:26 | hiredman | forkjoin has some facilities for telling the pool will block, but the simplified model presented by fold doesn't expose that, and I am not sure how well it works in any case |
| 14:27 | hiredman | you certainly want an Executor in any case, because you want to specify exactly how many threads should be working on whatever, where as you don't have control over that with fold (as you have seen) |
| 14:31 | mgaare | any hints for debugging log4j/slf4j issues? I'm getting an infinite loop somewhere causing a stack overflow on starting repl: http://pastebin.com/h0urpgQT |
| 14:33 | justin_smith | mgaare: I assume this is with lein repl auto-loading your main namespace? |
| 14:33 | justin_smith | mgaare: or does this happen even when starting a normal clojure.core repl in hte user ns? |
| 14:33 | mgaare | justin_smith: I have a file that defines a user ns |
| 14:35 | mgaare | doesn't happen when I remove that file |
| 14:38 | mgaare | probably due to this, I think: http://www.slf4j.org/codes.html#log4jDelegationLoop |
| 14:40 | mgaare | not that exactly, but something like it |
| 14:49 | mgaare | ok, solved it. did lein deps -tree and found both org.slf4j/log4j-over-slf4j and org.slf4j/slf4j-log4j12 being brought in |
| 14:49 | mgaare | er :tree |
| 14:54 | lodin__ | Other than not being able to do a :refer :all (without :exclude or :rename), is there any downside with doing (ns-unmap *ns* 'System) (defprotocol System ...)? |
| 14:56 | lodin__ | Could e.g. the ns-unmap call mess with AOT compilation, or what-not? |
| 15:22 | justin_smith | gfredericks: it's awesome following that cheshire issue right now |
| 15:22 | justin_smith | gfredericks: really glad you are doing this (sorry I didn't do it sooner) |
| 15:28 | gfredericks | one failing test left |
| 15:28 | gfredericks | justin_smith: want to debug it for me? :D |
| 15:29 | justin_smith | gfredericks: haha, maybe I can later, leaving for lunch soon, but sure! |
| 15:37 | gfredericks | justin_smith: branch linked on the issue |
| 15:37 | justin_smith | cool, I'll check it out later, thanks |
| 15:43 | weskinner_work | Does anyone know how to do password confirmation validation with bouncer? |
| 15:46 | scriptor | I'm using evil mode, problem is that means I can't seem to get Cider's M-. binding to work |
| 15:46 | scriptor | anyone know how to work around that? |
| 15:47 | scriptor | it's probably because . is vim's repeat command key, but if I'm doing M- first it shouldn't use that |
| 15:49 | wasamasa | unbind M-. |
| 15:50 | wasamasa | as M-. is bound to another command in evil's normal state map |
| 15:51 | wasamasa | you should really be asking this in #emacs :P |
| 15:51 | scriptor | yeah, doing so now |
| 16:27 | rasmusto_ | scriptor: also, see spacemacs :) |
| 16:32 | hellofunk | rasmusto_: spacemacs looks interesting, thanks |
| 16:38 | tmtwd | how do I open a lein repl directly through emacs (rather than cider-jack-in)? |
| 16:40 | Reefersleep_ | hello |
| 16:41 | Reefersleep_ | I have a reagent\figwheel application which I’m hosting on github pages |
| 16:41 | Reefersleep_ | but it’s like the css isn’t loading |
| 16:42 | Reefersleep_ | (when I access my index.html, I mean |
| 16:42 | rasmusto_ | hellofunk: just turn on the paredit, autocomplete, and clojure configuration layers and you have a working emacs/vim hybrid setup |
| 16:42 | arrdem | tmtwd: cider-jack-in does create a bare (headless) lein repl and then connects to it over nREPL. What are you trying to do? |
| 16:42 | tmtwd | arrdem, okay thanks |
| 16:42 | tmtwd | I think that's what I wanted |
| 16:43 | arrdem | ok |
| 16:43 | arrdem | yeah you probably don't need anything else. |
| 16:43 | Reefersleep_ | when I go to the index.html in the folder on my computer and load it into the browser, everything is fine |
| 16:43 | Reefersleep_ | anyone have a clue what I’m doing wrong? |
| 16:44 | Reefersleep_ | This is my github page |
| 16:44 | hellofunk | rasmusto_: i think i'll give it a try. emacs key chords are starting to drag down my worldview |
| 16:45 | Reefersleep_ | this is my github repo: https://github.com/Reefersleep/derpanet |
| 16:45 | oddcully | Reefersleep_: just to have it mentioned: there is also #clojurescript |
| 16:45 | Reefersleep_ | cheers oddcully :) |
| 16:46 | oddcully | Reefersleep_: have you looked in the net-tab of your devtools, if the files just gets a 404 or something alike? |
| 16:47 | Reefersleep_ | why didn’t I do that |
| 16:47 | Reefersleep_ | yes, my .js is getting a 404 |
| 16:48 | Reefersleep_ | don’t see why, though |
| 16:49 | oddcully | Reefersleep_: the file is on that server? the paths are right? can you copy the url there and test for yourself? is the request cross-http/https and is your browser blocking it? |
| 16:51 | Reefersleep_ | the path matches the one I see in my local folder |
| 16:52 | Reefersleep_ | I *just* pushed it to the github page |
| 16:52 | Reefersleep_ | it shouldn’t be cross-http, it’s the very same site |
| 16:52 | Reefersleep_ | it’s just /js/compiled/file.js |
| 16:53 | oddcully | the leading / means an absolute path for that domain. is this the case? |
| 16:53 | Reefersleep_ | the URL is http://reefersleep.github.io/resources/public/js/compiled/derpanet.js - I get a 404 on going there |
| 16:53 | Reefersleep_ | well… I don’t know. |
| 16:54 | Reefersleep_ | The index.html file, which I’m viewing, is in the same folder as the js folder |
| 16:56 | oddcully | well the css is there. never used githup.io myself, so is there some way to look, whats actually there? |
| 16:57 | Reefersleep_ | I don’t know, I’m completely green :) |
| 16:58 | Reefersleep_ | with github.io, that is |
| 16:59 | amalloy | so, Reefersleep_, the thing is, i don't see any evidence your .js file exists |
| 16:59 | amalloy | like, github.io is just serving files directly out of https://github.com/Reefersleep/Reefersleep.github.io as far as i know |
| 17:00 | amalloy | and there is no .js file to be seen |
| 17:00 | amalloy | it doesn't invoke lein cljsbuild for you or whatever other thing |
| 17:00 | Reefersleep_ | uhm |
| 17:00 | Reefersleep_ | you’re right |
| 17:00 | Reefersleep_ | wtf happened |
| 17:01 | Reefersleep_ | the .js is in my local folder |
| 17:01 | Reefersleep_ | which I just pushed |
| 17:01 | amalloy | well, check your gitignore, and whether you've added/committed before pushing |
| 17:03 | Reefersleep_ | amalloy |
| 17:03 | Reefersleep_ | the folder is in gitignore |
| 17:03 | Reefersleep_ | I think you saved me :) |
| 17:03 | Reefersleep_ | no idea why it’s there, though |
| 17:04 | amalloy | because you would ordinarily not want to commit compiled files to your github repo |
| 17:04 | oddcully | the figwheel template has it |
| 17:04 | oddcully | it's autogenerated stuff there |
| 17:04 | oddcully | so it's usually sane to ignore it |
| 17:04 | amalloy | only in the special case where someone is serving directly from your git repo, rather than building and then serving, would you want to check that in |
| 17:05 | oddcully | true, but maybe only with a min-build |
| 17:06 | Reefersleep_ | thanks a lot, both of you |
| 17:06 | Reefersleep_ | I’m going to try and work this out |
| 17:07 | Reefersleep_ | I get why it’s ignored to begin with |
| 17:07 | Reefersleep_ | I didn’t expect the lein figwheel template to have anything specified in the .gitignore file |
| 17:07 | amalloy | Reefersleep_: pretty much every lein template has stuff in gitignore |
| 17:08 | amalloy | you can just git add -f js/compiled/whatever.js |
| 17:08 | Reefersleep_ | I’m pushing to both the pages repo and to my github repo from the same local file |
| 17:08 | Reefersleep_ | so actually it’s fine that it’s normally ignored |
| 17:08 | oddcully | but be aware, that the file will change extremly how it gets built |
| 17:08 | oddcully | if you build with min then there is one huge mess of js |
| 17:08 | Reefersleep_ | amalloy are you saying that I can one-off push that file to a particular repo? |
| 17:08 | amalloy | no |
| 17:08 | Reefersleep_ | oddcully what do you mean, min? |
| 17:09 | oddcully | if you have the dev build there is the file and the out/ dir |
| 17:09 | Reefersleep_ | I build with figwheel, I guess? And whatever plugin takes care of autobuilding |
| 17:09 | oddcully | if you run figwheel it uses the dev config to build the js files |
| 17:09 | Reefersleep_ | yeah I use the dev config |
| 17:10 | oddcully | but for release you want to do a build with the min setting (e.g. lein clean && lein cljsbuild once min) |
| 17:10 | oddcully | see the project.clj for the config of both |
| 17:10 | Reefersleep_ | aha |
| 17:11 | Reefersleep_ | oddcully: Do you have a tip on how to push something to one repo, and not the other? |
| 17:11 | Reefersleep_ | I’m (also) a github newb :l |
| 17:11 | Reefersleep_ | *git |
| 17:12 | Reefersleep_ | guess I could do a commit, push it to one repo, then just undo the commit locally? |
| 17:13 | oddcully | im a github.io noob ;) |
| 17:13 | oddcully | my approach would be to separate this in two repos maybe |
| 17:14 | Reefersleep_ | rasmusto_: I’ve been thinking about getting into emacs. Could you repeat what you told hellofunk earlier? I dig vim bindings ;) |
| 17:14 | oddcully | then let your build build that stuff into the other and push that |
| 17:14 | arrdem | is there a good Make channel? |
| 17:14 | Reefersleep_ | oddcully that makes sense, maybe |
| 17:14 | Reefersleep_ | no idea how to set that up - the build process, I mean |
| 17:14 | oddcully | first of all, i'd check, how others do |
| 17:14 | oddcully | there are lots of nikola/octopress/younameit pages on github.io |
| 17:15 | oddcully | unless github builds stuff for them, they have the same problem |
| 17:16 | hellofunk | Reefersleep_: he was basically saying to check out spacemacs |
| 17:17 | oddcully | hellofunk: me? never! i'd go with arrdem's make |
| 17:17 | amalloy | arrdem: i don't think so; i'd just try the C channel |
| 17:20 | Reefersleep_ | hellofunk: really? or are you saying that it would be equivalent to what he’s saying? :) |
| 17:20 | Reefersleep_ | oddcully: good suggestion |
| 17:35 | Seylerius | Is there a simple way to pass several keys of a map as args to a function? |
| 17:35 | amalloy | (apply f (map m [a b c d])) |
| 17:40 | hellofunk | Reefersleep_: he said to check out spacemacs |
| 17:40 | hellofunk | oddcully: ?? |
| 17:40 | lazybot | hellofunk: Definitely not. |
| 17:40 | Seylerius | amalloy: Thanks |
| 17:40 | Seylerius | (inc amalloy) |
| 17:40 | lazybot | ⇒ 285 |
| 17:40 | randomcharhere | Whats the syntax in clojure for ((x < 10)&&(y < 10) ) |
| 17:40 | Reefersleep_ | hellofunk: cheers :) |
| 17:41 | Reefersleep_ | (and (< x 10) (< y 10)) ? |
| 17:41 | hyPiRion | (and (< x 10) (< y 10)) |
| 17:41 | Reefersleep_ | maybe |
| 17:41 | randomcharhere | doh thanks :) |
| 17:42 | randomcharhere | trying to piece together a clojure education from disparate web site and books couldnt find something so simple anywhere |
| 17:43 | amalloy | also, (every? #(< % 10) [x y]) |
| 17:43 | amalloy | there are lots of ways to write stuff |
| 17:43 | randomcharhere | cool |
| 17:43 | Seylerius | ,(doc filter) |
| 17:43 | clojurebot | "([pred] [pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects. Returns a transducer when no collection is provided." |
| 17:43 | zimablue | I was waiting for someone to shorten it, sitting here thinking how |
| 17:44 | Reefersleep_ | hehehe |
| 17:44 | zimablue | is partial idiomatic in clojure? it constrains you to only binding the first variables right? as in you can't bind 2 and leave 1 open if that makes sense |
| 17:45 | zimablue | because I was thinking you'd have to do something like (partial ( > 10)) whatever the syntax is |
| 17:45 | hellofunk | zimablue: partial is definitely idiomatic. but there are other ways to do things too, like pass a literal if your args aren't in order |
| 17:45 | zimablue | pass a literal? |
| 17:45 | arrdem | ( ... #(foo % 3) ...) |
| 17:45 | hyPiRion | zimablue: You can do (partial > 10), but in this case you know that you will take exactly one argument. |
| 17:45 | hellofunk | #(> % 10) |
| 17:46 | lodin__ | zimablue: Beware that (partial f (g x)) and #(f (g x) %) are not equivalent though w.r.t. the time of evaluation of (g x). |
| 17:46 | hyPiRion | And #(< % 10) is going to be faster to run than (partial > 10) unless that has changed recently |
| 17:46 | amalloy | hyPiRion: most applications of partial you know exactly how many args you will have, so i don't really get the "but" there |
| 17:47 | amalloy | like i don't use partial a lot either, but i don't consider whether i know how many args are left when deciding whether to use partial |
| 17:47 | zimablue | the last thing I read was haskell so I always feel like lambdas are naughty but I guess they're idiomatic/unavoidable. lodin__ I should know but I'm guessing partial is the one evaluating up front? |
| 17:48 | hyPiRion | amalloy: Eh, maybe not. I don't use partial if I can use function literals or (fn [...] ...) |
| 17:48 | arrdem | if only we had currying... /me ducks |
| 17:48 | amalloy | hyPiRion: well uh...you can always use those. so you are saying you never use partial |
| 17:49 | hyPiRion | amalloy: But it's shorter to write (partial + 1) than (fn [& v] (reduce + 1 v)) |
| 17:49 | lodin__ | zimablue: Yeah, partial is just a function, so the arguments are evaluated before it is passed. Something this is what you want, particularly if the function is going to be called several times, and g is costly. |
| 17:49 | hyPiRion | oh, I see that I didn't include that. Well. I use the thing most readable. |
| 17:50 | zimablue | thanks, that's a really interesting point |
| 17:50 | amalloy | we can all get behind that, hyPiRion |
| 17:50 | Seylerius | ,(doc ->) |
| 17:50 | clojurebot | "([x & forms]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc." |
| 17:50 | amalloy | also, (partial + 1) is a fun example, because you can write it without partial or lambdas: (comp inc +) |
| 17:51 | Reefersleep_ | amalloy / oddcully : Just for kicks, I decided to try to remove the line from my .gitignore, git add my js folder, commit and push to my github page repo |
| 17:52 | Reefersleep_ | so now the app works :D and I just have to undo what I did and make a new commit in order to push normally to my dev repo |
| 17:52 | hyPiRion | amalloy: ahh, you and your tricks. (partial + 10) then, unless you prefer (comp inc inc inc inc inc inc inc inc inc inc +) |
| 17:53 | amalloy | hyPiRion: (comp inc inc octoinc +) |
| 17:53 | Reefersleep_ | amalloy / oddcully: you can view the site here if you feel like it: http://reefersleep.github.io/resources/public/index.html |
| 17:53 | zimablue | (iterate 10 inc) > |
| 17:53 | lodin__ | zimablue: Why did reading Haskell make you feel like lambdas are naughty? |
| 17:53 | rasmusto_ | Reefersleep_: spacemacs |
| 17:54 | Reefersleep_ | rasmusto_: cheers. Dansker? |
| 17:54 | amalloy | you don't need lambdas nearly as much in haskell because of currying, and when you do need them you can often shove them into a where clause. so if you see a lot of lambdas in a haskell function it is "usually" not that well written |
| 17:55 | oddcully | Reefersleep_: cool |
| 17:56 | Reefersleep_ | it’s unfinished of course :) |
| 17:57 | hellofunk | (inc amalloy) |
| 17:57 | lazybot | ⇒ 286 |
| 17:58 | Reefersleep_ | (inc hellofunk) |
| 17:58 | lazybot | ⇒ 3 |
| 17:58 | oddcully | Reefersleep_: you have upped the :dev build now - since it's not your upstream there, you might consider the time users have to wait. if you build the :min one, there will only be one .js file to download |
| 17:59 | Reefersleep_ | ah ok, so just do those two commands you mentioned and then commit that instead of what I’ve got now? |
| 18:00 | oddcully | yes, but you will see a _huge_ diff with this |
| 18:00 | oddcully | so for now while dev'ing things, you might stick with :dev |
| 18:00 | oddcully | i just wanted to mention this |
| 18:01 | oddcully | the :min build will turn all your out/**/*.js files into one blob of optimized js |
| 18:01 | Reefersleep_ | ah alrigh |
| 18:01 | Reefersleep_ | t |
| 18:01 | Reefersleep_ | this stuff is tricky. I need an automated release build process, really |
| 18:01 | Reefersleep_ | Like you suggested. |
| 18:04 | Reefersleep_ | But for now, I’m just happy that it’s up, really! :D |
| 18:12 | zimablue | lodin__I didn't write lots of it I mostly just wanted to understand it but I think I remember reading that they prefer to write it in that headless way where you don't have an explicit variable on both sides of an arrow, if that makes sense. |
| 18:13 | csd_`` | I've got functions A and B. A takes a channel and returns nothing. B is not asynchronous and returns a hashmap. A needs to be called before B. The problem is, A and B are wrapped in the let that defines the channel passed to A, and B is going to have its own result that will need to be bound. Meanwhile A returns nothing. So it seems like I'm left with the option of either having A inside the let but binding _, or having a nested l |
| 18:13 | csd_`` | B. Or i could use an atom or something i guess. I don't love any of the options. Can anyone suggest what might be best? |
| 18:13 | zimablue | pointfree that's it |
| 18:21 | lodin__ | zimablue: Like double = (*) 2 instead of double x = (*) 2 x, you mean. |
| 18:21 | justin_smith | csd_``: first part of your question is cut off, but one option for sync (if one thing that is async has to get to a specific point in its computation before something else should run) is to have the async thing deliver a promise, and have the sync thing explicitly deref the promise before doing its thing |
| 18:22 | Seylerius | If I've got a series of strings that go "Bla blah blah. Blah Blah. High foo. Blah Blah Blah.", what's the easiest way to filter that into everything before the word "High"? |
| 18:22 | csd_`` | justin_smith: i'm more concerned with style than the syncronicity |
| 18:23 | zimablue | there's a thread here where they argue both sides of it a bit: http://www.reddit.com/r/haskell/comments/2fbe4t/compose_to_avoid_lambdas/ is there an argument to be made in clojure that lambdas would be somehow harder to integrate with macros? |
| 18:23 | Seylerius | ,(doc map) |
| 18:23 | clojurebot | "([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments. Returns a transducer when no coll... |
| 18:23 | lodin__ | Seylerius: If it's a string then a regexp would be good, I figure. |
| 18:24 | justin_smith | csd_``: OK, the part of your question that had your actual question in it was cut off then |
| 18:24 | Seylerius | Off I go to a clojure regexp guide, then. |
| 18:24 | Seylerius | Thanks, lodin__ |
| 18:24 | Seylerius | (inc lodin__) |
| 18:24 | lazybot | ⇒ 1 |
| 18:24 | justin_smith | Seylerius: they are just java regex |
| 18:24 | Seylerius | justin_smith: Great, thanks. |
| 18:24 | justin_smith | or js regex, for cljs |
| 18:24 | csd_`` | justin_smith: basically i'm trying to simplify this (let [c (chan)] (init-async-thingie c) (let [foos (mk-foos)] (use-the-foos c))) |
| 18:24 | csd_`` | if that makes sense |
| 18:25 | Seylerius | (And yes, I pass points around like candy. I like my gratitude to count) |
| 18:25 | justin_smith | yeah, I would move (mk-foos) into the first let binding |
| 18:25 | Seylerius | (inc justin_smith) |
| 18:25 | lazybot | ⇒ 273 |
| 18:25 | csd_`` | justin_smith: and bind the init-async to _ ? |
| 18:25 | csd_`` | it has to occur first |
| 18:25 | justin_smith | yeah |
| 18:25 | csd_`` | ok |
| 18:26 | lodin__ | Seylerius: Clojure has syntax support for regexps via #"regexp-goes-here". |
| 18:26 | csd_`` | i'm generally unclear on whether using side effecting actions in let bindings like that is ok |
| 18:26 | justin_smith | csd_``: that's why we have that _ idiom |
| 18:27 | csd_`` | got it, thanks |
| 18:34 | randomcharhere | How do I add more data to an array pf vectors? |
| 18:35 | justin_smith | what is a pf? |
| 18:35 | randomcharhere | sorry typo of |
| 18:36 | justin_smith | randomcharhere: conj for the vectors, for the array you are out of luck, maybe you can use a vector instead, or make a new array |
| 18:36 | randomcharhere | I use def to define one but cant seem to add more data to it |
| 18:36 | justin_smith | randomcharhere: vectors are immutable |
| 18:36 | justin_smith | you need to use def again, or use the return value of conj directly. The original will not change. |
| 18:36 | randomcharhere | not looking to change the data just keep adding to it |
| 18:36 | justin_smith | ,(def a []) |
| 18:36 | clojurebot | #'sandbox/a |
| 18:36 | justin_smith | randomcharhere: adding is a change |
| 18:37 | justin_smith | ,(def b (conj a 1)) |
| 18:37 | clojurebot | #'sandbox/b |
| 18:37 | justin_smith | ,b |
| 18:37 | clojurebot | [1] |
| 18:37 | justin_smith | ,a |
| 18:37 | clojurebot | [] |
| 18:37 | justin_smith | a did not change |
| 18:37 | justin_smith | you cannot add anything to a (but you could use def again and replace a) |
| 18:40 | randomcharhere | so how do you keep track of a large array without having to copy the thing over just to add some more data? |
| 18:41 | justin_smith | randomcharhere: by not using defs for things that should change |
| 18:41 | justin_smith | randomcharhere: typically we'd have something like reduce or loop where each iteration sees a new vector with the new data added |
| 18:41 | justin_smith | but there is no single vector mutating - it's a new argument coming in each time |
| 18:43 | amalloy | randomcharhere: remember that getting a changed copy of a vector (or map or whatever) isn't "copying" |
| 18:43 | lodin_ | randomcharhere: The way vectors are implemented you don't need to copy the whole vector when you add to it. |
| 18:43 | amalloy | it behaves the same as copying, but is implemented more efficiently |
| 18:44 | justin_smith | yeah, good point, the original does not change, but the whole thing isn't usually copied (only a small part) |
| 18:45 | randomcharhere | hmmmm ;/ |
| 18:46 | justin_smith | randomcharhere: because the vector is guaranteed immutable, we can share the same data in two vectors |
| 18:46 | justin_smith | randomcharhere: which means we don't need to do much copying |
| 18:46 | lodin_ | randomcharhere: Do you know how a linked list works? (Vectors are not linked list, btw.) |
| 18:47 | justin_smith | lodin_: oh, yeah, that's a good example, two linked lists can differ only by the head |
| 18:47 | randomcharhere | understood but how do I create a vector/array whatever so I can add more data to it? |
| 18:48 | justin_smith | randomcharhere: with [] |
| 18:48 | randomcharhere | started with (def a [ (vec (for [x (range 3) y (range 2) ] [x y 0]))]) |
| 18:48 | randomcharhere | just an example |
| 18:49 | justin_smith | randomcharhere: here's an example ##(loop [acc [] new (rand)] (if (> (count acc) 3) acc (recur (conj acc new))) |
| 18:49 | justin_smith | ,(loop [acc [] new (rand)] (if (> (count acc) 3) acc (recur (conj acc new))) |
| 18:49 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 18:49 | justin_smith | err |
| 18:49 | amalloy | justin_smith: just one more ) at the end |
| 18:50 | randomcharhere | :P |
| 18:50 | justin_smith | ,(loop [acc [] new (rand)] (if (> (count acc) 3) acc (recur (conj acc new) (rand)))) |
| 18:50 | clojurebot | [0.7726313852857776 0.4344170843561387 0.11577137255160963 0.1291733565449812] |
| 18:51 | justin_smith | that's a silly loop, but at least it shows the principle - each new vector is the arg of the next loop iteration |
| 18:51 | justin_smith | randomcharhere: we don't use def for things that are meant to be updated (unless it's a container for mutation, like an atom) |
| 18:52 | randomcharhere | I feel like still missing something |
| 18:52 | justin_smith | randomcharhere: we have constructs that are meant to use a new set of args on each iteration |
| 18:52 | justin_smith | they don't need to mutate anything to accumulate data |
| 18:52 | lodin_ | ,(let [a [1 2] a (concat a a)] a) |
| 18:52 | clojurebot | (1 2 1 2) |
| 18:53 | justin_smith | lodin_: that's misleading because it's shadowing |
| 18:53 | lodin_ | But I think that is what randomcharhere wants. |
| 18:53 | justin_smith | sure, but that's just one a hiding the other, but it might look like a wes changing |
| 18:54 | justin_smith | ,(let [a 0 b (fn [] (println a)) a 1] (b)) |
| 18:54 | clojurebot | 0\n |
| 18:54 | lodin_ | justin_smith: And the next step would be fore randomcharhere to realize that. :-) |
| 18:54 | lodin_ | s/fore/for/ |
| 18:55 | randomcharhere | Just so use to coming from c c++ python ... ti assining a variable and being able to mangle/spindle what not that variable |
| 18:55 | justin_smith | randomcharhere: right, we don't really do that much |
| 18:57 | lodin_ | randomcharhere: Right, so instead of a = stuff(...); a.sort(); you do (let [a (stuff ...) a (sort a)] ...). In real code that would probably be written differently, but you get the idea. |
| 19:03 | randomcharhere | hmm guess'll go bang my head againt the wall some more :p |
| 19:05 | justin_smith | randomcharhere: it requires a different style of programming. If you haven't done functional programming with immutable data before, I'd recommend finding a good book. |
| 19:06 | justin_smith | clojure programming if you're experienced with other languages, clojure from the ground up or clojure for the brave and true if you are less experienced |
| 19:08 | phren0logy | I got the early-access of Clojure for the Brave and True and found it to be harder to follow than Living Clojure. |
| 19:08 | randomcharhere | Ironically most books I've found will "list" all the commands and desribe them |
| 19:11 | amalloy | randomcharhere: it may help to think about recursion: because there's no way for clojure programmers to modify a value, we need some other place to store a new "version" of that value. the stack is a convenient place to do that, and that's what recursive functions do: produce new stack frames to hold values in |
| 19:12 | amalloy | eg if clojure is new to you, and you're having trouble getting the immutability and the new syntax at the same time, try writing a function in python that does something without any mutation. for example, implementing multiplication in terms of addition is a fairly simple one |
| 19:12 | amalloy | (and yet often still hard if you aren't used to thinking that way) |
| 19:12 | lodin_ | randomcharhere: Maybe a fun (?) exercise would be to try to write Python but all lines that don't have a return value are banned, except def, if, and return. You are allowed to have a module called "functions" in which you break these rules and can do whatever you want, so e.g. sorted would be in functions and be "def sorted(xs): ys = list(xs); ys.sort(); return ys;" if it wasn't in Python already. |
| 19:13 | lodin_ | Then, when you have gotten going, also add the requirement that the function are not allowed to modify their arguments. But that can wait. |
| 19:14 | lodin_ | s/function/functions/ |
| 19:16 | lodin_ | Assignment is also allowed, but x[k] = v is not, because that's sugar for some method call. |
| 20:30 | Seylerius | If I need to grab and process multiple things from an API, and need to wait 6 seconds between API calls, what's the most efficient way to ensure this happens? |
| 20:44 | ToBeReplaced | Seylerius: I'd use a ScheduledThreadPoolExecutor to make calls and put results on a channel |
| 20:54 | bucketh3ad | Hey. I'm wondering if anyone has any experience with sparkling, the clojure library for apache spark. I'm going through the tf-idf tutorial right now and I've run into an error I can't figure out. |
| 21:03 | Seylerius | Does anyone have a guide on how to use ScheduledThreadPoolExecutor in Clojure? |
| 21:34 | ToBeReplaced | Seylerius: you should learn java interop and then reference the javadoc https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html |
| 21:36 | ToBeReplaced | i've done the exact thing you're trying to do with an external service that i had to play nice with, but the code is closed so i can't offer an example |
| 23:36 | Seylerius | How do I spin off a thread and have two-way communication with it? Basically, I want to spin off a thread that waits for something sent into its channel, marks the time, does shit with sent thing, and then sends it back, then waits until it's at least 6 seconds after the marked time, then repeats. |
| 23:37 | Seylerius | And I want the original thread to then be able to stick shit into the channel, wait for a return, and then continue processing. |
| 23:38 | justin_smith | Seylerius: sounds like core.async |
| 23:39 | Seylerius | justin_smith: Would I make two channels, and then define the thread to read one and write the other, and at the same time have the originating thread write the first and read the second? |
| 23:48 | justin_smith | Seylerius: sounds about right, a common practice in core.async is to send a channel along with your request, and have the other end send the result back to the channel you sent in |
| 23:49 | justin_smith | kind of like a callback on an ajax call, but with threads, and with channels |