#clojure logs

2016-02-01

00:00lockdownscottj: gonna give it a try some day, my mba with 4gb doesn't like it, used eclipse on other machines
00:03lockdownit can do a repl without lein, I wonder it does it, is it referring to the network repl introduced in 1.8?
00:03lockdown+how
00:04justin_smithlockdown: clojure.jar plus capturing stdin/stdout?
00:04justin_smithlockdown: also, you can use lein to calculate classpath and cache it, and use that to launch clojure.jar
00:04lockdownjustin_smith: prolly
00:05rhg135that feature is great for cljs
00:05arrdemI have a script somewhere for doing just that.. use lein to compute the classpath, cache it and never boot lein again unless project.clj changes. gives you a really fast repl start.
00:05rhg135before the other IDEs got nREPL usable for cljs
00:06rhg135that's what fast trampoline is no?
00:06lockdownjustin_smith: oh nice
00:06justin_smitharrdem: btw if you use lein trampoline and turn on LEIN_FAST_TROMPOLINE in the shell lein does that for you
00:07lockdowncode formatting, that one must be hard for clojure
00:07arrdemlockdown: clj-fmt and clojure-mode do a pretty good job
00:09lockdownarrdem: does it follow some guide? don't see anything in the clj-fmt repo
00:10arrdemlockdown: it aims to be configurable, but I think that bozhidar's guide dominates
00:12arrdemhttps://github.com/bbatsov/clojure-style-guide link in case you can't find it
00:14lockdownthanks
01:25athinggo2ngonI am relatively new to Clojure, and I am having a hard time reading the following. I wanna know if it's due to the poor quality of the code.
01:25athinggo2ngonhttp://pastebin.com/NxtnMT8t
01:27opqdonutyeah I would've used some helper functions / local variables there
01:28opqdonutalso if you don't know as-> that's going to throw you off a bit
01:28opqdonutalso, I think a for would look better instead of that map
01:29Bronsaathinggo2ngon: that code isn't even valid
01:29opqdonutyeah it's actually missing the parameter vector
01:30opqdonutshould be something like (defn get-lookup-datasources [xforms]
01:32justin_smitheven worse, it uses flatten
01:33opqdonut:P
01:51RaynesSup peeps. Who manages the new Clojure website?
01:54RaynesWhile I appreciate the reference to tryclj.com, I haven't maintained it in literally years and probably won't for at a minimum 3 months. It's old, broken in mysterious ways a lot, and I have generally completely ignored reported issues. It might not be worth being on there unless someone wants to help me out with maintaining and updating it (I can work with you a bit, just busy with other things most of the time, you'd be given admin on the repo) or
01:54Raynes wait on my completely detached ass to return from the void.
01:55justin_smithRaynes: I think contacting cognitect or the clojure-dev mailing list would get you in touch with the right person
01:56RaynesI'll hit the clojure-dev mailing list methinks, since I'm also asking for help.
01:57domgetterRaynes: Thanks for the awesome website :)
01:57RaynesThe one with the ancient Clojure version and half-broken sandbox? You're welcome good sir.
01:58Raynes:p
01:58RaynesGuys I'm so deep in Python I feel like a mouse.
01:58RaynesGonna have to get some hython or something
01:58princeso_what is the reason one can not pass macros as arguments?
01:59RaynesBecause they're not functions.
01:59RaynesThey're things that expand to code.
02:01RaynesThey are... speshul, to put it gently.
02:04BronsaRaynes: just open a ticket over https://github.com/clojure/clojure-site/issues
02:04princeso_i suspected that maybe it was because they cannot be recompiled every time you call them with diferent parameters. is that right?
02:04RaynesBronsa: Damn son you is on it.
02:04Bronsaprinceso_: macros are of no use at runtime
02:11RaynesBronsa: https://github.com/clojure/clojure-site/issues/55
02:11RaynesCommented
02:12amalloyprinceso_: that is one way of describing it, which seems reasonably correct
02:12Raynesamalloy: Hello darkness, my old friend.
02:14RaynesAlso you guys I really need a Clojure Python port.
02:14RaynesLike a week ago.
02:14RaynesGet it done.
02:14Raynes:p
02:14justin_smithRaynes: how close is pixie to being the right thing?
02:15amalloyaren't there a number of bad clojure borts to python?
02:15justin_smithI guess it can't do python interop at runtime (directly at least)
02:15amalloylike Hy or something
02:15amalloyclearly you have to make your own, Raynes
02:15RaynesWith all this time I have
02:15RaynesHell, I'm running late being on irc right now.
02:16Bronsaenough talking, let's start building this already
02:17Raynesjustin_smith: You just told me about it. From first glance pypy scares me.
02:17RaynesI don't work in this environment and know little about it.
02:17RaynesI am now enterprisey as fuck, sorry guys.
02:17RaynesWorth looking into though.
02:18RaynesNoted and thank you kind sir
02:20Raynesjustin_smith: No python 3.5 interop is a nogo
02:21justin_smithhy uses python's mutable types, and its assoc mutates maps
02:22RaynesI need it's libraries.
02:22justin_smithfair enough
03:26breezelihi all!what mean is the keyword" :blastoff!"
03:31MasseRbreezeli: it's not a keyword
03:31MasseRIt's just a symbol
03:31MasseRNo wait, clojure terminology :foo is a keyword, sorry
03:32MasseRBut anyways, it's just a user defined keyword like :foo or :bar
03:32breezeliit like a strng
03:32breezelistring
03:33breezelimaybe
03:33MasseR(keyword "blastoff!")
03:33MasseR> (keyword "blastoff!")
03:33breezelilook like!
03:34breezeli(defn countdown
03:34breezeli [x]
03:34breezeli (if (zero? x)
03:34breezeli :blastoff!
03:34breezeli (do (println x)
03:34breezeli (recur (dec x)))))
03:34breezelithis example
03:35Bronsabreezeli: please don't paste long snippets in IRC
03:35breezeliok,sorry
04:26renlhi I was wondering if I wanna search some text in a big text file do I have to reread the entire file everytime i need to do a search since there is no variables to store the read content
04:27MasseRrenl: you can always save the contents to a variable
04:28renli thought there is no variables in clojure? im super noob at this
04:28MasseRAh I see what you mean
04:28MasseRThere are variables, they are (by default) immutable
04:28MasseR(def foo "foo")
04:28MasseRCreates a 'variable'
04:28MasseRas well as (let [foo "foo"] foo)
04:29renlso if i (def mystr (slurp "bigfile"))
04:29MasseRExactly :)
04:29renldo i get the string in the file or do i just define the slurp command
04:30MasseRFormer
04:30renlas in everytime i access mystr am i reading the file again?
04:30renloh ok
04:30renlthanks
04:30renland when does this (def ....) kick in? the moment i run the script?
04:31MasseRI'm not actually sure. Clojure is lazy, but I'm not sure if it's only datastructures that are lazy
04:31MasseRBut basically the def kicks in when that line is read
04:32renlok thanks :)
04:32MJB47it reads the file when a) the function enclosing the def is called or 2) if it is at the root scope of a namespace, when the namespace is called
04:33ridcully_,(doc delay)
04:33clojurebot"([& body]); Takes a body of expressions and yields a Delay object that will invoke the body only the first time it is forced (with force or deref/@), and will cache the result and return it on all subsequent force calls. See also - realized?"
04:34renl@MJB47 so if i have multiple functions enclosing the def do i read the file everytime or only the first time?
04:34MJB47everytime i believe
04:34MJB47unless you memoise it
04:50J_Arcane... '() is not nil?
04:51opqdonutit's not
04:51opqdonut,(next (list 1))
04:52J_ArcaneWhich means, apparently, that you can't trust if-let if the result can return '()
04:52clojurebotnil
04:52opqdonut,(rest (list 1))
04:52clojurebot()
04:52J_Arcane...
04:52Rick77Hi! Is there any special notation to specify that a method accepts a vector instead of a map? Something that doesn't require me to add ^clojure.lang.PersistentArrayMap?
04:58Rick77tumbleweeds rolling in wind... :)
05:00tdammerswhy is it important for the argument not to be a map?
05:00tdammersor any other kind of collection, for that matter
05:01Rick77I would like to pass the result of a function to java, just for safekeeping, and I would like for java to know the argument type. I figured out it would matter, but now that you are asking I'm not so sure...
05:01tdammersah, interop...
05:01jellytuxHi, I wanna start learning clojure
05:01Rick77to be honest I was also just curious if there is a way: some algorithms work with specific kind of collections and not other, what if I would like my function to be called only with maps?
05:02jellytuxdoes clojure run within JVM?
05:02jellytuxI don't fancy java :(
05:02Rick77jellytux, yes, it does
05:02MJB47yes, bugt clojurescript and clojureCLR dont
05:02tdammersjellytux: yes, normally it does; there's clojurescript that targets JavaScript as a backend, and it's theoretically possible to use other backends, but I am not aware of any
05:02MJB47however i would like to point out that java != JVM
05:02Rick77oops, ehm, yes, as MJB47 said :)
05:02tdammersright, CLR
05:03tdammersRick77: I'd probably settle for restricting my function to map-like things using preconditions
05:03Rick77tdammers, DBC like stuff, then?
05:04Rick77sounds good to me
05:04Rick77tdammers, thank you!
05:04tdammersRick77: was thinking of this: http://blog.fogus.me/2009/12/21/clojures-pre-and-post/
05:07Rick77tdammers: didn't even knew that existed... thank you! (I'm still in the process of learning clojure, but since there is no way to take it without having something practical to do with it, I'm going with what I have :) )
05:07tdammersnp
05:07Rick77thanks!
05:08jellytuxmay I use vim as my editor? I don't know whether JVM implies Eclipse :(
05:08MJB47most people use emacs or vim for clojure
05:09MJB47for IDE, i believe cursive (intellij) is used
05:09MJB47i dont think many people use eclipse
05:10lumathis is from the latest State of Clojure survey: http://static1.squarespace.com/static/5372821be4b0aefc6719057e/t/56a7dc8d3b0be343e82ef921/1453841550679/?format=1000w
05:11jellytuxMJB47: awesome!
05:24dysfunluma: that's quite interesting. i expected more light table even though i don't like it
05:25jellytuxSorry for asking again, but is it advised to learn Java before Closure?
05:25MJB47it helps, but isnt necessary
05:25dysfunjellytux: it's really not necessary
05:25jellytuxit seems to use Java String objects
05:25jellytuxand many other things from Java
05:25dysfunyes, because it's a bit silly to create your own basic types when java has them
05:25dysfunit makes working with java stuff a nightmare
05:26dysfunwhat clojure brings you by default is a bunch of useful functions for working with (mostly) collections and a means of interoping with java
05:26ridcully_but it helps alot to know the underlying bit and bobs. e.g. know what a classpath is, how classes are loaded etc.
05:27dysfuntbh i think even that's abstracted away by build tools adequately
05:27ridcully_yes, but when things blow up, you will have to look into this
05:28dysfunjellytux: the best advice i can offer is if you find yourself using a java type, you can google its long name (e.g. java.lang.String) and google will show you the oracle page for that class
05:28dysfunbut it's rare i drop to the java interface. there are some good reasons to with strings occasionally (performance)
05:29dysfunand if you are familiar with java and you know a given class solves your proboem, you can just use that
05:29dysfunthere are an awful lot of libraries that wrap java to put a nicer interface on it though
05:29dysfunsee e.g. http://www.clojure-toolbox.com/
05:30dysfunalso i recommend http://conj.io/ as a useful tool for finding relevant functions while you're learning
05:30jellytuxI think I am gonna try learning haskell instead, I don't wish to have anything to do with Java
05:30jellytuxa language should stand on its own
05:30jellytuxhopefully Haskell does
05:30dysfunlike haskell uses llvm as a backend?
05:30jellytuxdysfun: I don't know
05:30TEttingeror C-- before that
05:30dysfunit seems like an odd reason to pick a tool
05:30domgetterHaskell uses wizards and time machines
05:31dysfuni don't use clojure when i need something to start up very quickly, but otherwise it's a fantastic environment
05:31TEttingerif you want a language that stands on its own, there's... assembly
05:31dysfunand every library i could ever want at my fingertips
05:31TEttingerthere's sorta JS
05:31jellytuxdysfun: what do you use if you want to start up quickly?
05:31dysfunone of the reasons i don't program haskell is that i don't have every library i could ever want at my fingertips
05:32dysfundepends. c++, c or haskell depending
05:32TEttingerLuaJIT here
05:32dysfunor perl
05:32dysfunif you don't have massive performance requirements, perl can be brilliant
05:33dysfunbut startup time isn't everything
05:33dysfunbeing able to launch something and forget about it and not be bothered by having to worry about it falling over, that's a nice thing to have
05:33jellytuxI want to learn a functional language
05:33TEttingerif it's text-processing heavy I usually prefer the really excellent JVM regular expression lib, and I don't really understand the sigil mess in perl
05:34dysfunit's pretty straightforward. $one_thing, @list_of_things, %map_of_things
05:35dysfun$list_of_things[0], $map_of_things{'a_key'} # still talking about one item, so $, [] and {} say you're talking about a list or a map
05:35dysfunthe corresponding list ops are @foo[1..5], @map{'a','b'}
05:35TEttingeroh yeah, that stuff is simple
05:36TEttingerit's when they start packing on punctuation that I glaze over
05:36jellytuxTEttinger: which language are you discussing?
05:36TEttingerperl
05:36dysfunthe thing clojure taught me was that syntax dosn't matter
05:36TEttinger6 for me
05:36dysfunperl6 is mad, i'm not defending it
05:36dysfunperl5 on the other hand is an excellent tool
05:36TEttingerah ok
05:36MJB47dysfun: interesting, clojure taught me the opposite lol
05:36jellytuxis it similar to PHP?
05:36TEttingerperl?
05:37jellytuxyes
05:37dysfunphp was derived from perl but somehow they made it really shit
05:37TEttingerPHP is a much less capable language that everything
05:37MJB47i find the compactness/expressiveness of clojure/s expression syntax to be incredible
05:37ridcully_perl is the only language i have to run over to the book shelf to search the cookbooks for things like list in maps
05:37dysfunit's not forgiving to newbies, i'll grant. but that problem is you not knowing how to wield it properly
05:38TEttingerI haven't tried perl 5. I was trying the grammar stuff in perl6 and it's pretty... black magic opaque
05:38dysfunyeah, don't get me started
05:38dysfuni speak out against perl 6 a lot. i'm er... 'infamous' in the perl community
05:38TEttingerhehe
05:39dysfunthat's one thing clojure has over perl
05:39TEttingerI really have found clojure much more readable now that I've stuck with it
05:39TEttingerinitially it was hard to read
05:39dysfunnobody wants to write C to glue into the jvm, but with perl it's just achievable enough you go for it
05:39ridcully_perl was my go to lang for all adminy stuff. i only use it for oneliner nowadays. i have not even looked at 6
05:39dysfuntbh i don't actually write perl any more
05:40dysfunand i haven't spoken at a perl conf in 4 years i think
05:40jellytuxwhat kind of programs do you write in clojure?
05:40dysfunright now i'm writing a restful webservice for example
05:41jellytuxcould I get a sneakpeek?
05:41dysfunwhat, you mean some code?
05:41jellytuxdysfun: yeah
05:41dysfunit's going to be open source, so i don't see why not
05:41jellytuxcool
05:41dysfunoh actually, i can show you some of the templating stuff i pushed yesterday
05:42jellytuxgit?
05:42dysfunyeah
05:42dysfunhttps://github.com/irresponsible/wildebeest/blob/master/src/wildebeest/html_string.cljc
05:42TEttingerI write clojure mainly for one-liner stuff these days but sometimes, for jobs that would be really complex text handling in an imperative language, I write a few paragraphs of clojure and it does the equivalent of pages of java
05:43dysfuni just like simple libraries and having macros to eliminate repetitive typing
05:43TEttingerabsolutely
05:43TEttingerI love the seq stuff
05:43jellytuxwow, even though I've never coded in clojure before, it really looks strikingly familiar
05:43dysfunit's nice, but you often pay for it
05:43TEttingerespecially the conveniences relating to seqs, re-seq , line-seq
05:43jellytuxvery readable
05:44dysfunjellytux: well i've been writing clojure for 2 or 3 years now, so that's what it can be, not what you'll write while you're learning
05:44TEttingeryeah, it's common for beginners to over-use "mutable" types like atoms and refs when there are ways to avoid them
05:44dysfunand obviously while i'm making lots of changes, it's not very neat and tidy :)
05:45dysfunwhich reminds me, i need to finish porting midje to cljs
05:45jellytuxI coded a bit in Rust, and stumbled upon that problem myself
05:45tdammersTEttinger: depends on the beginner ;)
05:45dysfunheh, i actually prefer c++ over rust
05:46dysfunmodern c++ that is. c++11/14
05:46jellytuxI prefer both :D
05:46dysfungotta say i was pleasantly surprised
05:46dysfuni've been doing a lot of c++ (desktop client) work recently and modern c++ is much more enjoyable than old skool c++
05:47dysfuni was also surprised to enjoy it so much after doing so much clojure
05:48tdammersmodern C++ feels a lot like Haskell to me, in many ways
05:48dysfunmaybe once you decide syntax doesn't matter and just go with the way the language encourages, you attain enough enlightenment to not care and just write code :)
06:02jeaye_,{:a :b (when true {:c :d})}
06:02clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
06:02jeaye_Is something like that possible?
06:02jeaye_Where some expression within a map literal can return a new key-value pair for the map.
06:03jeaye_Sure, I can wrap it in a let, destructure, etc, but I'm wondering if some inline way of doing this exists.
06:03MJB47i think because if it was (when false ...) it would return nil
06:03MJB47and obviously you cant have {:a :b nil}
06:03jeaye_mmm
06:03MJB47might be possible with a macro?
06:04ridcully_,(cond-> {:a :b} true (assoc :c :d))
06:04clojurebot{:a :b, :c :d}
06:04jeaye_,(doc cond->)
06:04clojurebot"([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression."
06:05jeaye_ridcully_: Neat! Thanks.
06:21daveauhi all. Is there a standard way to convert a sequence of numbers (could be bytes or ints e.g. [255 -11]) to a string (e.g. like using (apply str (map char [255 -11])) but char -11 fails) ?
06:21daveauI can do (String. (byte-array [255 -11])) - but seems wrong. Just wondering, is there a more clojury way of doing this?
06:28jeaye,(apply str [1 2 3 4 -11])
06:28clojurebot"1234-11"
06:29jeayedaveau: What output are you expecting? -11 isn't a valid char.
06:29MJB47he said -11 should fail
06:29daveausorry. -11 should not fail
06:29MJB47oh i missread
06:29MJB47my bad
06:29jeayedaveau: Ok, what do you expect -11 to output?
06:30daveaui can't copy in the character, but an extended ascii/utf-8 character
06:31daveauso [255 -11
06:31daveau*so [255 -11] would be a two character string.
06:31jeayeSo you're expecting these to be multi-byte UTF8 chars?
06:32daveauno, a string with two single utf8 chararacters.
06:32daveausame output as (String. (byte-array [255 -11]))
06:33daveauthis works, i just thought I was doing it wrong...
07:00jeayeRaynes: ping
07:16jonathanj,(conj {:a :b} (when true {:c :d}))
07:16clojurebot{:a :b, :c :d}
07:17jonathanj,(conj {:a :b} (when false {:c :d}))
07:17clojurebot{:a :b}
07:24jeayejonathanj: Nice!
07:24jeayeEven simpler.
07:25jeayeActually, not much simpler in practice. http://dpaste.com/15QFTC7
07:25jeayeSimpler to understand, I think.
07:26jeayeAh, typo
07:26jeayeBetter http://dpaste.com/041YQ1W
07:31ridcully_another option would be `merge` - which basically is a conj, but "sounds" better
07:35jeayeI'm currently seeing an issue with Raynes' fs lib, where touch doesn't properly set the modification date.
07:36jeaye(fs/touch "meow" (+ (System/currentTimeMillis) 3600000))
07:36jeayeShould be an hour in the future
07:47jeayeUnfortunately, the modification time remains the creation time.
07:47jeayeAh, only when creating.
07:48jeayeIf the file already exists, it behaves as expected.
07:48jeayeRaynes: ^^
11:47irctcWhere are clojure jobs?
11:47irctcI need one.
12:03kwladykairctc i guess in USA and UK ;)
12:14Kamuelakwladyka: where? lol
12:15kwladykaKamuela i guess in the Internet. Anyway there are much more job offer in Clojure then in east europe.
12:15cortexmanis there a way to get this REPL version of fib working in a loop? https://gist.github.com/brianmingus/58fa0ac88161abdbb52e
12:16justin_smithcortexman: would make more sense to do it as a lazy-seq, but yes
12:17cortexmanjustin_smith, i can't get it to work. seems that it can't access *1 and *2 inside a loop
12:17justin_smiththose are special repl values, you have to change that part
12:17cortexmani'm trying to use those.
12:17justin_smith,((fn fib [a b] (lazy-seq (cons (+ a b) (fib b (+ a b))))) 0 1)
12:18clojurebot(1 2 3 5 8 ...)
12:18justin_smithcortexman: those are only useful in the repl
12:18justin_smiththey literally are defined only by the repl
12:19justin_smiththe above lazy-seq uses arguments to hold the last two results
12:19justin_smithI know it doesn't look the same, but it's the same flow
12:20justin_smithit would be easier to read using loop maybe, but then you need to decide when it stops
12:20MJB47i get the feeling cortexman is doing it as an exercise, and not for actual code :P
12:21cortexmanyah
12:21justin_smithwell, exercise or not, *1 or *2 are not going to be helpful outside of the repl
12:24ShayanjmI'm building a 'distributed application' (i.e: 4 separate applications, all communicating via a few redis queues)
12:24Shayanjmare there any best practices on how to structure these types of applications in Clojure? Should they be compiled as a single jar and run with options? Or should they be 4 distinct applications (4 jars)?
12:25justin_smithShayanjm: how distinct are the servers?
12:25Shayanjmjustin_smith: they're 4 components to a whole, essentially. There's something that generates a lot of data that then needs to be processed/consumed by the other components
12:26justin_smithShayanjm: no harm in sharing the same codebase and having a different -main for each
12:26justin_smithShayanjm: then you can launch with java -cp uber.jar clojure.main this-main.ns
12:26ShayanjmCool, I'm assuming there are no performance impacts unless I load a bunch of stuff I shouldn't inside those -mains
12:27Shayanjmmaybe just start up performance impairment
12:27Shayanjmbut not run time, right?
12:27justin_smithShayanjm: the perf impact would come with loading, if you don't load the other namespaces they won't have much effect
12:27justin_smithnot even startup, if you don't load them
12:27ShayanjmAwesome
12:27Shayanjmalso, on that note - any best practices on the actual distribution architecture?
12:28justin_smithShayanjm: clojure doesn't eagerly load every namespace it could (though you probably already know this)
12:28justin_smithShayanjm: logging, lots and lots of logging
12:28Shayanjmi.e: is it efficient to be running like 4 of the same clj processes at a time as 'workers'?
12:28justin_smithotherwise you'll have no idea what is happening when things break (and during dev things will break)
12:28Shayanjmor should that be handled by threading inside one such process?
12:28justin_smithShayanjm: that really depends on the job!
12:29justin_smithis it network bound, cpu bound, memory bound?
12:29Shayanjmah sweet, so the same tradeoffs as the rest of the programming world :)
12:29Shayanjmwas just wondering re: overhead of running multipleinstances of the JVM
12:29justin_smithright - but if you use threads, use real thread pools. Claypoole is a great lib for this
12:29Shayanjmsweet, thanks
12:29justin_smithShayanjm: it's not helpful to have more than one jvm on a box, but it's very helpful to have more boxes
12:30justin_smithduring dev you probably want more jvms on one box just so you can control them all
12:30ShayanjmYeah
12:30Shayanjmbut production should be 1 jvm per box with multiple threads?
12:31justin_smithShayanjm: consider kafka - I know you mentioned redis, but kafka has some nice properties (including the fact that the message queue doubles as a log which is great when things go bad)
12:31Shayanjmoooh that does sound nice
12:31justin_smithShayanjm: exactly. And backpressure / pool sizes to keep within the limits of that box.
12:31Shayanjmyeah I'm not sold on redis by any means, it just seemed like an easy solution
12:31justin_smithkafka plus transit for encoding the messages has been awesome in my distributed app
12:31Shayanjmfantastic, I'll probably just throw all of those into like a config.clj or something
12:32Shayanjmwhat type of message encoding have you needed?
12:32justin_smithI just blindly throw data into transit mostly
12:32justin_smithand get regular clojure out the other end
12:32Shayanjmlmao awesome
12:33Shayanjmthat sounds ideal tbh
12:33Shayanjmi'm going to look at kafka + transit
12:33justin_smithit's worth it, yeah
12:33Shayanjmthanks justin_smith
12:34justin_smithone bonus of kafka being a log based queue: when boxes fall over, other boxes can easily grab the messages those boxes were handling
12:34justin_smithShayanjm: np! this is like most of the hard stuff with the app I've been working on, so there's lots I could say about it :)
12:35Shayanjmjustin_smith: I had to do something similar in an earlier application, but it wasn't quite as distributed as this
12:35ShayanjmI could get away with throwing everything into a single queue and consuming from STDIN/STDOUT
12:35Shayanjmbut this particular application will need some level of performance guarantees + searchable history
12:36Shayanjmso +100 for kafka :) Thanks again for the suggestions
12:36ShayanjmWill probably be back to pick your brain later tho
13:36justin_smithI don't know why it took me this long to do it, but I just made an uberjar with clojure 1.8. plus pomegranate for resolving deps (and a helper function that automatically adds clojars to the repos). If your list of deps is fairly short this seems like the ideal thing for clojure with any deps you might need usable in a script
13:37justin_smithI would have used alembic (which is slightly friendlier) but it bails out if it can't find a project.clj
14:06Shayanjmjustin_smith: which kafka wrapper do you use?
14:07justin_smithShayanjm: clj-kafka, but I mostly use kafka directly (since it's a scala / java project) and just use a few of their helper functions
14:07Shayanjmgotcha
14:17Shayanjmjustin_smith: another one off question... What's the overhead of a read against Kafka? i.e: if I want to verify that the data in question is not actually a duplicate of something (recently) previously processed, would that verification step be better done by keeping an up-to-date atom in memory than against kafka itself?
14:21l1xhey guys
14:21l1xwho can you override this? https://github.com/damballa/abracad/blob/master/src/clojure/abracad/avro/util.clj#L5
14:22justin_smithShayanjm: Kafka ensures that a given consumer only gets each message once, I've never seen any issue with this. For a cluster I just make sure all servers are in the same consumer group, and that way each message will go to one server.
14:23Shayanjmjustin_smith: Right, my specific usecase is in scraping. Between scraping intervals I can't guarantee that the site in question has infact changed
14:23Shayanjmand I don't want to be spinning the wheels more than necessary
14:25l1xjustin_smith: strictly speaking with 8.x if the consumer crashes before it could commit the offset that caused the crash it will receive it again
14:25justin_smithl1x: aha, that makes sense - there's no such thing as "exactly once" in distsys after all
14:26justin_smithl1x: but in practice I've found this a small enough concern compared to other bugs introduced by my own code that it's pretty far down the list
14:29l1xyeah theory vs practice :)
14:35blake_So, I'm about to move my server-side rendering to client-side with reagent.
14:35blake_Where previously I sent the client HTML, I'm now going to send a data structure.
14:35blake_And I'm going to make a reagent function that renders that structure, as it would've been in the HTML.
14:36blake_Every time there's a change, the server sends a new structure, and the client renders it.
14:36blake_And this will be faster because...React compares the renderings, not the data structure. And in fact isn't even aware of the data structure (except, I guess, as an atom whose state changes).
14:36blake_Is that about right?
14:36justin_smithsounds about right, though sometimes it's easier to just send the differences and merge them on the frontend
14:37justin_smithblake_: err, that last part - react compares the data structures not the rendered result, so you have that backward
14:37blake_Hmm. Not sure I'm going to know what the differences are.
14:37justin_smithblake_: for immutable data, the comparison is especially fast
14:37justin_smithblake_: look at the code that changed the data?
14:37justin_smithblake_: though that doesn't work in all apps of course
14:38blake_justin_smith: Heh. It's POI. So sorta a black box, though I do have some code to test dependencies. (Which wasn't easy to get.)
14:38blake_justin_smith: But the structure comes from the server side, and must, so how is the data immutable.
14:38blake_I mean, if I'm swapping out the whole structure every time?
14:38justin_smithOK in that case it probably won't be incremental updates then (most apps would have some kind of incremental change)
14:39blake_Well, they are incremental in fact, but not to me. Or not easily to me. So...will it really be faster?
14:39justin_smithblake_: just like in any other usage of an atom, the atom is mutable, the data inside is immutable
14:40blake_So, let's say my data structure is a list of the words in a dictionary.
14:40justin_smithblake_: the key is that react can quickly go through the data structure, if it knows it changed, and figure out which subkeys are equal (no need to update) and which are no longer equal (need update)
14:40blake_Which I've retrieved from the server.
14:40blake_And then I ask the server for the list again, and it's exactly the same but for one new word.
14:41justin_smithblake_: OK
14:41blake_With regular Clojure, I'm using the same underlying reference. The tree shares actual branches.
14:41blake_But here I'm getting the list from the server--it's essentially a copy.
14:42justin_smithblake_: if the list is rendered as a list (eg in a table or ul), react will ask you to put a unique key on each item (which can be the word itself), that way it knows what needs update in the list and what is unchanged
14:42justin_smithit doesn't need to be the same Object, having the same structure suffices (though having the same object is faster of course)
14:45blake_OK, the key thing...that's probably what I'm missing.
14:45blake_But it does seem like it's comparing the rendered form to me. Not the actual rendered form on-screen but the underlying DOM. Which maybe calling a "rendering" is confusing. =P
14:46justin_smithno, the point of react is to touch the dom as little as possible
14:46blake_But it does this by having a shadow DOM, right?
14:47justin_smithso it has the dom (what the browser actually renders), the input data (not shaped like the dom at all), your components (which take input data and render something shaped like the dom) and the last version of the input data
14:47justin_smithit compares the last version of the input data to the new version of the input data. Where they differ, it updates the shadow dom, and that is propagated to the dom
14:48justin_smithit doesn't need to compare anything to the dom, because the dom won't have changed
14:48justin_smithand in fact if you change the dom yourself, react just throws an error and says "you broke it"
14:49justin_smithmore or less
14:49justin_smith(for those parts of the dom it actually watches / updates)
14:49blake_Well, sure.
14:50justin_smithblake_: so nothing gets compared to the dom, it compares the data to the new data, that decides which components are re-rendered, and that updates the shadow-dom
14:51blake_OK, so in my case, I'll need a table rendering but also a cell rendering, so that it can update the individual cells rather than the whole table every time, I'm thinking.
14:52justin_smithblake_: sure, if you put the right :key metadata on the cells, it should be able to handle that intelligently (at least that's how it works in reagent, which is the wrapper I have experience with)
14:52blake_justin_smith: Reagaent has been the most approachable for me.
14:53justin_smithblake_: it basically uses the :key to know the difference between "cells changed order" and "cells changed value"
14:53blake_And I was planning on have the server send vectors (rows) of maps (cells), where the contents of each cell are style and value.
14:54justin_smithmakes sense - then you could key on style and reagent should be able to do the rest
14:54blake_Well, I was going to key on the cell address. Could I key on the style if the style is shared between more than one cell?
14:55justin_smithoh, then you do need to key on the address I guess
14:56blake_Yeah, a lot of style sharing. The styles are in the CSS, which is generated for the whole thing up front. Though thinking about, I'll probably have to have local overrides.
14:59blake_Are Reagent components atomic?
15:01Shayanjmamalloy_: strong work on ring-buffer, super helpful
15:01Shayanjmreally nice to use too - works exactly as you would expect it to
15:15spuzis it possible to desctructure the parameter of an anonymous function?
15:17scottjspuz: not in #() literals, but in (fn [...]) yes
15:17Glenjamin,((fn [[a b c]] (str a b c)) ['y 'e 's])
15:17clojurebot"yes"
15:18spuzscottj, thanks scottj. I was thinking about #() literals specifically
15:18spuzis there a name for #() vs fn ?
15:18Glenjaminfunction shorthand, i guess
15:18scottjspuz: anonymous function literal and fn
15:18spuzthanks
15:19scottjspuz: #(let [[a b] %] ...)
15:21scottjspuz: #(let [[arg1 [arg2-a arg2-b]] %&] ...)
15:21Glenjaminalthough i'd argue at that point (fn) is preferrable
15:21scottjGlenjamin: agreed
15:24Bronsa`everytime I need to write more than one % I switch to fn
15:41adam____hey how do I make a function which takes a map but requires that the map which is being passed in has certain keys?
15:41adam____like is there a way to catch that at compile time?
15:41adam____or can people pass in whatever and then if the map doesnt have the key it will just give me nil
15:48base698_it's probably one line. use keys
15:49base698_and contains?
15:49base698_Adam ^^^
15:53rcassidyaw, he left.
15:53rcassidy,(defn key-stuff [{:keys a b}] (str a b))
15:54clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
15:54rcassidy,(defn key-stuff [{:keys [a b]}] (str a b))
15:54clojurebot#'sandbox/key-stuff
15:54rcassidy,(key-stuff {:a "hi" :c "nope"})
15:54clojurebot"hi"
16:11SomelauwWhy does core.matrix have both mul and emul? https://mikera.github.io/core.matrix/doc/clojure.core.matrix.html
16:20amalloyi'm glad to hear that, Shayanjm
16:22justin_smithyeah, you can't enforce keys of the input to a function at compile time because you don't know the keys of the input at compile time
16:27olieideli'm having problems joining the clojurians slack channel. it says already invited but i never got any email. is this a common problem?
16:29amalloyirc is secretly where all the cool kids hang out anyway
16:33justin_smith~irc
16:33clojurebotirc is only for opionfests
16:33justin_smith~slack
16:33clojurebotslack is where all the cool kids went.
16:34blake_clojurebot is committed to the lie.
16:34amalloyopionfests, huh?
16:35hiredmanthat quote should be attributed
16:35hiredman-- rhickey
16:35justin_smithamalloy: like oktoberfest but much sleepier, I imagine
16:35amalloywell rich probably spelled it right. or did he not?
16:35hiredmanno idea
16:53gfrederickstcrawley: I bet you were hoping somebody would ask a question about immutant 1.1.4
16:53gfrederickscan I be that somebody for you?
16:55ShayanjmIf I have a collection like '([1 2 3] [4 5 6] [7 8 9]) - how do I combine all the elements in the collection to result to [1 2 3 4 5 6 7 8 9]?
16:55Shayanjmis there a nice idiomatic way to do it?
16:55justin_smithShayanjm: apply concat
16:56justin_smith,(apply concat '([1 2 3] [4 5 6] [7 8 9]))
16:56Shayanjmjustin_smith: you are my hero today
16:56clojurebot(1 2 3 4 5 ...)
16:56justin_smithShayanjm: with great knowledge of clojure trivia comes great responsibility
16:57justin_smithShayanjm: also, if you preferred a vector, reduce into would work there too
16:57justin_smith,(reduce into '([1 2 3] [4 5 6] [7 8 9]))
16:57clojurebot[1 2 3 4 5 ...]
16:57justin_smithbut reduce into will not do what you want if the first item fails to be a vector
16:57justin_smith,(reduce into '((1 2 3) [4 5 6] [7 8 9]))
16:57clojurebot(9 8 7 6 5 ...)
16:57Shayanjmah
16:57justin_smithso apply concat is in that sense more general
16:58Shayanjmthat makes sense
16:58amalloyjustin_smith: reduce into []
16:58justin_smithamalloy: oh, true
16:58amalloyi would never count on the first to be a vector, really
16:58justin_smith,(reduce into [] '((1 2 3) [4 5 6] [7 8 9]))
16:58clojurebot[1 2 3 4 5 ...]
16:58tcrawleygfredericks: I'm all ears!
16:59amalloyit's been a long time since i used reduce's 2-argument flavor for real code
16:59justin_smithamalloy: I guess 3 arg is almost always better, since you would usually know what kind of structure you are building
16:59ShayanjmIs there any significant difference between (into [] (apply concat ...)) vs. (reduce into [] ...)?
17:00justin_smithShayanjm: yes, the reduce into does less work
17:00Shayanjmawesome
17:00justin_smithShayanjm: since with concat you build a strucure of one type, then empty it into a structure of another type (vs. simply filling a structure of the type you wanted from the start)
17:01ShayanjmThat makes sense
17:01ShayanjmI really should do some research on these actual implementations
17:04gfrederickstcrawley: I'm wondering how difficult and/or impossible it is to have various web apps deployed at the root with different ports to differentiate them
17:05tcrawleythat's only possible if you 1) run multiple immutant 1.x processes, or b) deploy apps that start their own webservers within the container on other ports (i.e. jetty, immutant 2, etc)
17:06tcrawleyboth are !good options
17:06tcrawleyiii) use a proxy in front of immutant that maps ports to context paths
17:06gfrederickstcrawley: ACK thanks
17:06tcrawleymy pleasure!
17:07gfrederickstcrawley: does immutant 2 support this better?
17:08tcrawleyyes, with immutant 2, you can start up multiple undertow servers on different ports, but since you have different apps, it would probably be better to run each as a separate process, on a different port
17:08tcrawleyif you deploy Immutant 2 apps to WildFly, you're back in the same situation as Immutant 1
17:08gfredericksoh gotcha okay cool ACK ACK
17:08gfrederickswe can't inc people anymore can we
17:09gfredericks(inc tcrawley)
17:09amalloyyou can (dec lazybot) though
17:09gfredericks,(def karma (atom {}))
17:09amalloyin memoriam
17:09clojurebot#'sandbox/karma
17:09gfredericks,(swap! karma update 'tcrawley (fnil inc 0))
17:09clojurebot{tcrawley 1}
17:09tcrawleyha
17:13gfredericks~immutant |runs on| wildflower
17:13clojurebotYou don't have to tell me twice.
17:19WorldsEndlessFor interop purposes I need to un-lazy a seq, but doall doesn't seem to work
17:19WorldsEndless(type texts)
17:19WorldsEndlessclojure.lang.LazySeq
17:19WorldsEndlessturbo-tenure.users> (type (doall texts))
17:19WorldsEndlessclojure.lang.LazySeq
17:20hiredmanthe type of the seq there has nothing to do with if it has been forced
17:20hiredmanwhy do you think you need a non-lazy seq for interop?
17:20WorldsEndlessI'm trying to call a java function upon the array, but it isn't an array but a lazy seq (at least, that's how I'm interpreting the error)
17:21hiredmanseqs (lazy or not) are not arrays
17:22WorldsEndlessAh. That would be it
17:22hiredmanif you need an array, you need to make one and copy the data from the seq you have in to one, there are some functions for this kind of thing, they generally have "array" in the name
17:22WorldsEndlesst-oarray
17:48spuzis there an equivelant of java.util.List.indexOf for vectors?
17:49justin_smith,(.indexOf [:a :b :c] :b) ; yes
17:49clojurebot1
17:49justin_smith,(instance? java.util.List []) ; spuz - furthermore
17:49clojurebottrue
17:50justin_smithso it has an equivalent to indexOf because it is a List so it has indexOf
17:50spuzjusticefries, thanks is that the recommended way to find elements in a vector?
17:50spuzbecause it seems it wouldn't work in clojurescript as it relys on java interop
17:50justin_smithspuz: if you want to know the index of the equal item, sure
17:51justin_smithspuz: true
17:51amalloyyou usually don't want to know about indexes
17:51spuzi want to find the index because i need to find neighbours (this is for a soduku solver)
17:53MalnormaluloIs a vec here representing a row/column?
17:53spuzyes
17:53hiredmana vector is like a data structure that indexes entries by a single key, which is a number which is the index, what you want is a datastructure that indexes entries multiple ways, so you can look up entries via an index, and lookup indices via an entry
17:53justin_smithspuz: alternatively you could have a bimap from number to position
17:53MalnormaluloMaybe you need to rethink your data structure. It's a sparse matrix -- should you have all those empty cells?
17:54justin_smithMalnormalulo: well eventually you would want to fill the sudoku
17:54spuzMalnormalulo, there are no empty cells, just incomplete cells
17:54MalnormaluloYes, but the constraints of sudoku mean you can just as easily map this the other way
17:55MalnormaluloNumber in the cell as key, location as value.
17:55justin_smithideally you map both, which is why I mentioned bimap
17:55spuzMalnormalulo, interesting
17:55Malnormaluloa bimap would also be useful, yeah
17:56spuzI'll think about using a bimap
17:56Glenjaminsudoku is actually a trimap
17:56justin_smithspuz: I don't know if it's in a lib anywhere, but there is this https://gist.github.com/semperos/3835417
17:56Glenjamin[x, y, z] => boolean
17:56justin_smithGlenjamin: oh?
17:57Glenjaminhttps://hal.archives-ouvertes.fr/hal-00641973/document
17:58Malnormaluloby trimap do you mean an omnidirectional map between sets of three related values, or a map where the key is a tuple of three values?
17:58Glenjamini should dig out my old sudoku visualiser and put it on github
17:58Glenjaminoh, i might have used the wrong term, i meant the latter
17:58hiredman,(doc clojure.set/index)
17:58clojurebotExcuse me?
17:58hiredman,(require clojure.set)
17:58clojurebot#error {\n :cause "clojure.set"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.ClassNotFoundException\n :message "clojure.set"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java....
17:58hiredman,(require 'clojure.set)
17:58clojurebotnil
17:58hiredman,(doc clojure.set/index)
17:58clojurebot"([xrel ks]); Returns a map of the distinct values of ks in the xrel mapped to a set of the maps in xrel with the corresponding values of ks."
17:58amalloyi think i might be some kind of mutant. i was in the middle of recording a keyboard macro in emacs, and suddenly my fingers started trying to use vimkeys instead
17:58Glenjaminoh, yeah, trimap isn't the right term
17:59justin_smithGlenjamin: yeah, the idea with bimap is it's one data structure where you can look up value and get position (if any) and look up position and get value (if any) without linear scans
17:59MalnormaluloYeah, here "bimap" is just meaning that the key and value each can be used to uniquely retrieve the other
17:59justin_smithright
17:59Malnormaluloshorthand for "bidirectional map"
17:59justin_smithGlenjamin: but now I really want to see a problem elegantly solved with a trimap
17:59spuz"We have fully clarified the symmetry relationships that exist between Naked, Hidden and Super-Hidden Subset rules (the latter being classically known as XWing, Swordfish, Jellyfish, Squirmbag and other existent or non existent "fishy patterns")"
17:59spuzoh man what did i get into here?
17:59Glenjaminbasically sudoku can be visualised as a cube
18:00Glenjaminand then you can view the same puzzle from a different side
18:00Glenjaminand see an equivalent puzzle
18:00Malnormalulothat makes sense
18:00Glenjamintreat each cell as a set of possible answers
18:00Glenjamina solved cell is a set of size 1
18:01MalnormaluloThat's hardcore combinatorial optimization, though. I suspect the problem here is less about deduping and more about just solving the thing.
18:03Malnormalulo(though I'm totally reading that paper later because heck yeah hardcore combinatorial optimization)
18:04spuzGlenjamin, that's pretty interesting. thinking of a soduku solution as 81 points in a 9x9x9 3d cube kind of makes sense
18:05Glenjaminwhen you "rotate", boxes become rows, rows become columns etc
18:05MalnormaluloHuh, under that model it's not unlike the n-queens problem
18:05Glenjaminit's NP-Complete, so equivalent to a bunch of stuff when generalised
18:05Glenjamin(i did my dissertation on sudoku)
18:06MalnormaluloWell, yeah. But usually the equivalence isn't so easy to see :P
18:07Glenjaminmy favourite one is bin-packing
18:07spuzGlenjamin, but what advantage does rotation give you? You can always solve a puzzle without rotation
18:07Glenjaminbecause it makes me feel like i'm solving some really complex puzzle whenever i go shopping
18:08Glenjaminspuz: it gives you a fresh perspective (literally), so your eyes get another look
18:08Glenjaminsome of the heuristic-based techniques are easier to spot than others
18:08spuzyeah i can see that
18:08Malnormaluloiiiiiiinteresting
18:08Glenjaminbrute-force-wise norvig's approach is pretty much the way to go
18:09Glenjaminbacktracking search with constraint propagation
18:09MalnormaluloOh man, I can almost remember what that means
18:09Malnormalulo(I need to review my into to AI course)
18:09spuzwell i'm coming at this just trying to impelement my own algorithm, but I've heard the core.logic solutions can be much faster than norvigs algorithm
18:10Glenjaminyou should end up with the same algorithm with core.logic - but expressed differently
18:10spuzi wonder why the performance would be different, let me see what i found earlier...
18:12spuzHere we go: https://news.ycombinator.com/item?id=4325746
18:13spuz"Norvig's hard one that takes 188 seconds in Python takes ~60ms (in clojure)"
18:13spuzobviously python vs clojure is not a fair comparison of the two algorithms
18:13Glenjamini would expect that to be the runtime, rather than the alg
18:13Glenjaminwill have a read
18:14Glenjamin> It's actually pretty simple. Most of the performance is from Clojure, the purely functional design which gives us backtracking "for free", and the random access nature of the constraint store.
18:15Glenjaminyeah, aiui it's the same alg, but with an optimised general constraint propagation + backtracking search system
18:16Glenjaminweird that i recalled all this pretty quickly after all this time
18:16Glenjaminfunny what sticks
18:19MalnormaluloI keep meaning to go back and re-implement the basic discrete search algorithms so I remember them better. At this point I'm probably going to have to relearn them entirely
18:21arryHi! How come lein uberjar with :aot :all doesn't compile all dependencies? I've excluded sources from uberjar, and it tells me that ring/middleware/multipart_params/temp_file__init.class isn't in the jar. (and it isn't)
18:21justin_smitharry: do you explicitly require its namespace in your code?
18:23justin_smitharry: ring is pulling some sneaky runtime bullshit https://github.com/ring-clojure/ring/blob/1.4.0/ring-core/src/ring/middleware/multipart_params.clj#L75 if you add an explicit requirement for that namespace in your code that will fix it
18:24arryI didn't require it explicitly
18:24justin_smitharry: right - look at my link, load-var requires the thing at runtime, aot has no way to know you needed it
18:24justin_smithso if you require it yourself that should fix the issue
18:25justin_smithit's ring'
18:25justin_smiths fault not yours
18:25arrynice, thanks
18:25arryit's cool to get help within 2 minutes of posting the question :D
18:26justin_smithheh, glad I could help
18:27arryis there a way to avoid recompiling sources that haven't changed? I've run `lein uberjar` for maybe 10th time today, with no code changes, and it gets tiring that it takes 5 minutes to compile everything
18:28justin_smitharry: do you have a reason to run uberjar other than deploying?
18:28arrysure
18:28arryto test the deployment :D
18:28arryi package the app, see if it works, it doesn't, i change stuff and repackage
18:29justin_smithjust saying it's easier to run a repl and just incrementally integrate your code updates in the repl
18:29justin_smithand interact with the app locally
18:29arryit works in the repl, but deployment options differ. For example, clojurescript stuff is different
18:30justin_smitharry: that's why one also compiles cljs in the repl (figwheel makes this easier but you can also compile from the repl and it does incremental building nicely)
18:30justin_smithor you can use the cljsbuild plugin for continuous auto-building
18:31arryyes, it does work in the figwheel and in the repl. But for production it has to be run with advanced compilation, and Figwheel choked on it when I changed the options to something other than :none
18:32arryAnother reason is that I try to trim uberjar size: it contains ridiculous amount of needless cruft - whole Bootstrap release package, Rhino, etc
18:32justin_smithyeah, figwheel can't do advanced, but the bugs caused by aot / advanced compilation (neither of which play nicely with incremental dev) are rare and eventually predictable
18:33justin_smithbut really no, I don't think there's a way to use lein uberjar that caches better than the current implementation, though perhaps there's room to make a better incremental jar building tool?
18:33justin_smiths/implementation/default - I am sure you could hack lein to do better caching
18:34arryI wish it were so. I tried to look in Leiningen source but it was so functional and pure that I didn't understand where stuff happens
18:34justin_smitharry: did you get as far as the uberjar plugin?
18:34arryI think so
18:34justin_smitharry: perhaps boot would be more to your taste
18:35arryyes, that's an option; and I seem to remember they had something about incremental compilation in a recent news item
18:36arrythough to be honest my priority is to get my site to public, so I have only time for complaining instead of fixing the infrastructure stuff :)
18:49amalloywhining-driven development
19:29bcoburnthe thing in Clojure where I maps/vectors are also functions is amazing. Might be the feature I'd miss most if I switched back to Common Lisp
20:10pilneclojure is much fun
20:11pilnealthough i've been intrigued by prolog lately
20:11pilneGuest71828-: it is not very safe to use a computer as administrator for general tasks. protip.
20:13pilnebut minikanren (core.logic) is something i've been reading up to on as well
20:55BRODUSi have a project where i need to create a simple tasks that starts a server and runs grunt watch, i know I could create a plugin to do this, but that seems overkill, does leiningen have another way to do this?
20:55BRODUSor do people normally write a shell script in this case?
20:56justin_smithBRODUS: lein-shell can make an arbitrary shell command into a lein task https://github.com/hyPiRion/lein-shell
20:56justin_smithbut if you are going to leave it running that means lein will have to stay running too of course
20:57BRODUShmm, shell script it is
20:57BRODUSbut thanks for the link,
21:53KamuelaDoes it make sense to design programs or think in terms of every outermost function is the one with side effects?
21:57LucidTortoiseIlearned something today. The iPad is way to small to serve a second screen.
21:58LucidTortoiseWell, it is great as long as you use any resolution below retina.
21:58LucidTortoiseThen you can actually read text!
23:24jklGh