#clojure log - Jul 09 2015

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:17 shiranaihito: elvis4526: there are only stupid answers :)

0:19 currentoor: Has anyone built a datomic backed application and deployed to heroku?

0:26 I was wondering what's the right way to deploy a datomic backed app for a beginner?

0:31 namra: hm there's something i don't understand with atoms: http://pastebin.com/iGYyF7M9

0:31 it'll throw a nullpointer exception at the places (not (nil? kh @heartbeat-counter)) and (< (kh @heartbeat-counter))

0:31 and i don't understand why

0:32 someone an idea?

1:29 andyf_: namra: still there?

2:03 namra: clojuredocs.org down?

2:14 kwladyka: when should i use sets?

2:14 if i need unique values it mean i should sets or not necessary?

2:26 namra: kwladyka: "Sets are collections of unique values.

2:26 "

2:26 so yea if you want a collection with no duplicates

2:27 (doc #{})

2: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

2:27 namra: (doc #)

2:27 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

2:27 namra: (doc sorted-set)

2:27 clojurebot: "([& keys]); Returns a new sorted set with supplied keys. Any equal keys are handled as if by repeated uses of conj."

2:27 namra: (doc set)

2:27 clojurebot: "([coll]); Returns a set of the distinct elements of coll."

2: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

2:34 in other word: i am looking the best way to write/read coordinates on 2-dimension board to later draw this board

2:36 aztak: kwladyka: hehe, I'm doing something similar to render a maze :)

2:36 I actually use a hash where keys are the coordinates:

2:37 {[0 0] {:some-content 123}, [0 1] {:another-content 345}}

2:37 Lookup is then simply ([0 0] map-ref)

2:38 Not sure if it's the best approach - another alternative would be nested vectors (a 2-d array).

2:38 kwladyka: mmm now it looks like obviously solution :)

2:38 aztak, thx

2:41 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} ?

2:42 how do you solve only one thing can be in one place?

2:43 aztak: No - '#{}' is a Set, right? I have a Hashtable '{:key1 value :key2 value}'

2:43 kwladyka: I don't - it isn't needed for my maze hack :/

2:44 (but unique coordinates is enforced since the coordinates [x y] is the key of the Hashtable)

2: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}}

2:47 yeah but i have to remeber all possible unique configurations of figures on the board

2:47 so i think i should use sets of maps :)

2:50 *rookie -> rook :)

3:40 celwell: Hi, is there a prettier way to write this, since it's using the 'o' so repetively:

3:40 (defn valid-price?

3:40 "Is the stated 'total_price' accurate?"

3:40 [db-conn o]

3:40 (= (:total_price o)

3:40 (calculate-cost db-conn

3:40 (:gas_type o)

3:40 (:gallons o)

3:40 (:time-in-minutes o)

3:40 (:coupon_code o)

3:40 (:vehicle_id o)

3:40 (:user_id o)

3:40 (:referral_gallons_used o))))

3:40 justin_smith: celwell: don't do that

3:41 celwell: oops, should have used a gist I guess

3:42 Here is the code: https://gist.github.com/celwell/08aa26dade2550d92631

3: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))

3:43 celwell: alternately (apply calculate-cost db-conn (map o [:gas_type :gallons :time-in-minutes :coupon_code :vehicle_id :user_id :referral_gallons_used]))

3:44 it might also make sense to define calculate-cost to take a hash-map as an arg

3:44 celwell: Hmm... thanks. How would you personally do it?

3:44 the last suggestion?

3: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

3:45 the calls are just more readable that way usually

3:45 Bronsa: don't forget about destucturing

3:46 justin_smith: yeah, I'd be destructuring on the impl side :)

3:46 celwell: sorry, how would destructing work?

3:47 justin_smith: (defn calculate-cost [db {:keys [gas_type gallons time-in-minutes ...]}] ...)

3:47 then you call (calculate-cost db o)

3:47 celwell: interesting route to go

3:48 justin_smith: I'd do it that way if the args usually all come from the same place

3:48 I'd likely even do it if they didn't for readability's sake...

5: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?

5:16 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 :/

5: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?

6:16 fikusz: (type (int 10)) gives me java.lang.Integer: how can I get a primitive int type?

6:28 Pupeno: Does anybody have a recommendation on libraries to do http requests (get, posts, cookies) and parsing the resulting html?

6:30 arrdem: $mail andyf great that sorting function worked perfectly and is live as of now. bug fixed.

6:30 lazybot: Message saved.

