2014-05-24
| 00:27 | yedi | is 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:28 | yedi | i know you could probably add a watch? and listen for changes to the map atom and update the keys atom accordingly |
| 00:28 | yedi | but is there like a simpler way of doing it |
| 01:05 | trap_exit | ambrosebs: ! |
| 01:05 | trap_exit | can I send you a pm? |
| 01:05 | trap_exit | s/can/may/ |
| 01:05 | ambrosebs | trap_exit: you're t x? |
| 01:05 | ambrosebs | trap_exit: come to #typed-clojure |
| 01:25 | Frozenlock | Oh look, they invented blogging http://www.twitlonger.com/ |
| 01:25 | Frozenlock | What would the world be without Twitter? |
| 01:26 | jweaver | Twitter 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:29 | Frozenlock | Eyeballs! It's like money, but better! |
| 01:37 | amatsu | Is there any way to make 'conj' always return a set, even when the first argument is nil? |
| 01:41 | amatsu | ,((comp set conj) nil 1) |
| 01:41 | clojurebot | #{1} |
| 01:41 | amatsu | that works |
| 01:41 | amatsu | I hope 'set' is instant if the argument is already a set.. |
| 01:45 | dbasch | amatsu: unfortunately it isn't https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L3778 |
| 01:46 | amatsu | yikes |
| 01:46 | amatsu | is there a transient set? |
| 01:47 | dbasch | ,(transient #{}) |
| 01:47 | clojurebot | #<TransientHashSet clojure.lang.PersistentHashSet$TransientHashSet@8d4344> |
| 01:47 | amatsu | ,(transient #{}) |
| 01:47 | clojurebot | #<TransientHashSet clojure.lang.PersistentHashSet$TransientHashSet@1269273> |
| 01:47 | amatsu | cool |
| 01:47 | amatsu | dbasch: thanks! |
| 01:47 | dbasch | what are you trying to do btw? |
| 01:49 | amatsu | dbasch: I'm running through a list of strings which I want to add into a set, which is already inside the hash-map |
| 01:49 | amatsu | I wanted to use update-in |
| 01:50 | amatsu | but using conj the function for update-in resulted in creating lists instead sets. |
| 01:51 | dbasch | amatsu: you can use union for sets |
| 01:51 | amatsu | ,(clojure.set/union nil #{2}) |
| 01:51 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set> |
| 01:52 | amatsu | oh, that works perfectly |
| 01:52 | amatsu | dbasch: thanks again |
| 01:52 | dbasch | np |
| 02:15 | irctc | how can i make my clojure app emulate a program like "md5sum -" where i read input until eof? |
| 02:15 | irctc | read stdinput i mean |
| 02:18 | irctc | im 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:20 | dbasch | irctc: you could just (slurp *in*) |
| 02:23 | irctc | dbasch: im trying that in the repl.. how do i tell slurp to stop? i enter control+D but it eats that up too |
| 02:24 | TEttinger | ctrl-d doesn't input EOF? |
| 02:24 | irctc | it does |
| 02:24 | irctc | im using cmd on windows 8.1 |
| 02:25 | irctc | TEttinger it just inserts ^D over n over again |
| 02:25 | aditya-a | irctc: are you in any way connected with http://irctc.co.in/ ? Because that would be totally awesome :-) |
| 02:25 | irctc | aditya-a no, i typed "clojure irc channel" in google and clicked the second link looool |
| 02:30 | aditya-a | irctc: :D for half a second I dared to hope that the Indian Railways was evaluating Clojure :-) |
| 02:40 | jweaver | Terminology wise, what is the difference between a list and a "sequence"? |
| 02:40 | jweaver | Is a sequence just anything that is ordered? |
| 02:40 | beamso | i think a sequence is a map, set, list or vector |
| 02:41 | beamso | actually, it's more than that. a string can be a sequence (of characters) |
| 02:42 | irctc | isn't a sequence a common interface thats implemented by all the data structures string map list etc? |
| 02:42 | dbasch | technically speaking, a sequence is anything that implements ISeq |
| 02:43 | irctc | so no matter if you get a string, map, list whatever, you can call (first s) (rest s) etc |
| 02:43 | jweaver | I 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:44 | irctc | so rest could be a list too |
| 02:44 | jweaver | Yes |
| 02:45 | jweaver | REPL spits out a list |
| 02:47 | dbasch | no, a list is a sequence but a sequence doesn’t need to be a list |
| 02:49 | dbasch | list is anything that implements IPersistentList |
| 02:49 | jweaver | Ok |
| 02:49 | dbasch | ,(list? (rest [1 2 3])) |
| 02:49 | clojurebot | false |
| 02:50 | dbasch | ,(seq? (rest [1 2 3])) |
| 02:50 | clojurebot | true |
| 02:50 | jweaver | Ahhhhhhh |
| 02:50 | jweaver | Ok ok |
| 02:50 | jweaver | I see :-) |
| 02:51 | trap_exit | why does fn take an optional name? |
| 02:52 | trap_exit | is it for calling itself? |
| 03:51 | ticking_ | is there a way to limit the scope a macro has acess to (limit the env)? |
| 04:51 | boyscared | anyone know where clojure conj 2014 is going to be yet? |
| 05:01 | clgv | boyscared: there wasn't any announcement on the mailing list yet |
| 05:03 | boyscared | was hoping it'd be in the same place as 2013 |
| 05:05 | clgv | boyscared: I doubt that since it was at a different place in 2012 |
| 09:00 | mr-foobar | Just edited the wiki page -- https://en.wikipedia.org/wiki/Clojure Thoughts ? |
| 09:25 | S11001001 | mr-foobar: Very nice; I've made my suggestions in the form of a followup edit :) https://en.wikipedia.org/w/index.php?title=Clojure&diff=609941052&oldid=609938764 |
| 09:30 | clgv | mr-foobar: S11001001: more inline citations the page says ;) |
| 09:32 | clgv | huh? why is the software transactional memory not mentioned on the wikipedia page? |
| 09:32 | mr-foobar | S11001001 clgv: sweet :) |
| 09:32 | clgv | ah damn. only the abbreviation is missing :P |
| 09:33 | clgv | overread it because it is not at then beginning of one of the bullet points ^^ |
| 09:37 | mr-foobar | edn doubt -- is it sane, if I map tagged literals to a function data type ? #md/parser "fooparser" -- maps to a helpers.fooparer |
| 09:38 | mr-foobar | basically I want to refer function references from a config file |
| 09:47 | clgv | mr-foobar: why not just use fullqualified symbols and resolve them after reading the config? |
| 09:48 | mr-foobar | clgv: I am using jsedn :) |
| 09:49 | clgv | no idea what that is |
| 09:55 | patrickod | I'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:55 | patrickod | the issue I'm having is that the list of admins is only created at application start |
| 09:56 | patrickod | the admins-for-login method selects admins from the DB and gives back a map that friend needs for its creds/bcrypt-credential-fn |
| 09:56 | patrickod | what 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:59 | benmoss | anyone have any experience working with JavaFX? |
| 10:00 | benmoss | i 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:01 | benmoss | I get “HeadlessException java.awt.dnd.DropTarget.<init> (DropTarget.java:95)” |
| 10:11 | ddellacosta | patrickod: I don't understand; this admins-for-login fn is only executed when the app loads, then the user data is stored somewhere? |
| 10:12 | patrickod | ddellacosta: Yep that seems to be what's happening (I'm not too familiar with the internals of friend - I'm new to clojure) |
| 10:13 | ddellacosta | patrickod: are you using the same exact code from the friend example? {:credential-fn (partial creds/bcrypt-credential-fn users) ... etc. |
| 10:13 | patrickod | yep that's where that snippet originated. I just swapped out the users variable for a function that produces the map |
| 10:15 | ddellacosta | patrickod: ah, so, your code looks something like (partial creds/bcrypt-credential-fn (admin-for-logins)) ? |
| 10:15 | patrickod | yeah |
| 10:17 | yotsov | just 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:17 | clgv | patrickod: dont use map with credentials but a function that retrieves credentials |
| 10:17 | ddellacosta | patrickod: so, just make it a function |
| 10:18 | patrickod | ah I see so partial is executing the function only once |
| 10:18 | patrickod | so I should have (fn [user] (creds/bcrypt-credential-fn (admins-for-login) user)) |
| 10:19 | ddellacosta | patrickod: partial is creating a closure, so your function is getting called on init. Try something like #(creds/bcrypt-credential-fn (admin-for-logins) %) |
| 10:19 | ddellacosta | patrickod: or yeah, that works too |
| 10:19 | patrickod | that makes sense :) thanks ! |
| 10:20 | clgv | patrickod: you could also just have a function (defn get-credentials [username] ...) |
| 10:20 | clgv | no need to load all available login data ... |
| 10:21 | patrickod | true |
| 10:21 | ddellacosta | one thing at a time now, clgv ;-) |
| 10:21 | ddellacosta | (no, good point though) |
| 10:23 | clgv | it is unfortunate that only the degenerate/special case is documented in the readme and not th general case |
| 10:23 | ddellacosta | clgv: sorry, I don't follow, what do you mean? |
| 10:25 | clgv | ddellacosta: afaik the friend readme contains only the example where constant credentials map is used |
| 10:26 | ddellacosta | clgv: 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:31 | ddellacosta | yotsov: maybe you know it but https://github.com/rkneufeld/lein-try is similar |
| 10:33 | clgv | ddellacosta: well not really, lein-oneoff is primarily for executing scripts while lein-try starts you a repl with the specified dependencies |
| 10:33 | ddellacosta | clgv: ...similar in the sense of being a lightweight way to try out libs, is all I meant |
| 10:34 | clgv | ddellacosta: yeah. but tat is not the point of lein-oneoff ;) |
| 10:35 | ddellacosta | clgv: fair enough, I stand corrected. :-) |
| 10:35 | clgv | but lein-try is awesome ^^ |
| 10:36 | yotsov | ddellacosta: no I didn't, it looks equally nice, thanks |
| 10:43 | patrickod | can (friend/authenticated be wrapped around many routes? |
| 10:43 | patrickod | or must it be one to one ? |
| 10:46 | clgv | patrickod: you can use context |
| 10:46 | patrickod | ah so (friend/authenticated (context ... ) |
| 10:46 | clgv | patrickod: (context "/admin" request (friend/wrap-authorize (admin-routes server-node) #{::admin})) |
| 10:47 | patrickod | ah I was using the the other way around (context /admin (friend/authenticated ... ) |
| 10:47 | clgv | maybe what you posted as well, didnt try that variant. |
| 10:47 | clgv | the example I posted is from one of my projects |
| 10:48 | patrickod | I'll give that a shot. thanks :) |
| 11:39 | adsisco | any library to get clojure to execute code at regularly timed interval? |
| 11:40 | martintrojer | quartz? |
| 11:40 | martintrojer | http://clojurequartz.info |
| 11:42 | adsisco | abit of an overkill, i just want it to execute a function every second |
| 11:42 | martintrojer | future with a Thread/sleep ? |
| 11:45 | adsisco | mind if i get a simple example? i'm new to clojure |
| 11:45 | martintrojer | (future (dotimes [_ 10] (println "hello") (Thread/sleep 1000))) |
| 11:46 | adsisco | and how would i stop it? |
| 11:46 | martintrojer | you can use an atom |
| 11:46 | martintrojer | or go core.async and use channels |
| 11:47 | martintrojer | (future (while @running (println "hello") (Thread/sleep 1000))) |
| 11:47 | martintrojer | (def running (atom true)) |
| 11:48 | martintrojer | (reset! running false) |
| 11:50 | adsisco | martintrojer: thanks! i'll try it right away |
| 12:15 | master_op | hello how can merge maps and use the highest value when duplicatekeys {:u1 5 :u2 6} {:u1 3 :u2 7} ==> {:u1 5 :u2 7} |
| 12:17 | master_op | any help please ? |
| 12:28 | master_op | can anyone help me please ? |
| 12:30 | Bronsa | ,(merge-with max {:a 1 :b 2} {:a 2 :b 1}) |
| 12:30 | clojurebot | {:b 2, :a 2} |
| 12:30 | Bronsa | master_op: ^ |
| 12:32 | master_op | thank you , you save me |
| 13:02 | dissipate | does anyone know when the next RuPy conference is? |
| 13:14 | dissipate | anyone here been to rupy? |
| 13:15 | sandbags | no but it sounds interesting... i like things that live on intersections (Ruby/Clojure dev here) |
| 13:22 | dissipate | sandbags, i'm more interested in clojure at this point, but ruby and python are a lot more pervasive in industry |
| 13:23 | dissipate | sandbags, so it seems like a good conference |
| 13:23 | sandbags | likewise, my interest in Ruby peaked a few years ago |
| 13:23 | sandbags | client work requires me to keep my eye in but anything new i am doing myself now, i do in clojure |
| 13:23 | sandbags | but there's still a lot of interesting people/projects in the ruby world |
| 13:24 | dissipate | sandbags, but don't you see how ruby/python are limited whereas clojure is not? |
| 13:24 | sandbags | define "limited" |
| 13:25 | dissipate | sandbags, lack of macros. built in data structures are not persistent. significantly more boilerplate required for concurrency. |
| 13:25 | sandbags | well it depends on your perspective |
| 13:26 | sandbags | i wouldn't say "Ruby is limited. Clojure is not" I would say "They have different strengths" |
| 13:26 | dissipate | sandbags, what are the strengths of ruby? |
| 13:26 | sandbags | compared to what? |
| 13:27 | dissipate | sandbags, clojure |
| 13:27 | sandbags | and from what perspective... i mean if i wanted to write an OO app, Ruby wins hands-down |
| 13:28 | dissipate | sandbags, 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:28 | sandbags | if i'm coming from most C-based languages the Ruby syntax will be considerably easier to get to grips with |
| 13:28 | dissipate | sandbags, no reason to write an OO app just for the sake of OO |
| 13:28 | sandbags | also the imperative style will be considerably more familiar than a functional approach |
| 13:29 | sandbags | but really why does one have to "win" |
| 13:29 | dissipate | sandbags, i agree with those practical considerations |
| 13:29 | dissipate | sandbags, but in terms of where we want to go, i don't think it's ruby. |
| 13:29 | fortruce_ | master_op: if you were still wondering, you can use merge-with |
| 13:30 | dissipate | sandbags, you must agree since all of your new stuff is in clojure |
| 13:30 | sandbags | well again it depends where you think that is... when i can just say "Computer do X" |
| 13:30 | sandbags | all this () stuff will seem rather ridiculous! |
| 13:30 | fortruce_ | ,(def m {:x 1 :y 2 :z 3}) |
| 13:30 | clojurebot | #'sandbox/m |
| 13:30 | fortruce_ | ,(def z {:x 2 :y 1 :z 2}) |
| 13:30 | clojurebot | #'sandbox/z |
| 13:30 | fortruce_ | ,(merge-with #(if (> % %2) % %2) m z) |
| 13:30 | clojurebot | {:y 2, :z 3, :x 2} |
| 13:30 | sandbags | dissipate: i find clojure very interesting and pleasing to work with right now is all i know |
| 13:31 | sandbags | dissipate: learning clojure has been (in a rather more challenging way) very like learning Ruby |
| 13:32 | dissipate | sandbags, 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:32 | dissipate | sandbags, even John Carmack is into functional programming now. |
| 13:32 | sandbags | again i'm not sure "limited" is a word i would choose |
| 13:33 | sandbags | there's a lot of functional goodness in Ruby |
| 13:33 | sandbags | i believe, although i've not looked into it, that someone built a set of persistent collections for Ruby |
| 13:33 | dissipate | sandbags, sure, but it's watered down |
| 13:33 | sandbags | perhaps, but the question is "for problem X, is it good enough?" |
| 13:34 | dissipate | sandbags, i think taking the OO approach for everything is quite harmful actually, and that's what ruby/python/java lead you to do. |
| 13:34 | sandbags | i wrote quite a lot of software in Ruby that seemed to work pretty well |
| 13:34 | fortruce_ | 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:34 | sandbags | i also embedded Ruby in Objective-C apps that worked quite well |
| 13:35 | sandbags | not something i would try with Clojure |
| 13:35 | sandbags | sadly |
| 13:35 | dissipate | sandbags, i see ruby/python as harmful now actually. necessary, sure, but not taking us in the right direction. |
| 13:36 | sandbags | well it's an opinion |
| 13:36 | dissipate | i mean, only necessary in certain industrial applications because of their pervasiveness |
| 13:37 | dissipate | sandbags, what do you think of John Carmack getting into FP in an industry dominated by C++? |
| 13:37 | sandbags | i don't really have an opinion on it... I know roughly who JC is but not much beyond that |
| 13:38 | sandbags | and now i am getting thrown out of Starbucks |
| 13:38 | fortruce_ | you were typing too passionately |
| 13:38 | dissipate | thrown out of starbucks? wow... |
| 13:38 | fortruce_ | haha |
| 13:39 | dissipate | fortruce, do you think more languages with persistent data structures will pop up? |
| 13:40 | fortruce | dissipate: 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:41 | fortruce | I'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:41 | dissipate | fortruce, then there is Haskell which forces you into purity. but the syntax is too heavy IMO. |
| 13:42 | fortruce | dissipate: haskell goes a bit too far for my tastes as well, I think Clojure strikes a very nice middle ground |
| 13:42 | fortruce | I really need to play around with core.typed to see what that brings to the table as well |
| 13:50 | chrissf | dissipate: 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:52 | dissipate | chrissf, 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:53 | hyPiRion | dissipate: 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:56 | chrissf | dissipate: I've always felt uneasy with the idea of methods and data co-mingled. |
| 13:58 | dissipate | chrissf, well, you are actually trying to hide data. the problem is when you want to do something different with that data. |
| 14:00 | dissipate | chrissf, 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:07 | chrissf | dissipate: or as Rich Hickey has talked about before, you're creating weird little mini-dsls |
| 14:10 | dissipate | chrissf, 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:13 | dissipate | chrissf, 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:13 | dissipate | er, rather why the underlying data should be wrapped in an object |
| 14:14 | chrissf | dissipate: 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:15 | chrissf | you start throwing everything and the kitchen sink into your class |
| 14:16 | chrissf | the whole dogma of everything that exists should exist in a class is finally starting to wane |
| 14:16 | chrissf | ...finally |
| 14:16 | dissipate | chrissf, yep, that opens up a whole can of design patterns, starting with SOLID. |
| 14:54 | adsisco | https://www.irccloud.com/pastebin/f5rWU7t1 |
| 14:55 | adsisco | any idea why i keep getting "off2" even though status is on? |
| 14:55 | adsisco | is there a race condition? |
| 14:56 | adsisco | it returns fine if i remove the (status-off) function |
| 14:59 | amalloy | how could we possibly know whether there's a race condition, without knowing what status-off does |
| 14:59 | adsisco | https://www.irccloud.com/pastebin/la6ZpdRP |
| 14:59 | adsisco | its a web app on composure btw |
| 15:00 | adsisco | basically, i goes to www.app.com/on, it will write to a file "on" |
| 15:00 | adsisco | www.app.com/off and its a "off" |
| 15:00 | adsisco | and the /status page just reads off that file |
| 15:00 | amalloy | certainly there's a race if there's a call to get-status at the same time as a call to anything else interesting |
| 15:00 | adsisco | but if its status is on, i want to return "on" and re-write the file to "off" |
| 15:01 | amalloy | but if you're just testing manually, you're unlikely to get the timing to trigger that |
| 15:01 | adsisco | how should i fix it? |
| 15:02 | amalloy | i 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:03 | dbasch | btw (str “on”) is the same as “on” |
| 15:04 | adsisco | so instead of writing to file, i use (def state "on) (def state "off") ? |
| 15:05 | dbasch | no, something like (def state (atom {:status :off})) |
| 15:06 | dbasch | and swap accordingly |
| 15:06 | dbasch | that’s an example, your atom can have anything you need in it |
| 15:07 | adsisco | but 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:07 | dbasch | if you do it with a file you’ll have to coordinate access to it |
| 15:07 | dbasch | that’s why people use transactional databases |
| 15:08 | adsisco | yea, i'm using that |
| 15:08 | adsisco | its just easier to do i/o when prototyping |
| 15:08 | adsisco | guess i have no choice... |
| 15:08 | dbasch | unless you can guarantee that your system has only one caller |
| 15:08 | adsisco | https://www.irccloud.com/pastebin/g3KmipXj |
| 15:09 | adsisco | but when i look at it |
| 15:09 | adsisco | i already tested the condition |
| 15:09 | dbasch | if you’re returning off2, it means that x wasn’t on |
| 15:10 | dbasch | you should add a print statement and see what you’re slurping |
| 15:10 | adsisco | i'm suspecting that too |
| 15:10 | adsisco | letme try |
| 15:11 | adsisco | (= (slurp save-path) "on") returns true |
| 15:11 | adsisco | seems correct... |
| 15:12 | adsisco | i mean, once the condition returns true, i should get "on2" irregardless |
| 15:13 | adsisco | the additional (status-off) fn shouldn't affect the return string |
| 15:13 | adsisco | its just (str "on2") |
| 15:13 | adsisco | https://www.irccloud.com/pastebin/oMZ9YSfA |
| 15:13 | adsisco | this works perfectly fine |
| 15:14 | dbasch | well, 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:15 | dbasch | if you call it twice, the second time would return on2 if you don’t change it |
| 15:15 | adsisco | you're right!! |
| 15:15 | adsisco | on repl |
| 15:15 | adsisco | if i call it once |
| 15:15 | adsisco | it worked |
| 15:16 | adsisco | if i'm calling it through my browser |
| 15:16 | adsisco | its secretly calling it twice? |
| 15:16 | adsisco | is it supposed to do that? |
| 15:17 | dbasch | no, it’s not. it must be a problem with your app’s logic |
| 15:19 | adsisco | i don't know what happened... but its working now... |
| 15:20 | adsisco | thanks bro =D |
| 15:20 | dbasch | you should probably review your design. A system that doesn’t work if it’s called twice is very fragile |
| 15:20 | dbasch | for one, you should not use a GET for that call as it’s not idempotent |
| 15:21 | adsisco | any suggestion? |
| 15:22 | dbasch | I don’t know what your app does how it’s meant to be used, so it’s hard to say |
| 15:22 | dbasch | *or how |
| 15:23 | adsisco | basically its a queue of commands |
| 15:23 | adsisco | and i just keep reading off it and execute |
| 15:24 | adsisco | through restful apis |
| 15:25 | dbasch | so for your command api you should be using post or put |
| 15:26 | dbasch | and I assume you will store your commands in a queue, not a file |
| 15:26 | adsisco | yea, probably using AWS queue or something |
| 15:27 | dbasch | it’s very important that you don’t use GET for requests with side effects, especially it it’s an open app |
| 15:27 | dbasch | you don’t want a random web crawler triggering actions |
| 15:28 | adsisco | it's a closed app. by using post/put, it means i should try and retrieve only with credentials? |
| 15:29 | dbasch | not necessarily. GET is meant to request data, POST is for submitting data for processing |
| 15:32 | adsisco | actually, 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:33 | dbasch | so requesting a song to be played should be a POST |
| 15:33 | dbasch | I assume it comes from a form anyway |
| 15:34 | adsisco | btw i would like to add you on linkedin |
| 15:34 | adsisco | i've just sent my request, i'm edwin |
| 16:25 | ToxicFrog | How do I go about debugging core.typed when it's crashing? |
| 16:47 | waynr | technomancy: 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:48 | waynr | probably through a binding on a var in the leiningen.release namespace if i understand correctly how that kind of thing works |
| 16:54 | hughfdjackson | heyhey :) |
| 16:54 | hughfdjackson | it'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:54 | hughfdjackson | any recommendations? |
| 16:55 | dbasch | hughfdjackson: the closest to a framework is probably http://www.luminusweb.net/ |
| 16:56 | hughfdjackson | thanks dbasch |
| 16:56 | hughfdjackson | do people tend to create their own stack out of small libraries in the clojure world? (noir + hiccup + .. whatever else is necessary?) |
| 16:57 | dbasch | yes |
| 16:57 | dbasch | it’s standard to use ring / compojure and add whatever you need to that |
| 16:57 | hughfdjackson | awesome, i'll start there then |
| 17:10 | yedi | the only thing that i haven't figured out with the ring/compojure style webapps, is simple ways to do user authentification |
| 17:10 | yedi | though it seems like buddy might be the ticket for that |
| 17:14 | dbasch | yedi: I wrote a small library for db-based password auth, https://github.com/dbasch/wheel/blob/master/src/wheel/core.clj |
| 17:26 | yedi | dbasch: cool, i'll check it out |
| 17:27 | dbasch | yedi: suggestions / improvements welcome |
| 18:06 | catern | is there an idiom or form for returning a value if the value is truthy, and returning something else if the value is falsey? |
| 18:07 | catern | nvm! or, of course! |
| 18:23 | catern | i 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:34 | gfredericks | catern: println? other than that if you don't mind installing some repl middleware there is https://github.com/fredericksgary/debug-repl |
| 18:35 | catern | yeah, println is what i'm using right now, but it seems so crude |
| 18:35 | gfredericks | it gets 2% better when you learn the trick (doto x println) |
| 18:35 | catern | that's a useful trick |
| 18:36 | catern | thanks :D |
| 18:36 | gfredericks | :) |
| 18:38 | gfredericks | reiddraper: do you think this stateless-prng thing is worth polishing? |
| 18:39 | catern | mm, this would be a useful thing to do with reader macros |
| 18:40 | catern | (the println or doto x println, that is) |
| 18:45 | gfredericks | pretty easy too |
| 18:45 | gfredericks | could use #p |
| 18:46 | gfredericks | (fn [form] `(doto ~form (->> (println "YO:")))) |
| 18:46 | reiddraper | gfredericks: i'll admit i still don't quite understand what the original issue was, but i also haven't dug in too much |
| 18:46 | reiddraper | gfredericks: 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:48 | catern | alternatively, 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:48 | gfredericks | reiddraper: 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:48 | gfredericks | so e.g., if you wanted to resume a shrink |
| 18:49 | catern | but maybe that's impossible? is that kind of information (variable names) preserved? |
| 18:49 | reiddraper | gfredericks: it's not obvious to me how that should cause more randomness to be used by the stateful RNG |
| 18:50 | gfredericks | catern: only on defns |
| 18:50 | gfredericks | reiddraper: less actually |
| 18:50 | gfredericks | by skipping the dead ends, the stateful RNG gets used a different way |
| 18:51 | catern | gfredericks: why only on defns? |
| 18:51 | gfredericks | catern: it's actually on the var that defn creates, rather than the function; it's a feature of defn, rather than fn |
| 18:51 | amalloy | catern: 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:51 | reiddraper | gfredericks: can you show me where the RNG gets used during the lazy shrink tree stuff? That _should_ all be deterministic |
| 18:52 | reiddraper | gfredericks: am i asking the right questions, or am i misunderstanding something more fundamental? |
| 18:52 | gfredericks | reiddraper: no I think you're tracking |
| 18:52 | gfredericks | reiddraper: the shrinking is unrelated to randomness, for all generators except bind |
| 18:54 | gfredericks | because the bind function has to create a new generator every time the outer value shrinks |
| 18:55 | gfredericks | it makes sense conceptually |
| 18:56 | akurilin | Random 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:56 | reiddraper | gfredericks: (defn elements [coll] (gen/bind (gen/choose 0 (count coll)) #(gen/return (nth coll %)))) |
| 18:56 | reiddraper | gfredericks: though that could be writen with fmap too |
| 18:56 | gfredericks | (def list-and-el (bind (not-empty (list nat)) (fn [nums] (tuple (return nums) (elements nums))))) |
| 18:57 | reiddraper | akurilin: labelling messages with unique idents like that is common, yes |
| 18:57 | fifosine | I'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:58 | gfredericks | reiddraper: 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:58 | fifosine | How do I call these functions correctly? |
| 18:58 | gfredericks | and we have to *call* that generator |
| 18:58 | gfredericks | and the generator will twerk the Random object |
| 18:58 | reiddraper | gfredericks: right, ok, i'm following |
| 18:58 | gfredericks | other than bind, shrinking doesn't involve calling generators |
| 18:59 | gfredericks | so that's why bind is a special case |
| 18:59 | reiddraper | gfredericks: ok, yes, i'm understanding now |
| 18:59 | gfredericks | so 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:59 | dbasch | akurilin: that, or a hash of the content |
| 19:00 | akurilin | reiddraper: 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:00 | reiddraper | akurilin: i'm afraid that's a much more difficult question :) |
| 19:00 | akurilin | ahah!! |
| 19:00 | gfredericks | akurilin: two weeks. nothing bad can possibly happen. |
| 19:00 | reiddraper | akurilin: and one the many reasons distributed systems are hard (and fun) |
| 19:00 | akurilin | I guess that's basically something that depends on the system's SLA and implementation etc |
| 19:01 | akurilin | so it's case-by-case |
| 19:01 | reiddraper | akurilin: where at all possible, you'll find it's preferable to be able to tolerate duplicate messages (by making idempotent message processing) |
| 19:02 | akurilin | reiddraper: isn't using a unique identifier basically enabling that, at least at the protocol level? |
| 19:02 | akurilin | so if you receive the same message twice, you still confirm |
| 19:02 | akurilin | or are you talking about something else? |
| 19:03 | reiddraper | akurilin: 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:03 | reiddraper | for example, adding an element to a set is idempotent, so need to keep track of message ids there |
| 19:04 | gfredericks | only if your set is always growing; at which point this isn't saving any space versus an always-growing set of UUIDs |
| 19:04 | fifosine | Anyone able to help me out? :/ |
| 19:04 | gfredericks | ~anyone |
| 19:04 | clojurebot | Just 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:04 | akurilin | reiddraper: fair enough, that's a good example |
| 19:04 | fifosine | I'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:05 | akurilin | reiddraper: 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:06 | fifosine | gredericks: ^ |
| 19:06 | akurilin | double-submission being a big consideration obviously |
| 19:06 | reiddraper | akurilin: neat |
| 19:06 | akurilin | In the real world I think people just tell you to use redis or zeromq and stfu :) |
| 19:07 | reiddraper | akurilin: nah, this is still a problem in 'the real world', and neither of those projects solve this issue |
| 19:07 | reiddraper | gfredericks: 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:08 | gfredericks | reiddraper: 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:09 | reiddraper | gfredericks: related: https://github.com/rickynils/scalacheck/issues/67 |
| 19:09 | gfredericks | but my version isn't even necessarily as good as theirs, I just made something up |
| 19:10 | gfredericks | reiddraper: 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:10 | reiddraper | gfredericks: okie |
| 19:10 | gfredericks | I was imagining it would be a bigger change than it actually turned out to be |
| 19:11 | reiddraper | gfredericks: insofar as having to add split calls, i don't mind at all |
| 19:11 | akurilin | reiddraper: oh ok that's good to know, nothign going to waste then!! |
| 19:11 | reiddraper | yeah |
| 19:14 | gfredericks | reiddraper: okay so your only concern is statistical quality? |
| 19:14 | gfredericks | I suppose perf could conceivably get worse |
| 19:14 | gfredericks | when I run the tests on the two versions the total runtime is comparable |
| 19:14 | gfredericks | I should try it on my real life generators |
| 19:17 | akurilin | reiddraper: do people ever scale pubsub web services horizontally? |
| 19:21 | gfredericks | kafka? |
| 19:22 | reiddraper | gfredericks: well my first concern would be correctness :) |
| 19:22 | reiddraper | akurilin: yes |
| 19:23 | gfredericks | disclaimer: I have never heard the word "kafka" before and just imagined that it might hypothetically be the name of a pubsub service |
| 19:25 | amalloy | gfredericks is a big proponent of the new fad Architecture By Guessing |
| 19:44 | gfredericks | experts call it "surprisingly effective" |
| 19:50 | ImperialCity_G | i 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:54 | gfredericks | make a library they can both use? |
| 19:56 | ImperialCity_G | gfredericks i never did that before.. how will leinengen find it if its not on clojars etc? |
| 19:56 | gfredericks | `lein install` will put it in your local repo under ~/.m2 |
| 19:57 | ImperialCity_G | so whenever i make a new change to the library do i just run 'lein install' again and im good to go? |
| 19:59 | gfredericks | yeah 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:33 | akurilin | amalloy: lol |
| 20:34 | akurilin | I'm still dealing with the conflict between "big design first" vs "evolutionary design" in my head. |
| 20:34 | akurilin | Seems like both are considered silver bullets depending on who you listen to. |
| 20:35 | gfredericks | the only silver bullet is /dev/null |
| 20:35 | gfredericks | or, in clojure, /dev/nil |
| 20:35 | dbasch | akurilin: http://en.wikipedia.org/wiki/No_Silver_Bullet |
| 20:35 | akurilin | Every time someone says evolutionary design is end all be all I think of http://en.wikipedia.org/wiki/Recurrent_laryngeal_nerve |
| 20:35 | hyPiRion | gfredericks: (require '[dev.nil :refer sink]) ? |
| 20:36 | akurilin | dbasch: I really need to read that one, thank you |
| 20:37 | hyPiRion | akurilin: 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:38 | akurilin | hyPiRion: yessir, that sounds very familiar |
| 20:40 | gfredericks | hyPiRion: every time I want to suppress *out* I'm surprised there's no dev-null easily accessible |
| 20:43 | gfredericks | ,(def dev-null (proxy [java.io.Writer] [] (write [chars int int]) (flush []) (close []))) |
| 20:43 | clojurebot | #'sandbox/dev-null |
| 20:43 | gfredericks | ,(binding [*out* dev-null] (println "OKAY")) |
| 20:43 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/fn--25/fn--30> |
| 20:43 | gfredericks | ,(def dev-null (proxy [java.io.Writer] [] (write [^chars cs ^int i ^int i']) (flush []) (close []))) |
| 20:43 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Only long and double primitives are supported, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:44 | gfredericks | so much for being able to only implement the one write method |
| 20:44 | hyPiRion | gfredericks: pretty sure you only need to supply (write [c]) |
| 20:44 | gfredericks | hyPiRion: the docs say (write [chars int int]) |
| 20:44 | gfredericks | ,(def dev-null (proxy [java.io.Writer] [] (write [c]) (flush []) (close []))) |
| 20:44 | clojurebot | #'sandbox/dev-null |
| 20:44 | gfredericks | ,(binding [*out* dev-null] (println "OKAY")) |
| 20:44 | clojurebot | nil |
| 20:45 | gfredericks | hyPiRion: apparently you know more than those docs though |
| 20:45 | amalloy | gfredericks: do i have a flatland lib for you |
| 20:45 | gfredericks | my goal as an OSS developer is to eventually release all of flatland/useful, one lib per function |
| 20:46 | amalloy | https://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:46 | amalloy | i guess you want a writer instead though. we didn't do that one |
| 20:46 | amalloy | you could wrap a flatland.io.core.OutputStream in an OutputStreamWriter maybe? depends what you need to do |
| 20:47 | hyPiRion | gfredericks: 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:47 | gfredericks | hyPiRion: my guess |
| 20:47 | gfredericks | is |
| 20:47 | gfredericks | the spec is right |
| 20:48 | gfredericks | proxy is making a class that thinks it implements (write [c]), so the super never gets called |
| 20:48 | hyPiRion | ,(System/getProperty "java.version") |
| 20:48 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 20:48 | gfredericks | ,(require 'clojure.core.reducers) |
| 20:48 | clojurebot | #<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath: > |
| 20:48 | gfredericks | ,*clojure-version* |
| 20:48 | clojurebot | {:major 1, :minor 6, :incremental 0, :qualifier nil} |
| 20:49 | gfredericks | ,(alter-var-root #'*clojure-version* assoc :minor 8) |
| 20:49 | clojurebot | {:major 1, :minor 8, :incremental 0, :qualifier nil} |
| 20:49 | gfredericks | ,(alter-var-root #'*clojure-version* assoc :qualifier "HAXED") |
| 20:49 | clojurebot | {:major 1, :minor 8, :incremental 0, :qualifier "HAXED"} |
| 20:50 | hyPiRion | gfredericks: 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:50 | gfredericks | hyPiRion: it does implement the one that matters |
| 20:50 | gfredericks | it just accidentally implements others as well |
| 20:52 | hyPiRion | gfredericks: huh? I don't follow. public void write(cbuf, off, len) is abstract, meaning you have to implement it.. right? |
| 20:52 | gfredericks | yes, which my proxy does |
| 20:52 | gfredericks | ,(def dev-null (proxy [java.io.Writer] [] (write [chars int int]) (flush []) (close []))) |
| 20:52 | clojurebot | #'sandbox/dev-null |
| 20:53 | gfredericks | ,(.write dev-null ^chars nil ^int 3 ^int 2) |
| 20:53 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas> |
| 20:53 | gfredericks | ,(.write dev-null ^chars (make-array Character/TYPE 0) ^int 3 ^int 2) |
| 20:53 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas> |
| 20:53 | gfredericks | ,(.write dev-null ^chars (make-array Character/TYPE 0) 3 2) |
| 20:53 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: dev-null in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:53 | hyPiRion | gfredericks: you can probably, you know, use reflection there |
| 20:53 | gfredericks | consarnit |
| 20:53 | gfredericks | ,(def dev-null (proxy [java.io.Writer] [] (write [chars int int]) (flush []) (close []))) |
| 20:53 | clojurebot | #'sandbox/dev-null |
| 20:53 | gfredericks | consarnit |
| 20:53 | gfredericks | ,(.write dev-null ^chars (make-array Character/TYPE 0) 3 2) |
| 20:53 | clojurebot | nil |
| 20:53 | gfredericks | see there it goes |
| 20:54 | hyPiRion | ,(binding [*out* dev-null] (println "OKAY")) |
| 20:54 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/fn--92/fn--97> |
| 20:55 | hyPiRion | gfredericks: oh right, you should return the number of bytes written probably, and it hiccups internally. |
| 20:55 | hyPiRion | chars* |
| 20:59 | gfredericks | ,(def dev-null (proxy [java.io.Writer] [] (write [chars int int] (count chars)) (flush []) (close []))) |
| 20:59 | clojurebot | #'sandbox/dev-null |
| 20:59 | gfredericks | ,(binding [*out* dev-null] (println "OKAY")) |
| 20:59 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/fn--171/fn--176> |
| 21:00 | gfredericks | hyPiRion: ^ that error really makes me think it's trying to call the proxy fn with a different arity |
| 21:01 | hyPiRion | gfredericks: yeah |
| 21:11 | gfredericks | if 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:27 | numberten | (take-while (comp not zip/end?) (iterate zip/next zipper)) runs in linear time on the size of zipper right? |
| 21:27 | numberten | assuming all the zippers generated utilize sharing? |
| 21:33 | nathan7 | numberten: (complement zip/end?) |
| 21:34 | nathan7 | numberten: (instead of (comp and zip/end?)) |
| 21:34 | gfredericks | clojurebot: clojure is clj4j |
| 21:34 | clojurebot | Alles klar |
| 21:34 | sdegutis | ~guards |
| 21:34 | clojurebot | SEIZE HIM! |
| 21:36 | gfredericks | clojurebot: clojurescript is clj.js |
| 21:36 | clojurebot | Alles klar |
| 21:42 | trap_exit | in 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:42 | trap_exit | so 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:42 | Shiro-Ichida | Turn it into a map? |
| 21:43 | Shiro-Ichida | Or, wait, no, that wouldn't work even with your example. |
| 21:43 | trap_exit | not at all |
| 21:43 | trap_exit | were ou referring to my question? |
| 21:43 | trap_exit | I thought youw ere ansewring a question efore mine |
| 21:43 | Shiro-Ichida | No, I was referring to your question. I am bad at reading comprehension. |
| 21:44 | trap_exit | it's fine, I'm bad at putting 'spaces' chars in the right place when typing |
| 21:46 | Shiro-Ichida | You could do a reduce? That's kinda ugly though. |
| 21:52 | gfredericks | '(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:52 | gfredericks | ,(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:52 | clojurebot | #'sandbox/remove&next |
| 21:53 | gfredericks | (remove&next #{:tag} '(1 :tag 2 3)) |
| 21:53 | gfredericks | ,(remove&next #{:tag} '(1 :tag 2 3)) |
| 21:53 | clojurebot | (1 3) |
| 21:53 | gfredericks | ,(remove&next #(zero? (rem % 5)) (range 20)) |
| 21:53 | clojurebot | (2 3 4 7 8 ...) |
| 21:54 | gfredericks | maybe remove+1 is a less terrible name |
| 21:54 | gfredericks | or remove-2 |
| 22:04 | Jahkeup | With cljsbuild, do you have to add a script tag to load the Closure library before the main script (the cljsbuilt one) |
| 22:14 | arthurz | Hi, 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:18 | dbasch | arthurz: there is an equivalent java api you can use |
| 22:22 | arthurz | dbasch: WatchService then, OK, thank you |
| 22:23 | arthurz | dbasch: is there a library that can operate on a bunch of files in a muli-threaded way? |
| 22:24 | dbasch | arthurz: I guess it depends on what you mean by operate. What’s the use case? |
| 22:25 | arthurz | dbasch: need to read each with an intent to 1) validate content 2) parse 3) load to a database |
| 22:26 | dbasch | arthurz: if they are all independent files you can parallelize that easily in clojure, e.g. with pmap |
| 22:27 | dbasch | (doc pmap) |
| 22:27 | clojurebot | "([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:30 | catern | if 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:31 | catern | them* |
| 22:32 | catern | because, 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:32 | Guest84262 | thank you dbasch |
| 22:32 | catern | oh derp |
| 22:33 | catern | nevermind |
| 22:33 | catern | that was happening because I was doing '({'foo testval}) |
| 23:19 | arthurz | Is there a way to run a Clojure program like daemon/Windows Service (need to constantly watch for new files arriving)? |
| 23:20 | akhudek | arthurz: make an uberjar and use any standard backgrounding technique |
| 23:23 | catern | can I get syntax-quote to return a PersistentList instead of a Cons? |
| 23:23 | catern | ,(class `(1 2 3)) |
| 23:23 | clojurebot | clojure.lang.Cons |
| 23:23 | catern | ,(class '(1 2 3)) |
| 23:23 | clojurebot | clojure.lang.PersistentList |
| 23:28 | arthurz | akhudek: hmm that means the background process would run say java -jar my.jar |
| 23:28 | akhudek | arthurz: yep |
| 23:30 | arthurz | akhudek: how would I interact with the wrapped process to for example pause it? |
| 23:31 | akhudek | arthurz: you could have your program catch sighup or some other signal |
| 23:37 | arthurz | akhudek: then no choice, probably a socket would do, or just a database control table may be |
| 23:37 | arthurz | akhudek: then no choice, probably a socket would do, or just a database control table may be |
| 23:38 | akhudek | arthurz: sure, those are good methods too |
| 23:40 | arthurz | thank you for your help akhudek |