#clojure log - Sep 18 2015

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

3:12 roelof: Hello, I try to do some challenges from codeingames. One of them I have to move a person on a screen but as far as I know Clojure variables are imutable

3:12 How can I change the x and Y coordinates for that person ?

3:16 namra: roelof: did you look at play-clj

3:16 it uses a global gamestate

3:17 and a modified version is returned by any function

3:17 roelof: namra: I did not. Where can I find it

3:17 namra: roelof: https://github.com/oakes/play-clj --- there you go

3:19 ok it passes an entities vector to the fns and you may return a modified version of this vector with your desired changes which will become the new gamestate

3:19 rritoch: roelof: If you need thread safety, see refs & atoms, if you don't, see make-array/aset as arrays are mutable.

3:19 roelof: namra : oke, after a quick look I see that I can use the inc and dec functions.

3:21 namra: or you do as rritoch says but play-clj is the more functional approach but also require more memory

3:22 roelof: thanks, I will look into that also, Do one of you know if the book brave and true is talking about this ?

3:22 namra: about atoms, immutability etc?

3:23 certainly it's a very nice introductory text you can get a feel from it because it's based on the authors blog posts

3:24 roelof: http://www.braveclojure.com/

3:24 roelof: no, about make-array

3:27 namra: don't know if he does in the book, but not in the blog articels

3:27 roelof: oke, I will look. In a few days a new version is due, so I wait for that

3:40 oddcully: roelof: isn't coding game basically reading stdin and printing the results? it would help if you could link to that problem

3:41 namra: oddcully: but you still have to handle the gamestate, like the position of the character in the world

3:41 in a pure oo language you just would call a threadsafe method on an object to change the coordinates

3:42 oddcully: i am aware of that. but what i remember from codinggame is not that sophisticated

3:42 namra: you could also do that in clojure, but when you want to keep it functional you stay with immutability

3:43 and that means the gamestate is mangled by functions which return a modified version

3:43 so it about handling gamestate

3:44 but i don't know the mentioned site so you might be right that it can be done simpler

5:31 mash333: gonna play ps4

5:32 sorry wrong ping:)

7:09 borkdude_: fun trick question: why does this return an empty seq? (remove (comp zero? :questions) ({:questions 1} {:questions 0}))

7:10 oddcully: borkdude_: because maps are functions

7:11 borkdude_: correct

7:12 mavbozo: ,(remove (comp zero? :questions) ({:questions 1} {:questions 0}))

7:12 clojurebot: ()

7:12 mavbozo: ,(remove (comp zero? :questions) '({:questions 1} {:questions 0}))

7:12 clojurebot: ({:questions 1})

7:13 mavbozo: that one quote i missed

7:13 oddcully: ,({{:questions 0} 1} {:questions 0})

7:13 clojurebot: 1

8:45 mungojelly: how can i get callbacks from a sqlite database instead of having to poll it?

8:52 mavbozo: mungojelly, do you use clojure.java.jdbc library?

8:52 mungojelly: mavbozo: i'm trying to learn how to use it right this moment

8:54 sqlite isn't smart enough to have the changes i'm interested in ready for me, is it? the best i can do is watch for the db file to be touched and then search to see if what i'm interested in has changed?

8:54 sorry i don't understand databases (obviously)

8:55 mavbozo: ah, so you want to get notification from the sqlite is something changes?

8:55 Wild_Cat: are you attempting to use sqlite as a message queue of sorts?

8:55 mungojelly: my task i'm practicing on is to respond to things that happen in firefox, which are stored apparently in sqlite databases

8:56 i want the most recent youtube videos i've gone to, which is a simple enough query i can figure that out with this jdbc docs i'm sure, but should i just poll periodically or what? :/

8:57 Wild_Cat: mungojelly: are you doing this from a separate process, or from within Firefox?

8:57 if 1. then yes, you do. If 2. I don't know.

8:57 mavbozo: since clojure/java.jdbc don't have notification api, you have to do long polling

8:57 mungojelly: i'd also like to use databases as message queues! that seems like a sensible strategy in general. except apparently you have to poll for changes. oh hey yeah maybe firefox has a hook for me, i'll check that out. :)

9:12 ane: could anyone review the clojure wikipedia article a bit, i've been improving it here and there

10:13 jonathanj: is there a function in Clojure core that does this: (defn just-call-f [f & rest] (fn [& ignored] (apply f rest)))?

