#clojure logs

2015-03-23

00:02ben_vulpesahahaha
00:02ben_vulpesi very definitely wired a figwheel server into the reloaded/component/system flow.
00:02ben_vulpesyussss.
01:46SeyleriusHow d'you recurse an anonymous function?
01:47TEttingerSeylerius: give it a name. ##((fn rec [n] (if (> n 5) n (rec (inc n)))) 0)
01:47lazybot⇒ 6
01:48SeyleriusWhy the ##?
01:48TEttingerfn allows names for this exact purpose
01:48TEttingerjust telling lazybot to eval
01:48SeyleriusShiny
01:48TEttinger((fn rec [n] (if (> n 5) n (rec (inc n)))) 0)
01:48TEttingeris the actual snippet
01:50SeyleriusAwesome, thanks.
01:51SeyleriusWow, my internet really slows down in the rain...
01:52TEttingersatellite internet?
01:52TEttingeror cellular of some kind?
01:52SeyleriusWireless. 802.11n over TDMA, essentially, broadcast from a tower at the head of the lake.
01:53TEttingerhow far does this reach? wow
01:56Seylerius##(fn flatify [coll] (loop [remainder coll result []] (if (empty? remainder) result (if (coll? (first remainder)) (recur (rest remainder) (concat result (flatify (first remainder)))) (recur (rest remainder) (conj result (first remainder)))))))
01:56lazybot⇒ #<sandbox6330$eval45317$flatify__45318 sandbox6330$eval45317$flatify__45318@271546bb>
01:56SeyleriusWait...
01:56SeyleriusForgot to make it do something.
01:56Seylerius##((fn flatify [coll] (loop [remainder coll result []] (if (empty? remainder) result (if (coll? (first remainder)) (recur (rest remainder) (concat result (flatify (first remainder)))) (recur (rest remainder) (conj result (first remainder))))))) [1 [2 3] 4])
01:56lazybot⇒ (4 1 2 3)
01:56SeyleriusHrm.
01:57SeyleriusAhah.
01:58Seylerius##((fn flatify [coll] (loop [remainder coll result []] (if (empty? remainder) result (if (coll? (first remainder)) (recur (rest remainder) (concat result (flatify (first remainder)))) (recur (rest remainder) (concat result [(first remainder)])))))) [1 [2 3] 4])
01:58lazybot⇒ (1 2 3 4)
01:58Seylerius^_^
01:59TEttingerSeylerius, is this for 4clojure?
01:59TEttinger~flatten
01:59SeyleriusIt is.
01:59clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
01:59SeyleriusFlatten is in fact the task.
01:59TEttingerthat's a good solution though
02:00SeyleriusThanks.
02:01TEttinger,(defn flatify [coll] (loop [remainder coll result []] (if (empty? remainder) result (if (coll? (first remainder)) (recur (rest remainder) (concat result (flatify (first remainder)))) (recur (rest remainder) (concat result [(first remainder)]))))))
02:01clojurebot#'sandbox/flatify
02:02TEttinger,(flatify [:a :b {:a 0 :b #{1 2 3}}])
02:02clojurebot(:a :b :a 0 :b ...)
02:02TEttinger,(flatify [:a { :b #{1 2 3}}])
02:02clojurebot(:a :b 1 3 2)
02:02TEttingernice!
02:03SeyleriusI'm a little prone to over-engineering things, but I prefer the fully generalized solution where possible.
02:04amalloySeylerius: flatten is a lot easier to implement with mapcat than with loop/recur
02:04Seyleriusamalloy: I'll take a look at mapcat.
02:04SeyleriusHmm... Interesting.
02:05amalloy,((fn flatify [x] (if (coll? x) (mapcat flatify x) [x])) '[1 2 [3 [4] 5] [6 (7)]])
02:05clojurebot(1 2 3 4 5 ...)
02:05SeyleriusNice.
02:17Seylerius##((fn [string] (apply str (re-seq #"[A-Z]" string))) "HeLlO, WoRlD!")
02:17lazybot⇒ "HLOWRD"
02:19SeyleriusSo, what's the deal with clojurebot and lazybot? Does lazybot eval any s-exp that starts with a double-# and discards after eval, while clojurebot expects the whole line to be a s-exp that starts with a comma, and it keeps state?
02:34amalloySeylerius: close enough. lazybot also evals lines starting with &, and allows ##'(expressions) to appear mid-sentence
02:34lazybot⇒ (expressions)
02:34SeyleriusNeat.
02:34SeyleriusAnd lazybot discards, while clojurebot doesn't?
02:35amalloywell, "discards". lazybot doesn't allow definitions
02:36amalloyclojurebot evals more or less anything, and throws away the whole VM every 15 minutes or so
02:37SeyleriusGotcha. Shiny.
02:38SeyleriusWhat about the ,(inc amalloy) stuff? That get discarded?
02:38SeyleriusOr is that maintained separately?
02:38amalloySeylerius: it's a separate thing. not really clojure at all, just a regex that matches something like (inc|dec username)
02:39SeyleriusRight.
02:39amalloy(inc Seylerius)
02:39lazybot⇒ 1
02:39Seylerius(inc amalloy)
02:39lazybot⇒ 240
02:39SeyleriusFor answering all these damn questions.
02:51vascan i upsert enumerated types in datomic?
03:36dstocktonhow would i get the metadata for a var defined in another namespace?
03:39dysfundstockton: (meta #'namespace/var)
03:39dstocktondysfun: so i'd have to know the symbol of the var in that namespace
03:40dstocktonits actually a fn argument, so in my current namespace has a completely different var
03:40dysfunif you don't manually attach metadata, it's attached to a symbol
03:40dysfuner to a var, sorry
03:40dysfunnot to a value
03:40dstocktonyeah, i guess i'll have to rethink what im doing then
03:40dysfunthe user can quote it and you can use find-var, or you can wrap it in a macro to deal with the quoting
03:41dstocktonim building some widgets, wanted to add configuration data to the component fns
03:41dysfunyes, perhaps start by explaining what you're trying to do :)
03:41dstocktonlike {::required true}
03:41dysfunwidgets could be any number of things. could you be a little more specific?
03:41dstocktonom component fns
03:41dysfunoh right
03:41dstocktonits actually cljs
03:42dysfunyou probably want a macro to make it tidy
03:42dysfunor put the component in a datastructure with meta information
03:43dstocktonstill not sure where i'd stick the metadata to make it more tidy, so that i could reference it later
03:43dstocktoni could wrap them in another map i suppose
03:43dysfuna code example might help. http://refheap.com/
03:47dstocktonboils down to something like this https://www.refheap.com/98788
03:49dysfunhrm, it looks alright
03:49dysfuni don't have an om project in a state i could test it, mind
03:51dysfunbut i'm guessing you're adding tracking tags heh
03:54dstocktonmeta is just nil, i guess because widget is a completely different var to the original definition
03:55dysfunoh i see
03:56dysfunthat's because the function 'component' has metadata, not the value you're checking
03:56dysfunhowever, you can use with-meta to wrap meta on the result
03:56dysfunhowever, i bet if you (meta #'component), you should see it
03:59dstocktonprobably dysfun, but i don't know the var's name inside some-fn
03:59dstocktonit would be #'widget (wouldnt work)
03:59dysfun,(meta (with-meta :foo {:bar :baz}))
03:59clojurebot#error{:cause "clojure.lang.Keyword cannot be cast to clojure.lang.IObj", :via [{:type java.lang.ClassCastException, :message "clojure.lang.Keyword cannot be cast to clojure.lang.IObj", :at [clojure.core$with_meta__4097 invoke "core.clj" 216]}], :trace [[clojure.core$with_meta__4097 invoke "core.clj" 216] [sandbox$eval25 invoke "NO_SOURCE_FILE" 0] [clojure.lang.Compiler eval "Compiler.java" 6784] ...
04:00dysfunor similar. you get the idea
04:00dstocktonso wrap the defn in a with-meta?
04:00dysfunno, wrap the code inside the defn in with-meta
04:00dstocktonaha
04:01dysfunalthough you may just want to create a custom record for it
04:01dysfun(that implements IRender)
04:01dysfunthat way you can attach whatever information you like
04:03dstocktondysfun: great, that works
04:03dysfunthinking about it, that's how i'd play it
04:03dstocktonfeels kind of hacky but could clean it up with a custom record like u say
04:04dstocktonso i end up having to call it like (meta (widget))
04:05dysfunno
04:05dysfunyou don't need the metadata now
04:05dysfunthey'll just be fields in the record
04:06dstocktonoh, i see what you mean
04:06dysfun(defrecord foo [name] om/IRender (render [_
04:06dysfun...)
04:07dysfuni haven't played enough with om to a get a feel for what the useful idioms are, but that seems like a generally useful pattern in this case
04:07dstocktonusually the records are created on the fly with reify
04:08dysfunyes. there's no need to do it that way
04:10dstocktonok, thanks for the advice, think im on the right track now
04:11dysfunyw
04:23noncomi have just cloned my project from the repo, and here's what i am getting with leiningen: https://www.refheap.com/98791
04:23noncomhow can i fix this?
04:26TEttingerat java.io.WinNTFileSystem.canonicalize0 (WinNTFileSystem.java:-2
04:27TEttingerthat -2 is a little crazy
04:28TEttingerso it thinks you're in an unsafe to delete directory, apparently https://github.com/technomancy/leiningen/blob/master/src/leiningen/clean.clj#L69
04:32noncomalso, another symptom is that lein deps can't find clojars or maven repo and update the deps..
04:33noncomneither UAC nor firewall are enabled on this machine.. hmm, strange thing
04:37stainnoncom: http proxy settings?
04:37stainoh hang on.. on the file system!
04:38noncomstain: well, lein suggested that too, but no, no proxying here..
04:38stainnoncom: and you are not running two builds at the same time, right?
04:38noncomyeah, i have no builds running, since it cannot even fetch the deps
04:38stainhow did you do the git clone?
04:39stainfrom another local repository, or from the network?
04:39noncomit was hg clone.. but i did this from eclipse + ccw, fetching from bitbucket.org
04:39noncomi did not have this problem before..
04:39stainok, I know this is silly.. but try shutting down Eclipse
04:40stainthis is Windows - which has very eager file and directory locking
04:40noncomi shut it down, but it is still the same. also, eclipse was never an issue before..
04:41stainhttps://github.com/stain/jdk8u/blob/master/src/windows/classes/java/io/WinNTFileSystem.java#L428
04:41noncomheh.. idk what is going on.. i would suppose some problems in paths in project.clj, but the repo worked fine just yesterday on two different machines and there were no commits to it since then
04:42stainand https://github.com/stain/jdk8u/blob/master/src/windows/native/java/io/WinNTFileSystem_md.c#L243
04:43stainhave your project.clj got any hard-coded paths in it?
04:44noncomnot really.. besides, it just wokred on two other machines just yeaterday..
04:46pkughi there, i just recently started diving into Clojure as a disappointed Python developer looking for some cleanliness and peace of mind ..:) currently i'm reading the highly regarded Joy of Clojure but it's keeping my pace and excitement kind of slow, it'd be nice to jump straight into program and algorithm composition patterns and some well commented real world examples to eventually start coding, i've found rosetta code a good resource so far but it lacks co
04:47dysfunthat cut off at 'lacks co'
04:47dysfunanyway, TJOC is more a tour through the entire language. it's a very good piece to notch yourself up a level, but it's definitely not like e.g. 'dive into python'
04:48dysfun4clojure is a good way to learn
04:48pkugoh sorry - but it lacks comments, what could you guys suggest in addition?
04:48pkugthanks
04:49dysfuni'd recommend picking a project and building it. we can point you in the right direction once you've decided
04:50noncomstain: ehh, well, problem is here anyway.. i have to leave now from this machine, so, probably this mystery will never be resolved.. although on my record it happens for the second time.
04:51stainpkug: Clojure in Action is a bit more like that - lots of simple piece meals that don't really connect. The second edition is in the MEAP programme, so you cean read it before its' finished: http://www.manning.com/rathore2/ (basically beta-testing the book)
04:51TEttinger$mail noncom it is possible windows or a firewall locked the files when you checked them out. I know downloading zips from github has them blocked by default, including all their contents, which prevents them from going out and making network calls
04:51lazybotMessage saved.
04:52dysfunstain, pkug: i was disappointed by the first edition, fwiw
04:52dysfuni tried to learn clojure out of it
04:53staindysfun: yeah, it didn't quite do it for me either.. I liked more Joy of Clojure - that is true to its title and is good to get you started.. although it's more like a "taster tour"
04:53pkugdysfun: ok so i'm currently doing a Coursera's course on discrete optimization and i'd like to tackle those problems with Clojure instead of Python for eg.. i doubt i'll be able to learn a new language and utilize optimization techniques so quick (it'd be pretty hardcore but i guess worth a try). So for instance it could be implementing a travelling salesman or graph coloring with constraint programming or dynamic programming algorithms.
04:53stainthe O'Reilly one I haven't read
04:53stainhttp://www.clojurebook.com/
04:53stainit's a bit old now
04:54dysfunpkug: okay. well most of that is data structure manipulation. which means list comprehensions and conditionals in python, yes?
04:54TEttingerclojure's definitely a good pick for graph-type algos
04:54dysfunin clojure, most everything boils down to mapping and reducing data structures
04:55TEttingeryep. map, reduce, some filter in there, and plenty of delicious anonymous fns
04:55pkugdysfun: correct, i could attempt to "translate" what i wrote in Python to Clojure but I feel there's supposed to be some "magic moment" when you can approach those problems in a different cleaner way rather than imperative Python:)
04:55stainand with the lazy sequences you can often do "the naive thing" and still run it quite efficiently
04:56anei started learning clojure just by getting my hands dirty with a project
04:56dysfunpkug: well you find yourself not using mutation, that's a good start
04:56stainpkug: right, trying to do it imperatively in Clojure will not be so much fun.. as you will be fighting against the language
04:56dysfunanyway, ultimately everything boils down to composing a bunch of simple higher order functions
04:56dysfunanything involving data structures, anyway
04:56stainane: me2, started with a mini-webserver for something trivial with a fair bit of data structure manipulation
04:57dysfunand then once you've written it, you can look at how to tidy it up
04:57dysfunand suddenly the code is half the size and you're like "wow, lisp is cool"
04:57stainand then you go a bit overkill for a few months
04:57pkugright and those examples in rosetta code are really tempting, for instance if you take a look at sudoku it's really short yet feels clean and nice (loc is probably not a good measure, i know)
04:57stain"I can generate a function that generates that metafunction!"
04:58kungiHow would you convert a BufferedInputStream to a String?
04:58kungiIs there some magic helper function?
04:58dysfunyou can read from the stream. eg. slurp
04:58dysfunthough that might not take a stream, i don't remember
04:58dysfun,(doc slurp)
04:58clojurebot"([f & opts]); Opens a reader on f and reads all its contents, returning a string. See clojure.java.io/reader for a complete list of supported arguments."
04:59Empperislurp can eat a stream
04:59staindon't forget that character set..
04:59pkugi think most of the solutions in J and Clojure there are the shortest ones, of course i find J really hard to read though
05:00kungidysfun: \o/ thank you
05:00dysfunclojure tends to score quite well on code golf because the standard library is very pragmatic
05:00TEttingerJ is unbelievably terse, but it's pretty much write-once, read-never
05:00stain:encoding "UTF-8" is probably what you need
05:00Empperiyeah, I suggest using that too
05:01Empperi:encoding that is
05:02stain(it will use UTF-8 by default anyway - but often it's good to be explicit in case you later find out it wasn't UTF-8)
05:02staine.g. an InputStream from a network or file location
05:02stainand perhaps a bit of Windows
05:02TEttingerif you're looking for code golf, I'm pretty happy with some of the techniques used in this HP-Lovecraft-book-cult-style text generator
05:02TEttinger&(let[a #(apply str(flatten %))r repeatedly p partition N rand-nth n #(a(N(concat(repeat %"")(mapcat p[1 2 3]%&))))v #(n 0"aioeu""iaai")w(fn[](let[b(n 6"!.""""...")s[(n 0"STKNYPKLG""GlThShNyFt""ZvrCth")(r(N[1 2])#(do[(v)(n 9(map str"'-"(r 2 v)))(n 0(concat"lpstnkgx"[(N["h""gl""gr""nd"])(v)])"rlthggghtsltrkkhshng")]))]][b(if(seq b)[" "s][(n 3",")" "(.(a s)toLowerCase)])]))](re-find #"[A-Z].+"(a[(r 500 w)"."])))
05:02lazybot⇒ "Gliarlirk theng kindek... Thalalt! Zvrai-urk pakuth glail, nyia'ouai'igh... Glend ne-iak shiten! Kiaiegg pesh. Shagu'iash, nyaithogr sult! Thex... Yak gegil! Ku-axa'okh so-inguh! Soggias. Cthaie'iagg, thoth siagish, gliagh ftet, kiat! Ftu'akhung. Tha-ung! Pixelt fti... https://www.refheap.com/98793
05:03TEttingerdo not attempt to understand it
05:03TEttingerit was shrunk repeatedly to fit in one IRC message
05:03TEttingerit makes use of a ton of really neat clojure-only features though
05:04TEttingerit treats strings as sequences of characters so it can split them into single-char sequences, two-char sequences, and 3-char sequences
05:04TEttingerit makes use of map with two collections of different length, which terminates when it reaches the shorter length
05:06stainTEttinger: oh my, that made Klingon!
05:06TEttingerhaha
05:06TEttingerI have a bunch of these generators
05:07stainyou have just insulted my mother, I shall have to honour her and kill you
05:07TEttingerthey're really fun to write, it's a real challenge to make them small enough to fit in ~400 chars
05:08TEttingera much cleaner, longer version of a similar program that generates planet names and trims swears from the list: http://ideone.com/zwnFAL
05:08pkugTEttinger: that's quite hard to read for a newcomer:) is it common for people to rely on some sort of editors highlighting different logic parts of parentheses (if/then/else parts etc.) and current blocks being edited ?
05:09TEttingerabsolutely. it's very difficult to write clojure without paren matching at least when you highlight a paren
05:09TEttingerwhich thankfully everything a step past notepad can do
05:09dysfunalso rainbow parens
05:10TEttingerif you're used to IDEs, Cursive not only is a nice environment for writing Clojure, it provides one of the few really high-quality debuggers for clojure
05:10TEttingerCursive is an IntelliJ IDEA plugin or something like that, not sure of the exact term
05:10dysfunhttps://github.com/jjl/elisp/blob/master/cust/jproject-cust.el the top of this is how i've set up emacs for clojure. or at least the last version that's on github
05:11TEttingeractually even lein repl provides paren matching, since version 1.0 I think
05:11TEttingeralso tab completion
05:11dysfunboth have been in there a while
05:12pkugok, and what about vim? i see internet generally recommends vim-fireplace it has repl integrated, should come with paren matching too then
05:12dysfundunno. assuming people do packages like emacs, you probably need rainbow-parens separately
05:12stainpkug: yeah, I am happy enough with parens-matching using % in gvim (it swaps to the opposite side) - but can't stand myself rainbow parentheses
05:12anevim isn't as smart about lisps as other editors
05:12oddcullypkug: fireplace works like a charm for my beginner needs
05:14anecider and clj-refactor make emacs a really nice clojure environment
05:16the_freyyeah I still use other editors work work in ruby || some_lang but really look forward to working with clj/emacs when I have clojure to do
05:16pkugstain: yup there's an extended matchit plugin.. i guess right now it's been integrated into vim by default, it makes it easy to set up custom tag matching as well using same "%"
05:17aneplus you can get vim inside emacs anyway :P
05:19stainane: nooooooooo!
05:21oddcullyane: does it really run an instance or does ist just "emulate" (which usually takes about 2s to see that it does not work at all *coughintellijcough*)
05:23clyfehelp https://gist.github.com/clyfe/1ffe4a8857d40f00e789
05:23stainAtom with vim and clojure mode is also kind-of OK
05:50aneoddcully: it does not run an instance, it provides a vimlike modal interface to edition. it's called evil-mode
05:52aneoddcully: and it is about ten thousand times better than the intellij emulation
05:56oddcullyane: (* 0 10000) ;P
05:58aneheh
06:03dysfunjust found ^:unsynchronized-mutable. is that documented anywhere?
06:06mpenetdysfun: in deftype probably
06:07mpenet,(doc deftype)
06:07clojurebot"([name [& fields] & opts+specs]); (deftype name [fields*] options* specs*) Currently there are no options. Each spec consists of a protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* Dynamically generates compiled bytecode for class with the given name, in a package with the same name as the current namespace, the given fie...
06:07mpenetwell :]
06:08dysfunheh
06:09mpenetit's jvm specific btw, cljs has :mutable I think
07:54m1dnight_guys, for some dark reason leiningen takes ages to compile. Instead of like half a minute it takes about 1-2 minutes.
07:54m1dnight_Any way to debug this?
07:54m1dnight_it's very small project with maybe 5 files.
07:55m1dnight_or could it be due to dependencies?
07:56TEttingerm1dnight_, have you tried https://github.com/technomancy/grenchman
07:56hyPiRionm1dnight_: `lein version` runs fine?
07:57m1dnight_ill try soon, code is still compiling :/
07:58m1dnight_hyPiRion: that works fine, yes
07:58m1dnight_Leiningen 2.5.1 on Java 1.7.0_75 OpenJDK 64-Bit Server VM
07:58borkdudeis is possible in clojure to indent long string literals nicely like in other languages, like Scala?
07:59hyPiRionm1dnight_: and if you do `lein compile` now, how long does it take? Still as long?
07:59hyPiRionIt might be that you had to AOT compile the dependencies too
07:59m1dnight_strange, that completes rather quick
08:00m1dnight_weird, now a simple lein run executes perfectly
08:00hyPiRionhm
08:01m1dnight_lein clean && lein run seems to run fine now
08:01m1dnight_strang
08:01m1dnight_lets blame cosmic noise
08:01hyPiRionyeah, dang those cosmic rays
08:02borkdudelein was probably submitting privacy sensitive usage statistics
08:02m1dnight_:D
08:03TEttingerborkdude, since s-expressions don't have a concept of indentation, I'm not so sure that's a good idea
08:08dstocktonborkdude: maybe just break it up with str over many lines?
08:24spinningarrowhas anyone used the rainbow_parentheses plugin for vim (https://github.com/kien/rainbow_parentheses.vim)? I'm trying to enable it only for clojure files (instead of all files), but I can't figure out how.
08:27spinningarrowanyone?
08:27clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
08:29TEttingerspinningarrow, uh it's pretty early in most of the US, Vim came up a little while ago so probably someone can answer (dysfun?)
08:30whodidthishttps://github.com/amdt/vim-niji this should work just by installing
08:31spinningarrowTEttinger: makes sense - thanks!
08:31spinningarrowwhodidthis: checking it out now
08:32oddcullyspinningarrow: i have not used it. but puttin the toggle into a ~/.vim/ftplugin/clojure.vim might work?
08:32TEttinger(inc whodidthis)
08:32lazybot⇒ 1
08:38profilspinningarrow: you can put it into an augroup with autocmd, thats how I do it
08:38profilspinningarrow: https://github.com/profil/dotvim/blob/master/vimrc#L81
08:38spinningarrowoddcully: that didn't work for some reason
08:40whodidthisspinningarrow: add "filetype plugin on
08:40whodidthisto .vimrc
08:40borkdudedstockton that's a good one
08:40spinningarrowprofil: that worked like a charm
08:40spinningarrowthanks!
08:43profilnp :)
08:43whodidthisman, clj-refactor seems amazeing, i wish i had an actual com puter to use emacs on
08:46profilI am writing a program where I am keeping some state in an atom, is it possible to listen for changes on this atom?
08:46Glenjamin(doc add-watch)
08:46clojurebot"([reference key fn]); Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any pending sends if agent or ref. Note that an atom's or ref's state
08:47profilGlenjamin: ahh, nice thanks
08:49profilis this the preferred way to listen for stateful events? or is there some other more clojure-like to do it? I am already using core.async to handle websockets and tcp connections
08:49spinningarrowwhodidthis: I ended up going with vim-niji (no setup required!) cheers :D
08:55Larva_Will Clojure be compatible with PAIP book http://norvig.com/paip.html ?
09:00dnolenLarva_: PAIP is written on Common Lisp, so not compatible. But translation to Clojure should be relatively straightforward.
09:00dnolenLarva_: but that assumes you're willing to learn enough Common Lisp & Clojure to do that
09:01Larva_dnolen : so it is possible after all?!
09:02dnolenLarva_: I don't see why not
09:02Larva_dnolen : oh very well, Ta!
09:09noncomwhat is clojure's common way to have some shared data memory among many namespaces? sure, i can make one with an atom and then require it from everywhere, but is this the way?
09:09noncommaybe there is a library for that?
09:10dnolennoncom: you probably want to use something like Stuart Sierra's component
09:11noncomdnolen: cool, from reading the intro i think this is it
09:25pkugAnybody read Paradigms of AI Programming by P. Norvig? would it still be relevant in learning Clojure? I just came across that it's available in my local lib
09:27arrdempkug: Not directly, Clojure and Common Lisp are quite different in some ways, but there exist a couple projects which have translated all the examples to Clojure if you wanted to try and read along that way.
10:20justin_smith /win 22
10:20justin_smithoops
10:20tcrayford____don't use win32 kids, it kills
10:21gfredericksjustin_smith: better change your passwords
10:21gfredericks,(def password " /win 22")
10:21clojurebot#'sandbox/password
10:21justin_smithhaha
10:22justin_smithtcrayford____: but win 22, that would have rocked, if intel actually came through with the 22 bit processor it was designed for
10:26oddcullyopposite of a catch-22?
10:40cnb_I'm trying to merge 2 vectors but always the resulting vector is only 1 element longer than the original. I'm doing (merge v (vector (take 250 (repeat "")))); v has 217 elements, after the merge the resulting vector only has 218 elements, what is wrong ?
10:40gfrederickscnb_: try into instead
10:40gfredericksmerge is for maps
10:40hyPiRiongfredericks is correct.
10:41gfrederickshyPiRion: it's not a fact until you teach it to clojurebot
10:41justin_smithcnb_: merge would replace item 0 to 249 from v with ""
10:41justin_smith,(merge [:a :b :c] [0 1 2 3 4 5 6])
10:41clojurebot[:a :b :c [0 1 2 3 4 ...]]
10:41justin_smitherr
10:41justin_smithnever mind!
10:42justin_smithanyway, it's still wrong
10:42gfrederickskind of disappointing that it does anything at all :/
10:42hyPiRion,(merge nil []) ;; hurray
10:42clojurebot#error{:cause "Vector arg to map conj must be a pair", :via [{:type java.lang.IllegalArgumentException, :message "Vector arg to map conj must be a pair", :at [clojure.lang.APersistentMap cons "APersistentMap.java" 35]}], :trace [[clojure.lang.APersistentMap cons "APersistentMap.java" 35] [clojure.lang.RT conj "RT.java" 610] [clojure.core$conj__4067 invoke "core.clj" 85] [clojure.core$merge$fn__459...
10:43noncom,(conj {} [:a :b :c 1 2])
10:43clojurebot#error{:cause "Vector arg to map conj must be a pair", :via [{:type java.lang.IllegalArgumentException, :message "Vector arg to map conj must be a pair", :at [clojure.lang.APersistentMap cons "APersistentMap.java" 35]}], :trace [[clojure.lang.APersistentMap cons "APersistentMap.java" 35] [clojure.lang.RT conj "RT.java" 610] [clojure.core$conj__4067 invoke "core.clj" 85] [sandbox$eval73 invoke "NO_...
10:43hyPiRionoh right
10:43hyPiRion,(merge nil [:a :b])
10:43clojurebot{:a :b}
10:43hyPiRionof course
10:44noncom,(merge '() [2 2])
10:44clojurebot([2 2])
10:44noncom,(merge '() {})
10:44clojurebot({})
10:44cnb_gfredericks using into gives the same result
10:46justin_smith,(into [:a :b :c] [0 1 2 3 4 5 6])
10:46clojurebot[:a :b :c 0 1 ...]
10:46justin_smithcnb_: it really shouldn't
11:00justin_smithwoah, TIL for the IBM 1401 computer, there was an extra rental fee to access specific hardware instructions
11:00justin_smithI'm glad that hasn't come back
11:00gfredericksIBM 1401 Pro
11:01justin_smithfreemium CPU
11:01justin_smith"sorry, your computer is too slow to run this app. But for a small monthly fee you could get SMID instructions."
11:02justin_smithSIMD I mean
11:02justin_smith"single multiple instruction data" would sure be useful
11:04justin_smith"The bit test instruction cost only $20 a month" http://www.righto.com/2015/03/12-minute-mandelbrot-fractals-on-50.html
11:06noncomjustin_smith: probably these devices were technically difficult and that's why instructions did cost more money... it looks like an instruction was more like a plugin-module (from the pictures)
11:07justin_smithnoncom: yeah, you actually got an extra card that plugged into the machine and implemented the instruction
11:07xemdetiajustin_smith, this is still common even today. Lots of IBM processors are feature restricted depending on what you want to do
11:07justin_smithxemdetia: fascinating, I didn't realize
11:07xemdetiait lets customers cut costs if they don't want to use it
11:08justin_smithoh, the 1401 also had hardware level support for pounds / shillings / pence conversions
11:08noncomalso, i remember that not so old story about ati radeon somewhat around the 9000 module, where you could get a more powerful videocard (next grade in fact) by just melting down some component on the circuit board
11:08xemdetiaI believe there was a hardware xml parser that they had in one chipset but I forget the name of it.
11:11noncomalso, we're coming back to modularization: https://en.wikipedia.org/wiki/Project_Ara and https://phonebloks.com/en
11:11xemdetiaah thats right, datapower
11:12xemdetiait wasn't in a chipset after all, my bad
11:12justin_smithnoncom: do you think that those will really fly as cell phones?
11:12justin_smithxemdetia: it was believable. I mean we have hardware level codecs for mp3 / mp4
11:13justin_smithand hardware level network routing
11:13xemdetiawell I just went to a talk once from one of the people in the early networking hardware days and he said the next company was a part of was hardware/ASIC XML parsers
11:13noncomjustin_smith: idk.. serious people are behind this.. and all this is backed by these popular trends to provide cheap hardware to poor countries and to improve the ecological sustainability
11:13xemdetiaI just thought it got dropped into the power arch as a coprocessor I did not realize it was a standalone
11:17noncomjustin_smith: and, btw, they're having a food tuck designed specifically to sell the phones :D
11:17justin_smithhaha, of course
11:18justin_smiththrow in bicycles somehow, and you may even sell two of them here in Portland
11:18noncomyeah :)
11:25gfredericksbicycles stapled to phones
11:27justin_smithgfredericks: noncom: see what you do is you take two unicycles and you add grommets so that they both attach to a cellphone et voila! bicycle
11:28noncomphonecycle
11:28noncomgoogle phonecycle to be precise
11:28justin_smiththat's too believable
11:28noncomi just want to be able to run clojure on it
11:29noncomso that i can program while biking
11:29noncomfor long distances
11:39noncom,(ns-map)
11:39clojurebot#error{:cause "Wrong number of args (0) passed to: core/ns-map", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (0) passed to: core/ns-map", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 28] [sandbox$eval180 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java"...
11:40noncom,*ns*
11:40clojurebot#object[clojure.lang.Namespace "sandbox"]
11:40noncom,(ns-map *ns*)
11:40clojurebot{primitives-classnames #'clojure.core/primitives-classnames, +' #'clojure.core/+', Enum java.lang.Enum, decimal? #'clojure.core/decimal?, restart-agent #'clojure.core/restart-agent, ...}
11:40noncom,(ns-refers *ns*)
11:40clojurebot{primitives-classnames #'clojure.core/primitives-classnames, +' #'clojure.core/+', decimal? #'clojure.core/decimal?, restart-agent #'clojure.core/restart-agent, sort-by #'clojure.core/sort-by, ...}
11:40noncom,(ns-aliases *ns*)
11:40clojurebot{}
11:40noncom,(count (ns-refers *ns*))
11:40clojurebot629
11:40noncom,(count (ns-map *ns*))
11:40clojurebot726
11:41justin_smith,(require '[clojure.string :as str])
11:41clojurebotnil
11:41noncomooooooooops! sorry
11:41justin_smith,(ns-aliases *ns*)
11:41clojurebot{str #object[clojure.lang.Namespace "clojure.string"]}
11:41noncomi thought i am in a private chat with clojure bot :D
11:41justin_smithhaha
11:41justin_smithat least you didn't do anything embarrassing
11:41noncom:)
11:42noncomthank you, yes :)
11:44noncomjustin_smith: can i make clojurebot to print on several lines?
11:44noncom,(mapv #(println "whoa! " %) [1000 3000 6000])
11:44clojurebotwhoa! 1000\nwhoa! 3000\nwhoa! 6000\n[nil nil nil]
11:44justin_smithnoncom: nope, neither of the bots can do that
11:45noncomi guess it uses conch which just returns the str of the output streams..
11:46noncomand threads/futures are not allowed to space the execution in time..
11:46programistoi don't use a ton of java or clojure, so i'm unsure where to start....i'd like to slowly append to a string over several iterations and then finally return a string or write to a file, is there a preferred way to do that?
11:47programistoi know java has a number of buffer classes
11:47noncomprogramisto: ummm either just add to the string or use java StringBuffer
11:48noncomthe second variant is preferable is more efficient, although requries more characters of code
11:48programistook
11:48justin_smithprogramisto: iterations of what?
11:48programistowalking a tree, appending to the string based upon nodes
11:48justin_smitha single loop? successive calls to a function?
11:49justin_smithsorry, I hit return just after I saw your answer
11:49nullptrclojure.string/join https://github.com/clojure/clojure/blob/d7175e84e27816ee227220023a5411386d6aa32e/src/clj/clojure/string.clj#L178
11:50myguidingstarhi all, what are the equivalent of those in Clojurescript? clojure.lang.IPersistentList clojure.lang.ISeq clojure.lang.IMapEntry and clojure.lang.IPersistentCollection
11:50programistoio just realizEd atoms can hold strings
11:51programistopretty simple, then
11:51programistothanks all
11:52justin_smithprogramisto: but you don't need an atom for this
11:52nullptrin cljs you can use goog.string.StringBuffer
11:54programistononcom: okay, so it lools like the "proper" and easy solution is to just use a stringbuffer
11:54programistowell, maybe not, but that's what i'm going with
11:54programistothansk :)
11:57justin_smithStringBuilder maybe?
11:58programistojustin_smith: you are right, didn't realize they were same api
11:59justin_smithprogramisto: is this clj or cljs?
11:59programistojustin_smith: regular clj
12:00justin_smithyeah, StringBuilder would be the way to do it then
12:00programistoawesome, i appreciate you taking the time to help so much
12:14acron^What would be the best way to implement something like a routing macro, in terms of updating some global lookup ?
12:14noncomacron^: a little vague query.. could you add more detail?
12:15acron^Yeah sure, I just want to create a routing table like for any normal web service (add-route "/foo", (fn [..] ...))
12:16acron^Lets say I have a (def routes []) hanging around
12:16acron^What's the best way to handle this inside my add-route macro?
12:16acron^AFAIK, I can't "alter" 'routes' because it's immutable
12:17justin_smithacron^: this really depends on what routing lib you are using.
12:17acron^I'm not using one
12:17acron^this is about how I would create one
12:17justin_smiththen it depends on how you implement your routing
12:17justin_smithI would forget the "macro" part for now. Implement the functionality. Macros are for syntax, not functionality.
12:18acron^Ok
12:18acron^Message comes in, I parse the route
12:18justin_smiththe annoying thing about using a global for routing, is that it means an end user can't have subsites that each do their own routing in one app
12:18acron^I want to pass it to a dedicated function
12:18justin_smithsure
12:19acron^Without a switch, obviously
12:19justin_smithobviously? there are a lot of ways to do routing. A trie for example.
12:19acron^So it's just a string compare lets say, 1 to 1
12:20acron^"foo" => foo-func, "bar" => some-other-func
12:20acron^My routes are trivially always defined as a single string
12:24acron^Is the answer not to use state at all and just pass around the routing table?
12:25justin_smithacron^: the more typical thing is to construct the routing function, then wrap that with your middleware, and hand that to the server process as the handler
12:25justin_smithacron^: one thing that is useful is if you have a pure data representation of the routes, that can be converted into a routing function
12:25acron^My problem is just an idiomatic one I think
12:25justin_smiththen if you want to add or modify routes, you modify the data structure, then you regenerate the routing function
12:26acron^Yeah, okay
12:26justin_smithso it's like a compiler - it takes a structure of routes and functions to call for those routes, and compile that into a function that takes a request and calls the endpoint
12:27justin_smithwhich means you stay flexible (it can be edited and regenerated) while also staying simple (you don't have to worry about modifying a running function)
12:49m1dnight_Hi guys. Could somebody help me with figuring out the equivalent of (this.isInterrupted()) in clojure?
12:49m1dnight_I tried the thread-stopper as an alternative, but it's not found in my repl
12:51m1dnight_aha, found it!
12:51m1dnight_(Thread/interrupted)
12:51m1dnight_problem solved :>
12:54justin_smithisInterrupted surely?
12:54m1dnight_nope, interrupted
12:54justin_smith,(Thread/interrupted)
12:54m1dnight_I thought so at first too, but it's interrupted
12:54clojurebotfalse
12:54justin_smithahh
12:54m1dnight_,(Thread/isInterrupted)
12:54clojurebot#error{:cause "isInterrupted", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.NoSuchFieldException: isInterrupted, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.NoSuchFieldException, :message "isInterrupted", :at [java.lang.Class getField "Class.java" 1584]}], :trace [[java.lang.Class getField "Class.java" ...
12:55justin_smith,(.isInterrupted (Thread/currentThread))
12:55clojurebotfalse
12:55m1dnight_oh, you have currentThread
12:55justin_smiththat's the more verbose alternative ^
12:55m1dnight_that wsa another solution
12:55justin_smithyeah
12:55m1dnight_I was looking for how to get a reference to this, but couldnt find it
12:55justin_smithis that a static method or a field?
12:55m1dnight_found Thread/interrupted in a book
12:55m1dnight_isInterrupted is a field iirc
12:55justin_smith,Thread/interrupted
12:55clojurebot#error{:cause "Unable to find static field: interrupted in class java.lang.Thread", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to find static field: interrupted in class java.lang.Thread, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to find stati...
12:55justin_smithnot a field
13:01gfredericks,(Thread/interrupted)
13:01clojurebotfalse
13:01gfredericksit's a static method
13:27ToxicFrogSo, a friend of mine just ran into an interesting issue with the clojure compiler
13:28ToxicFrogHe calls into a Java library that includes a static initializer that instantiates a class that spawns a thread that does some stuff in the background
13:28justin_smithToxicFrog: there is something in 1.7 if this is the issue I am thinking of
13:28ToxicFrogThis happens when he compiles the code, since the compiler loads the class file to check static method resolution (at least, I think this is what happens)
13:29ToxicFrogSo at, say, lein uberjar time, he gets log messages from this library starting up, and then it never exits because the library's background thread is waiting for a shutdown message that never comes.
13:29justin_smithToxicFrog: yeah, that's the issue
13:29ToxicFrogThis is fixed in 1.7?
13:31justin_smithToxicFrog: yeah, there are changes to address this behavior (switching .forName to .forNameNonLoading in relevant places)
13:31ToxicFrogjustin_smith: awesome! Do you know what I should search for if I'm looking for bug tracker/changelog entries related to this?
13:31justin_smithToxicFrog: I am looking for that right now
13:32ToxicFrogThankyou :)
13:32justin_smithToxicFrog: http://dev.clojure.org/jira/browse/CLJ-1315
13:33justin_smithToxicFrog: shown as closed and fixed in 1.7
13:33ToxicFrogThanks.
14:03broma0Anyone use Riak with clojure? Experiences? I'm thinking of using it in a project
14:22justin_smithso how long until maven can use project.clj directly? http://www.infoq.com/news/2015/03/maven-polyglot?utm_source=reddit&amp;utm_medium=link&amp;utm_campaign=maven%20polyglot
14:26atyzSo what happens when you do something like (map (partial some-function some-argument) some-collection). Does it create that partial function on every element?
14:27justin_smithatyz: no, the function is only created once
14:28atyzjustin_smith: Thank you. Does it incur more overhead than (map #(some-function some-argument %) some-collection)?
14:29justin_smithatyz: #() creates something that runs faster, but it also generates a new class
14:29justin_smithpartial creates something slightly slower (because it is always varargs) but doesn't create a new class
14:29Bronsawell faster for >3 elements :)
14:29Bronsajustin_smith: it's unrolled
14:29atyzso in some instances its better to use one or the other, but mostly its negligable?
14:29justin_smithBronsa: partial is?
14:29justin_smithOK
14:30atyzThank you Bronsa justin_smith
14:30turbofaileh? `partial' itself is unrolled, but doesn't the function that partial returns use varargs every time?
14:31Bronsano
14:31Bronsathat's unrolled too
14:31turbofailhm, perhaps i'm looking at an older version then
14:31Bronsawell, partial actually isn't vararg at all
14:32Bronsa,(partial + 1 2 3 4 5)
14:32clojurebot#object[clojure.core$partial$fn__4484 "clojure.core$partial$fn__4484@21e2f47b"]
14:32Bronsanevermind I'm blind
14:33hiredman#ugg
14:33turbofailah yeah later versions of partial do in fact return multi-arity functions
14:34Bronsaah yeah, looks like it's a 1.7 enhancement, thought it had always been the case
14:34Bronsahttp://dev.clojure.org/jira/browse/CLJ-1430
14:35justin_smiththat makes me feel a little better about being ignorant of that
14:39numbertenanyone know why test.check documentation requires [clojure.test.check :as tc] when it isn't used?
14:39numberteni've also found that removing it breaks the tests.. so was kinda curious why it appears to be necessary
14:40justin_smithmy first suspicion is ill behaved macros
14:41reiddrapernumberten: which tests?
14:41numbertentests that I wrote using test.check
14:42numberteni get a ClassNotFoundException when i remove that requirement
14:42numberteni think it's probably macros, i'll take a look at the functions I call
14:43justin_smithnumberten: so do you import some class that test.check generates? because yeah, removing a require will make it so the class doesn't get generated
14:43numbertenhttps://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/clojure_test.clj#L33
14:43numbertenI think that's it?
14:44Bronsahttps://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/clojure_test.clj#L57
14:44justin_smithnumberten: it generates a call to assert-check, which uses ct/is
14:45Bronsathis might why it doesn't work if test.check isn't loaded then
14:45justin_smithoh, that would do it to, yeah
14:46justin_smithit's odd that it is spelling out the namespace though, inside a ` block
14:46amalloyjustin_smith: it doesn't require test.check
14:46amalloyso ` would qualify it incorrectly
14:47amalloywhat's odd to me is that it doesn't require test.check
14:47amalloybut i see, it does the require at runtime
14:47justin_smithoh wait, yeah, that is weird
14:47justin_smithI had misread the clojure.test requirement above, oops
14:54BinaryResultHi all, DiscoMelee.com is hiring clojure devs. http://www.reddit.com/r/Clojure/comments/301coc/disco_melee_is_hiring_clojure_developers/
14:57gfredericksamalloy: it's a cyclic dependency problem
14:57gfredericksthere's a comment in the file about it
14:59gfredericksnumberten: so you're saying if you're just using clojure.test.check.clojure-test, your tests break when you don't require clojure.test.check?
14:59gfredericksthis sounds plausible just from looking at the code; it's surprising I haven't heard of this before
14:59amalloygfredericks: i see, thanks
15:00gfredericksthe cyclic dependency thing was just considered an aesthetic problem till now, but since it seems to be reaching into userland I'd call it a bug worth fixing
15:00dysfunis there anything for screenscraping that sort of works like a template language? build a template and reverse engineer the data out of it?
15:01justin_smithdysfun: enlive is good for both scraping and generating html
15:01justin_smithdunno about general screen scraping though
15:01dysfunta, i'll have a look
15:01reiddrapergfredericks: agree its a bug, if that's the case
15:02gfredericksreiddraper: I'm gonna upsert a ticket
15:02dysfunjustin_smith: it just occurred to me that the two operations are pretty similar
15:02reiddrapergfredericks: thanks
15:03justin_smithdysfun: yeah, I have had great luck getting content via enlive, and it also does templating / programmatic transforms
15:03gfredericksreiddraper: any objections to fixing by adding more options to quick-check for reporting?
15:03dysfunand yet all the screenscraping libraries i've used either don't parse properly or expect you to pick out a tree via selectors
15:03gfredericksrather than quickcheck calling the .clojure-test functions directly
15:03justin_smithdysfun: enlive even has a thing where you can give it an html file to create a templating data structure out of
15:04dysfunthat sounds really very shiny indeed
15:04reiddrapergfredericks: no objection
15:04dysfun(inc cgrand)
15:04lazybot⇒ 1
15:06mavbozojustin_smith: what enlive parser do you use most for screenscraping? tagsoup or jsoup?
15:06gfrederickslooks like TCHECK-33 to me
15:06gfredericksI'll work on that later today
15:06justin_smithmavbozo: I just let it use its default
15:06justin_smithI do nothing super fancy
15:06gfredericksnumberten: ^
15:07numbertenhm?
15:07numbertenah cool
15:47pandeirocan ragtime be used to migrate multiple different databases with one single migrations directory, or should there be a single migrations set per database?
15:54caternoh god why is using clojure so painful
15:54caternmy .lein/profiles.clj looks like:
15:55mavbozopandeiro: I use different directory for each database
15:55catern{:user {:plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]]
15:55catern :dependencies [[org.clojure/tools.nrepl "0.2.7"]]}}
15:55caternand yet when I run lein repl
15:55caternI get
15:55pandeiromavbozo: thanks; do you include the creation of database/role in the migrations?
15:55pandeirocatern: put tools.nrepl in :dev dependencies
15:56caternhttp://sprunge.us/JcbZ
15:56caternwhy
15:56caternwhy why why
15:56mavbozopandeiro: no, there is a init script I put outside the migrations dir
15:56catern(why regarding my nrepl output)
15:57pandeirocatern: dunno, you're worried about the indentation there?
15:57pandeiroor the fact it's using 0.2.6 instead of 0.2.7?
15:57mavbozopandeiro: it helps if i want to rebase.
15:57caternpandeiro: the second one
15:57pandeiromavbozo: thanks a lot
15:57caternpandeiro: likewise when I use cider-jack-in it uses 0.2.6 for some reason
15:57pandeirocatern: i guess :dev gets merged in 'on top of' (my technical term) the regular project deps
15:58pandeirocatern: same issue
15:58amalloylein probably inserts its own nrepl version into your project
15:58amalloyor something like that
15:58caternI'm not even in a project right now
15:58gfrederickslein is supposed to check for existing one though
15:58pandeirowhat amalloy said
15:58caternI'm just running lein repl in a random directory
15:58gfredericksI've been using a profile like that for a while and I thought it was working
15:58gfrederickscatern: what happens if you run it in an actual project?
15:58gfredericksI think lein-without-a-project can have weird degradations like this
15:59catern:(
15:59caternnow it uses 0.2.7
15:59caternbut this is dumb
15:59caternI just have a single .clj file that I want to do use with CIDER
15:59caternfor a few calculations
15:59caterngfredericks: er, ^
16:00caternIt used 0.2.7 when I ran it in a project
16:00gfrederickshyPiRion might know how to wrangle lein-without-a-project
16:01caternwhy is this complicated? why is this different from normal lein usage? why doesn't it refuse to run if it is obviously broken?
16:02gfrederickscatern: digging into the leiningen code to try to solve the problem would be an instructive way to get answers to those questions
16:04catern:(
16:05caterncan I just like, delete 0.2.7
16:05caterner, 0.2.6
16:05caternfrom somewhere
16:05caternto force it to use 0.2.7
16:05caternexcept I already did this, deleting it from .m2
16:05caternand it had no effect
16:05gfrederickswell I should hope not
16:06gfredericksit'd be bad if the dependencies you got were sensitive to what was in your cache
16:06caternbut 0.2.6 doesn't appear to actually exist anywhere
16:06caternand it isn't downloading it again
16:06gfredericksit's hard-coded into lein
16:06caternD:
16:07gfredericksyou're saying it doesn't get downloaded into .m2 again?
16:07caterncorrect
16:07gfredericksbut it runs with 0.2.6 anyhow?
16:07caternyes
16:08caternor at least claims to
16:09gfrederickshttps://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L484
16:09gfredericksis where it is hard-coded
16:09gfredericksbut anyhow the part about it not coming back to .m2 is a lot harder to believe
16:09gfredericksgonna try it myself
16:10caternspecifically I deleted /home/catern/.m2/repository/org/clojure/tools.nrepl/0.2.6
16:11caternand it hasn't come back
16:11gfredericksyep mine redownloaded
16:11gfredericksthat's what I deleted too
16:12gfredericksso that's super weird but maybe not your original problem
16:12kaplanWhat dies reify dio?
16:12kaplan*do
16:13gfrederickscreates an anonymous type that implements some interfaces and/or protocols
16:14amalloygfredericks: an instance of an anonymous type
16:14gfredericksdepends on how you're thinking about it
16:14gfredericksat compile time it creates a type :P
16:15kaplanCan anyone walk me through the example code here? https://github.com/omcljs/om
16:16patrickgombertkaplan: what in particular? it might be best to start with https://github.com/omcljs/om/wiki/Conceptual-overview
16:17caternso I have this code: http://ix.io/h3J
16:17caterndoes it have any obvious performance problems or infinite loops?
16:17catern(sim) is taking a while to terminate...
16:18catern(sometimes)
16:18catern(sometimes it finishes quite quickly)
16:18amalloycatern: that looks like it should take a long time. getting down to 0 will take a long time with those betting odds
16:18caternamalloy: only 100 bets or so...
16:19caternor 1000
16:19caternstill
16:19kaplanok patrickgombert , thanks
16:19catern1000 is not a lot
16:19caterna 1000 invocations of a trivial function... come on clojure, don't tell me you're that slow!
16:21amalloycatern: on average you lose, what, 1/37th of $15? 0.5ish? so the average number of bets is indeed not very many, like 600 or so, but you can easily get lucky and go a lot longer
16:25amalloycatern: i think it actually takes quite a bit longer than that
16:25amalloyi just tried starting with $90 instead of $300, and the first four calls to (count (sim)) returned: (542 26 1190)
16:26amalloyso the mean is low but the variance is very high
16:28amalloyanyway, tldr your problem is with math, not with clojure
16:30caternamalloy: uhhhhhh
16:31caternoh!
16:31caternwhoops!
16:31caternI think I have the conditional the wrong way around :)
16:32caternthanks amalloy
16:32caternincidentally
16:32caternI'm kind of curious
16:33caternwhat other languages have standard functions like "iterate" or "take-while"?
16:33amalloyhaskell. probably python in its iter-whatever package
16:33raekHaskell, Scala, O'Caml?
16:33sdegutisOh hi raek
16:34raeksdegutis: hi.
16:34sdegutiscatern: my favorite of these three are so far is Haskell fwiw
16:34caternoh
16:34caternhuh
16:34caternokay
16:35caternneat
16:37raekand all those languages borrowed their standard libraries from ML... :-)
16:37caternanother question, is there some function that's equivalent to what I'm doing in: (map #(do % (sim)) (range 10))
16:38caternor just a better way to do it?
16:41aperiodic(take 10 (repeatedly sim))
16:41caternaperiodic: beautiful
16:41aperiodicthough that may not be exactly equivalent due to lazy seq chunking
16:43raek(dotimes [_ 10] (sim))
16:43aaelonyI like the idea of yesql, but I need it to output the final query string to make sure it is parameterized correctly and also defer execution. Does anyone know if this is possible?
16:43raekcatern: ^
16:44caternraek: ah, hm
16:44raekI assume sim is run for its side-effects. as aperiodic hinted, you will get unpredictable behavior if you mix side-effects and lazy sequences
16:44amalloyraek: catern is trying to get the actual results from sim
16:44caternisn't there something like "tabulate"
16:44raekoh, right.
16:44caternraek: no, sim is pure
16:45aperiodicit's not pure
16:45caternwell
16:45caternmodulo grabbing random numbers :)
16:46aperiodicthe take & repeatedly version just may end up doing extra work that's never used
16:46caternso, is there not something like (tabulate f n) which generates a sequence of length n, running f on the indices?
16:46catern(you'd just do that with map I assume?)
16:47aperiodicmap-indexed
16:48aaelonyok nevermind, I'll just slurp and replace to fit my use case...
16:49aperiodiccatern: not exactly what you want. seems like tabulate is just (map f (range n))
16:50caternaperiodic: yes
16:50caternthat's why I say, just use map
16:51aperiodicyup
16:55caternokay
16:55caternI have another elegance question
16:56catern(def sims (take numsims (repeatedly sim)))
16:56catern(def num_temporarily_rich (count (filter pos? (map (fn [sim] (count (filter #(> % 1000) sim))) sims))))
16:56catern;; this finds the number of simulations where at some point the balance is over 1000
16:56caterncould I make this nicer?
16:57catern(it's already so much nicer than in an imperative language, lol)
16:57bensucatern: you could use ->>
16:58amalloycatern: (repeatedly num-sims sim)
16:58caternamalloy: :D
17:00amalloyalso, checking whether the count of a coll is positive is really gross. just check whether it has at least one element, with seq
17:01caternamalloy: hm? how?
17:01caternoh
17:01caternfilter seq?
17:01caternwow, that's hacky :D
17:01amalloy"hacky"
17:01caterncouldn't I just use identity rather than seq?
17:01bensucatern: or remove empty?
17:02Glenjamin(doc keep)
17:02clojurebot"([f] [f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects. Returns a transducer when no collection is provided."
17:02Glenjaminhrm, is there a filter-by in core?
17:03Glenjamini guess that's just done with (for)
17:03caternokay, it now looks like:
17:03catern(def num_temporarily_rich (->> sims (map (fn [sim] (filter #(> % 1000) sim))) (remove empty) count))
17:03catern;
17:03Glenjamin(for [s sims
17:03catern(yuck, for)
17:04caternis there a way to clean up that (map (fn [sim] ...?
17:04amalloyuhhhhhhhhhhhhh, (remove empty xs) should be a no-op
17:04amalloyor rather, it should produce () every time
17:04Glenjaminwait, sim is a number?
17:04caternGlenjamin: sim is a seq of numbers
17:05Glenjaminso it's just (->> sims (filter #(> % 100)) count) then?
17:05Glenjaminoh right, sorry
17:05Glenjaminsims is a seq of sim, and sim is a seq of numbers
17:05caternamalloy: ah, true, replacing that with (filter seq) like you said)
17:06bensucatern: I meant empty? not empty.
17:06caternnow replacing that*
17:06caternbensu: oh, derp
17:07caternhmm
17:07caternbattle it out
17:07caternwhich is better, (filter seq) or (remove empty?) :D
17:07caternI can tell from the docstring for empty? that this is a point of debate
17:07bensucatern: I'm not in for a battle! I just like it when my filter predicate clearly returns a bool
17:08caternbensu: I tend to agree :)
17:08bensucatern: without in mind you could also say (filter seq?)
17:08bensucatern: *with that in mind
17:08amalloybensu: that is a really bad plan
17:09bensuamalloy: why?
17:09amalloyseq? is very different from seq
17:09amalloyyou can't use it to test whether a collection is empty, which is what catern is trying tod
17:10bensuamalloy: ahh yes, just found this: ;; (seq x) is the recommended idiom for testing if a collection is not empty
17:11bensuamalloy catern: my 0.02 are then (remove empty?)
17:14crazydiamondHi. Is there function to make alphabetical sorting of vector of strings by some custom alphabet?
17:15kwladykahi, i am reading a book about Clojure and read some coursers in the Internet. But i choose bad book, because it is describing functions in really dry way. I need do some coursers which learn me how to thing, when use lists, when vectors, how to solve real problems. For now there is so many possibility for me in Clojure, i don't know how to do things in this language.
17:15kwladykaCan you recommend me some coursers which learn me how to think in Clojure and how to solve problems?
17:15kwladykaNot describe functions
17:16Bronsacrazydiamond: look at sort-by
17:17crazydiamondBronsa, I'm trying to use it, but I rather need correct version of keyfn
17:17{blake}kwladyka: I can't really recommend the stuff I read for that. I've mostly found it more useful to do things in Clojure, then go back to the various books/docs.
17:18{blake}kwladyka: However, I haven't tried tbaldridge's videos yet, and they may be the ticket.
17:19Glenjamin,(->> sims (filter (partial some #(> % 1000))) count) ; catern - how about this
17:19clojurebot2
17:19mavbozokwladyka: the closest book I could find is How to Design Program book htdp.org
17:19mavbozokwladyka: it uses racket lang which is quite similar to clojure, esp the immutability
17:20mavbozokwladyka: there's a mooc that uses that book too https://www.coursera.org/course/programdesign
17:40kwladykathx for info :)
18:01crazydiamondHi. In Datomic, can I sort using custom key-function?
18:10kludgecode_Basic question: I have a bunch of maps. I want to dump them into a data structure sorted data structure with heap semantics. I could not find a heap implementation for Clojure. Suggestions?
18:12justin_smithkludgecode: like a sorted-set or sorted-map or something?
18:13justin_smithkludgecode: actually, can you describe what you mean by "heap semantics"? do you just mean associative lookup?
18:13kludgecodejustin_smith: I don't need map or set semantics.
18:15turbofailthere's always java.util.PriorityQueue
18:15kludgecodejustin_smith: By "heap semantics" I mean :1: data structure maintains sort order on addition of new items. :2: "popping" or "first"ing produces the first value in sorted order.
18:17kludgecodeturbofail: does that put me into the world of mutation and should I really go there if it does?
18:17turbofailit's very much in the world of mutation
18:18turbofailwhether you should go there depends on how you're going to use it
18:19kludgecodeturbofail: I am very new, so forgive me. Can I just throw ordinary Clojure maps into it without great risk of obscure Java errors?
18:19turbofailyes, there'll be no problems there
18:20turbofailthe only problems you'll get will be the usual set of mutable data structure caveats
18:21kludgecodeturbofail: Can you point me to some example code, so that I have something to guide me through the interop ceremony? I haven't done any yet and was hoping to avoid it?
18:21kludgecodeturbofail: the scope should probably be ok for mutation in this application.
18:22gfrederickskludgecode: I think clojure's sorted-set is all you want
18:22gfredericksor sorted-set-by, depending
18:22justin_smithgfredericks: he said he didn't want set semantics
18:23gfredericksor didn't "need"
18:23turbofailkludgecode: (let [q (java.util.PriorityQueue. 10 compare)] (doseq [i (repeatedly 10 #(rand-int 100))] (.add q i)) q)
18:23turbofailthat's about all you need
18:23gfredericksthrow some random IDs on them if you worry about duplicates
18:24turbofailer, missing a dot in there somewhere
18:24turbofail(let [q (java.util.PriorityQueue. 10 compare)] (doseq [i (range 100)] (.add q i)))
18:24justin_smith(inc gfredericks)
18:24lazybot⇒ 126
18:24justin_smiththat's a great idea actually
18:24turbofailbut yes in general i'd agree that a sorted set would work fine
18:24kludgecodegfredricks: How will `sorted-set` determine that two maps are identical? Will all fields need the same values?
18:25justin_smithkludgecode: yes, that is how equality is done for clojure data structures
18:25justin_smithkludgecode: which is why adding a random id to each element before insertion would fix the de-duping if you don't what it
18:25gfredericks,(def my-heap (atom (sorted-set-by :priority)))
18:25clojurebot#error{:cause "clojure.lang.Keyword cannot be cast to java.util.Comparator", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Comparator, compiling:(NO_SOURCE_FILE:0:0)", :at [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3622]} {:type java.lang.ClassCastException, :message "clojure.lang.Keyword c...
18:25gfredericksdamn comparators
18:25hiredmanyou could also roll your own heap
18:25gfrederickslike a boss
18:25hiredmanhttp://typeocaml.com/2015/03/12/heap-leftist-tree/
18:26kludgecodejustin_smith: that's what I thought, but I hate to assume anything.
18:26kludgecodehiredman: I think you have mistaken me for someone else.
18:27kludgecodeunless you're just being theoretical...
18:27turbofaileh. it's not that hard to implement
18:27hiredmanno, I mean, it is a nice write up of a straight forward to implement persistent heap with examples in a straight forward functional language
18:28gfredericks,(def my-heap (atom (sorted-set-by #(compare (:priority %1) (:priority %2)))))
18:28clojurebot#'sandbox/my-heap
18:28gfredericks,(swap! my-heap conj {:data 12 :priority 3})
18:28clojurebot#{{:data 12, :priority 3}}
18:28gfredericks,(swap! my-heap conj {:data "eight" :priority 8})
18:28clojurebot#{{:data 12, :priority 3} {:data "eight", :priority 8}}
18:29gfredericks,(swap! my-heap conj {:data "taco" :priority 1})
18:29clojurebot#{{:data "taco", :priority 1} {:data 12, :priority 3} {:data "eight", :priority 8}}
18:29gfredericks,(first @my-heap)
18:29clojurebot{:data "taco", :priority 1}
18:30kludgecodegfredricks: Thanks. Using `atom` means that I only have one heap to worry about, right?
18:30kludgecodeYes, I am that new
18:30kludgecodeVersus passing a new value recursively.
18:31justin_smithkludgecode: you should check out some of the official clojure docs http://clojure.org/documentation
18:31justin_smithfor this specific question http://clojure.org/atoms
18:32gfrederickskludgecode: probably don't use an atom, I was just doing that to have some state in the replbot
18:32justin_smithkludgecode: passing a new value recursively will also end up using structural sharing as applicable (won't copy the whole data structure to do one add or remove typically)
18:32kludgecodejustin_smith: RTFM'ing is how I got into this mess. I have a vague idea understanding of what they do.
18:32gfrederickskludgecode: atoms and sorted sets are orthogonal features; one is the data structure, the other is state management
18:34justin_smithkludgecode: in this specific case it answers your specific question in the first sentence of the page, and has a better intro than anyone here could give.
18:35justin_smithkludgecode: to be clear, I am not saying "read the docs instead of asking questions here", but sometimes a link to a doc gives a better answer
18:35kludgecodegfredricks: That's what I thought. The `heap`/`sorted-set` is managing my state. The analogy is prioritzing continuations in the language of the data.
18:35justin_smithkludgecode: no, a sorted-set is stateless in clojure, so an atom manages the state (or the updated binding via recursion etc.)
18:36kludgecodejustin_smith: I understand. I was just trying to make sure I was on the right track when I saw `atom` in the example code. It surprised me. That's all. Thanks.
18:36gfredericks,(def my-number (atom 42))
18:36clojurebot#'sandbox/my-number
18:36kludgecodegfredricks: I understand. Thanks.
18:36gfredericks,(swap! my-number * 12)
18:36clojurebot504
18:36justin_smithyou could say the sorted set "is" your current state, and the atom manages changes in state (by replacing it with another sorted set)
18:38kludgecodejustin_smith: So then I can just refer to the atom instead of building the set up manually each time around?
18:39justin_smithright, though an alternative is if you have some recursive function and you pass an updated version each time
18:39justin_smithtypical fp techniques you know
18:39gfredericksatoms are a sort of functional impurity; we try to avoid them when feasible
18:40kludgecodegfredricks: that's why I've deprioritized learning them in detail.
18:40gfredericksthey're handy for quick&dirty things
18:42kludgecodeThanks for all the help. I think I have enough to push the rock a bit further up the hill.
18:50gfredericksspeaking of quick&dirty I think deffing something in a function is occasionally the easiest way to do something
18:51justin_smithgfredericks: or a top level let block with defs inside it
18:51justin_smithno, actually that is never convenient
18:52gfredericksI don't mean that I keep the code that way
18:53justin_smithgfredericks: but for fixing cyclic weirdness in namespaces then, that sort of thing?
18:53gfredericksno just for stashing an arg to a function so I can poke it at the repl
18:53gfredericksI throw (def foo foo) somewhere in there
18:54gfredericksand then run the code
18:54gfredericksand boom I have a global handle to it
18:54gfredericksyou tell me a faster way of doing that and I'll repent
18:54justin_smithgfredericks: ahh, my version of that is (def debug (atom nil)) and then inside the function (swap! debug foo)
18:54turbofailyeah i usually use an atom for that
18:54gfrederickssounds slower to me :)
18:55justin_smithgfredericks: bonus, with the atom version, you can make it a vector, and conj values on - peek it to get the most recent, but you can also do things with the values it has had over time
18:55gfredericksoh totes
18:55justin_smithgfredericks: slower in dev time? it takes a few seconds maybe
18:55gfredericksyours is two steps
18:55justin_smithright, right
18:56justin_smithit also doesn't make me die of embarassment when coworkers see it
18:56gfredericksI only do it in private
18:56jonathanjif i have a map like {:key "the key" :value "the value"}, is there a concise way to turn that into {"the key" "the value"}?
18:57gfredericks(let [{:keys [key value]} m] {key value})
18:57amalloy(map m [:key :value])
18:57justin_smith,(conj {} ((juxt [:key :value]) {:key "the key" :value "the value"}))
18:57clojurebot#error{:cause "Key must be integer", :via [{:type java.lang.IllegalArgumentException, :message "Key must be integer", :at [clojure.lang.APersistentVector invoke "APersistentVector.java" 284]}], :trace [[clojure.lang.APersistentVector invoke "APersistentVector.java" 284] [clojure.core$juxt$fn__4459 invoke "core.clj" 2454] [sandbox$eval25 invoke "NO_SOURCE_FILE" 0] [clojure.lang.Compiler eval "Compi...
18:58justin_smitherr
18:58justin_smith,(conj {} ((juxt :key :value) {:key "the key" :value "the value"}))
18:58clojurebot{"the key" "the value"}
18:58amalloyoh, you want it to be a map too. so i guess (apply hash-map (map m [:key :value]))
18:58jonathanjwhat is allowed to be a key of a map?
18:58amalloyanything
18:58justin_smithjonathanj: things
18:59jonathanjbyte[]?
18:59turbofailpreferably immutable things
18:59turbofailbut they don't have to be
18:59amalloyif you do it with mutable things, or things with bad hashcodes, you will probably be sad, but it is allowed
18:59justin_smithanything but a primitive, and yeah, better if it is immutable
19:02jonathanjhmm
19:02jonathanjso i actually have a list of maps with that structure
19:03jonathanj[{:key "a" :value "1"} {:key "b" :value "2"}] => {"a" "1" "b" "2"}
19:03justin_smith,(apply conj {} (map (juxt :key :value) [{:key "the key" :value "the value"} {:key :a :value :b}]))
19:03clojurebot{"the key" "the value", :a :b}
19:04jonathanjhmm
19:04justin_smithbetter ##(into {} (map (juxt :key :value) [{:key "the key" :value "the value"} {:key :a :value :b}]))
19:04lazybot⇒ {"the key" "the value", :a :b}
19:07jonathanjah yes, i was wondering how to get rid of `apply conj {}`
19:07jonathanjthanks
19:07turbofailusing a byte array as a hash key is probably a bad idea actually
19:07justin_smithbecause of the mutation thing, right?
19:07hiredmanbyte arrays have identity equality and hash codes
19:07turbofailthe mutation thing, and the hash code is identity based
19:08hiredmanhttp://docs.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html#equals%28java.lang.Object%29
19:08turbofail~[(.hashCode (.getBytes "foo")) (.hashCode (.getBytes "foo"))]
19:08clojurebotCool story bro.
19:08justin_smith,[(.hashCode (.getBytes "foo")) (.hashCode (.getBytes "foo"))]
19:08clojurebot[867692635 1896153315]
19:09amalloy,(into {} (for [x ["test" "test"]] [(.getBytes x) x]))
19:09clojurebot{#object["[B" "[B@6dbbc7b6"] "test", #object["[B" "[B@4334b602"] "test"}
19:09hiredmanuggh
19:09hiredman#array
19:09TEttingerugggggggh reiterated
19:09TEttingeris there a reader literal for arrays?
19:10turbofailhm, that'd be a nice touch
19:10turbofail#u8[10 24 124 33]
19:11justin_smithwhat would u8 stand for there?
19:11turbofaili haven't had a whole lot of need for such a thing but i imagine someone else might
19:11turbofailwell as this is the JVM it would stand for "uh... i wish this was unsigned" 8-bit
19:12justin_smithhaha, I was gonna say
19:13turbofailbut presumably the EDN reader handler could translate it into the appropriate equivalent signed numbers
19:19gfredericksmy guess is that clojure wouldn't want to default to roundtrip serialization on objects where identity semantics are the normal approach
19:19gfredericksI suppose it could still try to print arrays with #array and just not have a default reader though
19:22gfredericks#byte 42
19:23turbofailbah, i still haven't gotten a plane ticket and hotel room for clojure/west
19:23gfredericksdo it right this second
19:23gfredericksdrop everything
19:24turbofaili'm still considering taking amtrak to portland though
19:25turbofaili might be a little bit insane
19:26gfredericksI would do amtrak if I had time and money
19:27TEttingerthe train is nicer than a plane, I gotta say
19:27turbofaili feel like a long time on a train with no internet access might be a good thing for me
19:27TEttingertrains can have internet these days
19:28gfredericksand then they don't
19:29turbofailhm. looks like the train in question does have internet access. oh well
19:29turbofaili've been told the route has amazing natural scenery
19:30hyPiRionHm. What's unnatural scenery?
19:30justin_smithturbofail: the northern route?
19:30TEttingerlike #clojure in your IRC client
19:30justin_smithhyPiRion: gary, indiana
19:30TEttingerwhich is what you might be staring at!
19:30turbofailunnatural scenery would be, say, the surface of trantor
19:30raspasovturbofail: I'm considering driving :)
19:30turbofailor the under-surface rather
19:31TEttingerturbofail, yeah the car ride around oregon area is so nice
19:31TEttingerI'm used to southern california being in constant drought, so seeing *green*
19:31TEttingeris nice
19:31turbofailjustin_smith: i'm coming from california. the route would be the coast starlight train
19:31justin_smithoh, that's a nice one, sure
19:32justin_smithmy trip will be like walking ten blocks to the light rail, then riding for ten minutes until we get downtown
19:32raspasovjustin_smith: you live in Portland?
19:33TEttingerjustin_smith IS portland
19:33justin_smithyeah
19:41btkinghey all. new person to clojure here and i’m running into a roadblock. i am trying to define a var like `(def my-var ‘(1 2 3))` and then use it like so `(first my-far)`. I keep getting exceptions around unbound vars no matter what I try. I would love some help.
19:42amalloywell uh, my-var is different from my-far
19:43amalloyotherwise what you're doing is fine; if you spell things right and it's still broken, more details are needed
19:44btkinglol yes i am spelling things right, other than right here now. So if I spell correctly in the above case, the exception is: IllegalArgumentException Don’t know how to create ISeq from: clojure.lnag.Var$Unbound
19:45raspasovbtking: can you create a gist with your whole namespace?
19:48justin_smith,(def a)
19:48clojurebot#'sandbox/a
19:48justin_smith,(first a)
19:48clojurebot#error{:cause "Don't know how to create ISeq from: clojure.lang.Var$Unbound", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: clojure.lang.Var$Unbound", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.lang.RT first "RT.java" 626] [clojure.core$first__4061 invok...
19:48btkingsure i can. however, i just noticed when i am getting different results per machine. i am getting the error on ubuntu, and not on my osx machine. seems like i have some other issues to sort out. thanks for the time
19:48justin_smithbtking: ^ most common cause of that error
19:48justin_smithbtking: are you maybe calling def inside a function?
19:50Wild_Catbtking: I'm noticing the def line you pasted has a non-standard quote in it. Maybe that's the problem?
19:51btkingthat’s not the issue, i am on two machines now and typed the output from one to the other, some formatting thing occurred
19:56TEttinger,(def my-var ‘(1 2 3))
19:56clojurebot#error{:cause "Too many arguments to def", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.RuntimeException, :message "Too many arguments to def", :at [clojure.lang.Util runtimeException "Util.java" 221]}], :trace [[cl...
19:57TEttingerthat would be if that nonstandard quote got in there
19:58btkingi’ve resolved the issue, i am using cider for repl/evaluation and the nrepl version was behind the package version
19:58TEttingerbtking, can you get any value for my-var after defining it? like
19:58TEttingerah ok
19:58btkingthanks for all the ideas, of course there was no actual problem with the code
19:58TEttingerheh, of course
19:58justin_smiththe def inside function one is fun
19:59justin_smith,(defn not-called [] (def unbound 42))
19:59clojurebot#'sandbox/not-called
19:59justin_smith,undbound
19:59clojurebot#error{:cause "Unable to resolve symbol: undbound in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: undbound in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: undbound in this context",...
19:59justin_smithoops
19:59justin_smith,unbound
19:59clojurebot#object[clojure.lang.Var$Unbound "Unbound: #'sandbox/unbound"]
19:59justin_smiththe var is created at compilation time
20:09kludgecode,my-heap
20:09clojurebot#error{:cause "Unable to resolve symbol: my-heap in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: my-heap in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: my-heap in this context", :a...
20:11kludgecode,(def my-heap (atom (sorted-set-by #(compare (:p %1)(:p %2)))))
20:11clojurebot#'sandbox/my-heap
20:12kludgecode,(swap! my-heap {:d 1 :p1})
20:12clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
20:12justin_smithkludgecode: swap! needs a function
20:12kludgecode,(swap! conj my-heap {:d 1 :p 1})
20:12clojurebot#error{:cause "clojure.core$conj__4067 cannot be cast to clojure.lang.IAtom", :via [{:type java.lang.ClassCastException, :message "clojure.core$conj__4067 cannot be cast to clojure.lang.IAtom", :at [clojure.core$swap_BANG_ invoke "core.clj" 2237]}], :trace [[clojure.core$swap_BANG_ invoke "core.clj" 2237] [sandbox$eval73 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784]...
20:13justin_smithkludgecode: the function comes after the atom
20:14justin_smith,(swap! my-heap conj {:d 1 :p 1})
20:14clojurebot#{{:d 1, :p 1}}
20:15kludgecodeAnyway, the point I was hoping to make is that `sorted-set-by` will only take one value of the comparison field for maps. That is if `my-heap` contains {:p 1 :d 2}, then {:p1 :d 3} cannot be added.
20:16kludgecodeLooks like I need java.util.PriorityQueue, after all.
20:16turbofailit works fine if your comparison function factors in other bits
20:18gfrederickskludgecode: you can use a comparison of (juxt :p identity)
20:18justin_smith(inc gfredericks)
20:18lazybot⇒ 127
20:18justin_smiththat's the ticket
20:19justin_smithnice, max value for a signed byte
20:19amalloy4karma set gfredericks -128
20:19gfredericks,Byte/MAX_VALUE
20:19clojurebot127
20:19gfredericks(identity gfredericks)
20:19lazybotgfredericks has karma 127.
20:19gfredericksphew
20:19justin_smithhaha
20:20kludgecodeturbofail: So I could kludge my code around the set semantics? Why does that sound attractive?
20:21justin_smithkludgecode: if what gfredericks suggested (which implements what turbofail said) is too ugly, you could always implement your own heap
20:21gfredericksit's still easier than managing a mutable thing
20:21gfrederickskludgecode: this also might work: https://github.com/clojure/data.priority-map
20:22gfrederickslooks like it handles duplicate priorities fine
20:24kludgecodeI thought about it before. I don't know that I really want to manage identities in the form of keys just for the sake of managing them. Though it would be kind of kludgey.
20:25kludgecodeAt least the hurt with mutation is a known form of hurt. I suspect I'll invent enough new ones on my own.
20:27gfredericksso what's your application for this?
20:32kludgecodegfredricks: Right now I'm using Coursera's *Discreet Optimization* as a platform for learning more about Optimization and Clojure. Right now I'm writing a branch and bound solver for the knapsack problem where the state is tossed on a heap. The state is a map containing a knapsack and an estimate. The heap sorts by estimate. I was using sorted-set-by. It turns out I was losing states because...
20:32kludgecode...estimates were staying the same. I didn't know this until this discussion, only that things weren't working.
20:33kludgecodesince the application is single threaded, mutation isn't quite so bad.
20:34justin_smithkludgecode: #(compare ((juxt :p identity) %1) ((juxt :p identity) %2)) sorts properly, and eliminates the problem you site
20:34justin_smith*cite
20:35justin_smithBut if a mutable never leaves scope, and never gets threaded, you can of course use it in pure code.
20:37kludgecodejustin_smith: So #(compare ((juxt :estimate identity) %1)((juxt :estimate identity) %2)) would sort on :estimate ?
20:38justin_smithsort on :estimate, if :estimate matched, it would then sort on the whole map as a value
20:40kludgecodeThat makes sense. BTW, I just came across juxt last night in Joy of Clojure 2nd edition. Thanks.
20:40justin_smith,(sorted-set-by #(compare ((juxt :estimate identity) %1) ((juxt :estimage identity) %2)) {:estimate 8 :val -1} {:estimate 1 :val 42} {:estimate 1 :val 100} {:estimate :2 :val 33})
20:40clojurebot#{{:estimate 8, :val -1} {:estimate 1, :val 42} {:estimate 1, :val 100} {:estimate :2, :val 33}}
20:40justin_smithkludgecode: that's why I inc'd gfredericks, juxt is always great
20:40justin_smith(inc juxt)
20:40lazybot⇒ 21
20:40amalloy~juxt
20:40clojurebotjuxt is pretty metal
20:41turbofailcertainly it should be the other way around, metal is pretty juxt
20:41kludgecodeBack to bashing away. Thanks.
20:42justin_smithwait, in my example above, why is the one with :estimate 8 first? I must be using sorted-set-by wrong
20:43justin_smithugh, "estimage"
20:43justin_smith,(sorted-set-by #(compare ((juxt :estimate identity) %1) ((juxt :estimate identity) %2)) {:estimate 8 :val -1} {:estimate 1 :val 42} {:estimate 1 :val 100} {:estimate 2 :val 33})
20:43clojurebot#error{:cause "clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable", :via [{:type java.lang.ClassCastException, :message "clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable", :at [clojure.lang.Util compare "Util.java" 153]}], :trace [[clojure.lang.Util compare "Util.java" 153] [clojure.lang.APersistentVector compareTo "APersistentVector.java" 424] [clojure.la...
20:45justin_smith,(sorted-set-by #(compare ((juxt :estimate vec) %1) ((juxt :estimate vec) %2)) {:estimate 8 :val -1} {:estimate 1 :val 42} {:estimate 1 :val 100} {:estimate 2 :val 33})
20:45clojurebot#{{:estimate 1, :val 42} {:estimate 1, :val 100} {:estimate 2, :val 33} {:estimate 8, :val -1}}
20:45justin_smithkludgecode: there was a tricky bug left, see this version ^
20:46justin_smithtl/dr you can't compare hash-map (or even seq, my first fallback) but putting it in a vec solves it
20:57lvhI have a system that has a bunch of stuff running in parallel using pipeline-blocking. All of the concurrently running processes do some stuff to the world, and then occasionally subscribe to (the same) states of the world. Since pipeline-blocking takes a transducer, I didn't want to mess with core.async's mult + tap, and just wrote something that add-watch'es an atom. However; it doesn't work; it blocks indefinitely. https://github.
20:57lvhcom/lvh/nordschleife/blob/master/src/nordschleife/affect.clj#L12-L63
20:59justin_smithlvh: irc broke up that url
20:59lvhhttps://github.com/lvh/nordschleife/blob/master/src/nordschleife/affect.clj#L12-L63
21:00lvhjustin_smith: Sorry; looked good from my end :-) Did that work?
21:01lvhIt's a little gross, but I couldn't come up with a significantly better way of doing it
21:01justin_smithyeah
21:01Shayanjmquestion - is this proper "clojuric form"? I thought the most elegant way to handle this is to do all of the math in a let statement, and just return in the next line: https://gist.github.com/shayanjm/451a3242685225aa934b
21:01Shayanjmbut unsure if this is how another clojurist would handle it
21:02lvhShayanjm: I'd definitely indent it more
21:02amalloyShayanjm: the general approach is fine, but you could use some newlines in the expressions for lat2 and lon2
21:03justin_smithShayanjm: one thing to note is that I don't think clojure is smart enough to simplify your multiply calls eg (Math/cos lat1) - though hotspot might be
21:03amalloyindenting it more doesn't really make sense...?
21:03justin_smiths/multiply/multiple
21:03Shayanjmhmmk
21:04Shayanjmbut past that the functional structure of it is ok?
21:04amalloyseems fine to me
21:04Shayanjmgreat, thanks for the feedback :)
21:04justin_smithyes, that's how any of us would break a computation into steps, yeah
21:04amalloyi would also consider defining aliases for the frequently-used functions in Math, so you don't have to keep typing/reading Math/whatever
21:04ShayanjmYeah definitely, that was on my next to-do
21:05Shayanjmactually that brings me to my next question, does it make sense to add vars inside the let corresponding to frequently used vals?
21:05Shayanjmi.e: bind 'coslat1' to (math/cos lat1)
21:05Shayanjmand just use that in the next sets of computations? Or does it make no performance difference?
21:06justin_smithShayanjm: I'm going to do a benchmark of (let [y (Math/sin x)] (+ y y)) vs. (+ (Math/sin x) (Math/sin x))
21:06justin_smithbecause I honestly wonder if there is a perf difference there
21:06Shayanjmsweet :)
21:08lvhamalloy: Yes, I meant linebreaks in those exprs, and indent those, instead of being on the same line :)
21:10Shayanjmjustin_smith: maybe a better test would be (let [a 1 y(Math/sin x)] (+ y y)) vs. (let [a 1] (+ (Math/sin x) (Math/sin x)))
21:10Shayanjmjust in case there's any overhead in invoking a let
21:10amalloythere's not
21:11Shayanjmdisregard me
21:11justin_smithShayanjm: yeah, even with full hotspot optimization turned on, the version with the let binding is twice as fast
21:11justin_smithbecause it does half as many Math/sin calls
21:11Shayanjmwell shit
21:11justin_smithjust benchmarked it with criterium
21:12ShayanjmThat actually surprises me
21:12justin_smithShayanjm: yeah, when in doubt, you can usually assume that clojure's compiler did not optimize something :)
21:12ShayanjmYeah noted
21:13justin_smithfor reference, the actual criterium tests / results: https://www.refheap.com/98811
21:13kludgecodejustin_smith: Thanks. When I was out walking the dogs, I realized that I have what boils down to :id already -- the unique path through the tree of the search space. Though I'm not sure about sorting a vector of booleans?
21:14lvhMostly because I spent a good while writing faster Chebyshev interpolated versions of a lot of those functions for a while :)
21:14justin_smithlvh: I think it comes down to a floating point sin instruction (not a cheap instruction)
21:14justin_smithand not super high quality in its output either
21:15justin_smitheg. for audio you want to do a proper calculation of the waveform and sample it from a table, rather than rely on the noisy output of the CPU instruction
21:16justin_smithkludgecode: OK - be sure to see my update, replace identity with vec
21:16justin_smithor use a guaranteed unique element from the input to replace vec
21:16lvhjustin_smith: Yeah. One of the benefits of the chebyshev version was that it was significantly more accurate than the instruction.
21:17justin_smithlvh: I forget, does the Chebyshev way of calculating use stored intermediates or lookup tables?
21:20justin_smithlvh: did anyone address your deadlock issue?
21:20lvhjustin_smith: you approximate a part of the function as the ratio of two polynomials
21:20lvhjustin_smith: nope
21:20lvhjustin_smith: the chebyshev part is "compute the polynomials"
21:21lvhwell, I guess that's the horner part, with some extra smarts for certain value ranges
21:22lvhjustin_smith: so, for very large inputs, fsin is pretty much totally wrong
21:22lvhjustin_smith: which is unfortunate since it takes a double :)
21:22kludgecodejustin_smith: now, after looking again and double clutching, I understand. My brain was still stuck back in identity gear.
21:22amalloylvh: i can't really follow all of the stuff going on in that paste, but it looks like you might have multiple different processes adding watches to an atom with the same key?
21:23amalloyi would expect that to replace the watcher, so that only one process is actually notified when whatever happens
21:23lvhamalloy: Yes, but the problem persists when I build the pipeline with a parallelism of 1
21:24justin_smithlvh: lines 42 through 46
21:24justin_smiththe second watch replaces the first
21:25justin_smiththe first one will never get triggered, because the second one replaced it
21:25justin_smithso if you wait on prev, you will wait forever
21:26justin_smithin fact, every time you call (get-state) there, you are ensuring any values from previous calls to (get-state) will never unblock
21:26justin_smithsince each one replaces the watcher, and ensures the chan can never be delivered to
21:26lvhjustin_smith: I don't understand why with parallelism 1; won't get-state block until it's done, therefore preventing the second (get-state) from overriding the watcher??
21:26lazybotlvh: What are you, crazy? Of course not!
21:27amalloygood work, lazy
21:27justin_smithlvh: you bind prev to (get-state), on the next line, you bind curr to (get-state), ensuring that prev's channel will never, ever be written to
21:27amalloyaw c'mon, who added another nick in here that starts with lazy. pls lazylambda, think of the tab-completion
21:27justin_smithhaha
21:27amalloylvh: replace line 29 with: k (gensym)
21:28justin_smithyeah, that may just be the fix
21:28amalloyis all that really needs to change to address what justin_smith and i are talking about. maybe there are more issues after that, but...
21:29justin_smithlvh: and I don't understand this code well enough to say this with 100% certainty, but when I see code this mind-pretzel-forming, I am inclined to believe there is some way to fold the code so my brain doesn't need to fold so much over it
21:30lvhjustin_smith: sure, but I'm saying is once (get-state) is evaluated, prev's channel is already closed, right? get-state blocks until something happens to it, and let bindings are evaled sequentially
21:30lvhjustin_smith: Yeah, I totally appreciate that it's gross. I can't think of a better way to do it, though.
21:30justin_smithlvh: why would prev's channel be closed?
21:30justin_smithit's sitting there waiting to be written to
21:31justin_smith(as in "c" as bound in block-until-updated)
21:31amalloyjustin_smith: lvh is pointing out that block-until-updated blocks
21:31lvherr, not closed, but already written to, right?
21:31lvhmaybe it should be closed, I'm not sure it matters
21:31lvhI could make it a promise-chan anyway, I know it'll only ever get one item on it
21:31amalloyso curr doesn't get defined until prev's watcher has already fired
21:31lvhamalloy: Yeah, that's what I'm saying :)
21:31justin_smithamalloy: ahh, right, - so it doesn't even return until the atom is changed...
21:34lvhOK, so let's talk about that code being totally gross
21:35justin_smithhaha
21:35lvhmaybe I'm missing some cool way of doing it
21:35justin_smithlvh: cool way, or a way of expressing it that would make it more clear to a reader what "it" is
21:36lvhjustin_smith: I think the latter would count as cool, but given that *this* is what I have right now I'll settle for less
21:36lvhSo, I have a system, and the system is supposed to have some properties that hold over time. Specifically, it's orchestrating creating and deleting some servers. Eventually, the system under test (not part of this code; this code treats it as a black box), makes there be the Appropriate amount of servers.
21:36lvhI have some pure functions that take a series of steps and figure out what that appropriate thing is.
21:37lvhSo, basically: do some stuff, figure out if the black box did the right stuff. You do that by observing the total state of the world. All of these scenarios (generated sequences of events) observe the same state of the world, so I want to distribute it to all of the things executing scenarios.
21:37lvhIdeally, scenarios would be executed concurrently.
21:38lvhDoes that help at all?
21:38lvhI guess my problem definition is pretty imperative :)
21:40lvhPart of the problem is that servers don't magically appear. They need to build; building takes time. That's what that :acquiesce method impl does.
21:42lvhI guess an alternative, but clearly not isomorphic, design would be to produce an ordered map of timestamps and things to do at that timestamp, and asynchronously both execute and collect all of that information, and then process it all the way at the end.
21:43lvh(Fortunately this only runs on one box, so I can get a monotonic & accurate clock if I really want)
21:51justin_smithit seems like the thing that would translate to core.async would be to have a function named after verifying each step, and then run those in series, followed by the verification logic?
21:52lvhjustin_smith: so, there's a verification step, and there's some "do-a-thing" steps
21:52lvhjustin_smith: I wanted them to be separate because I want to check if there's a difference between A-A-A and A-wait-A-wait-A-wait
21:53lvh(turns out, from manual testing, there probably is)
21:53lvhjustin_smith: which is why there's the defmulti; the other reason there's a defmulti is that it makes the xform really easy, it's just map ;-)
21:54lvhjustin_smith: Here's some of the less gross scenarios code: https://github.com/lvh/nordschleife/blob/master/src/nordschleife/scenarios.clj
23:19justin_smithI started a server on my vps on port 8000, I keep getting attempts to hit /manager/html from the same ip...
23:22TEttingermake that URL redirect to the wikileaks snowden stuff
23:24justin_smithooo, that would be smart