#clojure logs

2014-05-24

00:27yediis there a way to have an atom just be a transformative window of another atom? like i want an atom that will always be the keys of the map in a different atom
00:28yedii know you could probably add a watch? and listen for changes to the map atom and update the keys atom accordingly
00:28yedibut is there like a simpler way of doing it
01:05trap_exitambrosebs: !
01:05trap_exitcan I send you a pm?
01:05trap_exits/can/may/
01:05ambrosebstrap_exit: you're t x?
01:05ambrosebstrap_exit: come to #typed-clojure
01:25FrozenlockOh look, they invented blogging http://www.twitlonger.com/
01:25FrozenlockWhat would the world be without Twitter?
01:26jweaverTwitter is like the worlds largest IRC channel... and I'm not really sure how you make money off of that, which might explain TWTR decline.
01:29FrozenlockEyeballs! It's like money, but better!
01:37amatsuIs there any way to make 'conj' always return a set, even when the first argument is nil?
01:41amatsu,((comp set conj) nil 1)
01:41clojurebot#{1}
01:41amatsuthat works
01:41amatsuI hope 'set' is instant if the argument is already a set..
01:45dbaschamatsu: unfortunately it isn't https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L3778
01:46amatsuyikes
01:46amatsuis there a transient set?
01:47dbasch,(transient #{})
01:47clojurebot#<TransientHashSet clojure.lang.PersistentHashSet$TransientHashSet@8d4344>
01:47amatsu,(transient #{})
01:47clojurebot#<TransientHashSet clojure.lang.PersistentHashSet$TransientHashSet@1269273>
01:47amatsucool
01:47amatsudbasch: thanks!
01:47dbaschwhat are you trying to do btw?
01:49amatsudbasch: I'm running through a list of strings which I want to add into a set, which is already inside the hash-map
01:49amatsuI wanted to use update-in
01:50amatsubut using conj the function for update-in resulted in creating lists instead sets.
01:51dbaschamatsu: you can use union for sets
01:51amatsu,(clojure.set/union nil #{2})
01:51clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>
01:52amatsuoh, that works perfectly
01:52amatsudbasch: thanks again
01:52dbaschnp
02:15irctchow can i make my clojure app emulate a program like "md5sum -" where i read input until eof?
02:15irctcread stdinput i mean
02:18irctcim using jline2 to read from stdin using this example: http://goo.gl/XYriUX but if i execute my app remotely via ssh, the program doesnt finish reading input properly like "md5sum -" does
02:20dbaschirctc: you could just (slurp *in*)
02:23irctcdbasch: im trying that in the repl.. how do i tell slurp to stop? i enter control+D but it eats that up too
02:24TEttingerctrl-d doesn't input EOF?
02:24irctcit does
02:24irctcim using cmd on windows 8.1
02:25irctcTEttinger it just inserts ^D over n over again
02:25aditya-airctc: are you in any way connected with http://irctc.co.in/ ? Because that would be totally awesome :-)
02:25irctcaditya-a no, i typed "clojure irc channel" in google and clicked the second link looool
02:30aditya-airctc: :D for half a second I dared to hope that the Indian Railways was evaluating Clojure :-)
02:40jweaverTerminology wise, what is the difference between a list and a "sequence"?
02:40jweaverIs a sequence just anything that is ordered?
02:40beamsoi think a sequence is a map, set, list or vector
02:41beamsoactually, it's more than that. a string can be a sequence (of characters)
02:42irctcisn't a sequence a common interface thats implemented by all the data structures string map list etc?
02:42dbaschtechnically speaking, a sequence is anything that implements ISeq
02:43irctcso no matter if you get a string, map, list whatever, you can call (first s) (rest s) etc
02:43jweaverI ask because the reading I am doing is explaining destructuring, and the "&". As in: (let [[x y & rest] v] rest), and "rest" it says is a sequence, not a vector. So I'm wondering what exactly that terminology means.
02:44irctcso rest could be a list too
02:44jweaverYes
02:45jweaverREPL spits out a list
02:47dbaschno, a list is a sequence but a sequence doesn’t need to be a list
02:49dbaschlist is anything that implements IPersistentList
02:49jweaverOk
02:49dbasch,(list? (rest [1 2 3]))
02:49clojurebotfalse
02:50dbasch,(seq? (rest [1 2 3]))
02:50clojurebottrue
02:50jweaverAhhhhhhh
02:50jweaverOk ok
02:50jweaverI see :-)
02:51trap_exitwhy does fn take an optional name?
02:52trap_exitis it for calling itself?
03:51ticking_is there a way to limit the scope a macro has acess to (limit the env)?
04:51boyscaredanyone know where clojure conj 2014 is going to be yet?
05:01clgvboyscared: there wasn't any announcement on the mailing list yet
05:03boyscaredwas hoping it'd be in the same place as 2013
05:05clgvboyscared: I doubt that since it was at a different place in 2012
09:00mr-foobarJust edited the wiki page -- https://en.wikipedia.org/wiki/Clojure Thoughts ?
09:25S11001001mr-foobar: Very nice; I've made my suggestions in the form of a followup edit :) https://en.wikipedia.org/w/index.php?title=Clojure&amp;diff=609941052&amp;oldid=609938764
09:30clgvmr-foobar: S11001001: more inline citations the page says ;)
09:32clgvhuh? why is the software transactional memory not mentioned on the wikipedia page?
09:32mr-foobarS11001001 clgv: sweet :)
09:32clgvah damn. only the abbreviation is missing :P
09:33clgvoverread it because it is not at then beginning of one of the bullet points ^^
09:37mr-foobaredn doubt -- is it sane, if I map tagged literals to a function data type ? #md/parser "fooparser" -- maps to a helpers.fooparer
09:38mr-foobarbasically I want to refer function references from a config file
09:47clgvmr-foobar: why not just use fullqualified symbols and resolve them after reading the config?
09:48mr-foobarclgv: I am using jsedn :)
09:49clgvno idea what that is
09:55patrickodI'm using friend with compojure to password protect a few routes in my web service. https://gist.github.com/d0b2301f9bc2c80b3c3a is the code implementing this
09:55patrickodthe issue I'm having is that the list of admins is only created at application start
09:56patrickodthe admins-for-login method selects admins from the DB and gives back a map that friend needs for its creds/bcrypt-credential-fn
09:56patrickodwhat would be the easiest way to have this execute on each authentication request such that an admin added to the DB during the lifecycle of the application would be valid?
09:59benmossanyone have any experience working with JavaFX?
10:00benmossi have seen everyone recommend this tip for being able to avoid the Application subclass but it doesn’t work for me https://github.com/daveray/upshot/blob/develop/src/upshot/core.clj#L69
10:01benmossI get “HeadlessException java.awt.dnd.DropTarget.<init> (DropTarget.java:95)”
10:11ddellacostapatrickod: I don't understand; this admins-for-login fn is only executed when the app loads, then the user data is stored somewhere?
10:12patrickodddellacosta: Yep that seems to be what's happening (I'm not too familiar with the internals of friend - I'm new to clojure)
10:13ddellacostapatrickod: are you using the same exact code from the friend example? {:credential-fn (partial creds/bcrypt-credential-fn users) ... etc.
10:13patrickodyep that's where that snippet originated. I just swapped out the users variable for a function that produces the map
10:15ddellacostapatrickod: ah, so, your code looks something like (partial creds/bcrypt-credential-fn (admin-for-logins)) ?
10:15patrickodyeah
10:17yotsovjust came across https://github.com/mtyaka/lein-oneoff and it's probably not very mature to get excited about such things but I find it very cool
10:17clgvpatrickod: dont use map with credentials but a function that retrieves credentials
10:17ddellacostapatrickod: so, just make it a function
10:18patrickodah I see so partial is executing the function only once
10:18patrickodso I should have (fn [user] (creds/bcrypt-credential-fn (admins-for-login) user))
10:19ddellacostapatrickod: partial is creating a closure, so your function is getting called on init. Try something like #(creds/bcrypt-credential-fn (admin-for-logins) %)
10:19ddellacostapatrickod: or yeah, that works too
10:19patrickodthat makes sense :) thanks !
10:20clgvpatrickod: you could also just have a function (defn get-credentials [username] ...)
10:20clgvno need to load all available login data ...
10:21patrickodtrue
10:21ddellacostaone thing at a time now, clgv ;-)
10:21ddellacosta(no, good point though)
10:23clgvit is unfortunate that only the degenerate/special case is documented in the readme and not th general case
10:23ddellacostaclgv: sorry, I don't follow, what do you mean?
10:25clgvddellacosta: afaik the friend readme contains only the example where constant credentials map is used
10:26ddellacostaclgv: oh, I see what you're saying. Yeah, I suppose he's kind of caught between a rock and a hard place with that one though; the goal is to illustrate clearly how it works with the assumption folks are pretty comfortable with Clojure.
10:31ddellacostayotsov: maybe you know it but https://github.com/rkneufeld/lein-try is similar
10:33clgvddellacosta: well not really, lein-oneoff is primarily for executing scripts while lein-try starts you a repl with the specified dependencies
10:33ddellacostaclgv: ...similar in the sense of being a lightweight way to try out libs, is all I meant
10:34clgvddellacosta: yeah. but tat is not the point of lein-oneoff ;)
10:35ddellacostaclgv: fair enough, I stand corrected. :-)
10:35clgvbut lein-try is awesome ^^
10:36yotsovddellacosta: no I didn't, it looks equally nice, thanks
10:43patrickodcan (friend/authenticated be wrapped around many routes?
10:43patrickodor must it be one to one ?
10:46clgvpatrickod: you can use context
10:46patrickodah so (friend/authenticated (context ... )
10:46clgvpatrickod: (context "/admin" request (friend/wrap-authorize (admin-routes server-node) #{::admin}))
10:47patrickodah I was using the the other way around (context /admin (friend/authenticated ... )
10:47clgvmaybe what you posted as well, didnt try that variant.
10:47clgvthe example I posted is from one of my projects
10:48patrickodI'll give that a shot. thanks :)
11:39adsiscoany library to get clojure to execute code at regularly timed interval?
11:40martintrojerquartz?
11:40martintrojerhttp://clojurequartz.info
11:42adsiscoabit of an overkill, i just want it to execute a function every second
11:42martintrojerfuture with a Thread/sleep ?
11:45adsiscomind if i get a simple example? i'm new to clojure
11:45martintrojer(future (dotimes [_ 10] (println "hello") (Thread/sleep 1000)))
11:46adsiscoand how would i stop it?
11:46martintrojeryou can use an atom
11:46martintrojeror go core.async and use channels
11:47martintrojer(future (while @running (println "hello") (Thread/sleep 1000)))
11:47martintrojer(def running (atom true))
11:48martintrojer(reset! running false)
11:50adsiscomartintrojer: thanks! i'll try it right away
12:15master_ophello how can merge maps and use the highest value when duplicatekeys {:u1 5 :u2 6} {:u1 3 :u2 7} ==> {:u1 5 :u2 7}
12:17master_opany help please ?
12:28master_opcan anyone help me please ?
12:30Bronsa,(merge-with max {:a 1 :b 2} {:a 2 :b 1})
12:30clojurebot{:b 2, :a 2}
12:30Bronsamaster_op: ^
12:32master_opthank you , you save me
13:02dissipatedoes anyone know when the next RuPy conference is?
13:14dissipateanyone here been to rupy?
13:15sandbagsno but it sounds interesting... i like things that live on intersections (Ruby/Clojure dev here)
13:22dissipatesandbags, i'm more interested in clojure at this point, but ruby and python are a lot more pervasive in industry
13:23dissipatesandbags, so it seems like a good conference
13:23sandbagslikewise, my interest in Ruby peaked a few years ago
13:23sandbagsclient work requires me to keep my eye in but anything new i am doing myself now, i do in clojure
13:23sandbagsbut there's still a lot of interesting people/projects in the ruby world
13:24dissipatesandbags, but don't you see how ruby/python are limited whereas clojure is not?
13:24sandbagsdefine "limited"
13:25dissipatesandbags, lack of macros. built in data structures are not persistent. significantly more boilerplate required for concurrency.
13:25sandbagswell it depends on your perspective
13:26sandbagsi wouldn't say "Ruby is limited. Clojure is not" I would say "They have different strengths"
13:26dissipatesandbags, what are the strengths of ruby?
13:26sandbagscompared to what?
13:27dissipatesandbags, clojure
13:27sandbagsand from what perspective... i mean if i wanted to write an OO app, Ruby wins hands-down
13:28dissipatesandbags, that's a non-start. no one should be thinking 'i want to write an OO app'. they should be thinking 'i want to do x'
13:28sandbagsif i'm coming from most C-based languages the Ruby syntax will be considerably easier to get to grips with
13:28dissipatesandbags, no reason to write an OO app just for the sake of OO
13:28sandbagsalso the imperative style will be considerably more familiar than a functional approach
13:29sandbagsbut really why does one have to "win"
13:29dissipatesandbags, i agree with those practical considerations
13:29dissipatesandbags, but in terms of where we want to go, i don't think it's ruby.
13:29fortruce_master_op: if you were still wondering, you can use merge-with
13:30dissipatesandbags, you must agree since all of your new stuff is in clojure
13:30sandbagswell again it depends where you think that is... when i can just say "Computer do X"
13:30sandbagsall this () stuff will seem rather ridiculous!
13:30fortruce_,(def m {:x 1 :y 2 :z 3})
13:30clojurebot#'sandbox/m
13:30fortruce_,(def z {:x 2 :y 1 :z 2})
13:30clojurebot#'sandbox/z
13:30fortruce_,(merge-with #(if (> % %2) % %2) m z)
13:30clojurebot{:y 2, :z 3, :x 2}
13:30sandbagsdissipate: i find clojure very interesting and pleasing to work with right now is all i know
13:31sandbagsdissipate: learning clojure has been (in a rather more challenging way) very like learning Ruby
13:32dissipatesandbags, BTW, the top Ruby guys and the top Python guys must know that their languages are limited. i'm sure they are fully aware of Clojure. but they are riding that wave of 'industrial pragmatism'
13:32dissipatesandbags, even John Carmack is into functional programming now.
13:32sandbagsagain i'm not sure "limited" is a word i would choose
13:33sandbagsthere's a lot of functional goodness in Ruby
13:33sandbagsi believe, although i've not looked into it, that someone built a set of persistent collections for Ruby
13:33dissipatesandbags, sure, but it's watered down
13:33sandbagsperhaps, but the question is "for problem X, is it good enough?"
13:34dissipatesandbags, i think taking the OO approach for everything is quite harmful actually, and that's what ruby/python/java lead you to do.
13:34sandbagsi wrote quite a lot of software in Ruby that seemed to work pretty well
13:34fortruce_for me, clojure wins out because of the persistent collections, it's so nice not to have to worry about things changing under my feet...the functional bit is just icing on the cake :p
13:34sandbagsi also embedded Ruby in Objective-C apps that worked quite well
13:35sandbagsnot something i would try with Clojure
13:35sandbagssadly
13:35dissipatesandbags, i see ruby/python as harmful now actually. necessary, sure, but not taking us in the right direction.
13:36sandbagswell it's an opinion
13:36dissipatei mean, only necessary in certain industrial applications because of their pervasiveness
13:37dissipatesandbags, what do you think of John Carmack getting into FP in an industry dominated by C++?
13:37sandbagsi don't really have an opinion on it... I know roughly who JC is but not much beyond that
13:38sandbagsand now i am getting thrown out of Starbucks
13:38fortruce_you were typing too passionately
13:38dissipatethrown out of starbucks? wow...
13:38fortruce_haha
13:39dissipatefortruce, do you think more languages with persistent data structures will pop up?
13:40fortrucedissipate: I hadn't really thought about it, but I think with Clojure becoming more popular, and the introduction of Datomic, that more might pop up
13:41fortruceI've only been using Clojure for about 2 months now in my free time, the persistence has been my favorite part, but I am really enjoying functional programming
13:41dissipatefortruce, then there is Haskell which forces you into purity. but the syntax is too heavy IMO.
13:42fortrucedissipate: haskell goes a bit too far for my tastes as well, I think Clojure strikes a very nice middle ground
13:42fortruceI really need to play around with core.typed to see what that brings to the table as well
13:50chrissfdissipate: since you brought up Carmack and OO, I don't think he's a big OO believer. In fact, he has a semi-famous quote of "Sometimes all you really need is a function"
13:52dissipatechrissf, and he's right. OOP can be managed with patterns to some extent, but few in industry actually follow those patterns. it just ends up a mess.
13:53hyPiRiondissipate: Yes, persistent data structures will become popular. Elm just recently implemented RRB-trees, and there are people in Julia recreating Clojure's persistent ones
13:56chrissfdissipate: I've always felt uneasy with the idea of methods and data co-mingled.
13:58dissipatechrissf, well, you are actually trying to hide data. the problem is when you want to do something different with that data.
14:00dissipatechrissf, by replacing the raw/fundamental data structures with objects, you add complexity. in order for someone to even know exactly what you are talking about, they have to read your class.
14:07chrissfdissipate: or as Rich Hickey has talked about before, you're creating weird little mini-dsls
14:10dissipatechrissf, yep. and i truly have no idea why anyone would consider this a 'natural' approach to be used for everything. for programming UI's maybe but certainly not everything.
14:13dissipatechrissf, a lot of the OO patterns i have seen use these things called DTOs (data transfer objects). they are immutable objects to be passed around. but i see no reason why they should be wrapped up in an object. it's a fail.
14:13dissipateer, rather why the underlying data should be wrapped in an object
14:14chrissfdissipate: yep, I use immutable DTOs all the time. In the blogosphere there was the debate of anemic data models (DTOs) vs rich data models (whole bunch of methods in there). The problem with the rich data model is that it's so easy to start violating separation of concerns
14:15chrissfyou start throwing everything and the kitchen sink into your class
14:16chrissfthe whole dogma of everything that exists should exist in a class is finally starting to wane
14:16chrissf...finally
14:16dissipatechrissf, yep, that opens up a whole can of design patterns, starting with SOLID.
14:54adsiscohttps://www.irccloud.com/pastebin/f5rWU7t1
14:55adsiscoany idea why i keep getting "off2" even though status is on?
14:55adsiscois there a race condition?
14:56adsiscoit returns fine if i remove the (status-off) function
14:59amalloyhow could we possibly know whether there's a race condition, without knowing what status-off does
14:59adsiscohttps://www.irccloud.com/pastebin/la6ZpdRP
14:59adsiscoits a web app on composure btw
15:00adsiscobasically, i goes to www.app.com/on, it will write to a file "on"
15:00adsiscowww.app.com/off and its a "off"
15:00adsiscoand the /status page just reads off that file
15:00amalloycertainly there's a race if there's a call to get-status at the same time as a call to anything else interesting
15:00adsiscobut if its status is on, i want to return "on" and re-write the file to "off"
15:01amalloybut if you're just testing manually, you're unlikely to get the timing to trigger that
15:01adsiscohow should i fix it?
15:02amalloyi mean, don't use a file? why is a file involved here? just use an in-memory atom, which is designed to be atomic
15:03dbaschbtw (str “on”) is the same as “on”
15:04adsiscoso instead of writing to file, i use (def state "on) (def state "off") ?
15:05dbaschno, something like (def state (atom {:status :off}))
15:06dbaschand swap accordingly
15:06dbaschthat’s an example, your atom can have anything you need in it
15:07adsiscobut then again, can i do it with a file? i might want to extend the program beyond 2 states, and it would be easier to read off it
15:07dbaschif you do it with a file you’ll have to coordinate access to it
15:07dbaschthat’s why people use transactional databases
15:08adsiscoyea, i'm using that
15:08adsiscoits just easier to do i/o when prototyping
15:08adsiscoguess i have no choice...
15:08dbaschunless you can guarantee that your system has only one caller
15:08adsiscohttps://www.irccloud.com/pastebin/g3KmipXj
15:09adsiscobut when i look at it
15:09adsiscoi already tested the condition
15:09dbaschif you’re returning off2, it means that x wasn’t on
15:10dbaschyou should add a print statement and see what you’re slurping
15:10adsiscoi'm suspecting that too
15:10adsiscoletme try
15:11adsisco(= (slurp save-path) "on") returns true
15:11adsiscoseems correct...
15:12adsiscoi mean, once the condition returns true, i should get "on2" irregardless
15:13adsiscothe additional (status-off) fn shouldn't affect the return string
15:13adsiscoits just (str "on2")
15:13adsiscohttps://www.irccloud.com/pastebin/oMZ9YSfA
15:13adsiscothis works perfectly fine
15:14dbaschwell, what’s calling get-status and how? Are you debugging the results of the calls to get-status? it’s probably being called more than once
15:15dbaschif you call it twice, the second time would return on2 if you don’t change it
15:15adsiscoyou're right!!
15:15adsiscoon repl
15:15adsiscoif i call it once
15:15adsiscoit worked
15:16adsiscoif i'm calling it through my browser
15:16adsiscoits secretly calling it twice?
15:16adsiscois it supposed to do that?
15:17dbaschno, it’s not. it must be a problem with your app’s logic
15:19adsiscoi don't know what happened... but its working now...
15:20adsiscothanks bro =D
15:20dbaschyou should probably review your design. A system that doesn’t work if it’s called twice is very fragile
15:20dbaschfor one, you should not use a GET for that call as it’s not idempotent
15:21adsiscoany suggestion?
15:22dbaschI don’t know what your app does how it’s meant to be used, so it’s hard to say
15:22dbasch*or how
15:23adsiscobasically its a queue of commands
15:23adsiscoand i just keep reading off it and execute
15:24adsiscothrough restful apis
15:25dbaschso for your command api you should be using post or put
15:26dbaschand I assume you will store your commands in a queue, not a file
15:26adsiscoyea, probably using AWS queue or something
15:27dbaschit’s very important that you don’t use GET for requests with side effects, especially it it’s an open app
15:27dbaschyou don’t want a random web crawler triggering actions
15:28adsiscoit's a closed app. by using post/put, it means i should try and retrieve only with credentials?
15:29dbaschnot necessarily. GET is meant to request data, POST is for submitting data for processing
15:32adsiscoactually, i'm developing a karaoke-on-demand system. i've a server that have a queue of songs to be played. and a client that keeps reading off the server and just play whatever, no data processing or whatsoever.
15:33dbaschso requesting a song to be played should be a POST
15:33dbaschI assume it comes from a form anyway
15:34adsiscobtw i would like to add you on linkedin
15:34adsiscoi've just sent my request, i'm edwin
16:25ToxicFrogHow do I go about debugging core.typed when it's crashing?
16:47waynrtechnomancy: just fyi, i'm working on fixing the lein-release tests and will take a look at passing the 'level' arg to the second default bump-version task
16:48waynrprobably through a binding on a var in the leiningen.release namespace if i understand correctly how that kind of thing works
16:54hughfdjacksonheyhey :)
16:54hughfdjacksonit's been a while since i took a look at clojure - wondering what people tend to be using in terms of 'web frameworks' (set up http service/handle concurrent requests/responses)
16:54hughfdjacksonany recommendations?
16:55dbaschhughfdjackson: the closest to a framework is probably http://www.luminusweb.net/
16:56hughfdjacksonthanks dbasch
16:56hughfdjacksondo people tend to create their own stack out of small libraries in the clojure world? (noir + hiccup + .. whatever else is necessary?)
16:57dbaschyes
16:57dbaschit’s standard to use ring / compojure and add whatever you need to that
16:57hughfdjacksonawesome, i'll start there then
17:10yedithe only thing that i haven't figured out with the ring/compojure style webapps, is simple ways to do user authentification
17:10yedithough it seems like buddy might be the ticket for that
17:14dbaschyedi: I wrote a small library for db-based password auth, https://github.com/dbasch/wheel/blob/master/src/wheel/core.clj
17:26yedidbasch: cool, i'll check it out
17:27dbaschyedi: suggestions / improvements welcome
18:06caternis there an idiom or form for returning a value if the value is truthy, and returning something else if the value is falsey?
18:07caternnvm! or, of course!
18:23caterni am finding myself (during debuggin) frequently wanting to know what the value of some single expression in one of my functions is, with a specific input to that function. is there a way to do this quickly with just the usual CIDER repl and Emacs?
18:34gfrederickscatern: println? other than that if you don't mind installing some repl middleware there is https://github.com/fredericksgary/debug-repl
18:35caternyeah, println is what i'm using right now, but it seems so crude
18:35gfredericksit gets 2% better when you learn the trick (doto x println)
18:35caternthat's a useful trick
18:36caternthanks :D
18:36gfredericks:)
18:38gfredericksreiddraper: do you think this stateless-prng thing is worth polishing?
18:39caternmm, this would be a useful thing to do with reader macros
18:40catern(the println or doto x println, that is)
18:45gfrederickspretty easy too
18:45gfrederickscould use #p
18:46gfredericks(fn [form] `(doto ~form (->> (println "YO:"))))
18:46reiddrapergfredericks: i'll admit i still don't quite understand what the original issue was, but i also haven't dug in too much
18:46reiddrapergfredericks: is it an issue with 'normal' test.check usage, or only if you break the Gen abstraction and dig into the shrink trees yourself?
18:48caternalternatively, it would be nice if there was some REPL function like: (function-bindings expr f & args) "Destructures and binds the values of given arguments to the argument variables defined in f, then evalutes expr"
18:48gfredericksreiddraper: it's caused by trying to intentionally walk a specific path into the shrink tree, for the purpose of "replaying" a shrink (without the extra dead-ends)
18:48gfredericksso e.g., if you wanted to resume a shrink
18:49caternbut maybe that's impossible? is that kind of information (variable names) preserved?
18:49reiddrapergfredericks: it's not obvious to me how that should cause more randomness to be used by the stateful RNG
18:50gfrederickscatern: only on defns
18:50gfredericksreiddraper: less actually
18:50gfredericksby skipping the dead ends, the stateful RNG gets used a different way
18:51caterngfredericks: why only on defns?
18:51gfrederickscatern: it's actually on the var that defn creates, rather than the function; it's a feature of defn, rather than fn
18:51amalloycatern: https://github.com/flatland/useful/blob/develop/src/flatland/useful/debug.clj#L26 is a somewhat better version of (doto x prn), if you decide to go that direction rather than in the direction of some cider thing
18:51reiddrapergfredericks: can you show me where the RNG gets used during the lazy shrink tree stuff? That _should_ all be deterministic
18:52reiddrapergfredericks: am i asking the right questions, or am i misunderstanding something more fundamental?
18:52gfredericksreiddraper: no I think you're tracking
18:52gfredericksreiddraper: the shrinking is unrelated to randomness, for all generators except bind
18:54gfredericksbecause the bind function has to create a new generator every time the outer value shrinks
18:55gfredericksit makes sense conceptually
18:56akurilinRandom question: are there common patterns out there for preventing double-submission of "messages" between web services talking to each other? Perhaps identifying each message with a UUID and having the receiver make sure this isn't a duplicate?
18:56reiddrapergfredericks: (defn elements [coll] (gen/bind (gen/choose 0 (count coll)) #(gen/return (nth coll %))))
18:56reiddrapergfredericks: though that could be writen with fmap too
18:56gfredericks(def list-and-el (bind (not-empty (list nat)) (fn [nums] (tuple (return nums) (elements nums)))))
18:57reiddraperakurilin: labelling messages with unique idents like that is common, yes
18:57fifosineI'm following along with the book "Web Development in Clojure" but in it he uses some nifty LightTable tricks that I'm trying to keep up with. Specifically, I'm in the root of the project we're starting and I'd like to execute some functions. The function is in /src/guestbook/modules/db.clj so I'm trying to bring it into lein repl via "(use 'guestbook.modules.db)" but it throws this error: "FileNotFoundException Could not locate guest
18:58gfredericksreiddraper: so with list-and-el ^ we make a new generator given a list of numbers; during shrinking, that list of numbers shrinks, so we have to make a new generator
18:58fifosineHow do I call these functions correctly?
18:58gfredericksand we have to *call* that generator
18:58gfredericksand the generator will twerk the Random object
18:58reiddrapergfredericks: right, ok, i'm following
18:58gfredericksother than bind, shrinking doesn't involve calling generators
18:59gfredericksso that's why bind is a special case
18:59reiddrapergfredericks: ok, yes, i'm understanding now
18:59gfredericksso that can be fixed in bind, like with the patch I submitted a week or two ago; or alternatively stateless RNGs make the problem go away
18:59dbaschakurilin: that, or a hash of the content
19:00akurilinreiddraper: is there a common pattern for how long you keep the UUIDs or other unique identifiers cached around for on the receiver's end?
19:00reiddraperakurilin: i'm afraid that's a much more difficult question :)
19:00akurilinahah!!
19:00gfredericksakurilin: two weeks. nothing bad can possibly happen.
19:00reiddraperakurilin: and one the many reasons distributed systems are hard (and fun)
19:00akurilinI guess that's basically something that depends on the system's SLA and implementation etc
19:01akurilinso it's case-by-case
19:01reiddraperakurilin: where at all possible, you'll find it's preferable to be able to tolerate duplicate messages (by making idempotent message processing)
19:02akurilinreiddraper: isn't using a unique identifier basically enabling that, at least at the protocol level?
19:02akurilinso if you receive the same message twice, you still confirm
19:02akurilinor are you talking about something else?
19:03reiddraperakurilin: indeed, it is, but you might have some other ability to make a message idempotent, without having to remember an ID forever. Really just depends on your business domain
19:03reiddraperfor example, adding an element to a set is idempotent, so need to keep track of message ids there
19:04gfredericksonly if your set is always growing; at which point this isn't saving any space versus an always-growing set of UUIDs
19:04fifosineAnyone able to help me out? :/
19:04gfredericks~anyone
19:04clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
19:04akurilinreiddraper: fair enough, that's a good example
19:04fifosineI'm following along with the book "Web Development in Clojure" but in it he uses some nifty LightTable tricks that I'm trying to keep up with.  Specifically, I'm in the root of the project we're starting and I'd like to execute some functions.  The function is in /src/guestbook/modules/db.clj so I'm trying to bring it into lein repl via "(use 'guestbook.modules.db)" but it throws this error: "FileNotFoundException Could not locate gue
19:05akurilinreiddraper: I'm just trying to design a pubsub web service (not for production use, it's more of a potential test project for folks we're hiring) and I'm going through the various design decisions myself right now
19:06fifosinegredericks: ^
19:06akurilindouble-submission being a big consideration obviously
19:06reiddraperakurilin: neat
19:06akurilinIn the real world I think people just tell you to use redis or zeromq and stfu :)
19:07reiddraperakurilin: nah, this is still a problem in 'the real world', and neither of those projects solve this issue
19:07reiddrapergfredericks: ok, i think i have a much better understanding now, let me take a look at your branch, and maybe read one of the stateless RNG papers
19:08gfredericksreiddraper: yeah the unclearest thing to me is the split function; I looked up haskell's docs and it basically said "nobody's actually researched this we have no idea if it's okay"
19:09reiddrapergfredericks: related: https://github.com/rickynils/scalacheck/issues/67
19:09gfredericksbut my version isn't even necessarily as good as theirs, I just made something up
19:10gfredericksreiddraper: the main thing I was going for in putting that branch together was "what would this do to the structure/readability of the test.check code?"
19:10reiddrapergfredericks: okie
19:10gfredericksI was imagining it would be a bigger change than it actually turned out to be
19:11reiddrapergfredericks: insofar as having to add split calls, i don't mind at all
19:11akurilinreiddraper: oh ok that's good to know, nothign going to waste then!!
19:11reiddraperyeah
19:14gfredericksreiddraper: okay so your only concern is statistical quality?
19:14gfredericksI suppose perf could conceivably get worse
19:14gfrederickswhen I run the tests on the two versions the total runtime is comparable
19:14gfredericksI should try it on my real life generators
19:17akurilinreiddraper: do people ever scale pubsub web services horizontally?
19:21gfrederickskafka?
19:22reiddrapergfredericks: well my first concern would be correctness :)
19:22reiddraperakurilin: yes
19:23gfredericksdisclaimer: I have never heard the word "kafka" before and just imagined that it might hypothetically be the name of a pubsub service
19:25amalloygfredericks is a big proponent of the new fad Architecture By Guessing
19:44gfredericksexperts call it "surprisingly effective"
19:50ImperialCity_Gi have two leinengen projects, one is a client app and one is a server app. i have some functions that i need to write 2 times, one in each app. how can i make both projects share these functions
19:54gfredericksmake a library they can both use?
19:56ImperialCity_Ggfredericks i never did that before.. how will leinengen find it if its not on clojars etc?
19:56gfredericks`lein install` will put it in your local repo under ~/.m2
19:57ImperialCity_Gso whenever i make a new change to the library do i just run 'lein install' again and im good to go?
19:59gfredericksyeah you can do that; you can use snapshots if you don't want to update the version, or look at the lein checkouts feature
20:33akurilinamalloy: lol
20:34akurilinI'm still dealing with the conflict between "big design first" vs "evolutionary design" in my head.
20:34akurilinSeems like both are considered silver bullets depending on who you listen to.
20:35gfredericksthe only silver bullet is /dev/null
20:35gfredericksor, in clojure, /dev/nil
20:35dbaschakurilin: http://en.wikipedia.org/wiki/No_Silver_Bullet
20:35akurilinEvery time someone says evolutionary design is end all be all I think of http://en.wikipedia.org/wiki/Recurrent_laryngeal_nerve
20:35hyPiRiongfredericks: (require '[dev.nil :refer sink]) ?
20:36akurilindbasch: I really need to read that one, thank you
20:37hyPiRionakurilin: usually I do as much thinking as I'm allowed to in the beginning, then mutate stuff whenever feature requests come by. Finally when I've had enough, I start on scratch again and "recode" the whole shebang, or parts of it.
20:38akurilinhyPiRion: yessir, that sounds very familiar
20:40gfrederickshyPiRion: every time I want to suppress *out* I'm surprised there's no dev-null easily accessible
20:43gfredericks,(def dev-null (proxy [java.io.Writer] [] (write [chars int int]) (flush []) (close [])))
20:43clojurebot#'sandbox/dev-null
20:43gfredericks,(binding [*out* dev-null] (println "OKAY"))
20:43clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/fn--25/fn--30>
20:43gfredericks,(def dev-null (proxy [java.io.Writer] [] (write [^chars cs ^int i ^int i']) (flush []) (close [])))
20:43clojurebot#<CompilerException java.lang.IllegalArgumentException: Only long and double primitives are supported, compiling:(NO_SOURCE_PATH:0:0)>
20:44gfredericksso much for being able to only implement the one write method
20:44hyPiRiongfredericks: pretty sure you only need to supply (write [c])
20:44gfrederickshyPiRion: the docs say (write [chars int int])
20:44gfredericks,(def dev-null (proxy [java.io.Writer] [] (write [c]) (flush []) (close [])))
20:44clojurebot#'sandbox/dev-null
20:44gfredericks,(binding [*out* dev-null] (println "OKAY"))
20:44clojurebotnil
20:45gfrederickshyPiRion: apparently you know more than those docs though
20:45amalloygfredericks: do i have a flatland lib for you
20:45gfredericksmy goal as an OSS developer is to eventually release all of flatland/useful, one lib per function
20:46amalloyhttps://github.com/ninjudd/io/tree/develop/src/flatland/io/core contains an interface you can reify instead of proxy, and then a concrete java class that turns that into an inputstream
20:46amalloyi guess you want a writer instead though. we didn't do that one
20:46amalloyyou could wrap a flatland.io.core.OutputStream in an OutputStreamWriter maybe? depends what you need to do
20:47hyPiRiongfredericks: right, I'm not entirely sure why, but that worked for me. I've just kept doing it and for some reason it works.
20:47gfrederickshyPiRion: my guess
20:47gfredericksis
20:47gfredericksthe spec is right
20:48gfredericksproxy is making a class that thinks it implements (write [c]), so the super never gets called
20:48hyPiRion,(System/getProperty "java.version")
20:48clojurebot#<SecurityException java.lang.SecurityException: denied>
20:48gfredericks,(require 'clojure.core.reducers)
20:48clojurebot#<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath: >
20:48gfredericks,*clojure-version*
20:48clojurebot{:major 1, :minor 6, :incremental 0, :qualifier nil}
20:49gfredericks,(alter-var-root #'*clojure-version* assoc :minor 8)
20:49clojurebot{:major 1, :minor 8, :incremental 0, :qualifier nil}
20:49gfredericks,(alter-var-root #'*clojure-version* assoc :qualifier "HAXED")
20:49clojurebot{:major 1, :minor 8, :incremental 0, :qualifier "HAXED"}
20:50hyPiRiongfredericks: right, so does that mean there's a bug in proxy? I thought you a class had to implement all abstract methods to instantiatable
20:50gfrederickshyPiRion: it does implement the one that matters
20:50gfredericksit just accidentally implements others as well
20:52hyPiRiongfredericks: huh? I don't follow. public void write(cbuf, off, len) is abstract, meaning you have to implement it.. right?
20:52gfredericksyes, which my proxy does
20:52gfredericks,(def dev-null (proxy [java.io.Writer] [] (write [chars int int]) (flush []) (close [])))
20:52clojurebot#'sandbox/dev-null
20:53gfredericks,(.write dev-null ^chars nil ^int 3 ^int 2)
20:53clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>
20:53gfredericks,(.write dev-null ^chars (make-array Character/TYPE 0) ^int 3 ^int 2)
20:53clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>
20:53gfredericks,(.write dev-null ^chars (make-array Character/TYPE 0) 3 2)
20:53clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: dev-null in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:53hyPiRiongfredericks: you can probably, you know, use reflection there
20:53gfredericksconsarnit
20:53gfredericks,(def dev-null (proxy [java.io.Writer] [] (write [chars int int]) (flush []) (close [])))
20:53clojurebot#'sandbox/dev-null
20:53gfredericksconsarnit
20:53gfredericks,(.write dev-null ^chars (make-array Character/TYPE 0) 3 2)
20:53clojurebotnil
20:53gfrederickssee there it goes
20:54hyPiRion,(binding [*out* dev-null] (println "OKAY"))
20:54clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/fn--92/fn--97>
20:55hyPiRiongfredericks: oh right, you should return the number of bytes written probably, and it hiccups internally.
20:55hyPiRionchars*
20:59gfredericks,(def dev-null (proxy [java.io.Writer] [] (write [chars int int] (count chars)) (flush []) (close [])))
20:59clojurebot#'sandbox/dev-null
20:59gfredericks,(binding [*out* dev-null] (println "OKAY"))
20:59clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/fn--171/fn--176>
21:00gfrederickshyPiRion: ^ that error really makes me think it's trying to call the proxy fn with a different arity
21:01hyPiRiongfredericks: yeah
21:11gfredericksif only there were a lib that would let us (can it be? no) disassemble the bytecode that proxy creates, we could answer the question once and for all
21:27numberten(take-while (comp not zip/end?) (iterate zip/next zipper)) runs in linear time on the size of zipper right?
21:27numbertenassuming all the zippers generated utilize sharing?
21:33nathan7numberten: (complement zip/end?)
21:34nathan7numberten: (instead of (comp and zip/end?))
21:34gfredericksclojurebot: clojure is clj4j
21:34clojurebotAlles klar
21:34sdegutis~guards
21:34clojurebotSEIZE HIM!
21:36gfredericksclojurebot: clojurescript is clj.js
21:36clojurebotAlles klar
21:42trap_exitin clojure, given a list, is there a way to say, remove all items that are equal to :tag, and also remove all items right after :tag ? i.e. '(1 :tag 2 3) ==> '(1 3)
21:42trap_exitso it's not just a plain filter, but when an item gets filtered, I want it to kill the item right after it too
21:42Shiro-IchidaTurn it into a map?
21:43Shiro-IchidaOr, wait, no, that wouldn't work even with your example.
21:43trap_exitnot at all
21:43trap_exitwere ou referring to my question?
21:43trap_exitI thought youw ere ansewring a question efore mine
21:43Shiro-IchidaNo, I was referring to your question. I am bad at reading comprehension.
21:44trap_exitit's fine, I'm bad at putting 'spaces' chars in the right place when typing
21:46Shiro-IchidaYou could do a reduce? That's kinda ugly though.
21:52gfredericks'(defn remove&next [f coll] (if-let [[x & [x' & more :as xs]] (seq coll)] (if (f x) (recur f more) (lazy-seq (cons x (remove&next f xs))))))
21:52gfredericks,(defn remove&next [f coll] (if-let [[x & [x' & more :as xs]] (seq coll)] (if (f x) (recur f more) (lazy-seq (cons x (remove&next f xs))))))
21:52clojurebot#'sandbox/remove&next
21:53gfredericks(remove&next #{:tag} '(1 :tag 2 3))
21:53gfredericks,(remove&next #{:tag} '(1 :tag 2 3))
21:53clojurebot(1 3)
21:53gfredericks,(remove&next #(zero? (rem % 5)) (range 20))
21:53clojurebot(2 3 4 7 8 ...)
21:54gfredericksmaybe remove+1 is a less terrible name
21:54gfredericksor remove-2
22:04JahkeupWith cljsbuild, do you have to add a script tag to load the Closure library before the main script (the cljsbuilt one)
22:14arthurzHi, I am curious if there is an equivalent to the .Net's FileSystemWatcher in Clojure (to trigger an event on a file drop/modification)?
22:18dbascharthurz: there is an equivalent java api you can use
22:22arthurzdbasch: WatchService then, OK, thank you
22:23arthurzdbasch: is there a library that can operate on a bunch of files in a muli-threaded way?
22:24dbascharthurz: I guess it depends on what you mean by operate. What’s the use case?
22:25arthurzdbasch: need to read each with an intent to 1) validate content 2) parse 3) load to a database
22:26dbascharthurz: if they are all independent files you can parallelize that easily in clojure, e.g. with pmap
22:27dbasch(doc pmap)
22:27clojurebot"([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."
22:30caternif I have some symbols, and I want to use the as keys to a map, is it better to convert them into keywords first?
22:31caternthem*
22:32caternbecause, I seem to be running into trouble with needing to double-quote the symbols or something or it won't find the corresponding values
22:32Guest84262thank you dbasch
22:32caternoh derp
22:33caternnevermind
22:33caternthat was happening because I was doing '({'foo testval})
23:19arthurzIs there a way to run a Clojure program like daemon/Windows Service (need to constantly watch for new files arriving)?
23:20akhudekarthurz: make an uberjar and use any standard backgrounding technique
23:23caterncan I get syntax-quote to return a PersistentList instead of a Cons?
23:23catern,(class `(1 2 3))
23:23clojurebotclojure.lang.Cons
23:23catern,(class '(1 2 3))
23:23clojurebotclojure.lang.PersistentList
23:28arthurzakhudek: hmm that means the background process would run say java -jar my.jar
23:28akhudekarthurz: yep
23:30arthurzakhudek: how would I interact with the wrapped process to for example pause it?
23:31akhudekarthurz: you could have your program catch sighup or some other signal
23:37arthurzakhudek: then no choice, probably a socket would do, or just a database control table may be
23:37arthurzakhudek: then no choice, probably a socket would do, or just a database control table may be
23:38akhudekarthurz: sure, those are good methods too
23:40arthurzthank you for your help akhudek