#clojure logs

2014-11-08

00:15rritochI'd love to switch to Mac but they're so overpriced, Lenovo Flex 2 (15-Inch) $700, Mac (15-inch) $2000, does Tin Cook really think we're that stupid?
00:16justin_smiththere's offices full of people with office supplied macbooks saying yes
00:17rritochI've noticed, many of my clients use Mac, I just don't get it
00:18rritochMy server with 4 Teraflops of computing power via 2 Radeon 280X's cost me less than that Macbook
00:22rritochIt was the first time I've seriously looked at Mac's in 25 years, not because Mac has improved, but because Microsoft has devolved.
00:26caternswitch to Linux
00:26caternholy crap freenode spammers everywhere
00:26caternkickban kirloo, is spammer
00:29rritochWell, I am running Ubuntu (rooted) on my server, but Linux still requires a lot of complex maintenance and configuration to set it up properly.
00:30caternthat's not true
00:30caternalso what
00:30caternUbuntu (rooted), as in you have root?
00:30caternon a server you administrate, it would be highly unusual if you did not
00:30catern(have root)
00:30justin_smithif it was complex, would we really be using it on servers?
00:32rritochjustin_smith: Once it's configured it's stable for the most part, but getting the AMD drivers and OpenCL to work properly is a nightmare
00:32justin_smithrritoch: I bought this box with linux pre-installed. Compared to installing windows or mac from scratch it was a breeze to set up (but let's compare apples to apples - pre-installed to pre-installed, install from scratch to install from scratch)
00:32rritochIt still isn't working properly
00:32rritochI can't get any video-out on the second video card
00:33justin_smithrritoch: as soon as I first powered up this machine I had full accelerated video
00:33justin_smithjust like with a mac or windows box, the factory set it up for me
00:33justin_smithcomapre apples to apples
00:33rritochI can run dual screen on the one card, but if I connect screens to the second card they don't display anything
00:33justin_smithrritoch: I am using three screens right now, I can potentially use up to five, it just works
00:34rritochFrom separate AMD cards?
00:34justin_smithone card
00:34justin_smithlike I said, it was pre-configured by the folks who built my laptop
00:34rritochmulti-monitor works fine from my first video card, I just can't get any output on the second video card
00:34justin_smithjust as your windows box was pre-configured by the folks who built your machine
00:35rritochAt least not from Linux, I have a dual-boot to windows and both cards function properly from windows
00:35justin_smithand who configured that? I expect it worked when you first bought the machine.
00:36rritochIt is a problem with the AMD catalyst driver, but I"m not sure what
00:36rritochI configured it myself, it only came with Windows.
00:37caternrritoch: yes, but someone configured the Windows for you
00:37rritochNo, I just installed the Catalyst driver and it worked out of the box
00:39caternyes
00:39caternthat's what we're saying
00:39caternanyway
00:40rritochIt worked on windows out of the box
00:40rritochIt doesn't work on Ubuntu out of the box
00:40rritochthat is what I"m saying
00:41caternyes, that's because someone already (mostly) configured it for you on Windows
00:41caternanyway
00:41rritochWindows doesn't have any effect on linux in a dual-boot situation
00:41caternyes, justin_smith was just being competitive
00:42justin_smithcatern: I just think it is unfair that people compare the experience installing an OS from scratch, to the experience with an OS that was pre-installed and pre-configured
00:42caternyou seemed to be bashing Linux and praising Windows, so he was pointing out the seeming superiority of Windows in this regard is just a result of your laptop coming preinstalled and preconfigured with Windows
00:42caternjustin_smith: i agree
00:43justin_smith"I tried to build a mercedes from parts, but just driving my kia is easier"
00:43justin_smith(an exageration, of course0
00:44rritochjustin_smith: I've installed windows from scratch literally hundreds of times, and linux from scratch dozens of times, windows is always easier to install.
00:44rritochI suppose if you have garbage generic hardware linux is easy to use, but if you have good/modern hardware, linux is a nightmare.
00:45caternsee justin_smith that's why you don't jump so far ahead in the conversation
00:45rritochI have a 5th gen motherboard and 2X GPU's, so the setup was far from simple.
00:45justin_smithrritoch: I have a laptop with a top of the line video card that supports four simulaneous external displays, 32 gigs of ram installed, and 8 cores. The machine is over a year old but it is not trash.
00:46rritochI can't compare any of this to Mac, as I said I haven't used an apple product in over 25 years, unless you count virtual machines, but I just used a prepared VM drive for that so I really don't know what the install is really like.
00:46caternwell, anyway, on Windows you *STILL* have to look around for drivers, which is ridiculous, so Linux is superior there at least. you do have an unconventional setup so some configuration is to be expected
00:48justin_smiththis is all pretty off topic, I'm sorry I went off like that.
00:48rritochWell, clojure needs an OS, and needs a good one
00:49rritochI wish oracle would bring back sparc, I bet clojure would run like a sportscar on a sparc server.
00:51rritochI've been toying with the idea of a clojure OS, but I think that would be a brutal nightmare.
00:51razum2umis there any best practice to override map->MyRecord with a function with preconditions? or do I need to stick with another fn name?
00:51justin_smithrazum2um: why override? just write your own and use it
00:52justin_smithdon't steal the name, I think that would inevitably lead to confusion
00:52razum2umjustin_smith: but ideally not about to override it, just add precondition
00:53razum2umok, is there any semantic under fn* names, would it be ok for such cases?
00:54justin_smithrazum2um: just write a function that validates the arguments and constructs the structure
00:56razum2umjustin_smith: ok, but I think it good if such cases have traditionaly approved names, e.g. map->Record* means it behaves just like map->Record but may check args and fill in defaults
00:56razum2umi think convention over configuration is always good
00:56justin_smiththere is no such tradition that I know of
00:57justin_smithadding a * at the end typically means "don't use this one"
00:57justin_smithsee fn*, let*
00:57razum2umperhaps adding a bang will be good such in rails it means that fn may raise an exception
00:58razum2umbut agian, I think absence of convention is very bad for understanding other's people code
00:58justin_smithrazum2um: in clojure a bangh usually means that a function is not safe in a transaction, or it does some extreme mutation
00:59razum2umjustin_smith: yeah, naming and cache invalidation are hard :)
00:59justin_smith,(clojure.string/join \space (filter (comp #(.endsWith % "!") name) (keys (ns-publics 'clojure.core))))
00:59clojurebot"vswap! vreset! set-error-mode! set-agent-send-executor! disj! conj! pop! compare-and-set! reset-meta! set-error-handler! set-agent-send-off-executor! dissoc! assoc! reset! alter-meta! persistent! run! set-validator! swap! volatile! io!"
01:00razum2umyes, they deal with mutation
01:01razum2ume.g. will you recognize map->>Record without looking into source of fn?
01:03justin_smithI would expect construct-Record or make-Record to do something that map->Record does not
01:09razum2umjustin_smith: ok, but how you think, is there any sense to turn it and perhaps some other similar cases into a survey? just not to invent convention, but collaborately define it
01:16rritochDoes clojure provide any means of namespace inheritance? I'm thinking of changing the MVC framework I'm using to be more pure clojure (without the gen-class) but I'd like common functions available, like view-ns/render which can be overridden but have a default functionality "imported".
01:17rritochMy issue is that use/require doesn't actually "import" the functions into the current namespace, it just makes them available for use
01:26akhudekrritoch: you can refer either some of the symbols or all of the symbols when you require
01:26razum2umrritoch: I suggest to wirite a macro generating defn's which call original fn
01:26akhudekrritoch: or do you mean you want a copy essentially?
01:27rritochYes, I want a local copy, or better yet, reference
01:27rritochProbably similar to what akhudek suggested
01:27rritochBut some means of bringing in all of the symbols
01:28akhudeke.g. you if you import into foo into namespace b, you want to be able to call it as b.foo
01:29akhudekI think there was a thread on the clojure list about that
01:29akhudekdon’t remember any good solutions sadly
01:30rritochSomething like (map #(def (second %1)) (ns-publics 'some-other-ns))
01:31rritochBut of course it would need to be much cleaner than that, I suppose a macro could be used
01:32godd2I have (map #(vector %1 %2) (range 10) (range 10)) but I want to pass that second (range 10) -as the collection itself- to the anonymous function. Is there a way to stop map from sending the individual elements?
01:33rritochI guess ... (map #(def (first %1) (second %1)) (ns-publics 'some-other-ns)) is closer though I don't think that would work... A macro may
01:37rritoch,(map #(vector %1 %2) (range 10) (take 5 (repeatedly #(range 10))))
01:37clojurebot([0 (0 1 2 3 4 ...)] [1 (0 1 2 3 4 ...)] [2 (0 1 2 3 4 ...)] [3 (0 1 2 3 4 ...)] [4 (0 1 2 3 4 ...)])
01:37rritochgodd2: Is that ok with you?
01:37rritocherr
01:37rritoch,(map #(vector %1 %2) (range 10) (take 10 (repeatedly #(range 10))))
01:37clojurebot([0 (0 1 2 3 4 ...)] [1 (0 1 2 3 4 ...)] [2 (0 1 2 3 4 ...)] [3 (0 1 2 3 4 ...)] [4 (0 1 2 3 4 ...)] ...)
01:37TEttingertbaldridge: nice work with https://github.com/pixie-lang/pixie
01:41godd2yes! thank you rritoch
01:42TEttinger,(map (partial vector (range 10)) (range 10))
01:42clojurebot([(0 1 2 3 4 ...) 0] [(0 1 2 3 4 ...) 1] [(0 1 2 3 4 ...) 2] [(0 1 2 3 4 ...) 3] [(0 1 2 3 4 ...) 4] ...)
01:42TEttingerthat does put it in reverse order though
01:43godd2TEttinger that will nicely produce the list rritoch made, but I wanted to pass the collection to the anon function so I could do more work on it
01:43TEttingerah, ok
01:43TEttingeryou can have it as a variable, or other bound name
01:45TEttinger,(let [roll (fn [] (repeatedly 5 #(rand-int 100)))] (map (partial vector (roll)) (range 10))
01:45clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
01:45TEttinger,(let [roll (fn [] (repeatedly 5 #(rand-int 100)))] (map (partial vector (roll)) (range 10)))
01:45clojurebot([(53 29 24 43 64) 0] [(53 29 24 43 64) 1] [(53 29 24 43 64) 2] [(53 29 24 43 64) 3] [(53 29 24 43 64) 4] ...)
01:45TEttingerweird
01:46TEttinger,(let [roll (fn [] (repeatedly 5 #(rand-int 100)))] (map #(vector % (roll)) (range 10)))
01:46clojurebot([0 (51 59 8 71 10)] [1 (45 46 53 29 55)] [2 (60 10 97 46 57)] [3 (67 78 25 26 55)] [4 (80 40 53 14 9)] ...)
01:48godd2awww I cant do repeated #() ??
01:48lazybotgodd2: Uh, no. Why would you even ask?
01:48rritoch? It's repeatedly
01:49godd2sorry, nested
01:49godd2I can't do nested #()
01:50rritochNo but #() is just a reader macro, you can resort to an anony function via (fn [...] ....)
01:51godd2ah okay awesome
01:51godd2yay it worked! (map #(map (fn [x y] (vector x y)) %2 (repeat %1)) (range 10) (repeatedly #(range 10)))
01:51godd2I hope that's not an entirely stupid way of making a list of vector pairs of the cartesian product of (range 10) with itself
01:54TEttingerkinda
01:55TEttinger,(map #(map vector %2 (repeat %1)) (range 10) (repeatedly #(range 10)))
01:55clojurebot(([0 0] [1 0] [2 0] [3 0] [4 0] ...) ([0 1] [1 1] [2 1] [3 1] [4 1] ...) ([0 2] [1 2] [2 2] [3 2] [4 2] ...) ([0 3] [1 3] [2 3] [3 3] [4 3] ...) ([0 4] [1 4] [2 4] [3 4] [4 4] ...) ...)
01:56godd2I added (apply concat ...) to get rid of the list of lists
01:56TEttingerremember, fns are first-class in clojure, so (fn [x y] (vector x y)) is almost the same as vector
01:57godd2TEttinger but then I couldn't rely on map passing the elements of the colls from %2 and (repeat %1)
01:58godd2are you saying I could just pass (vector)
01:58TEttingerno
01:58TEttingerthe function vector
01:58TEttingerlike in the example I just posted
01:58godd2ahh okay I was making it more complicated than I needed to
01:59godd2,(apply concat (map #(map vector (repeat %1) %2) (range 10) (repeatedly #(range 10))))
01:59clojurebot([0 0] [0 1] [0 2] [0 3] [0 4] ...)
01:59TEttingervector, instead of an anon fn calling vector, should be ever so slightly faster, and simpler to write
01:59dbasch&(for [x (range 10) y (range 10)] [x y])
01:59lazybot⇒ ([0 0] [0 1] [0 2] [0 3] [0 4] [0 5] [0 6] [0 7] [0 8] [0 9] [1 0] [1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9] [2 0] [2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [2 8] [2 9] [3 0] [3 1] [3 2] [3 3] [3 4] [3 5] [3 6] [3 7] [3 8] [3 9] [4 0] [4 1] [4 2] [4 3] [4... https://www.refheap.com/92893
01:59TEttingerand yeah, for is good for this :P
01:59dbasch^ godd2 is that what you want?
02:00godd2dbasch that is precisely what I wanted. Ill go look at the docs for for now, thank you!
02:04rritoch,(map-indexed (fn [x y] (map (partial #(vec (list %1 %2)) x) (range 10))) (range 10)
02:04clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
02:05rritoch,(map-indexed (fn [x y] (map (partial #(vec (list %1 %2)) x) (range 10))) (range 10))
02:05clojurebot(([0 0] [0 1] [0 2] [0 3] [0 4] ...) ([1 0] [1 1] [1 2] [1 3] [1 4] ...) ([2 0] [2 1] [2 2] [2 3] [2 4] ...) ([3 0] [3 1] [3 2] [3 3] [3 4] ...) ([4 0] [4 1] [4 2] [4 3] [4 4] ...) ...)
02:06rritoch,(map-indexed (fn [x y] (map (partial #(vec (list %1 %2)) x) (range 2))) (range 3))
02:06clojurebot(([0 0] [0 1]) ([1 0] [1 1]) ([2 0] [2 1]))
02:20godd2Here is the completed problem. Feel free to offer any criticism of the code, including format. https://gist.github.com/nicklink483/a7ad9968a9a58c7ebf0a
02:26arrdemOkay. Someone convince me to learn a structural editing mode for emacs
02:29nonubyis there a nil loving nth? rather than IOOB exceptipn
02:30nonubyah nevermind 3rd arg is default not found, fits
02:33rritoch,(map #(seq (zipmap (range 10) (take 10 (repeatedly (partial identity %))))) (range 10))
02:33clojurebot(([0 0] [7 0] [1 0] [4 0] [6 0] ...) ([0 1] [7 1] [1 1] [4 1] [6 1] ...) ([0 2] [7 2] [1 2] [4 2] [6 2] ...) ([0 3] [7 3] [1 3] [4 3] [6 3] ...) ([0 4] [7 4] [1 4] [4 4] [6 4] ...) ...)
02:36rritochAny ideas why that isn't sorted?
02:38rritoch,(map #(sort (zipmap (range 10) (take 10 (repeatedly (partial identity %))))) (range 10))
02:38clojurebot(([0 0] [1 0] [2 0] [3 0] [4 0] ...) ([0 1] [1 1] [2 1] [3 1] [4 1] ...) ([0 2] [1 2] [2 2] [3 2] [4 2] ...) ([0 3] [1 3] [2 3] [3 3] [4 3] ...) ([0 4] [1 4] [2 4] [3 4] [4 4] ...) ...)
02:40TEttinger(doc zipmap)
02:40clojurebot"([keys vals]); Returns a map with the keys mapped to the corresponding vals."
02:40TEttingermaps aren't sorted
02:42TEttinger,(map #(interleave (range 10) (repeat 10 %)) (range 10))
02:42clojurebot((0 0 1 0 2 ...) (0 1 1 1 2 ...) (0 2 1 2 2 ...) (0 3 1 3 2 ...) (0 4 1 4 2 ...) ...)
02:42TEttinger,(map #(map vector (range 10) (repeat 10 %)) (range 10))
02:42clojurebot(([0 0] [1 0] [2 0] [3 0] [4 0] ...) ([0 1] [1 1] [2 1] [3 1] [4 1] ...) ([0 2] [1 2] [2 2] [3 2] [4 2] ...) ([0 3] [1 3] [2 3] [3 3] [4 3] ...) ([0 4] [1 4] [2 4] [3 4] [4 4] ...) ...)
02:43TEttingerthat closer to what you're after, rritoch?
02:43rritochI see, I just assumed they maintained the order items were added to them. Scary how many bugs may be floating around because of that mistake.
02:43TEttingermaps are never sorted by default, you can use the collections in a lib called "ordered" if you want the behavior you describe
02:44rritochI actually don't have use with this code, I was just playing with the different ways of creating a matrix of positional vectors
02:44godd2in (reduce conj () "hello") is the 'magic' that reduce is treating "hello" like a sequence of characters?
02:44TEttingerthere is the sorted-map , and you can also do sorted-map-by
02:44TEttingeryes
02:45TEttingerstrings can be treated as seqs by most core clojure fns
02:45TEttingerthey aren't actually seqs but they can be used as such
02:46TEttinger,(reduce str "hello " "world")
02:46clojurebot"hello world"
02:46TEttinger##(reductions str "hello " "world") ;; let's see how this works
02:46lazybot⇒ ("hello " "hello w" "hello wo" "hello wor" "hello worl" "hello world")
02:49godd2okay cool
02:50TEttingergodd2, you'll probably enjoy learning about destructuring, if you haven't already
02:50TEttingerit's one of the cooler features clojure has in regards to cleaning up code
02:51godd2I have learned about destructuring. I haven't tried it out with all the different types and such, but I do know how to, say, pass a vector as if its elements were the parameters
02:52godd2I come from a Ruby background, and destructuring seemed similar to passing arrays to methods and having individual params take on the elements themselves by default
02:54godd2But I'm trying to learn Clojure without trying to do things the Ruby way
02:58TEttingerit does seem like a lot of people come to clojure from the ruby community. both are concise, expressive languages, certainly, with a focus on getting stuff done.
02:59godd2Even in Rich's talks you'll see various examples of things which include Ruby in the list
03:07godd2ooooh, I like this ->> thingy
03:07arrdem-> and ->> are awesome
03:07arrdemfactor of at least four readability increase once I got used to it
03:13sam122Hi, I'd like to contribute to Clojure and hopefully try out for gsoc 2015. Is it too late to start?
03:13sam122And how much knowledge of Clojure is required?
03:14godd2sam122 when you say "contribute to Clojure" do you mean Clojure itself, or something that happens to be written in Clojure?
03:15sam122Clojure, Typed Clojure etc
03:16godd2Is this a good way of formatting? https://gist.github.com/nicklink483/65b1801b00e7e0bfb816
03:16arrdemSpeaking as an ex-gsoc student, getting changes into clojure/core itself is basically impossible unless you are actually Rich
03:16arrdemthat said anyone can propose changes with no background
03:16arrdemit's just that Rich'll take only what he likes
03:16arrdemcontributing to clojure.* is easy tho
03:17godd2Also, is there a go-to format guide for writing Clojure?
03:17arrdemambrosebs, the core.typed maintainer and the other contrib libraries are awesome to a man
03:17arrdemgodd2: there is a community style guide
03:17arrdem$google clojure style guide
03:17lazybot[bbatsov/clojure-style-guide · GitHub] https://github.com/bbatsov/clojure-style-guide
03:18arrdemthere's also Eastwood, which tries to lint for unidiomatic code,
03:18arrdembut form the most part formatting isn't standardized
03:18godd2alright, thank you
03:19arrdemgodd2: functions on the same line as arguments, arguments broken by line only when you'd go over 80 or it'd be detrimental to readability.
03:19arrdemgodd2: the = and seq/reverse here
03:19arrdemgodd2: otherwise looks fine
03:19sam122Would a basic knowledge be sufficient?
03:19nonubyi have this in my project.clj https://www.refheap.com/92897 yet running lein with-profile couchexport uberjar still produces project name version (e.g. ncdoffice-0.0.2-snapshot.jar) and not couchexport.jar, any ideas?
03:20arrdemsam122: well you have to convince a maintainer or two to support you for GSoC... so prior experience/interest is a huge help
03:20sam122Ok :)
03:20sam122Thanks!
03:21sam122I hope there are more slots in 2015.
03:22arrdemshrug. find something to work on and seriously put some time into it ahead of time. I wouldn't say that getting accepted to GSoC is a horribly high bar for Clojure
03:22arrdemnot that we've had a slack project I know of so... shrug
03:51wildharvestI'm stuck on problem #22 on 4clojure, counting a sequence without using count. It's saying I tripped the alarm when I haven't used count.
03:52wildharvestI'm assuming its a macro thing, but I'm not sure if its a bug or if my solution is wrong
03:55TEttinger,(reduce (fn [c _] (inc c)) 0 [1 2 3])
03:55clojurebot3
03:55TEttingerwhat's your solution so far, wildharvest?
03:56wildharvestMy solution was (fn [s] (let [r 0] (doseq [i s] (swap! r inc)) r))
03:57TEttingerwell, swap! only works on atoms
03:58TEttingerso since r is a number, it wouldn't run anyway
03:58arrdemdo you really need mutability here?
03:58arrdem^ always ask this in Clojure
04:01wildharvestI knew I was headed in the wrong direction with swap! but wasn't quite sure how to do it with filter/reduce/map but your solution cleared that up for me
04:03wildharvestThanks TEttinger & arrdem
04:03TEttingerno prob
04:03arrdemmy pleasure
04:04arrdemI'll be here, with beer, telling you to do it better all night :P
04:41ingsocanyone use counterclockwise, I am wondering how you can get the saved changes immediately reflected in the integrated REPL - save + load
04:43amalloyarrdem: another thing to always reconsider: whether you really need the integer indices of a seq
04:44ingsocCTRLK+ALT+K seems to compile into REPL window
05:15crocketDoes clojure suffer java's null pointers?
05:17amalloybasically
05:18borkdudecrocket yes, but you can use core.typed to prevent some
05:19crocketJAva libraries throw NPEs which clojure can't prevent.
05:19borkdudecrocket most NPEs will come from interop code. Clojure's composable functions and datastructures cope with nil in a sane way.
05:19TEttingeralso, many of clojure's core functions handle nil better.
05:19crocketCan programmers write clojure codes that throw NPEs not because of java libraries?
05:19TEttinger,(map inc nil)
05:19clojurebot()
05:20TEttingercrocket: of course
05:20TEttinger,(+ 1 nil)
05:20clojurebot#<NullPointerException java.lang.NullPointerException>
05:20crocketnil == null?
05:20TEttingeryes, in clojure
05:20borkdude,(throw (NullPointerException.))
05:20clojurebot#<NullPointerException java.lang.NullPointerException>
05:20crocketThat's no good
05:20crocketnull is a mistake.
05:21borkdudecrocket maybe you can try Haskell then ;)
05:21TEttingernot having nil would mean clojure couldn't use any java libs, which would be a worse mistake
05:22crocketWhat about clojurescript?
05:22borkdudecrocket same thing
05:22crocketnull in javascript is different from null in java.
05:22TEttingerjavascript also has the concept of null, yeah
05:23borkdudecrocket Crockford said that he only uses undefined and not null
05:23TEttingeryou of course won't get NPE in clojurescript because that's an error defined on the Java VM
05:23TEttinger(technically, maybe you could if you mis-wrote a macro, but it would show up at compile time)
05:24TEttingerthere's probably something similar in JS, though I wouldn't know what it is
05:24crocketjavascript doesn't have NPE.
05:25crocketclojure looks amusing to my eyes.
05:25crocketJAva is too verbose.
05:25crocketClojure seems to beat scala on JVM.
05:25borkdudecrocket it is very amusing and also addicting
05:25TEttingercrocket, yeah, agreed about scala
05:25crocketScala is becoming the next C++.
05:25TEttingerscala is a very large language that suffers from bloat yes
05:26crocketYet, scala still has some advantages.
05:26TEttingerclojurescript's macros are done in clojure in the process of generating the javascript, and the clojure part of the compiler is on the JVM, so that's the only place CLJS can technically throw NPEs, at compile-time
05:27TEttingernever in production, which is nice
05:28TEttingerclojure is definitely a very succinct language, short code is common where in java it would be many lines
05:28crocketA fellow programmer at my company showed how beautiful clojure was compared to javascript and java.
05:29crocketYet, there is one doubt.
05:29crocketWhen coding in nodejs, I needed a lot of documentations.
05:29crocketDo I need a lot of documenatations due to dynamic nature?
05:29crocketDo I need a lot of documenatations due to dynamic nature in clojure?
05:30TEttingerthe docs are good, certainly, and there's a lot of effort to improve them further
05:30TEttingeronce you know the core functions in the standard lib, there's a lot less to look up
05:31crocketTEttinger, no
05:31crocketI want to know if the dynamic nature of clojure requires me to attach a lot of documentations to my code.
05:31crocketok
05:31crocketIn nodejs, there was no standardized way to document codes.
05:31crocketbecause static analysis fails.
05:31TEttingerwell if you're working with other programmers, they would appreciate docs. there is a standard here
05:32crocketJSDoc fails to document JS codes.
05:32crocketNo single document lib documents JS codes well.
05:34TEttinger,(defn map-indexed-2 "Runs function f on the first elements of coll1 and coll2, passing the index as the first argument, then the second elements, etc." [f coll1 coll2] (map f (range) coll1 coll2))
05:34clojurebot#'sandbox/map-indexed-2
05:34TEttinger,(doc map-indexed-2)
05:34clojurebot"([f coll1 coll2]); Runs function f on the first elements of coll1 and coll2, passing the index as the first argument, then the second elements, etc."
05:35ingsocmy first impressions of clojure (an hour or so) are that the tooling leiningen and counterclockwise(eclipse plugin) are very nice and this is my first lisp and although early days I am findign the whole environment more approachable than Ocaml (which I dipped my toes into yesterday), also I like the python style documentation for functions - dosctrings?
05:35TEttinger,(map-indexed-2 + [0 100 200 300] [0 10 20 30])
05:35clojurebot(0 111 222 333)
05:36TEttingeringsoc, yep, docstrings are nice
05:36crocketOCaml
05:36crocketThe razor of Ocaml
05:36crocketoops
05:36TEttingerOccam's razor?
05:36crocketIt's Ocam's razor.
05:38TEttingerOCaml is a strongly typed functional language with a very good, but very strict, compiler. technomancy wrote a faster-starting substitute for part of leiningen in OCaml, called Grenchman IIRC
05:38TEttingerone of the cool things OCaml can do is debug in reverse
05:39TEttingernot many libs for OCaml though
05:40rritochDoes clojure use any classloaders other than the thread's context class loader and Compiler/LOADER ?
05:40ingsocwell i haven't abandoned trying Ocaml, I just had a few problems early on. I had shortlisted Ocaml or Clojure to learn as a next language
05:40TEttingerclojure has more momentum, I'd say
05:41TEttingerit's definitely advancing into some rarely-found features, like the "transducers" being introduced with clojure 1.7
05:41TEttingercore.async I have heard good things about
05:44rritochI setup the following function to call methods on OSGi services http://pastebin.com/b7shFxXK but I'm not sure if there are any other classloaders I need to override.
05:50ingsocTEttinger: the main thing that puts me off clojure is JVM being a big beast (slow startup), but on the plus side it means it has access to all of the java ecosystem. Ocaml is much lighter weight in this regard and it also has pattern matching which I have really enjoyed in erlang.
05:57TEttingeringsoc, I've been curious about a new project called Pixie that runs a clojure-like lisp on PyPy's VM
05:57TEttingerI'm not sure if it can call python code yet https://github.com/pixie-lang/pixie
05:58TEttingerbut it does get fast startup times from that VM
05:58TEttingertbaldridge is likely asleep, but he's the guy to ask
06:24massi`hello *
06:27annelieshello
06:51godd2is there a way to not print the next return value in lein repl?
06:56hyPiRiongodd2: I usually do `(do (my-expr) nil)` to print nil instead
06:57hyPiRion,(map #(throw (Exception. %)) ["foo"])
06:57clojurebot#<Exception java.lang.Exception: foo>
06:57hyPiRion,(do (map #(throw (Exception. %)) ["foo"]) nil)
06:57clojurebotnil
06:58godd2okay cool, thanks
07:09godd2Is there a reason that leiningen won't claim more than 4 to 4.5 GB of ram?
07:10anneliesRunning a 32-bit JVM?
07:11godd2"Java HotSpot(TM) 64-Bit Server VM 1.7.0-b147" when lein repl starts up
07:12anneliesWhat is the value of :jvm-opts in project.clj?
07:13godd2That key isn't in the project.clj that boots with that repl
07:13godd2its just the default project file from lein new app
07:14godd2it's not a big deal, I was just somewhat curious.
07:16rritoch,(.maxMemory (Runtime/getRuntime))
07:16clojurebot#<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)>
07:17rritochgodd2: I suspect it has something to do with that, I have 8GB ram, but my max memory is 2GB
07:18anneliesI have 4GB and maxMemory returns 1GB.
07:20godd2ah okay got it. I did the maxMemory thing before and after adding :jvm-opts ["-Xmx12G"] to the project file and got 3.5 GB before and ~10.8 GB after
07:21anneliesGB vs GiB perhaps.
07:22godd2yes /GB/GiB/g
07:22godd2I divided by 1024^3
07:23godd2awesome, thanks guys. I super promise not to thoughtlessly set max ram higher :P
07:25anneliesI wish I wrote software where memory limits were actually a thing. :(
07:27godd2Oh I was just messing around in Clojure. apparently (reduce + (take 40000000 (range))) takes up around 5 gigs once it's finished
07:27Bronsagodd2: (take n (range)) is just (range n) btw
07:28anneliesThere is an O(1) algorithm to do that. :p
07:28anneliessum of integer range
07:28godd2n * (n+1) / 2 I know
07:28godd2I just wanted to see how far Clojure would dutifully be persistent along the way
07:29hyPiRiongodd2: huh, that shouldn't take 5 gigs
07:31godd2hyPiRion You're right, sorry. I did a (def a (take 40000000 (range))) and then (reduce + a) on a new line
07:31hyPiRionI'm not able to reproduce that with (reduce + (range 40000000)) actually
07:31hyPiRionah, right
07:31hyPiRionyeah, if you retain the head, you're going to have a bad time. But if you don't, then it should either store 1 or 32 elements only
07:32godd2because of the lazy eval of range?
07:32hyPiRionyup
07:34ingsocTEttinger: "transducers" ?, also i hear protocols are raved about but i don't know much about them are they kinda like interfaces
07:35godd2ingsoc: https://www.youtube.com/watch?v=6mTbuzafcII
07:35hyPiRioningsoc: protocols are like interfaces, but unlike interfaces, you can implement the protocol outside the record/class
07:36hyPiRionthis means if I have a protocol P in lib A, and a record R in lib B, and that I can implement the protocol for R in my app without changing lib B
07:36ingsocRich Hickey's hair gets wilder
07:37ingsoc:D
07:37SagiCZ1ingsoc: i just wanted to say that
07:38godd2"As time goes on his hair just gets better and better." - top comment from reddit thread of that video
07:38ingsocBrian May
07:39godd2It reminds me of Steven Pinker's hair
07:39ingsocHair proportional to features ?
07:40godd2Hickey might be able to join The Luxuriant Flowing Hair Club for Scientists
07:41ingsocIsaac Newton had a fair barnet on him also :)
07:44ingsochow come clojure is so fast even with it appearing to be so dynamic ? Is this just testament to the power of JVM JIT etc. ?
07:46Lowl3v3lingsoc, i believe it is primarily, yes.
07:47ingsocI know you shouldn't choose a language because of the tooling counterclockwise for eclipse and leiningen are just making clojure so much easier to use than Ocaml (I don't use or have the time to invest in learning Emacs)
07:47Lowl3v3lingsoc, you should take the time, it is worth.
07:50SagiCZ1ingsoc: but eclipse is so horrible i cant imagine any sane person could use it
07:50ingsocLowl3v3l: I have heard this a lot
07:50ingsocI have also heard that a lot
07:50ingsoc:D
07:50SagiCZ1http://www.ihateeclipse.com/
07:51ingsoceclipse appears overwhelmingly complex (considering most people just want to code in an editor)
07:51ingsocbut I kinda forced myself to use it (not knowing any better) and I spose now I know my way around it i like it
07:51ingsoc:/
07:52SagiCZ1ingsoc: i dont think its complex, but its bloated, buggy and incredibly slow
07:52ingsocversion 4+ is ridiculously slow on linux atm
07:52ingsoc3.7 works fine
07:53ingsocI code in isolation and have never been exposed to Emacs to "see the light"
07:53ingsocmaybe I will have a look one day
07:53SagiCZ1ingsoc: see intellij if you want a good ide for java and cant cope with emacs
07:54ingsocSagiCZ1: I use intellij (Webstorm) for web dev
07:54anneliesI once wrote a function that returned whether an editor is good or not.
07:54ingsocand I like it
07:54ingsocI use eclipse for python and erlang - at the time if I wanted an IDE for erlang it was the only resonably mature option
07:54anneliesIt was (partial contains? #{:emacs :vim})
07:55ingsoc:)
07:55SagiCZ1ingsoc: alright, cant believe you can still go back to eclipse.. its so bad :D
07:55ingsocI would NOT be able to code for the web now without Webstorm
07:56godd2never heard of it. what's webstorm?
07:56anneliesIntelliJ specialised for client-side web dev.
07:57godd2ah okay
07:57ingsocgodd2: from the intelliJ IDE guys (Jetbrains)
07:57SagiCZ1annelies: well i cant say that vim or emacs is bad, but it was just too much to learn new language (clojure) and a completely new editor (emacs)
07:58ingsocIt is focussed for web dev and at the time i didn;t want to have all the other features confusing the IDE (like what happens with eclipse with all its different "perspectives")
07:59ingsocnot sure if thre is an intelliJ/Webstorm plguin for clojurescript though yet
07:59ingsocplugin*
07:59SagiCZ1ingsoc: i still distinctly remember the wtf moment i experienced when trying to turn debugging on in eclipse..
08:00SagiCZ1ingsoc: there is Cursive
08:00SagiCZ1ingsoc: https://cursiveclojure.com/
08:00SagiCZ1it is amazing
08:01m1dnightugh, i've about had it with emacs and cider
08:01m1dnightthing randomly "cant find file on classpath"
08:01ingsocanyone using lightable
08:01Lowl3v3lSagiCZ1, is cursive ready to use yet?
08:01ingsoclight table*
08:02ingsocthe demos show some great promise, looks to be implementing Bret Victors demo of an interactive IDE
08:04SagiCZ1Lowl3v3l: its not finished, but i use it every day without a problem
08:04anneliesWhat'd you call (fn [& fs] (apply comp (reverse fs)))? pmoc?
08:04ingsochttp://vimeo.com/36579366 skip to 16:45 and see how he interactively develops binary search
08:04Lowl3v3lSagiCZ1, to sad i do not like non-open-source products
08:04ingsocapparently that kind of thing is avaiulable in light table for clojure
08:05anneliesMay be better to use #(-> % ...) though I guess.
08:05SagiCZ1Lowl3v3l: yeah... ive seen how open source eclipse is great.. i would rather pay a couple $$ for a good editor than tear my hair
08:06Lowl3v3lSagiCZ1, well. Emacs is Open Source and i like it. Vim too.
08:07SagiCZ1Lowl3v3l: yeah, but those are decades old.. i guess they are polished now
08:07Lowl3v3lSagiCZ1, and they are still good. I just don't like closed source in general^^
08:07SagiCZ1Lowl3v3l: i understand
08:13ingsocso what language did you guys use prior to clojure ?, are there a lot of java converts or from totally different environment (non JVM)
08:13SagiCZ1ingsoc: for me it was mostly Java
08:14Lowl3v3li use a whole couple of languages upt to now, clojure isn't even my only lisp^^
08:14SagiCZ1yeah i actually had a brief episode with Common Lisp before discovering Clojure
08:14ingsocSagiCZ1: it looks WAY more concise than Java so I am guessing for you clojure has been a productivity enhancer
08:14ingsocok
08:15ingsoca guy at a local tech meetup keeps telling me how clojure changed his views on programming and loves it keeps asking me to try it, I do the same to him but with erlang
08:15SagiCZ1ingsoc: definitely, the only gripe with clojure i have, is not understanding it as much as i understand java, so some things which should be quicker and easier to do in clojure are actually harder.. but i am getting there
08:15ingsoc:)
08:17ingsocmy concern with clojure is do i inevitably have to learn java to become truly competent. I know I am comparing apples and oranges a bit here but I use coffeescript but in the end I had to know javascript to use it effectively
08:17godd2same coming from Ruby. everything looks out of order...
08:17hyPiRionI started out with Java/Common Lisp. Really hard to understand how to do purely functional programming in the beginning, but with experience that feels superior in many cases.
08:17hyPiRionGuess coming from Erlang makes that transition a bit easier
08:17SagiCZ1ingsoc: i am not sure you would have to know java, but it might help a lot
08:18hyPiRioningsoc: Can't speak for Clojure/Java, but I don't know JavaScript properly and managed to create rather "sophisticated" ClojureScript programs
08:19godd2But I have found a couple amazing Clojure tutorials. http://www.braveclojure.com/getting-started/ for text (you can skip the emacs part if you don't emacs) and for video: https://www.youtube.com/watch?v=9A9qsaZZefw&amp;list=PLAC43CFB134E85266
08:19hyPiRionAs long as you find non-Java libraries for the things you want to do, life should be easy without Java knowledge.
08:19ingsochyPiRion: yeah, erlang was originally a bit painful as it was my first ever functional language. No loops (only recursion), single assignment, no objects or global anything etc.
08:20ingsocbig shift, but now i find it a better way to structure programs
08:20ingsocseems to force you down the path of divide and conquer with small independent easily understood functional components
08:21SagiCZ1ingsoc: i guess thats a common experience with most functional languages.. it is hard at the beginning but you can appreciate it later.. especially testing just seems so easy compared to java mutant world
08:21ingsochyPiRion: I am hoping to try clojurescript at some point as I still haven't found a nice language for client side web dev yet. Coffeecript is a nicer face to JS but it is still quite fragile
08:23Lowl3v3lSagiCZ1, there is a reason why i prefer teaching with functional languages.
08:23hyPiRionLeaky abstractions, eh
08:23Lowl3v3li believe in general functional programming is, for someone who didn't program before, easier
08:24SagiCZ1Lowl3v3l: i am not sure.. maybe for mathematcians.. imperative programming is easy because it is just a sequence of steps.. the computer follows it like a cooking recipe
08:24ingsocone problem I find people have is recursion, it seems some people have real trouble visualising in their minds eye what is occurring
08:25SagiCZ1ingsoc: it is definitely not trivial.. especially trying to visualize the call stack
08:25godd2Some otherwise imperative languages offer recursive tools, so it's not all bad depending on the transition
08:25Lowl3v3lthe problem is that imperative programming allows for constructs like x = x+1; which is kind of absurd if you think about it^^
08:25ingsocactually, do you have to be mindful in clojure of the stack or is there tail call optimisations like in erlang/Ocaml
08:26Lowl3v3lingsoc, there is a possibility for tail calls
08:26SagiCZ1there are ONLY tail recursions in clojure, right?
08:26godd2SagiCZ1 yes but not all tail recursions are tco'd
08:26SagiCZ1godd2: i see
08:27godd2at least, that's my understanding
08:27Lowl3v3lwell no. There is recur.
08:27ingsoctco means that the compiler/runtime knows that to continue next recursion it doesn't need to push anything else onto stack ?
08:27Lowl3v3lBut in general you could write a non-tail-recursion by directly calling a function generating a stack overflow with enough calls
08:28SagiCZ1does functional programming imply immutable data?
08:30godd2SagiCZ1 not necessarily. in Clojure you can tap into java data structures which are mutable
08:30ingsocSagiCZ1: my understanding is that immutable data is a key trait of functional language
08:30Lowl3v3lSagiCZ1, depends on. There is up to my mind at least the theoretical possibility to do it without by not using the von-neumann-architecture... But practical i believe so.
08:30godd2SagiCZ1 there'
08:31godd2SagiCZ1 there's also the difference between "pure" functional and functional. a "pure" function never returns anything different given some inputs
08:31Lowl3v3lgodd2, well, but foing that you leave the functional space, don't you? Functional means side-effect-free which is why clojure isn't strictly functional in the sense haskell, for example, is.
08:31SagiCZ1godd2: i wasnt talking about clojure specifically.. its possible to write a clearly imperative code in clojure.. if you use atoms and mutate states of java objects using interop.. but it is still a functional language
08:32godd2SagiCZ1 right, Clojure doesn't restrict you from not being functional, but if you want to be funcitonal, it provides every opportunity
08:32SagiCZ1godd2: i see your point
08:52oskarkvHm, what is going on here? https://www.refheap.com/919221bb6a9664a3485c8cb01
08:53oskarkvOh, literals...
08:56justin_smithoskarkv: looks like you should just match on PRIMARY / SECONDARY / MIDDLE I guess?
08:56justin_smithI haven't tried matching enums in a case before
09:01justin_smith,(case java.time.format.FormatStyle/FULL FULL :true LONG nil MEDIUM nil SHORT nil)
09:01clojurebot#<CompilerException java.lang.ClassNotFoundException: java.time.format.FormatStyle, compiling:(NO_SOURCE_PATH:0:0)>
09:01justin_smithoh, new in 1.8, duh
09:02justin_smithanyway, yeah, it seems there is no way to match on an enum (none I could figure out, at least)
09:03oskarkvjustin_smith "The test-constants are not evaluated." So I guess Class/Something is just a symbol in the case
09:03justin_smithhmm
09:03justin_smithyeah, I guess so, I thought the reader did that, but OK
09:03justin_smithoh right, the reader could not do that
09:10ingsochmmm, jobs in UK are pretty thin on the ground for clojure devs . Maybe people wanting to use clojure get java jobs and introduce clojure into their workplace
09:10ingsoc(not that I care about popularity but it would be interesting to know if clojure IS getting more popular in industry)
09:11anneliesWhere is the transducer library?
09:11anneliesI cannot find the functions mentioned in the talk on this page: http://clojure.github.io/clojure/
09:12SagiCZ1~lazy-logs
09:12clojurebotlazy-logs is http://logs.lazybot.org/
09:14SagiCZ1ingsoc: if you want a language that is widely used and get a job with it, java is the surest way to go.. there is just so many java jobs its mind boggling.. i was looking for a java job and was employed within 5 days
09:14Glenjaminis anyone else seeing all the gravatars missing on github.com?
09:15AeroNotixGlenjamin: force refresh
09:15Glenjaminseems like github itself is now breaking anyway
09:15Glenjaminall the graphs on https://status.github.com/ just shot up
09:16ingsocSagiCZ1: I was just curious as to whether clojure is becoming an employable skill and popularity increasing or has it topped out
09:16Glenjaminingsoc: where in the UK are you looking?
09:17Glenjamini know thoughtworks are pushing Clojure quite a bit, and there's some GDS stuff thats starting to use it
09:18AeroNotixuswitch are big clojure users
09:18AeroNotixin the UK
09:18Glenjamini think mail online do a bunch of clojure as well
09:19ingsocGlenjamin: currently in Manchester, and I have been to some of the their tech talks. I was just curious as to the general trend of whether companies are seeing the benefits of moving away from traditional languages like java/.net for greenfield projects
09:19AeroNotixThe Guardian do a bit here n there, though mainly Scala.
09:20ingsocScala seems overly complicated
09:20AeroNotixingsoc: you should look at the financial sector in London
09:20Glenjaminingsoc: outside of London i mostly see companies playing it safe with PHP/Java/.net/Python/Ruby
09:20ingsocyeah, erlang seems popular in London too in finance
09:20Glenjaminand really, who wants to go live in London?
09:20ingsocyeah exactly
09:20AeroNotixmeh, rough with the smooth
09:21AeroNotixI moved from Blackpool to Poland to write Erlang+Clojure
09:21Glenjaminif you fancy heading over to Sheffield we're doing some ClojureScript at the functional programming meetup on tuesday
09:21ingsocwhatever you extra case you earn will be absorbed by property costs, unless you want shit loads of commuting wasting your life away
09:21Glenjaminhttp://defshef.github.io
09:21AeroNotixSheffield/Leeds is where I am thinking of moving back to
09:21GlenjaminThere's a lot more jobs in Leeds unfortunately :(
09:21ingsoci meant, whatever extra you earn by working in London will be absorbed by property costs
09:22AeroNotixGlenjamin: that's what I've heard as well
09:22GlenjaminI think Sheffield is much nicer, but I'm biased
09:22justin_smithingsoc: that's what folks say about SF around here
09:22AeroNotixmy brother is in Leeds at the moment
09:22GlenjaminWhere's he working?
09:22AeroNotixJust at Uni
09:23the_freyingsoc you looking for a clojure job in manchester?
09:24SagiCZ1justin_smith: i mean... living in SF is exactly the same as anywhere else in the US.. except when you open the door outside.. you are in SF, haha
09:24Glenjaminthe_frey: do some exist?
09:24the_freyour company is moving some infrastructure to it, I'm having to learn clojure for work atm :)
09:24ingsocthe_frey: no, I was just curious as to where the job market is heading, whether more opportunities are being created over time. I am a complete clojure noob, just started out today pretty much lol, I am an erlang and frontend web dev
09:25the_freythough tbf we are tiny
09:25the_freyright k
09:25Glenjaminoh neat, i could probably do some clojure in manchester
09:25justin_smithSagiCZ1: I meant in terms of the money you make / how much you pay for rent
09:25the_freybut yeah we are hiring (I think)
09:25the_freylemme find the link
09:25the_freyhttp://www.swirrl.com/jobs
09:26the_freyour clojure yoda is the guy who runs lambda lounge in mcr, really really clever dude
09:26SagiCZ1justin_smith: you make more, you spend more.. you are living in Cali..
09:26Glenjaminis lambda lounge still going? i heard it had fizzled out
09:27justin_smithSagiCZ1: it seems like half of Cali is trying to move here
09:27the_freyGlenjamin: it became a lot more infrequent for a while because of the difficulty of finding speakers
09:27the_freybut it's got a bit more momentum of late
09:27Glenjaminoh cool, i should try and head across the pennines then
09:28SagiCZ1justin_smith: and half of the world is trying to move to Cali ...
09:28the_freyI _believe_ we might be sponsoring beers at the next one because I think we might be doing one of the talks
09:28Glenjaminmight be able to blag some (def shef) speakers out of it
09:28the_freyabout the graph data & RDF stuff we're doing in clojure
09:28the_freyhence why a rubyist like me is shifting over to it :)
09:29justin_smithI hear many stories of folks who get hired at a ruby shop and slowly push everything into clojure
09:29ingsocthe_frey: Rick ?
09:30ingsocI did an erlang talk there a while back
09:30AeroNotixingsoc: what're jobs like in the UK for Erlang?
09:30ingsocwas my first tech talk so was not as smooth as i wanted
09:30ingsoc:)
09:30AeroNotixI'm writing Erlang as a dayjob at the moment
09:30the_freyingsoc yeah Rick, really nice guy to work with, gotta say
09:31ingsocAeroNotix: mainly London based work, but there are some companies using it outside of London but it seems to be not widely publicised
09:31AeroNotixhmm, ok
09:33GlenjaminSomeone's doing an Erlang POC at the mo in the company in Leeds I'm working for
09:33ingsocAeroNotix: keyword search on a local jobsite brings back 18 with clojure and 12 with erlang, there are obviously thousands of java and .net and 100's of python/ruby
09:33Glenjaminbut I suspect hiring concerns will mean it never makes it to production
09:34AeroNotixingsoc: interesting. I write Erlang and Clojure at work but I am based in Poland (blackpool originally). Thinking of coming home soon.
09:34Glenjaminwe're having enough issues hiring people who are any good at Node.js
09:34AeroNotixGlenjamin: then stop using node.js
09:34AeroNotixSolved.
09:34AeroNotixThat'll be my daily fee, thanks
09:34Glenjaminhah
09:34the_freyGlenjamin to be fair we have trouble hiring rubyists :) there are crap programmers in every lang
09:34ingsocAeroNotix: well I think these technologies are still kinda a technical edge over the competition that use traditional languages
09:35Glenjaminit's not so bad really, being JS you can write it functionally
09:35ingsocso maybe their use doesn't get shouted about outside of their respective tech communities
09:35Glenjaminsupervisord + rabbitMQ + node.js processes = poor man's erlang
09:35AeroNotixAt that point just use Erlang
09:36Glenjaminwell yes, but that doesn't really help us deal with the the 3 years-worth of code that's running and works
09:36anneliesWrite a JavaScript-to-BEAM compiler.
09:36ingsocyeah in clojure
09:36Glenjaminwhich is why someone is doing an erlang proof-of-concept
09:37ingsocsomeone created a javascript project that can interpret beam files in browser
09:37anneliesSpeaking of writing compilers in Clojure, core.logic seems a good fit for implementing type inference.
09:38ingsocAeroNotix: Funny you say you moved from UK to Poland, usually it is the other way around
09:38AeroNotixingsoc: tell me about it
09:38ingsocdid you meet a Polish girl in UK then emigrate with her
09:38AeroNotixduh
09:38AeroNotix:)
09:39ingsoclol
09:39ingsocwhat's wrong with meeting a nice English girl on a hen do in Blackpool
09:39ingsoc:P
09:39ingsoclol
09:40AeroNotixyeah and be disgusted 24/7
09:40ingsoctray of fish and chips and a couple of bacardi breezers for her
09:41ingsocand you're in
09:41AeroNotixtoo easy, in my youth I took advantage of this :)
09:42ingsocAeroNotix: what's the salary to living cost ration like in Poland ?
09:42ingsochoping it is better than what it appears to be for unskilled Polish workers
09:42ingsoc(which causes them to move here)
09:43AeroNotixingsoc: I'm in a unique field so it's pretty good for me
09:43AeroNotixbut for regular folk, it's hard. Of course.
09:43AeroNotixbut I make 4kGBP a month so I'm not complaining.
09:43AeroNotixover here that's extremely good
09:44ingsochow much is a tyskie over there ?
09:44ingsoc:)
09:44AeroNotixI don't drink piss
09:44ingsocloool
09:44ingsocwell i don;t drink it, but I don;t know any other Polish beers
09:44AeroNotixKeep an eye out for Pinta or Ale Browar
09:45ingsoci guess you would have to earn a fair bit more than that to live a similar standard in UK
09:46AeroNotixWhat are you getting?
09:46ingsocsounds like you are doing pretty good then
09:48ingsocI am currently taking time out to learn other things (living off investments) but when I was working it would be circa 55-60k per annum although this was not programming, I was working as operations management type role
09:48ingsocI just have an interest in programming
09:48AeroNotixok
09:49AeroNotixWhat're people using to generate documentation/
09:49AeroNotix?
09:50ingsocAeroNotix: are you using clojure and erlang on the same system, or are these separate projects
09:51ingsocjust interested to how they are being used together
09:52SagiCZ1ingsoc: is it rude to ask people how much they make in UK?
09:52AimHereIt can be, yes
09:52ingsocerm, possibly yeah, but obviously it depends on individual. IRC is anonymous though
09:53AeroNotixingsoc: Erlang is used for maintaining a high number of connections to hardware devices
09:53AeroNotixingsoc: CLojure is used because Erlang isn't a general purpose language
09:53ingsocI wouldn't walk up to someone in person and say oh btw what do you earn
09:53AeroNotixAimHere: yes it's rude but we are anonymous
09:54SagiCZ1ingsoc: i see, thanks
09:54AimHereWell he asked about the UK; on the Internet, the concept of 'rudeness' has long gone out of fashion
09:54ingsocAeroNotix: so are you communicating with clojure over ports or some other mechanism
09:54ingsoc(erlang ports)
09:54AeroNotixingsoc: typically HTTP
09:54ingsocok
09:54AeroNotixingsoc: you could call it a microservices architecture
09:54AeroNotixErlang forms the hub
09:54AimHereOn the internet, you're a sophisticated gentleman, if you don't call people by racial or offensive epithets, or post pictures of people being beheaded more than once a day or so
09:55ingsocI have used python (for certain libs not available in erlang) and communicated over port (stdio)
09:55SagiCZ1off topic, i am using joda time, and i have a date [year month day], and i need to know which week in the month is the day in.. first, second, third or fourth week.. how can i do that?
09:55AeroNotixingsoc: I'd prefer HTTP over ports as a first pass, optimize as necessary
09:56ingsocAeroNotix: i found it useful as you get to have the processes supervised by erlang so you only have to worry about keeping the erlang node running (which is generally bullet proof)
09:56SagiCZ1wait.. i could just do (quot 30 day) i guess
09:57ingsocit wasn;t about optimisations
09:57AeroNotixingsoc: meh, just use a proper init system which keeps processes alive
09:57ingsoc(OS Process running python/JVM)
09:57ingsocyeah i notice ubuntu has upstart that can do that
09:58ingsocrestart mnechanism etc.
09:58AeroNotixindeed
09:58ingsoc(I am a windows guy originally but switched to linux as the open source ecosystem is much better)
09:59anneliesSagiCZ1: just (quot day 7)
09:59annelies,(map #(quot % 7) (range 31))
09:59clojurebot(0 0 0 0 0 ...)
09:59annelieslol
10:00ingsocdoes the "?" in odd? empty? have any special relevance other than it makes it visually appear as a question
10:00AimHereNo. That's it's sole purpose
10:00AeroNotixingsoc: just makes it a question
10:00AimHereThere are no side effects
10:00AeroNotixsome lisps use the -p suffix
10:01AeroNotixintegerp stringp etc
10:01AeroNotixfor predicate
10:01SagiCZ1zerop?
10:01AeroNotixSagiCZ1: just zero? or zerop
10:01justin_smith,(defn !? [a] (+ a a))
10:01clojurebot#'sandbox/!?
10:02justin_smith,(!? 2)
10:02clojurebot4
10:02justin_smithingsoc: clojure has very few operators / special symbols. It's usually just part of a name.
10:04justin_smithin fact, the only things other than white space that I can think of that are contiguous with a name, but not part of it, would be () {} # . ^ [] (I may have missed one or two)
10:04justin_smith/ of course has special meaning inside a symbol too
10:05justin_smith@
10:06justin_smith` and '
10:07anneliesYou can have foo'bar as name.
10:07justin_smithahh, and foo@bar too
10:07justin_smith,(def foo@bar 0)
10:07clojurebot#<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)>
10:08justin_smithor not
10:08justin_smithheh
10:08anneliesyou can with #
10:08justin_smithyeah, many of those are only special as the first character
10:08justin_smithnone special as last
10:08SagiCZ1clj-time uses system language for the formatter, how can i switch it to english?
10:08anneliesHere is the exact syntax: http://clojure.org/reader
10:08SagiCZ1this should give me the name of the month, but its in my local language:
10:08SagiCZ1(f/unparse (f/formatter "MMMMM") (t/date-time 2010 6))
10:08anneliesUnder "Symbols"
10:09justin_smithannelies: thanks
10:10justin_smithannelies: that's not really accurate, though, because it doesn't indicate that ' can be used (which is commonly used in symbols in practice)
10:11anneliesSagiCZ1: eww assumptions. Anyway: (with-locale (f/formatter "MMMMM") java.util.Locale/ENGLISH)
10:11anneliesOr Locale/ENGLAND maybe.
10:12SagiCZ1annelies: where is with-locale from? is it clojure.core?
10:12anneliesin clj-time.format
10:13SagiCZ1annelies: thank you so much, works well
10:13SagiCZ1(inc annelies)
10:13lazybot⇒ 1
10:14anneliesI wish tools did away with assuming default locales and time zones and stuff like that.
10:14anneliess/tools/libraries/
10:14anneliesSuch defaults are only useful in a very small set of programs.
10:15SagiCZ1very true
10:16ingsocIthought clojure was single-assignment so why does the repl allow reassignment ? just for convenience ? or is there something different at work ?
10:16justin_smithingsoc: not single assignment at all
10:16justin_smithvars are mutable
10:16ingsocok it is within a defined namespace it is single assignment
10:16justin_smithno, vars are mutable
10:17justin_smiththe value in the var is usually immutible, a var itself is not
10:17justin_smithand every var used in practice is in a namespace (def / defn can only make namespaced global definitions)
10:18GlenjaminSagiCZ1: i think you can set the default JVM locale to english, and most libs will use that as their default
10:19Glenjamini've got :jvm-opts ["-Duser.language=en" "-Duser.country=GB"] in my project.clj, which i think is related
10:19m1dnighthow are macros expanded, from the outside in, or the inside out?
10:19SagiCZ1Glenjamin: thanks
10:19justin_smithm1dnight: outside in - a macro decides how to handle each of its arguments
10:19Glenjamin,(macroexpand-1 '(and (and 1 2) 3))
10:19clojurebot(clojure.core/let [and__4069__auto__ (and 1 2)] (if and__4069__auto__ (clojure.core/and 3) and__4069__auto__))
10:20m1dnightaha excellent :) thank you
10:20Glenjaminforgot about symbol expansion, that's not as clear as i was expecting it to be
10:20justin_smithm1dnight: otherwise things like when / and etc. couldn't short circuit
10:20m1dnightah, valid point
10:20m1dnighthadn't thought about ti that way
10:21Wild_Cathold on, why is and a macro?
10:22justin_smith~source and
10:22justin_smithit uses if
10:22justin_smithif is the more fundamental
10:22Wild_Catoh, because it does shortcut evaluation
10:23justin_smithas does or
10:23Wild_Catright, makes sense.
10:23gfredericksif or and when, let not but-last.
10:23Wild_CatI actually wouldn't have expected Clojure's boolean operators to do shortcut eval.
10:23anneliesWhy not?
10:23gfredericksnew game - make english sentences out of clojure functions.
10:24justin_smithhah
10:24gfredericks"vector is not list."
10:26annelies,is
10:26clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: is in this context, compiling:(NO_SOURCE_PATH:0:0)>
10:26justin_smith,(require 'clojure.test)
10:27clojurebotnil
10:27justin_smith,#'clojure.test/is
10:27clojurebot#'clojure.test/is
10:27justin_smithit's a macro though
10:28justin_smith,(doc future-cancel)
10:28clojurebot"([f]); Cancels the future, if possible."
10:28justin_smithmy favorite bit of poetry in the clojure codebase
10:28Glenjaminwhen short reductions compare and repeatedly cycle, double key locking
10:28anneliesSometimes I wish I were a prn-str.
10:28Glenjaminthere's not many nouns :(
10:29m1dnightnot any?
10:29m1dnight:D
10:29justin_smiththe hard part is the lack of articles
10:29Glenjamin"do reductions keep rational?"
10:30justin_smithhaha
10:30justin_smithagent prefers locking intersection
10:31justin_smiththat would be better if I could use "the"
10:31Glenjamin"do some parents compare distinct?"
10:32justin_smithaha
10:32anneliesdo not take hash
10:32justin_smithparernts reverse, locking intersection
10:32justin_smithmuch better
10:34anneliesHmm, speaking of rearranging words, I should port my Markov chain library to Clojure.
10:34justin_smithI did one - I was amazed how succinct I could do everything in clojure actually
10:35justin_smithcomplete with optional seed and variable memory
10:35anneliesHere is the existing one in Scala: http://ideone.com/Do2DTU
10:36m1dnightoh dear, second time this week i misspell "filter" with "fitler"
10:36annelies(def fitler filter) and nobody will notice :)
10:36justin_smithannelies: ah, yourse is by word, I did mine by character - which means with a shorter memory it is prone to inventing "words"
10:36m1dnight:D
10:37anneliesOh I meant just porting MarkovChain, not NonsenseGenerator
10:37justin_smithannelies: oh, that will be like a four liner I bet
10:38anneliesYeah. :P
10:38anneliesWell, a protocol and a function transition
10:39anneliesMine is bugged actually. It fails if the PRNG returns exactly 0.0.
10:39anneliesThen it throws a NotImplementedException :v
10:42justin_smithannelies: I am not very good at reading scala - does yours use start / stop tokens?
10:42anneliesNo idea what those are. :P
10:42anneliesThe nonsense generator just constructs a map of (current word, set of possible next words) pairs
10:43anneliesAnd then it starts at a random word.
10:43justin_smithannelies: when analyzing an input, a start token is inserted at the beginning, a stop token appended at the end, then "generate" will start with one of the start tokens (with a weighed probability) and stop if it reaches a stop token.
10:44ingsocAeroNotix :name <- is this kinda like an atom in erlang
10:44anneliesOh no it just picks a random word to start with. There is no stop token, it stops when you stop calling transition.
10:45anneliesSo to construct a nonsense paragraph just reduce with transition and string concatenation
10:45AeroNotixingsoc: yeah
10:45AeroNotixingsoc: but there's no atom table
10:45oskarkvSay I want to use JavaFX or Swing or some other Java lib. And I have an idea for a new Node/Control (like Label, Image, Button). Then I would like to create a named class, that can extend a class and implement interfaces. What would you guys use for that? It almost seems like the easiest choice would be to forget about the named class thing and make a proxy for each instance.
10:45justin_smithannelies: an interesting side effect of using start/stop tokens is that if your input was grammatical, the output will start with a capitalized word, and end with a period / newline
10:45AeroNotixingsoc: so you can make as many as you want
10:45anneliesjustin_smith: a right :p
10:46justin_smithoskarkv: yeah, proxy or refiy likely
10:46justin_smith*reify
10:46justin_smithtime for coffee
10:46grandyanyone know the best practice for server side session state in compojure ?
10:46oskarkvbut reiddraper can't extend classes, right?
10:46oskarkvops
10:47oskarkvreify*
10:47justin_smithI am pretty sure reiddraper has extended quite a few classes :)
10:47oskarkvhehe
10:47oskarkvWouldn't it make sense for clojure to be able to make new named classes for interop purposes?
10:47justin_smithoskarkv: reify can implement any number of interfaces
10:48grandyis it ring-clojure ?
10:48oskarkvor maybe that's what genclass does
10:48oskarkvjustin_smith yeah but not extend classes right?
10:48justin_smithoskarkv: right, but swing should only care about interfaces, not classes for the most part, I would hope
10:48justin_smithoskarkv: maybe my optimism is misplaced
10:48oskarkvhehe
10:49oskarkvSometimes it saves work to extend :p
10:49justin_smithanyway, if interfaces are sufficient (hopefully they are), with the help of defprotocol you can extend however you like - unless it actually needs you to inherit specific classes
10:50anneliesWeighted choice is one of those things I love implementing imperatively rather than functionally.
10:50justin_smithheh
10:50ingsocAeroNotix: ok thanks
10:50AeroNotixingsoc: nw
10:51justin_smithannelies: my rng is of course imperative, but I actually did the weighted choice as a pure function otherwise
10:51anneliesYou can write pure functions using imperative programming.
10:51justin_smithof course
10:51justin_smithbut I used standard fn / reduce and no state mutation is what I mean
10:53grandyok fine
10:54justin_smithgrandy: ring-clojure is a session state?
10:54grandyit has a session namespace
10:54justin_smithyeah - compojure is just a routing lib
10:54justin_smithfor the other stuff, you want to look at ring middlewares
10:55grandyjustin_smith: cool that's what i thought but wanted to make sure i hadn't missed something... there have been a few deprecated projects in this area
10:55justin_smithit's true
10:56justin_smithgrandy: I've never even heard of someone using compojure without ring
10:56justin_smiththough it may be hypothetically possible
10:56grandyjustin_smith: cool yeah i think there have been some other libs that may do some session stuff too, also on top of ring
10:57justin_smithright, and they will all act as a ring middleware
10:57anneliesHmm, I guess I can use reductions for it.
10:57SagiCZ1,(for [i "abc"] (for [j (range 3)] (str i j)))
10:57SagiCZ1i need this to return ("a0" "a1" "a2" "b0"... should i use flatten?
10:57clojurebot(("a0" "a1" "a2") ("b0" "b1" "b2") ("c0" "c1" "c2"))
10:58justin_smithgrandy: I use ring.middleware.session/wrap-session
10:58grandyjustin_smith: ahh ok perfect that looks useful
10:58justin_smithgrandy: you can specify what sort of storage you want with that
10:59grandyjustin_smith: cool
10:59SagiCZ1nevermind, got it
11:00justin_smithSagiCZ1: you don't need to ever nest for calls
11:00justin_smith,(for [i "abc" j (range 3)] (str i j))
11:00clojurebot("a0" "a1" "a2" "b0" "b1" ...)
11:01SagiCZ1yeah i found that out, thanks
11:01justin_smithOK - just making sure you figured out the simple way
11:05anneliesI think I got it: https://gist.github.com/rightfold/a2394f6d9cd785fcc990
11:05justin_smithvery nice
11:05justin_smithbetter than mine
11:05justin_smithhttps://github.com/noisesmith/markov-toy/blob/master/src/markov/core.clj#L14
11:08oskarkv,(for [i "abc" j (range 3)] (str i j))
11:09clojurebot("a0" "a1" "a2" "b0" "b1" ...)
11:09oskarkvoh, was scrolled up :p
11:17m1dnightguys, I'm having a brainy problem. At runtime I want to add stuff to a list and then return that list.
11:17m1dnightThe reason is that I need the values of the expression before.
11:17m1dnightIs there an idiomatic way?
11:18m1dnightsince immutability and all ..
11:18m1dnightwait a minute
11:19m1dnightyeah, still. I have a function that does a message send to a thread. But this send could contain values that are in the current lexical scope. However, I want to do those message sends during a commit. Ergo, I have to get the values out of scope to use them in a differnet one
11:20m1dnightSo I figured I could 'cons' them to a list (to say it in lisp terms) and then return that list to the other scope
11:20Glenjaminm1dnight: can you provide a code sample i'm not clear why (cons) isn't enough here?
11:21m1dnightwell, I have a meta-circular STM implementation. I also have an implementation of Erlang actors. Now in my state change of my actors (ie the body) I want to send messages to other actors.
11:21m1dnightBut, i'm experimenting with an actor that has a dosync in his body, and inside that dosync, sends a message to another actor
11:22m1dnightI want to hold that message back until commit.
11:22m1dnightbut, since the commit happens in a different scope, i need to get the values that are sent to an actor in a message out of the scope
11:24Glenjaminyou might be able to do something with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/add-watch
11:24m1dnightwait a minute, i think you gave me an idea :D
11:24m1dnight
11:24Glenjaminif i'm understanding, you want to queue up message sends until your current actor transaction is finished, then send them
11:24m1dnightyes, indeed
11:25m1dnightbut that's easy, because a message is a keyword (e.g., :message)
11:25m1dnightso I can do something like (! actor :message <var> <var>..)
11:25m1dnightthat sends the message :message to the actor and attaches the values <var>
11:30cristianHi guys. I wonder what's the idiomatic way in clojure to define functions that might fail or that might return null. In Java 8, I'm mostly using Optional. In Haskell I use Maybe and Either.
11:31cristianHow do you usually implement such functions in Clojure?
11:31Glenjamingenerally i'd just return null
11:31ingsocAeroNotix: lein repl :connect seems like a it provides some of the remsh stuff of erlang
11:31Glenjamini think core.typed has a way of saying whether a function will or wont return null
11:31ingsochave you sued this ?
11:31ingsocused*
11:31AeroNotixingsoc: it does
11:32Glenjamina lot of core functions do something useful if you pass null
11:32Glenjamin,(assoc nil :a 1)
11:32clojurebot{:a 1}
11:33ingsocAeroNotix: can you reload new version of code ?
11:33ambrosebscristian: do you want to know how to define such functions or use their outputs?
11:33AeroNotixingsoc: yes, much better than the way Erlang does it, too.
11:33AeroNotixingsoc: because you don't have supervision trees to tear down as a whole, you can just redefine whatever you need in-place and the running code picks it up.
11:34GlenjaminAeroNotix: as long as there's no state :D
11:34justin_smithingsoc: as I mentioned before, vars are mutable, so to the extent that your code is all vars, yes - the tricky thing is of course any closed over state, sometimes to get a good reload you need to define a restart of some sort
11:34Glenjaminsee also, the "component" library
11:34AeroNotixYeah component is really good
11:34justin_smithGlenjamin: yes, component was what I was getting at :)
11:34ingsochmmm, to get this straight in my mind, does the Java VM when running clojure listen on the nrepl port all the time
11:35ingsocso you can connect at any time or do you have to enable something in the project ?
11:35Glenjaminingsoc: when you run "lein repl", it starts a client+server
11:35justin_smithingsoc: only if you open an nrepl listener
11:35justin_smithlein opens one for you
11:35justin_smithor you can do so yourself in production code if you wish
11:35justin_smithbut you should not use lein in production
11:35AeroNotixIn production code I have nrepl spawning a listener as part of main
11:36ingsocok i see. I was doing this in counterclockwise. I spose when you run your project in counterclockwise it does plumbing for you
11:36anneliesI wish I wrote production code.
11:36AeroNotixannelies: Why don't you?
11:36ingsoc(it runs lein)
11:37justin_smithingsoc: the code to start your own nrepl server is clojure.tools.nrepl package
11:37justin_smithit's pretty easy
11:38cristianambrosebs: I want to know how you define such functions. For instance, you can define a function that returns Either in Scala (or haskell), and the client of the function knows that it has to pattern match the result to know if the computation succeeded or not (and if not, you get useful data about what went wrong). How do you guys handle such cases in clojure? I don't want to just emulate what I do in
11:38cristianimperative languages... I want something more Clojure-idiomatic
11:38anneliesAeroNotix: I mean in Clojure.
11:39anneliesI write it in Python though.
11:39ambrosebscristian: in Clojure you just return null in the function and document it in the docstring or contract.
11:39cristianOk
11:39cristianThanks
11:40Glenjaminambrosebs: does core.typed let you annotate as "will not return null" ?
11:40ambrosebsGlenjamin: yes, references are non-nullable
11:40anneliescristian: it's better to use \/ than Either for that in Scala. Either isn't designed for failure vs. success, but just as a utility union type.
11:40Glenjaminand presumably with anything that can return null i have to handle it to type check?
11:40ambrosebscristian: check out some->, when for some macros to help *use* nullable values
11:41cristianannelies: pardon my ignorance... what do you mean by \/
11:41ingsoci need to learn how this works then. I thought this wasn't possible on JVM and afaict all clojure code is compiled into java classes / byte code ? so what's the deal there ? Or could you also do this with java code ?
11:41ambrosebsGlenjamin: yes, just in the same way you'd do it in clojure. (fn [a :- (U nil Int)] (when a (inc a)))
11:42Glenjamini think mostly i forget to check for nil :) i should really find an excuse to play with core.typed
11:42justin_smithingsoc: it's the opposite - every object in the jvm is nullable, and we just adapt to that
11:42anneliescristian: http://docs.typelevel.org/api/scalaz/nightly/#scalaz.$bslash$div has a right-bias (right indicates success) for map, filter etc... which is far more useful than Either's left and right projections when dealing with failure vs. success
11:44ingsocjust looking at jetty, looksamazingly easy to providew a simple http api
11:44justin_smithingsoc: in clojure, use ring
11:44ingsocfun stuff :)
11:44ingsocring ?
11:44ingsocoh ok
11:44justin_smiththere are very few reasons not to use the ring abstraction
11:45cristianannelies: thanks. That's interesting. Why doesn't clojure have something like that? Is it not need ti?
11:45ambrosebsGlenjamin: a good excuse, but my advice is to become comfortable with some-> and the like.
11:45justin_smithit turns mutating code on streams into pure functions of request-map / response-map
11:45anneliescristian: No idea. I always throw exceptions when something goes wrong.
11:46ambrosebsGlenjamin: or least use contracts to be explicit about what values you think are allowed at certain points.
11:46justin_smithcorrect me if I am wrong, but my gist is that as opposed to the scala approach where they try to define a more sane semantics (and all the work that goes into that...) clojure takes the lazier approach of taking the java semantics as a given and dealing with it in a way that tries to minimize complexity
11:46Glenjaminambrosebs: i suspect the greater benefit to me would be the tool reminding me i forgot to use some/when/if/or etc
11:46ambrosebsGlenjamin: sure, core.typed is the perfect tool for that.
11:46ambrosebsit will find *all* the cases you forget in typed code.
11:48ambrosebsthe only time I've described core.typed as the perfect tool for anything.
11:49Glenjaminhaha
11:49ambrosebsbut you exactly described the reasons for core.typed's existence
11:49justin_smithambrosebs: your humility is appreciated
11:49ambrosebs:)
11:54ingsocAeroNotix: last question for the day (hopefully :P). Overall what are your impressions of clojure as a compliment to erlang and how it compares on productivity to alternatives ?
11:57anneliesHeh, clojure as a compliment to erlang. "Hey erlang, you've got a nice clojure there!"
11:57ingsoc:)
11:57ingsoc:P
11:57justin_smith"hey erlang, love those actors, mind if I borrow a few ideas?"
11:58anneliessuch as lightweight processes ;_;
11:58justin_smithannelies: isn't this what core.async was going for?
11:59anneliesNever looked into core.async.
11:59ingsocwell erlang = (robustness, concurrency, stability) clojure = (speed, libraries, deployability, lisps - so worth learning to expand programming knowledge)
11:59ingsocthis is how i am viewing it
12:00anneliesElixir runs on the Erlang VM and borrows many ideas from Clojure.
12:00pdkit's got...
12:00pdka promising future
12:00anneliesSuch as macros and protocols.
12:00justin_smithingsoc: clojure is no slouch on concurrency eitehr, if you compare it to anything *but* erlang :)
12:00anneliesIf you are into that stuff.
12:03andyfambrosebs: core.typed is also the perfect tool to break Eastwood, and/or stretch it to its limits :)
12:03ambrosebsandyf: glad to be of service
12:03andyfI think I?ll declare it done when it gives correct warnings for core.typed :)
12:04ambrosebshehe
12:04andyfThat reminds me, there is a pretty darn big function generated via macro in one namespace I wanted to note to you. Let me find its name.
12:05justin_smithandyf: I've wondered, is eastwood named after the actor?
12:05andyfjustin_smith: Clojure LINT :)
12:05justin_smithomg it's worse than I imagined
12:05justin_smiththanks
12:06andyfJonas Enlund came up with the name, so I can't take credit. I wish I would have thought of it.
12:07Glenjaminthats genius
12:09andyfambrosebs: Also, I have to ask, what do you use to navigate your 150+ namespaces? :)
12:09ambrosebsandyf: is it that many?! vim's Command-T
12:10andyfCounting test namespaces, definitely. I don't recall if non-test namespaces exceed that on their own.
12:12ambrosebswell that's a great success. I had a few 8000 liners a few years ago.
12:14andyfambrosebs: Namespace clojure.core.typed.base-env-clj-rclass, the delay-and-cache-env call. It is only too large for Eastwood, not Clojure, I think because of extra tools.reader metadata and the way syntaxquote works. That means it is probably within a factor of 2 of being too large for Clojure, though.
12:15ambrosebsandyf: oh that's a stupid hack. I can fix that for you.
12:15ambrosebsandyf: it should really be reading those forms from a separate file, the code should be minimal.
12:16andyfNo need to fix it for me, but I certainly won't stop you if you wish ;)
12:16ambrosebssure
12:17andyfYou aren't the first to auto-generate huge Clojure functions, and you won't be the last. 64KB max method size seems strangely small for the JVM bytecode, but I understand there has to be a limit somewhere.
12:17anneliesAfter being here for a few hours I can say I like this chatroom.
12:18ambrosebsthe other delay-and-cache-env calls hit the method limit all the time.
12:22andyfcore.typed: 161 non-test namespaces, 143 test namespaces. 304 total. Not counting cljs
12:22ambrosebswow!
12:23justin_smithI have libraries with fewer lines than that
12:24Glenjamindoes that include all the clojure.core annotations?
12:24ambrosebsGlenjamin: that's just one file
12:26andyfGlenjamin: If you were asking me regarding core.typed namespaces, I don't know which ones contain those annotations.
12:26ambrosebshttps://github.com/clojure/core.typed/blob/master/module-check/src/main/clojure/clojure/core/typed/base_env.clj
12:26ambrosebsit's a big un
12:27Glenjamini love how a "big" clojure file is < 2k lines
12:27Glenjamini've had similar "this is getting a bit big" feelings, then looked to note the file is ~250 lines
12:27justin_smithGlenjamin: yeah, seriously
12:28justin_smithGlenjamin: I propose that the platonic ideal of a clojure namespace is a perfect square: longest line is 80 chars, 80 lines long.
12:29Glenjaminotoh, a huge flat namespace of non-interacting pure functions is probably still quite tidy
12:29justin_smithof course
12:29Glenjamindid you see the joe armstrong post about namespaces recently?
12:30ambrosebsif anyone needs a big ns form for some reason: https://github.com/clojure/core.typed/blob/master/module-check/src/main/clojure/clojure/core/typed/check.clj
12:30Glenjaminhttp://erlang.org/pipermail/erlang-questions/2011-May/058768.html
12:30Glenjaminread that this week - only just noticed it's > 3 years old
12:30justin_smithGlenjamin: the one where he digressed to talk about letrec, yeah
12:31justin_smithI think technomancy brought it up recently
12:31Glenjaminaha
12:32Glenjamini have occasionally thought to build to "lein util" plugin, that lets you build your util.clj namespace by pulling functions from a remote repo w/ metadata into one file
12:33andyfGlenjamin: To avoid the extra dependency for utils only?
12:34Glenjaminandyf: yeah, and flatten it a bit
12:34Glenjamincore.experimental, useful, medley etc could all just be functions in a util-function repository
12:35andyfI've got a pre-alpha 'dolly' lib that helps me copy code into Eastwood source and rename its namespaces, to avoid namespace version conflicts with projects being linted.
12:35Glenjaminsimilar sort of idea i guess, but for fns
12:35andyfI wouldn't recommend it for general use: https://github.com/jafingerhut/dolly
12:35Glenjaminthat sounds like it'd be very useful for lein itself too
12:36andyfGlenjamin: Are there often conflicts between Leiningen namespaces and namespaces of projects managed by Leiningen?
12:36Glenjamini've had issues between lein and speclj before
12:37Glenjaminonly affects plugins, not app code
12:37Glenjaminunless the app pulls in lein for some reason
12:41andyfYes, my guess was that something like dolly would be useful for some plugins, but not a lot else.
12:49m1dnightHmm, I get "can not embed object in code" when I try to build a macro
12:49m1dnightI want to grab a variable defined in the scope of macro expansion, is that not possible? (a macro to be specific)
12:50m1dnightI.e., create a variable in your macro function, and make the expanded code use it
12:50m1dnightI'll build a minimal testcase, to make things clear perhaps
12:50AeroNotixshow the code
12:51m1dnightokay, but it might be confusing :p
12:51m1dnighthold on
12:52AeroNotixbecause it sounds like you just want a gensym
12:52AeroNotixunless you're making an anaphoric macro, of which I am not going to help anyone make one of those.
12:52justin_smithAeroNotix: how principled of you
12:53AeroNotixjustin_smith: I find anaphoric macros incredibly annoying
12:53justin_smithAeroNotix: does #(= x %) count?
12:54AeroNotixjustin_smith: no
12:54AeroNotixjustin_smith: you provide the symbol, technically
12:55m1dnighthttps://www.refheap.com/92918
12:55justin_smithoh, so as-> would be anaphoric
12:55m1dnightwhat is an anaphoric macro? :p
12:55justin_smithhttp://en.wikipedia.org/wiki/Anaphoric_macro
12:56m1dnightI have a list of expressions, but I want to modify them, such that they instead of execute, put their parameters in an atom
12:56m1dnightafterwards, I'll execute another function that will do something with those parameters
12:56ingsocMacros scare me. Well, I mean maintaining code that someone had gone macro crazy with would be scary
12:56m1dnightin a different lexical scope
12:56hyPiRionm1dnight: imagine if-let worked like this: (if-let (get my-map :foo) (+ 2 it) 1) – where it is the result of the if-let expression
12:57AeroNotixingsoc: it's all about using them judiciously
12:57justin_smithingsoc: to be fair, things like ->, ->>, or, and, when, def, defn are indespensible - but making new macros definitely demands a compelling reason
12:57m1dnightI'm just trying to make a proof of concept here, not production code :p
12:58AeroNotixm1dnight: what are you actually trying to accomplish
12:58m1dnightwell, I have a list of expressions that I execute in a dosync block. One of those expressions can be "(! actor message [values])"
12:58m1dnightbut, in a dosync block we can retry, so I have to make sure to send those messages only once.
12:59arrdemfor those of you who hanve't tried it, I highly reccomend core.logic+pldb if you want to play with a smallish dataset
12:59justin_smithm1dnight: what about using a delay for that? a delay will only be realized once
12:59m1dnighteuhm
12:59m1dnightholy *beep beep beep*
12:59justin_smith,(def d (delay (do (println "realized") 1)))
12:59clojurebot#'sandbox/d
12:59justin_smith,@d
12:59clojurebotrealized\n1
13:00justin_smith,@d
13:00clojurebot1
13:00m1dnightthat could work as well
13:00m1dnightbut what I was trying to accomplish was
13:01m1dnighttransform any expression in the dosync of form (send actor message [vars]) to (swap! storage (fn [msgs] (cons {:msg message :actor actor :vars vars} msgs))
13:01m1dnightthis way, I can send the messages during commit phase
13:02m1dnightbut since that commit phase happens in a different lexical scope I have to figure out something such that I can write to an atom or something outside the scope of my actual dosync body
13:02m1dnightwhich I can then access in the scope present during committing
13:02m1dnighthence, I tried putting my code in a let as yo ucan see
13:03AeroNotixm1dnight: your juxt function doesn't seem right
13:03m1dnightoh, it is
13:03m1dnightoutput is right, is what i mean by that :p
13:03justin_smithAeroNotix: what's wrong with that juxt?
13:04AeroNotixjustin_smith: looks like they wanted to split the expressions into things which begin with #'! and those which don't
13:04justin_smith,((juxt filter remove) even? (range 10))
13:04clojurebot[(0 2 4 6 8) (1 3 5 7 9)]
13:04justin_smithand that's what it does
13:04m1dnightAeroNotix: yes so I can then transform those to the form I showed above
13:04AeroNotixRight yeah I expected that to remove them altogheter
13:05justin_smithm1dnight: I can't prove it, but this almost smells like a hand rolled monad
13:05m1dnighthahaha
13:06m1dnightspare me monads, please
13:06m1dnight:'(
13:06arrdemhahaha
13:06arrdemdon't fear the state monad :P
13:06m1dnightI don't fear it, if I can keep it at a safe distance in a cage
13:06m1dnight\o/
13:07justin_smithyour problem is that you are using ~ on delayed-msgs
13:07justin_smiththat doesn't really make sense
13:07m1dnightyeah, when i remove it I get what I want, but then it says it cant find the variable
13:07justin_smithremember that your macro should build the form to compile, not run the code you want run directly
13:07m1dnightno such var: meta-clojure.stm.actor-friendly/delayed-msgs
13:08justin_smithm1dnight: right, because it is not bound in that scope - I think you want to return a binding form that captures the atom
13:08m1dnightoh
13:08justin_smith`(let [delayed-msgs# (atom {})] ...)
13:09AeroNotix>>> because it sounds like you just want a gensym
13:09justin_smithAeroNotix: right, some of us were a bit slower connecting the dots
13:09AeroNotixNo, I just called it. I didn't look too hard at the code! :)
13:09AeroNotixjustin_smith: good job on figuring it out :)
13:10justin_smithbut the gensym isn't the crux of it, the need to capture the binding is - the gensym is just one tool in doing that
13:11madscientist`0
13:11madscientist`doh
13:11m1dnightyeah, I was too focused on capturing the atom and forgot about just putting it in the macro as well
13:11m1dnightthanks a bunch :) really
13:12justin_smithm1dnight: yeah a macro body can capture a literal form to be embedded, but cannot capture a value
13:12m1dnightmy head is de-hurting at the moment :D
13:12m1dnightI get it \o/
13:12justin_smithawesome
13:19m1dnightwhat does wrong number of args (-1) mean, actually?
13:19m1dnight0+ would be more logical, no? :p
13:25justin_smithyes, that is weird
13:25andyfm1dnight: There is a bug in Clojure for wrong arity errors for macros that subtracts 2 because macros have &form &env hidden args.
13:25justin_smithm1dnight: but macros get two invisible arguments
13:25andyfI've seen a CLJ ticket for it.
13:25andyfI think
13:25m1dnightoh that might explain :D
13:25justin_smithyeah, that is about it
13:26justin_smithclojure, the land of leaky abstractions
13:30andyfhttp://dev.clojure.org/jira/browse/CLJ-1279 Vote early, vote often.
13:34arrdemjustin_smith: eh could leak worse
13:34justin_smitharrdem: sure, but we do have a lot of them if you go looking
13:35arrdemI guess
13:38justin_smitharrdem: I never really got the impression that seamlessness in abstractions was even a goal with clojure. I mean we don't really make much effort to hide implementation details in general.
13:38justin_smithnot a dig or a complaint, just an observation of the design style
13:39bbloom_i think that if an abstraction is well designed, you don't have to bother hiding the implementation details: people simply won't go looking for them
13:40justin_smithbbloom_: right, so we let them leak, they are useful regardless
13:40bbloom_,(.tail []) ; whoops!
13:40clojurebot#<Object[] [Ljava.lang.Object;@189f393>
13:41AeroNotixYeah the JVM leaks through everywhere
13:41bbloom_,clojure.lang.PersistentVector/EMPTY_NODE
13:41clojurebot#<Node clojure.lang.PersistentVector$Node@537a5a>
13:41bbloom_,(.tail clojure.lang.PersistentVector/EMPTY_NODE)
13:41clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: tail for class clojure.lang.PersistentVector$Node>
13:42bbloom_,(.tail (clojure.lang.PersistentVector/EMPTY_NODE))
13:42clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: tail for class clojure.lang.PersistentVector$Node>
13:42bbloom_,(.array (clojure.lang.PersistentVector/EMPTY_NODE)) ; ah of course
13:42clojurebot#<Object[] [Ljava.lang.Object;@8ded54>
13:43bbloom_,(.shift [])
13:43clojurebot5
13:43bbloom_,(set! (.shift []) 0)
13:43clojurebot#<IllegalAccessException java.lang.IllegalAccessException: Can not set final int field clojure.lang.PersistentVector.shift to java.lang.Integer>
13:43bbloom_aw, final
13:44bbloom_oh well, still
13:44AeroNotixbbloom_: yes Clojure is on the JVM :)
13:44bbloom_AeroNotix: i was trying to break all vectors w/o reflection :-P
13:45bbloom_well, w/o nefarious reflection
13:46andyfbbloom_: You can break their immutability without much effort by aset'ing .tail
13:46bbloom_andyf: that i know / have done in this very channel before :-) i was trying to break ALL vectors
13:47andyfYou mean, one Java interop call that would cause every instance of a vector to behave incorrectly from that point forward?
13:47bbloom_yes
13:47justin_smithbbloom_: we played with a similar trick for breaking the number 5
13:47justin_smithit was amusing
13:47bbloom_justin_smith: do share
13:48justin_smithfinding it in my notes
13:48gfredericks(.tail [1 2 3])
13:48gfredericks,(.tail [1 2 3])
13:48clojurebot#<Object[] [Ljava.lang.Object;@1ba146b>
13:48justin_smith,(let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field 5 2))
13:48clojurebotnil
13:48justin_smith,(inc 5)
13:48clojurebot3
13:48andyfYou can break the JVM's 5, but Plato's 5 is safe in the world of forms
13:49justin_smithhaha
13:49gfredericks~5 is the set of all sets with 5 elements
13:49clojurebotIk begrijp
13:49bbloom_, (.getDeclaredFields Long) 3)
13:49clojurebot#<Field[] [Ljava.lang.reflect.Field;@5753b0>
13:49bbloom_,(.getName (.getDeclaredFields Long) 3))
13:49clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: getName for class [Ljava.lang.reflect.Field;>
13:49bbloom_,(.name (.getDeclaredFields Long) 3))
13:49clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: name for class [Ljava.lang.reflect.Field;>
13:49bbloom_,(clojure.reflect/reflect (.getDeclaredFields Long) 3))
13:49clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.reflect>
13:49bbloom_,(require 'clojure.reflect)
13:49clojurebotnil
13:49bbloom_eh wahtever... how do i get the name of a field?
13:50gfredericks.getName?
13:50bbloom_i tried that
13:50bbloom_oh dur it's an array
13:50gfrederickswith 3?
13:50bbloom_,(.name (nth (.getDeclaredFields Long) 3))
13:50clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: name for class java.lang.reflect.Field>
13:50bbloom_i suck
13:50bbloom_,(.getName (nth (.getDeclaredFields Long) 3))
13:50clojurebot"value"
13:51andyfThe world of forms: Bringing you real immutability since 348 BC
13:51bbloom_ah ok i gotcha. boxed small numbers are interned
13:51justin_smith, (nth (.getDeclaredFields Long) 3)
13:51clojurebot#<Field private final long java.lang.Long.value>
13:51justin_smith,(.getName (nth (.getDeclaredFields Long) 3))
13:51clojurebot"value"
13:51bbloom_andyf: https://en.wikipedia.org/wiki/348_BC <- i was hoping you knew the actual year
13:51justin_smithbbloom_: ^
13:52bbloom_justin_smith: i got there eventually :-P
13:52justin_smithbbloom_: aha, I missed it while I was finding it in my own repl
13:52andyfSorry, I don't know when he wrote about it first, so I approximated by the year Plato died.
13:53justin_smith,(= 5 3)
13:53clojurebotfalse
13:53justin_smith,(= 5 2)
13:53clojurebottrue
13:54justin_smith,(let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field 5 (inc 4)))
13:54clojurebotnil
13:54justin_smith,(= 5 2)
13:54clojurebottrue
13:54justin_smithI thought I fixed that...
13:54justin_smith,(let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field (inc 4) (inc 4)))
13:54clojurebotnil
13:54justin_smith,(= 5 2)
13:54clojurebottrue
13:54justin_smith,(inc 2)
13:54clojurebot3
13:54justin_smith,(inc 5)
13:54clojurebot3
13:54mearnshthis is why we can't have nice things
13:55AeroNotix,(inc (+ 3 2))
13:55clojurebot6
13:55justin_smith:( I forgot how to fix it
13:55AeroNotix,(inc 5)
13:55clojurebot3
13:55AeroNotix5
13:55AeroNotix,5
13:55clojurebot2
13:55justin_smith,(let [five (long (int (+ (int 1) (int 4)))), field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field five (int (+ (int 1) (int 4)))))
13:55clojurebotnil
13:55andyfOnce you make 5 equal to something else, the JVM extrapolates and is able to prove that all numbers are simultaneously equal to, and not equal to, all others.
13:55justin_smith,5
13:55clojurebot5
13:55justin_smithok, found the fix
13:55justin_smithandyf: if only
13:55andyfIt's downhill from there
13:56bbloom_this statement is false.
13:56andyfand simultaneously not downhill from there
13:56justin_smithI can't take credit for the trick, I just made a note of it to study, amalloy_ was who I saw do it
14:00AeroNotix,(inc [])
14:00clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>
14:08m1dnightWhat function do I have to map over a list of functions to execute all of them?
14:09justin_smith#(%)
14:09justin_smithequivalently (fn [f] (f))
14:09m1dnightriiight!
14:09m1dnightthanks justin_smith
14:09justin_smithnp
14:10justin_smithif you want to get way into semantic overload, (fn [fn] (fn)) actually works
14:10m1dnighthahaha
14:10arrdemhehe
14:10justin_smithbut that shadows fn which is weird so don't do that
14:11m1dnight:D
14:11andyfjustin_smith: Please, no. Zach Tellman's Manifold library defines a function called 'catch' that uses try/catch in its definition.
14:11justin_smith,(take 42 (map (fn [fn] (fn)) (repeat (constantly 42))))
14:11clojurebot(42 42 42 42 42 ...)
14:11justin_smithandyf: ouch
14:12andyfIt all works, where the catch occurrences inside try are try/catch, and the ones not inside try are the function, but yeah, weird.
14:13justin_smithyeah, that seems gratuitously clever
14:13gfredericks,((fn [fn] (fn fn fn fn fn fn fn)) list)
14:13clojurebot(#<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> ...)
14:13justin_smithhaha
14:13justin_smithgfredericks: it's now reminding me of "Being John Malkovich"
14:14justin_smithbut instead of crawling in to be Malkovich, you crawl into the weird little door and suddenly you are an anonymous function...
14:14justin_smithhttps://www.youtube.com/watch?v=Q6Fuxkinhug
14:14andyfself reference isn't what i used to be
14:15justin_smithclassic scene
14:15justin_smithnor is semantic satiation
14:52ghadishaybanabout to release this tiny library of clojure 1.7 "helpers" https://github.com/ghadishayban/reducers
14:52ghadishaybanmore reducible sources, reduce-based ops and a couple other novel things
14:53ghadishaybanwould love to get some eyes on it
14:54ghadishaybaninspired by some an musing from hiredman
14:55ghadishaybanthe implementation of select-keys with transducers becomes super nice (and fast):
14:56ghadishayban(defn select-keys
14:56ghadishayban [map keyseq]
14:56ghadishayban(into {} (keep #(find map %)) keyseq))
14:57justin_smith,(doc find)
14:57clojurebot"([map key]); Returns the map entry for key, or nil if key not present."
14:57justin_smithis that an optimization for get?
14:58ghadishaybanit returns the whole MapEntry. sister function to get
14:58justin_smithoh, interesting
14:59justin_smith,(find [:a] 0)
14:59clojurebot[0 :a]
14:59ghadishayban,(conj {} [:a :b])
14:59justin_smithassuming that's odd
14:59clojurebot{:a :b}
14:59gfredericksuseful for implementing plumbing.core/safe-get
14:59gfredericksor more generally, for doing both contains? and get in one lookup
15:01ghadishayban,(class (find {:a :b} :a))
15:01clojurebotclojure.lang.MapEntry
15:01justin_smith,(type (find [:a] 0))
15:01clojurebotclojure.lang.MapEntry
15:02gfrederickslifehack: to protect yourself against accidentally evaling a scratch file, put (don't load this) on the first line
15:02gfredericksI guess it works just as well without the parens
15:02gfrederickscould even be englishified as "Don't load this."
15:02justin_smithalternatively (why did you load this file? you shouldn't have tried)
15:03justin_smithgfredericks: the bonus with the parens I think is that you would get the whole thing, not just the first invalid symbol
15:03ghadishayban,filter-key
15:03clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: filter-key in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:03ghadishayban,*clojure-version*
15:03clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
15:03justin_smithgfredericks: err... I guess not
15:05ghadishayban(defn filter-key [keyfn pred coll] (into (empty coll) (filter (comp pred keyfn)) coll))
15:05ghadishayban,(defn filter-key [keyfn pred coll] (into (empty coll) (filter (comp pred keyfn)) coll))
15:05clojurebot#'sandbox/filter-key
15:06ghadishayban(filter-key val even? {:a 2 :b 1 :c 4 :d 5})
15:06ghadishayban,(filter-key val even? {:a 2 :b 1 :c 4 :d 5})
15:06clojurebot{:c 4, :a 2}
15:06ghadishayban,(filter-key key string? {:a 2 :b 1 "HI" 4 :d 5})
15:06clojurebot{"HI" 4}
15:06justin_smithoh, that's very nice
15:07ghadishaybantransducers are the shit
15:07ghadishaybanthat's all using transients
15:07justin_smithso I am seeing
15:08ghadishaybansimilarly,
15:09ghadishayban,(filter-key :a string? [{:a 3} {:a "foo"}])
15:09clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: filter-key in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:09ghadishaybanguess that var expired?
15:09justin_smithclojurebot protects us from ourselves with periodic automatic resets
15:09gfredericks~transducers |are| the shit
15:09clojurebotAck. Ack.
15:20ghadishaybanwhat do people normally call the find-first function:
15:20ghadishayban(first (filter pred coll))
15:21bbloom_ghadishayban: i usually just do (let [[x] (filter pred coll)] ...
15:21ghadishaybanslick
15:22ghadishaybani called it any...and i hate it
15:22ghadishaybanhttps://github.com/ghadishayban/reducers/blob/master/src/ghadi/reducers.clj#L66-L80
15:22bbloom_ghadishayban: i've seen it called "one" in ORMs ಠ_ಠ
15:23ghadishaybanlet's call it some!
15:23ghadishaybanjk
15:25SagiCZ1if i have a custom loop in which i am building a list (adding an element to it in each iteration) is there any way to make this lazy?
15:25justin_smithcinderella (like how the prince lines up all the women and takes the first one that can wear the shoe)
15:25ghadishaybannice
15:26justin_smithSagiCZ1: use a function that self calls within lazy-seq
15:26bbloom_SagiCZ1: just use a recursive call and lazy-seq
15:26bbloom_justin_smith: heh
15:26SagiCZ1(doc lazy-seq)
15:26clojurebot"([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. See also - realized?"
15:26SagiCZ1this one right?
15:26justin_smithright
15:26justin_smith@grim lazy-seq
15:26SagiCZ1k thanks
15:26justin_smith$grim lazy-seq
15:26justin_smithnot in yet, OK
15:27SagiCZ1what is grim?
15:27justin_smithit would have found this http://grimoire.arrdem.com/1.6.0/clojure.core/lazy-seq/
15:27ghadishaybanSagiCZ1: depending on what you're doing, look at iterate
15:27justin_smithhas some examples
15:27justin_smithoh yeah, iterate sometimes works - depends
15:28ghadishaybani added a reducible iterate that little reducers lib: https://github.com/ghadishayban/reducers/blob/master/src/ghadi/reducers.clj#L43-L50
15:28SagiCZ1and is it generally a good idea to make your functions return lazy seqs? i mean i just end up rewriting it to use lazy seq..
15:28justin_smithSagiCZ1: in some cases lazy-seqs are very handy
15:30ghadishaybanSagiCZ1: though i will say, almost in 100% of cases there a way using clojure seq functions (like iterate, map, mapcat, filter) without having to call lazy-seq manually
15:30ghadishaybani mean, to express a loop
15:30ghadishaybanif you can paste your loop to refheap...
15:31SagiCZ1ghadishayban: but loop is specifically for cases where you cant express it another way
15:32ghadishaybanunless you can't see that there is another way to express it :)
15:32SagiCZ1ghadishayban: which might be very possible.. i have no problem pasting it on refheap, maybe you can take a look if you want
15:32ghadishaybanusually if you're iterating simultaneously through two collections, then loop is your only option
15:33amalloyghadishayban: in many of those cases, map is fine
15:33amalloyi definitely wouldn't say "usually"
15:33SagiCZ1i guess i am doing all kinds of weird stuff https://www.refheap.com/92926
15:35justin_smithas-is, that could be a reduce on ticks
15:35justin_smithwhere events is the accumulator
15:36SagiCZ1justin_smith: is reduce lazy?
15:36justin_smithand uncompleted bars is also an accumulator
15:36justin_smithno
15:37SagiCZ1you are just saying i dont necessarily need loop
15:37justin_smithit could also be a (:events (last (take-while pred (iterate f [ticks bars]))))
15:37justin_smithor something like that
15:37justin_smithdefinitely don't need loop
15:38ghadishaybanjustin_smith: that's kinda hard to grok
15:38justin_smiththere may be a more straightforward way to use iterate there actually
15:38justin_smithghadishayban: yeah, it's a mess, sorry
15:39SagiCZ1i just need to make it lazy..
15:40justin_smithSagiCZ1: it would be fairly straightforward to make it lazy with reductions, where you would have completed-bars and uncomplete-bars for each step
15:41SagiCZ1i thought reduce is not lazy?
15:41SagiCZ1reductions not= reduce
15:42SagiCZ1(doc reductions)
15:42clojurebot"([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."
15:43SagiCZ1i need to learn this stuff.. i will probably head to 4clojure, before i tackle this big loop
15:45justin_smithSagiCZ1: something like this I think https://www.refheap.com/92929
15:46justin_smithno wait...
15:46SagiCZ1wow, thanks for taking the time to write that.. i will look into it
15:46justin_smithI just saw a mistake in that actually
15:48justin_smithSagiCZ1: updated, I am sure it is still imperfect https://www.refheap.com/92929
15:48justin_smithbut may be a good starting point
15:49justin_smithSagiCZ1: the big picture is that at each step it generates a two element vector of the events (completed bars) and the bars (the ones still being used) and you get a lazy-seq with one pair of these generated from each tick
15:49justin_smith(or that is what it does if it isn't still buggy)
15:50amalloySagiCZ1's loop looked a lot like a filter and/or a mapcat to me; i don't have time to write it up atm, but i don't see any steps depending on the results of previous steps
15:50justin_smithamalloy: it moves things between completed / uncompleted
15:50justin_smithwell, one way
15:50amalloyokay
15:51justin_smithit does an update of the previous "completed" bars at each step
15:51justin_smiththat's why I think it need accumulators
15:52justin_smithbut I have been known to use reduce / reductions when a filter or mapcat would do, so it's worth a second check on that
15:53justin_smithSagiCZ1: one trivial change I did is replace #(:complete %) with :complete in a couple places - in that context it was identical
15:54justin_smithbut I tried to keep each of the steps of the core logic the same as your version, so the adaptation is clear
15:55justin_smith*should be clear, barring more mistakes on my part
15:58SagiCZ1amalloy: in one iteration some bars get completed (and they get replaced by new bars) but others have to be past to the next step
15:58SagiCZ1justin_smith: thanks again, i will try it out once i get back to it
15:59justin_smithnp, I was just spinning my wheels before trying a big db migration on my scratch db, that I am procrastinating on because it will probably fail and I will need to reset the db again...
15:59justin_smith:)
16:11SagiCZ1:)
16:19justin_smithwell, I sure did call that one, time to wipe the test db again!
16:58donbonifacioI have a hash, with a lazy-seq somewhere, how can I find it
17:00justin_smithso it's a hash map with a lazy-seq inside it?
17:00justin_smithdo you have a handle to that hash-map?
17:01justin_smithor maybe the better question is - where did this hash map and lazy seq come from, and what do you expect to find in them?
17:03donbonifacioI have a hash that I'm passing to monger, and it's complaining clojure.lang.LazySeq cannot be cast to java.lang.String
17:04donbonifacioI do have a key that's an array, I'm gessing that it can't convert that to a string and maybe it's calling it a LazySeq
17:04justin_smithI doubt it
17:05justin_smithyou could use clojure.walk/postwalk
17:09justin_smith,(clojure.walk/postwalk (fn [el] (when (isa? (type el) clojure.lang.LazySeq) (println el)) el) {:a 0 :b 1 :c {:d (range 10)}})
17:09clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk>
17:10justin_smithmaybe something like that? but there is probably a more elegant way to do it
17:10justin_smith,(require 'clojure.walk)
17:10clojurebotnil
17:10justin_smith,(clojure.walk/postwalk (fn [el] (when (isa? (type el) clojure.lang.LazySeq) (println el)) el) {:a 0 :b 1 :c {:d (range 10)}})
17:10clojurebot(0 1 2 3 4 ...)\n{:a 0, :b 1, :c {:d (0 1 2 3 4 ...)}}
17:18justin_smith,(do (clojure.walk/postwalk (fn [el] (when (isa? (type el) clojure.lang.LazySeq) (println el)) el) {:a 0 :b 1 :c {:d (range 10)}}) nil) ; a little more clear maybe?
17:18clojurebot(0 1 2 3 4 ...)\n
17:27irctcWould anyone have any idea why my tiny Clojure server will not read from a Socket before the Python Client closes its own socket. -> gist https://gist.github.com/KristoKoert/3d1aa3ccd90a8bfcc341
17:30justin_smithirctc: how do you know the clojure code is not reading?
17:32justin_smithare you developing inside an editor by any chance? because your defns are in the wrong order
17:33irctcI had a load of printlns in between every step, The server executed till the comment i left. At the same time the python server continued sending its message until I exit the python script and once I exit it all the messages are recieved and the Clojure program continues as expected (will read every time), but will not hear the client if I try reconnecting.
17:34irctcIt might be that my python script is wrong as well..
17:34irctcInside emacs, I am just trying it out, so evaling :)
17:35justin_smithirctc: using cider?
17:35justin_smithlook for an *nrepl-connection* buffer - that should get your .println output
17:36irctcYes, cider.
17:36justin_smithyeah, the way emacs/cider/clojure handle stdout is way weird, some things from threads go in the wrong buffer due to dynamic binding and how that works when spawning threads
17:37irctcActually I DO get all the messages and I have the cider repl open and see them in there. But the problem is that the messages only come through AFTER I stop the Python script. For whatever reason..
17:37irctcAnd all of them at the same time.
17:39justin_smithoh, sorry, yeah
17:39justin_smithis that python code sending full lines?
17:40justin_smithbecause .readLine might be waiting for a newline
17:40justin_smithmaybe socket.send does not insert newlines?
17:40irctcOh? I will try that right now!
17:40justin_smithactually I would be surprised if it did
17:45irctcNice, it worked! Great, a really simple mistake... Thanks guys :)
17:49justin_smithnp
18:22justin_smithis there a paredit command that is like C-t but for list elements and not characters?
18:22justin_smithso if I have [a b |c d] and I run that command, it should become [a c b |d]
18:23Bronsajustin_smith: isn't that transpose-sexps?
18:24justin_smithBronsa: probably, I didn't find it on my paredit cheat-sheet
18:24Bronsajustin_smith: don't think it's a paredit function
18:25justin_smithBronsa: yeah, it kind-of works, but totally doesn't respect hash-map structure
18:25justin_smithbut better than nothing
18:25Bronsajustin_smith: yeah looks like it's in emacs and bound to C-M-t
18:25justin_smithyeah
18:27anneliesoh the joy of writing code in Java
18:49amalloyjustin_smith: doesn't respect hash-map structure how?
18:49justin_smithit transposes keys and values separately, not as a pair
18:49justin_smithnot that it would be reasonable to expect that I guess
18:50justin_smithmaybe I will write a nice dwim that moves key value pairs forward and back in hashmap literals
18:50justin_smithand otherwise acts just like transpose-sexps
19:38anneliesI am going to sleep ladies and gentlemen.
19:38Bronsabye
19:38anneliesgoodbye
19:41anneliesThere is get and get-in, assoc and assoc-in, and update-in, but why not update?
19:41andyfannelies: There will be in Clojure 1.7
19:41Bronsaannelies: update has been added in 1.7
19:41anneliesNice. :)
19:42andyfyou ask interesting questions while you sleep :)
19:43anneliesI also really wish numerator and denominator worked on integers. :c There's a bug report of it already though.
19:43andyfhave you voted for it?
19:43anneliesYeah
19:44andyfThen except for encouraging others to vote on it and writing a patch that works, you've done all you can :)
19:45Bronsain my experience, a ticket with no patch will hardly get considered unless it's a serious bug
19:49andyfBronsa: I think it matters more whether Rich or a screener like Alex think the description is something they agree is a problem, not whether there is currently a patch.
19:50andyfA screener triaging a ticket, or Rich vetting one, seem to me to have little to do with the presence/absence of a patch, but I'm guessing based on watching, not knowing.
19:50Bronsaandyf: I would like to agree with you but I'm pretty sure there is a *large* number of valid tickets that have never been seen by Rich or by any screener
19:51andyfAlex Miller has seen every one multiple times, I'm sure.
19:52andyfSummer 2013 he checked and/or updated the state of every single open ticket, and he's vetted about 1/5 of the open ones.
19:52andyfsorry, triaged, not vetted
19:52justin_smithandyf: is 0.1.5 the latest eastwood available from maven?
19:52andyfjustin_smith: yes
19:52justin_smithcool, thanks
19:52justin_smithso this does not have the from-repl stuff you talked about recently, right?
19:52andyfYou can check on clojars.org for any project hosted there what all version are that have been released, fyi, but I don't mind answering.
19:53justin_smithOK
19:53andyfIt can be run from the REPL, and you don't need Leiningen.
19:53justin_smithoh, cool
19:53andyfInstructions here: https://github.com/jonase/eastwood#running-eastwood-in-a-repl
19:53andyfWith I hope appropriate and not-too-scary warnings
19:54justin_smithandyf: I had assumed, given the big version difference between github and clojars, that the newer feature was not available or maybe I just wasn't finding it
19:54andyfDon't do it in a live production JVM is the most important warning.
19:54justin_smithright, I wouldn't need that anyway, thanks
19:54andyfOh, you mean the 0.2.0-SNAPSHOT on github?
19:54justin_smithright
19:55justin_smiththat's what confused me
19:55andyfThat is not binding, but I am hoping it encourages me to add the feature for source code annotations to disable linters on a per-file and/or per-expression basis, which I consider worth bumping the version to 0.2.0 when released.
19:56annelieswell, time to really sleep
19:56anneliesgoodbye! <3
19:56andyfI'm doing development on master. You have to checkout a version-specific tag if you want to see source code for a specific release (or unzip the jar)
19:57Bronsaandyf: eh well, updating the status of a ticket doesn't mean it has been considered, it's just maintainance from my POV. there are a lots of "dead" tickets (i.e. that see no activity whatsoever) in jira
19:58andyfI'm gradually becoming accustomed to taking the long view, e.g. 5 years out :)
19:58justin_smithandyf: thanks. This message is confusing (caused by a misnamed file that I forgot to delete) - is it worth filing a ticket for? https://www.refheap.com/92941
19:58Bronsaandyf: I'm not criticizing Alex's work btw, the process is just really frustrating sometimes
19:59andyfUnderstood. Paraphrasing Sir Lawrence of Arabie from the movie, the trick is not minding that it takes the time it does :)
19:59andyfArabia, even.
20:00Bronsaandyf: it's counterproductive though. Say I open a ticket and attach a patch and that ticket doesn't get considered until 2 years later when the patch doesn't apply anymore
20:00Bronsain the meantime I've lost interest in clojure and/or don't use it anymore for my work and I'm not going to update the patch, and the ticket becomes stale
20:00andyfBronsa: That is the same situation we would be in even if all of the other 400 open tickets were considered before that ticket's patch -- most likely it wouldn't apply cleanly any more
20:01justin_smithandyf: update with suggested replacement message https://www.refheap.com/92941
20:02andyfjustin_smith: Sure, open a ticket for that. The message you see now is correct, but I agree a bit verbose for the common special case you have.
20:02Bronsaandyf: I'm not sure it would be this bad. consider patch 1 that affects file a and patch 2 that affects the same file is written 3 months later
20:03Bronsaandyf: if patch 1 has been merged within the 3 months period, patch 2 will be writte on top of patch 1 and will apply cleanly
20:03justin_smithandyf: the "has namespace" / "should have namespace" are identical, which I thought may have been a bug. I'll file it as a suggestion.
20:03Bronsaandyf: if patch 1 has not been merged, patch 1&2 will conflict and once one gets merged the other will not apply anymore
20:04andyfjustin_smith: I'd call it a confusing message, to be sure, and worth a special case in the code that prints the messages.
20:04andyfjustin_smith: that sentence fragment combined with the "or should be in file" are technically correct, where it is really the second part after the or that is true in this instance. I'm all for clearer warning messages.
20:05justin_smithcool, thanks
20:06andyfBronsa: We are not alone in wishing the process went faster sometimes. To me, the heart of the issue is: our wishes do not trump someone else's free will in choosing what they do with their time.
20:08andyfAnother way of looking at it is this: ~8 years after first working on the project, the creator still spends a chunk of his free time every month enhancing it. i.e. it is not abandoned.
20:10andyfAnd, he adds things to it like transducers, rather than restricting himself to considering problem reports that have been created by others.
20:11Bronsaandyf: I envy your ability to feel this way knowing the amount of time you spend around JIRA and noticing the (mostly) lack of activity around it by any core member other than Alex
20:12andyfBronsa: I would not have spoken like this 2 years ago. It is an acquired attitude :)
20:13Bronsaandyf: I don't see your last point as a positive thing. To me that shows exactly how little issues reported by community members are valued
20:13andyfIn the mean time, I think you are having a big impact on projects like core.typed, core.async, Eastwood, and whatever else tools.analyzer.* are getting use in.
20:15andyfBronsa: I don't know exactly how much time is spent by who on what, but I get the distinct impression that if all they did was focus on tickets from community members, they wouldn't have time/energy left for adding cool new stuff.
20:16andyfBronsa: Out of curiosity, do you know of any other projects besides the ones I mentioned using tools.analyzer?
20:17Bronsaandyf: crossclj uses t.a AFAIK
20:17andyfOh, yeah. That site is amazing.
20:19andyfFrancesco even found and fixed an issue I reported recently, where many of the "this var is used in places x, y, z, ..." had a bug in it.
20:19Bronsait is indeed. my only complaint is that the UI feels a bit too "heavy" sometimes
20:22Bronsaandyf: ah, nrepl-refactor or however it's called uses t.a too. not sure if in a released version or a still in dev
20:25andyfI bet the list will grow as more people think of uses for it. Hats off to you, my friend.
20:26justin_smith(inc andyf)
20:26lazybot⇒ 5
20:26justin_smitheastwood is awesome, thanks
20:26justin_smithI just regret I didn't start using it sooner
20:27Bronsa(inc andyf)
20:27lazybot⇒ 6
20:28andyfGot to go for a while. Talk to you folks later.
20:28Bronsahave some internet points. I'll need yo buy you a beer if we ever get the chance to meet, for having my back when I break things
20:30andrewhrBronsa: maybe a stupid question, but there is any work around a t.e.js? found only the t.e.jvm
20:31Bronsaandrewhr: no and I honestly have no interested in forking the cljs compiler to adapt its emitter to compiler t.e.js's AST rather than cljs.analyzer's one
20:32andrewhr*you* don’t have any interest or the *community* don’t see any value with that?
20:33nonubydestructing question, i dont what the difference is between defn x [handlers] and defn x [[& handlers]]
20:33andrewhrbtw, I’m just asking to you bc your work with t.e.jvm
20:34andrewhrnot want to mean anything bad, please
20:35Bronsaandrewhr: *I* don't have interest nor time, and I guess neither does the community. There's not much value in another cljs compiler, t.a.js otoh is valuable because it is (in my biased opinion) a lot more powerful than cljs.analyzer
20:35amalloynonuby: the second version is just silly
20:36amalloyyou are correct in implying that there is no difference
20:36Bronsaamalloy: there is though, the first will accept "1", the second won't
20:36amalloywell, yes
20:36Bronsait's a silly way to assert (coll? arg)
20:36amalloyand the second will convert [] to nil
20:36Bronsawut?
20:36nonubyso its like some form of weak typing checking... ah you said first
20:36amalloywon't it?
20:37Bronsano idea
20:37amalloy,((fn [[& xs]] xs) [])
20:37clojurebotnil
20:37amalloyBronsa: because & destructuring never returns an empty seq, only nil or non-empty
20:37BronsaTIL
20:37nonubyamalloy, cool. thanks just something i noticed on compojure.core/routes
20:38andrewhrBronsa: thanks. just want to know how the clj(s) community feels about that
20:38Bronsaamalloy: do you happen to know if that was a conscious decision or an accident of the impl?
20:38amalloyBronsa: i believe it's a legacy of the time when there was no such thing as a non-empty seq
20:39Bronsaand/or if there's an obvious reason why it doesn't return () that I'm missing
20:39amalloyit's a decision that i really wish we could undo
20:39amalloyer, no such thing as an empty seq
20:40Bronsaandrewhr: well I'm not the right person to ask such a thing then :) I'm not really part of the cljs sub-community
20:41amalloythe problem is that it means you should never use & xs destructuring in a lazy function. consider this reasonable implementation of map: (fn map [f xs] (lazy-seq (when-let [[x & xs] (seq xs)] (cons (f x) (map f xs)))))
20:41amalloyit looks correct, but because xs will never be nil, you end up forcing one more element of the input collection than the user asks for
20:41andrewhrBronsa: still think it’s a valulable opinion :)
20:43andrewhranother shot for you: t.a is capable of doing some kind of incremental analysis? let’s say - to use it for making some kind of code highlight for example
20:43Bronsaamalloy: makes sense, thanks
20:47Bronsaandrewhr: t.a assumes fully evaluated env but there are ways to analyzing code w/o evaluating it, even though that requires a bit of configuration & the analysis might be inaccurate
20:47Bronsaandrewhr: not sure if that's what you were asking me though
20:49andrewhrBronsa: so you will only be able to really analyze code in a “live runtime”, if I get it right
20:49andrewhr(in a precise way)
20:49Bronsaandrewhr: in t.a.jvm yes. for cljs it's a bit different because it has no resident compiler & reified namespaces
20:50andrewhrgot it
20:50andrewhrthanks again!
20:51Bronsaandrewhr: silly example, "(defmacro foo [] (list 'def 'bar 1)) (foo) bar", the analyzer has no way to know that "bar" refers to a var if you don't evaluate the defmacro expr and it's invocation before analyzing the symbol "bar"
20:53Bronsaandrewhr: I mean, there are certainly techniques it could use to figure it out in this case, but that's out-of-scope for t.a
21:01andrewhrBronsa: I see. requiring a live environment will not be a true problem for what I have in mind
21:08puredangerBronsa (and andyf ) : just browsing the back chat. just fyi, the ticket situation is frustrating for me too.
21:08dc_whats the best way to combine two lists in clojure like this: [1 2 3] [4 5 6] => [[1 4][2 5][3 6]]
21:08dc_like is there a function that does that?
21:08godd2interleave?
21:08hyPiRion,(apply map list [[1 2 3] [4 5 6]])
21:09clojurebot((1 4) (2 5) (3 6))
21:09dc_ahh ok yep, that's what i'm looking for
21:09hyPiRionIf you want vectors
21:09hyPiRion,(apply mapv vector [[1 2 3] [4 5 6]])
21:09clojurebot[[1 4] [2 5] [3 6]]
21:09dc_godd2 hipirion: thanks
21:09hyPiRionnp
21:10Bronsapuredanger: yeah I don't find it hard to believe that. I'm sorry if you've been named in my small rant but I assure you I that I (and I hope to talk for most of the community) really apprecciate your work
21:10puredangerI do what I can
21:11godd2,(map vector [1 2 3] [4 5 6])
21:11clojurebot([1 4] [2 5] [3 6])
21:11godd2oh I see that doesn't return a vector
21:12godd2,(mapv vector [1 2 3] [4 5 6])
21:12clojurebot[[1 4] [2 5] [3 6]]
21:25smnirvenokay folks, let's say I have a sequence of maps, and I want to call a certain function once for every map in the sequence, but for use in the -> macro
21:27smnirvenany ideas on how i might accomplish that?
21:28Bronsasmnirven: you want to map inside a -> expression?
21:28smnirvenyeah something like that
21:29Bronsayou can do (-> coll ... (as-> coll (map f coll)) ..)
21:29TEttinger(doc as->)
21:29Bronsasmnirven: assuming you can't use ->>
21:29clojurebot"([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."
21:30justin_smith,(-> [{:a 0 :b 1} {:a 1 :b 2}] (#(map :a %))) ; another option
21:30clojurebot(0 1)
21:31TEttinger,(-> [{:a 0 :b 1} {:a 1 :b 2}] ((partial map :a))) ; yet another option
21:31clojurebot(0 1)
21:32smnirvenahh, partial might be the ticket here
21:32Bronsajustin_smith: I find that really ugly
21:33justin_smith,(-> [{:a 0 :b 1} {:a 1 :b 2}] (->> (map :a))) ; yet another
21:33clojurebot(0 1)
21:33Bronsawhenever I find myself wanting to (-> .. (#(..))) I just lift the lambda in a let over the -> expr
21:33TEttingerthat last one looks like a winner, justin_smith
21:34justin_smithTEttinger: and of course it can bump up a level again if you need -> again
21:34Bronsaand I also tend to avoid nesting ->/->>/doto as that gets unreadable pretty fast :P
21:34smnirvenlet's say the collection coll [{:a 1} {:a 2}]
21:35smnirvenI want to insert the same function in an existing thread macro once for each map in that collection
21:35smnirven(-> orig (f1) (f2 {:a 1}) (f2 {:a 2})
21:36smnirventrying to figure out how to do that with any number of maps in that collection
21:36justin_smithsmnirven: that does not work in general unless you know the maps (or at least how many there are) when the macro is expanded
21:36TEttingerthat sounds like a different use case
21:37Bronsasmnirven: are you sure you want (f2 (f2 (f1 orig) {:a 1}) {:a 2})?
21:38smnirvenBronsa: yep
21:40Bronsathat's (reduce f2 (f1 orig) [{:a 1} {:a 2}]), I wouldn't really insert it in a -> expr
21:40smnirventhere's a pretty good chance im attacking this in the wrong way entirely -- basically im trying to compose a sqlkorma select with the possibility of multiple joins
21:55arrrmsWhat are people's opinions on the Web Development with Clojure book? There are only two Amazon reviews (http://www.amazon.com/Web-Development-Clojure-Build-Bulletproof/dp/1937785645/ref=sr_1_1?ie=UTF8&amp;qid=1415500923&amp;sr=8-1&amp;keywords=clojure+web+development)
22:19godd2Is there a way to have lein repl print out transients in a prettier way?
22:20gfredericksgodd2: check out print-method
22:20gfredericks,(transient [1 2 3])
22:20clojurebot#<TransientVector clojure.lang.PersistentVector$TransientVector@13c422e>
22:21gfredericks,(defmethod print-method clojure.lang.TransientVector [tv pw] (print-method (into [] (map #(get tv %) (range (count tv)))) pw))
22:21clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.lang.TransientVector, compiling:(NO_SOURCE_PATH:0:0)>
22:21gfredericks,(defmethod print-method clojure.lang.PersistentVector$TransientVector [tv pw] (print-method (into [] (map #(get tv %) (range (count tv)))) pw))
22:21clojurebot#<MultiFn clojure.lang.MultiFn@18eaab5>
22:21gfredericks,(transient [1 2 3])
22:21clojurebot[1 2 3]
22:21godd2oh wow
22:21gfredericksor if you want it to be less ambiguous
22:21godd2did you just change clojurebot for good? (or at least for a while)
22:22gfredericks,(defmethod print-method clojure.lang.PersistentVector$TransientVector [tv pw] (.write pw "#transient ") (print-method (into [] (map #(get tv %) (range (count tv)))) pw))
22:22clojurebot#<MultiFn clojure.lang.MultiFn@18eaab5>
22:22gfredericks,(transient [1 2 3])
22:22clojurebot#transient [1 2 3]
22:22godd2I like that even more
22:22gfredericksgodd2: I think it'll reboot after 10 minutes or something
22:23godd2Where should I put code for lein repl to run as it's booting up?
22:23godd2in a dependency?
22:24justin_smithgodd2: clojure will load user.clj
22:24justin_smithsrc/user.clj for example
22:24justin_smithmore detail here http://dev.solita.fi/2014/03/18/pimp-my-repl.html
22:25godd2yay!
22:25minaminaminaHey there! I was trying to write a cljs library that I could deploy to clojars, and require in another project. The library is written, it's simple, and it works, but when I try to require it somewhere else, the only visible namespace is my-namespace.core
22:25minaminaminaWould anyone mind looking at the project.clj file to see what I'm doing wrong?
22:25smnirven_link plz
22:26minaminaminahttps://github.com/minasmart/squelch/blob/master/project.clj
22:27minaminaminaincluding it in the dependencies section of another project doesn't produce errors, but trying to require anything other than squelch.core makes it complain: WARNING: No such namespace: squelch.audio-context at line 1...
22:27justin_smithminaminamina: you have - in your file names
22:28smnirven_yep thats it
22:28justin_smithclojure cannot find files named that way
22:28smnirven_underscores to the rescue
22:28minaminaminaOK, I was wondering about that. Should they be underscored?
22:28justin_smithrename audio-context.clj to audio_context.clj
22:28minaminaminaThen should namespaces be named with hyphens or underscores?
22:28justin_smithyeah, the namespace can keep the same name, just rename all the files
22:28smnirven_filenames should be underscored, but the namespace names can still be hypens
22:28justin_smithso ns is audio-context, file is audio_context
22:29minaminaminaFor namespace naming, what is more typical? Hyphen or underscore?
22:29justin_smithminaminamina: there is a nice tool called eastwood (a lein plugin) that detects these kinds of issues
22:29justin_smithhyphen is preferred for namespaces
22:29justin_smithbut it has to be underscore in the file
22:29minaminaminaOK, cool! And thanks Justin! I'll check out that plugin!
22:29minaminaminaThanks alot!
22:30justin_smithnp
22:49grandyi'm new to clojure and a bit confused about how to use sessions in compojure, anyone know of a public repo that does this?
22:50godd2how do you get the keys from a transient hashmap?
22:50godd2,(keys (transient {:a 1 :b 7}))
22:50clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.PersistentArrayMap$TransientArrayMap>
22:52justin_smithgrandy: https://www.refheap.com/92948 you can use this definition as a middleware foar a cookie session
22:53grandyjustin_smith: thanks!
22:53justin_smiththat uses ring.middlware.session/wrap-session
22:53justin_smiththere are other options for in-memory rather than server sessions
22:53grandyjustin_smith: dumb question but how do I set the session to {:hello "world"}
22:53justin_smithof course you probably want to fix the key, cookie-name, max-age
22:54vermahow do I run the jar chestnut gives me? just doing a java -jar app.jar doesn;t seem to work,
22:54justin_smithgrandy: in your handler create a response map, with {:body "text of page" :status 200 :session {:hello "world}}
22:54vermait just drops me into a clojure repl
22:54grandyjustin -- I tried that but then I removed it and refreshed the page and it was gone from the session data,
22:55justin_smithverma: you can specify a class / method to run, if you have a -main defined and aot compile that namespace
22:56justin_smithgrandy: with the middleware set up properly, you should see the same data come in under :request
22:56grandyhmm
22:56justin_smithgrandy: you need to watch out for accidentally attaching a null :session in between of course
22:56vermajustin_smith, :uberjar profile says :aot :all, so I guess it'd be aot compiled, I am also not sure what the command line would look like
22:57justin_smithverma: if your main ns is set up properly (such that lein run works) the compiled jar will work too
22:57grandyjustin_smith: this is my handler, do you see anything obviously wrong with it? quite possible there is something very dumb going on: https://gist.github.com/mmmurf/0cfe722ad60c47c34b1f
22:57vermajustin_smith, oh let me try lein run
22:57justin_smithyou aren't returning the right thing
22:58justin_smithgrandy: you are passing the session as the response map
22:58justin_smithyou want to pass the session INSIDE the response map
22:58vermajustin_smith, does the class with -main needs to have :gen-class, I was just wondering since chestnut didn't do that
22:58grandyjustin_smith: hmm I think I have to review the signatures that are going on there... I'll try w/ a simple text response
22:58justin_smithgrandy {:body [:body ...] :session (assoc (:session params) :count 1)}
22:59justin_smithgrandy: you need to put what you were previously returning into the :body key
22:59justin_smithright now, [:body ...] inside common is doing nothing, it's just a data literal that is not used or returned by the function
22:59grandyjustin_smith: ahh so {:body is not a hiccup function it's a map for ring?
23:00amalloygrandy: yes
23:00justin_smithgrandy: yes, ring accepts multiple return values
23:00amalloyjustin_smith: how do you mean?
23:00justin_smithif you specify a string, that becomes the page body, if you return a map, the :body key is used for that
23:00justin_smithamalloy: just that it is polymorphic on what you return to it
23:00grandyjustin_smith: ahh ok, so does this mean that in my compojure code all handlers that update hte session need to return a map?
23:01justin_smithright
23:01justin_smithamalloy: I should have said "accepts multiple return types"
23:01grandyjustin_smith: ahh ok i see, now it is starting to make sense
23:02justin_smithgrandy: and I was wrong above, you want {:body (common [:body ...]) :session ...} in the response map
23:02justin_smithor bind the rendered result of common in a let, of course
23:02grandyjustin_smith: ok cool I think I've done that...
23:03grandyjustin_smith: https://gist.github.com/anonymous/586bf33aea6347999969
23:03justin_smithverma: you can specify an arg that says run clojure.core and then another arg that tells clojure.core to run a specific function in a specific ns - one moment, I need to find it
23:04justin_smithgrandy: yeah, that looks about right
23:04vermajustin_smith, nice! I actually tried to run lein run and it had problems, so I fixed those and running a lein uberjar right now
23:04verma51seconds to compile clojurescript :(
23:05grandyjustin_smith: oddly it's not persisting
23:06justin_smithgrandy: so :count 1 is not coming in on the next load?
23:06grandyjustin_smith: correct, not if I comment out line 8 above
23:07justin_smithgrandy: and you have the ring-session middleware in place?
23:07grandyjustin_smith: in other words, the line that prints the session (line 5 above) prints {}
23:07grandyjustin_smith: [ring.middleware.session :refer :all]
23:07justin_smiththat requires the session, are you putting it in your middleware?
23:07grandyhttps://www.irccloud.com/pastebin/INl3FSu0
23:08grandyI think so, see the paste
23:08justin_smithOK, you might want add some arguments to wrap-session
23:08justin_smithalso check in your browser if the cookie is being created
23:08grandyjustin_smith: ahh good idea
23:09justin_smithmaybe create an unencrypted cookie while debugging
23:09justin_smithverma: java -cp foo.jar clojure.main -m foo
23:09justin_smithwhere foo/-main is the main function
23:10justin_smithverma: you may not need that, but the advantage there is you don't need any aot for that to work
23:10justin_smithclojure finds and loads your code
23:11zerkmsguys, could you please give me some hints about how idiomatically implement a file reader that would read all the lines that are added in runtime (which is more or less obvious) with ability to gracefully stop it
23:14justin_smithzerkms: basic idea is to create a file reader using clojure.java.io (io/reader (io/file "name")) and then you have a few options, probably easiest is to put it in a future, (def reader-thread (future (while (not (.isInterrupted (Thread/currentThread))) (.readLine reader))))
23:14justin_smiththen you can call (future-cancel reader-thread) if you want it to stop
23:14justin_smithand probably you want to do something with the return value of .readLine of course :)
23:15zerkmsI've head similar thoughts
23:15zerkmsbut
23:15zerkms.readLine is blocking
23:15justin_smithyeah, put it in a future
23:15zerkmswhat? (.readlLine reader)?
23:15justin_smithzerkms: the whole loop, like I did above
23:15grandyjustin_smith: hmm do you see anything wrong w/ this?
23:15grandyhttps://www.irccloud.com/pastebin/rqHj35ln
23:16justin_smithor, use polling and non-blocking read
23:16justin_smithpolling is guaranteed more complex though, of course
23:17justin_smithgrandy: that isn't a valid key I don't think - the number of X in my example was exactly the number of characters that need to be in the key
23:17zerkmsI see, so in your solution you don't immediately terminate .readLine() but just don't care if it's still there in memory awaiting for next line
23:17grandyjustin_smith: ahh ok
23:18justin_smithzerkms: well, it checks if the thread is interrupted (future-cancel will do the thread-interruption for you)
23:18zerkmsjustin_smith: for the check to occurr a next line should arrive
23:19justin_smithright, polling is more complicated, but also possible
23:19zerkmsok
23:19justin_smithzerkms: like adding an if based on whether data is available, and a sleep if it isn't
23:19justin_smiththen you are guaranteed to check the condition more often
23:20zerkmsI'm not caviling (not sure if it's a correct word here, cannot find better in my dictionary) - just pretty newbie with clojure so want to make sure I'm not missing something basic
23:20vermajustin_smith, nice! that seems to work great! thanks for your help
23:20verma(inc justin_smith)
23:20lazybot⇒ 120
23:20justin_smithzerkms: and you just need to look out for the pathological condition where there is data, but it freezes in the middle of giving you a line
23:20justin_smithverma: which one, the fixing lein run, or specifying the main class?
23:21zerkmshonestly I tried implementing polling then realized the code looks like java
23:21justin_smithheh
23:21justin_smiththere isn't much purely functional about a polling loop
23:22zerkmstried to reimplement simplified http://commons.apache.org/proper/commons-io/apidocs/src-html/org/apache/commons/io/input/Tailer.html which is I find nice implementation for this task (in java though)
23:22vermajustin_smith, oh actually chestnut comes with a Procfile which had the exact same command :P
23:22justin_smithzerkms: there is java.nio.* too, I don't have a whole lot of experience with it though
23:23justin_smithverma: haha, nice
23:23justin_smithverma: so I could have just said rtfpf
23:23vermajustin_smith, totally :P
23:24zerkms" java.nio.* too" --- yep, I deliberately want to do that as much manually as possible, as a person who only read A LOT and watched A LOT of different things about clojure but have written < 100 lines in total in clojure
23:24justin_smithgrandy: small thing about your last paste, the comment about (:session session) isn't quite accurate, for what it's worth - you probably meant (:session params), but that's just a nitpick
23:25justin_smithzerkms: interop isn't super hard, and this is the sort of thing clojure just doesn't have a simple clojure-wrapped solution for
23:25justin_smithsorry
23:25grandyjustin_smith: please do nitpick, this is my first clojure project so I need to be informed of any/all stupidity :)
23:25zerkms(inc justin_smith)
23:25lazybot⇒ 121
23:25grandyjustin_smith: ok so now it works nearly as expected, with the following three handlers:
23:26zerkmswould it ban me if I inc myself? :-D
23:26grandyhttps://www.irccloud.com/pastebin/X5Wu3LCN
23:26justin_smithit'll just be sassy about it
23:26grandyjustin_smith: those map to /session /session1 and /session2
23:26justin_smithgrandy: cool
23:27justin_smithgrandy: what's handy for this kind of thing is update-in / assoc-in
23:27grandyjustin_smith: hmm how woudl I modify those?
23:27justin_smith,(update-in {:session {:count 0}} [:session :count] inc)
23:27clojurebot{:session {:count 1}}
23:27justin_smith,(update-in {:session {:count 0}} [:session :count-2] (fnil inc 0))
23:27clojurebot{:session {:count-2 1, :count 0}}
23:28justin_smithgrandy: update-in is pretty much perfectly designed for this kind of case (I intentionally burried :session deeper than needed to show how it digs in)
23:29justin_smith&*clojure-version*
23:29lazybot⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}
23:30vermaTIL fnil
23:30justin_smithfnil is my friend
23:30justin_smith(inc fnil)
23:30lazybot⇒ 3
23:31grandyjustin_smith: thanks!
23:31justin_smithgrandy: np, glad you figured it out
23:36zerkmsjustin_smith: cannot get it working :-( (while ...) blocks while not finished which is never
23:37justin_smithzerkms: did you put it in a future?
23:37zerkmsyep, and whern I'm dereferencing it - it blocks
23:37zerkmssince `while` works forever
23:37justin_smithyeah, deref is not what you want
23:38justin_smithunless you want it to be done, and get the return value
23:38justin_smithfutures run whether you deref them or not
23:38zerkmsyep, but how to get the value from it then
23:38zerkmsa global atom would be ugly
23:38justin_smithzerkms: you could send the values to an agent or queue
23:39justin_smithor act on the data within the loop itself
23:39zerkmsor that... doesn't look idiomatic hmm
23:39zerkmsI thought it will be trivial to implement an infinite list
23:39zerkmss/list/sequence/
23:39RaynesWell that's not great.
23:41justin_smithzerkms: hmm (defn f [handle] (when more-data (cons (read-available handle) (lazy-seq (f handle)))))
23:41justin_smiththat's kind of like line-seq
23:41justin_smithmaybe that's all you need? but line-seq will block too won't it?
23:41zerkmshandle is the last resort for me, but yes
23:53grandyjustin_smith: oddly it appears that it's not using the cookie params I am setting, it is also not using the name, therefore I think it is ignoring the configuration info for cookie sessions -- thoughts?
23:53grandyhttps://www.irccloud.com/pastebin/thNcygv4
23:56justin_smiththat looks right