10:14 (constantly #(apply f arg1 arg2)) is possibly the same?

10:15 justin_smith: jonathanj: if arg2 is a collection holding the rest of the args to f, I guess

10:16 jonathanj: actually, i guess my constantly thing isn't quite the same

10:20 sdegutis: I'm planning to make a library that's API-compatible with Compojure but builds up data structures instead of function composition, for easier inspection and to get rid of the function/var-caveat. Would anyone here be interested?

10:26 justin_smith: sounds like a good plan, but I can't commit time (at least this month...). Also there should be a dev-time "interpreted" mode where it follows the data structure every time, and a prod "compiled" mode where it can route more efficiently

10:28 sdegutis: justin_smith: ahh good idea for efficiency

10:29 justin_smith: anyway it seems like it should actually be a simple lib, I expect it could be done in an hour or so, by making use of a lot of still-applicable public functions in Compojure (and possibly using Clout for the rest)

10:29 I plan to do this just to fix the var-bug I'm having to work around in our app. I'll make it open source in case anyone else is interested.

10:32 skeuomorf: grimoire returning server errors for anyone else?

10:32 Bronsa: yup

10:32 justin_smith: skeuomorf: on and off, but it works with a refresh...

10:32 Bronsa: arrdem: ^

10:32 justin_smith: (for me)

10:33 skeuomorf: I see

10:33 arrdem: skeuomorf: sorry just broke it, working on it.

10:33 justin_smith: http should have a "insert coin to continue" error

10:33 arrdem: https://twitter.com/arrdem/status/644881749395177472

10:33 justin_smith: *an

10:33 arrdem: justin_smith: lol that's gonna be the next thing...

10:33 skeuomorf: arrdem: No worries, thanks for working on it :)

10:33 arrdem: thank me later :P

10:34 skeuomorf: (inc ardem)

10:34 err

10:34 ,(inc arrdem)

10:34 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...

10:34 skeuomorf: (inc arrdem)

10:34 BOT, WHERE ART THOU?

10:34 justin_smith: skeuomorf: lazybot has been even less reliable than grimoire

10:34 skeuomorf: justin_smith: It appears so :)

10:34 arrdem: lol

10:34 arrdem: justin_smith: I'm offended by that my uptime was perfect all summer until today

10:35 justin_smith: heh, sorry, bad wording :P

10:35 arrdem: lazybot goes down more than my old AOL line

10:36 skeuomorf: well, it's *lazy*

10:39 justin_smith: arrdem: oh wait, it exists but isn't implemented, 402

10:40 oddcully: hehe

10:40 arrdem: justin_smith: what exists?

10:40 oddcully: the http status code for "insert coin"

10:40 justin_smith: http status "insert coin to continue"

10:40 arrdem: also added an nginx redirect for grimoire intil I get stuff working again

10:41 sdegutis: hehehe http://i.ytimg.com/vi/z5kGR3TZnqk/maxresdefault.jpg

10:41 arrdem: nice error message :D

10:41 justin_smith: also noticed, there's a lemongrab status code - 406 NOT ACCEPTABLE

10:41 sdegutis: Remember when that pic used to actually appear on TVs? It was around the same time you actually had to turn a physical dial to change channels.

10:42 oddcully: ugh saw that one enough for a (yester)day

10:42 Bronsa: 418 I'M A TEAPOT, always the best http status code

10:42 justin_smith: it's true

10:42 arrdem: it is known

10:43 justin_smith: twitter's 420 ENHANCE YOUR CALM is also good (though not standard)

10:43 Bronsa: apparently twitter used to return a 420 Enhance Your Calm

10:43 heh

10:45 arrdem: FYI you can add a ns alias with c.c/alias too

10:46 arrdem: Bronsa: oh the new notes?

10:46 thanks I'll fix that in a minute

10:54 ugh bug in a bash script somewhere caused that

10:54 Grimoire is back up

10:55 oddcully: woohoo

10:55 arrdem: skeuomorf: fix'd

10:56 skeuomorf: arrdem: YAY, thanks :)

10:56 (inc arrdem)

10:56 GODDAMN YOU BOT, STOP BEING LAZY

10:57 slawo: hey guys, beginner question here

10:57 why is it that in nREPL, I can't do (set! clojure.pprint/*print-right-margin* 140)

10:58 And get a IllegalStateException Can't change/establish root binding of: *print-right-margin* with set clojure.lang.Var.set (Var.java:221)

10:58 oddcully: time for dutifulbot

10:58 slawo: It would seem to me that *print-right-margin* is meant to be changed/rebound

10:58 arrdem: usefulbot

10:58 slawo: but it is stubborn

10:59 having found this in a gist: https://gist.github.com/djKianoosh/2653859

10:59 oddcully: lazbot can go to slack }:P

10:59 skeuomorf: ^

10:59 slawo: it looks dodgy

11:24 gfredericks: jcrossley3: ping

11:34 roelof: is the author of brave and true sometimes here ?

11:43 diphtherial: hello; this is probably a stupid question, but i've installed ultra in an attempt to give myself a colorized REPL, but when i start up 'lein repl' it looks pretty much the same

11:44 is there some special way to launch the repl that enables ultra? i've added the parts specified in the readme to my ~/.lein/profiles.clj file, by the way