6:32 dstockton: Pupeno: clj-http and enlive?

6:33 Pupeno: Thanks.

6:45 Do you use envile for parsing HTML? it looks like a templating engine.

6:47 tdammers: it's both, in a way

6:47 although that might not be immediately obvious from skimming the documentation

7:55 Pupeno: Is there a more idiomatic way to do two assoc-ins other than nesting them?

8:07 aztak: Pupeno: assoc supports multiple key-values

8:07 ,(def a-map {:foo "bar"})

8:07 clojurebot: #'sandbox/a-map

8:07 Pupeno: aztak: but I'm not using assoc, I'm using assoc-in.

8:08 aztak: ,(assoc a-map :zip "zap" :zap "zip")

8:08 clojurebot: {:foo "bar", :zip "zap", :zap "zip"}

8:08 aztak: ah :)

8:08 read that too fast, sorry :)

8:08 Pupeno: np

8: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 ...))

8:28 Though I tend to thrush my update-ins sometimes without issues, and I don't think it's unidiomatic.

8: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.

8:40 something like (multi-assoc-in m [:foo :baz "bar"] [:foo :bar "baz"])

8:49 crocket: How do I traverse a list recursively for side effects in a clojure macro?

8:49 clojure.walk.walk doesn't seem to fit my need.

8:50 I want to collect the list of symbols in a list and return it.

9:10 snowell: crocket: Do you mean get only the values that are symbols?

9:10 Either way it doesn't sound like a side effect

9:12 justin_smith: crocket: in a list, or a nested list?

9:14 crocket: (get-symbols (+ 1 2 3 (- 1 2 3))) == ("+" "-")

9:14 I want to write get-symbols macro)

9:15 justin_smith, snowell ^^

