#clojure logs

2015-08-31

00:00TEttingerthere's a lazy-cat?
00:00justin_smithTEttinger: have you ever seen a cat that wasn't lazy?
00:00justin_smith:P
00:00justin_smith(doc lazy-cat)
00:00clojurebot"([& colls]); Expands to code which yields a lazy sequence of the concatenation of the supplied colls. Each coll expr is not evaluated until it is needed. (lazy-cat xs ys zs) === (concat (lazy-seq xs) (lazy-seq ys) (lazy-seq zs))"
00:00TEttingerI mean, yes. I have a cat who was raised by dogs and thinks he is a dog
00:01TEttinger(plays with water, completely unafraid of almost everything, greets strangers instead of running like any other cat)
00:01TEttinger(doc reductions)
00:01clojurebot"([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."
00:03joness2i am not sure how lazy-cat works.. is it a macro that prevents strict evaluation?
00:03justin_smithjoness2: exactly - all laziness in clojure requires function indirection or macros that prevent evaluation
00:03justin_smithif you dig down deep enough at least
00:04Bronsaoh well
00:04Bronsalooks like direct linking is broken
00:04justin_smith?
00:04TEttingerBronsa: a grimoire thing?
00:04Bronsahttp://dev.clojure.org/jira/browse/CLJ-1809
00:04BronsaTEttinger wat
00:05BronsaTEttinger no idea why you thought of grimoire but it's about a new 1.8 feature
00:05TEttingeroh, sorry, I just saw "direct linking" and couldn't remember if you did grimoire or who else did
00:05BronsaI think I understand what's going wrong but it's a mess :/
00:06BronsaTEttinger ah, no that's arrdem
00:06TEttingerbrrnem
00:08TEttingerBronsa: when's 1.8 scheduled, is it on some sort of fast track relative to 1.6-1.7?
00:08BronsaTEttinger I seem to understand so, you'll have to ask puredanger
00:08BronsaI'm a mere contributor, not part of the core team that make such decisions :)
00:09TEttingerI don't really know what the new features are. If I had to guess, monaducers
00:09TEttinger"because monads and transducers are so hot right now"
00:10TEttingeris clojure in clojure off the target list?
00:10BronsaTEttinger cinc has never been an official target
00:11TEttingererr, maybe target is wrong word, goal to work toward?
00:12Bronsano official plans, just unofficial efforts
00:12TEttingerah ok
00:12Bronsa(mine :P)
01:00H4nswhat self-hosted CI tool do you recommend for clojure? i've been using jenkins, but it is so ugly. teamcity does not seem to offer anything specific to clojure, but it looks slightly better. anything else?
01:01justin_smithI've only used jenkins, it worked OK
02:07Jaood´œ∑´®†\üø¨ˆπåß∂∂ƒ©©˙∆˚¬…ææ
02:07Empperiexactly that
02:07EmpperiI agree 100%
02:08EmpperiH4ns: we use Jenkins and it's fine as long as you don't need full deploy pipeline management
02:08Empperiit *can* do that too but it's hairy
02:09Empperiplanning to move into Go CD
02:21H4nsthanks, justin_smith and Empperi - i guess we'll just put up with the ugliness and continue using jenkins. it works well for us, too.
04:50Rancid-punk2j Hi guys
04:50Rancid-punkWho is this man ? http://s22.postimg.org/cv0461qsh/Ratzinger_vreu7o.jpg
04:51BronsaRancid-punk: trolling is not welcome in this channel
06:58OlajydHi clojurians :)
07:01OlajydI’m having a little issue with using the clj-time, I tried using the t/after and t/before to check if a particular date falls within the range, but I’m getting this error: `No such var: clj-time.core/equal?` even after requiring the clj-time 0.11.0 in the project.clj. Any ideas?
07:01Olajyd:)
07:08oddcullyOlajyd: it might help, if you could provide a minimal failing example in a gist/refheap/...
07:08Olajydok
07:09Olajydin a min
07:13Olajydoddcully: https://www.refheap.com/109013
07:15OlajydAlias for clj-time.core is `t` and alias for clj-time.format is `tf`
07:22oddcullyOlajyd: without trying anything, the first two things: a) why do you not use t/equals? (most likely not related to the error) and b) equal? was added in 0.10.0
07:28Olajydok
07:28Olajydodccully , got it now, bumped the version to 0.10.0 and it worked
07:29Olajydwas previously 0.9.0
08:20noncomis there any library that can generate a webform for a clojure map that is required to be filled?
08:20winksounds like an ace idea :P
08:21noncomheh :)
08:30oddcully(map #(str "<input type=text name=" % "/>") (keys themap))
08:37noncomoddcully: nice start that would be! :)
08:42neurostormlein repl does not seem to find my resources/log4j.xml file. several warnings are issued. should anything be added in the project.clj file except the dependency?
08:43oddcullynoncom: since this is a little splitted between here and #clojurescript. above is not ordered
08:44noncomneurostorm: lein resource-paths? https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L160
08:45noncomneurostorm: this level is better for you, i think: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L281 (or maybe not)
08:48neurostormthanks!
08:58neurostorm(.exists (clojure.java.io/file (clojure.java.io/resource "log4j.xml"))) ; reports true, but still i get:
08:58neurostormlog4j:WARN No appenders could be found for logger (io.netty.util.internal.logging.InternalLoggerFactory).
08:58neurostormlog4j:WARN Please initialize the log4j system properly.
08:58neurostormlog4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
09:01neurostormok, seems to be a error in the xml. sorry
09:03crazydiamondHi. If I need to have map with like 10 mln keys, would be in-memory Datomic DB more performant than just Clojure map?
09:07crazydiamondJust got java.lang.OutOfMemoryError: GC overhead limit exceeded O_o
09:11cenzhehi guys
09:11cenzhewhat is the most effective way to keep a thread-safe count
09:12cenzhemy attempt now is: (def a-cache (atom {}))
09:12cenzhe(def inc-base-0 (fnil inc 0))
09:12cenzhe(defn record-one [n] (swap! a-cache update n inc-base-0))
09:14cenzhebut the performance is not satisfactory. I got the code embeded in my program, takes an extra 2 seconds to complete, and this routine get called around 550k times
09:15cenzheI guess I need to avoid the boxing and unboxing of the count? like how?
09:16expezcenzhe: perhaps keep the count with an agent
09:16cenzhecool idea
09:16cenzheI'll add that in
09:17cenzheanything else?
09:17noncomcenzhe: also, for things you need to do really fast, it is possible to use some direct java code. like you could have your counters written in java
09:17noncomas for the agent - i am not sure. agents are not guaranteed to be synchronized. of course in this case the count addition task likely won't take long, but you're walking thin ice..
09:18cenzhenoncom: I believe clojure can do things just as fast as Java with careful coding and proper optimization techniques
09:18cenzheMe wrong?
09:18noncomcenzhe: another option would be to restructure your code. perhaps having a global count variable is not what you really need here. so, it will depend
09:19noncomcenzhe: in most cases, yes. but sometimes it is worth to write some 10 lines of java and be as fast as possible than have unstable or ugly clojure code that only tries to approach the same speed
09:21noncomcenzhe: as per your mentioned "proper optimization and careful coding" - i was referring it when i said that probably you could restructure your program to avoid the global counter
09:21cenzheI don't quite follow the "global counter" part
09:21cenzhenoncom: what are the other alternatives?
09:22noncomcenzhe: you're keeping a counter, am i not right? here's your original question: "what is the most effective way to keep a thread-safe count?"
09:22cenzheyes, actually a handful of counters
09:22noncomcenzhe: an alternative would be to include then in a (let ...) of a higher function
09:22noncomi cannot say more since i am not fully aware of your scenario
09:23cenzhenoncom: I guess this is to avoid the var deref cost, right?
09:23noncomright
09:23noncombut i am not sure it is applicable to your scenario
09:24noncomif you call the function on an external stimuli, like a key press, then you have to keep something global so the state can persist across the key presses
09:24cenzhethat seems to be possible, but I haven't tried this before, not sure how much boost I'll get
09:24noncomso, 1) java code, 2) include in a let of a higher function 3) use an atom.
09:25noncomif i'd care for speed, id use 1 :D
09:25cenzhe:D thanks for the leads
09:26cenzheI just realize that my CPU are mostly occupied, the agent method may not work actually
09:26cenzheI'll try the let first, and see how far that goes
09:46noncomcrazydiamond: that's too much. although you could tweak JVM to get that heap... bu
09:46noncomyou said 10 mln objects, you really need a db
09:46noncomcoz
09:46crazydiamondnoncom, yep, I realized that. thanks
09:47crazydiamondHi all. How do I sent Clojure vec like ["foo", "bar"} via Clojure JNA to C function that excepts char** ?
09:47sdegutisI'm writing a blog post on mutability in Clojure's core, and I thought a sanity check would be prudent. Is there anything wrong with my conclusion, that Clojure inherently (and unidiomatically) relies on mutability for making defmulti/defmethod work?
09:48spacepluksdegutis: I think all vars are mutable
09:50sdegutisBut typically the community's agreed-upon idiomatic style is to write a var declaratively and pull it into the namespace that requires it.
09:51sdegutisIn this case, the namespace defining the defmulti would then be required to :require the namespaces that have the defmethods.
09:51sdegutisExcept that severely limits the "extensibility" of defmethod itself, since the creator of this "interface" is then required to know all the implementors.
09:52sdegutisSo the only way to keep that extensibility is to *force* the implementation of these two methods to rely on mutating the defmulti whenever it comes across a defmethod.
09:57spacepluksdegutis: why do you need to require the implementors namespace? :?
09:58sdegutisspacepluk: If you write a defmulti, and a defmethod in another namespace, but never require that namespace, then calling the defmulti with the dispatch-value used in that namespace will result in a no-matching-whatever error.
09:58spaceplukI mean the side exetending the multimethod requires the multimethod, I think that's ok
09:58spaceplukI see
09:59spaceplukbut in a real usecase you'd be using the extender namespace I think
09:59spacepluks/using/requiring/
10:01spaceplukI'm still learing clojure though, I might be missing something
10:01spaceplukn
10:01sdegutisWe had a bug in our system a few years ago because we were using a web framework that required the namespace needed based on the request being made, so sometimes the ns with the extender wasn't required for quite a long time. It caused a lot of bugs that took us a while to figure out.
10:02spaceplukyeah, extending types is a lot like monkey-patching
10:02spaceplukit's probably not a good idea to do it dynamically at runtime
10:02sdegutisThat's what I'm saying though, all extending of types currently happens at runtime.
10:03spaceplukyup
10:03sdegutisThe problem only happens when you try to require namespaces at runtime instead of inside (ns (:require ...)).
10:03spaceplukwith runtime I mean after the app starts
10:03sdegutisAh right.
10:04spaceplukthese are the "cons" of dynamic languages I guess :)
10:06zetlenhey folks. is it frowned upon to try and ask questions in #clojure-beginners and here at the same time?
10:11sdegutisgo for it
10:20sdegutisDear Emacs users in here: what Clojure packages do you use?
10:38troydmcan anyone suggest core.logic tutorial?
10:48ryuoi have been considering the merits of various Lisp dialects. is there some reason to prefer closure to others such as common lisp or scheme?
10:50blkcatjvm integration would seem like a pretty major one
10:51opqdonutI love the persistent built-in data structures
10:51opqdonutand the parallelism and concurrency stuff
10:51ryuoby persistent, you mean how some Lisp implementations can save machine state to be reloaded later?
10:52opqdonutno
10:52opqdonutI mean that the structures are immutable (but efficient)
10:52opqdonute.g. adding an element to the end of a vector gives you a new vector
10:53opqdonutmeans you don't need to worry about leaking references to your private structures, or insert deep copies everywhere
10:53spaceplukyeah, I really like that too
10:53spaceplukand jvm/js interop is a big plus
10:54spaceplukI also like the syntax sugar for the different data structures
10:54spaceplukhardcore lispers would disagree I guess
10:55ryuoi come from the world of low level C. i've been trying to break into functional, but Lisp is somewhat confusing to navigate in terms of where I expend my efforts.
10:55ryuoI should*
10:56opqdonutyeah it's not easy
10:56spaceplukif you're trying to interop with c code gambit or chicken might be better for you
10:56spaceplukthere's clojure-terra but it's not finished
10:56opqdonutfor getting stuff done you could look at clojure, but if you don't need the jvm or want to learn an "authentic" lisp go for some scheme variant
10:57ryuoHm.
10:58opqdonutbut it doesn't really matter, it's easy to transition from clojure to scheme or vice versa
10:59opqdonutjust do something and see what happens
11:00spaceplukyup, switching from low-level to a functional style is the hard thing to do
11:02spaceplukmaybe lua might help there, it's pretty much scheme with syntax
11:03ryuoi was thinking it wouldn't be too bad, considering i have a talent for abstract math...
11:04ryuohm.
11:05spaceplukit's not too bad, just try to make something :)
11:06ryuoC did teach me that it is important to know a great deal about language nuances.
11:07ryuoif you want to use it to do a lot of programming at least.
11:07spaceplukthe good thing about lisps is that the language itself doesn't have a lot of nuances, it's as simple as it gets.
11:08ryuothe rest is grasping the sheer flexibility you have?
11:08spaceplukyes hehehe
11:08spaceplukdo you have any specific needs? or is it just for learning?
11:08ryuowell, i was wanting to learn a higher level language of the Lisp family to use for developing a MUD server's content.
11:09ryuoi was thinking C is a poor choice here due to the higher development costs.
11:10ryuoit takes longer to make anything useful with C. you have to implement a lot of support code before you get to the real content.
11:10spaceplukclojure sounds like a good fit for that
11:12ryuois it still possible to draw from C libraries? i was planning to at least use C libraries to handle networking, unless java has some telnet lib.
11:12spaceplukI'm sure there are some
11:12spaceplukyou can use JNI or JNA for the c code but it's not fun
11:14spaceplukor maybe this -> https://github.com/bagucode/clj-native
11:14ryuookay, then is there some recommended reading for a through introduction to clojure? oreilly has a number of books but
11:14ryuothorough*
11:14ryuosome appear to be for advanced topics in clojure.
11:15ryuoi still plan to write C code, but i need to also learn to use higher level languages.
11:15ryuoi can't limit myself to only low level. that's how i feel.
11:16spaceplukI read these: http://www.braveclojure.com/ https://www.manning.com/books/the-joy-of-clojure-second-edition
11:17spaceplukI think you might like lua, it's very easy to interact with c code and you can write functional code with it
11:17ryuoone other question. how stable is clojure for API? i'm used to C where APIs typically remain the same indefinitely.
11:17spaceplukspecially luajit's ffi is great
11:17spaceplukI think clojure itself is pretty stable
11:17ryuoat least for ISO and POSIX.
11:17ZimaBlue`ryuo: I wouldn't recommend Joy Of Clojure, I read that already knowing bits about FP and found it way too hard. Probably the hardest textbook I've ever read. braveclojure is a good intro and currently enjoying "clojure programming"
11:19ryuoZimaBlue`, I assume you had experience with non-FP before?
11:19ryuoi've used C for the last 7 years and enjoyed it, but i need something more.
11:19ryuoshell scripts only go so far as well.
11:20ryuohm.
11:21luxbockryuo, you could also look at Racket
11:21luxbockI haven't really used it much, but my impression is that it has an easier FFI support than Clojure
11:22ryuoso many Lisp implementations. -head explodes-
11:22ryuohaha
11:22spaceplukheheh
11:22spaceplukryuo: you can also go this way http://www.buildyourownlisp.com/ :D
11:22luxbockJohn Carmack is using Racket to script his VR work
11:22ryuomaybe it would be best if i just studied what Lisps have in common.
11:23ryuofor now. i wonder if there is a book for that. =p
11:23ZimaBlue`the original paper by mcarthy
11:23ZimaBlue`called something like recursive functions of symbolic expressions
11:23ZimaBlue`http://www-formal.stanford.edu/jmc/recursive.pdf
11:24luxbockalso, Structure and Intepretation of Computer Programs, which uses Scheme (which Racket is a dialect of)
11:25ryuoah.
11:25ZimaBlue`it's pretty readable, I think I read that the compiler code in it has a couple of issues but you get the idea. Also halfway through he gets bored and invents GC
11:25spaceplukI think you'll learn more effectively if you can apply the stuff to real projects you're working on, that's what made it for me with lua/js
11:25spaceplukyou see the benefits immediately
11:26ryuothat's the funny thing. it took me years of writing stupid things before I was good enough with C to do anything productive.
11:26ryuoI was used to high level doing so much implicitly.
11:26ryuohaha
11:26luxbockI have also heard many people praise this book http://www.ccs.neu.edu/home/matthias/HtDP2e/
11:27luxbockbut I haven't read it myself, it's on the TODO list :)
11:27spacepluklittle schemer is also very cool
11:27spaceplukand it's an easy read
11:27luxbockyeah, very funny as well
11:27ryuothe best application i've found for C was optimizing tasks that i couldn't find another way to speed up.
11:28spaceplukc is good for using c libraries hehe
11:28spaceplukare you familiar with oop?
11:29ryuovaguely. mainly the general ideas i had to apply in a C context.
11:29ryuoa structure plus common functions.
11:29noncomhow can i create a routing table for compojure so that it gets re-resolved on each http access to my server? ideally i'd like to store everything in a {} that i can update from time to time
11:29spaceplukgood, don't waste your time :P
11:29ryuothat's about all it is in C.
11:29tdammersC is kind of cleansing
11:30tdammersuseful for the rare occasions where you need a lot of control, at the expense of safety
11:30ryuospacepluk, waste my time in C?
11:30spaceplukOOP
11:30ryuoyet it is what is so wildly advocated.
11:30ryuoall they talk about is OOP in my college courses.
11:31ryuolol
11:31tdammersOOP is a local optimum
11:31spaceplukmost people don't understand oop though
11:31hfaafbno true OOP
11:31tdammersand frankly, the original Kay OOP isn't such a bad idea at all
11:31luxbockI recently read http://arcanesentiment.blogspot.sg/2013/09/why-concatenative-programming-matters.html which makes me want to give Factor a try
11:32ryuothere's so many paradigms.
11:32luxbockthere's tons of great posts in that blog
11:32tdammersbut ironically, one of the languages that most closely does that isn't considered OOP at all, but "functional"
11:32ryuoeven array programming. XD
11:32spacepluktdammers: agreed
11:32TMAryuo: OOP is easily explained to a pointy haired boss (on the level: see you have a car that has four wheels; let call each piece an object)
11:32tdammersyeah
11:32tdammersOOP looks familiar to management types
11:33luxbockoh whops, I meant to link http://evincarofautumn.blogspot.com/2012/02/why-concatenative-programming-matters.html
11:33spaceplukmost people think that OOP is about shoehorning design patterns in your code and overengineering until you have to thow away the whole thing
11:34spaceplukat least that's my perception of it, with the people I've worked with
11:34hfaafbthat's not what people think OOP is, that's what people experienced in big legacy monolithic repos
11:34ryuohuh. it talks about composition vs application.
11:34hfaafblike the ... eventual outcome of large oop systems
11:34ryuowhat's the difference? at some point it has to executed...
11:34tdammersspacepluk: consider yourself lucky... it means that the people you've worked with are at least semi-enlightened
11:34spaceplukhehehe
11:35spaceplukfuck that's depressing
11:35ryuoi always thought composition was just combining functions to form a new kind of function
11:35tdammersryuo: the difference isn't about how it gets executed; it's about how you keep your code manageable
11:35luxbockryuo: yeah that whole explanation he gives for it is what really made me appreciate the post
11:35tdammersoh wait, different discussion
11:35crazydiamondHi. How do I install library like this to use from Clojure? https://github.com/dren-dk/HunspellJNA I've installed it by "mvn install" but (import 'dk.dren.hunspell.Hunspell) raises java.lang.ClassNotFoundException
11:38luxbockcrazydiamond are you using Leiningen?
11:38crazydiamondluxbock, boot
11:38crazydiamondluxbock, it's like leiningen in terms of :dependencies etc
11:39spaceplukcrazydiamond: is it running with the correct classpath?
11:40crazydiamondspacepluk, at least I have access to other libs from ~/.m2 , like datomic
11:41spaceplukcrazydiamond: are the native binaries included in the jar? :?
11:41crazydiamonddunno, but I have some in my system :)
11:41spaceplukI don't really know how that works, just shooting ideas
11:42crazydiamondit passed tests
11:42crazydiamondduring mvn install
11:42crazydiamondspacepluk, it seems quite hard to get it working :-(
11:42spaceplukit looks like the bundle the binaries in a different jar, maybe it's a separate dependency?
11:42crazydiamondah, you mean Java binaries
11:43crazydiamondnot C
11:43spaceplukno the native binaries
11:43crazydiamond(it's the lib that gives access to C lib via JNA)
11:43spaceplukI think they put them in a jar
11:44spaceplukcheck for hunspell-linux* hunspell-win* etc.
11:44spaceplukmaybe they are in a separate maven package
11:47lambda-smithMan, Clojure is so nice, I couldn't stop using it
11:47crazydiamondspacepluk, I've just added to :dependencies in my build.boot, and it works
11:48spaceplukah cool, then it was the classpath
11:49sdegutisWhat's your usual technique on having a test-service (e.g. for email) and replacing it with a live-service (e.g. AWS-SES) when your program is live?
11:50spaceplukreader conditionals? :?
11:50spaceplukI have no usual technique though since I'm a noob hehe
11:51sdegutisHmm I wonder... I bet the people who normally could answer this have me on /ignore
11:52spaceplukhehehe
11:53sdegutisHi justin_smith.
11:59justin_smithsdegutis: hello
11:59sdegutisYou must be really productive at work today justin_smith.
11:59justin_smithjust getting started
12:02spaceplukis there any async alternative to monger?
12:02justin_smithdoesn't monger support fire and forget? I thought that was the default with mongo stuff.
12:03justin_smithor do you mean like queries with callbacks
12:03spaceplukI don't know, it looks like it blocks the current thread
12:03spaceplukbecause it returns the result of the queries
12:03spaceplukyes
12:05sdegutisspacepluk: The nature of Mongo is that all queries block the entire Mongo server, in order to ensure consistent results.
12:06sdegutisWe moved to Datomic in large part for that reason.
12:06spaceplukthat doesn't mean that you need to block the client though
12:06sdegutisDatomic Free is working amazingly for us.
12:06spaceplukI really want to try that
12:09spaceplukbut for this I need mongodb :/
12:11spaceplukI guess I can just use the java driver but monger looked so good :(
12:11justin_smithspacepluk: you could use (future (callback (monger/query ....)))
12:11justin_smithunless the java driver does something nicer I guess
12:12justin_smithalso what about using monger and then using the java driver directly for the features monger doesn't support?
12:12spaceplukwill that spawn a thread for every query? I'm still learing clojure's in and outs
12:12spaceplukthat's a good idea
12:13justin_smithspacepluk: each call to future uses a thread from the thread pool
12:13justin_smiththe thread gets returned to the pool when the callback returns
12:13spaceplukthe limits the number of concurrent queries, right?
12:13spacepluks/the/that/
12:13justin_smiththe thread pool is unlimited
12:13justin_smithwell, limited by what your OS can do thread wise I guess
12:13spaceplukthat sounds scary hehehe
12:14justin_smithyou can also use core.async or your own thread pool if you want something more controlled
12:14justin_smithyou could mitigate this by putting one callback on a series of queries all in one future
12:14justin_smithor by making a thread pool doing queries where you specify the max size
12:15noncomdoes anyone know how to get data from backend into a reagent form ?
12:15noncomi want the page to be generated with data from the backend... is this possible at all?
12:15justin_smithnoncom: I typically use a websocket
12:15noncomjustin_smith: can you give a tiny code example?
12:16justin_smithnoncom: or you can have a backend service that serves up your form I guess
12:16justin_smithnoncom: websockets and tiny examples don't really go together so nicely...
12:16noncomoh ok
12:16spaceplukjustin_smith: thank you, that's very helpful :)
12:16justin_smithunless you were planning on a websocket architecture, what about a service on your backend that returns your base form for reagent as json?
12:16noncomi'm just trying to get some real data into html forms generated in luminus, which uses reagent on this
12:17justin_smithOK
12:17justin_smithwell, you could make luminus put real data in there right?
12:17noncomno
12:17justin_smithis it really that inflexible?
12:17noncomi think i'm missing something, that's what. i can't believe it is that inflexible
12:18noncomyes, a backend service that returns forms is how i always did it in the past
12:18justin_smithnoncom: eg. I'd think you could make a function that takes a template, fills in some parts of it, and returns a new template for the frontend reagent to use
12:18noncombut you see, luminus has new features now so i am tryin to explore them
12:18justin_smithnoncom: or you could have a ajax/json service that gives the data to reagent...
12:19sdegutisjustin_smith: how do you select between services (e.g. an email-service) depending on your environment, so that you get an in-memory service when running tests or running a dev environment, and a live one in production?
12:19justin_smithnoncom: OK, best of luck
12:19noncomjustin_smith: yeah.. i just don't know how to organize data transfer between my clj and cljs code..
12:19noncomeh, this is all too much.. i have to figure out many things before i get there.. or just use the old approach - simply make the backend generate the forms
12:20justin_smithsdegutis: I use environ usually - my latest madness is to have a "config" component that sets up all this environment specific stuff (or at least populates an options map so my other components can be configured)
12:20sdegutisby component do you mean stuartsierra/component ?
12:20justin_smithnoncom: I think the json/ajax approach is straightforward enough - reagent makes ajax request, gets json data, fills in data used for rendering, renders page
12:21justin_smithsdegutis: indeed
12:21noncomyes. now i just have to find out how to add ajax request and data display to reagent templates..
12:21justin_smithnoncom: reagent should already be taking data from memory (an ratom right?) and using that to render
12:21sdegutisHmm everyone seems to be using Component these days.
12:22justin_smithnoncom: the only extra step is making an ajax request and putting data from the result into your ratom(s)
12:22sdegutisI built my app before the days of Component so I don't really know how I'd restructure it to fit that in hree.
12:22sdegutis*here
12:22justin_smithsdegutis: using environ to select your config map from a map of maps should work with or without component, component just makes the whole thing cleaner
12:23noncomjustin_smith: you mean that reagents atom incapsulates ajax interaction?
12:23sdegutisRight, I was going on a tangent :P
12:23justin_smithsdegutis: or alternately instead of a map of maps you can have a directory of edn files staging.clj dev.clj prod.clj
12:23justin_smithnoncom: I mean make an ajax request and in the callback put data you get from the request into the ratom in order to change parts of the page
12:24sdegutisjustin_smith: my current approach is to use (System/getProperty "myapp.env") to get the env name, and then selecting a plain Clojure map of settings based on that.
12:24noncomah i see, right
12:24sdegutisjustin_smith: the problem with this approach is it only describes the settings for the live environment, or whether to use the memory-environment -- it can't actually switch between them.
12:24justin_smithnoncom: websockets have a similar logic, but are faster (it's one connection that stays open instead of separate requests that get negotiated)
12:25justin_smithsdegutis: that's the part that component makes easier
12:25justin_smithshut down components, reset config, start up components
12:25noncomjustin_smith: i used websockets a bit before. do you think that they are better than ajax in almost any case?
12:25sdegutisjustin_smith: So each service has a default in-memory implementation, just made up of normal vars, like (defn send-email [to from subject body] ...), and there's an alternative implementation in an adjacent namespace that actually uses the real service (e.g. SES), along with a function in that namespace called go-live! which just uses alter-var-root to replace the default implementation in the other namespace with this function in t
12:25sdegutishis namespace.
12:25justin_smithnoncom: I prefer them where they are supported, definitely - much smoother
12:25sdegutisThis technique feels... a bit weird.
12:26noncomi see
12:26justin_smithsdegutis: yeah, I prefer having a component which provides the configurable part of the emailer
12:27justin_smithnoncom: also, if you ever want such a thing, websockets free you from the request/response paradigm - you can have pushes of data in either direction, and whether that needs a response can be negotiable
12:28noncomyeah, i once made a prototype of an online RTS with them.. seemed really pleasant to work with
12:28noncombut somehow it all seems a bit clunky.. the whole web thing
12:30sdegutisjustin_smith: Hmm. Thanks. I'll have to think on this for a while and try to wrap my head around it.
12:32noncomjustin_smith: have you ever worked with reagent sessions + ajax?
12:33noncomjustin_smith: now i managed to get ajax working and i got this kind of code: http://joxi.ru/Y2Lj69ehaPbWr6
12:33noncomfeels a bit weird :D
12:35noncomjustin_smith: btw what are you using for websockets? immutant?
12:45oddcullynoncom: your gut feeling is right
12:45oddcullythe more you keep stuff like this out of your html/hiccup/... the better
12:45oddcullytell some fn or some message bus (e.g. core async), that something needs to be done
12:46oddcullythen let it happen and when it happended update the atom/datascript/state/...
12:46oddcullywhich the propagates into an update of the html
12:47oddcullys/the/&n/
12:54sdegutis,(-> :foo {:bar})
12:55clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
12:55sdegutis:(
12:55sdegutis,(-> :foo (hash-map :bar))
12:55clojurebot{:foo :bar}
12:55sdegutis:D
12:57sobelgah, i can't get clojure.java.jdbc/insert! to work on my (Oracle) table to save myself. is there a special trick w/oracle?
12:57sobeli can select so i know the connection is there but insert! seems to generate bad sql. ORA-00926: missing VALUES keyword
13:03sdegutisIs there a less vacuous way of accomplishing this?
13:03sdegutis,(->> ["command" "web" "port" "8080"] (partition 2) (map (fn [[a b]] [(keyword a) b])) (apply concat) (apply hash-map))
13:03clojurebot{:command "web", :port "8080"}
13:11ystaelsdegutis: clojure.walk/keywordize-keys
13:12sdegutis,(->> ["command" "web" "port" "8080"] (apply hash-map) (clojure.walk/keywordize-keys))
13:12clojurebot#error {\n :cause "clojure.walk"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.walk"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.net.U...
13:12sdegutis,(require 'clojure.walk)
13:12clojurebotnil
13:12sdegutis,(->> ["command" "web" "port" "8080"] (apply hash-map) (clojure.walk/keywordize-keys))
13:12clojurebot{:command "web", :port "8080"}
13:12sdegutisystael: I like your style.
13:12ystaelglad i could help :)
13:15justin_smithnoncom: sente, http-kit implementation
13:16noncomi see
13:34lperhowdy, has anyone here had success using gen-class to override a protected method (javax.swing.JPanel/paintComponent) without reflection warnings?
13:44vince`\help
13:45vince`erc-list
13:46vince`/erc-list
13:46vince`//channel
13:46vince`/erc-list
13:47amalloysobel: nobody can guess what is wrong with your insert! if you don't paste an example call to it. and of course it's *possible* that oracle doesn't support even the most basic sql, but i'd first guess that it's my own code
13:49noncomjustin_smith: i am exploring the example with websockets in luminus. i did everything as in the tutorial, however, i am gettin some strange error in the server log
13:49noncomthe response of the ws compojure handler is {:status 200, :body #<UndertowWebsocketChannel org.projectodd.wunderboss.web.async.websocket.UndertowWebsocketChannel@4fe927d1>}
13:50noncomso it is trying to return the websocket object as a result
13:50noncombut then there comes the error: Cannot JSON encode object of class: class org.projectodd.wunderboss.web.async.websocket.UndertowWebsocketChannel: org.projectodd.wunderboss.web.async.websocket.UndertowWebsocketChannel@4fe927d1
13:51noncomcould you shed some light on this? i am sure i am not supposed to send a java object as a response body
13:51buharinhello
13:51buharin:)
13:51amalloynoncom: i am pretty sure you are
13:51buharinI start reading Clojure for the Brave and True
13:51amalloyit's a Channel into which stuff gets written
13:52buharincause I thought I am brave and true enough to read it
13:52amalloyi'd guess that the issue is rather that you're wrapping a json middleware around a route that doesn't return json (instead returning a websocket)
13:52buharinbut I am afraid that there are no jobs for clojure and it is waste of time
13:52buharin:(
13:52noncomamalloy: so, i am sending it to the html frontend? why then compojure complains that it cannot JSON-encode it ..
13:52noncomah, i am supposed to encode it somehow?
13:53noncombuharin: that depends. actually clojure is getting pretty much of a foothold on the world-wide arena...
13:53amalloyi am claiming that you are probably encoding it when you're not supposed to
13:53amalloyprobably with some json middleware, as i said
13:54noncombuharin: even in my country where clojure invitations are rare, i am able to apply clojure to my daily work and it gives very good results and brings pleasure
13:54amalloythat error is rather unlikely to be coming from compojure itself, because compojure doesn't do any json encoding
13:54expezanyone have a leiningen hook I can look at? The docs seem to be somewhat out of date.
13:55noncomamalloy: ah, so this is just some middleware getting in the way? the object should be sent without any encoding
13:55noncom?
13:55amalloythat is my guess
13:55buharinnoncom, oh ok
13:55amalloybut i don't know what you are doing aside from following some tutorial
13:56noncomamalloy: heh, nothing else. i am actually, moving very closely to the luminus tutorial
13:56noncomprobably the tutorial on websockets diverges from the rest of the tutorial, i will look more closely to its github repo
14:11lambda-smithSo guys, any news on the GUI front? Is Seesaw still the best option?
14:12justin_smithlambda-smith: I'd say a majority of our frontends (at least out of those vocal here) are html / cljs. I've seen some people using JavaFX via interop as well.
14:13lambda-smithHi see, thanks justin_smith
14:30sdegutislambda-smith: yeah most people use cljs/html/reagent afaik
14:30sdegutislambda-smith, justin_smith: I've toyed with using Reagent inside Electron.
14:31lambda-smithYeah, it seems like web app/using Electron is the way to go nowaday.
14:31lambda-smithOh well, I guess it's about time I learn Electron + Clojure web stack
14:32sdegutisPersonally I just stuck with plain old Electron + JavaScript (+ a few libs of course). Clojure isn't a significant improvement over JS, so it's not worth the difficulties it causes.
14:32justin_smithman, "reagent electron" is a shitty google search
14:33sdegutisOne of the worst in fact.
14:33sdegutisExtremely real science term.
14:33justin_smithadding javascript helped, but really now
14:33sdegutisBtw is the overhead of (#'foo) significantly higher than (foo)?
14:33justin_smithsdegutis: crit/bench will give you the info you seek
14:33lambda-smithsdegutis: what kind of overhead?
14:34sdegutisI'm considering changing my massive entry-point (defroutes ...) to have things like #'user-routes instead of user-routes for dynamic reloading to work better.
14:34sdegutisCPU I guess.
14:34justin_smithlambda-smith: it needs to do the var indirection on every call
14:34sdegutisjustin_smith: never heard of that, thanks
14:34lambda-smithHm.. I see
14:34justin_smithsdegutis: criterium.core/bench
14:34sdegutis(woo finally made it to reddits front page, my life's checklist is almost complete)
14:34tcrayford____actually so does calling it without the var quote, right?
14:35justin_smithtcrayford____: the difference is how often / under what circumstances lookup is forced
14:35justin_smith#'foo is looked up anew on every invocation, foo can be inlined, or if used as an arg to a first class function is only looked up on the invocation of said function (which may used that looked up value N times)
14:36justin_smithtcrayford____: in sdegutis ' usage, he passes #'foo to a handler which spends the rest of the app lifetime derefing #'foo on every usage, where if passed foo it would have only looked it up once
14:36tcrayford____ah, yep
14:36tcrayford____uh haha
14:36sdegutisSo I guess it might be slower. But it's the JVM so probably not noticeably slower in produciton.
14:37tcrayford____bahaha
14:37tcrayford____(if (:development env) #'user-routes user-routes) it's fine
14:37justin_smithtcrayford____: hey we could even make a macro for that!
14:39sdegutisWill that thread well inside -> ?
14:39sdegutisOh wait it's inside (defroutes) not (->)
14:51sdegutisIt's not working.
14:52sdegutisMy code isn't noticing my redefined function.
15:03sdegutisWhat could cause a redefined function (redefined with `C-c C-k` while CIDER is running) to not be seen and used by the running code?
15:05sobelCan anyone help me figure out how to diagnose my fairly fundamental problem getting clojure.java.jdbc/insert! to work...at all?
15:06sobeli can query but insert! complains: SQLSyntaxErrorException ORA-00926: missing VALUES keyword
15:08sdegutisPlease Help. I ran (jetty/run-jetty #'my-handler {:port 8080}) and now inside CIDER I evaluated (defn my-handler [] {:status 200 :body "ok so far"}) and refresh but the change is not visible.
15:08sdegutisWhat am I doing wrong??
15:08lazybotsdegutis: Definitely not.
15:09mdeboardwhat
15:09mdeboard@ lazybot
15:09sdegutismdeboard: lazybot has really lame responses programmed in for when you type ?? at the end of something
15:10sdegutisIt's annoying but you learn to just get used to it.
15:10mdeboardoh
15:14clojurianHi, I'm having trouble with dynamic reloading using CIDER. First I ran (run-jetty #'my-handler). Loaded my page and the handler shows. Now, inside CIDER, I evaluated a new definition of my-handler using C-x C-e, and refreshed my browser, but the change is not visible. What am I missing or doing wrong?
15:15justin_smith$mail sdegutis so not even an exception thrown because your handler got an arg and you didn't define it to take one?
15:15lazybotMessage saved.
15:15mdeboardSure clojurian is sdegutis
15:15mdeboardSurely*
15:16clojurianWell there goes my one shot at trying to ask this question of all those who have me on /ignore
15:16justin_smithI still haven't found this thing called "electron" that can be used in combination with the "reagent" library because electron+reagent is just giving me a bunch of chemistry results
15:16TimMcmdeboard: I was confused why you said that, but it's probably based on messages I had ignroed.
15:16sdegutisjustin_smith: Oh I thought you knew what it was already.
15:17sdegutisjustin_smith: https://github.com/atom/electron/
15:17justin_smithOK they renamed atom
15:17justin_smithI know what atom is
15:17sdegutisjustin_smith: right not even an exception was thrown
15:17justin_smith*was
15:17sdegutisjustin_smith: no they renamed atom-shell
15:17mdeboardTimMc, lol
15:17sdegutisjustin_smith: Atom is still Atom
15:17mdeboardI have no idea who sdegutis is, was just trying ot help out justin_smith :P
15:17sdegutisWhat did TimMc say?
15:17TimMcbecause surely a complaint about cider being weird is not very specific.
15:18justin_smithOK
15:18sdegutisI can't see it at all but I don't have him on ignore.
15:18sdegutisOoooh.. I see.. TimMc private messaged mdeboard to let him know I'm a troll he should /ignore.
15:18sdegutisFriendliest community ever. A+.
15:18mdeboardI regret so much about my actions in the last 5 minutes now
15:18mdeboardpretend I said nothing
15:18sdegutisdone
15:18sdegutisjustin_smith: no exception, nothing
15:19sdegutisnot in the emacs-cider-repl, not in the terminal repl.. nothing
15:19cfleming$mail snowell: That's great, thanks! You can reformat using Code->Reformat Code, or whatever you have that bound to (the menu will show you). If you have code selected, only that code will be reformatted.
15:19lazybotMessage saved.
15:19cfleming$mail hante_monsta: You can configure all the indentation in Cursive - if you're having problems doing that, let me know.
15:19lazybotMessage saved.
15:21sdegutisOkay already #clojure, I can take a hint. Enjoy your peace and quiet without trolls like me ruining it.'
15:22TimMcmdeboard: Consider the logs wiped.
15:22TimMcbut now my messages to you look weird!
15:22mdeboardI appreciate your business advice re: my frozen yogurt stand
15:27TimMc:-)
15:29amalloysobel: i already gave you a suggestion
15:30amalloyas you can see if you scroll back, my suggestion was to gist an example insert! that's not working. otherwise the only thing we have to work with is "it doesn't work", and the only useful advice to give is "have you tried turning it off and back on again?"
15:38sobelamalloy: i didn't see that earlier. i eventually narrowed it to problems mapping tags to table names
15:52hostHello beautiful Clojuristas! I've recently changed OS to Windows (needed Photoshop). Is Clojure development on that OS plausible? Or pain in the bum?
15:55Rurikhost, use an IDE for sanity
15:55hostRurik: Light Table + Leiningen is enough?
15:56Bronsahost: I'd suggest IntelliJ
15:56hostBronsa: Why?
15:56Bronsawith cursive
15:56Bronsahost: cursive is really good
15:56Bronsahttps://cursiveclojure.com/
15:56hostBronsa: Does it have instant feedback?
15:56Bronsait's easy to setup and really powerful
15:57hostor instarepl of some sort?
15:57Bronsahost: it has an integrated repl
15:57Bronsano, not like lighttable's instarepl
15:57hostBronsa: instarepl is a killer feature for me
15:57hostso I guess cursive is not in my type
15:58hostbut I will look at it
15:58Bronsaoh well, then it sounds like light table is actually what you want :)
15:58hostI've also had issues with \n and \r\n here, are pitfalls like this common on Windows?
15:59hostlike these*
16:00tdammerssheesh... you don't need an IDE for clojure
16:01Ruriktdammers, command line on windows sucks
16:02tdammersdid I say "command line"?
16:03vaitelI'm using Emacs + cider on windows; it seems to work pretty well.
16:03Bronsatdammers: nobody said you *need* an IDE
16:04ashwink005can anyone tell me how do I make a sqlite db SELECT call
16:05ashwink005SELECT * FROM database WHERE id=x name=y
16:05ashwink005how do I pass in the variables? i.e. x and y
16:07ashwink005anyone please!
16:08hostMaybe something with "let" statement? But I'm a noob, you don't have to listen to me
16:09ashwink005no I know I need to call the jdbc library's function
16:09Bronsaashwink005: https://github.com/ogrim/clojure-sqlite-example
16:09ashwink005but what and how do I pass the SELECT string
16:11ashwink005Bronsa: yeah how do I add arguments to the where clause
16:11ashwink005Bronsa: any idea? (def output (query db "select * from news"))
16:11Bronsahttps://github.com/clojure/java.jdbc#example-usage
16:23ashwink005Bronsa: thanks I'll look into it
17:11ashwink005how do I make a post request in Clojure?
17:11ashwink005is the hiccup form the only way
17:12surtnashwink005: clj-http should work - https://github.com/dakrone/clj-http#post
17:22ZimaBlue`I'm having some project.clj problem, when I add my source paths it gives me could not locate on classpath. The relevant line is: :source-paths ["src/cljs" "src/demo"] and that matches the directory structure but I always get Could not locate demo/core__init.class or demo/core.clj on classpath.
17:22ZimaBlue`but with the source commented out, it's fine
17:25expezZimaBlue`: like you don't have a src/demo/demo/core.clj file, which is what leiningen is looking for
17:26expezs/like/likely/
17:26expezZimaBlue`: so just change "src/demo" to "src" and you'll be good to go.
17:31ZimaBlue`expez: thanks, but I don't understand - is it adding together my prefixed demo in the main and suffixed demo in the src string?
17:31expezZimaBlue`: the default value for source-paths is ["src" "test"], you told it to consider src/demo the root of your source directory
17:32expezZimaBlue`: so if you have a namespace named demo.core then leiningen will look at the root for a folder named demo and then look for a file there called core.clj
17:33ZimaBlue`I think I understand, thank you!
17:57ZimaBlue`I'm still failing, now cljs isn't working:
17:57ZimaBlue`structure: src/cljs/demo/app.cljs, code: (ns demo.app)
17:57ZimaBlue`(.write js/document "Hello, ClojureScript!")
17:57ZimaBlue`config:
17:57ZimaBlue` :cljsbuild {:builds
17:57ZimaBlue`[{:source-paths ["src/cljs"] :compiler {
17:57ZimaBlue` :output-to "resources/public/js/app.js"
17:57troydmhow can I make sure that cider-nrepl is loaded?
17:57ZimaBlue` :optimizations :whitespace
17:57ZimaBlue` :pretty-print true}}]}
17:57ZimaBlue`
17:57troydmwhen I type lein repl and I have cider-nrepl in user profile in .lein/profiles.clj how can I make sure it's actually loaded?
17:59oddcullyZimaBlue`: please don't paste large portions of code here. use a gist/refheap/... instead
17:59oddcullyZimaBlue`: also "isn't working" might need some more elaboration
18:01ZimaBlue` sorry - what I mean is that when I go into resources, there isn't a compiled js file. I'll use that link in future - not been on irc mnuch before.
18:02dnolenZimaBlue`: there's also a #clojurescript channel these days
18:03dnolenZimaBlue`: I would make a gist w/ your project.clj and your project structure so people can examine that.
18:03ZimaBlue`ok, I'll repost the question over there. Thanks
18:13kwladykaDid you hear about remote job for Clojure Junior or in Europe with relocation? :)
18:45expeztroydm: when you call cider-jack in (in emacs) you'll get a warning if the middleware is missing or misconfigured. If you want to check in `lein repl` if the middleware is active (although I can't see why) you can check for the presence of any of cider.nrepl.* namespaces
18:52troydmexpez: ic
19:02hiredman /win 19
19:09ashwink005what does -> mean in clojure
19:09ashwink005can't google it
19:10Rurikashwink005, threading macro
19:10TEttingerashwink005: yep, there's a good resource for ungoogleable symbols in clojure
19:10ashwink005TEttinger: could u send me a link?
19:10TEttingerhttps://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/
19:10ashwink005Rurik: thanks :)
19:16TEttingerashwink005: you may also want to bookmark clojuredocs and/or grimoire
19:17ashwink005TEttinger: I have bookmarked clojure docs. But couldn't find the name of the operator
19:17ashwink005thanks man :)
19:18TEttingerhttp://conj.io/ is the quick reference page of grimoire
19:19troydmgrimoire only contains core library right?
19:20TEttingernope http://conj.io/store/v1/org.clojure/clojure/1.7.0/clj/clojure.string
19:20TEttingerneed to click the + but it does have all the standard stuff
19:21TEttinger"oh you wish you were using common lisp do you?" http://conj.io/store/v1/org.clojure/clojure/1.7.0/clj/clojure.pprint/cl-format
20:23gargsmsI am a Clojure newbie. I made a Compojure project and configured the routes. I can do GET properly but in case of POST, I get `Invalid Anti Forgery Token` error. Any help?
20:28thearthurgargsms: the corasponding get request should be sending you a csfr prevention token (Cross Sire Request Forgery)
20:28gargsmsthearthur, How do I do that?
20:29thearthurthis needs to be passed to the post request to prevent CSRF attacks (on all web applications, this is not Clojure specific)
20:29gwsgargsms: https://github.com/ring-clojure/ring-anti-forgery
20:29gwsgargsms: you've probably configured that, and you can either disable it for now to test your routes, or pass the __anti-forgery-token form parameter
20:35gwsas the README mentions you can get the value that is associated with that parameter by calling ring.util.anti-forgery/anti-forgery-field
20:37gwswhich will generate the HTML necessary, rather. You can get the actual value out of a dynamic var in that lib if you want to create some custom HTML
20:47troydmis there a builtin function that would remove element from a list returning a new copy of list?
20:48rhg135rest
20:48rhg135or pop
20:51justin_smithtroydm: you don't need copies of immutable data
20:51justin_smithrhg135: neither of those copy
20:52rhg135justin_smith: I didn't see the copy
20:52rhg135why would you want it though?
20:53justin_smithprobably because he didn't realize clojure lists were immutable, or didn't understand the implications of that fact
20:54justin_smithrhg135: that was the right answer for what troydm wanted, I was just being pedantic about the assumed details
20:56justin_smithrhg135: clojure-blindness
20:56rhg135indeed
20:57troydmjustin_smith: let's say I want to implement a function that would give me all possible permutations of a list, how would I go about implementing it? I have no clue
20:57rhg135being more pedantic, that is more due to the persistence
20:57rhg135non-persistent lists might get copied for perf
21:00justin_smithtroydm: clojure.combinatorics has that function if you just need the functionality
21:01justin_smithtroydm: but the general pattern in clojure is to write a recursive function where each iteration gets more results until you have created all of them
21:01troydmjustin_smith: I know about that, but I'm more interested in implementing it by my own
21:04justin_smithtroydm: so - how I would break it down - first take the elements of the list, and pass those as the "head" and all other members of the list as the "tail elements" for each recursive call. Then for the recursive calls generate a new set of heads and tails. recursively concatenate all results of this, stopping when each tail hits empty list
21:04justin_smithhmm, that's not very clear is it
21:06troydmjustin_smith: hmm, I got general idea
21:10gargsmsgws, I have the value. I tried passing it in the `X-Csrf-Token` header from the browser. I still get the same error.
21:17gwsyou're getting the value from the server and sending it back on each POST, or you've copied the value from some point in time and are passing that to test?
21:17gargsmsAh. Finally. Somehow I got it working.
21:17justin_smithtroydm: here's a broken version that shouldn't be far from working https://www.refheap.com/109034
21:17gargsmsThanks thearthur gws
21:18troydmjustin_smith: ic, thx
21:19justin_smith,((juxt take drop) 3 (range 10))
21:19clojurebot[(0 1 2) (3 4 5 6 7 ...)]
21:22TEttingerI can't remember, does the group of all permutations of a, say, 10-element list include 1-element and 2-element sublists or just re-orderings of the 10-element?
21:25justin_smithTEttinger: "a rearrangement of the elements of an ordered list into a one-to-one correspondance with itself"
21:25TEttingerif order doesn't matter, that's a combination, not a permutation right?
21:25justin_smithif order doesn't matter, permutation isn't defined
21:26TEttinger(and there are less comb's than perm's)
21:29TEttingerlike if the store sells 6 kinds of fruit, and I can buy any number of any of the kinds of fruit, and I want to know how many item numbers will be on the receipt (so quantity doesn't matter if > 0), that's a combination (there are 63 here, since you don't get a receipt if you buy nothing)
21:29TEttingerbut if it was something like arranging 6 different fruits in a line on a table, that's a different problem
21:54justin_smithTEttinger: well I figured out a way to do it, but it feels like a silly solution https://www.refheap.com/109034
21:55justin_smithI am sure that can be golfed down to like 1/4 the size
22:06TEttingerjustin_smith: yeah I think you're right about the size
22:06TEttinger,(let [limit 6] (nth (iterate #(for [p %, n (range (inc (count p)))] (concat (take n p) [(count p)] (drop n p))) [[0]]) (dec limit)))
22:06clojurebot((5 4 3 2 1 ...) (4 5 3 2 1 ...) (4 3 5 2 1 ...) (4 3 2 5 1 ...) (4 3 2 1 5 ...) ...)
22:06TEttinger&(let [limit 7] (nth (iterate #(for [p %, n (range (inc (count p)))] (concat (take n p) [(count p)] (drop n p))) [[0]]) (dec limit)))
22:06lazybotExecution Timed Out!
22:06TEttingerhaha
22:06TEttinger&(let [limit 5] (nth (iterate #(for [p %, n (range (inc (count p)))] (concat (take n p) [(count p)] (drop n p))) [[0]]) (dec limit)))
22:06lazybot⇒ ((4 3 2 1 0) (3 4 2 1 0) (3 2 4 1 0) (3 2 1 4 0) (3 2 1 0 4) (4 2 3 1 0) (2 4 3 1 0) (2 3 4 1 0) (2 3 1 4 0) (2 3 1 0 4) (4 2 1 3 0) (2 4 1 3 0) (2 1 4 3 0) (2 1 3 4 0) (2 1 3 0 4) (4 2 1 0 3) (2 4 1 0 3) (2 1 4 0 3) (2 1 0 4 3) (2 1 0 3 4) (4 3 1 2 0) (3 4 1 2 0) (... https://www.refheap.com/109038
22:07TEttingerthere should be 120 elements there
22:07justin_smithfancy
22:07justin_smithI'm bad at lazy stuff
22:08TEttingerit can be quickly adapted to just get the nth item from the original list, too
22:09TEttinger&(let [limit 5 original [:a :b :c :d :e]] (map (partial map nth original) (nth (iterate #(for [p %, n (range (inc (count p)))] (concat (take n p) [(count p)] (drop n p))) [[0]]) (dec limit))))
22:09lazybotjava.lang.UnsupportedOperationException: nth not supported on this type: Keyword
22:09TEttingeraww
22:10TEttinger&(let [limit 5 original [:a :b :c :d :e]] (map #(map (partial nth original) %) (nth (iterate #(for [p %, n (range (inc (count p)))] (concat (take n p) [(count p)] (drop n p))) [[0]]) (dec limit))))
22:10lazybot⇒ ((:e :d :c :b :a) (:d :e :c :b :a) (:d :c :e :b :a) (:d :c :b :e :a) (:d :c :b :a :e) (:e :c :d :b :a) (:c :e :d :b :a) (:c :d :e :b :a) (:c :d :b :e :a) (:c :d :b :a :e) (:e :c :b :d :a) (:c :e :b :d :a) (:c :b :e :d :a) (:c :b :d :e :a) (:c :b :d :a :e) (:e :c :b ... https://www.refheap.com/109039
22:11TEttingerI had a bit of help from wikipedia and 14th century math whizzes in India :)
22:11justin_smithhaha, cheater
22:11TEttingerhttps://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
22:12TEttinger(that's not the algo I used though)
22:12TEttingerthis one, with no opts https://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm
22:16chousercan I play?
22:16justin_smithoh, please do
22:16justin_smithwith any luck I might learn something
22:17chouser&((fn perm [r m p] (if (> m 0) (mapcat #(comb (disj r %) (dec m) (conj p %)) r) [p])) '#{a b c d e} 5 [])
22:17lazybotjava.lang.RuntimeException: Unable to resolve symbol: comb in this context
22:17chouserheh
22:17justin_smithwhat is comb ?
22:17chouser&((fn perm [r m p] (if (> m 0) (mapcat #(perm (disj r %) (dec m) (conj p %)) r) [p])) '#{a b c d e} 5 [])
22:17lazybot⇒ ([a e c b d] [a e c d b] [a e b c d] [a e b d c] [a e d c b] [a e d b c] [a c e b d] [a c e d b] [a c b e d] [a c b d e] [a c d e b] [a c d b e] [a b e c d] [a b e d c] [a b c e d] [a b c d e] [a b d e c] [a b d c e] [a d e c b] [a d e b c] [a d c e b] [a d c b e] [... https://www.refheap.com/109040
22:17justin_smithahh
22:17justin_smithnice!
22:17chouserWorks with sets, so no good if the input it meant to have duplicates.
22:19chouserThat's an oldie, btw. 11 June 2008.
22:19justin_smithit's a classic problem, that just happens to hit some aspects of clojure programming I am pretty bad at
22:21chouseroh, I didn't mean to suggest you were bad at anything, just that I was cheating off my former self.
22:21justin_smithoh, no, I volunteered that part :)
22:22justin_smiththat's the reason I was asking for improvements / other approaches
22:22chouserIf you always want the full set of inputs:
22:22chouser&((fn perm [r p] (if (seq r) (mapcat #(perm (disj r %) (conj p %)) r) [p])) '#{a b c d e} [])
22:22lazybot⇒ ([a e c b d] [a e c d b] [a e b c d] [a e b d c] [a e d c b] [a e d b c] [a c e b d] [a c e d b] [a c b e d] [a c b d e] [a c d e b] [a c d b e] [a b e c d] [a b e d c] [a b c e d] [a b c d e] [a b d e c] [a b d c e] [a d e c b] [a d e b c] [a d c e b] [a d c b e] [... https://www.refheap.com/109041
23:14justin_smithsomeday I hope to attain this level of craftsmanship http://i.imgur.com/BUpsUAF.gifv
23:29TEttinger(inc chouser)
23:29lazybot⇒ 23
23:30TEttingerjustin_smith: IS THAT TRANSPARENT WOOD
23:32justin_smithTEttinger: it's wood cut so incredibly thin that you can see through it
23:32justin_smithby hand
23:32TEttingerand I thought the joins they do were amazing
23:32TEttingerwow
23:32jeayeIs it the technique or the tool?
23:32justin_smithan act of remarkable skill and handicraft - he probably spent decades getting that good
23:32justin_smithjeaye: I'm sure the tool is a part of it too
23:33justin_smithanyway, metaphorically it is all about how much he crafted and honed his craft which is what will inspire me to become a better programmer
23:34TEttingerhttps://www.youtube.com/watch?v=W1pvUlQgYtk
23:36justin_smithTEttinger: having worked on American mcmansion style construction sites, the comparison is really embarrassing
23:36TEttingerI can imagine!
23:37justin_smithit's amazing what these guys do with hand tools
23:41TEttingerit's interesting because japan doesn't have endless quantities of lumber that they could just throw more sequoias at a building project, and doesn't have much iron that historically could have been used for mass-producing large heavy weapons (like the horribly successful 10-15-foot spike of metal called a pike and used heavily by disposable peasants in european wars)
23:41TEttingerjapan's traditional building techniques emphasize not wasting materials
23:42TEttingerit makes you wonder about what scarcities drive programming innovation
23:43justin_smithTEttinger: developer attention span and discipline
23:43justin_smithwhich leads us to things like fp and OO which at least in theory keep the worst outcomes from happening when we forget what we were doing :)
23:43TEttingerclojure got a lot of attention initially because the multicore revolution was starting, and it seems to have already ended, but clojure is still (thankfully) in use
23:46TEttingerit seems like a lot of clojure's big new ideas are going to be needed for future developments (GPU programming could really benefit from some kind of immutability when you have hundreds or thousands of tiny compute units)