11:45 (i'm also using OS X, if that matters)

12:01 stuartsierra: slawo: You can only `set!` a Var which currently has a thread-local binding in effect.

12:01 The REPL creates thread-local bindings for a bunch of common Vars such as *warn-on-reflection*.

12:02 You can still create your own local binding around calls to pprint with `binding`.

12:07 sdegutis: stuartsierra: hey glad to see you're here; just wanted to say that Component is really well designed

12:10 stuartsierra: thank you

12:11 slawo: stuartsierra: thanks, I'll give it a go!

12:28 sdegutis: Is there some Clojure-specific way of creating an #inst that's a given day (like 9/18/2015 at midnight)?

12:29 carkh: (clojure.core.match/match [[:bar :baz]] [([:bar & r] :as m)] m) -> [:bar]

12:30 is that a bug or am i not understanding it ?

12:31 i was expecting [:bar :baz]

12:34 sdegutis: carkh: Yeah I would have expected [:bar :baz] too...

12:34 carkh: Oh no wait, you have too many outer-parentheses I think.

12:34 ,(clojure.core.match/match [[:bar :baz]] ([:bar & r] :as m) m)

12:34 Try that.

12:34 clojurebot: #error {\n :cause "clojure.core.match"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.core.match"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n ...

12:35 sdegutis: carkh: Oh wait no, just remove the & and it works as expected

12:35 carkh: it says : Pattern rows must be wrapped in []

12:35 sdegutis: carkh: (clojure.core.match/match [[:bar :baz]] [([:bar r] :as m)] m) ==> [:bar :baz]

12:36 And r becomes :baz

12:36 And m becomes [:bar :baz]

12:36 carkh: right, but the thing is, i need to take several rest arguments in the real code

12:37 that's just a minimal test case

12:37 sdegutis: Ah. Hmm, it seems that https://github.com/clojure/core.match/wiki/Basic-usage suggests you should use the :seq keyword or something?

12:38 carkh: checking it, but i did see & in this document

12:38 sdegutis: Yeah this doc has & too, along with :seq

12:38 But :seq isn't working for me.

12:39 carkh: i have a match without the :as pattern

12:39 and i can have the :as pattern working without the &

12:39 looks like there is some problem with the interraction of the 2

12:40 sdegutis: Sorry I can't figure it out :/

12:41 carkh: i still can rebuild the vector, i was hoping to avoid that as it's in a rasius server which will get many requests a second

12:41 radius*

12:41 thanks anyways =)

12:46 sdegutis: carkh: You might be able to find some people in the commit history in this channel and ask them?

12:46 carkh: yep, ping dnolen !

12:46 sdegutis: Yeah that guy.

12:47 carkh: looks like any clojure related thing ends up with him =P

12:50 dnolen: carkh: fortunately that's the not the case

12:50 carkh: dnolen: =)

12:51 dnolen: just looks like a bug, file an issue, even better if you submit a patch

12:51 carkh: dnolen: there is no issue thing on github

12:51 dnolen: carkh: Clojure libraries don't use GitHub for issues, JIRA

12:51 http://dev.clojure.org/jira/browse/MATCH

12:52 carkh: ahyes ok thanks will do

12:59 * sdegutis adds "get JIRA account" to TODO list

13:02 carkh: sdegutis: just did it, was quite painless

13:03 sdegutis: For me to make a new account is more involved.

13:43 justin_smith: sdegutis: you didn't troll the clojure jira did you?

13:43 sdegutis: justin_smith: sorry what?

13:43 justin_smith: "For me to make a new account is more involved."

13:53 slawo: hey guys, does anybody have advice on how to make leiningen not download a dependecies transitive test-dependenices?

13:53 I don’t intend to run the test-suite of my deps, so …

13:53 justin_smith: slawo: define the dependency such that its test dependencies are separate from runtime

13:53 slawo: how do I do that?

13:54 justin_smith: there's not much a user of the lib can do

13:54 the author has to fix it

13:54 (or you could fix it for them)

13:54 slawo: If I see it correctly, the scope is set to test on their pom

13:54 and maven did not download that stuff

13:54 the moment I used leiningen

13:54 I got half the internet and an ancient version of guava on my hands :)

13:55 justin_smith: oh, that might be a lein bug then...

13:56 slawo: let me see if I can come up with a minimal case

14:02 urgh, nevermind, my bad

14:02 maven was downloading the stuff too

14:02 justin_smith: yeah, sounds like the lib's fault then

14:03 slawo: quick question: https://github.com/michaelklishin/validateur/blob/master/project.clj

14:03 that’s what I am looking at

14:04 there’s these profiles for different circumstances, and :dev seems to be the one pulling stuff in

14:05 do the profiles translate into something in the generated pom that I can use to get a scoped dependency?

14:05 justin_smith: slawo: yeah, if they are using cljx, they need to ship all those libs to compile it out if they are shipping source

14:05 hmm...

14:06 slawo: I do not know how to convince clojars to tell me what they have https://clojars.org/com.novemberain/validateur/versions/2.4.2

14:08 justin_smith: slawo: what does "convice clojars to tell me what they have" mean? if you go to the main validateur page it shows versions available if that's what you mean https://clojars.org/com.novemberain/validateur

14:08 slawo: what they have in terms of xml :) https://clojars.org/repo/com/novemberain/validateur/

14:08 found it

14:10 clojurescript.test 0.2.1 so this thing is not scoped in the test group, and it downloads hairball (tm) transitively

14:10 thanks :)