9:15 snowell: ,(filter symbol? (flatten '(+ 1 2 3 (- 1 2 3))))

9:15 clojurebot: (+ -)

9:15 justin_smith: ,(map name (filter symbol (tree-seq '(+ 1 2 3 (- 1 2 3)))))

9: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...

9:15 justin_smith: :P

9:16 crocket: ,(map name (filter symbol? (tree-seq '(+ 1 2 3 (- 1 2 3)))))

9: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...

9:16 justin_smith: ,(map name (filter symbol (tree-seq seq seq '(+ 1 2 3 (- 1 2 3)))))

9:16 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.String>

9:16 justin_smith: ,(map name (filter symbol? (tree-seq seq seq '(+ 1 2 3 (- 1 2 3)))))

9:16 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>

9:16 snowell: (apply str (filter symbol? (flatten '(+ 1 2 3 (- 1 2 3)))))

9:16 justin_smith: ugh

9:17 snowell: ,(apply str (filter symbol? (flatten '(+ 1 2 3 (- 1 2 3)))))

9:17 clojurebot: "+-"

9:17 crocket: Clojure compiler is rejecting your errors.

9:17 snowell: grr

9:17 ,(map str (filter symbol? (flatten '(+ 1 2 3 (- 1 2 3)))))

9:17 clojurebot: ("+" "-")

9:17 crocket: ,(doc flatten)

9: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."

9:17 justin_smith: ,(map name (filter symbol? (tree-seq seq? seq '(+ 1 2 3 (- 1 2 3)))))

9:17 clojurebot: ("+" "-")

9:18 * justin_smith probably needs coffee.

9:18 crocket: ,(doc tree-seq)

9: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."

9:18 snowell: justin_smith's answer is probably better or more elegant. Usually is :D

9:18 crocket: I think snowell's solution is more concise.

9:19 ,(filter symbol? (tree-seq seq? seq'(+ 1 2 3 (- 1 2 3))))

9: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...

9:19 crocket: ,(filter symbol? (tree-seq seq? seq'(+ 1 2 3 (- 1 2 3)))))

9: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...

9:20 crocket: ,(filter symbol? (tree-seq seq? seq '(+ 1 2 3 (- 1 2 3))))

9:20 clojurebot: (+ -)

9:20 crocket: ,(doc flatten)

9: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."

9:20 musty: :(

9:20 crocket: ,(flatten (+ 1 2 3 (- 4 5 6 (+ 7 8 9) 10 11 12)))

9:20 clojurebot: ()

9:20 crocket: ,(flatten (+ 1 2 3 (- 4 5 6 10 11 12)))\

9:20 clojurebot: ()

9:20 snowell: crocket: You have to quote the list

9:21 justin_smith: ,(flatten {:a 0 :b [1 2 3]})

9:21 clojurebot: ()

9:21 crocket: ,(flatten '(+ 1 2 3 (- 4 5 6 10 11 12)))

9:21 clojurebot: (+ 1 2 3 - ...)

9:21 crocket: ,(flatten '(+ 1 2 3 (- 4 5 6 )))

9:21 clojurebot: (+ 1 2 3 - ...)

9:21 justin_smith: ,(flatten #{[:a :b :c] [[:d :e] :f]})

9:21 clojurebot: ()

9:22 crocket: ,(flatten '#{[:a :b :c] [[:d :e] :f]})

9:22 clojurebot: ()

9:22 crocket: Is set a sequence?

9:22 justin_smith: ,(seq? #{:a})

9:22 clojurebot: false

9:22 justin_smith: ,(coll? #{:a})

9:22 clojurebot: true

9:22 crocket: ,(seq? [1 2 3])

9:22 clojurebot: false

9:23 crocket: (seq? '(1 2 3))

9:23 ,(seq? '(1 2 3))

9:23 clojurebot: true

9:24 crocket: ,(list? '(1 2 3))

9:24 clojurebot: true

9:24 justin_smith: ,(list? (list 1 2 3))

9:24 clojurebot: true

9:24 crocket: ,(coll? '#{1 2 3})

9:24 clojurebot: true

9:24 justin_smith: you don't need the ' there

9:24 crocket: I think clojure will be complemented well by pixie.

9:25 clojure is a lot more elegant than java, javascript, python, C, and C++.

9:25 tdammers: that's not a very high standard to compare yourself with :x

9:26 crocket: Those are the languages I learned in the past,

9:26 I can't compare clojure with languages I haven't learned.

9:26 tdammers: obviously :D

9:26 crocket: I retired as a commercial programmer, and now I learn at home.

9:27 tdammers: cool

9:27 crocket: Most commercial programming environments are degrading.

9:27 tdammers: tell me about it

9:27 crocket: Most companies prevent you from learning.

9: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

9:28 crocket: tdammers, Which company do you work for?

9:28 tdammers: tiny one in the netherlands

9:28 crocket: Is it a lab?

9:28 tdammers: nope

9:28 crocket: It's typically a corporate lab.

9:28 tdammers: well, not really... we're not sure yet

9:28 crocket: Can you tell me the name? I want to see the website.

9:28 tdammers: we don't really have a website

9:29 crocket: ok

9:29 tdammers: working on that

9:29 crocket: What do you do?

9:29 What does the company do?

9:29 tdammers: government-related stuff

9:29 we're operating on the edge between government IT and the corporate world

9:29 crocket: Anyway, good luck with maintaining a high degree of autonomy once your company grows beyond 20 people.

9:29 tdammers: oh, the parent company is larger than that

9:30 vas_: Hi everyone..

9:30 tdammers: but our team is currently 5 people

9:30 vas_: What does "Don't know how to create ISeq from: java.lang.Long" usually mean o_O

9:30 tdammers: with a bit of commercial support from "outside"

9:30 (in the form of marketing, sales, profitability research, etc.)

9:30 justin_smith: vas_: it means numbers are not sequential collections

9:30 crocket: A good thing about learning at home is you get to learn and work on things as you see fit.

9:30 tdammers: (and also money)

9:30 justin_smith: vas_: eg. ##(first 1)

9:30 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

9:30 tdammers: crocket: absolutely, and clojure is a wonderful playground for these things

9:31 crocket: No company would pay me for what I want to do for now.

9:31 tdammers: me neither, but this is close enough for now

9:32 crocket: I plan to learn several languages and AIs.

9:32 vas_: justin_smith: Oh thank you that is very clear.

9:32 crocket: It's going to take 3-4 years to finish learning and start working on AIs.

9:32 However, the learning doesn't stop there.

9:32 tdammers: nah, I wouldn't look at it that way

9:32 crocket: It will take about 3-4 years to start working on AIs.

9:32 tdammers: you never finish learning, you just do things as well as you can, and you learn along the way

9:33 crocket: tdammers, I was about to say that I never stop learning.

9:33 tdammers: and no, I don't think you need to spend 3 years before you can write a simple AI

9:33 copycat: how does clojure compare with racket?

9:33 crocket: tdammers, The kind of AIs that I want to write takes years of learning.

9:33 tdammers, I'm learning it from a mentor.

9: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

9:34 crocket: tdammers, His AI design requires knowledge of semiotics, turing ordinal, and so on...

9:34 tdammers: just do a bunch of simple ones first, and you'll stumble upon the relevant language features

9:34 ah, but then the bottleneck is more in the realm of grokking the theory

9:34 not so much implementing it in a programming language

9:35 crocket: tdammers, Right now, I don't even know the relevent theories.

9:35 tdammers: exactly

9:35 I bet once you do, and have gotten your feet wet a bit, the implementation part isn't going to be the biggest problem

9:35 crocket: Meanwhile, I want to build some useful web services that I use personally.

9:35 I also want to write some simple CLI apps in clojure-like pixie.

9:36 I'd definitely use clojure for any non-trivial apps...

9:39 copycat, You can compare runtime performance characteristics of clojure and racket.

9:39 Racket runtime doesn't require a lot of RAM, and it starts up fast.

9:39 But, after loading, racket is slower than clojure.

9:39 copycat: i don't think i'm programming at a level where i need to care about the run time performance

9:39 crocket: Runtime performance matters if you want to write simple CLI apps.

9:40 clojure doesn't fit small CLI apps.

9:40 tdammers: ^

9:40 crocket: For any CLI app that needs to be executed repeatedly, startup time needs to be small.

9:40 copycat: what are examples of CLI apps?

9:40 r4vi: there's also hy which allows you to use the python interpreter

9:40 tdammers: exactly. if you want to use it in a script, we're talking milliseconds here

9:40 copycat: i've only made GUIs for fun

9:40 crocket: copycat, DDNS clients, ntp clients

9:41 tdammers: the DDNS client could be written as a daemon though

9:41 copycat: to be honest

9:41 i've never heard of those terms

9:41 tdammers: the NTP clients *should* be written as a daemon, even, so that you can nudge instead of jump

9:41 crocket: If you want to run a DDNS client daemon on Raspberry Pi, clojure won't cut it.

9:41 copycat: like i said, i'm new to the world of software

9:41 GUIs are all i'm familiar with

9:41 tdammers: well, JVM in general on a Pi sounds like a bad idea to me

9:42 crocket: If you want to run daemons on OpenWrt and RaspBerry Pi, clojure will not make it.

9: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

9:42 with a simple easy-to-use ide

9:42 crocket: While Racket is a good language, it has multiple languages.

9:42 tdammers: idk, the IDE and how everything assumes that you want to use it somewhat turned me away from racket

9:43 not my style at all

9:43 crocket: And, clojure has one style.

9:43 one langauge, one stgyle

9:43 copycat: i guess it's aimed for easing newbies into software development

9:43 crocket: tdammers, You can use emacs istead of DrRacket.

9:44 tdammers: crocket: more of a vim man myself

9:44 crocket: vim works well on terminals.

9:44 emacs doesn't.

9:44 copycat: what programs did you guys work on when you started learning programming?

9:44 CLI apps?

9:44 tdammers: MS-DOS 4 batch scripts

9:44 copycat: i thought most people begin by creating GUIs and games

9:45 zimablue: for me - yes, tiny c++ programs that calculated the movements of pendulums at uni, this was about 6 years ago

9:45 I think the next generation will probably be straight in with guis and javascript

9:46 tdammers: the current generation already is

9:46 mobile apps and all that

9:47 digiorgi: c++ data structures in the university

9:52 copycat: i have a couple of newbie questions

9:54 i know this sounds dumb, but what's so good about a question about being hosted on the jvm?

9:54 the website doesn't offer much in the way of information

9:54 justin_smith: copycat: existing corporate infrastructure

9:54 copycat: what does that mean in concrete examples?

9: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

9:55 tdammers: one advantage is that it's easier to sell to management

9: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

9:55 tdammers: you don't need to hire new IT staff, you don't even have to train them

9:55 the deployment procedure is pretty much the same - "here's a jar, do your thing"

9: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

9:56 exactly

9:56 it also means, in terms of optimizing the resulting code, we can just re-use the runtime optimizations of the jvm

9: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

9:56 copycat: could you elaborate on - the deployment procedure is pretty much the same - "here's a jar, do your thing"

9:56 justin_smith: instead of inventing that from scratch

9:57 copycat: in order to run a clojure uberjar, all you need is java

9:57 that's literally the only thing that needs to be installed on the server

9:57 tdammers: and yes, from the language implementation point of view, it means that you only need to invent the "front-end" part

9:57 it was an important factor in getting clojure the traction any new language needs

9:58 I think that if it hadn't been for the jvm, clojure wouldn't have made it

9:58 copycat: what other things does clojure has going for it?

9: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

9:58 tdammers: not because other lisps are necessarily better, but because they would have had a more complete set of libraries available

9:58 blkcat: ^ strongly agree. jvm was clojure's trojan horse

9:59 justin_smith: copycat: pervasive immutability without having to deep copy all your data

9:59 tdammers: justin_smith: that comparison isn't entirely fair though, because clojure is compiled and python isn't

9: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

9:59 tdammers: yes

9:59 ofc

9: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 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 tdammers: but then you still have dependency hell on the dev and build machines

10:02 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 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 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 there's a difference there, is all I am saying

10:05 tdammers: oh, sure

10:05 but then, the interfaces tend to be a lot stricter in Haskell

10:06 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 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 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 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 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 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 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 uncontrolled laziness has always struck me as a blatant oversight in Haskell's design

10:16 wasamasa: justin_smith: .ppt?

10:17 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 rolls eyes

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 I think he does that on purpose

10:19 wasamasa: yes he does

10:20 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 heh, sure

10:21 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 and take on only those who are open to whatever tech you pick

10:22 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 as programmers, we sometimes forget that technical superiority is just one of many factors

10:26 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 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 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 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 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 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 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 ,\\

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 or repl-listen, fails

10:58 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 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 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 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 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 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 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 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 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 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 ...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 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 (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 ^-

13:32 (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 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 tmtwd: also, you can use M-x cider to connect to the same open port

13:39 (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 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 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 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 don't do that

14:19 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html

14:20 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html

14:20 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 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 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 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 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 doesn't happen when I remove that file

14:38 probably due to this, I think: http://www.slf4j.org/codes.html#log4jDelegationLoop

14:40 not that exactly, but something like it

14:49 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 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 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 gfredericks: really glad you are doing this (sorry I didn't do it sooner)

15:28 gfredericks: one failing test left

15:28 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 anyone know how to work around that?

15:47 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 as M-. is bound to another command in evil's normal state map

15:51 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 I have a reagent\figwheel application which I’m hosting on github pages

16:41 but it’s like the css isn’t loading

16:42 (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 I think that's what I wanted

16:43 arrdem: ok

16:43 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 anyone have a clue what I’m doing wrong?

16:44 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 yes, my .js is getting a 404

16:48 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 I *just* pushed it to the github page

16:52 it shouldn’t be cross-http, it’s the very same site

16:52 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 well… I don’t know.

16:54 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 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 like, github.io is just serving files directly out of https://github.com/Reefersleep/Reefersleep.github.io as far as i know

17:00 and there is no .js file to be seen

17:00 it doesn't invoke lein cljsbuild for you or whatever other thing

17:00 Reefersleep_: uhm

17:00 you’re right

17:00 wtf happened

17:01 the .js is in my local folder

17:01 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 the folder is in gitignore

17:03 I think you saved me :)

17:03 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 it's autogenerated stuff there

17:04 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 I’m going to try and work this out

17:07 I get why it’s ignored to begin with

17:07 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 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 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 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 see the project.clj for the config of both

17:10 Reefersleep_: aha

17:11 oddcully: Do you have a tip on how to push something to one repo, and not the other?

17:11 I’m (also) a github newb :l

17:11 *git

17:12 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 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 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 there are lots of nikola/octopress/younameit pages on github.io

17:15 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 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 oddcully: ??

17:40 lazybot: hellofunk: Definitely not.

17:40 Seylerius: amalloy: Thanks

17:40 (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 (and (< x 10) (< y 10)) ?

17:41 hyPiRion: (and (< x 10) (< y 10))

17:41 Reefersleep_: maybe

17:41 randomcharhere: doh thanks :)

17:42 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 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 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 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 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 so for now while dev'ing things, you might stick with :dev

18:00 i just wanted to mention this

18:01 the :min build will turn all your out/**/*.js files into one blob of optimized js

18:01 Reefersleep_: ah alrigh

18:01 t

18:01 this stuff is tricky. I need an automated release build process, really

18:01 Like you suggested.

18:04 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 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 Thanks, lodin__

18:24 (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 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 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 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 ,(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 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 randomcharhere: typically we'd have something like reduce or loop where each iteration sees a new vector with the new data added

18:41 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 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 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 ,(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 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 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 ,(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 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 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 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 (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 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 s/function/functions/

19:16 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 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 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:38 * Seylerius nods

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 kind of like a callback on an ajax call, but with threads, and with channels

Logging service provided by n01se.net