2014-09-13
| 00:00 | justin_smith | and of course, that really means the general programming style that works with immutibility |
| 00:00 | catern | learning that value has made programming in mutable languages *more* painful! |
| 00:00 | justin_smith | why? why not just program immutibly in whatever language? |
| 00:00 | justin_smith | in clojure, you can still need to touch mutible state or APIs in the jvm |
| 00:01 | justin_smith | though its true you will find less immutible infrasctucture, some stuff isn't so hard to adapt |
| 00:03 | ToxicFrog | So I have the following form: (some-> (:name x) (.equalsIgnoreCase (:name y))) |
| 00:03 | ToxicFrog | I want to eliminate reflection, and know that (:name x) and (:name y) have type String. |
| 00:04 | ToxicFrog | Where do I put the ^String annotations? |
| 00:04 | ambroseb_ | (let [^String a (:name x)] (some-> a ....)) |
| 00:04 | ToxicFrog | (rather, I know that (:name y) has type String and (:name x) is either a String or nil, but if it's nil the some-> will never get around to making the method call anyways) |
| 00:04 | justin_smith | ToxicFrog: this code may be clearer without the some-> form if annotated |
| 00:06 | ToxicFrog | ambroseb_: aah. The docs say that type hints can be placed on "expressions" as well as parameters, var-names and let-names, but isn't really clear on how you do that. |
| 00:06 | ToxicFrog | So I was hoping I could attach the ^String to (:name x) directly somehow. |
| 00:06 | ambroseb_ | ToxicFrog: mm it's an art |
| 00:06 | ambroseb_ | :) |
| 00:06 | ambroseb_ | ToxicFrog: especially when you're passing nil ... |
| 00:07 | ToxicFrog | Actually, looking at it, I'm not sure I am passing nil. The some-> may be a holdover from an earlier version. |
| 00:31 | michaniskin | is it possible to have nested nrepl clients? |
| 00:31 | michaniskin | like if i have a repl session going can i attach to another nrepl server |
| 00:32 | justin_smith | michaniskin: yeah, I would be surprised if it did not work, via clojure.tools.nrepl |
| 00:32 | michaniskin | i must be doing something wrong, it disconnects me from the current session |
| 00:33 | justin_smith | hrm - I would think it would be re-entrant |
| 00:33 | ToxicFrog | Dear god the type signature on every? |
| 00:33 | justin_smith | haha, I can only imagine |
| 00:33 | ToxicFrog | I was expecting something like [(Seqable Any) -> Boolean] |
| 00:33 | ToxicFrog | Instead it's (All [x y] (IFn [(IFn [x -> Any :filters {:then (is y 0), :else tt}]) (Coll x) -> java.lang.Boolean :filters {:then (is (Coll y) 1), :else tt}] [(IFn [x -> Any :filters {:then (is y 0), :else tt}]) (U (IPersistentCollection x) nil) -> java.lang.Boolean :filters {:then (is (U (IPersistentCollection y) nil) 1), :else tt}] [(IFn [x -> Any]) (U (Seqable x) nil) -> java.lang.Boolean])) |
| 00:34 | justin_smith | woah |
| 00:34 | ToxicFrog | (why am I looking at this? Because core.typed doesn't come with type annotations for clojure.core/not-any?) |
| 00:35 | ToxicFrog | (so I figured I'd check every?, which I thought would have the same type) |
| 00:35 | ToxicFrog | (I'm not so sure anymore) |
| 01:15 | ToxicFrog | justin_smith: so it turns out to be a lot more readable if you run it through pprint and ignore the filters. |
| 01:16 | ToxicFrog | I am a bit confused as to why it has three signatures, though -- one taking (Coll x), one (U (Seqable x) nil), and one (U (IPersistentCollection x) nil) |
| 01:27 | ToxicFrog | Argh. It's complaining that String/contains can't be applied to arguments (U String nil), but String implements CharSequence and the code in fact runs fine |
| 01:27 | ToxicFrog | maybe this will make more sense in the morning |
| 02:39 | dorkmafia | http://paste.debian.net/120653/ how come that doesn't work? I also tried {:libpaths [["python/"]["skype4py/Skype4Py/"]] } but {:libpaths ["python/"]} working? |
| 02:40 | dorkmafia | /ing/d |
| 06:45 | dagda1 | is there anything similar to respond_to? in clojure that will let me know if a datatype has a method or am I thinking about this all wrong |
| 06:45 | justin_smith | dagda1: you can use clojure.reflect/reflect to get all slots and methods on an object |
| 06:46 | dagda1 | justin_smith: thanks |
| 06:46 | justin_smith | or you can use instance? / isa? to see if it implements the protocol or interface defining that method |
| 06:46 | justin_smith | that's less expensive, but also less reliable |
| 07:00 | papachan | hi |
| 07:01 | papachan | i would like conj a map {} with doseq because i need to iterate each key value of another map |
| 07:01 | papachan | i was thinking something like this, but obviously it doesn't work |
| 07:01 | papachan | https://code.stypi.com/papachan/conj.clj |
| 07:32 | milos_cohagen | papachan: if you want to create a new map, from an old map, with some transformations in between, you can use reduce perhaps |
| 07:32 | milos_cohagen | ,(reduce (fn [m [k v]] (assoc m k v)) {} {:a 0 :b 1}) |
| 07:32 | papachan | milos_cohagen thank you i will try with reduce |
| 07:32 | clojurebot | {:a 0, :b 1} |
| 07:33 | milos_cohagen | doXXX functions are mostly for performing side effects, like mutating something, printing something, etc |
| 07:34 | milos_cohagen | clojure functions like conj or assoc or "pure", no side-effects |
| 07:35 | milos_cohagen | i mean "are pure" not "or pure" |
| 07:37 | papachan | milos_cohagen ok it does the same think when i am using conj |
| 07:41 | milos_cohagen | papachan would be happy to take a look if you post a snippet |
| 07:43 | papachan | milos_cohagen, |
| 07:44 | papachan | https://code.stypi.com/papachan/snippet.clj |
| 07:49 | milos_cohagen | papachan thanks but from that repl session i'm having a hard time interpreting your goal. what are the requirements of params-parser |
| 07:51 | papachan | milos_cohagen i am receiving a params {:model "android" :version "1.2.1"} |
| 07:52 | milos_cohagen | ok |
| 07:52 | papachan | need to put it in a session cookie structure |
| 07:52 | papachan | as at final |
| 07:52 | papachan | and assoc with the actual session cookie |
| 07:54 | papachan | i was working with do seq but its not the result: it executed each times it detect a keyword |
| 07:55 | milos_cohagen | ok so, we want a function f which accepts two maps as arguments a and b. (defn f [a b] ..) |
| 07:55 | milos_cohagen | map "a" keys and vals should be added in someway to map "b"? |
| 07:57 | milos_cohagen | and an updated version of map "b" should be returned? |
| 07:57 | papachan | yes i was trying with your reduce code, but still don't understand how i recur each keywords to make a new map structure |
| 07:57 | papachan | should return the final at my snippet but not repeated |
| 08:01 | milos_cohagen | ok so we do (defn f [a b] ...), the ... could be a reduce form, so we say (defn f [a b] (reduce reduce-fn b a)) |
| 08:01 | papachan | ok |
| 08:03 | milos_cohagen | reduce-fn accepts two args, the accumulated vale, which starts with "b", and second arg is the first k,v of "a", and should return the new accumulated value |
| 08:04 | milos_cohagen | sorry hard to explain, i can't just write the answer for you because your examples don't show what "a" and "b" values look like exactly with exact desired output |
| 08:06 | papachan | milos_cohagen i am trying to make something work. will try your example |
| 08:17 | milos_cohagen | good luck! |
| 08:30 | kqr | can I somehow figure out the type of an object I have in my clojure program? it exhibits some interesting properties and I'd like to know what it is |
| 08:30 | kungi | I am trying to test my core async code but the test finishes with the report before the assertations in the go-blocks had a chance to run |
| 08:31 | kungi | Is there an asynchronous testing helper for clojure.test? |
| 08:31 | kungi | kqr: class maybe what you want |
| 08:31 | kungi | ,(class "") |
| 08:31 | clojurebot | java.lang.String |
| 08:31 | kqr | kungi, yes I did, thanks |
| 08:32 | kqr | it's just a java.io.File |
| 08:32 | kqr | interesting! |
| 08:54 | kqr | does anyone know why I get the exception: http://lpaste.net/2155899009351286784 ? even though according to javadocs one of the copy methods take two paths as arguments? |
| 08:55 | kqr | ...wait |
| 08:55 | kqr | clojure has a copy function? |
| 08:55 | kqr | just maybe i should use that instead |
| 09:00 | kqr | but that fails too |
| 09:00 | kqr | hm |
| 09:01 | kungi | kqr: https://clojure.github.io/clojure/clojure.java.io-api.html |
| 09:01 | kqr | who woulda thunk copying files would be so difficult on the jvm :D |
| 09:01 | kungi | kqr: there is also a copy function |
| 09:01 | kqr | i saw that |
| 09:01 | kqr | but if I try to (clojure.java.io/copy (File. "t1.txt") (File. "t2.txt")) it complains about one of them not being a var |
| 09:02 | kqr | if I assign them to variables before doing the call I get an IllegalArgumentException in multimethod "do-copy" |
| 09:02 | ToxicFrog | kqr: re Files/copy: is it possible that the reflector is finding the wrong method for it? |
| 09:03 | ToxicFrog | There's a bunch of different versions of copy, including one that takes (Path OutputStream) and one that takes (Path Path); if it's only finding the former, there's your problem |
| 09:03 | kqr | http://lpaste.net/4103219378718244864 |
| 09:03 | kqr | full version of the error I get with the clojure-native copy function |
| 09:04 | kqr | ToxicFrog, yeah, that's what I suspected... but I don't know how I can make it find the other one |
| 09:05 | ToxicFrog | kqr: hmm. I tried adding type annotations to mark both src and dest as ^Path but that didn't work :/ |
| 09:06 | kqr | weird |
| 09:07 | ToxicFrog | Oh, I see, reading the docs on java interop it looks like type hints help it on resolving the type of this when making method calls but no mention is given of resolving arguments in overloaded functions |
| 09:07 | kqr | well |
| 09:07 | kqr | (clojure.java.io/copy (clojure.java.io/file "t.txt") (clojure.java.io/file "t2.txt")) works |
| 09:08 | kqr | even though clojure.java.io/file according to docs passes the argument straight to java.io/File |
| 09:10 | ToxicFrog | kqr: ok, but that's expected? |
| 09:10 | ToxicFrog | Look at the docs: "Input may be an InputStream, Reader, File, byte[], or String." |
| 09:10 | ToxicFrog | clojure.java.io/copy supports Files but not Paths |
| 09:11 | kqr | ToxicFrog, shit yeah you're right |
| 09:11 | kqr | ToxicFrog, I thought my variables source and dest were files, but they are paths |
| 09:11 | kqr | ToxicFrog, thanks |
| 09:12 | kqr | they were files for the longest time, then I made them into paths before asking here :) |
| 09:15 | ToxicFrog | Huh. I must not understand how to set type hints. |
| 09:15 | ToxicFrog | I thought they were stored in the metadata, but: |
| 09:15 | ToxicFrog | user=> (let [^Path p (.toPath (File. "/etc/passwd"))] (meta p)) |
| 09:15 | ToxicFrog | nil |
| 09:16 | kqr | i thought so too |
| 09:28 | ToxicFrog | Huh. |
| 09:28 | ToxicFrog | Ok, so if I use with-meta, everything works fine |
| 09:28 | ToxicFrog | If I use the ^ macro, no metadata is applied |
| 09:28 | ToxicFrog | Oh. Because I'm using it in the wrong position. |
| 09:28 | ToxicFrog | asdfh |
| 09:35 | kqr | haha |
| 09:36 | ToxicFrog | But it still doesn't work with Path! |
| 09:36 | ToxicFrog | aaaaaaaaagh |
| 09:36 | ToxicFrog | user=> (def x ^int {}) (meta x) |
| 09:36 | ToxicFrog | {:tag #<core$int clojure.core$int@12a133b2>} |
| 09:36 | ToxicFrog | user=> (def src ^Path (.toPath (File. "/tmp/foo"))) (def dst ^Path (.toPath (File. "/tmp/bar"))) (meta dst) |
| 09:36 | ToxicFrog | nil |
| 09:57 | kqr | is there a way to store some information about my application in a separate file? i'm trying to create a web app, and both ragtime and korma wants information about the database but in separate formats |
| 09:58 | kqr | and i'd rather not commit the details of the database to the repo |
| 09:58 | rweir_ | I've used https://github.com/weavejester/environ pretty happily |
| 09:58 | rweir_ | which doesn't help with getting the stuff into your libraries, but it does do the 'what are the values' bit |
| 10:00 | kqr | I just now realised that project.clj is a normal clojure file |
| 10:00 | kqr | that certainly helps |
| 10:01 | rweir_ | yeah |
| 10:01 | rweir_ | think carefully about how much magic you put in there though |
| 10:03 | kqr | well ragtime wants a jdbc url, so somehow I need to convert the db details into a url |
| 10:03 | kqr | is that too much magic? |
| 10:03 | rweir_ | ah |
| 10:03 | rweir_ | I'd probably do that in my real-code instead of project.clj, but I don't have a strong opinion either way :) |
| 10:03 | kqr | how'd that work? |
| 10:04 | kqr | what I'm imagining is a file that simply contains a map with host, db name, username and password |
| 10:04 | rweir_ | ie do at the point where you first interact with ragtime [I've not used it, so apologies if that's a stupid answer] |
| 10:04 | kqr | and then project.clj *and* src/db/schema.clj must use that information |
| 10:04 | kqr | the first interaction with ragtime is in the project.clj file |
| 10:04 | rweir_ | oh, interesting |
| 10:04 | kqr | or rather, that's where you're supposed to tell it which database to use |
| 10:05 | rweir_ | ah, I see [looking at the docs] |
| 10:05 | kqr | the broader context is that I'm trying to learn the luminus framework |
| 10:05 | kqr | I find it as confusing as the next guy |
| 10:20 | dagda1 | is there a way to find the common elements in 2 vectors? |
| 10:21 | zot | convert to set and do intersection? |
| 10:47 | gfredericks | anybody know what's up with marmalade? |
| 10:51 | Raynes | gfredericks: Everything sucks. |
| 10:52 | gfredericks | (inc Raynes) |
| 10:52 | gfredericks | a few of my packages aren't available after removing marmalade from my list |
| 10:57 | gfredericks | lazybot being gone is symbolic of everything being broken this morning |
| 10:58 | Bronsa | it's not like lazybot being gone is a first |
| 10:59 | Raynes | you know what |
| 11:00 | Raynes | Fuck it |
| 11:00 | justin_smith | Bronsa: that's the difference between FUBAR and SNAFU |
| 11:00 | Raynes | IT'S THE ONLY WAY TO BE SURE |
| 11:00 | hyPiRion | Raynes: Have a supervisor on it? |
| 11:00 | hyPiRion | get mail every time it crashes |
| 11:01 | Bronsa | Raynes: <3 |
| 11:01 | Raynes | hyPiRion: I'd love for it to be as simple as monitoring it, but it's not quite that easy. |
| 11:01 | Raynes | hyPiRion: When lazybot dies his process almost never dies. |
| 11:01 | hyPiRion | Raynes: oh, right |
| 11:01 | Raynes | He is designed in such a way that if he can't talk to one IRC he doesn't really care that much |
| 11:01 | Raynes | The problem is he can't tell when he can't talk to ANY irc :P |
| 11:02 | justin_smith | Raynes: I assume it also has to detect and act on disconnects fro mthe server |
| 11:02 | Raynes | It does not. |
| 11:02 | hyPiRion | It's the "100% CPU time after server disconnect"-bug? |
| 11:02 | Raynes | Uses an ancient unmaintained version of irclj that doesn't handle disconnects at all, really. |
| 11:02 | Raynes | Nah, he just loses connection and can't do anything about it |
| 11:02 | Raynes | So he sends pings every now and then |
| 11:02 | hyPiRion | ah, haha |
| 11:02 | Raynes | Hoping for an answer |
| 11:02 | Raynes | It's quite sad really |
| 11:02 | Raynes | Let me put the kid out of his misery |
| 11:03 | justin_smith | you could make him close the connection and reconnect every half hour |
| 11:03 | justin_smith | lol |
| 11:03 | Raynes | That's srs engineering right there |
| 11:03 | hyPiRion | Well, if anyone has nothing to do in their sparetime, they could patch up poor lazybot |
| 11:03 | Raynes | hyPiRion: Step one: use newer half-assed irclj implementation. |
| 11:03 | Raynes | Step two: figure out it needs to be less half assed, make it less half assed |
| 11:03 | Raynes | Step three: #win |
| 11:04 | hyPiRion | Raynes: I was talking about step two mostly |
| 11:04 | hyPiRion | implement proper irclj |
| 11:04 | Raynes | The newer irclj is pretty solid |
| 11:04 | Raynes | I don't think it actually lacks much of anything lazybot would need. |
| 11:08 | gfredericks | Raynes: so a vigorous manual restart tends to fix transient problems? |
| 11:08 | Raynes | gfredericks: It doesn't actually go down that much. |
| 11:08 | gfredericks | but when it does that fixes it? |
| 11:08 | Raynes | Well yes, because the only 'problem' is usually just that it has lost connection for one reason or another. |
| 11:09 | Raynes | Birds sitting on power lines and shit. |
| 11:09 | Raynes | Normal stuff. |
| 11:09 | Raynes | Irclj needs handling for connection loss and lazybot needs new irclj after that. |
| 11:09 | Raynes | Then he will be legion without my help. |
| 11:09 | gfredericks | the hipchat bot I run at work is run in a bash loop that kills/restarts every ten minutes |
| 11:10 | Raynes | Sounds like an average Python program. |
| 11:10 | justin_smith | gfredericks: that was my "joke" suggestion |
| 11:10 | gfredericks | it has the advantage that it's easy to do :P |
| 11:10 | Raynes | Hey |
| 11:11 | Raynes | Could be like "Hmmmmmm... Nobody has said anything on any of these 40 channels I'm in in the past half hour..." |
| 11:11 | Raynes | "I... guess I should kill myself now?" |
| 11:11 | Raynes | "(System/exit 0) ; goodbye cruel world" |
| 11:12 | justin_smith | Raynes: sounds like my ex having a bpd attack |
| 11:13 | justin_smith | Raynes: isn't there an IRC protocol level thing for checking if you are connected? |
| 11:13 | Raynes | justin_smith: What's the first thing they do to a robot at the doctor's office? |
| 11:13 | Raynes | THEY CHECK HIS BYTLES. |
| 11:14 | Raynes | justin_smith: Well, ideally your socket realizes nothing's popping out the other end, but you can send PINGs to the server and if you do not get a response in a timely manner you can assume you're lost in interspace. |
| 11:14 | justin_smith | Raynes: like every half hour he could run /msg nickserv listchans |
| 11:14 | justin_smith | or just that |
| 11:14 | Raynes | IRC is super async. |
| 11:15 | justin_smith | right, distributed, async |
| 11:15 | Raynes | It's real hard to be like "gimme a list of channels" and then say "oh, here's my list of channels" |
| 11:15 | Raynes | You kinda have to send 'gimme a list of channels' off into the void and then receive the response from the void. |
| 11:15 | gfredericks | so srsly should I expect marmalade to be down for a long time? |
| 11:15 | Raynes | The problem is six other commands could return before that one, despite your ordering :P |
| 11:15 | Raynes | gfredericks: It's marmalade. Expect it to never come back up. |
| 11:15 | justin_smith | Raynes: reminds me of my experiments with mud scripting |
| 11:16 | justin_smith | basically you need multiple state machines ready to be triggered or finalized, because who knows which part of your logic a given message may be destined for |
| 11:16 | gfredericks | I need to give up on emacs package managers and just maintain a personal collection of .el files, don't I? |
| 11:17 | justin_smith | gfredericks: technomancy seems fond of el-get |
| 11:17 | gfredericks | what's that? another package manager? |
| 11:17 | justin_smith | http://www.emacswiki.org/emacs/el-get |
| 11:17 | gfredericks | my current problem is that some of my packages are only in this one repo that Raynes said will never come back |
| 11:17 | xeqi | gfredericks: I'm going to guess its maintained by one person, so yes |
| 11:18 | justin_smith | gfredericks: above link has a "why have both" rationale (up to you whether it's reasonable or not, of course) |
| 11:18 | gfredericks | "Think apt-get for emacs" |
| 11:18 | Raynes | gfredericks: It is way too early and I'm way too bitter to say one single useful non-silly thing right now. |
| 11:19 | gfredericks | Raynes: it's like 10am amirite |
| 11:19 | Raynes | I woke up at 7AM |
| 11:19 | Raynes | Didn't even get to go to the toilet before having to solve crisises. |
| 11:19 | gfredericks | waking up at 7am is sleeping in for me |
| 11:19 | Raynes | Waking up at noon is sleeping in for me. |
| 11:20 | gfredericks | I woke up at 8am today and that was *highly* unusual |
| 11:23 | gfredericks | who is going to stramg lop |
| 11:24 | justin_smith | bizzaro justin am going stramg lop thisy ear |
| 11:24 | justin_smith | (not actually going to strange loop) |
| 11:26 | gfredericks | does cider have a buffer-local current-ns variable? |
| 11:27 | gfredericks | I was looking at my 0.5.0 source and it seemed to mostly just infer based on an initial (ns ...) form, which doesn't help my org-babel uses |
| 11:28 | gfredericks | I see nrepl-client.el has (defvar-local nrepl-buffer-ns ...) |
| 11:32 | justin_smith | gfredericks: edebug is an awesome stepping debugger, that shows you the result of every form as it is evaluated, by the way |
| 11:34 | gfredericks | justin_smith: thanks; I'm still n00b enough that extra tools are likely to just layer confusion |
| 11:37 | allen | does anyone know of a plugin that allows me to load clojar or external libraries from within a lein repl |
| 11:37 | allen | similar to https://github.com/rkneufeld/lein-try |
| 11:38 | allen | except have the ability to load different libraries as we go with the flow |
| 11:38 | Raynes | https://github.com/cemerick/pomegranate |
| 11:38 | xeqi | alembic |
| 11:39 | allen | Raynes, beautiful. Thanks |
| 11:39 | allen | (inc Raynes) |
| 11:39 | lazybot | ⇒ 51 |
| 11:39 | gfredericks | hi lazybot |
| 11:39 | Raynes | Whatever is at the top of the inevitable 1200 libraries on top of pomegranate I guess |
| 11:40 | gfredericks | gimme uses fireflox uses alembic uses pomegranate so if you're not using gimme you're basically losing |
| 11:41 | Raynes | It looks like alembic doesn't use pomegranate? |
| 11:41 | Raynes | Which is horrifying |
| 11:41 | xeqi | it does |
| 11:41 | gfredericks | I use pomegranate, with a helper: https://github.com/gfredericks/repl-utils/blob/master/src/com/gfredericks/repl.clj#L12-18 |
| 11:41 | Raynes | xeqi: Oh, a transitive dep? |
| 11:41 | Raynes | Lovely |
| 11:41 | xeqi | I think through lein-as-resource |
| 11:42 | hugoduncan | which is woefully out of date |
| 11:43 | mantas | $ lein run [11:39:52] |
| 11:43 | mantas | Exception in thread "main" java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.Keyword, compiling:(caffeinate/web.clj:1:1) |
| 11:43 | mantas | line one is simple: (ns caffeinate.web |
| 11:43 | mantas | any explanation as to why this happens? |
| 11:43 | Raynes | Well, I'd close that for starters. |
| 11:43 | justin_smith | allen: pallet/alembic is easier to use than pomegranate |
| 11:44 | Raynes | Line one is a red herring, mantas. Please show us your whole ns form |
| 11:44 | allen | ok cool, i'll check out all three |
| 11:44 | xeqi | mantas: through the magic of macros, line 1 is basically everything in the (ns ..) form |
| 11:44 | allen | ohh nvm alembic is developed by pallet |
| 11:44 | Raynes | Is pomegranate difficult to use? O.o |
| 11:45 | xeqi | Raynes: well, you do have to pass the repositories. and if you have mirrors... |
| 11:45 | justin_smith | Raynes: alembic uses the project.clj dep syntax, and is automatically recursive |
| 11:45 | hugod | alembic keeps pomegranate off your project's classpath |
| 11:45 | justin_smith | and you don't need to specify repos at all |
| 11:45 | xeqi | hugod: does alembic keep track of what is already been distilled? |
| 11:45 | xeqi | to avoid different distilled calls bring in conflicting deps? |
| 11:46 | hugod | xeqi: it checks what is already loaded in the clsspath |
| 11:46 | hugod | and warns on conflicts |
| 11:46 | Raynes | Well, clearly alembic is the best thing since sliced ham. |
| 11:46 | justin_smith | xeqi: alembic, in my experience, does not import things if some other version is already imported |
| 11:46 | xeqi | right, I thought it had something that way |
| 11:46 | justin_smith | Raynes: I found it much easier to use compared to pomegranate |
| 11:46 | Raynes | I understand |
| 11:48 | zeebrah | i'd like to trace a function for debugging. is it doable? |
| 11:48 | justin_smith | zeebrah: tools.trace |
| 11:48 | justin_smith | https://github.com/clojure/tools.trace very easy to use |
| 11:49 | zeebrah | justin_smith: cheers |
| 11:50 | zeebrah | this isn't quite what i had in mind. i was hoping for a CL like trace :( |
| 11:51 | justin_smith | zeebrah: tracing the execution of the function? |
| 11:51 | zeebrah | yep |
| 11:52 | justin_smith | zeebrah: I hear tell cursive clojure (it's an intellij idea plugin) has good step debugging, but have not actually tried it myself |
| 11:53 | zeebrah | justin_smith: actually wait, trace-ns is kinda cool and does the job :) |
| 11:54 | justin_smith | zeebrah: it doesn't get you the step by step internals though, but I guess it gets you your helper functions |
| 11:55 | justin_smith | on a more insane end of things, you can use jdb to trap and step and interact with the stack on the byte code level |
| 11:55 | justin_smith | but if trace-ns suffices, cheers :) |
| 11:55 | zeebrah | justin_smith: thanks for the help :) |
| 11:56 | justin_smith | np |
| 11:57 | kungi | I would like to have an atom containing a map of key -> #set pairs. How do I append to such a structure? When the #set belonging to a key is empty it is easy, but how do I append to an existing set in a map with a swap! operation? |
| 11:58 | justin_smith | ,(swap! (atom {:numbers #{0}}) update-in [:numbers] conj 1 2 3) |
| 11:58 | clojurebot | {:numbers #{0 1 3 2}} |
| 11:58 | justin_smith | definitely looks weird, as both swap and update-in take their args just stacked on the end without parens |
| 11:59 | kungi | justin_smith: yes it does :-) |
| 11:59 | kungi | justin_smith: Can I add a non existing key that way? |
| 11:59 | gfredericks | it's fun once you get the hang of it though |
| 11:59 | gfredericks | yes |
| 11:59 | kungi | ,(swap! (atom {:numbers #{0}}) update-in [:blubber] conj 1 2 3) |
| 11:59 | clojurebot | {:blubber (3 2 1), :numbers #{0}} |
| 11:59 | kungi | Awsome! |
| 11:59 | justin_smith | kungi: you need fnil for that if it needs to be a set |
| 11:59 | gfredericks | (fnil conj #{}) instead of conj |
| 12:00 | justin_smith | ,(swap! (atom {:numbers #{0}}) update-in [:blubber] (fnil conj #{}) 1 2 3) |
| 12:00 | clojurebot | {:blubber #{1 3 2}, :numbers #{0}} |
| 12:00 | mantas | huh, thanks! yes, the issue was later in the (ns... ) declaration. i didn't know macros had this effect. |
| 12:01 | kungi | justin_smith: Thank you |
| 12:01 | justin_smith | np |
| 12:02 | gfredericks | ,(def my-atom (atom {:foo [1 2 3]})) |
| 12:02 | clojurebot | #'sandbox/my-atom |
| 12:02 | gfredericks | ,(swap! my-atom update-in [:foo 0] dec) |
| 12:02 | clojurebot | {:foo [0 2 3]} |
| 12:03 | gfredericks | ,(swap! my-atom update-in [:foo 0] + 42) |
| 12:03 | clojurebot | {:foo [42 2 3]} |
| 12:19 | allen | date |
| 12:21 | iartarisi | Hello, I'm using Korma and trying to restrict the number of fields from a select query. I'd like to get SELECT games.white_id FROM games; but I get all the fields *plus* white_id instead: |
| 12:21 | iartarisi | (dry-run (select games (fields :white_id))) |
| 12:21 | iartarisi | dry run :: SELECT "games"."stones", "games"."white_id", "games"."black_id", "games"."white_id" FROM "games" :: [] |
| 12:21 | iartarisi | |
| 12:22 | iartarisi | I have the latest korma: 0.4.0 |
| 13:10 | Shoop | Whats the best way to turn ((1 1) (2 2)) into [[1 1] [2 2]]? |
| 13:11 | shosti | ,(vec (map vec '((1 1) (2 2)))) |
| 13:11 | clojurebot | [[1 1] [2 2]] |
| 13:12 | justin_smith | ,(mapv vec '((1 1) (2 2))) |
| 13:12 | clojurebot | [[1 1] [2 2]] |
| 13:16 | Shoop | Thanks :D |
| 13:18 | Shoop | Is vec the same as #(apply vector %)? |
| 13:19 | justin_smith | $source vec |
| 13:19 | lazybot | vec is http://is.gd/GCHYnT |
| 13:20 | Shoop | not literally but conceptually |
| 13:20 | justin_smith | interestingly, if you supply an array as the argument, it aliases it, and you break the contract of vectors if you later modify the array |
| 13:23 | justin_smith | where vector will not do anything like that |
| 13:27 | Jaood | cider needs some keep-alive method |
| 13:42 | gfredericks | ,(def argh (into-array [0 1 2 3 4])) |
| 13:42 | clojurebot | #'sandbox/argh |
| 13:42 | gfredericks | ,(seq argh) |
| 13:42 | clojurebot | (0 1 2 3 4) |
| 13:42 | gfredericks | ,(def vee (vec argh)) |
| 13:42 | clojurebot | #'sandbox/vee |
| 13:42 | gfredericks | ,vee |
| 13:42 | clojurebot | [0 1 2 3 4] |
| 13:42 | gfredericks | ,(aset argh 2 :hehe) |
| 13:42 | clojurebot | #<ArrayStoreException java.lang.ArrayStoreException: clojure.lang.Keyword> |
| 13:42 | gfredericks | ,(aset argh 2 42) |
| 13:42 | clojurebot | 42 |
| 13:42 | gfredericks | ,vee |
| 13:42 | clojurebot | [0 1 42 3 4] |
| 13:43 | gfredericks | ,(doc vec) |
| 13:43 | clojurebot | "([coll]); Creates a new vector containing the contents of coll. Java arrays will be aliased and should not be modified." |
| 13:43 | gfredericks | welp can't say it didn't warn you |
| 13:43 | gfredericks | does it do that even for large arrays? |
| 13:44 | gfredericks | ,(def argh (into-array (range 100000))) |
| 13:44 | clojurebot | #'sandbox/argh |
| 13:44 | gfredericks | ,(def vee (vec argh)) |
| 13:44 | clojurebot | #'sandbox/vee |
| 13:44 | gfredericks | ,(aset argh 0 42) |
| 13:44 | clojurebot | 42 |
| 13:44 | gfredericks | ,(take 10 vee) |
| 13:44 | clojurebot | (0 1 2 3 4 ...) |
| 13:45 | justin_smith | fascinating |
| 13:45 | gfredericks | it'd have to break it up at some point anyways; might as well be immediately |
| 13:45 | justin_smith | so maybe "will be" should say "can be" |
| 13:45 | gfredericks | right :) |
| 13:46 | gfredericks | we need a variant of the word "modify" for talking about immutable data structures |
| 13:47 | gfredericks | how about "schmodify" |
| 13:47 | gfredericks | or "schmutate" |
| 13:47 | justin_smith | elaborates? |
| 13:47 | gfredericks | yeah? |
| 13:47 | justin_smith | exponunds upon |
| 13:47 | justin_smith | err, expounds upon |
| 13:47 | gfredericks | not really a good analogy from normal life |
| 13:51 | jjl` | hi all. I'm writing some clojure that will need to be usable from java. what's the simplest way of writing test cases in java within a clojure project? |
| 13:51 | gfredericks | jjl`: test cases for automated testing? |
| 13:51 | jjl` | yes |
| 13:51 | gfredericks | leiningen has an option for specifying the location of java sources |
| 13:52 | gfredericks | I guess the rest of the answer depends on how you want to execute/launch the tests |
| 13:52 | gfredericks | e.g., do you mind writing tests in clojure that call your java code? |
| 13:52 | gfredericks | or do you need a java test framework? |
| 13:53 | jjl` | i think okay with the former, provided the java test harness doesn't get shipped in the final jar |
| 13:53 | gfredericks | yeah, leiningen lets you distinguish between dev stuff and final-package stuff |
| 13:54 | jjl` | okay. do you know which project.clj keys i'll need to read up on? |
| 13:56 | gfredericks | check the sample.project.clj file in the leiningen repo; they'll be one called :java-source-path or something similar |
| 13:57 | gfredericks | then try writing a test with clojure.test that runs your java code |
| 13:57 | jjl` | yeah, i just found that. presumably :exclusions is the other one i need? |
| 13:57 | gfredericks | or first you could try `lein run -m MyClass` |
| 13:57 | gfredericks | which I think works |
| 13:57 | gfredericks | jjl`: if you put it in the :dev profile then you don't need to exclude anything |
| 13:57 | gfredericks | :profiles {:dev {:java-source-paths ...}} |
| 13:57 | jjl` | oh, handy :) |
| 13:58 | jjl` | thanks :) |
| 13:58 | gfredericks | np |
| 14:28 | nkozo | I start a "lein repl" and then connect from emacs using cider, now if a Thread prints to *out* (using the timbre logging library) only the "lein repl" prompt shows the output, the cider nrepl session doesn't show it. Why? How you can print to both? |
| 14:44 | gfredericks | nkozo: um. |
| 14:44 | gfredericks | when you say "a Thread" I assume you mean not the thread you're using directly from cider |
| 14:49 | gfredericks | I think I know what all the pieces involved are, I just don't know what the best approach is |
| 15:17 | ultranapoletano | ciao |
| 15:17 | ultranapoletano | !list |
| 15:27 | jjl` | is there a way of building an abstract class member in clojure? i need it for some java interop and i'd be loathe to write it in java |
| 15:30 | gfredericks | what's an abstract class member? |
| 15:31 | jjl` | an abstract method |
| 15:31 | gfredericks | what would that look like in java? |
| 15:32 | jjl` | abstract class Foo { abstract void bar(); } |
| 15:32 | gfredericks | I'm curious what sort of java interop that's useful for |
| 15:34 | jjl` | Basically I'm building something where arbitrary objects will be passed around because of dynamic typing. All lovely and fine in clojure, but in javaland, you need type safety. I'd like a generic callback mechanism a la Callable, but different |
| 15:35 | gfredericks | why not an interface? |
| 15:36 | jjl` | because an interface doesn't permit you to enforce a given constructor |
| 15:37 | gfredericks | welp I don't know of any way to do abstract stuff in clojure; it doesn't sound like it'd be intolerable to write it in java |
| 15:38 | jjl` | no, indeed, it's not that much hassle, it's just i'd prefer to keep as much in clojure as possible |
| 15:45 | arohner | is #datomic logged anywhere? |
| 15:46 | TEttinger | arohner, it would be kinda ironic if the channel for a database wasn't logged in some database |
| 15:46 | arohner | google doesn't seem to know about it |
| 15:47 | redblackbit | any idea why (meta ^:foo 'bar) return nil while the documentation states that: Symbols and collections support metadata |
| 15:48 | TEttinger | ,(meta ^:foo +) |
| 15:48 | clojurebot | nil |
| 15:48 | TEttinger | ,(meta +) |
| 15:48 | clojurebot | nil |
| 15:48 | TEttinger | hm |
| 15:49 | TEttinger | ,(meta inc) |
| 15:49 | clojurebot | nil |
| 15:49 | TEttinger | might need var-quote |
| 15:49 | redblackbit | right |
| 15:49 | arohner | + resolves to the fn |
| 15:49 | arohner | ,(meta #'+) |
| 15:49 | clojurebot | {:added "1.2", :ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :inline-arities #<core$_GT_1_QMARK_ clojure.core$_GT_1_QMARK_@6e4c32>, ...} |
| 15:49 | redblackbit | but why doesn’t it work with a symbol? |
| 15:49 | TEttinger | ,(meta ^:foo #'bar) |
| 15:49 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: bar in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:50 | arohner | ,(meta (with-meta 'bar {:foo true})) |
| 15:50 | clojurebot | {:foo true} |
| 15:50 | gfredericks | redblackbit: it's because of what ' does |
| 15:50 | TEttinger | maybe ^:foo isn't evaluated until the form is done? |
| 15:50 | gfredericks | ,(meta ^:foo (quote bar)) |
| 15:50 | clojurebot | nil |
| 15:50 | gfredericks | ,(meta (quote ^:foo bar)) |
| 15:50 | clojurebot | {:foo true} |
| 15:50 | gfredericks | redblackbit: your code is equivalent to the first of those two ^ |
| 15:51 | redblackbit | gfredericks: oic |
| 15:51 | gfredericks | also there is: |
| 15:51 | redblackbit | gfredericks: makes kinda a pain to attach metadata to symbols though |
| 15:51 | gfredericks | ,(with-meta 'bar {:foo true}) |
| 15:51 | clojurebot | bar |
| 15:51 | gfredericks | ,(meta (with-meta 'bar {:foo true})) |
| 15:51 | clojurebot | {:foo true} |
| 15:54 | redblackbit | gfredericks: anyway, thx! |
| 15:54 | gfredericks | np |
| 16:11 | danielszmulewicz | Question to the emacs power users: I'm writing a minor mode that makes sense only with clojurescript files, however, there is no clojurescript-mode hook. Any ideas? |
| 16:16 | gfredericks | is there a clojurescript-mode? |
| 16:23 | danielszmulewicz | gfredericks: People have written their own, but now with cider and the official stack. Anyway, I posted an issue on cider's github. |
| 16:41 | noncom | ,(.getConstructor (java.lang.Class/forName "java.util.ArrayList")) |
| 16:41 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: getConstructor for class java.lang.Class> |
| 16:42 | noncom | ^^^ why is it searching for the constructor in class Class ? why does not it looking for the constructor in class ArrayList ? |
| 16:46 | dbasch | noncom: you’re calling a method that doesn’t exist |
| 16:47 | dbasch | : ,(.getConstructors (java.lang.Class/forName "java.util.ArrayList")) |
| 16:47 | dbasch | &(.getConstructor (java.lang.Class/forName "java.util.ArrayList")) |
| 16:47 | lazybot | java.lang.IllegalArgumentException: No matching field found: getConstructor for class java.lang.Class |
| 16:47 | dbasch | &(.getConstructors (java.lang.Class/forName "java.util.ArrayList")) |
| 16:47 | lazybot | ⇒ #<Constructor[] [Ljava.lang.reflect.Constructor;@b3cde94> |
| 16:48 | dbasch | &(first (.getConstructors (java.lang.Class/forName "java.util.ArrayList”))) |
| 16:48 | lazybot | java.lang.RuntimeException: EOF while reading string |
| 16:49 | dbasch | &(first (.getConstructors (java.lang.Class/forName "java.util.ArrayList"))) |
| 16:49 | lazybot | ⇒ #<Constructor public java.util.ArrayList(java.util.Collection)> |
| 16:55 | noncom | dbasch: thanks! |
| 17:12 | raspasov | hi everyone |
| 18:21 | onielfa | Hello, I have a stupid problem. When trying to use println like (println "Hello") in the REPL, I got a java.lang.NoSuchMethodError. Am I missing something? |
| 18:22 | hyPiRion | onielfa: `lein downgrade 2.4.2` |
| 18:23 | hyPiRion | we're working on it, there's a bug in latest stable =/ |
| 18:23 | onielfa | hyPiRion: Thanks a lot! I am going to downgrade :) |
| 18:25 | onielfa | hyPiRion: It works now :) Let's continue learning Clojure, thanks! |
| 18:25 | hyPiRion | onielfa: no problem =) |
| 20:48 | Bronsa | it's kind of unfortunate that disj only works on sets and not on maps |
| 20:59 | gfredericks | Bronsa: so (disj {1 2} [1 3]) would return {1 2}? |
| 21:01 | Bronsa | gfredericks: yeah, disj and dissoc have the same function signature |
| 21:02 | gfredericks | Bronsa: huwhat? dissoc doesn't take a value |
| 21:02 | Bronsa | gfredericks: wat |
| 21:04 | Bronsa | what I'd like is for disj to be (defn poly-disj [m & args] (apply (if (map? m) dissoc disj) args)) |
| 21:06 | gfredericks | Bronsa: so then you lose the conj/disj symmetry |
| 21:06 | Bronsa | no? the opposite |
| 21:06 | gfredericks | the symmetry being the type |
| 21:06 | Bronsa | right now disj only works on sets |
| 21:06 | gfredericks | ,(defn poly-disj [m & args] (apply (if |
| 21:06 | gfredericks | (map? m) dissoc disj) args)) |
| 21:06 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 21:06 | raspasov_ | yea conj works on everything |
| 21:06 | gfredericks | ,(defn poly-disj [m & args] (apply (if (map? m) dissoc disj) args)) |
| 21:06 | clojurebot | #'sandbox/poly-disj |
| 21:07 | gfredericks | ,(-> {} (conj [1 2]) (disj [1 2])) |
| 21:07 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.IPersistentSet> |
| 21:07 | gfredericks | ,(-> {} (conj [1 2]) (poly-disj [1 2])) |
| 21:07 | clojurebot | [1 2] |
| 21:08 | gfredericks | ,(-> #{} (conj [1 2]) (ploy-disj [1 2])) |
| 21:08 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ploy-disj in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:08 | gfredericks | ,(-> #{} (conj [1 2]) (poly-disj [1 2])) |
| 21:08 | clojurebot | [1 2] |
| 21:08 | gfredericks | wat |
| 21:08 | gfredericks | ,(defn poly-disj [m & args] (apply (if (map? m) dissoc disj) m args)) |
| 21:08 | clojurebot | #'sandbox/poly-disj |
| 21:08 | gfredericks | ,(-> {} (conj [1 2]) (poly-disj [1 2])) |
| 21:08 | clojurebot | {1 2} |
| 21:08 | gfredericks | ,(-> #{} (conj [1 2]) (poly-disj [1 2])) |
| 21:08 | clojurebot | #{} |
| 21:08 | gfredericks | Bronsa: ^ that is the mismatch I'm referring to |
| 21:09 | gfredericks | (had to fix a boog in your poly-disj) |
| 21:09 | Bronsa | yeah sorry for the typo :( |
| 21:10 | Bronsa | gfredericks: I honestly don't see how what you're trying to say |
| 21:10 | Bronsa | sticking a key/value pair in a disj doesn't make any sense |
| 21:10 | gfredericks | wrt sets, conj and disj are opposites |
| 21:10 | gfredericks | conj takes a thing to add, disj takes a thing to remove |
| 21:10 | gfredericks | wrt maps, conj and poly-disj are not opposites in that sense |
| 21:10 | gfredericks | conj takes a PAIR to add, poly-disj takes a KEY to remove |
| 21:12 | Bronsa | gfredericks: different operations take different inputs |
| 21:13 | Bronsa | by your point dissoc is not the opposite of assoc |
| 21:13 | gfredericks | I might be imagining and intended pairing of conj and disj |
| 21:13 | gfredericks | an* |
| 21:14 | Bronsa | gfredericks: yeah, disj right now has definitely nothing to do with conj, the latter being highly polymorphic while the former being defined only on sets |
| 21:14 | gfredericks | the names seem related |
| 21:14 | gfredericks | and "defined only on sets" always made sense to me as being the only context where it could be defined |
| 21:14 | amalloy | Bronsa: i don't really agree: disj and conj seem to me like they're intended to be inverses |
| 21:15 | gfredericks | amalloy! thank goodness you're here! |
| 21:15 | amalloy | if disj worked on maps i'd expect it to work like gfredericks's version, not yours |
| 21:15 | amalloy | or, probably, to require an actual MapEntry |
| 21:16 | gfredericks | eh, conj takes a vector pair |
| 21:16 | amalloy | gfredericks: yeah, but the mapentry didn't exist yet. it's plausible that disj on the map would only remove entries which are in the map |
| 21:17 | gfredericks | does java-style never involve creating map entries before adding them to maps? |
| 21:18 | amalloy | i can't think of an instance of that, but maybe |
| 21:18 | gfredericks | amalloy: in any case do you have a less hand-wavey argument for this than I do, or is it just "they seem like inverses"? |
| 21:18 | Bronsa | amalloy: gfredericks it had never crossed my mind that (disj {} [k v]) might make sense, and I still don't think it does but point taken |
| 21:19 | Bronsa | I still wish there was a function that behaved like poly-disj, whichever its name |
| 21:19 | amalloy | no, i have nothing concrete |
| 21:19 | gfredericks | amalloy: at least there's two of us |
| 21:20 | amalloy | Bronsa: you can create that function, of course, with protocols. i'm sure you know that; are you hoping for it to be in core instead? |
| 21:20 | Bronsa | amalloy: yeah I meant in core |
| 21:23 | Bronsa | `remove-keys` maybe |
| 21:24 | amalloy | Bronsa: you could even call it `without`, like the java method on maps |
| 21:24 | amalloy | (-> my-set (without x y z)) |
| 21:25 | amalloy | er, i guess i meant the method on sets |
| 21:25 | Bronsa | yeah without is probably better. remove-keys might suggest an association with select-keys, which only works on maps |
| 22:56 | wei | what’s a good way to pass data between two clojure processes? redis/carmine? |
| 23:00 | bbloom | wei: dramatically more information needed |
| 23:04 | wei | bbloom: good point. i have one process that controls multiple processes. the child processes are interchangeable and can start and stop unpredictably. requirements are that the messages be encrypted and durable across restarts. tangentially related, I recall Rich’s Language of the System talk had some great principles but he didn’t have time to cover how to implement such a system in Clojure |
| 23:05 | bbloom | are the processes on one box or distributed across several? |
| 23:14 | wei | bbloom: would it significantly change the design? |
| 23:15 | bbloom | wei: you can use the file system or you can use the network |
| 23:15 | bbloom | wei: why do you need encryption? |
| 23:15 | bbloom | wei: why do you need durability? |
| 23:15 | bbloom | you asked a reeeaaaallly general (and difficult) question |
| 23:15 | wei | thanks for humoring me :) |
| 23:16 | bbloom | maybe talk about your high level goal a bit |
| 23:18 | wei | haha, this reminds me of a previous conversation where you said, “guaranteed deliverability is a lie” |
| 23:18 | bbloom | wei: i would have reminded you of that :-P |
| 23:20 | wei | reading up on some design now.. i’ll come back later with more specific questions :) |
| 23:21 | vanila | hi |
| 23:21 | vanila | https://www.youtube.com/watch?v=f84n5oFoZBc |
| 23:21 | vanila | Hammock Driven Development - Rich Hickey |