2015-08-24
| 02:31 | amalloy | TEttinger: j.u.regex.Pattern/quote |
| 02:31 | TEttinger | (inc amalloy) |
| 02:31 | lazybot | ⇒ 294 |
| 02:44 | Kneiva | Yay, lazybot is back. |
| 03: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. |
| 03:29 | oddcully | ,(let [there? #{0 3 9}] (map there? (range 10)) |
| 03:29 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 03:29 | oddcully | oho |
| 03:30 | oddcully | ,(let [there? #{0 3 9}] (map there? (range 10))) |
| 03:30 | clojurebot | (0 nil nil 3 nil ...) |
| 03:30 | opqdonut | nice |
| 03:32 | deg | But, my input is potentially infinite. |
| 03:33 | opqdonut | then you need to type out the recursive lazy-seq definition yourself |
| 03:34 | deg | I'm not sure what you mean. |
| 03:35 | deg | 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. |
| 03: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))))) |
| 03:36 | opqdonut | you recursively define a lazy seqnence |
| 03:36 | opqdonut | 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) |
| 03:37 | opqdonut | in general the functional equivalent of a loop that has variables x, y, z is a recursive function with arguments x, y, z |
| 03:37 | deg | Thanks. I need to wrap my head around that for a minute, but it looks good. |
| 03:37 | opqdonut | and returning a lazy sequence corresponds to an imperative generator (e.g. using python's yield) |
| 03:38 | opqdonut | just indent the code nicely and it should be fairly obvious |
| 03:38 | opqdonut | "inds" is the list of indexes for 1s, "ind" is the current index we're at |
| 03:38 | gilliard | opqdonut: nice. |
| 03: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 |
| 03:40 | opqdonut | code would probably be more efficient if one used repeat and concat instead of cons |
| 03: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? |
| 03:41 | opqdonut | yep |
| 03:42 | opqdonut | hmm |
| 03:42 | deg | Yup. For my purposes, that extra efficiency is not needed, and would probably make the code less readable. But, point taken. |
| 03:44 | opqdonut | btw here's one more approach: |
| 03:44 | opqdonut | ,(let [inds [0 3 4 9] intervals (map - (rest inds) inds)] (mapcat #(cons 1 (repeat (dec %) 0)) intervals)) |
| 03:44 | clojurebot | (1 0 0 1 1 ...) |
| 03:45 | opqdonut | needs some additional code to take care of the position of the first 1 |
| 03: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. |
| 03: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 |
| 03: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. |
| 03:51 | deg | What would you say is the community consensus for which approach is more idiomatic? |
| 04:54 | ely-se | do people actually use core.typed? |
| 05:08 | vijaykiran | ely-se: I didn't see enough usage in the wild |
| 05:12 | ely-se | "Type Error (saftcof/fridge.clj:24:4) Unannotated var clojure.core/update" |
| 05:12 | ely-se | bleh |
| 05:15 | TEttinger | ely-se: is it updated to clojure 1.7? |
| 05:15 | ely-se | update-in gives a similar error anyway :p |
| 05:18 | ely-se | https://github.com/clojure/core.typed/wiki/clojure.core-Annotations |
| 05:19 | ely-se | yes, rewriting it to use assoc works |
| 05:22 | ely-se | ugly but worth it |
| 05:33 | ely-se | it already caught a bug I just wrote :p |
| 05:51 | newpm | Hello |
| 05:57 | newpm | 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 |
| 05:57 | newpm | , 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? |
| 05: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... |
| 05:59 | TEttinger | newpm: clojure's a good very-different kind of language |
| 06: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. |
| 06: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 |
| 06:00 | newpm | I just don't want it to be TOO removed from what my team does and thinks in terms of programming philosophy |
| 06:00 | TEttinger | yeah if you're on the JVM, Clojure has great integration |
| 06: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 |
| 06:01 | tdammers | if you're looking for an easier transition, I hear people use Scala with some success |
| 06:01 | TEttinger | ,(doto (java.util.TreeMap.) (.put "a" 1) (.put 8 "b")) |
| 06: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... |
| 06:01 | tdammers | it's not as nice from a FP point of view, but the transition can be a little less painful |
| 06:02 | TEttinger | ,(doto (java.util.TreeMap.) (.put "a" 1) (.put "b" 8)) |
| 06:02 | clojurebot | {"a" 1, "b" 8} |
| 06:02 | TEttinger | huh, it is statically typed even with erasure |
| 06:02 | TEttinger | I'm not a huge fan of scala |
| 06:03 | tdammers | me neither, but I've heard success stories of people getting it into shops that were previously deeply rooted in Java |
| 06:03 | gilliard | TEttinger: Because the treemap is trying to sort its keys and long.compareTo(string) doesn't work. |
| 06:03 | tdammers | something like clojure or, gasp, Haskell, wouldn't have flown |
| 06: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 |
| 06:04 | TEttinger | (in scala) |
| 06:04 | tdammers | in all fairness, if you want IDE integration, it's near impossible to beat Java |
| 06:05 | TEttinger | did you mean C#, the language that is borderline unusable without VS? :P |
| 06:05 | jeaye | Who says so? |
| 06:05 | TEttinger | there is XS and monodevelop now |
| 06:05 | TEttinger | but it's such a huge difference working with large files in VS |
| 06:06 | TEttinger | jeaye: if you wanted to find all usages in a C# project in vim? |
| 06:06 | TEttinger | all usages of a particular method overload |
| 06:06 | jeaye | Yup, can do. |
| 06:06 | TEttinger | how? |
| 06: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 |
| 06:06 | clojurebot | with style and grace |
| 06:07 | TEttinger | in VS that's ctrl-k r |
| 06:07 | newpm | That is another additional overhead i would like to ideally avoid - learning ohw to use vim or emacs :) |
| 06:08 | TEttinger | clojure works well with IntelliJ IDEA's Cursive plugin |
| 06:08 | TEttinger | your team may want to use Eclipse or IntelliJ |
| 06:08 | jeaye | TEttinger: You're familiar with vim, I hope; it has a _very_ extensive plugin community with thousands of plugins across many languages. |
| 06:09 | jeaye | 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. |
| 06:09 | TEttinger | I don't know what those plugins do or if any will, say, erase my file if I press the wrong key |
| 06:09 | jeaye | hah |
| 06:09 | jeaye | 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. |
| 06:10 | jeaye | Or misinformed, anyway. |
| 06:10 | ely-se | I already love core.typed. |
| 06:10 | TEttinger | does it have breakpoint debugging for C#? |
| 06:10 | TEttinger | does it have breakpoint debugging for Clojure? |
| 06:10 | ely-se | I hope it won't turn out to be a disaster. |
| 06:10 | oddcully | TEttinger: who say, that cursive is not raining nukes on some country while you type? |
| 06:11 | TEttinger | as long as it's like murderer alley, sure cursive go right ahead |
| 06:11 | ely-se | TEttinger: can it handle Unix line endings? |
| 06:12 | TEttinger | I think VS can. I've never encountered issues with that outside of the stupidest programs like notepad |
| 06: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). |
| 06:14 | jeaye | I've enjoyed using it for CL work, anyway. |
| 06:14 | TEttinger | ah ok |
| 06:14 | newpm | thanks everyone! |
| 06: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. |
| 06: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 |
| 06:56 | cfleming | oddcully: I know, my response was a joke too :-) |
| 06:58 | cfleming | 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. |
| 06:58 | oddcully | what if the server with the issue tracker is the target of the nuke? |
| 07:01 | cfleming | That would be sneaky. I'm not sure if Github issues are adequately distributed. |
| 07: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 ? |
| 07:19 | kwladyka | pseudonymous, use (require 'namespace :reload-all) |
| 07:19 | kwladyka | pseudonymous, and (namespace/foo ...) or (use namespace) if you preffer |
| 07:31 | the-kenny | There is no support for :pre and :post in `defprotocol', right? |
| 07:31 | the-kenny | I would like to add some constraints to protocol functions, applying to *all* implementations. |
| 08: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 :) |
| 08:04 | SigmundL | hmm slack group too? lot's of messaging apps now :-) |
| 08: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. |
| 08:09 | kwladyka | Anyway where can i share article like this about Clojure? |
| 08:10 | kwladyka | pseudonymous, for me my solution is much more comfortable, but i also started with in-ns at first day in REPL ;) |
| 08:10 | kwladyka | especially intellij remember history of commands and you can easy run them again when you open your project. It is much more usability then. |
| 08:24 | shrayasr | Hello everyone |
| 08:24 | shrayasr | I'm having a little problem understanding and taming timestamps |
| 08:24 | shrayasr | is anyone around to help? |
| 08:24 | shrayasr | (i'm using clj-time) |
| 08:25 | oddcully | ~ask |
| 08:25 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 08:27 | shrayasr | the server i'm hosting on is in the GMT timezone. |
| 08:27 | shrayasr | but I want to store timestamps in another timezone (Say X) |
| 08:27 | shrayasr | I'm able to get the string representation of the timestamp in the "X" timezone |
| 08:28 | shrayasr | But to insert into the DB (regular jdbc) |
| 08:28 | shrayasr | I need it to be in the "timestamp" type |
| 08:29 | shrayasr | which I can get via the clj-time.coerce/to-sql-time function |
| 08:29 | shrayasr | But then the coerce/to-sql-time function doesn't take the time zone into consideration |
| 08:29 | shrayasr | Sooooo. I'm stuck |
| 08:30 | the-kenny | Let me check how I handled it |
| 08:30 | shrayasr | Sounds great, thanks @the-kenny |
| 08:32 | shrayasr | I see that we can start the JVM with a specified timezone, Any reason I *shouldn't* be doing this? |
| 08:32 | shrayasr | I assume if I do this, then it is straightforward for me |
| 08: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 |
| 08:34 | the-kenny | I'm quite sure I have a snippet which does some more (by manually creating the value with `ISQLParameter') |
| 08:35 | the-kenny | That might have been postgres-specific though |
| 08:39 | the-kenny | 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" |
| 08:40 | the-kenny | as seen here: http://www.postgresql.org/docs/9.1/static/datatype-datetime.html#AEN5777 |
| 08:44 | en590 | clojure! |
| 08:50 | gfrederi` | clojure! |
| 08:59 | dstockton | clojure! |
| 08:59 | snowell | clojure? |
| 08:59 | clojurebot | clojure is a language to use if you want to up your game |
| 08:59 | en590 | well that's exactly what I want to do |
| 09:00 | en590 | i've found two books that look good to learn it, 'living clojure' and 'clojure in action 2nd edition' |
| 09:00 | en590 | are these good |
| 09: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* |
| 09:05 | en590_ | sorry i d/c |
| 09:17 | en590_ | I'm on linux what environment do you all use to develop in? |
| 09:17 | en590_ | like ide or whatever |
| 09: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. |
| 09:19 | schmir | en590_: I'm using emacs, but that may be a bit too hard when you're learning clojure at the same time. |
| 09:19 | schmir | emacs with cider |
| 09:20 | akabander | I'm on Linux and OS X, our target platform is Linux-y though. |
| 09:31 | kwladyka | en590_, i also recommend intellij |
| 09:31 | kwladyka | with own shortcuts i super great |
| 09:31 | snowell | I use Light Table, FWIW |
| 09:32 | kwladyka | light table is crap unfortunately, it has so big potential but if i know author abandon project to care about new one |
| 09:32 | kwladyka | and for today light table doesn't work enough good for me |
| 09:34 | snowell | I tried getting IntelliJ/Cursive set up once and hit problems |
| 09:35 | snowell | I'm not against trying it again... |
| 09:35 | cfleming | snowell: Let me know if you have problems, I'm always interested in trying to make it easier. |
| 09: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. |
| 09: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) |
| 09:38 | akabander | cfleming: I gather you work on Cursive? The pages are pretty coy about who the author(s) are. |
| 09:38 | cfleming | akabander: I do - I'm the only developer. |
| 09:39 | akabander | Oh, well... Thanks for your efforts, it's a terrific plugin and makes my days pretty pleasant! |
| 09:39 | cfleming | Thanks! That's always good to hear. |
| 09:43 | kwladyka | snowell, what kind of problems? |
| 09:44 | snowell | I don't really remember. I'm actually trying it again atm |
| 09:45 | cfleming | snowell: Cool, I'll be around for a couple of hours if you're having issues. |
| 09:46 | snowell | It may have been as dumb as Light Table's rainbow parens were brighter |
| 09:46 | snowell | I am a fickle man :) |
| 09:47 | cfleming | Fortunately I recently changed Cursive's rainbow parens to be quite garish :-) |
| 09: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 |
| 09: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? |
| 09:49 | kwladyka | if you want use intellij cursive i strongly recommend shortcut for slurp forward and barf forwards |
| 09:50 | akabander | I get weird looks when I ask people if their editor can slurp and barf. |
| 09:50 | snowell | I'm unfamiliar with barf |
| 09:50 | snowell | I thought it was spit |
| 09:50 | akabander | I think it's the same thing but harder to confuse with split |
| 09:51 | cfleming | They're two different things. Slurp/Barf refer to paredit (structural editing) and slurp/spit are functions for reading/creating files. |
| 09:51 | akabander | #dadjokefail |
| 09:51 | cfleming | Ba-doom-*tschhh* |
| 09: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 |
| 09:58 | snowell | I'll keep using it and report back on its awesomeness |
| 09:58 | cfleming | I also accept reports on non-awesomeness :) |
| 09:58 | cfleming | Are you able to show me your project.clj? |
| 09:58 | snowell | Probably not, though I did just submit a report through the IDE |
| 09:59 | snowell | It's just (let [blah blah] (defproject normal "stuff")) |
| 09: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 | en590_ | clojure is 1 of the most beautiful languages ive seen |
| 10:18 | en590_ | 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 | cfleming | 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 | jeaye | Quite a few. |
| 10:26 | justin_smith | yes, I'm a full time clojure dev, there are many others around here |
| 10:27 | justin_smith | 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 | snowell | 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 | arkh | 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 | en590_ | 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 | en590_ | 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 | en590_ | 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 | cfleming | When it's run in-process, I mean. |
| 10:42 | cfleming | 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 | snowell | 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 | cfleming | 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 | justin_smith | en590: cons is what conj ends up invoking for lists (you'll notice that conj on vectors behaves differently) |
| 12:14 | justin_smith | 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 | justin_smith | 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 | en590 | this has happened in hexchat and also quassel irc |
| 12:27 | philth-irssi | en590, probably a client setting. |
| 12:27 | philth-irssi | iirc, x-chat had a "Number of reconnet attempts" option. |
| 12:28 | philth-irssi | don't know about hexchat or quassel tho' |
| 12:31 | en590 | ok idisabled ping timeout stuff |
| 12:31 | en590 | maybe it works |
| 12:32 | en590 | 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 | en590 | i expected opposite behavior |
| 12:35 | ely-se | please no :( |
| 12:35 | ely-se | 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:37 | philth-irssi | wtf? |
| 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 | oddcully | (= 1N 1) |
| 12:39 | oddcully | erm |
| 12:39 | oddcully | ,(= 1N 1) |
| 12:39 | clojurebot | true |
| 12:39 | philth-irssi | Stop this madness. |
| 12:39 | oddcully | ,(= 1M 1) |
| 12:39 | clojurebot | false |
| 12:39 | philth-irssi | bigints are ints? |
| 12:40 | philth-irssi | , (type 1M) |
| 12:40 | clojurebot | java.math.BigDecimal |
| 12:40 | philth-irssi | Ooh |
| 12:41 | philth-irssi | (= (type 1) (type 1N)) |
| 12:41 | philth-irssi | ,(= (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 | en590 | i got the error ClassNotFoundException clojure.set java.net.URLClassLoader$1.run (URLClassLoader.java:366) |
| 12:47 | en590 | 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 | philth-irssi | ffs |
| 12:49 | philth-irssi | anyways it works in real repl. |
| 12:49 | philth-irssi | ,(do (require 'clojure.set) (clojure.set/union #{"a"} #{"b"}) ) |
| 12:49 | clojurebot | #{"a" "b"} |
| 12:49 | philth-irssi | Ah-ha! |
| 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 | iwo | I was imagining just something like: {:f s/Fn} |
| 12:54 | iwo | (i.e. map must have a key :f with a value that's a function) |
| 12:54 | rhg135 | (s/=>...) |
| 12:55 | rhg135 | 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 | iwo | 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 | 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 | philth-irssi | Aw |
| 13:01 | ely-se | her :p |
| 13:01 | rhg135 | I'm a he :-P |
| 13:02 | rhg135 | Ambiguity |
| 13:02 | philth-irssi | What do they sandbox clojurebot with? |
| 13:03 | rhg135 | Jvm sandboxing iirc |
| 13:03 | ely-se | oooh |
| 13:04 | ely-se | I see. :p |
| 13:04 | ely-se | philth-irssi: the JDK has facilities for that. |
| 13:04 | rhg135 | The pronoun has two possible targets |
| 13:04 | rhg135 | 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 | philth-irssi | 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 | justin_smith | 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 | ely-se | a hashmap has only a single index |
| 13:21 | ely-se | 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 | wasamasa | 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 | wasamasa | 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 | hiredman | 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:30 | philth-irssi | Ta-da |
| 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:34 | en590 | in a 'let' expression why are the bindings done in a vector and not a map? |
| 13:34 | justin_smith | en590: they are ordered and can refer to previous bindings |
| 13:34 | justin_smith | en590: also maps only allow keys to happen once, let bindings allow re-binding that shadows a previous key |
| 13:35 | justin_smith | ,(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 | oddcully | (inc justin_smith) |
| 13:36 | lazybot | ⇒ 287 |
| 13:37 | oddcully | yeah i knew, then i forgot |
| 13:37 | oddcully | 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 | en590 | 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 | ely-se | hiredman: cool I'll look at it |
| 13:41 | ely-se | 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 | ely-se | 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 | en590 | 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 | sdegutis | 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 | sdegutis | 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 | sdegutis | 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 | en590 | 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 | justin_smith: ok so what's our bank PIN btw |
| 13:56 | justin_smith | hunter2 |
| 13:56 | justin_smith | don't tell anyone |
| 13:56 | sdegutis | don't worry it just shows up as ******* to everyone else |
| 13:57 | sdegutis | 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 | rhg135 | 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 | sdegutis | 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 | sdegutis | Most (if not all) of my helper functions are completely obsoleted by new Datomic features. |
| 14:00 | sdegutis | (Although not really "new" anymore.) |
| 14:00 | rhg135 | I didn't use datomic till last year |
| 14:01 | rhg135 | 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 | en590 | 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 | philth-irssi | ,((fn [] "hi")) |
| 14:08 | clojurebot | "hi" |
| 14:08 | philth-irssi | you can't call a string. |
| 14:09 | philth-irssi | str is a function you can call, with the arg "hi". |
| 14:09 | philth-irssi | 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 | justin_smith | 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 | spieden | 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 | spieden | gratsi |
| 14:11 | justin_smith | np |
| 14:15 | en590 | clojure is like a dream language |
| 14:15 | en590 | u dont even had to do math you just inc stuff |
| 14:16 | en590 | ,(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 | luxbock | 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 | en590 | (iterate count (iterate inc 0)) |
| 14:20 | en590 | ,(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 | justin_smith | ,(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 | en590 | 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: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 | bja | 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 | en590 | ,(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 | sdegutis | en590: the fundamental rule of all lisp syntax is dead simple: a(b,c,d) = (a b c d), that's it |
| 14:32 | sdegutis | en590: now you fully understand all of lisp. |
| 14:32 | sdegutis | 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 | sdegutis | 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 | sdegutis | im not joking, thats literally all there is to understanding lisp |
| 14:34 | akabander | (map inc '(1 2 3)) |
| 14:35 | akabander | ,(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 | en590 | 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 | sdegutis | 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 | sdegutis | I meant clearer than '(1 2 3) '(1 2 3) |
| 14:37 | akabander | Clearer or not, yours ran :) |
| 14:37 | sdegutis | :P |
| 14:38 | sdegutis | 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 | sdegutis | 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 | sdegutis | 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 | oddcully | irctc: please go ahead |
| 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 | sdegutis | 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 | sdegutis | Works fine for me. Upgrade I guess. |
| 14:42 | sdegutis | 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 | sdegutis | 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 | irctc | and its from a ClassNotFoundExceitpion |
| 14:45 | irctc | a class that im attempting to use |
| 14:45 | irctc | but if i use a normal 'lein run' it works perfect |
| 14:45 | TEttinger | irctc: interesting. |
| 14:45 | TEttinger | 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 | irctc | https://www.refheap.com/108683 |
| 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 | irctc | 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 | irctc | http://stackoverflow.com/questions/31197792/leiningen-bug-in-producing-uberjars-or-misunderstanding |
| 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 | TEttinger | err, jar hm. |
| 14:52 | justin_smith | irctc: yeah, lein-localrepo plugin does it |
| 14:52 | justin_smith | irctc: there is also a mvn command that will do it |
| 14:52 | TEttinger | https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html |
| 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 | irctc | 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 | ely-se | 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 | en590 | and justin_smith |
| 14:59 | en590 | and akabander |
| 15:00 | en590 | 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 | en590 | 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 | en590 | ,(* 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 | justin_smith | ,(+ :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 | philth-irssi | ,(+) |
| 15:05 | clojurebot | 0 |
| 15:05 | akabander | Specifically 1 is the identity cofactor of the multiplication operation |
| 15:05 | philth-irssi | ,(*) |
| 15:05 | clojurebot | 1 |
| 15:05 | philth-irssi | :D |
| 15:06 | akabander | And 0 is the identity cofactor of the addition operation. |
| 15:06 | en590 | (+ (+) (*) (*)) |
| 15:06 | en590 | ,(+ (+) (*) (*)) |
| 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 | oddcully | ,(> 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 | akabander | "(< 0)"... "I'll take late 80s movies for $100, Alex" |
| 15:08 | akabander | 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 | philth-irssi | Whoa |
| 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 | clojurebot | Source not found\n |
| 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 | akabander | So arity one is always true |
| 15:11 | en590 | how do you prounounce arity irl |
| 15:11 | en590 | 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 | TEttinger | = does reference equality for objects, and identity returns a Double in this case |
| 15:15 | TEttinger | ,(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 | en590 | is that why the error messages are so crazy |
| 15:15 | TEttinger | en590, not quite. it does run on the JVM |
| 15:15 | TEttinger | it generates the same format that java compiles to |
| 15:15 | TEttinger | .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 | TEttinger | ,(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 | TEttinger | it has crazy JS stuff instead |
| 15:18 | en590 | yah was about to ask lol |
| 15:18 | en590 | i much prefer javascript |
| 15:18 | en590 | 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 | en590 | 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 | TEttinger | 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 | snowell | It also introduces the wonderful mutability of native JS objects if you want it to |
| 15:22 | snowell | 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 | TEttinger | because there are a ton of java libs |
| 15:25 | TEttinger | and java still performs better on certain tasks by a large margin |
| 15:25 | TEttinger | (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 | snowell | 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 | TEttinger | 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 | en590_ | it also allows portions of existing java code to slowly be ported to clojure? |
| 15:33 | en590_ | or is a complete rewrite generally done |
| 15:33 | TEttinger | more commonly, you write a wrapper |
| 15:33 | TEttinger | 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 | TEttinger | 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 | TEttinger | *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 | sdegutis | 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 | wasamasa | 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 | wasamasa | http://dev.clojure.org/display/design/Reader+Conditionals |
| 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 | oddcully | 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 | TEttinger | https://github.com/franko/luajit-lang-toolkit/ |
| 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 | TEttinger | 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 | TEttinger | 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 | bearjack | 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 | kwladyka | 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 | bearjack | Even though when I do it in the repl there's a message |
| 16:00 | bearjack | NullPointerException java.lang.ProcessBuilder.start (ProcessBuilder.java:1010) |
| 16:00 | bearjack | 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 | kwladyka | 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 | irctc | heres what my project.clj looks like now |
| 16:09 | irctc | https://www.refheap.com/108686 |
| 16:10 | irctc | i added RTAClient, log4j, and spread using 'lein localrepo install' |
| 16:12 | irctc | justin_smith: any ideas? im getting an error that states "could not find artifiact in" |
| 16:13 | irctc | 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 | justin_smith | whether that's lein localrepo or mvn install or whatever |
| 16:17 | irctc | so i did that |
| 16:17 | irctc | 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 | justin_smith | since the org/artifact is org.clojure/clojure |
| 16:20 | irctc | does .m2 live within the project root repo? |
| 16:20 | irctc | 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 | kwladyka | 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 | irctc | 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 | irctc | killed it |
| 16:23 | irctc | 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 | TEttinger | 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:34 | TEttinger | kwladyka: https://github.com/daveray/seesaw/blob/develop/src/seesaw/event.clj#L30-L32 |
| 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 | TEttinger | 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 | sh10151 | 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 | sh10151 | 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:44 | hiredman | http://clojure.org/data_structures#Data%20Structures-Keywords |
| 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 | oddcully | 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 | sdegutis | ,(: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 | sdegutis | ,(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 | sdegutis | hahahahaha |
| 18:04 | lazybot | sdegutis: What are you, crazy? Of course not! |
| 18:04 | sdegutis | lazybot: LAZYBOT< YOURE ALIVE!!! |
| 18:04 | sdegutis | 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 | justin_smith | 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 | eriktjacobsen | 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 | xemdetia | 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 | {blake} | 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 | en590 | 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 | en590 | ,(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 | justin_smith | 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 | justin_smith | ,(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 | en590 | ,(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 | amalloy | it's like (let [5 2] 5) - 5 is a value, not a name |
| 19:43 | amalloy | likewise :a |
| 19:43 | en590 | how are keywords values and not names? |
| 19:44 | amalloy | well. most stuff in clojure is values |
| 19:45 | amalloy | 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 | en590 | ,(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 | neoncontrails | ,(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 | neoncontrails | ,(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 | justin_smith | ,(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 | en590 | ,(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 | justin_smith | ,(boolean (not-empty ())) |
| 21:24 | clojurebot | false |
| 21:25 | en590 | (not-empty '()) |
| 21:25 | en590 | ,(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 | neoncontrails | ,(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 | neoncontrails | 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 | justin_smith | ,(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 | justin_smith | and true is not a function |
| 21:29 | en590 | (boolean true) |
| 21:29 | en590 | ,(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 | en590 | but that isn't explicit and seems like shit |
| 21:31 | en590 | 'Please use the idiom (seq x) rather than (not (empty? x))' |
| 21:32 | en590 | ,(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 | merl1n | (empty? [1 2 3]) |
| 21:33 | merl1n | ,(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 | surtn | ,(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 | neoncontrails | ,(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 | surtn | 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 | TEttinger | 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 | neoncontrails | (defn add1 [x] (if (empty? x) (reduce + x))) |
| 21:46 | TEttinger | ,(defn add1 [x] (if (empty? x) (reduce + x))) |
| 21:46 | clojurebot | #'sandbox/add1 |
| 21:46 | TEttinger | you can def here :) |
| 21:46 | TEttinger | it lasts 10 minutes or so |
| 21:46 | neoncontrails | ,(defn add1-good [x] (if (seq x) (reduce + x))) |
| 21:46 | clojurebot | #'sandbox/add1-good |
| 21:46 | TEttinger | and you may have wanted not empty? |
| 21:46 | neoncontrails | ,(defn add1-bad [x] (if (empty? x) (reduce + x))) |
| 21:46 | clojurebot | #'sandbox/add1-bad |
| 21:46 | neoncontrails | (add1-bad []) |
| 21:47 | TEttinger | ,(add1-bad []) |
| 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 | TEttinger | ,(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 | neoncontrails | Good one, Rich |
| 21:53 | TEttinger | I think PMOC is likely one of the many perl-related acronyms, like CPAN |
| 21:53 | TEttinger | 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 | TEttinger | \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 | TEttinger | \c[APOSTROPHE] is the same as an escaped ' but behaves correctly even in misbehaving syntax highlighters |
| 21:57 | TEttinger | 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 | neoncontrails | https://en.wikipedia.org/wiki/Black_Perl |
| 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 | TEttinger | 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 | en590 | ,(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 | TEttinger | they're... they're actually doing something good with core java. I'm as stunned as you are. |
| 22:01 | TEttinger | 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 | justin_smith | 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 | neoncontrails | (this is my own personal opinion) |
| 22:07 | en590 | i like this page it has a good ui |
| 22:07 | en590 | thank u justin_smith |
| 22:08 | justin_smith | en590: the page was made by our friend arrdem |
| 22:08 | justin_smith | (inc arrdem) |
| 22:08 | lazybot | ⇒ 46 |
| 22:09 | neoncontrails | heh |
| 22:09 | neoncontrails | (arrdem) |
| 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: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 | justin_smith | (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:16 | justin_smith | arrdem: we were admiring your work |
| 22:16 | arrdem | yes yes but you were admiring the WRONG WORK |
| 22:16 | justin_smith | is this a thing we can all use? |
| 22:16 | arrdem | if you want to deal with skummet |
| 22:17 | arrdem | 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 | TEttinger | I have never honestly written a protocol |
| 22:25 | arrdem | protocols are pretty neat |
| 22:34 | arrdem | 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 | TEttinger | it's possible clojure has caught up now |
| 22:38 | TEttinger | (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:38 | TEttinger | badass. |
| 22:39 | TEttinger | 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 | arrdem | but no we've gotten no "this is release candidate material" or otherwise feedback. |
| 22:40 | neoncontrails | Speaking of efficiency/imperative interop |
| 22:40 | neoncontrails | (defn answer2 [maxrange] |
| 22:40 | neoncontrails | (reduce + (filter #(or (zero? (mod % 3)) |
| 22:40 | neoncontrails | (zero? (mod % 5))) |
| 22:40 | neoncontrails | (range maxrange)))) |
| 22:40 | neoncontrails | err |
| 22:40 | arrdem | neoncontrails: STOP PASTING USE REFHEEAP |
| 22:41 | arrdem | *refheap.com |
| 22:41 | neoncontrails | OKAY SORRY |
| 22:41 | arrdem | sorry for caps, wanted to catch you before you retried :P |
| 22:41 | arrdem | 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 | neoncontrails | Ehh, kinda. Project Euler #1 |
| 22:42 | neoncontrails | Which is basically fizzbuzz, but with an added reduce() step |
| 22:43 | neoncontrails | 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 | neoncontrails | ,(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 | TEttinger | 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 | clojurebot | #'sandbox/answer3 |
| 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 | TEttinger | which is very hard to measure |
| 22:51 | TEttinger | 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 | TEttinger | ,(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 | TEttinger | remember that was 24 earlier? |
| 22:52 | TEttinger | welcome to JVM benchmarking crazyland |
| 22:52 | neoncontrails | Interesting |
| 22:53 | neoncontrails | 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 | TEttinger | 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 | TEttinger | 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 | TEttinger | 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 | andyf | 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 | TEttinger | ...no GC has occurred. Anyone have an <cut off> |
| 23:49 | TEttinger | 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 | andyf | 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 | andyf | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | andyf: you said "things moved when gc did not occur" |
| 23:56 | justin_smith | 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 |