# #clojure log - Aug 24 2015

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

2:31 amalloy: TEttinger: j.u.regex.Pattern/quote

2:31 TEttinger: (inc amalloy)

2:31 lazybot: ⇒ 294

2:44 Kneiva: Yay, lazybot is back.

3:24 deg: What is an idiomatic/efficient way to generate, e.g. (1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, ...) from (0, 3, 4, 9, ...)? That is: my input is a sequence of integers, unbounded but sorted, representing the positions that should be 1 in my output.

3:29 oddcully: ,(let [there? #{0 3 9}] (map there? (range 10))

3:29 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

3:29 oddcully: oho

3:30 ,(let [there? #{0 3 9}] (map there? (range 10)))

3:30 clojurebot: (0 nil nil 3 nil ...)

3:30 opqdonut: nice

3:32 deg: But, my input is potentially infinite.

3:33 opqdonut: then you need to type out the recursive lazy-seq definition yourself

3:34 deg: I'm not sure what you mean.

3:35 I think I need to take advantage of the fact that the list is sorted. Naively, in an imperative language, I would iterate the integers, and check if each one matched the head of the input list. If not, continue; if yes, output the value and pop the head of the input list. But, I'm not sure how to write that elegantly in Clojure.

3:36 opqdonut: (defn f [ind inds] (if (= ind (first inds)) (cons 1 (lazy-seq (f (inc ind) (rest inds)))) (cons 0 (lazy-seq (f (inc ind) inds)))))

3:36 you recursively define a lazy seqnence

3:36 with that definition, for example (take 20 (f 0 [0 3 4 9])) evaluates to (1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0)

3:37 in general the functional equivalent of a loop that has variables x, y, z is a recursive function with arguments x, y, z

3:37 deg: Thanks. I need to wrap my head around that for a minute, but it looks good.

3:37 opqdonut: and returning a lazy sequence corresponds to an imperative generator (e.g. using python's yield)

3:38 just indent the code nicely and it should be fairly obvious

3:38 "inds" is the list of indexes for 1s, "ind" is the current index we're at

3:38 gilliard: opqdonut: nice.

3:39 opqdonut: I just banged out that function in one go, it's quite natural once you've done this sort of thing a couple of times

3:40 code would probably be more efficient if one used repeat and concat instead of cons

3:41 deg: Yup, I see it now. By, using repeat, you mean to look at the size of the gap, rather than iterating over all the intermediate values?

3:41 opqdonut: yep

3:42 hmm

3:42 deg: Yup. For my purposes, that extra efficiency is not needed, and would probably make the code less readable. But, point taken.

3:44 opqdonut: btw here's one more approach:

3:44 ,(let [inds [0 3 4 9] intervals (map - (rest inds) inds)] (mapcat #(cons 1 (repeat (dec %) 0)) intervals))

3:44 clojurebot: (1 0 0 1 1 ...)

3:45 opqdonut: needs some additional code to take care of the position of the first 1

3:47 deg: Not bad! A little bit harder for me to grok than the first one, but still understandable. The difference is that (at my current level of experience) your first version is immediately readable; the second would require me to add some comments in order to understand it later.

3:49 opqdonut: yeah, I find it that for non-trivial tasks it's clearer to write out the recursion instead of gluing together sequence functions

3:50 deg: Yup. I'm not used to lazy seqs today, because I'm coming back to Clojure after nearly a year away. But, in general, I always have trouble scanning complicated combinations of sequence functions.

3:51 What would you say is the community consensus for which approach is more idiomatic?

4:54 ely-se: do people actually use core.typed?

5:08 vijaykiran: ely-se: I didn't see enough usage in the wild

5:12 ely-se: "Type Error (saftcof/fridge.clj:24:4) Unannotated var clojure.core/update"

5:12 bleh

5:15 TEttinger: ely-se: is it updated to clojure 1.7?

5:15 ely-se: update-in gives a similar error anyway :p

5:19 yes, rewriting it to use assoc works

5:22 ugly but worth it

5:33 it already caught a bug I just wrote :p

5:51 newpm: Hello

5:57 I've recently taken over a team that develops SaaS apps in java and flex. I haven't coded in about 10 years, but even when I did, it was simple stuff like implementing quicksort in C etc. Given that I'm going to be working with a whole bunch of devs and testers, I'd like to learn a new programming language - one that helps me understand programming

5:57 , but from a non C/Java POV (so I can have the pleasure of relearning programming as well). Do you gurus have any recommendations for me?

5:57 clojurebot: #error {\n :cause "Unable to resolve symbol: but in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: but in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: but in this conte...

5:59 TEttinger: newpm: clojure's a good very-different kind of language

6:00 newpm: Yes. I've been fascinated by functional programming paradigms - I've heard people say great things about it, esp from a foundational perspective.

6:00 TEttinger: other choices that might be useful in a similar way to Clojure would be haskell, possibly erlang, or maybe in a different functional approach, one of the newer science-y languages like Julia

6:00 newpm: I just don't want it to be TOO removed from what my team does and thinks in terms of programming philosophy

6:00 TEttinger: yeah if you're on the JVM, Clojure has great integration

6:01 newpm: I am posing the same questions in those two other channels, TEttinger. Ideally, I'd spend a month on each language and decide for myself but I don't know if I have that time

6:01 tdammers: if you're looking for an easier transition, I hear people use Scala with some success

6:01 TEttinger: ,(doto (java.util.TreeMap.) (.put "a" 1) (.put 8 "b"))

6:01 clojurebot: #error {\n :cause "java.lang.String cannot be cast to java.lang.Long"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to java.lang.Long"\n :at [java.lang.Long compareTo "Long.java" 50]}]\n :trace\n [[java.lang.Long compareTo "Long.java" 50]\n [java.util.TreeMap put "TreeMap.java" 560]\n [sandbox\$eval48 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eva...

6:01 tdammers: it's not as nice from a FP point of view, but the transition can be a little less painful

6:02 TEttinger: ,(doto (java.util.TreeMap.) (.put "a" 1) (.put "b" 8))

6:02 clojurebot: {"a" 1, "b" 8}

6:02 TEttinger: huh, it is statically typed even with erasure

6:02 I'm not a huge fan of scala

6:03 tdammers: me neither, but I've heard success stories of people getting it into shops that were previously deeply rooted in Java

6:03 gilliard: TEttinger: Because the treemap is trying to sort its keys and long.compareTo(string) doesn't work.

6:03 tdammers: something like clojure or, gasp, Haskell, wouldn't have flown

6:04 TEttinger: it seems like you either go all-in on the functional stuff and have to deal with a mountain of complex APIs, or you go to the simpler OOP stuff and basically have slightly slower java with worse IDE integration

6:04 (in scala)

6:04 tdammers: in all fairness, if you want IDE integration, it's near impossible to beat Java

6:05 TEttinger: did you mean C#, the language that is borderline unusable without VS? :P

6:05 jeaye: Who says so?

6:05 TEttinger: there is XS and monodevelop now

6:05 * jeaye uses C# frequently in vim, with realtime semantic completions, just fine.

6:05 TEttinger: but it's such a huge difference working with large files in VS

6:06 jeaye: if you wanted to find all usages in a C# project in vim?

6:06 all usages of a particular method overload

6:06 jeaye: Yup, can do.

6:06 TEttinger: how?

6:06 tdammers: back when I was still using C#, I settled for using VS for most stuff, and hooking vim into it for mass edits

6:06 clojurebot: with style and grace

6:07 TEttinger: in VS that's ctrl-k r

6:07 newpm: That is another additional overhead i would like to ideally avoid - learning ohw to use vim or emacs :)

6:08 TEttinger: clojure works well with IntelliJ IDEA's Cursive plugin

6:08 your team may want to use Eclipse or IntelliJ

6:08 jeaye: TEttinger: You're familiar with vim, I hope; it has a _very_ extensive plugin community with thousands of plugins across many languages.

6:09 TEttinger: Aside from project-based completion (including external references, etc), there is functionality for the whole suite of refactoring tricks, snippets, etc. All you'd want.

6:09 TEttinger: I don't know what those plugins do or if any will, say, erase my file if I press the wrong key

6:09 jeaye: hah

6:09 Well, if you're not a vim user, you'd likely think that way. Still, my point isn't to get you to use vim/emacs/whatever. My point is just that your claims about the state of editing C# are uninformed.

6:10 Or misinformed, anyway.

6:10 ely-se: I already love core.typed.

6:10 TEttinger: does it have breakpoint debugging for C#?

6:10 does it have breakpoint debugging for Clojure?

6:10 ely-se: I hope it won't turn out to be a disaster.

6:10 oddcully: TEttinger: who say, that cursive is not raining nukes on some country while you type?

6:11 TEttinger: as long as it's like murderer alley, sure cursive go right ahead

6:11 ely-se: TEttinger: can it handle Unix line endings?

6:12 TEttinger: I think VS can. I've never encountered issues with that outside of the stupidest programs like notepad

6:13 jeaye: TEttinger: Not sure about either since 1) I don't need the first; 2) I'm too new to clojure to've needed the second. Vim has a slime-like plugin, slimv, which is certainly usable (not gonna compare it to emacs, the proper lisp editor).

6:14 I've enjoyed using it for CL work, anyway.

6:14 TEttinger: ah ok

6:14 newpm: thanks everyone!

6:48 cfleming: oddcully: TEttinger: As far as I'm aware, Cursive does not rain nukes on any country while you're typing. If you believe this to be the case, please file an issue in the tracker.

6:56 oddcully: cfleming: that was a joke and not aimed at cursive. each and every piece of software has the potential of wrecking havoc on your computer. intellij plugins are not more or less safe than vim/emacs/... plugins

6:56 cfleming: oddcully: I know, my response was a joke too :-)

6:58 If Cursive actually were raining nukes, I'm not sure an issue in the tracker would be an appropriate response level, especially given how long it takes me to fix issues.

6:58 oddcully: what if the server with the issue tracker is the target of the nuke?

7:01 cfleming: That would be sneaky. I'm not sure if Github issues are adequately distributed.

7:07 pseudonymous: While technically working in a repl, I have a question (maybe even a few) - after much experimentation, I've found that (require 'path.to.clj-file)(in-ns 'path.to.clj-file) at least allows me to refer to the functions defined within. However, now I can't access general (core?) functions such as doc. Is there a tutorial or something which covers working with the repl, namespaces & such ?

7:19 kwladyka: pseudonymous, use (require 'namespace :reload-all)

7:19 pseudonymous, and (namespace/foo ...) or (use namespace) if you preffer

7:31 the-kenny: There is no support for :pre and :post in `defprotocol', right?

7:31 I would like to add some constraints to protocol functions, applying to *all* implementations.

8:00 pseudonymous: kwladyka: Also found out that *ns* points to my current namespace and by going back to the initial NS via in-ns all is well :)

8:04 SigmundL: hmm slack group too? lot's of messaging apps now :-)

8:09 kwladyka: I wrote http://clojure.wladyka.eu/posts/2015-08-24-how-to-improve-algorithm-speed.html connected with https://github.com/kwladyka/chess-challenge about how to improve algorithm speed in Clojure. I am sharing that with you and i will be very grateful if you can give me feedback about article.

8:09 Anyway where can i share article like this about Clojure?

8:10 pseudonymous, for me my solution is much more comfortable, but i also started with in-ns at first day in REPL ;)

8:10 especially intellij remember history of commands and you can easy run them again when you open your project. It is much more usability then.

8:24 shrayasr: Hello everyone

8:24 I'm having a little problem understanding and taming timestamps

8:24 is anyone around to help?

8:24 (i'm using clj-time)

8:25 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

8:27 shrayasr: the server i'm hosting on is in the GMT timezone.

8:27 but I want to store timestamps in another timezone (Say X)

8:27 I'm able to get the string representation of the timestamp in the "X" timezone

8:28 But to insert into the DB (regular jdbc)

8:28 I need it to be in the "timestamp" type

8:29 which I can get via the clj-time.coerce/to-sql-time function

8:29 But then the coerce/to-sql-time function doesn't take the time zone into consideration

8:29 Sooooo. I'm stuck

8:30 * the-kenny remembers dealing with exactly this some time ago

8:30 the-kenny: Let me check how I handled it

8:30 shrayasr: Sounds great, thanks @the-kenny

8:32 I see that we can start the JVM with a specified timezone, Any reason I *shouldn't* be doing this?

8:32 I assume if I do this, then it is straightforward for me

8:33 the-kenny: shrayasr: Hm, my code just extends jdbc/ISQLValue and calls `clj-time.coerce/to-timestamp'. That doesn't seem to handle timezones either

8:34 I'm quite sure I have a snippet which does some more (by manually creating the value with `ISQLParameter')

8:35 That might have been postgres-specific though

8:39 shrayasr: By extending ISQLParameter for org.joda.time.DateTime (or some other class/record) you should be able to set the type of the PGobject to 'TIMESTAMP WITH TIME ZONE' and the value to some string lile: "2004-10-19 10:23:54+02"

8:44 en590: clojure!

8:50 gfrederi`: clojure!

8:59 dstockton: clojure!

8:59 snowell: clojure?

8:59 clojurebot: clojure is a language to use if you want to up your game

8:59 en590: well that's exactly what I want to do

9:00 i've found two books that look good to learn it, 'living clojure' and 'clojure in action 2nd edition'

9:00 are these good

9:02 pseudonymous: So I finally came to a point where I need to reload something. While (require '[<my namespace> :as <short-hand>] :reload-all) doesn't yield any error, I still can't access anything from the NS (not even the old functions). I see references to "clojure.tools.namespace.repl" but including it fails (Could not locate.....) - what do people do ? Reopning the REPL constantly *sucks*

9:05 en590_: sorry i d/c

9:17 I'm on linux what environment do you all use to develop in?

9:17 like ide or whatever

9:18 akabander: I've been using IntelliJ with the Cursive plugin. I'm normally an Emacs/command-line coder, but IntelliJ has some nice features.

9:19 schmir: en590_: I'm using emacs, but that may be a bit too hard when you're learning clojure at the same time.

9:19 emacs with cider

9:20 akabander: I'm on Linux and OS X, our target platform is Linux-y though.

9:31 kwladyka: en590_, i also recommend intellij

9:31 with own shortcuts i super great

9:31 snowell: I use Light Table, FWIW

9:32 kwladyka: light table is crap unfortunately, it has so big potential but if i know author abandon project to care about new one

9:32 and for today light table doesn't work enough good for me

9:34 snowell: I tried getting IntelliJ/Cursive set up once and hit problems

9:35 I'm not against trying it again...

9:35 cfleming: snowell: Let me know if you have problems, I'm always interested in trying to make it easier.

9:36 akabander: The only issue I had with Cursive was that it didn't seem to be able to create keymappings for the structural editing commands, I had to create them manually.

9:37 cfleming: akabander: You should be able to - not sure when you tried it, but that's been in there for a while now (https://cursiveclojure.com/userguide/keybindings.html)

9:38 akabander: cfleming: I gather you work on Cursive? The pages are pretty coy about who the author(s) are.

9:38 cfleming: akabander: I do - I'm the only developer.

9:39 akabander: Oh, well... Thanks for your efforts, it's a terrific plugin and makes my days pretty pleasant!

9:39 cfleming: Thanks! That's always good to hear.

9:43 kwladyka: snowell, what kind of problems?

9:44 snowell: I don't really remember. I'm actually trying it again atm

9:45 cfleming: snowell: Cool, I'll be around for a couple of hours if you're having issues.

9:46 snowell: It may have been as dumb as Light Table's rainbow parens were brighter

9:46 I am a fickle man :)

9:47 cfleming: Fortunately I recently changed Cursive's rainbow parens to be quite garish :-)

9:48 snowell: It doesn't seem to want to read my project.clj. This could be because it starts with a let instead of defproject

9:48 cfleming: That shouldn't be a problem, but it is a problem if you're doing things like slurping a version.txt file or something like that?

9:49 kwladyka: if you want use intellij cursive i strongly recommend shortcut for slurp forward and barf forwards

9:50 akabander: I get weird looks when I ask people if their editor can slurp and barf.

9:50 snowell: I'm unfamiliar with barf

9:50 I thought it was spit

9:50 akabander: I think it's the same thing but harder to confuse with split

9:51 cfleming: They're two different things. Slurp/Barf refer to paredit (structural editing) and slurp/spit are functions for reading/creating files.

9:51 cfleming: Ba-doom-*tschhh*

9:57 snowell: Yeah, cfleming, it must have been me being stupid about colors. Looks like it's working OK outside of yelling at me that it can't load my project.clj

9:58 I'll keep using it and report back on its awesomeness

9:58 cfleming: I also accept reports on non-awesomeness :)

9:58 Are you able to show me your project.clj?

9:58 snowell: Probably not, though I did just submit a report through the IDE

9:59 It's just (let [blah blah] (defproject normal "stuff"))

9:59 cfleming: Weird, that should work. I'll see if I can reproduce with a simple case.

10:01 snowell: At the base, it seems to be a NPE

10:01 cfleming: Are you using lein-sub?

10:02 shrayasr: the-kenny: Had to go AFK. Sorry about that.

10:03 snowell: No?

10:04 cfleming: snowell: Can you paste the stacktrace to refheap?

10:07 en590_: i love function programing so much

10:09 snowell: cfleming, You know what, I might actually be able to see what it's NPE'ing on

10:09 en590_: have you guys completed most of 4clojure? this site is amazing

10:10 wasamasa: feels like a third to me

10:14 en590_: could anyone reccomend a resource for learning about functional programming in general?

10:15 shrayasr: en590_: I found this 3 part series to be a lovely intro to FP: http://miles.no/blogg/why-care-about-functional-programming-part-1-immutability

10:18 en590_: ok neat thank you

10:18 clojure is 1 of the most beautiful languages ive seen

10:18 i guess thats true for all the lisps

10:19 snowell: cfleming: Looks like the problem is with a :repositories key in defproject

10:20 cfleming: snowell: That should work - lots of Cursive users are using custom repos

10:20 Is it a problem with GPG or something similar?

10:23 shrayasr: en590_: No problem. Enjoy :)

10:24 kwladyka: What questions did you have on clojure interview?

10:26 en590_: wait there are real clojure jobs?

10:26 jeaye: hah

10:26 Quite a few.

10:26 justin_smith: yes, I'm a full time clojure dev, there are many others around here

10:27 dozens, there are dozens of us!

10:27 akabander: I'm a professional Clojure dev -- convinced my boss that my piece of the project should use Clojure...

10:27 snowell: I do clojure at work despite the efforts of many of our clients :)

10:27 en590_: dang the world is a great place

10:28 akabander: And at some point I'll probably need a minion or two, or somone at my level.

10:29 jeaye: akabander: May I PM you?

10:29 snowell: cfleming: https://www.refheap.com/108673

10:30 Sorry about the delay, had to clean it up / anonymize it :D

10:30 rsenior: en590_: job market is good for Clojure folks

10:31 en590_: yah i believe it the language is just a joy

10:32 arkh: if compiling clojurescript with leiningen + cljsbuild works with all :optimzations except for :none, what could I be doing wrong? I've tried including a <script> reference to goog/base.js as well as taking everything made in target/cljsbuild-compiler-0/ and putting it in the webservers js folder so relative link references would be happy. Looks like the

10:32 browser is just loading my js, base.js and deps.js only so far

10:33 snowell: cfleming: Grr. The NPE should have been obvious, as I recently deleted JARS_HOME. I feel very bad that I'm getting paid to code and can't see that

10:33 cfleming: snowell: Ah :-)

10:34 snowell: Of course fixing that led to a different error: https://www.refheap.com/108674

10:34 cfleming: Sometimes it's hard to see the wood for the trees, for sure.

10:34 kwladyka: do you know good video (prefer) / article about how to use macros? But not about how to use it technically, how to use it to write super code :)

10:34 cfleming: snowell: Is JARS_HOME an absolute path?

10:35 snowell: Yeah, it was. And I deleted that folder

10:36 en590_: I'm a linux noob trying to install leiningen. it says Place it on your \$PATH where your shell can find it (eg. ~/bin)

10:36 how do I do this? I downloaded the lein script to my desktop

10:36 cfleming: snowell: So Cursive currently has an issue (to be fixed shortly) where it runs lein in-process, so CWD is always set to somewhere in the IntelliJ bin directory

10:36 en590_: do i do 'sudo copy lein.txt ~/bin'

10:37 gilliard: en590_: you don't need sudo

10:37 cfleming: If you're slurping or calling File. or something similar, it won't work properly because the CWD is bad.

10:37 snowell: Well it's not a relative path

10:37 gilliard: en590_: make sure there is a directory ~/bin first, then "mv ~/Downloads/lein ~/bin". ~ is just shorthand for your home dir.

10:37 en590_: i'm confused what does the ~ stand for

10:37 cfleming: I suspect there's something like that going on, but I can't see it from your project file. I've never seen that negative bytes error before.

10:38 gilliard: en590_: You can do "ls ~" etc

10:38 kwladyka: ok i found, it looks good enough http://www.lispcast.com/when-to-use-a-macro

10:38 snowell: It might be that some of the jars I need only existed in JARS_HOME

10:38 en590_: I don't see a /bin in my home folder

10:38 there is one in the root folder

10:38 cfleming: I'd expect a FileNotFound or similar in that case, though.

10:39 gilliard: en590_: There often isn't one on a new install. "mkdir ~/bin" will create one.

10:40 snowell: Well I'm getting that error just doing `lein deps` on the CLI. So I don't think it's a cursive problem

10:40 en590_: ok got it working

10:40 thank you

10:40 cfleming: snowell: Googling around, that message does seem to be a glorified FNF

10:40 en590_: linux is very cool

10:42 cfleming: snowell: Thinking about it, you're likely to have a problem in Cursive since you won't be able to set env vars where lein can see them.

10:42 When it's run in-process, I mean.

10:42 I'll add that to my list of things to fix - I'm actually planning a major lein update to fix all this sort of thing soon.

10:46 snowell: Well, something must have just been screwy in my local env. I reverted the changes, updated jars-home to exist, and now it works :/

10:47 Thanks for at least making me look critically at it though, and for the willingness to help out :D

10:47 cfleming: No worries, glad it's working!

10:47 I'm going to get all those lein fixes in in probably the release after next - perhaps a month or so.

12:11 en590: is (conj '(1 2) 3) equally efficient as (cons '(1 2) 3)

12:11 justin_smith: en590: it's (cons 3 '(1 2)), the second arg to cons must be sequential

12:12 en590: cons is what conj ends up invoking for lists (you'll notice that conj on vectors behaves differently)

12:14 en590: depending on your use case, you might want a vector rather than list (which is part of why it is good to use conj rather than cons, so that remains flexible)

12:14 but yes, conj on a list and cons on a list should be the same in perf

12:26 en590: hey i have a problem in my irc client whenever my internet craps out for a few seconds then returns, the irc doesnt connect again

12:26 this has happened in hexchat and also quassel irc

12:27 philth-irssi: en590, probably a client setting.

12:27 iirc, x-chat had a "Number of reconnet attempts" option.

12:28 don't know about hexchat or quassel tho'

12:31 en590: ok idisabled ping timeout stuff

12:31 maybe it works

12:32 why is (= 1 1.0) false but (== 1 1.0) true

12:33 oddcully: (doc ==)

12:33 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"

12:33 snowell: en590: because == is type-independent

12:34 en590: yeah makes sense just seems like the two should be switched

12:34 i expected opposite behavior

12:35 ely-se: please no :(

12:35 IMO = on different types should even fail with an exception

12:36 rhg135: , (= '(1) [1])

12:36 clojurebot: true

12:37 ely-se: :'(

12:37 philth-irssi: , (= 1 1.0)

12:37 clojurebot: false

12:37 rhg135: Sad indeed

12:37 philth-irssi: , (= [1] '(1))

12:37 clojurebot: true

12:38 akabander: Because they are equivalent seq's?

12:38 philth-irssi: , (== [1] '(1))

12:38 clojurebot: #error {\n :cause "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers equiv "Numbers.java" 208]}]\n :trace\n [[clojure.lang.Numbers equiv "Numbers.java" 208]\n [sandbox\$eval141 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval14...

12:39 * philth-irssi mind-blown

12:39 oddcully: (= 1N 1)

12:39 erm

12:39 ,(= 1N 1)

12:39 clojurebot: true

12:39 oddcully: ,(= 1M 1)

12:39 clojurebot: false

12:39 philth-irssi: bigints are ints?

12:40 , (type 1M)

12:40 clojurebot: java.math.BigDecimal

12:41 (= (type 1) (type 1N))

12:41 ,(= (type 1) (type 1N))

12:41 clojurebot: false

12:42 agarman: is it appropriate to ask datomic questions here?

12:43 snowell: You'd probably have better luck in #datomic :)

12:44 agarman: snowell: good call...it's a mix of Clojure + datomic, but I'll ask there first.

12:47 en590: i'm in the repl and when i tried to do (clojure.set/union #{:a} #{:b})

12:47 i got the error ClassNotFoundException clojure.set java.net.URLClassLoader\$1.run (URLClassLoader.java:366)

12:47 do i have to load in this module

12:48 philth-irssi: (require 'clojure.set)

12:48 oddcully: en590: yes require it

12:48 philth-irssi: ,(require 'clojure.set)

12:48 clojurebot: nil

12:48 philth-irssi: ,(require 'clojure.set) (union #{a} #{b})

12:48 clojurebot: nil

12:48 philth-irssi: ,(do (require 'clojure.set) (union #{a} #{b}) )

12:48 clojurebot: #error {\n :cause "Unable to resolve symbol: union in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: union in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: union in this...

12:49 en590: neat thank you

12:49 philth-irssi: ,(do (require 'clojure.set) (clojure.set/union #{a} #{b}) )

12:49 clojurebot: #error {\n :cause "Unable to resolve symbol: a in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: a in this context"\n ...

12:49 anyways it works in real repl.

12:49 ,(do (require 'clojure.set) (clojure.set/union #{"a"} #{"b"}) )

12:49 clojurebot: #{"a" "b"}

12:53 iwo: hey, anyone here familiar with prismatic schema? I'd like to define a schema that says a value must be a function, I can't seem to find a way to do this

12:54 I was imagining just something like: {:f s/Fn}

12:54 (i.e. map must have a key :f with a value that's a function)

12:54 rhg135: (s/=>...)

12:55 There's a => function to make function schemas

12:56 iwo: ah okay, so I need to define the arity of the expected fn?

12:57 rhg135: I think so

12:57 akabander: ,(doc =>)

12:57 clojurebot: It's greek to me.

12:57 iwo: thanks!

12:58 looks good.

12:58 rhg135: Np

12:58 ely-se: clojurebot: in that case I want my money back.

12:58 clojurebot: No entiendo

12:58 ely-se: D:

12:58 rhg135: clojurebot is lacking

12:59 snowell: clojurebot: Don't listen to him

12:59 clojurebot: Excuse me?

12:59 * ely-se hits clojurebot a few times in the hope it will work again

12:59 rhg135: Did you try turning off and on again?

13:00 en590: ,(+ 1 1)

13:00 clojurebot: 2

13:00 ely-se: ,(System/exit 0)

13:00 clojurebot: #error {\n :cause "denied"\n :via\n [{:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox\$enable_security_manager\$fn__849 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox\$enable_security_manager\$fn__849 invoke "sandbox.clj" 69]\n [clojurebot.sandbox.proxy\$java.lang.SecurityManager\$Door\$f500ea40 checkExit nil -1]\n [java.lang.Runtime exit "Runtime.java" 1...

13:00 ely-se: rhg135: I tried but failed.

13:00 en590: ,"clojurebot is a good bot"

13:00 clojurebot: "clojurebot is a good bot"

13:01 * rhg135 forwards ely-se to his supervisor

13:01 ely-se: her :p

13:01 rhg135: I'm a he :-P

13:02 Ambiguity

13:02 philth-irssi: What do they sandbox clojurebot with?

13:03 rhg135: Jvm sandboxing iirc

13:03 ely-se: oooh

13:04 I see. :p

13:04 philth-irssi: the JDK has facilities for that.

13:04 rhg135: The pronoun has two possible targets

13:04 Because English

13:05 philth-irssi: rhg135, ely-se, Ah, thanks!

13:06 ely-se: who is Ah?

13:06 rhg135: It may also use something else. You can check the source.

13:06 philth-irssi: rhg135, ely-se, "Ah, thanks!"

13:06 ambiguity :P

13:06 rhg135: English!

13:06 philth-irssi: Yea, I just found the github.

13:06 ely-se: the misinterpretation was intentional :p

13:07 rhg135: We should just speak lisp with English words

13:07 ely-se: (ok)

13:07 rhg135: It's a midway point

13:08 philth-irssi: you mean lithp

13:08 ely-se: (= :cool rhg135)

13:08 rhg135: (not (take-off this))

13:13 ely-se: I want to implement a data structure that wraps a set together with a collection of (function, map) pairs that can be used to find elements in the set quickly (like RDBMS indices)

13:18 justin_smith: ely-se: that sounds a lot like a hash-map

13:18 ely-se: no, it's different

13:18 wasamasa: if your hashmap doesn't allow to find elements quickly, URDOINITRONG

13:18 ely-se: wait, I'll implement it

13:19 justin_smith: ely-se: typically the right way to do pairs with quick lookup in clojure is a hash-map

13:19 not to say that's the entirety of what would be implemented... but it should be the core of it

13:20 ely-se: yes, I know, but that's not what I'm looking for

13:21 a hashmap has only a single index

13:21 and you have to make sure you consistently manage the keys

13:21 justin_smith: what does "consistently manage the keys" mean?

13:22 wasamasa: sounds like something a programmer shouldn't be bothered with

13:22 most likely staying with one data type for the keys

13:23 justin_smith: ely-se: I'm thinking most of us don't actually understand what you are trying to do here

13:23 ely-se: again, let me implement it

13:26 wasamasa: a quick search indicates that using more than one index on a database can be problematic with regards to performance

13:26 because the way they usually go at it is looking for all matches for the first index, looking for all matches for the second index, then combining these and returning the results

13:27 tcrayford____: Query planners though

13:29 hiredman: ,(doc clojure.set/index)

13:29 clojurebot: Excuse me?

13:29 hiredman: jerk

13:30 anyway, clojure.set/index exists, and even if you don't use it, a read through the source should be useful

13:30 philth-irssi: ,(do (require 'clojure.set) (doc clojure.set/index))

13:30 clojurebot: "([xrel ks]); Returns a map of the distinct values of ks in the xrel mapped to a set of the maps in xrel with the corresponding values of ks."

13:32 hiredman: clojure.set/index can build single key and multi key indices, and you can generally keep all the indices in a single map

13:32 * justin_smith feels vindicated, though ignored.

13:34 en590: in a 'let' expression why are the bindings done in a vector and not a map?

13:34 * rhg135 pats justin_smith, 'you'll get them next time'

13:34 justin_smith: en590: they are ordered and can refer to previous bindings

13:34 en590: also maps only allow keys to happen once, let bindings allow re-binding that shadows a previous key

13:35 ,(let [a 0 b (inc a) b (inc b)] b)

13:35 clojurebot: 2

13:35 justin_smith: there's two reasons that would not work with a hash-map

13:36 en590: ok very neat thank you

13:36 oddcully: ,(inc justin_smith)

13:36 clojurebot: #error {\n :cause "Unable to resolve symbol: justin_smith in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:...

13:36 oddcully: omg

13:36 justin_smith: without the ,

13:36 oddcully: i am so used to that not working...

13:36 (inc justin_smith)

13:36 lazybot: ⇒ 287

13:37 oddcully: yeah i knew, then i forgot

13:37 now i unforgot

13:37 en590: (inc justin_smith)

13:37 lazybot: ⇒ 288

13:38 en590: i love the inc function it is very explicit

13:39 rhg135: Gasp, you passed him

13:39 en590: but yeah justin that was an intense answer it was like perfect

13:40 my mind just expanded

13:40 ely-se: justin_smith: https://ideone.com/c4FGGC

13:40 justin_smith: ely-se: I hope you saw hiredman 's remarks above

13:41 ely-se: oh

13:41 hiredman: cool I'll look at it

13:41 that has no insertion, though

13:43 hiredman: they are clojure datastructures

13:43 ely-se: you can use arbitrary functions as keys, add and remove elements, etc

13:43 hiredman: insertion is indexing a single record or records, and then merge-with into the existing db

13:43 ely-se: s/keys/indices/

13:44 brb; dinner

13:44 hiredman: as written, no, you cannot use arbitrary functions as keys

13:47 en590: How much clojure do I need to get hired as a junior clojure dev?

13:48 and what kind of project would be good to show I know the language decently

13:49 sdegutis: How does reader macros like #db/id[:db.part/db] work?

13:49 Do they expand at compile time?

13:50 justin_smith: sdegutis: get ready to have your mind blown

13:50 sdegutis: I noticed that putting #db/id[:db.part/db] in a loop always resolves to the exact same constant at every interval in the loop.

13:50 justin_smith: sdegutis: they are expanded when reading

13:50 sdegutis: justin_smith: no that can't be it it's too simple and makes too much sense

13:50 rhg135: Lol

13:51 sdegutis: justin_smith++

13:53 en590: how long have you all been clojuring i want to be amazing at this language

13:53 justin_smith: three or four years I think

13:53 sdegutis: en590: You will be amazing at it in 10 years by definition.

13:53 en590: There's a law of physics that says it takes 10 years to be amazing at a thing.

13:53 en590: there is just so much cool stuff I feel like I learn so much with a lisp language

13:54 sdegutis: Also I've probably been doing it 1 day short of justin_smith's duration, I think I started the day after him.

13:54 Which means by definition I'll always know 1 less fact about Clojure than justin_smith.

13:54 en590: What kind of projects did you work on starting out?

13:54 I'm reading a book about the basics but I can't think of anything to actually make

13:54 sdegutis: en590: don't worry the high fades and then you sober up and realize Lisp is really just JavaScript all along.

13:54 justin_smith: en590: I got hired to work on a rapid application development web platform

13:54 sdegutis: justin_smith: wait just like me?

13:55 justin_smith: I guess so? must have been something going around back in 2012 or so?

13:55 sdegutis: justin_smith: does this.. does this mean we're twins?

13:55 justin_smith: soul-mates, surely

13:55 * sdegutis hugs justin_smith

13:55 sdegutis: justin_smith: ok so what's our bank PIN btw

13:56 justin_smith: hunter2

13:56 don't tell anyone

13:56 sdegutis: don't worry it just shows up as ******* to everyone else

13:57 only I can see it cuz soulmates

13:57 rhg135: I thought it'd be justin

13:57 sdegutis: Ah crap, I didn't realize the reader-macro thing means I can't use it in a helper function.

13:57 rhg135: Or your bod

13:57 Dob*

13:57 sdegutis: rhg135: its from a website that had quotes from IRC, its before your time, see IRC was Slack back before there was Slack

13:58 rhg135: sdegutis: tempid is a function

13:58 sdegutis: ah right then I'll just keep using (tempid)

13:58 thanks

13:58 rhg135: Np

13:59 sdegutis: Datomic has changed so much in the last 2.5 years, I need to restructure all my code now to take full advantage of all the new awesomeness.

14:00 Most (if not all) of my helper functions are completely obsoleted by new Datomic features.

14:00 (Although not really "new" anymore.)

14:00 rhg135: I didn't use datomic till last year

14:01 I feel like I wasted my mind's db budget

14:06 en590: ,(def a (fn [] (str "hey"))

14:06 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

14:07 en590: ,((fn [] ("hi")))

14:07 clojurebot: #error {\n :cause "java.lang.String cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.IFn"\n :at [sandbox\$eval47\$fn__48 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox\$eval47\$fn__48 invoke "NO_SOURCE_FILE" 0]\n [sandbox\$eval47 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval47 invoke "NO_SOURCE_FILE...

14:07 en590: why does this not work and I have to put str before the "hi" ?

14:07 is it trying to use "hi" as the function

14:07 akabander: Because there's no function named "hi"

14:08 en590: what if I just wanted to return "hi"

14:08 philth-irssi: remove the parens

14:08 ,((fn [] "hi"))

14:08 clojurebot: "hi"

14:08 philth-irssi: you can't call a string.

14:09 str is a function you can call, with the arg "hi".

14:09 which return "hi"

14:09 en590: yeah thank you

14:09 justin_smith: en590: the misunderstanding here might have been what parens do

14:09 in most languages they group things, in clojure they invoke things

14:09 en590: yah i get it know i think, first element in parens is the function

14:09 justin_smith: right

14:09 philth-irssi: (inc justin_smith)

14:09 lazybot: ⇒ 289

14:10 justin_smith: or a macro, or special form - something you can invoke at least

14:10 snowell: lazybot is back!

14:10 spieden: is there a command line nrepl client with fast startup? (non-jvm)

14:11 thought maybe that's how gretch worked but now i can't find it -- maybe spelling wrong

14:11 justin_smith: spieden: grench

14:11 spieden: ah!

14:11 gratsi

14:11 justin_smith: np

14:15 en590: clojure is like a dream language

14:15 u dont even had to do math you just inc stuff

14:16 ,(inc (inc 0))

14:16 clojurebot: 2

14:16 justin_smith: ,(nth (iterate inc 0) 1000000)

14:16 clojurebot: 1000000

14:17 luxbock: I'm writing a library that wraps a native library via JNA, and to safeguard myself from segfaults I'm keeping track of the state of the native library in an atom, so that my functions can throw if they get passed arguments that are in conflict with the state

14:17 en590: is that lazy iteration or whatever?

14:17 luxbock: now stylistically, I'm wondering if I should create a record for the library, where the field points to the atom

14:17 justin_smith: en590: iterate generates a lazy seq of repeated calls to the first arg, with the second arg as the first input

14:18 luxbock: or if my CLJ side API functions should just be referring to the atom itself

14:18 en590: ,(nth (iterate dec 0) 100)

14:18 clojurebot: -100

14:18 luxbock: like on one hand it feels right that functions that need to make calls to the library should take something (i.e. the record) as their arguments

14:18 but on the other hand it feels a bit silly to have a record that can only ever be instantiated once

14:19 en590: ,(iterate dec 0)

14:19 clojurebot: (0 -1 -2 -3 -4 ...)

14:19 en590: ok i get it

14:20 (iterate count (iterate inc 0))

14:20 ,(iterate count (iterate inc 0))

14:20 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

14:20 en590: haha get heaped java

14:20 justin_smith: en590: a fun example from the other day ##(iterate #(apply map list %) '((a b)(c d)(e f)))

14:20 lazybot: Execution Timed Out!

14:20 justin_smith: hrm

14:21 ,(iterate #(apply map list %) '((a b)(c d)(e f)))

14:21 clojurebot: (((a b) (c d) (e f)) ((a c e) (b d f)) ((a b) (c d) (e f)) ((a c e) (b d f)) ((a b) (c d) (e f)) ...)

14:23 en590: wow apply and map in the same function

14:23 i cant handle that

14:24 rhg135: You soon will

14:25 bja: (partial apply ....) is another good one

14:25 en590: so i'm applying a mapping of the list of the argument in the code above?

14:26 bja: you're taking in a sequence of things you want to turn into a sequence of lists

14:26 * rhg135 begins chanting 'one of us!'

14:27 bja: map is will take from multiple sequences at a higher arity

14:27 en590: so map does the (a b)(c d)(e f) part and apply does the(a c e)(b d f) part?

14:28 bja: so stuff like `(map list (range 3) (range 3))` => '((0 0) (1 1) (2 2))

14:28 yeah

14:28 en590: ,(map '(1 2 3) '(1 2 3))

14:29 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn>

14:29 en590: ,(map list( '(1 2 3) ) '(1 2 3))

14:29 bja: (map f [a1 b1] [a2 b2] [c1 c2]) gives you '((f a1 b1 c1) (f a2 b2 c2))

14:29 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to clojure.lang.IFn"\n :at [sandbox\$eval49 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox\$eval49 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval49 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler ...

14:29 justin_smith: en590: you almost had it, too many parens though

14:29 bja: ,(map list (range 3) (range 3))

14:29 clojurebot: ((0 0) (1 1) (2 2))

14:30 justin_smith: ,(map list '(1 2 3) '(1 2 3)) ; en590

14:30 clojurebot: ((1 1) (2 2) (3 3))

14:30 en590: oh map takes its first argument as another function without any parens ok neat

14:31 ,(apply list '(1 2 3) '(1 2 3))

14:31 clojurebot: ((1 2 3) 1 2 3)

14:31 bja: yeah, map just takes a fn, either one that already exists on one that you specify inline via (fn ...) or #(...)

14:31 sdegutis: rhg135: datomic is excessively cool

14:32 en590: the fundamental rule of all lisp syntax is dead simple: a(b,c,d) = (a b c d), that's it

14:32 en590: now you fully understand all of lisp.

14:32 everything else about lisp is identical to javascript.

14:33 en590: ,(inc 1)

14:33 clojurebot: 2

14:33 en590: ,(inc(1))

14:33 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox\$eval169 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox\$eval169 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval169 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 69...

14:34 sdegutis: en590: (1) is the same as 1() in another language, which makes no sense

14:34 en590: do you understand that?

14:34 akabander: Trying to invoke a literal again?

14:34 en590: yes i get it now

14:34 sdegutis: awesome

14:34 im not joking, thats literally all there is to understanding lisp

14:34 akabander: (map inc '(1 2 3))

14:35 ,(map inc '(1 2 3))

14:35 clojurebot: (2 3 4)

14:35 en590: ,(map list '(1 2 3) '(1 2 3)) ;ok i dont quite get this one

14:35 clojurebot: ((1 1) (2 2) (3 3))

14:36 en590: i understand map with one function argument and one data argument

14:36 but not with one function argument and two data arguments

14:36 justin_smith: en590: with two or more lists, the function will get two or more args

14:36 akabander: With multiple collections, map invokes fn with each element of each list as arguments.

14:36 sdegutis: en590: two data arguments acts like a list-comprehension in python/haskell

14:36 en590: it'll do (list 1 1) then (list 2 2) etc

14:36 akabander: ,(map vec '(1 2 3 4) '("a" "b" "c" "d"))

14:36 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/vec>

14:36 sdegutis: ,(map vector [1 2 3] [:a :b :c])

14:36 clojurebot: ([1 :a] [2 :b] [3 :c])

14:37 akabander: Yeah, thanks

14:37 sdegutis: that should demonstrate it a little clearer

14:37 akabander: That's what I was going for :)

14:37 sdegutis: akabander: oh sorry I didn't mean clearer than what you said

14:37 I meant clearer than '(1 2 3) '(1 2 3)

14:37 akabander: Clearer or not, yours ran :)

14:37 sdegutis: :P

14:38 I often get vec and vector mixed up in #clojure

14:38 akabander: We were both shooting for the same thing, you just aimed better.

14:38 sdegutis: Because in production code I more often use (->> ... (vec))

14:38 en590: ,(map + '(1 2 3) '(1 2 3))

14:38 clojurebot: (2 4 6)

14:38 sdegutis: So it's a habit to go for that one.

14:38 akabander: (Is it too obvious I'm American? :)

14:38 sdegutis: akabander: haha is it that I am?

14:38 en590: ,(apply vector [1 2 3] [:a :b :c])

14:38 clojurebot: [[1 2 3] :a :b :c]

14:38 sdegutis: hold on let me finish my red bull then ill ask again

14:38 en590: apply is different, I try to avoid it as much as possible

14:38 akabander: Next I'll use a football metaphor

14:39 en590: so apply does the entire first argument to the entire second ?

14:39 sdegutis: I wonder...

14:39 akabander: Yeah, I think of apply as "unlisting" the arguments

14:39 justin_smith: en590: apply takes any number of args and the last must be a collection

14:39 sdegutis: ,(reduce str ["this " "is " "a " "sentence."])

14:39 clojurebot: "this is a sentence."

14:39 sdegutis: haha!

14:39 justin_smith: en590: the first arg is used as a function, the rest are taken as args, with every element of the final collection appended

14:40 sdegutis: The only time I've ever needed apply in production code is for (apply = [...])

14:40 Which is totally cheating but meh.

14:40 justin_smith: ,(apply str "hello" [", " "world"])

14:40 clojurebot: "hello, world"

14:40 sdegutis: (I consider any Clojure code that can't be done just as simply in Haskell to be cheating.)

14:40 justin_smith: sdegutis: I use apply when I know what the first arg will be, and want to build a collection for the rest of the args

14:41 sdegutis: justin_smith: got concrete example?

14:41 irctc: hello everyone!

14:41 justin_smith: generalize "first" to "first N" actually

14:41 clojurebot: Gabh mo leithscéal?

14:41 sdegutis: I've used (apply concat ...) a few times, sadly.

14:41 irctc: i have an issue and i was wondering if anyone had a few minutes to help?

14:41 en590: ,(apply + "one plus one is " (+ 1 1))

14:41 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.RT cons "RT.java" 655]\n [clojure.core\$cons__4090 in...

14:41 sdegutis: irctc: you'd have way better chances if you just ask without asking to ask

14:41 irctc: otherwise we're likely to say "no" or something, when otherwise we would have just answered

14:42 justin_smith: sdegutis: anywhere where I would otherwise use partial, but it's an operation I am only doing once, so I just use apply instead

14:42 sdegutis: justin_smith: ahh interesting

14:42 irctc: thank you! so im having an issue compiling uberjars using leiningen v 2.5.1

14:42 justin_smith: en590: + does not work on strings in clojure

14:42 sdegutis: Hmm. I'm using Lein 2.5.2

14:42 Works fine for me. Upgrade I guess.

14:42 Also try `lein clean`.

14:42 irctc: for some reason, when i am using the 'lein run' command, all my dependancies are included properly

14:42 oddcully: also the last argument is no seq

14:42 justin_smith: en590: also the last arg to apply must be a collection

14:43 en590: is there a reason for that?

14:43 akabander: ,(apply str "one plus one is " (+ 1 1))

14:43 irctc: i have both profiles :debug and :uberjar the exact same

14:43 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.RT cons "RT.java" 655]\n [clojure.core\$cons__4090 in...

14:43 sdegutis: justin_smith: also, technically (apply str ...) is faster than (reduce str ...) because of magic.

14:43 I think amalloy_ taught me that.

14:43 justin_smith: sdegutis: not magic, StringBuilder :)

14:43 irctc: There are some external jars that im including in my project that i suspect arent being added to the project

14:43 sdegutis: justin_smith: that's technically magic, i.e. hidden optimizations

14:44 en590: ,(str "hi " (str 5))

14:44 clojurebot: "hi 5"

14:44 justin_smith: en590: that's fine, but the last arg of apply must be a collection

14:44 oddcully: ,(str "hi" 5)

14:44 clojurebot: "hi5"

14:44 sdegutis: ,"hi5"

14:44 clojurebot: "hi5"

14:44 sdegutis: mines shortest what i do i win

14:44 justin_smith: ,(apply str "one plus one is" [(+ 1 1)]) ; en590

14:44 clojurebot: "one plus one is2"

14:44 TEttinger: ,'hi5

14:44 clojurebot: hi5

14:44 irctc: but anywho, when i attempt to compile an uberjar and run the jar that was created, i get an ExceitionInInInitializerError

14:44 and its from a ClassNotFoundExceitpion

14:45 a class that im attempting to use

14:45 but if i use a normal 'lein run' it works perfect

14:45 TEttinger: irctc: interesting.

14:45 what's your project.clj like? can you put it on refheap?

14:45 irctc: or a 'lein with-profile uberjar run' it works as well

14:45 justin_smith: irctc: also, what is the specific class, that might be helpful as a clue

14:46 irctc: yea one moment

14:46 en590: ,(apply + '(1 2 3) '(1 2 3))

14:46 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.core\$_PLUS_ invokeStatic "core.clj" 962]\n [clojure.core\$_PLUS_ do...

14:46 en590: whoops

14:46 TEttinger: ,map + '(1 2 3) '(1 2 3))

14:46 clojurebot: #object[clojure.core\$map 0x57622de3 "clojure.core\$map@57622de3"]

14:46 en590: ,(apply + '(1 2 3) '(1 2 3)))

14:46 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.core\$_PLUS_ invokeStatic "core.clj" 962]\n [clojure.core\$_PLUS_ do...

14:46 TEttinger: ,(map + '(1 2 3) '(1 2 3))

14:46 clojurebot: (2 4 6)

14:46 justin_smith: en590: you can't use + on a list directly

14:46 TEttinger: apply takes only one collection too.

14:47 sdegutis: Pop quiz. Given {:nums [1 1] :words {1 "one", 2 "two"}} derive the string "one plus one is two".

14:47 en590: ,(apply + 5 '(1 2 3)))

14:47 clojurebot: 11

14:47 justin_smith: ,(apply map + [[1 2 3] [1 2 3]]) ; en590 compare this to what TEttinger did

14:47 clojurebot: (2 4 6)

14:47 irctc: So its the RTAClient.jar that isnt getting added

14:47 oddcully: or ,(apply + 1 '(2 3 4))

14:47 TEttinger: irctc: and this jar isn't available on clojars or maven central I imagine?

14:47 irctc: but if i run the project using 'lein run' there are no issues and the libraries classes are accessable and do what they were designed to do

14:48 TEttinger: no its in house

14:48 justin_smith: irctc: I am suspicious about explicitly putting a jar on the classpath via :resource-paths - is this something you generally have success with in uberjars?

14:49 irctc: also i found this, someone else seems to have had the same problem.

14:49 en590: ,(apply map + [[1 2 3] [1 2 3]]) ;could you explain the steps this takes to work?

14:49 clojurebot: (2 4 6)

14:49 justin_smith: irctc: I think the best fix is to use maven or lein to "install" the jars to your local .m2 cache and then add to :dependencies

14:50 irctc: justin_smith: It has worked so far. Im relatively new to clojure. Is there another way i should be including it?

14:50 justin_smith: irctc: the issue is combining this technique with uberjar, I am not confident that it's compatible

14:51 irctc: justin_smith: So there is some technique within leiningen that allows you to "install" a jar into some directory that will allow you to have it be accessable across the entire system? If so, how would i go about doing that?

14:52 TEttinger: yep, that would be mvn install IIRC

14:52 err, jar hm.

14:52 justin_smith: irctc: yeah, lein-localrepo plugin does it

14:52 irctc: there is also a mvn command that will do it

14:52 akabander: en590: I think (apply map + [[1 2 3] [1 2 3]]) is equivalent to (map + [1 2 3] [1 2 3])

14:53 irctc: justin_smith: Thank you so much! ill give it a shot and if it doesnt work ill head back here and let you know how it goes.

14:53 TEttinger: thank you as well! ill look into this.

14:53 TEttinger: ^ that's the mvn command btw, no problem

14:53 akabander: But I'm probably over-simplifying in my naivate

14:53 justin_smith: akabander: it is definitely 100% the same

14:54 akabander: Yay I got one! :)

14:54 en590: so whenever i apply a map i remove the outer layer of vector?

14:54 TEttinger: akabander: they're very similar. one has one more step it does of course, since it calls apply. but behavior is identical

14:54 justin_smith: the only missing part is that (apply map + [1 2 3] [[1 2 3]]) is also the same - apply allows extra args preceding the final coll

14:55 akabander: Ah yes that detail is important, otherwise more complex things could be confusing!

14:56 en590: (reduce + '(1 2))

14:56 TEttinger: en590: apply takes a function and turns the last argument, which should be some kind of collection, from a collection to potentially multiple arguments to the function. like justin_smith is saying, you can have other args before the last one that also get passed to the function, unaltered

14:56 en590: ,(reduce + '(1 2))

14:56 clojurebot: 3

14:56 oddcully: en590: for beginners it might be easer to grok the std case: (apply f [1 2 3]) - this does (f 1 2 3)

14:57 TEttinger: ,(*)

14:57 clojurebot: 1

14:57 TEttinger: ,(apply * [])

14:57 clojurebot: 1

14:57 ely-se: I should find a nice usecase for Clojure.

14:57 Writing software applications for tracking contents of fridges is boring.

14:58 justin_smith: ,(apply * nil)

14:58 clojurebot: 1

14:58 en590: ,(apply + '(1 2 3))

14:58 clojurebot: 6

14:59 en590: ,(map + '(1 2 3))

14:59 clojurebot: (1 2 3)

14:59 oddcully: ,(+ 3)

14:59 clojurebot: 3

14:59 TEttinger: ely-se: probably something that would benefit from, say, futures, lots of data operations at once, maybe java interop too

14:59 en590: cool thank you oddcully

14:59 and justin_smith

14:59 and akabander

15:00 and TEttinger

15:00 snowell: en590: apply will give you a value. map will give you a collection

15:00 TEttinger: map, apply, filter, and reduce are pretty central to daily clojure

15:00 snowell: ,(map inc '(1 2 3))

15:00 clojurebot: (2 3 4)

15:01 akabander: I am learning too; helping you teaches me. :)

15:01 en590: ah oddcully I see so mapping + to '(1 2 3) is just like list((+ 1) (+ 2) (+ 3))

15:02 but the inc actually does something to each one

15:02 justin_smith: en590: move one paren over, but sure :)

15:02 snowell: Well the + does something too. It adds the value to nil ;)

15:02 ely-se: TEttinger: I'd use Go or Erlang or Haskell if I wanted to do concurrency.

15:02 en590: ,(list (+ 1) (+ 2) (+ 3))

15:02 clojurebot: (1 2 3)

15:03 oddcully: ,(+)

15:03 clojurebot: 0

15:03 oddcully: ,(+ 1)

15:03 clojurebot: 1

15:03 oddcully: ,(+ 1 2)

15:03 clojurebot: 3

15:03 en590: (* nil nil)

15:03 ,(* nil nil)

15:03 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [clojure.lang.Numbers ops "Numbers.java" 1013]}]\n :trace\n [[clojure.lang.Numbers ops "Numbers.java" 1013]\n [clojure.lang.Numbers multiply "Numbers.java" 148]\n [sandbox\$eval145 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval145 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.j...

15:03 justin_smith: snowell: it doesn't add to nil though

15:03 en590: ,(+ 1 nil)

15:03 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [clojure.lang.Numbers ops "Numbers.java" 1013]}]\n :trace\n [[clojure.lang.Numbers ops "Numbers.java" 1013]\n [clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.lang.Numbers add "Numbers.java" 3640]\n [sandbox\$eval169 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval169 invoke "NO_SOURCE_FILE" -...

15:03 justin_smith: it's just the arity of + for one arg

15:03 snowell: I thought I might get called on that

15:03 justin_smith: heh

15:03 ,(+ :a)

15:03 clojurebot: #error {\n :cause "Cannot cast clojure.lang.Keyword to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "Cannot cast clojure.lang.Keyword to java.lang.Number"\n :at [java.lang.Class cast "Class.java" 3176]}]\n :trace\n [[java.lang.Class cast "Class.java" 3176]\n [clojure.core\$cast invokeStatic "core.clj" 338]\n [clojure.core\$_PLUS_ invokeStatic "core.clj" 952]\n [c...

15:03 justin_smith: :P

15:04 snowell: ,(* 6)

15:04 clojurebot: 6

15:04 akabander: Ely-se but what if you want good concurrency support and interop with other JVM languages? Please don't say "Scala".

15:04 en590: that multiplies 6 by 1

15:04 oddcully: ,(*)

15:04 clojurebot: 1

15:05 en590: 1 is the idempotentiaionary value of the * operation

15:05 justin_smith: ,(/ 6)

15:05 clojurebot: 1/6

15:05 justin_smith: divides 1 by 6

15:05 snowell: My brain exploded when I saw that word. If that's a real word I'm using it every day from now on

15:05 clojurebot: 0

15:05 akabander: Specifically 1 is the identity cofactor of the multiplication operation

15:05 clojurebot: 1

15:06 akabander: And 0 is the identity cofactor of the addition operation.

15:06 en590: (+ (+) (*) (*))

15:06 ,(+ (+) (*) (*))

15:06 clojurebot: 2

15:06 justin_smith: ,(> 0)

15:06 clojurebot: true

15:06 en590: lol

15:07 akabander: ,(< 0)

15:07 clojurebot: true

15:07 justin_smith: en590: it answers the existential question "is 0 greater than?"

15:07 oddcully: (> 666)

15:07 ,(> 666)

15:07 clojurebot: true

15:07 justin_smith: ,(> :not-even-a-number)

15:07 clojurebot: true

15:08 justin_smith: silliness

15:08 akabander: "(> 0)"... "I'll take late 80s movies for \$100, Alex"

15:08 "(< 0)"... "I'll take late 80s movies for \$100, Alex"

15:08 darn, whiffed it

15:08 oddcully: ,(= 42)

15:08 clojurebot: true

15:08 en590: what the shit

15:08 akabander: ,(== 42)

15:08 clojurebot: true

15:09 en590: unconsionable

15:09 TEttinger: ,(= Double/NaN)

15:09 clojurebot: true

15:09 TEttinger: ,(= Double/NaN Double/NaN)

15:09 clojurebot: false

15:09 akabander: ,(source =)

15:09 oddcully: oh yeah! NaNs arviing. this will be fun

15:10 akabander: But if you look, the definition includes ([x] true)

15:10 So arity one is always true

15:11 en590: how do you prounounce arity irl

15:11 air ity or are ity

15:11 akabander: Rhymes with parity

15:11 TEttinger: ,(let [nan (/ 0.0 0.0)] [(= nan nan) (= nan (/ 0.0 0.0))])

15:11 clojurebot: [false false]

15:11 philth: air-it-tee

15:11 TEttinger: ,(let [nan Double/NaN] [(= nan nan) (= nan (/ 0.0 0.0))])

15:11 clojurebot: [false false]

15:11 TEttinger: ,(let [nan (identity Double/NaN)] [(= nan nan) (= nan (/ 0.0 0.0))])

15:11 clojurebot: [true false]

15:12 TEttinger: who put that true here?

15:12 akabander: Because a always equals a... Read your Ayn Rand.

15:13 opqdonut: TEttinger: I'm intrigued

15:14 TEttinger: opqdonut: it's a quirk of = and NaN's non-equality-to-self

15:14 = does reference equality for objects, and identity returns a Double in this case

15:15 ,(let [nan (identity Double/NaN)] [(= nan nan) (= nan (/ 0.0 0.0)) (== nan nan)])

15:15 clojurebot: [true false false]

15:15 en590: So clojure converts to java then runs in the jvm?

15:15 is that why the error messages are so crazy

15:15 TEttinger: en590, not quite. it does run on the JVM

15:15 it generates the same format that java compiles to

15:15 .class files, what .jar files use

15:16 akabander: ,(= Double/NaN Double/NaN)

15:16 clojurebot: false

15:16 akabander: ,(let [nan Double/NaN] (= nan nan)

15:16 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:16 akabander: ,(let [nan Double/NaN] (= nan nan))

15:16 clojurebot: false

15:16 en590: why do the error messages mention java.lang.Number and stuff

15:17 TEttinger: the error messages are so crazy because yes, it's running between java-library-land, clojure-library-land, and your-clojure-code-land

15:17 ,(type "hello!")

15:17 clojurebot: java.lang.String

15:17 TEttinger: strings are java strings and can be passed off to java no problem

15:17 en590: will they ever fix it so there are no more crazy java stuff

15:17 TEttinger: that's clojurescript :)

15:17 it has crazy JS stuff instead

15:18 en590: yah was about to ask lol

15:18 i much prefer javascript

15:18 it is a much much smaller language right

15:18 TEttinger: ...sorta

15:18 en590: mostly b/c java has tons of libraries ?

15:18 TEttinger: javascript has a lot more oddities at the language level and cross-browser problems

15:18 akabander: But you're better of doing (map? my-thing) than (= (type {}) my-thing)

15:19 en590: yeah i like the javascript oddities

15:19 oddcully: you are the first one then

15:19 TEttinger: yep, if you know javascript you'd find clojurescript rather easy

15:19 en590: it's endearing

15:19 javascript is like little brother who has to support entire internet

15:20 TEttinger: oddcully: heh I like the lua oddities myself. "aww how cute you don't have regexes you have your own little thing that thinks its a regex"

15:20 oddcully: TEttinger: array start with index 1, because that is how we count!

15:20 en590: is clojurescript the exact same syntax as clojure?

15:20 opqdonut: TEttinger: ah, yeah

15:21 snowell: en590: It's not exact, but it's very similar

15:21 en590: it is a superset of clojure for dom stuff?

15:21 TEttinger: there's a subset that works on both, that's cljx right?

15:22 it's sorta its own language, since it has a different runtime. I wouldn't say it's a superset or subset of JVM clojure

15:22 snowell: en590: Clojure: (println "foo"), Cljs: (.log js/console "Foo")

15:22 It also introduces the wonderful mutability of native JS objects if you want it to

15:22 Spoiler alert: You really don't want it to

15:22 TEttinger: ,(.println System/out "foo")

15:23 clojurebot: nil

15:23 en590: what do you mean mutablity of objects? cant you change them in vanilla js already?

15:23 TEttinger: ,(.println System/err "foo")

15:23 clojurebot: nil

15:23 TEttinger: hm

15:23 snowell: TEttinger: I'm sure it's working; you're just getting the return values

15:23 TEttinger: en590: introduces to clojure. clojure has mutable Java objects

15:24 oddcully: ,(doto (java.util.HashMap.) (.put "a" 1))

15:24 clojurebot: {"a" 1}

15:24 en590: why does clojure still allow java crap to be used?

15:24 TEttinger: they're harder to access unintentionally in JVM clojure I think

15:25 because there are a ton of java libs

15:25 and java still performs better on certain tasks by a large margin

15:25 (for loops on multi-dimensional arrays come to mind)

15:25 en590: oh so kind of like using c in certain parts of python programs?

15:26 TEttinger: yeah, if C had a library for pretty much everything

15:26 en590: haha

15:26 snowell: en590: Being able to interact with java systems is not a small thing

15:26 TEttinger: pdfs? there are several java pdf libs, just call into one of those like you're writing java or use/make a wrapper

15:26 akabander: If it wasn't for the easy Java interop, I wouldn't have been able to justify Clojure to management.

15:27 snowell: +1 on that, akabander

15:27 Same with Clojurescript and JS interop

15:27 TEttinger: writing a pdf lib is not a small task, that's something you reallllllly want a lib for if you need it!

15:27 en590_: sorry i d/c

15:28 TEttinger: hey again

15:28 the main reason you want java interop or JS interop is to avoid rewriting non-trivial existing code

15:29 wasamasa: practicality trumps idealism

15:29 TEttinger: we're coders, we need to be practical to get stuff done :)

15:29 akabander: You can always write "pure clojure" if you really want to.

15:32 en590_: yes this makes perfect sense

15:33 it also allows portions of existing java code to slowly be ported to clojure?

15:33 or is a complete rewrite generally done

15:33 TEttinger: more commonly, you write a wrapper

15:33 like seesaw is a good example

15:34 en590_: what is a wrapper

15:34 TEttinger: Swing is a massive part of the java standard lib. it's unpleasant to use from java, much less clojure. https://github.com/daveray/seesaw Seesaw makes it very nice to use from clojure, all the hard work is done

15:35 sdegutis: justin_smith: thanks 4 all ur help in here btw all these years

15:36 TEttinger: seesaw makes it so you don't need the crazy anonymous inner class stuff that the java lib expects for things like event handling. you pass a clojure function and it turns it into what the java expects

15:36 it also adds features that swing doesn't have, like selectors to access classes like they're HTML divs with ids and classes

15:36 *to access widgets

15:36 sdegutis: Speaking of which, how is tbaldridge's port of Clojure going?

15:37 TEttinger: pixie? I think it's past the port stage :)

15:38 en590_: ok thanks for the explanation TEttinger

15:38 sdegutis: TEttinger: meaning it's stable or it's nothing like clojure?

15:40 TEttinger: sdegutis: I don't think it's considered stable yet but is definitely starting to move away from direct port stuff (lib is built around transducers from the start, IIRC)

15:40 sdegutis: oh nice

15:40 i'd love to use that for scripting since fast startup

15:41 TEttinger: I should really get back to my Lua Clojure-like idea

15:42 akabander: Anyone have experience creating "isomorphic" libs for Clojure/Clojurescript?

15:43 TEttinger: there's only a handful of properties that I wish clojure had now and doesn't, and "lightning fast startup time" is totally something that should be feasible on a scripting language VM

15:43 wasamasa: what would that even mean?

15:43 cljc?

15:43 TEttinger: cljx?

15:43 akabander: I don't know what it would look like, I think I saw a project that claims to be a module that can be used by both Clojure and Clojurescript transparently.

15:44 TEttinger: yeah, that's one of the things that's become easier with 1.7

15:44 en590_: shouldn't cljs be the exact same as clojure but minus the java stuff and plus the javascript stuff?

15:44 wasamasa: in an ideal world

15:44 oddcully: TEttinger: there is (was) cljsscript-lua - i tried that some time ago and it did not work

15:45 TEttinger: something salvageable there?

15:45 wasamasa: en590_: in reality there's a number of differences

15:45 TEttinger: maybe! I was going to try using LuaJIT-lang-toolkit

15:45 wasamasa: en590_: like, it not really having a character type

15:45 akabander: wasamasa: I think that's where I should start looking, thanks

15:46 wasamasa: akabander: cljx is a community project, cljc files are the official variant supported in newer clojure releases

15:46 TEttinger: oddcully: this one? https://github.com/raph-amiard/clojurescript-lua

15:47 ah, thanks wasamasa I wasn't clear

15:47 oddcully: TEttinger: i ask, because in some (long time not touched sadly) game stuff i have lua used alot. and the only "repl"-like fealing i had then was beeing able to have glsl shaders to reload

15:47 akabander: cljc yields some interesting results... Church of the Lord Jesus Christ is probably not what I'm looking for.

15:47 wasamasa: akabander: it is shown in the page I've linked

15:47 oddcully: TEttinger: yet seeing the e.g. the grimrock editor had my hopes up, that reloading lua stuff would work too quite reasonable

15:47 akabander: I saw it, just looking around and got a chuckle from the results.

15:48 TEttinger: oddcully: huh, I actually didn't get to the repl part when I worked on my stuff in lua, I could eval lisp strings from lua

15:49 it was uh fast with luajit, despite a really bad interpreter that I screwed up all by myself :)

15:57 bearjack: ,(try (+ "1 2 3") (catch Exception e (.getMessage e)))

15:57 clojurebot: bearjack: I don't understand.

15:57 bearjack: Is anyone up on the magic behind catch?

15:58 I'm just working through simple cases, but when I try to catch an exception for casting one type to another, no problem.

15:58 kwladyka: bearjack, http://clojuredocs.org/clojure.core/catch ?

15:59 i mean what is your problem exactly?

16:00 bearjack: I'm trying to send emails. And I'm testing the exception catching on a machine with no sendmail. So I'm getting a nullpointerexception, but no message returned.

16:00 Even though when I do it in the repl there's a message

16:00 NullPointerException java.lang.ProcessBuilder.start (ProcessBuilder.java:1010)

16:00 I'm just confused by what gets caught and what doesn't.

16:01 kwladyka: bearjack, *testing - do you mean clojure.test or manual try use it?

16:01 bearjack: kwladyka, manually trying to use it in the repl

16:03 kwladyka: bearjack, .getMessage is from Java ( http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html ) so it works the same like in Java

16:03 i am not it is helping you :)

16:04 irctc: hello again!

16:04 bearjack: I don't know much about java, I was hoping to avoid it. oh well, thanks :)

16:06 irctc: once you have used 'lein localrepo' to create a new entry with the jars you want included, how do you tell leiningen to search your local maven? it seems to only be search ing on central and clojuars

16:07 bearjack: irctc, did you use install? that should put it in your local .m2

16:07 irctc: if i run a 'lein localrepo list' i can see that the items have been added

16:07 akabander: exit

16:07 irctc: bearjack: yes i did

16:07 bearjack: what are you trying to achieve?

16:08 justin_smith: irctc: it will always check your local cache first

16:09 irctc: bearjack: i have some local jars that i need to include into my project. before when i added them within :resource-paths, my application worked properly when i did a 'lein run' but when i attempted to create an uberjar, it would state that some dependancies were missing.

16:09 heres what my project.clj looks like now

16:10 i added RTAClient, log4j, and spread using 'lein localrepo install'

16:12 justin_smith: any ideas? im getting an error that states "could not find artifiact in"

16:13 justin_smith: is there some particular directory i should be running the install within? i did it from within my project root.

16:15 justin_smith: irctc: you just need to make sure the install can see the jar you want installed

16:16 irctc: justin_smith: what do you mean by the install? and how can i go about doing that?

16:16 justin_smith: irctc: the command that puts it in your local repo

16:17 whether that's lein localrepo or mvn install or whatever

16:17 irctc: so i did that

16:17 but its saying that it cant be found

16:17 justin_smith: irctc: if you follow a file path mirroring your group/artifact do you find the jar?

16:18 irctc: can i print out the path somehow using localrepo?

16:18 justin_smith: irctc: yes, but it's also a simple transform

16:18 irctc: justin_smith: no idea how to go about doing that

16:19 justin_smith: eg. clojure1.7.jar gets put in .m2/repository/org/clojure/clojure/1.7/clojure-1.7.jar

16:19 since the org/artifact is org.clojure/clojure

16:20 irctc: does .m2 live within the project root repo?

16:20 or within ~/.lein?

16:20 justin_smith: it is in ~

16:20 kwladyka: somebody know any really good example of using macro? example from real world

16:21 i am talking about practical use not technical side

16:22 irctc: yes it is! figured it out though. i guess it was a simple spelling error -_-

16:22 now its time to test if an uberjar gets compiled properly

16:22 bearjack: irctc, good show! that's how I solve all my problems

16:23 irctc: YES

16:23 killed it

16:23 thank you justin_smith. you are a bro

16:24 snowell: (inc justin_smith) ; Being a bro

16:24 lazybot: ⇒ 290

16:26 kwladyka: snowell, in that way i should do something like (def justin_smith (+ 100 justin_smith)) ;)

16:27 snowell: Most of the times he's helped me lazybot has been dead, so I owe him a few myself

16:29 w33t: just btw, this is irctc. gonna stick around for a little while.

16:31 TEttinger: w33t: heh, I guessed it was you from the github username in your project.clj

16:32 kwladyka: a good one is when you have ugly interop and don't want to write it by hand.

16:33 w33t: TEttinger: Yea i really need to get better at hiding my identity. And the user im logged into as on this machine gives you my full name too... im really bad at this whole anonymous thing.

16:44 kwladyka: TEttinger, so when i want use mix of Java and Clojure and it looks like a monster? :)

16:49 TEttinger: kwladyka, that's a definite improvement when you use it though

16:50 the mapcat in the highlighted section and the ~@ before it means you just saved a ton of manual typing :)

16:55 sdegutis: git is one of those things that does its job and does it well and just keeps silently getting better in the background

17:27 sh10151: Any enlive users here? I'm trying to learn it and I can't figure out how to simplify this repetitive code: http://pastebin.com/edFbc4FH

17:27 Basically I have an html "data-key" attribute that I want to match a key in a Clojure map supplying the dynamic data to render

17:28 Seems like there should be a way to generate selector/transformation pairs and apply them all at once without hardcoding specific html attribute names

17:43 en590: hi what is the difference between ["a" "b" "c"] and [:a :b :c] ?

17:44 oddcully: "a" is a string, :a is a keyword

17:44 sdegutis: ,(:a 2)

17:44 clojurebot: nil

17:44 sdegutis: haha silly clojure

17:44 en590: what are keywords used for in vectors or lists

17:44 oddcully: ,(name :a)

17:44 clojurebot: "a"

17:45 sdegutis: ,({:a 2} (:a 2))

17:45 clojurebot: nil

17:45 oddcully: keywords are used as keywords. using it in a vector like this has no relevance

17:45 but keywords can be applied like functions on maps ,(:a {:a 1})

17:46 en590: ok thank you

18:01 sdegutis: ,((:a 2) {:a 2} (:a 2))

18:01 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [sandbox\$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox\$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6943]\n [clojure.lang.Compiler eval "Compiler.java" 6906]\n [clojure.core\$eval invokeStatic "core...

18:01 sdegutis: wait what

18:03 ,(:a {:b 2} 3)

18:03 clojurebot: 3

18:03 sdegutis: ,(:a {:b 2} nil)

18:03 clojurebot: nil

18:03 sdegutis: ,(nil {:b 2} nil)

18:03 clojurebot: #error {\n :cause "Can't call nil"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.IllegalArgumentException\n :message "Can't call nil"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6876]}]\n :t...

18:03 sdegutis: what??

18:03 ,(nil {:b 2})

18:03 clojurebot: #error {\n :cause "Can't call nil"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.IllegalArgumentException\n :message "Can't call nil"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6876]}]\n :t...

18:03 sdegutis: oh

18:03 hahahahaha

18:04 lazybot: sdegutis: What are you, crazy? Of course not!

18:04 sdegutis: lazybot: LAZYBOT< YOURE ALIVE!!!

18:04 ITS REALLY YOU!!

18:07 dxlr8r: man, back to python for scripting some stuff. feels like going back to the stone age :/

18:16 uptown: their stupid tricks are worse than our stupid tricks

18:21 justin_smith: uptown: the real question is which programming community has the best stupid tricks - my bet is on assembler

18:22 the difference is, when you are programming assembler, "stupid tricks" are also known as "programming"

18:22 xemdetia: flat memory model! tricks your boss will /hate/!

18:22 justin_smith: haha

18:25 uptown: of course, but it's messy down there by definition

18:26 eriktjacobsen: or extremely clean :) Always know where every byte of memory is and exactly what instructions are running. Higher level is way messier in that respect. Simple loop might end up invoking thousands of objects and silly subroutines

18:27 There is some comfort in having basically 100% confidence (assuming you understand your system calls) of whats going on

18:29 sdegutis: We are now fully upgraded for Datomic in Production and get to use all the fun new features <3

18:30 xemdetia: eriktjacobsen, I think my favourite thing is going through java trace files

18:31 or finding a jvm stacktrace cut off after 200 lines with 160 trimmed

18:32 uptown: eriktjacobsen: sure, but you only use that perfect knowledge to start abstracting away messy details so you can write in peace

19:12 {blake}: What controls which lein profile is used?

19:13 Ooh. lein/default, huh...

19:17 en590: Hi is it correct to think about maps and sets as unordered, and vectors and lists as ordered?

19:17 jsonp__: unless you're using an ordered set ;)

19:17 {blake}: en590: Yes. Although there are ordered versions of set.

19:20 en590: thank you

19:31 what does \a mean for example

19:31 amalloy: &(class \a)

19:31 lazybot: ⇒ java.lang.Character

19:31 justin_smith: ,(set "hello")

19:31 clojurebot: #{\e \h \l \o}

19:32 en590: neat

19:32 ,(hash-map "hello")

19:32 clojurebot: #error {\n :cause "No value supplied for key: hello"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No value supplied for key: hello"\n :at [clojure.lang.PersistentHashMap create "PersistentHashMap.java" 77]}]\n :trace\n [[clojure.lang.PersistentHashMap create "PersistentHashMap.java" 77]\n [clojure.core\$hash_map invokeStatic "core.clj" 374]\n [clojure.core\$hash_map doInvoke...

19:32 en590: ,(hash-map "hello" "ok")

19:32 clojurebot: {"hello" "ok"}

19:33 en590: ,("hello" {"hello" "ok"})

19:33 clojurebot: #error {\n :cause "java.lang.String cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.IFn"\n :at [sandbox\$eval97 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox\$eval97 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval97 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6...

19:33 en590: ,(:hello {:hello "ok"})

19:33 clojurebot: "ok"

19:33 justin_smith: en590: the special syntax where :key can act as a function is a special thing about :keywords

19:34 en590: the compiler always starts with what's in the calling position to figure out what to do - so even though the arg is a hash-map that doesn't make the string do a lookup

19:34 ,(ifn? :OK)

19:34 clojurebot: true

19:34 justin_smith: ,(ifn? "OK")

19:34 clojurebot: false

19:35 justin_smith: that's the difference - one follows the function interface, the other does not

19:35 en590: ,(let [:a #(+ 1 1)] (:a)

19:35 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

19:35 en590: ,(let [:a #(+ 1 1)] (:a))

19:35 clojurebot: #error {\n :cause "Unsupported binding key: :a"\n :via\n [{:type java.lang.Exception\n :message "Unsupported binding key: :a"\n :at [clojure.core\$destructure invokeStatic "core.clj" 4300]}]\n :trace\n [[clojure.core\$destructure invokeStatic "core.clj" 4300]\n [clojure.core\$let invokeStatic "core.clj" 4312]\n [clojure.core\$let doInvoke "core.clj" -1]\n [clojure.lang.RestFn invoke "RestFn.jav...

19:36 en590: ,(let [:a (#(+ 1 1))] (:a))

19:36 clojurebot: #error {\n :cause "Unsupported binding key: :a"\n :via\n [{:type java.lang.Exception\n :message "Unsupported binding key: :a"\n :at [clojure.core\$destructure invokeStatic "core.clj" 4300]}]\n :trace\n [[clojure.core\$destructure invokeStatic "core.clj" 4300]\n [clojure.core\$let invokeStatic "core.clj" 4312]\n [clojure.core\$let doInvoke "core.clj" -1]\n [clojure.lang.RestFn invoke "RestFn.jav...

19:37 en590: ,(let [:a 2] (:a))

19:37 clojurebot: #error {\n :cause "Unsupported binding key: :a"\n :via\n [{:type java.lang.Exception\n :message "Unsupported binding key: :a"\n :at [clojure.core\$destructure invokeStatic "core.clj" 4300]}]\n :trace\n [[clojure.core\$destructure invokeStatic "core.clj" 4300]\n [clojure.core\$let invokeStatic "core.clj" 4312]\n [clojure.core\$let doInvoke "core.clj" -1]\n [clojure.lang.RestFn invoke "RestFn.jav...

19:38 en590: ,(let ["a" 2] (:a))

19:38 clojurebot: #error {\n :cause "Unsupported binding form: a"\n :via\n [{:type java.lang.Exception\n :message "Unsupported binding form: a"\n :at [clojure.core\$destructure\$pb__4924 invoke "core.clj" 4291]}]\n :trace\n [[clojure.core\$destructure\$pb__4924 invoke "core.clj" 4291]\n [clojure.core\$destructure\$process_entry__4940 invoke "core.clj" 4297]\n [clojure.core\$reduce1 invokeStatic "core.clj" 912]\n [c...

19:38 en590: ,(let [a 2] (:a))

19:38 clojurebot: #error {\n :cause "Wrong number of args passed to keyword: :a"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Wrong number of args passed to keyword: :a"\n :at [clojure.lang.Keyword throwArity "Keyword.java" 97]}]\n :trace\n [[clojure.lang.Keyword throwArity "Keyword.java" 97]\n [clojure.lang.Keyword invoke "Keyword.java" 110]\n [sandbox\$eval303 invokeStatic "NO_SOURCE_FILE"...

19:38 en590: ,(let [a 2] a)

19:38 clojurebot: 2

19:38 en590: yay

19:39 ,(let [:a 2] :a)

19:39 clojurebot: #error {\n :cause "Unsupported binding key: :a"\n :via\n [{:type java.lang.Exception\n :message "Unsupported binding key: :a"\n :at [clojure.core\$destructure invokeStatic "core.clj" 4300]}]\n :trace\n [[clojure.core\$destructure invokeStatic "core.clj" 4300]\n [clojure.core\$let invokeStatic "core.clj" 4312]\n [clojure.core\$let doInvoke "core.clj" -1]\n [clojure.lang.RestFn invoke "RestFn.jav...

19:39 en590: hmm why doesn't this work?

19:42 amalloy: en590: only symbols can be bound to values

19:42 it's like (let [5 2] 5) - 5 is a value, not a name

19:43 likewise :a

19:43 en590: how are keywords values and not names?

19:44 amalloy: well. most stuff in clojure is values

19:45 symbols are values too, but constructs like let and fn allow you to use them as names for locals

19:46 en590: ok neat thank you

21:13 neoncontrails: I'm curious... why is set/union so much slower than brute force in this case? http://pastebin.com/NEZ94hsY

21:13 en590: Hi how do I use seq to check if array is not empty?

21:13 ,(every? seq '(1 2 3))

21:14 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.core\$seq__4116 invokeStatic "core.clj" 137]\n [clojure.co...

21:15 merl1n: ,(seq '(1 2 3))

21:15 clojurebot: (1 2 3)

21:15 merl1n: ,(seq '())

21:15 clojurebot: nil

21:15 merl1n: (I have no idea what I am doing btw)

21:15 neoncontrails: (some? (seq? '(1 2 3)))

21:15 ,(some? (seq? '(1 2 3)))

21:15 clojurebot: true

21:15 en590: I read that seq is how you test if collection is not empty

21:17 neoncontrails: whoops, I made a typo

21:17 ,(some? (seq '(1 2 3))

21:17 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

21:17 neoncontrails: ,(some? (seq '(1 2 3)))

21:17 clojurebot: true

21:18 justin_smith: ,(some? :anything)

21:18 clojurebot: true

21:18 justin_smith: ,(some? even (range))

21:18 clojurebot: #error {\n :cause "Unable to resolve symbol: even in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: even in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: even in this co...

21:18 justin_smith: ,(some? even? (range))

21:18 clojurebot: #error {\n :cause "Wrong number of args (2) passed to: core/some?"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/some?"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [sandbox\$eval214 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval21...

21:18 justin_smith: never mind

21:18 ,(some even? (range))

21:18 clojurebot: true

21:19 justin_smith: that's what I had it confused with

21:22 neoncontrails: Still curious why brute force is significantly more efficient than set/union here... can anyone explain? http://pastebin.com/NEZ94hsY

21:22 en590: how do i check if collection is not empty?

21:22 justin_smith: ,(boolean (not-empty ""))

21:22 clojurebot: false

21:22 justin_smith: ,(boolean (not-empty "a"))

21:22 clojurebot: true

21:22 neoncontrails: also (some? [coll])

21:23 surtn: ,(seq "")

21:23 clojurebot: nil

21:23 surtn: ,(seq {})

21:23 clojurebot: nil

21:24 en590: ah so if i convert anything that's not empty or nil into boolean value...it comes back true?

21:24 ,(boolean 5)

21:24 clojurebot: true

21:24 en590: ,(boolean '())

21:24 clojurebot: true

21:24 en590: =(

21:24 justin_smith: en590: that's why I used not-empty

21:24 ,(boolean (not-empty ()))

21:24 clojurebot: false

21:25 en590: (not-empty '())

21:25 ,(not-empty '())

21:25 clojurebot: nil

21:26 surtn: you genearally don't need to force things to booleans - lots of those functions (like not-empty or seq), return nil or truthy values

21:26 neoncontrails: @en590 I'm just a clojure n00b, but I think (some? [coll]) is a better predicate for that

21:26 ,(some? '())

21:26 clojurebot: true

21:26 justin_smith: ,(some? ())

21:26 clojurebot: true

21:26 neoncontrails: oh wait

21:26 justin_smith: neoncontrails: which is not what you want :)

21:26 neoncontrails: no, nevermind, that's terrible

21:26 haha yes. Good call ;)

21:26 en590: ,(true? '())

21:26 clojurebot: false

21:26 justin_smith: ,(some? [])

21:26 clojurebot: true

21:26 en590: ,(false? '())

21:26 clojurebot: false

21:27 justin_smith: so you definitely want not-empty, and maybe the explicit boolean cast too

21:27 neoncontrails: TIL. Thanks!

21:27 justin_smith: seq has the same consequences, but if what I am testing for is non-emptiness I find that not-empty is quite explicit about that

21:27 en590: ,(boolean (boolean( not-empty ( '())))

21:27 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

21:28 en590: ,(boolean (boolean( not-empty ( '()))))

21:28 clojurebot: #error {\n :cause "clojure.lang.PersistentList\$EmptyList cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList\$EmptyList cannot be cast to clojure.lang.IFn"\n :at [sandbox\$eval263 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox\$eval263 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval263 invoke "NO_SOURCE_FILE" -1]\n ...

21:28 justin_smith: en590: too many () on that

21:28 ,(boolean (not-empty ()))

21:28 clojurebot: false

21:28 en590: ,(boolean (true))

21:28 clojurebot: #error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [sandbox\$eval311 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox\$eval311 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox\$eval311 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.ja...

21:28 justin_smith: en590: remember () is not for grouping!

21:28 and true is not a function

21:29 en590: (boolean true)

21:29 ,(boolean true)

21:29 clojurebot: true

21:29 neoncontrails: So wait. Follow up question: why (not-empty [seq]) instead of (empty? [seq])

21:29 en590: oh yeah thats right

21:29 neoncontrails: ,(empty? '())

21:29 clojurebot: true

21:29 justin_smith: neoncontrails: well if you wanted to test for the opposite condition, sure

21:29 neoncontrails: It seems like the explicit boolean cast would be useful usually, wouldn't it?

21:30 justin_smith: though I guess (not (empty? x)) might be better then (boolean (not-empty x))

21:30 en590: ,(not-empty [1 2 3])

21:30 clojurebot: [1 2 3]

21:30 neoncontrails: (and closer to idiomatic scheme/lisp too in my experience, for what it's worth)

21:30 en590: according to the website it says use seq for the opposite of empty?

21:31 but that isn't explicit and seems like shit

21:31 'Please use the idiom (seq x) rather than (not (empty? x))'

21:32 ,(seq [1 2 3])

21:32 clojurebot: (1 2 3)

21:32 neoncontrails: That's extremely interesting. There must be a reason why (seq x) is preferred, but I don't see one

21:32 merl1n: ,(not (empty? [1 2 3]))

21:32 clojurebot: true

21:33 en590: why isn't there a not-empty?

21:33 merl1n: hmm, how is that the same?

21:33 (empty? [1 2 3])

21:33 ,(empty? [1 2 3])

21:33 clojurebot: false

21:34 surtn: neoncontrails: it's so you can use it once you determine it's not empty

21:34 ,(when-let [stuff [1 2 3]] (reduce + stuff))

21:34 clojurebot: 6

21:34 surtn: ,(when-let [stuff []] (reduce + stuff))

21:34 clojurebot: 0

21:34 merl1n: how is seq opposite of empty when it doesn't return boolean

21:35 neoncontrails: I think this might be a lispy thing. You don't really need the opposite of a boolean predicate, you just (if [pred? seq] #true-case #false-case) to dispatch on the false case

21:36 surtn: seq isn't the opposite of empty? it's just you can use it for that type of thing. Idiom, for sure. There's more than one way to do it.

21:36 neoncontrails: (if (seq '()) 1 2))

21:37 ,(if (seq '()) 1 2))

21:37 clojurebot: 2

21:37 merl1n: (not (empty? ..)) seems more readable though

21:37 surtn: depends what you're used to, I suppose

21:37 en590: sorryi dc

21:38 surtn: (not (empty? c)) will just return a boolean though - not very useful

21:38 merl1n: it is useful if that is what you need

21:38 surtn: ok, sure, say you were writing a predicate function

21:39 why do you check a collection for emptiness though? often it's to do something with that collection.

21:40 en590: ,(if (seq '()) "is true/not empty" "is false/empty, because seq returned nil")

21:40 clojurebot: "is false/empty, because seq returned nil"

21:41 merl1n: ,(filter (comp not empty?) [[1 2] [] [3 4]])

21:41 clojurebot: ([1 2] [3 4])

21:41 en590: ,(if (seq '(1 2 3)) "is true/not empty" "is false/empty, because seq returned nil")

21:41 clojurebot: "is true/not empty"

21:42 TEttinger: ,(filter seq [[1 2] [] [3 4]])

21:42 clojurebot: ([1 2] [3 4])

21:43 merl1n: I think (comp not empty) conveys the intent better

21:43 TEttinger: ,(filter seq [[1 2] 0 [3 4]]) ; fails too

21:43 jeaye: Agreed

21:43 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

21:43 TEttinger: ,(filter (comp not emoty?) [[1 2] 0 [3 4]]) ; fails too

21:43 clojurebot: #error {\n :cause "Unable to resolve symbol: emoty? in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: emoty? in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: emoty? in t...

21:43 neoncontrails: en590: okay got it. Contrast the following:

21:44 TEttinger: ,(filter (comp not empty?) [[1 2] 0 [3 4]])

21:44 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

21:44 TEttinger: hm

21:44 neoncontrails: ,((fn [x] (if (empty? x) (reduce + x))) [1 2 3])

21:44 clojurebot: nil

21:44 neoncontrails: ,((fn [x] (if (empty? x) (reduce + x))) [])

21:44 clojurebot: 0

21:44 TEttinger: interesting

21:44 neoncontrails: ,((fn [y] add1 [x] (if (seq x) (reduce + x))) [1 2 3])

21:45 clojurebot: #error {\n :cause "Unable to resolve symbol: add1 in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: add1 in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: add1 in this co...

21:45 TEttinger: ,((fn [x] (if (empty? x) (reduce #(* %1 %2) x))) [])

21:45 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: sandbox/eval51/fn--52/fn--53"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: sandbox/eval51/fn--52/fn--53"\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" 28]\n [clojure.lang.PersistentVector r...

21:45 TEttinger: need parens around arg grounds, neoncontrails

21:45 arg groups

21:45 neoncontrails: Sorry, this is more confusing. I'll just give you the two defs and you can play with them

21:45 (defn add1 [x] (if (empty? x) (reduce + x)))

21:46 TEttinger: ,(defn add1 [x] (if (empty? x) (reduce + x)))

21:46 TEttinger: you can def here :)

21:46 it lasts 10 minutes or so

21:46 neoncontrails: ,(defn add1-good [x] (if (seq x) (reduce + x)))

21:46 TEttinger: and you may have wanted not empty?

21:46 neoncontrails: ,(defn add1-bad [x] (if (empty? x) (reduce + x)))

21:47 clojurebot: 0

21:47 TEttinger: ,(add1-good [])

21:47 clojurebot: nil

21:47 justin_smith: ,(reduce + nil)

21:47 clojurebot: 0

21:47 justin_smith: ,(reduce * nil)

21:47 clojurebot: 1

21:47 jeaye: seq and empty? are negated here, neoncontrails

21:47 merl1n: is there a comp equivalent that composes functions in reverse?

21:47 en590: mann you guys are so smart

21:47 neoncontrails: jeaye: pardon, can you elaborate?

21:47 en590: i am copy pasting all this code to look over tomorrow morning lol

21:48 TEttinger: ,(defn pmoc [& args] (apply comp (reverse args)))

21:48 clojurebot: #'sandbox/pmoc

21:48 surtn: en590: you shouldn't confuse smart with familiar :)

21:48 TEttinger: ,(filter (pmoc empty? not) [1 2 3])

21:48 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

21:48 TEttinger: ,(filter (pmoc empty? not) [[1 2 3]])

21:48 clojurebot: ([1 2 3])

21:49 TEttinger: I think I screwed up somehwere

21:49 ,(filter (pmoc empty? not) [[1 2 3] [] [1 2]])

21:49 clojurebot: ([1 2 3] [1 2])

21:49 neoncontrails: TEttinger: what's the English translation of 'pmoc'?

21:50 jeaye: comp reversed

21:50 neoncontrails: Okay I don't normally LOL, but... LOL. :)

21:50 Good one, Rich

21:53 TEttinger: I think PMOC is likely one of the many perl-related acronyms, like CPAN

21:53 or perl 6's current GLR (great list refactoring)

21:53 justin_smith: TEttinger: pmoc is for mocking in drug testing scenarios (employee is on drugs? substitute this clean mock)

21:53 neoncontrails: That wouldn't surprise me. Larry Wall is weirdly hilarious

21:54 TEttinger: I think it's kinda entertaining that perl 6 code interleaves normal-looking perl code with stuff like .WHAT and .HOW

21:55 justin_smith: TEttinger: much code .WOW

21:55 TEttinger: but there's some serious brilliance/madness in the unicode handling. that stuff is impressive.

21:55 \c[SIGN OF THE HORNS] is the same as typing in a literal unicode emoji introduced in Unicode standard 8.0. Java 9 will be on Unicode 7.0 next year.

21:57 \c[APOSTROPHE] is the same as an escaped ' but behaves correctly even in misbehaving syntax highlighters

21:57 then again... Visual Studio 2015 is literally incapable of compiling one of the unicode data files that this implementation of perl 6 needs. it stack overflows in the parser.

21:59 neoncontrails: My favorite morsel of perl trivia is this poem

21:59 TEttinger: oh and did you all know that openjdk 9 actually isn't that hard to compile anymore, even on windows?

21:59 it's kinda shocked me

21:59 en590: hey just for fun is there a clearer way to increment all the values of a collection than this:

22:00 ,(map #(inc %) [1 2 3])

22:00 clojurebot: (2 3 4)

22:00 TEttinger: ,(map inc [1 2 3])

22:00 clojurebot: (2 3 4)

22:00 en590: shit lol thank you

22:01 TEttinger: I have several versions of a probably now-outdated openjdk 9 for windows x86 and x64, and yes, it actually does start up faster than java 8

22:01 they're... they're actually doing something good with core java. I'm as stunned as you are.

22:01 after like 5 years on java 6... I had lost all hope

22:03 en590: dang function programming is amazing

22:03 justin_smith: sure is

22:03 en590: after seeing solution to problem it usually seems obvious and in my face lol

22:03 justin_smith: that could mean you are learning

22:03 neoncontrails: That's a really common feeling in FP

22:04 en590: if i can just learn all the core functions i will be unstoppable

22:05 justin_smith: en590: have you looked at http://conj.io ?

22:05 en590: if you can learn that page, and a few libs for your domain... you're going to be pretty much set

22:06 neoncontrails: That's a little easier said than done, I think. Mastery of FP primitives lies in figuring out how to compose them, which takes a helluvalot of practice

22:06 (this is my own personal opinion)

22:07 en590: i like this page it has a good ui

22:07 thank u justin_smith

22:08 justin_smith: en590: the page was made by our friend arrdem

22:08 (inc arrdem)

22:08 lazybot: ⇒ 46

22:09 neoncontrails: heh

22:09 (arrdem)

22:09 ,(arrdem)

22:09 clojurebot: #error {\n :cause "Unable to resolve symbol: arrdem in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: arrdem in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: arrdem in t...

22:09 neoncontrails: ,arrdem

22:09 clojurebot: #error {\n :cause "Unable to resolve symbol: arrdem in this context"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: arrdem in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: arrdem in t...

22:10 justin_smith: neoncontrails: it's a pseudo-syntax for lazybot

22:10 (identity arrdem)

22:10 lazybot: arrdem has karma 46.

22:10 justin_smith: (identity justin_smith)

22:10 lazybot: justin_smith has karma 290.

22:10 justin_smith: (identity amalloy)

22:10 lazybot: amalloy has karma 294.

22:10 en590: (identify en590)

22:10 neoncontrails: Haha, I'm liking this community more and more.

22:10 justin_smith: en590: it's identity

22:11 en590: (identity eno789)

22:11 lazybot: eno789 has karma 0.

22:11 neoncontrails: (inc eno789)

22:11 lazybot: ⇒ 1

22:12 en590: (inc eno789)

22:12 lazybot: ⇒ 2

22:14 en590: all is right in the world now ok thank you everyone cya

22:15 * arrdem appears in a puf of smoke

22:16 justin_smith: arrdem: we were admiring your work

22:16 arrdem: yes yes but you were admiring the WRONG WORK

22:16 * arrdem pouts about strictly tagged clojure

22:16 justin_smith: is this a thing we can all use?

22:16 arrdem: if you want to deal with skummet

22:17 I need to start my own clojure fork with just that change

22:17 neoncontrails: arrdem: what's the case for using a strictly-tagged subset of Clojure versus, say, Haskell?

22:18 arrdem: neoncontrails: strictly tagged clojure is just a compilation mode for better interop performance, it isn't a real type system like Haskell.

22:19 neoncontrails: Ooh, that makes sense. Got it.

22:19 justin_smith: arrdem: so tl;dr I can use strictly tagged clojure and that would mean writing less of my perf-critical code in java?

22:19 arrdem: justin_smith: that was the idea

22:19 justin_smith: v. cool

22:23 TEttinger: I personally don't mind writing perf-critical code in java. it gives me a chance to be stupid and still program

22:23 neoncontrails: Random question, is there a Clojure analog of Java's abstract classes? (e.g. "abstract class Foo { ... }")

22:24 TEttinger: "hm, I could rewrite this ridiculous loop to use multiple functions... nah, labeled break/continue should be fine and this 200 line loop should do A-OK"

22:24 neoncontrails: I learned Java immediately after SICP, and I could never figure out how abstract classes related to anything I was familiar with from Scheme

22:25 TEttinger: there's protocols, which correspond to interfaces I suppose

22:25 I have never honestly written a protocol

22:25 arrdem: protocols are pretty neat

22:34 A little late, but wrt writing Java for perf, Clojure interop is already practically Java in sexprs so I don't personally see a compelling reason to use a different tool when we have all the same type information available

22:37 TEttinger: arrdem: I'm not entirely sure why, but some of the algorithms that I have written in both clojure and java seem to have significant perf differences. the type of algorithm is 2d-array-based, using primitive doubles

22:37 it's possible clojure has caught up now

22:38 (it's still kinda annoying to need type hints everywhere and need to avoid local assignment to avoid boxing)

22:38 arrdem: TEttinger: with amalloy and my strictly tagged changes, strictly hinted Clojure code should almost be byte for byte the same as Java implementations.

22:39 is it planned for 1.8 in however many years?

22:39 arrdem: well 1.8 is supposed to be this fall or something

22:39 but no we've gotten no "this is release candidate material" or otherwise feedback.

22:40 neoncontrails: Speaking of efficiency/imperative interop

22:40 (defn answer2 [maxrange]

22:40 (reduce + (filter #(or (zero? (mod % 3))

22:40 (zero? (mod % 5)))

22:40 (range maxrange))))

22:40 err

22:40 arrdem: neoncontrails: STOP PASTING USE REFHEEAP

22:41 *refheap.com

22:41 neoncontrails: OKAY SORRY

22:41 arrdem: sorry for caps, wanted to catch you before you retried :P

22:41 we have an ad-hoc one line paste limit around here

22:41 scriptor: fizzbuzz?

22:41 neoncontrails: https://www.refheap.com/108694

22:42 Ehh, kinda. Project Euler #1

22:42 Which is basically fizzbuzz, but with an added reduce() step

22:43 I'm curious, did I goof something in my answer3 defn, or is set/union actually a lot slower than brute forcing it?

22:46 TEttinger: ,(let [maxrange 100] (reduce + (distinct (concat (range 3 maxrange 3) (range 5 maxrange 5)))))

22:46 clojurebot: 2318

22:46 neoncontrails: Anecdotally, I've noticed set/union in Python is approximately an order of magnitude faster than reducing a filtered generator

22:47 TEttinger: ,(let [maxrange 1000] (reduce + (distinct (concat (range 3 maxrange 3) (range 5 maxrange 5)))))

22:47 clojurebot: 233168

22:47 neoncontrails: Oh wow, that's costly

22:48 ,(time (let [maxrange 1000] (reduce + (distinct (concat (range 3 maxrange 3) (range 5 maxrange 5))))))

22:48 clojurebot: "Elapsed time: 23.881238 msecs"\n233168

22:48 TEttinger: ,(let [maxrange 1000] (reduce + (distinct (into [] (range 3 maxrange 3) (range 5 maxrange 5)))))

22:48 clojurebot: #error {\n :cause "clojure.lang.LongRange cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.LongRange cannot be cast to clojure.lang.IFn"\n :at [clojure.core\$transduce invokeStatic "core.clj" 6575]}]\n :trace\n [[clojure.core\$transduce invokeStatic "core.clj" 6575]\n [clojure.core\$into invokeStatic "core.clj" 6591]\n [clojure.core\$into...

22:48 TEttinger: ,(let [maxrange 1000] (reduce + (distinct (into (range 3 maxrange 3) (range 5 maxrange 5)))))

22:48 clojurebot: 233168

22:48 TEttinger: ,(time (let [maxrange 1000] (reduce + (distinct (into (range 3 maxrange 3) (range 5 maxrange 5))))))

22:48 clojurebot: "Elapsed time: 24.208726 msecs"\n233168

22:48 neoncontrails: ,(defn answer3 [maxrange] (reduce + (cs/union (set (range 3 maxrange 3)) (set (range 5 maxrange 5)))))

22:48 clojurebot: #error {\n :cause "No such namespace: cs"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.RuntimeException: No such namespace: cs, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "No such namespace: cs"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n :tr...

22:48 TEttinger: ha slower

22:49 need to type it out or require here, not sure if require works

22:49 neoncontrails: ,(defn answer3 [maxrange] (reduce + (clojure.set/union (set (range 3 maxrange 3)) (set (range 5 maxrange 5)))))

22:49 clojurebot: #error {\n :cause "clojure.set"\n :via\n [{:type clojure.lang.Compiler\$CompilerException\n :message "java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.ClassNotFoundException\n :message "clojure.set"\n :at [java.net.URLClassLoader\$1 run "URLClassLoader.java" 366]}]\n :trace\n [[ja...

22:49 neoncontrails: nevermind, I'll REPL it

22:50 TEttinger: ,(require 'clojure.set)

22:50 clojurebot: nil

22:50 TEttinger: ,(defn answer3 [maxrange] (reduce + (clojure.set/union (set (range 3 maxrange 3)) (set (range 5 maxrange 5)))))

22:50 TEttinger: ,(answer3 1000)

22:50 clojurebot: 233168

22:50 TEttinger: ,(time (answer3 1000))

22:50 clojurebot: "Elapsed time: 3.914105 msecs"\n233168

22:50 TEttinger: woah

22:50 neoncontrails: Okay yeah, wow

22:50 TEttinger: this also depends on the JIT

22:51 which is very hard to measure

22:51 we've definitely hit the JIT compiler limit for some of range's internal stuff

22:51 neoncontrails: My local test says it's about an order of magnitude slower (4.29ms vs. 0.49ms)

22:51 TEttinger: it's possible the range just is getting JITed now

22:52 ,(time (let [maxrange 1000] (reduce + (distinct (into (range 3 maxrange 3) (range 5 maxrange 5))))))

22:52 clojurebot: "Elapsed time: 13.266595 msecs"\n233168

22:52 TEttinger: yep

22:52 remember that was 24 earlier?

22:52 welcome to JVM benchmarking crazyland

22:52 neoncontrails: Interesting

22:53 The question in my mind remains, so, this appears to be comparable to the brute-force solution, efficiency-wise

22:53 TEttinger: the JIT is top-notch for long-running functions, but microbenchmarks are very hard to predict

22:53 neoncontrails: why is it not faster?

22:57 camm_v222: Hi guys, I want to create an app on Clojure for Android, but I have a few problems trying to download Android SDK (for Fedora GNU/Linux). I can't download the SDK!!! I know it sounds silly but I just get on a loop trying to download it from here ( https://developer.android.com/intl/zh-cn/sdk/installing/index.html?pkg=tools ). May you help me, please?

23:02 TEttinger: camm_v222: just curious, are you intentionally downloading the chinese version, and could there be uh blockage issues?

23:04 camm_v222: there's some link confusion on their site. https://developer.android.com/intl/zh-cn/sdk/index.html#Other

23:08 camm_v222: TEttinger Yeah, I see, and I don't know what to do. It's the only official page that I've found to download the Android SDK.

23:09 TEttinger: I wonder if Fedora has it in a non-free repo

23:09 or even a free repo

23:10 camm_v222: Well, I'm going to search a repo for Fedora, it's my last chance. Thanks TEttinger.

23:11 TEttinger: hm not quite actually

23:11 I'm downloading it and I think I may be able to host the (large) archive somewhere, like mega or some other large-file host

23:14 arrdem: would be happy to host shasums or something else

23:46 andyf: I'm using some low-level library that shows details of memory layout inside of Java objects, and can also return the current address of a Java object. I know Java objects can be moved during garbage collection, but I'm seeing evidence that either (a) when you use the -XX:+PrintGCDetails command line option to Oracle's JVM, it doesn't print every time a GC occurs, or (b) objects can move even when no GC has occurred. Anyone have an

23:47 That is really a more Java-specific rather than Clojure-specific question, but the context is that I'm working on some utilities in Clojure to help calculate the size in memory of data structures.

23:49 TEttinger: your question cut off, andyf

23:49 ...no GC has occurred. Anyone have an <cut off>

23:49 andyf, this sounds very useful btw

23:50 andyf: Sorry, that was long. Ending was "Anyone have any knowledge of this?"

23:51 justin_smith: andyf: is hotspot allowed to move data around?

23:51 andyf: It scratches an itch of mine. Path-copying in immutable data structures is useful, but it is nice to be able to quantify "how much sharing usually happens between x and (conj x y), or between my-map and (assoc my-map x y)?"

23:52 justin_smith: Any time there is a compacting garbage collector involved, data can move during a collection. And that is the default for most JVMs, I think.

23:52 It is invisible to any program running on the JVM, as long as you don't use some unsafe method to peek at the addresses.

23:52 justin_smith: andyf: I mean the optimization process, aside from gc

23:53 I understand the concept of compacting gc, yes

23:53 andyf: justin_smith: Not sure I understand your question, then. Do you mean: is hotspot allowed to reformat the internals of instances of a particular class while it is running?

23:54 justin_smith: andyf: I could imagine an optimizer that says "these things in the heap will be used near each other, we can help cache performance by putting them near each other"

23:54 andyf: this would move things while gc is not occuring, is why I ask

23:55 andyf: justin_smith: I'm not aware of anything like that done intentionally by any existing GCs. Compacting collectors may end up doing that by accident, or by the fact that objects allocated near each other in time might be more likely to have references to each other.

23:55 justin_smith: andyf: I am not talking about the gc, I am talking about the hotspot optimizer

23:56 andyf: you said "things moved when gc did not occur"

23:56 I suggested another reason a thing might move in the heap (hypothetically)

23:57 andyf: justin_smith: Got your meaning now. I've not heard of such a feature.

23:58 justin_smith: andyf: OK. IIRC this is one of the big optimization features OCaml uses. I find OCaml interesting because their optimizations are powerful while not being very clever (contrast Haskell)

23:59 TEttinger: might also be useful to check every java version you can to see how they perform differently, once you get this working

Logging service provided by n01se.net