14:12 sdegutis: justin_smith: I don't troll anyone anymore except on reddit where it's the only appropriate thing to do.

14:13 justin_smith: sdegutis: if reddit doesn't want trolled it shouldn't wear such revealing comment threads

14:20 sdegutis: hear, hear!

14:30 hlolli: Is there any trick with quoted functions that has a variable that is a local variable in another function. When ever I eval the quoted function, it says it wont recognize a symbol that the function making the call should really recognize. I find it hard to describe, can somone relate?

14:31 justin_smith: hlolli: that's how it's supposed to work

14:31 hlolli: you can make a macro work that way if you really want to, but it tends to be a huge source of bugs

14:31 hlolli: you can't make a function do that

14:32 hlolli: I was thinking if gensymbol would solve anything?

14:32 justin_smith: no

14:32 hlolli: if your function needs something from another scope, then it should be passed in as an argument

14:32 hlolli: ah ok, it did work like that before actually, with arguments. I was somehow sure that was unneccecary. But ok.

14:32 justin_smith: it's intentional that just using the name doesn't work, because free symbols like that make a mess

14:34 hlolli: ok, thanks. I want to try if (defn blabla [arg] (atom '(fn arg))) could work, maybe you know already?

14:35 well with ~ symbol ofc..

14:35 justin_smith: wait, what do you expect that to do? it would put a list in the atom, the first element of that list would be the symbol fn

14:35 hlolli: ah, nevermind, I just try :)

14:36 justin_smith: hlolli: what are you even trying to do here?

14:36 hlolli: I could use this atom for function call in another function. I was hoping for some muteable function calls.

14:36 justin_smith: ,(def a (atom '(fn [])))

14:36 clojurebot: #'sandbox/a

14:36 justin_smith: ,(type @a)

14:36 clojurebot: clojure.lang.PersistentList

14:36 justin_smith: see, like I said, that just puts a list in an atom

14:38 hlolli: ok, that list could be very useful for me, if I can call it somehow in another function with it's own local scope symbols.

14:38 justin_smith: you can't call lists

14:38 I mean I guess you can eval it

14:38 hlolli: no not persistent list

14:38 yes, lingo differences.

14:39 justin_smith: hlolli: the atom has a list in it

14:39 not a function

14:39 hlolli: I am not sure why you are doing this, but I am sure there is a simpler way to do it than putting the source list for a function in an atom

14:39 hlolli: hmm, if you would eval a persistent list with a function call in first position, it will become funcion?

14:40 justin_smith: ,(type (eval '(fn [])))

14:40 clojurebot: sandbox$eval73$fn__74

14:40 justin_smith: yes, you get a function

14:40 but this is not the easy way to do anything

14:40 I promise, whatever it is you are really doing, there is an easier way than that

14:40 hlolli: yes, defenitely, Im really just experimenting with different possibilities. Actually Steven Yi sent me good tips recently to use performancethread. So Im trying to make all function calls in one performance thread.

14:41 what was the code post, postbin.com ?

14:41 justin_smith: use refheap.com

14:41 hlolli: ok 1min

14:46 https://www.refheap.com/109696

14:47 You can see how I'm quoting so I can change the code "on-fly", of course I'd like to make macro for many function calls without manualy editing the event-poll macro. I would like to create seperate functions that append new calls or dicard. Maybe you would know of better way for live-coding scenero?

14:54 justin_smith: hlolli: why can't you have an argument to the function?

14:55 hlolli: also, I don't actually see where you are quoting to change the code on the fly

14:56 hlolli: Yes I can, but the last question was actually about me experimenting with using atom-deref instead event-poll macro. If it could be a muteable variable, I could add as many function calls as I'd wish all with different if statements.

14:56 justin_smith: oh, wait, on line 62?

14:56 hlolli: yes

14:56 if you would run this, you can change the macro on-fly and it can change p3-field and the rem value (now 24)

14:57 justin_smith: hlolli: you don't need to eval or quote, just put the definition before perf-loop

14:57 amalloy: hlolli: if you make event-poll a function instead of a macro, you can just call it

14:57 and then you don't need to eval a list that uses it as a macro

14:57 justin_smith: there's that too

14:58 amalloy: event-poll as written doesn't need to be a macro for any reason

14:58 justin_smith: and if you want to redefine event-poll while developing, call #'event-poll and what it does in the perf-loop will change when you change the definition

14:58 hlolli: well, if I don't use symbol-quote, then if will never re-evaluate the function after I start performance thread.

14:58 it will...

14:58 justin_smith: hlolli: if you use the #'event-poll syntax it will see new definitions without having to restart the loop

14:59 hlolli: ok! yes that too. Ah...

14:59 justin_smith: hlolli: #'f means (var f) and vars are newly derefed each time they are called, and whatever the current val of the var is used

14:59 hlolli: that makes sense, can't bealieve I dint knew this earlier

15:00 justin_smith: hlolli: it's OK, that's why I prompted you for more info, because I was sure there was a simpler way than what you were trying to do before

15:00 hlolli: yes, and I had the feeling you knew a better way too, hehe

15:01 dxlr8r: congrats to me, posted an example. http://clojuredocs.org/clojure.core/defn#example-55fc6077e4b06a9ffaad4fc1 :)

15:04 hlolli: congrats!

15:04 dxlr8r: thx :)

15:04 justin_smith: hlolli: funny enough, I am doing some csound work right now myself, preparing a live instrument for a concert this weekend, it will be running on a raspberry pi so no clojure :P

15:05 hlolli: yes, are you performing?

15:06 justin_smith: yes, solo electronic set. I had high hopes to make a clojure program that would produce my optimized csound code but I won't have that working for the deadline, so I am just coding a state machine controlled by a MIDI controller directly in csound using tables and gotos

15:08 hlolli: ok, I was actually thinking, for long term goal, make a DSL for csound in clojure, or with osc server like overtone. If that is of any interest to csound users. I feel like supercollider is really growing much faster than csound just because of this client-server setup.

15:09 justin_smith: it's because supercollider has a UDP based API

15:09 so it's easy to hook whatever language into that

15:09 hlolli: yes, so my point should not have been clojure per say, but make a osc api.

15:09 justin_smith: csound doesn't have a machine friendly abstraction like that - we are stuck throwing strings together like animals or sql users

15:10 that's a good idea yes

15:10 hlolli: I mean you should be able to do (sin-osc 440) with csound and it can make the macro instr 1 asig poscil 1, 440 etc...

15:11 and rewriting instrument defenitions is possible already with the api.

15:11 it's just a lot of string work I guess, making strings.

15:11 Tagore: I've always liked the perlisgram "The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information."

15:11 justin_smith: (inc Tagore)

15:12 hlolli: it would be good to check out how that guy did his haskell DSL

15:13 hlolli: yes! I've been reading his source code and can't find out how he really did it. Because I NEVER see instr 1 stuff in his source code.

15:14 Well, I think I'll meet him in St. Pete, Im in berlin so it was a cheap flight for me to go to the conference.

15:55 neoncontrails: I didn't get a response when I asked this yesterday, but I'm still curious: when implementing message-passing in Clojure, what type do you typically dispatch on? Are there tradeoffs to using strings vs. quote literals vs. keywords, or is it all ultimately the same thing?

15:56 SICP dispatches on quote literals, but Scheme doesn't have robust support for strings, and keywords are a new type to me

15:57 So it makes sense it would use quote literals -- there's no other choice in Scheme

15:58 triss: not sure I'm 100% following but I think keywords would be the preferred thing in Clojure...

15:59 gfredericks: yeah symbols are not idiomatic to use for everyday things

16:01 neoncontrails: triss: it's a design pattern that SICP uses a lot. A good introduction to it can be found at the bottom of this page: https://mitpress.mit.edu/sicp/full-text/sicp/book/node45.html

16:03 gfredericks: neoncontrails: most uses of symbols are for names that actually refer to some artifact in the code, or similar; keywords are used the rest of the time

16:05 triss: neoncontrails: upon first skim I think this how we handle that sort of polymorphism in Clojure: http://clojure-doc.org/articles/language/polymorphism.html

16:05 multimethods seem similar to me....

16:05 neoncontrails: gfredericks: I think that makes sense. Is there an underlying difference between the two types, or is this strictly by convention?

16:07 triss: neoncontrails: this answer looks splendid: http://stackoverflow.com/questions/1527548/why-does-clojure-have-keywords-in-addition-to-symbols

16:07 neoncontrails: triss: this is great! I was actually wondering if there was a better way to implement this pattern with multimethods... I actually just learned about them a few days ago through dnolen's cljs tutorial

16:08 (inc triss)

16:08 (inc gfredericks)

16:09 triss: multimethods really are rather neat...

16:13 gfredericks: neoncontrails: multimethods can be even better with keywords because you can use inheritance if you need to; I don't *think* you can do that with symbols (but I might be wrong)

16:17 neoncontrails: gfredericks: I would love to see an example of this if you have one :)

16:23 gfredericks: neoncontrails: http://clojure.org/multimethods

16:40 sdegutis: (inc neoncontrails)

16:47 amalloy: gfredericks: you can't

16:48 gfredericks: amalloy: w00t

16:49 ,(-> (make-hierarchy) (derive :foo :bar))

16:49 sdegutis: amalloy: why can't you? why is it limited to keywords?

16:49 clojurebot: {:parents {:foo #{:bar}}, :ancestors {:foo #{:bar}}, :descendants {:bar #{:foo}}}

16:49 gfredericks: ,(-> (make-hierarchy) (derive 'foo 'bar))

16:49 clojurebot: {:parents {foo #{bar}}, :ancestors {foo #{bar}}, :descendants {bar #{foo}}}

16:49 gfredericks: amalloy: ^ um

16:49 amalloy: actually i guess i'm not any more sure than gfredericks probably was when he guessed that

16:49 gfredericks: ,(-> (make-hierarchy) (derive 42 45))

16:49 clojurebot: #error {\n :cause "Assert failed: (or (class? tag) (instance? clojure.lang.Named tag))"\n :via\n [{:type java.lang.AssertionError\n :message "Assert failed: (or (class? tag) (instance? clojure.lang.Named tag))"\n :at [clojure.core$derive invokeStatic "core.clj" 5408]}]\n :trace\n [[clojure.core$derive invokeStatic "core.clj" 5408]\n [clojure.core$derive invoke "core.clj" -1]\n [sandbox$eval7...

16:49 sdegutis: ,(-> (make-hierarchy) (derive "foo" "bar"))

16:49 clojurebot: #error {\n :cause "Assert failed: (or (class? tag) (instance? clojure.lang.Named tag))"\n :via\n [{:type java.lang.AssertionError\n :message "Assert failed: (or (class? tag) (instance? clojure.lang.Named tag))"\n :at [clojure.core$derive invokeStatic "core.clj" 5408]}]\n :trace\n [[clojure.core$derive invokeStatic "core.clj" 5408]\n [clojure.core$derive invoke "core.clj" -1]\n [sandbox$eval9...

16:49 amalloy: you're not *encouraged* to, but evidently you can

16:50 justin_smith: for top level heirarchies, only namespaced keywords are accepted

16:50 sdegutis: Also symbols lack ::this-feature of keywords.

16:50 justin_smith: I wonder if namespaced symbols are?

16:50 sdegutis: So that's something to consider.

16:50 gfredericks: ,`this-feature

16:50 clojurebot: sandbox/this-feature

16:50 justin_smith: ,(derive 'foo/bar 'foo/baz)

16:50 clojurebot: nil

16:50 sdegutis: You can do it manually like 'this/feature but ::feature turns into :this/feature when you're inside 'this *ns*.

16:50 justin_smith: ,(isa? 'foo/baz 'foo/bar)

16:50 clojurebot: false

16:50 gfredericks: I guess ` is slightly different

16:51 justin_smith: ,(isa? 'foo/bar 'foo/baz)

16:51 clojurebot: true

16:51 gfredericks: ,[::first `first]

16:51 clojurebot: [:sandbox/first clojure.core/first]

16:51 justin_smith: so yeah, derive even accepts symbols at the top level, but they are clumsier to use

16:51 sdegutis: ,`foo

16:51 clojurebot: sandbox/foo

16:51 gfredericks: amalloy: man we were so wrong

16:51 amalloy: gfredericks: incidentally it looks like this limitation is only an assertion in derive; there's no functionality that depends on this

16:51 gfredericks: amalloy: yeah I figured as much

16:52 sdegutis: ,`(foo)

16:52 clojurebot: (sandbox/foo)

16:52 amalloy: so you could reimplement derive without that assertion, and then you could inherit 44 from f1

16:52 gfredericks: inherit one hierarchy from another

16:52 sdegutis: amalloy: so it's a disciplinary limitation not a technical limitation

16:52 neat

16:53 Personally I prefer to inherit vars from namespaces.

16:53 And dates.

16:54 ,(-> (make-hierarchy) (derive (java.util.Date.) (java.util.Date.)))

16:54 clojurebot: #error {\n :cause "Assert failed: (not= tag parent)"\n :via\n [{:type java.lang.AssertionError\n :message "Assert failed: (not= tag parent)"\n :at [clojure.core$derive invokeStatic "core.clj" 5407]}]\n :trace\n [[clojure.core$derive invokeStatic "core.clj" 5407]\n [clojure.core$derive invoke "core.clj" -1]\n [sandbox$eval289 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval289 invoke "NO_SOU...

16:54 gfredericks: (doseq [[n1 n2] (partition 2 1 (range))] (derive n1 n2))

16:54 sdegutis: comma

17:03 eriktjacobsen: How to get namespace a function resides in from inside that function? *ns* refers to core at runtime

17:04 string of the namespace

17:04 justin_smith: eriktjacobsen: functions don't have namespaces

17:04 vars do

17:04 and vars can hold functions

17:04 hiredman: functions don't live in namespaces, names do

17:05 gfredericks: (inc hiredman)

17:06 * gfredericks forgot the incs were broken

17:06 eriktjacobsen: Ok. lets say I have a “cache” function defined somewhere, and everytime its called (from outside namespaces), I want to include a string version of the namespace that called it as a prefix.

17:06 gfredericks: for what purpose?

17:06 justin_smith: functions do not get that kind of information from callers

17:06 unless they pass it in

17:08 hiredman: my guess is because his "cache" is a bit of global state and he wants to give different clients different views over it

17:08 eriktjacobsen: gfredericks: to namespace the cache. afaik timbre does this with its log output. Ok. lets make it simplier and say I’ll pass it in. How would the var holding a function calling the cache pass its own namespace? again *ns* goes to core not the ns where the var is defined in

17:08 hiredman: functions don't have an own namespace

17:09 neoncontrails: eriktjacobsen: I defer to justin_smith on how you would actually implement this, but it sounds like you're trying to write a macro.

17:09 eriktjacobsen: Right I said the var holding the function…

17:09 hiredman: eriktjacobsen: I'd suggest not doing that

17:10 eriktjacobsen: I’m fine using a macro for this.. I’m just looking for absolutely any way to get a string version of the namespace from inside the function held by a var that is defined in that namespace

17:10 hiredman: eriktjacobsen: have the cache be some local state that a client can ask for, and then if you want different caches for different places then have the client ask for a new cache

17:12 implicitly namespacing your cache entries based on clojure namespaces is very fragile

17:12 eriktjacobsen: I’m simplifying the problem so we don’t get bogged down in details. For my actual purpose, I really need the namespace. I know this is possible, Timbre logging appends the namespace it was called from, so if you call (info blah) from anywhere inside api.foo.bar, it’ll print “api.foo.bar” in the output for that line. thats what I’m trying to replicate.

17:20 neoncontrails: eriktjacobsen: There should be a way to alias those namespace strings and map them to the original. Do the examples on this page help? https://clojuredocs.org/clojure.core/ns-aliases

17:23 eriktjacobsen: neoncontrails: thanks. In those examples, you must know the ns you are passing as argument into ns-aliases… i’m looking to find way to GET that ns. For instance… in file api.foo that has (ns api.foo) declared at top, I want (defn ns-string [] ???) to return “api.foo”. I just don’t know what would go in ???

17:33 gfredericks: eriktjacobsen: there's an easy way to do this with a macro, people just aren't telling you because they don't think it's a good idea

17:33 ,(str *ns*)

17:33 clojurebot: "sandbox"

17:33 gfredericks: ,(defmacro the-calling-namespace [] (str *ns*))

17:33 clojurebot: #'sandbox/the-calling-namespace

17:33 gfredericks: ,(the-calling-namespace)

17:33 clojurebot: "sandbox"

17:34 gfredericks: ,(defmacro assoc-calling-namespace [m] `(assoc ~m :ns ~(str *ns*)))

17:34 clojurebot: #'sandbox/assoc-calling-namespace

17:34 gfredericks: ,(assoc-calling-namespace {:foo 431})

17:34 clojurebot: {:foo 431, :ns "sandbox"}

17:35 gfredericks: also if you're not familiar with macros you might have a hard time making sense of how that works

17:36 eraserhd: I'd love advice for working with a Clojure newb who really wants to see a debugger and feels like they can't do anything without one.

17:38 They want to be able to see "intermediate results" which, you know, clojure so ...

17:40 gfredericks: (doto x prn) is pretty easy to type; I also wrote github.com/gfredericks/debug-repl which is kind of haxy but seems to still be useful in real life

17:40 it's not a debugger but it covers a lot of use cases; I think there are real debuggers too, like that thing what colin wrote

17:40 cursive

17:40 no idea about the current state of debuggers in emacs

17:41 eraserhd: doto! Doh! I've been using (as-> x (do (prn x) x)).

17:41 amalloy: ~doto is a solution to any problem

17:41 clojurebot: Ack. Ack.

17:43 eriktjacobsen: gfredericks: thank you

17:43 gfredericks: eriktjacobsen: np

17:48 cfleming: I think I'm going to use "that thing what colin wrote" as the new subtitle for the Cursive website.

17:48 xemdetia: have it appear in the about box

17:48 cfleming: Along with a tshirt for conferences saying "I'm the Cursive guy"

17:49 xemdetia: "primary schools don't need cursive anymore but I think you do"

17:49 cfleming: Oh that's nice

17:49 Clearly I need to crowdsource my marketing

18:05 justin_smith: true story, I've been relearning actual cursive penmanship. I found a place where I could buy the spencer worksheets and everything

18:06 cfleming: justin_smith has realised the need for Cursive

18:29 eriktjacobsen: justin_smith: I setup my 3d printer to act like pen plotter and write out perfect cursive / calligraphy, way better than I could :)

18:33 amalloy: well presumably justin_smith wants to do it by hand for whatever reason. you don't have to stop walking just because cars are better at getting places

18:33 justin_smith: sounds like a fun project, but I'm relearning cursive as something to do with my hands that is radically different from typing

18:33 exactly

18:54 crowgoose: lul

18:54 eraserhd: I'm pretty sure I can't print legibly anymore.

18:55 I think I'd rather tap two neurons for a serial port.

19:05 gfredericks: ~cursive is that thing what colin wrote

19:05 clojurebot: Ik begrijp

19:20 triss: ok this is a long shot... is there a simple means of looking up the names of args for a function?

19:22 domgetter: triss: at runtime? Or do you mean just looking up docs?

19:22 gfredericks: ,(meta #'first)

19:22 clojurebot: {:arglists ([coll]), :doc "Returns the first item in the collection. Calls seq on its\n argument. If coll is nil, returns nil.", :added "1.0", :static true, :line 49, ...}

19:22 triss: at runtime, like a proper dirt bag

19:23 awesome thanks guys!

19:23 I don't even feel that dirty

19:24 what does #' do?

19:24 I know ' is quote

19:25 amalloy: ,'#'foo

19:25 clojurebot: (var foo)

19:27 triss: yup same as saying (var blah)

19:27 sooooo...... I need to read up on var etc.

19:57 mungojelly: i thought about making my grids maps of maps of tiles but then i realized that's equivalent to making an index and then i realized that database writers are better at writing that algorithm than i am, so i'm not going to try to hand roll my own indexing that won't help anyone :)

20:11 neoncontrails: justin_smith: relevant to your interests, perhaps http://www.cs.toronto.edu/~graves/handwriting.cgi

20:25 rary: Hello, guys! I've read so many nice things about your community that I decide to learn Clojure.

20:26 justin_smith: lol crowgoose tried to DCC "virus.exe" to me

20:26 rary: welcome!

20:27 mungojelly: rary: i just started learning too. the community is nice enough but lots of communities are nice but here the language also just works so amazingly well and reaches everywhere and does everything.

20:31 rary: I've downloaded LightTable, because Emacs make me feel bad (sorry, it is great and so on, but I am too stupid for it).

20:32 mungojelly: like earlier today i set myself the task of learning how to connect to firefox's databases and draw out the most recent youtube videos i've been to-- but that was too easy, it was just one simple line that was easy to figure out :o

20:34 clojure dissolves all ordinary limitations and gives you delusions of grandeur

20:34 rary: mungojelly: wow, it sounds cool.

20:38 Okay, I thing it would be better for me to transit myself on #clojure-beginners.

20:38 mungojelly: rary: i'm on #clojure-beginners and it's been quiet, mostly there's room for simple questions here, just a few conversations here throughout a normal day

20:39 egogiraffe: justin_smith: heh, person tried sending that to me, too. at least they're honest, yanno.

20:40 mungojelly: actually #clojure-beginners hasn't had any conversation at all since i joined. maybe we should go talk about simple things there to give it some life. :)

20:40 rary: :D

20:42 mungojelly: i don't know much clojure yet in the big perspective but i know enough i could teach some basics if we had real beginners asking real beginner questions

20:44 justin_smith: rary: you might find intellij idea + cursive a more powerful and less buggy environment eventually, but light table can be a good start if you can handle its quirks

20:46 mungojelly: rary: beginners are free to talk here, but it's nice to have #clojure-beginners available if this channel gets all excited about advanced stuff about the compiler internals (which is known to happen)

20:46 basically, we don't want to miss someone's basic question because there's lots of scroll about another topic

20:48 rary: justin_smith: thank you for advice, I'll definitely try Cursive too.

20:57 TEttinger: I should pop into #clojure-beginners and ask about stuff like how to configure pmap to use more or less threads

21:01 justin_smith: TEttinger: hah

21:02 TEttinger: first step is to check out the clojure source, and find the code for pmap

21:02 TEttinger: I've built up way too much knowledge on the weird and arcane parts of clojure optimization and not enough on the practical stuff.

21:03 justin_smith: TEttinger: I just got clojure applied in the mail, and it has a good overview of what I would call the practical stuff

21:05 TEttinger: I do wish there was a better way to understand when clojure boxes things

21:05 ,(class (int 21)) ; is not handy

21:05 clojurebot: java.lang.Integer

21:05 justin_smith: TEttinger: NaN is the champ of all time, and wins all Boxing matches

21:06 TEttinger: it's beaten infinity twice

21:06 ,(* 2.0 (/ 1.0 0.0))

21:06 clojurebot: Infinity

21:06 TEttinger: hm

21:06 ,(/ (/ 1.0 0.0) 0.5)

21:06 clojurebot: Infinity

21:07 TEttinger: ,(* (/ 1.0 0.0) (/ 1.0 0.0))

21:07 clojurebot: Infinity

21:07 TEttinger: how did I get it...

21:07 amalloy: TEttinger: basically anytime you do something with a primitive other than (1) math or comparisons with it and another primitive; (2) call a java method taking a primitive; (3) call a clojure function hinted with the matching primitive type in its args

21:07 justin_smith: ,(* 2.0 (/ 1.0 0.0) (/ 0.0 0.0))

21:07 clojurebot: NaN

21:07 justin_smith: it consumes all it touches

21:07 TEttinger: ,(* (/ 1.0 0.0) (/ -1.0 0.0))

21:07 clojurebot: -Infinity

21:07 justin_smith: ,(/ 0.0 0.0)

21:07 TEttinger: ,(- (/ 1.0 0.0) (/ -1.0 0.0))

21:07 clojurebot: NaN

21:07 Infinity

21:08 TEttinger: ,(- (/ 1.0 0.0) (/ 1.0 0.0))

21:08 clojurebot: NaN

21:08 amalloy: you'll infect us all, justin_smi NaN

21:08 TEttinger: ah

21:08 infinity minus infinity is NaN

21:08 justin_smith: that's another way to make it yeah

21:09 amalloy: ,(* 0 (/ 1 0.0))

21:09 clojurebot: NaN

21:09 amalloy: oh that's the one justin_smith did

21:10 ,(/ (/ 1.0 0) (/ 1.0 0))

21:10 clojurebot: NaN

Logging service provided by n01se.net