#clojure logs

2015-01-07

00:03luxbockyeah I'm talking about writing data to a file
00:04luxbockI have a transducer that does a series of transformations on a datastructure, and I want to save the end result to file
00:04luxbockor it's a bit more complicated than that
00:07luxbockI have a list of nodes which I encode to binary via ztellman's Gloss library, and I want to write these to a file
00:08luxbockbut I also need to create a header that tells me at what byte count is each item located in that file
00:09luxbockso was planning on creating a transducer that takes an element, encodes it as a bytebuffer, checks how many bytes it has and then saves that into a file, returning the byte-count
00:09luxbockand then I can create the header from those byte-counts afterwards
00:10luxbockbut I wasn't sure if this is a good idea or not, so I thought to ask here first
00:10ztellmanluxbock: you're encoding it with 'gloss.io/encode'?
00:11luxbockztellman: yes
00:12ztellmanluxbock: no need to use a transducer, just use (->> bufs (map #(.remaining %)) (reductions +))
00:12ztellmanand potentially add a side-effect to the .remaining call if you want to do I/O as you're iterating
00:14luxbockztellman: the Clojure datastructures that I'm encoding are coming from a C API call, and they represent results of simulation that takes up a lot of memory, so one of my goals is to try to save the results of the simulation without running out of it
00:14luxbockso I'm trying to think of a way to process each of the nodes in my list individually
00:15ztellmanluxbock: so #(let [size (.remaining %)] (append-to-file %) size)
00:15ztellmansame basic deal
00:15luxbockztellman: cool I'll give that a try
00:16ztellmanthat'll have to be a scratch file you're appending to, though
00:16ztellmanif you want to have the header be at the front of the file
00:16ztellmanor put a fake header in your file and then overwrite it
00:17luxbockztellman: yeah I was considering doing the latter
00:17luxbockthanks for all of your libraries btw, with this project I've been using byte-streams, vertigo, potemkin and Gloss :)
00:17ztellmanhaha
00:17ztellmanvertigo!
00:17ztellmanglad someone's using it
00:17luxbockI'm using it with clj-native to perform the C API calls
00:18ztellmancool, let me know if you have any issues there
00:18ztellmanthat's a use case it was designed for, but I never actually used it for that myself
00:19luxbockztellman: there was someone on the Clojure ML asking a Gloss question a few days ago
00:19luxbockhttps://groups.google.com/forum/#!topic/clojure/NxsCPBk12mE
00:19ztellmanoh, thanks
00:19luxbockI didn't know how to do what he wanted and I suspect it might be imposible
00:19ztellmanI need to create some central place for questions
00:20luxbockohh, actually I misread what he was asking
00:48luxbockztellman: any reason why `defcodec` shouldn't take the same pre and post-decoder functions as its arguments as `compile-fram` does?
00:49luxbockI find myself using (def foo (gc/compile-frame X Y Z)) a lot because I usually want to clean up the data a bit
00:49ztellmanluxbock: that would be atypical for a def form
00:49ztellmanbut I dunno, I'm currently scoping out a ground-up rewrite, maybe I'll rethink that
00:52ztellmanyeah, I think I prefer that to having a complex set of arguments to a def-form
00:53luxbockztellman: when I searched for examples of people using Gloss I noticed a lot of them use defcodec around compile-frame
00:53ztellmanfair enough
00:54luxbockthink I might do that as well, just because it makes the code a bit easier to read, and I assume there's no drawbacks
01:00ddellacostanot exactly Clojure related, but does anyone have good reading suggestions for getting a good understanding of the JVM?
01:02rs0ddellacosta: that's a pretty huge topic
01:02mfikesddellacosta: I like Goetz JCiP for the JVM's memory model.
01:02rs0ddellacosta: there's performance, bytecode, the JIT compiler, the garbage collector... even the JVM spec only covers a small fraction of the functionality in a typical JVM
01:03ddellacostamfikes: this one, right? http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=sr_1_1?ie=UTF8&qid=1420610526&sr=8-1&keywords=brian+goetz
01:04mfikesddellacosta: Yep.
01:04ddellacostamfikes: gotcha, thanks
01:05rs0speaking of which, http://docs.oracle.com/javase/specs/jls/se8/html/index.html
01:05rs0or rather http://docs.oracle.com/javase/specs/jvms/se8/html/index.html
01:07mfikesddellacosta: But that only really covers one aspect of the JVM, as rs0 is saying. (But, it seemed be the part of the JVM that cost me the most cognitive load.)
01:08ddellacostamfikes: yeah, I was just interested in getting a kind of open-ended response to see what folk recommended. I'm interested in all sorts of topics surrounding the JVM, in particular what Clojure developers would care about.
01:09ddellacostawhat folks*
01:10ddellacostabut otherwise, I'm also very much interested in just simply understanding basics about the JVM, like how memory is structured and how to use visualvm effectively, for example.
01:11mfikesddellacosta: Then there's things like value types :)
01:11ddellacostafor example, this kind of information: http://blog.jamesdbloom.com/JVMInternals.html
01:12ddellacostamfikes: Are you talking about these? http://martinfowler.com/eaaCatalog/valueObject.html
01:13rs0ddellacosta: http://www.amazon.com/dp/1449358454 and http://www.amazon.com/dp/0137142528
01:13ddellacostars0: have you read both of those? Which do you prefer, they seem to cover the same topics?
01:13rs0ddellacosta: maybe http://cr.openjdk.java.net/~jrose/values/values-0.html ?
01:14rs0ddellacosta: the first book is more recent, but i haven't read as much of it as the second one
01:14mfikesddellacosta: If you have large array Point objects, those Point objects could be all over the heap, and expensive to touch.
01:14mfikesddellacosta: Yes, the John Rose stuff
01:14rs0mfikes: have you played with the Valhalla prototypes yet?
01:14ddellacostars0, mfikes: okay, thanks
01:16mfikesrs0: No, what is that?
01:16ddellacostabut sounds like value types are not presently a part of the JVM?
01:16rs0mfikes: the prototype implementation of specialization, e.g. Box<int> instead of Box<Integer>
01:16rs0mfikes: http://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html
01:17mfikesrs0: Cool stuff. :)
01:17mfikesddellacosta: Right, value types are a hopeful future, an aspect of the JVM that Clojure programmers may care deeply about :)
01:18ddellacostamfikes: got it, thanks for the clarification
02:22irctc(defmacro abc [name] (println name ", hello!"))
02:22irctcwhy (macroexpand '(abc "John")) return nil?
02:22luxbockirctc: println returns nil
02:22luxbockirctc: you probably want macroexpand-1
03:27macdicetotal newbie used to other lisps: shouldn't that be (defmacro abc [name] `(println ,name ", hello!")) ?
03:28luxbockmacdice: yeah, except in Clojure it's ~name
03:29macdiceah. thanks
03:48dysfunnaming things is hard. especially protocols
03:52rritochdysfun: Did you get my message about lein-sablecc?
03:53rritochdysfun: I've tested the generated AST and even been able to create a functional hello world from a custom interpreted language with it so it looks like 1.1.0 is fully functional.
03:56dysfunrritoch: yes, but every time i've come back to my screen you've logged out by the time i come to reply :)
03:56dysfungood work was mostly what i wanted to say
03:56dysfuni didn't think i'd have a need for it, but i found a new yak
03:58dysfunthen again, it might be sufficiently complex i just use parse-ez and to hell with performance
03:58rritochdysfun: hehe, SableCC is it's own yak farm collective... It takes about 5 minutes to code the grammar and hours to resolve conflicts.
03:58dysfunhaha, yes
03:58dysfunimagine me and my friend poring over what's wrong with our perl 5 grammar
04:02rritochdysfun: The most helpful article I've found so far is @ http://www.sable.mcgill.ca/listarchives/sablecc-list/msg00241.html
04:03rritochdysfun: I almost missed it in the google search results because it doesn't seem related, but it has some very helpful tips which has helped me resolve most conflicts in less time.
04:03dysfunoh yes, java is so simple
04:03dysfunwe just need a naming convention!
04:03dysfunbut the tips look good
04:04dysfunyou sort of get into the swing of resolving it after a while though, it's almost fun
04:04dysfuna bit like mod_rewrite rules, with similar levels of stockholm syndrome
04:06rritochAs for your naming issue, I usually just name things by the first thing I can think of, and eventually change the name to whatever I accidentally type most often instead of the assigned name.
04:06dysfunheh, i do that too
04:07dysfunprogramming's a strange game sometimes
04:07hellofunkdysfun: yes. and sometimes, after doing it every day, all day, for many days, you just feel like you've gotten into a strange loop
04:08dysfunah, someone else lives in groundhog day
04:08dysfundeathmarch projects are the worst
04:08hellofunkhttps://thestrangeloop.com/
04:08dysfunclojure seems the most generally fun time i spend programming, which is why i keep doing it
04:10dysfuni'm still looking for a good language for systems programming though. every time i think i've found something i realise it's crap and just use c
04:10dysfunocaml seems the least broken, but it's hardly unbroken. the syntax is the first sign something is very wrong.
04:10hellofunkdysfun: have you considered just using assembly. it's great for systems.
04:12dysfunif i never have to program assembly language again it'll still be too much for one life in what i've already done
04:12dysfunit's been so many years since i could do a better job at assembly than a compiler
04:13dysfuntechnology is pretty awesome
04:13rritochdysfun: C is really the best language for systems programming. If you compare the generated C code to generated C++ code you'll see C++ code produces a lot of junk symbols that aren't really part of the solution to the given problem.
04:14dysfunwell it doesn't have a choice because of the language
04:14dysfunbut in the general case, i find my c++ tends to be "c with classes" anyway, because c++ is hateful
04:15dysfuni finally found myself having to deal with utf8 data in c++ and by the end of discovering how the standard library mangles it i was ready to cry about the state of systems programming in 2014
04:17dysfunin the end i was relieved to find that somebody managed to implement the same thing i actually wanted already in C and i was happy
04:19rritochdysfun: Hmm, I think I dealt with that issue already but I don't have a clue where I the code is. I was trying to make a plugin to metatrader to publish and export metatrader features via web services so it could be controlled from Java.
04:21SagiCZ1rritoch: metatrader as in the forex/futures client?
04:21rritochdysfun: If I recall correctly I ended up converting UTF-8 to UTF-16 internally and used widechars
04:21rritochSagiCZ1: Yeah.
04:22dysfunrritoch: bingo!
04:22SagiCZ1rritoch: I found that thing so ugly and buggy that i am currently in the state of writing my own trading platform in clojure.. note that i dont aim to trade in high frequencies so i dont need extremely low latency
04:22dysfunrritoch: actually it's all pluggable of course (and why wouldn't it be when you only ever want a handful of things and it could all be made so much easier with a different api?)
04:24rritochSagiCZ1: Yes, and their internal data types are horrible and inconsistent. After about the millionth segfault I gave up on the project.
04:24rritochSagiCZ1: Their string length was just to small to do anything of value.
04:24SagiCZ1rritoch: i was trying to learn and use that MQL that they want you to write the plugins/experts in.. i cried
04:25dysfunoh, another domain specific extension language! just what the world needed!
04:25SagiCZ1dysfun: yup!
04:25SagiCZ1i coudlnt trust my money with that thing.. so i noped out
04:26rritochSagiCZ1: Yes, it is the MQL strings and arrays that are the problem, passing them to and from .dll plugins is a nightmare, but the strings themselves are just too small and the system usually segfaults randomly when you change the string length from a plugin.
04:26dysfundid you see gary bernhardt tweet the homepage of mathematica yesterday? nice comment on how the mess of code on the first page produced a pretty graph and how it's all so easy and understandable that dear god has wolfram ever programmed a thing before?
04:27dysfunhttps://twitter.com/garybernhardt/status/552224807664644096
04:28SagiCZ1rritoch: sounds really bad.. btw people in the past sometimes used Common Lisp for trading platforms.. it is actually what brought me to clojure. The rapid prototyping is very handy
04:28dysfunSagiCZ1: you mean the repl? or the fact everything is pretty easy to do?
04:29SagiCZ1dysfun: both actually
04:29dysfunthe latter i think lends clojure to being a good maintenance programming language as well as good for prototyping
04:29dysfunand since most programming is maintenance...
04:29SagiCZ1the only disadvantage is the garbage collection which could throw of some microsecond transactions.. one just has to keep that in mind
04:30dysfuncoming from perl, where they like to keep things simple too, clojure libraries have felt comfortable
04:30SagiCZ1i see
04:30dysfunthey're the minority. don't worry about it
04:30dysfunyou should be making it up in numbers
04:30SagiCZ1i am aiming at that
04:30rritochSagiCZ1: Well most trading systems use MT4 so it is a neccissary evil, unfortunatly they never published their protocol to allow third parties to develop functional trading platforms that are compatible with it. Developing a functional trading platform shouldn't be that difficult of a task, the hard part will be getting the brokers to use it.
04:31SagiCZ1i also cant not mention that testing pure functions is a pure bliss compared to testing mutable mess of c++ or java..
04:31SagiCZ1rritoch: actually you dont need to force the brokers to do anything.. most brokers offer platform independent api
04:31dysfunyes, testing is brilliant in clojure
04:31dysfuni like midje
04:31SagiCZ1most of them offer something called FIX
04:32SagiCZ1or some web based streaming such as REST
04:32SagiCZ1i am already trading my demo through clojure with no problems
04:32SagiCZ1as far as the trading systems go, i would have to rewrite them to use them, thats true
04:33rritochSagiCZ1: Well the companies I went through only provided MT4 services. If they had provided REST services I would probably still be trading.
04:33SagiCZ1these have rest, java, fix http://developer.oanda.com/
04:33rritochLol, My account was with Oanda
04:34SagiCZ1i guess you just wasnt looking hard enough mate! haha
04:34rritochThat must be new, I've never seen it before
04:35rritochAnyhow, they suspended my account, aparently new U.S. laws don't allow expats to utilize foreign trading systems, and I was using Oanda/Singapore
04:35rritochIt was the only way I could legally trade gold/silver/platinum
04:36SagiCZ1rritoch: that sounds super odd
04:36TMASagiCZ1: FIX is _the_ sane protocol for trading [considering the alternatives, like polling tables via JDBC -- each table row basically contains two columns -- message type and encoded message string]
04:37rritochSagiCZ1: They gave me an option to re-open my account under Oanda US, I just wasn't interested at the time it happened.
04:37hellofunkrritoch: why would you need a foreign account to trade gold or silver?
04:38SagiCZ1TMA: yeah well i started with the REST API, since i heard that FIX is the grandfather of trading protocols
04:38rritochhellofunk: The U.S. made it illegal to trade gold and silver.
04:38hellofunkrritoch: what? people trade gold and silver all the time, what are you referring to?
04:38rritochhellofunk: At least within the U.S.
04:39hellofunkrritoch: that is completely false. the gold and silver market is huge in U.S.
04:39hellofunkrritoch: you must be referring to something very specific and unusual
04:39rritochhellofunk: Well maybe they revoked the law
04:40hellofunkrritoch: it has been completely legal to trade gold and silver in the U.S. for many decades, there has never been a time when you couldn't
04:40rritochhellofunk: The law caused most brokers to deny and cancel the accounts of U.S. customers
04:40rritochhellofunk: That isn't true
04:40SagiCZ1gold/silver is very vague.. it depends if it was CFD or currency/silver or something else
04:40hellofunkrritoch: you must be talking about a very specific instrument, because general gold and silver trading has always been available
04:41hellofunkGold futures, gold ETFs, physical bars of gold, they are all an active market and have been at least during my entire career
04:42SagiCZ1so many traders around here
04:42rritochhttps://gold-forum.kitco.com/showthread.php?86011-It-is-illegal-to-trade-currencies-against-precious-metals-now
04:43rritochThis was another con-game by the current administration
04:43hellofunkrritoch: you are talking about Forex trading, not metal trading? big difference
04:44hellofunkrritoch: it is true that Forex laws have changed a lot in recent years, but trading metals has never been illegal
04:44rritochhellofunk: As far as I know it is still illegal to trade any precious metal in the U.S., the only way around it is to trade ETF's
04:45rritochhellofunk: Any metal trading your doing is probably only backed by ETF's.
04:45hellofunkrritoch: that is completely false.
04:45hellofunkrritoch: heck no. the futures industry?
04:47nonubymost idiomatic way to test if a parameter is a function?
04:47nonubygrr. fn? was trying to find a function?
04:48rritochhttp://www.financialsense.com/contributors/james-bibbings/2011/07/19/dodd-frank-restrictions-on-gold-and-silver-derivatives-market-now-in-effect
04:48rritochhellofunk: Per that article the law is in effect, but parts of it arn't yet being enforced.
04:49rritochhellofunk: But until the law is changed, it is technically illegal to trade precious metals in the U.S.
04:50hellofunkrritoch: wrong. that article is about OTC and Forex.
04:50rritochhellofunk: I'm not a lawyer, if you want to take the risk that's your decision
04:51rritochhellofunk: My lawyer assured me that it's illegal and the only way I could do it legally was by utilizing foreign brokers
04:51hellofunkrritoch: it's not a risk. the futures market is vast and legal. I work for an American broker. it is a pillar of the economy to allow metal trading
04:51hellofunkrritoch: check out the futures industry, it's traded by the billions every day
04:52hellofunkbut OTC and Forex are different markets and those have changed recently. if all you had was a Forex account, then this would have affected you, yes
04:55rritochhellofunk: I wasn't involved in futures trading, and I'm not willing to risk any SEC involvement in my business. The airfare alone would bankrupt me.
04:57rritochSpeaking of "illegals" exporting new cryptography technologies is also illegal, which is one benefit of being an expat since I'm never exporting cryptography technology from the U.S. but importing it into the U.S.
04:58rritochThey're all a bunch of ignorant laws limiting technology development, and the politicians that wrote those laws should all be fired.
04:59rritochI'm not sure if the precious metal laws effect software development though, but I wouldn't want to find out the hard way.
05:01hellofunkrritoch: the primary mechanism for trading metals in the world is the futures industry, which is gigantic and legal. if you were talking about unregulated markets like OTC and Forex, then of course those markets are in jeopardy. de-centralized financial markets can be a fragile spot for any economy, hence the laws you mentioned.
05:02hellofunkrritoch: feel free to join me in #clojure-offtopic if you want to discuss further
05:06rritochhellofunk: No thanks. I need to get back to work, but to bring it back on topic, clojure based trading libraries would certainly be a useful addition to clojars.
05:08rritochhellofunk: There is a disproportional overlap between the financial industry and clojure developers, so it is likely a good niche for clojure dominance.
05:08hellofunkrritoch: i have found that any programming language has a large number of traders among its developers.
05:08clgvHappy New Year to all Clojurians ;)
05:09rritochhellofunk: I'll pm you
05:09rritochhellofunk: This is delving into propriatary issues
05:11zarkonehello all! i have list of vectors, how can i use mapv with it without macro?
05:13zarkonewith mcaro i would do `(mapv f ~@elems)
05:14clgvzarkone: `apply`
05:14clgv(apply mapv f elems)
05:14zarkoneclgv
05:14zarkonei'm idiot
05:14zarkonethanks
05:15clgv,(apply mapv vector '([1 2] [3 4]))
05:15clojurebot[[1 3] [2 4]]
05:30TEttinger,(apply mapv identity '([1 2] [3 4]))
05:30clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/identity>
05:30TEttingerah
05:40CookedGryphondoes anyone have any good hints for better git merging with clojure?
05:41CookedGryphonI find I get far fewer merge conflicts in general with clojure code, but when I do get them they're often a bit annoying or not really conflicts
05:43martinklepschI'm using an atom in tests to count some requests made to a httpkit-fake thing: https://gist.github.com/6cdb6ee4c5516b6186ae
05:43rritochCookedGryphon: I use tortoisemerge which I believe came automatically when I installed tortoisesvn
05:44martinklepschfor some wierd reason these atoms sometimes have values that are not plausible except under the assumption that an old atom with an old value is recycled
05:45zotis there a way to use lein to generate a jar of all dependencies, so that i can separate out the building (and uploading) of a large dependency set, from the actual project code?
05:46martinklepschis there anything wrong with how I use atoms there? should I use something different?
05:46martinklepschzot: how do you mean? if there are separate dependencies as jars you must have gotten them from somewhere no?
05:47zotmartinklepsch: "i" didn't get them per se; leiningen downloaded them on my behalf, and i have no idea of what the entire chain is, and i don't want to. uberjar already does this part — i just haven't found the deps part split out (so far)
05:47rritochzot: I believe it would be possible to do it using a custom profile while doing a lein uberjar, just have that custom profile use an empty directory for it's :source-paths. I don't know for a fact it would work, but it should.
05:48zotrritoch: clever. i may try this :)
05:49rritochzot: Also put all your deps in the :dev profile, that will keep them from being included in your generated uberjar for the actual application.
05:50rritochzot: The final part, of linking your uberjar to the single dependency jar would be the hard part, and I'm not sure how to do it.
05:51zotclasspath isn't enough?
05:53rritochzot: I suppose you can add it to your classpath, I was just thinking of something more elegant, like modifying the manifest https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L417-L427
05:54zotah. that is definitely more elegant :)
05:55sm0kehello all
05:56sm0kei have this toy usecase https://www.refheap.com/95825
05:56sm0kecan somebody explain how is this not vulnerable to head holding?
06:18clgvCookedGryphon: "BeyondCompare" as merge tool is an option though you have to buy it. usually, "meld" under linux suffices for me
06:18hellofunksm0ke: this type of example confused me when I first started learning the language. maybe it still does. but if you switch the two count forms, do you see why it *would* retain the head?
06:19sm0kehellofunk: chaning order is ok, it makes sense
06:20sm0kebut in the example let [lazy ..] reference is there throughout!
06:20clgvsm0ke: I suppose "locals clearing" avoids to hold the head of the sequence
06:20hellofunksm0ke: actually your take while doesn't make sense to me. it is nil, no?
06:21hellofunk,(take-while #(< 10 %) (range 20))
06:21clojurebot()
06:22sm0keoops (< % 10)
06:22hellofunksm0ke: did you mean #(< % 400) instead if you are trying to chop the seq into 2 seqs
06:22sm0kebut i think that wont make a difference?
06:22sm0keor would it?
06:22clgvsm0ke: https://www.refheap.com/95826
06:23sm0keclgv: how the hell you get that so fast?
06:23clgvsm0ke: huh? what exactly do you mean?
06:23sm0kethe byte code?
06:23sm0kemakes sense
06:23clgvsm0ke: double click on a class file starts the decompiler GUI I use
06:23sm0ke(inc clgv)
06:23lazybot⇒ 41
06:24sm0keso clojure is setting it to nil just before function call
06:24hellofunksm0ke: if you wait for the second count to count the beginning of the lazy seq, then the first count cannot throw away the head since the head is used in the second count, that comes after
06:25hellofunksm0ke: but when you switch them, the head is no longer needed as it counts the rest of the seq
06:25sm0kebut there is still a problem what if i do .. alazy (take-while #(< 100000000 %) lazy)
06:26sm0kei mean #(< % 100000000)
06:26sm0keugh
06:27hellofunksm0ke: it would still depend on which end of the range you are counting first, right?
06:27clgvsm0ke: I'd say the original gist definitely keeps the first 400 realized elements in memory
06:28sm0keyep
06:28sm0kei think making alazy large would render localclearing useless
06:29sm0kehttps://www.refheap.com/95827
06:30sm0keis there a way around this?
06:30clgvsm0ke: partition + (map count)
06:30hellofunkjust try this to see the issue: (count (range 100000000)) it takes a while but it completes for me
06:31clgvsm0ke: or more like something similar to partition-by
06:31hellofunkbut if you count from teh head of the lazy seq before you count the send partition, then the head would not be retained
06:31hellofunk*second
06:32hellofunkswitching them, and counting the second first, means the head is retained since it is used by the second count form
06:32clgvsm0ke: if you can transform it to pipeline style (->> lazy (clever-partition #(< % 400)) (map count)) - you'll be sure that it is not holding on to the head of the seq
06:33sm0kelet me try partitioning
06:33hellofunksm0ke: your example is more or less the same as the one in the Oreilly book: (let [[t d] (split-with #(< % 12) (range 1e8))] [(count t) (count d)]) completes fine. but if you switch the counts, it is a memory erryr
06:34hellofunk*error
06:34hellofunkyou can read the explanation on page 99 if you have the book :)
06:34sm0kehellofunk: no its more than that, what if you substitute 12 with 1e8?
06:34hellofunksm0ke: now you are talking about a different issue unrelated to head retention, no?
06:35sm0keis it unrelated?
06:35sm0kei just changed a value!
06:35clgvsplit-with sounds good
06:36sm0ke,(doc split-with)
06:36clojurebot"([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
06:36clgvI totally forgot about that function ^^
06:36sm0kei didnt even knew it exists
06:36clgv$source split-with
06:36lazybotsplit-with is http://is.gd/QsZ10c
06:36hellofunksm0ke: well, count by itself does not hold onto the head, so i guess it is a head retention issue because you are asking it to hold onto the head when you put the count of the first partition *after* the count of the second
06:36clojurebotA nod, you know, is as good as a wink to a blind horse.
06:37clgvwell, that implementation is about the same as your code - so I'd guess that'll be no solution
06:37sm0kei have no luck with partition either
06:37sm0ke(let [[alazy blazy] (partition-by #(< % 100000000) lazy)]
06:38hellofunkthe solution is to arrange your non-head-retaining actions in a way that their combination doesn't force head retention
06:38hellofunkwhich is the point of the Oreilly example
06:44clgvhellofunk: but that's tricky if you don't know which is the larger part (maybe that does not occur in practical problems)
06:45hellofunki'm running this example right now, taking a few minutes for me: (let [[t d] (split-with #(< % 1e8) (range 1e8))] [(count t) (count d)])
06:45hellofunkclgv: it's not about which is larger, it's about which contains the head, which you would always know
06:46clgvok the head of the original seq, right
06:46hellofunkyes
06:47hellofunkso actually in my most recent example, the ordering doesn't matter at all. both are memory errors.
06:49hellofunkthe example made my computer sound like it was ready for liftoff
06:49hellofunkthe ultimate "side effect"
06:49clgv:P
06:51martinklepsch,(merge-with merge {:a {:b 1 :c 2} :x "test"} {:a {:c 3} :x "foo"})
06:51clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IPersistentCollection>
06:52martinklepschI kind of see why this breaks but is there a way to write this without a custom `merge` function?
06:52clgvmartinklepsch: no. but some libs probably include a deep-merge already
06:53clgvthe question reappeared here multiple times already
06:55hellofunkmartinklepsch: i'd be more inclined to change the map and make x a key for a map so all "levels" of the map have similar types of values
06:55hellofunk,(merge-with merge {:a {:b 1 :c 2} :x {:v "test"}} {:a {:c 3} :x {:v "foo"}})
06:55clojurebot{:x {:v "foo"}, :a {:c 3, :b 1}}
06:58clgvold contrib seemed to have a deep-merge-with
06:59clgvmartinklepsch: you can use crossclj.info to look for those
07:07dysfundoes core.async have a 'stop the world' mechanism such as might be required for a garbage collector to work properly?
07:08clgvdysfun: to get a consistent snapshot of all channels?
07:08dysfunto get a consistent snapshot of all refs in the world
07:08dysfunif you have many thousands of refs
07:08clgv"refs" as in Clojure's `ref`?
07:08dysfunyes
07:09clgvWhy is just using a transaction to read all of those not acceptable?
07:09dysfuncan transactions scale to millions of refs?
07:10clgvdysfun: depends on what is done with them
07:11dysfunwell, in this case, garbage collection
07:11clgvhuh?
07:11clgvyou can certainly run into problems with many short running transactions and some few long running transactions
07:12dysfuni want to have data that is generally manipulable as a map stored in a vector, like you have with a columnar store like hbase as a column primitive
07:12clgvdysfun: garbage collection is vm level, not really the level of your application
07:12dysfuni want to go through pruning data that i consider to be now unimportant
07:12clgvah ok
07:13dysfunso how would you model that?
07:13clgvgood question.
07:13dysfunheh :)
07:15clgvdysfun: are you sure you cant use one of the database options?
07:15dysfunit's a hobby thing, so i can't be bothered to faff around, it gets boring
07:15clgvdysfun: I still regret not having use a proper database for a certain use case. but I wont be able to change because of time constraints
07:16dysfunheh
07:18dysfuni'm hoping all of my data will fit in memory for some time to come
07:18clgvdysfun: that was my starting assumption ;)
07:18dysfunhahaha
07:18dysfunyeah, there's a point at which hadoop starts to appeal and then you know you're stuffed :)
07:18clgvthe problem for me has been that clojure's persistent datastructure add quite some overhead
07:19dysfunreally?
07:19dysfuni thought they were reasonably space-efficient
07:19clgvmy last quick work around has been to implement a map-alike that supports only the reading interfaces via a deftype
07:21clgvso I got something that works like a map with respect to reading - that worked since the data is read-only
07:21clgvjust some analysis stuff. but an ordinary sql database would have been the best choice to start with...
07:21dysfunooh, that's quite interesting. in my use case they're 99.9999% read-only
07:22dysfun(famous last words!)
07:23justin_smithmartinklepsch: for your atom issue, would retries account for the states you are talking about?
07:23clgvdysfun: CollReduce, Indexed, ILookup, Counted, IKVReduce are the interfaces/protocols I implemented
07:23justin_smithmartinklepsch: remember that they don't lock, if two concurrent changes happen, the one which observes an inconsistency between what it first sees, and the value when it attempts to update, retries with the new value
07:24dysfunclgv: thanks
07:24clgvdysfun: if you got those, you can access the data in idiomatic clojure
07:25dysfuninteresting. thanks.
07:25clgvdysfun: I have two deftypes Dataset and Row, to represent the data
07:27dysfun*nod*
07:30clgvdysfun: next time I'll use some kind of embedded sql database for that usecase
07:30dysfunheh. sqlite is pretty great
07:31clgvor even H2 or HSQLDB
07:31dysfun*nod*
07:36hellofunksqlite offers some neat features that many other dbs don't have or are harder to use, like an all in-memory database
07:45luxbockI want to write X amount of zero-bytes to a file first, fill it with some other stuff, and then finally replace those zero-bytes with something meaningful in the end
07:45luxbockI need to use RandomAccessFile for this right?
07:57AeroNotixluxbock: why do you need to write them to the file before determining what you need to write in the X bytes?
07:57AeroNotixfor efficiency?
07:58luxbockAeroNotix: I know the size of the header before but not the contents it has
07:58luxbockheader being the part of zero-bytes I want to re-write later
07:58AeroNotixGotcha, still, omitting efficiency woes, I'd probably use an in-memory stream first and then copy it to disk later.
07:59luxbockAeroNotix: I'm trying to avoid running out of memory when reading the results of a large computation which I'm reading via API calls to a C program that performs it
08:00luxbockthe more efficient I'm with memory, the larger simulations I can run
08:00AeroNotixok, so use a random access file then. I was just trying to save latency rather than memory.
08:00AeroNotixbut we're just pulling numbers out of our collective arses here.
08:01AeroNotixWrite the simplest thing and benchmark :)
08:01luxbockAeroNotix: thanks. latency is not an issue since this is run once and store for a long time type of operation
08:01AeroNotixoke doke
08:46hellofunkin Cursive keymaps anyone know what a diagonal arrow represents? left/right/up/down are obvious, but what is the diagonal arrow key?
08:47hellofunkand also, an arrow with a double dash intersecting it
08:51jonathanjhellofunk: does this help you: http://www.danrodney.com/mac/
08:52jonathanj(I don't use Cursive, so I'm not sure exactly what arrows you're seeing, but I think you're describing Home/End and PgUp/PgDn)
08:55hellofunkjonathanj: excellent, thank you!
09:03H4nsdoes apply realize its last argument? in other words, if a function has signature [ & foo] and i invoke it with a lazy seq using apply, would foo be a realization of that seq or would it be lazy as well?
09:05justin_smith&(apply (fn [x y & _] (+ x y)) (range))
09:05lazybot⇒ 1
09:05justin_smiththat would have been an infinite loop if apply realized any args past the first two
09:06opqdonut&(apply (fn [x y & _] (+ x y)) (range))
09:06lazybot⇒ 1
09:06justin_smithwell, if it realized the "last" arg at least (chunking, d'oh)
09:06opqdonutoh, that was already what you did, erm
09:06opqdonut&(apply (fn [x y & _] (+ x y)) 1 2 3 (range))
09:06lazybot⇒ 3
09:06justin_smithyeah, that was like my exact code
09:06opqdonutthat was what I meant to do
09:08H4nsinteresting, thanks!\
09:08NinerianHello, i have a beginner question. When I use another namespace with require, I cannot access the methods which are defined the. But a predefined refer works. Is there something to notice?
09:09opqdonutif you require, you need to use a prefix
09:09opqdonuti.e. (require 'foo) (foo/function 1 2 3)
09:09Ninerian‚(ns xml-to-plist.handler
09:09Ninerian (:require [xml-to-plist.dev :refer [browser-repl start-figwheel]] <— works
09:09Ninerian [xml-to-plist.util :refer [foo-cljx]] <— doesnt work
09:09opqdonut(refer 'foo) "mirrors" the definitions from foo to the current namespace
09:10opqdonutoh, you were talking about something different
09:11Nineriani cannot call foo-cljx
09:11Ninerianbut browser-repl
09:11opqdonutare you sure foo-cljx exists in xml-to-plist.util?
09:12justin_smithNinerian: using a prefix is good style by the way, and on a pedantic note, functions are not methods
09:13NinerianYes it is. When I copy the function into xml-to-plist.dev and include into the refer vector it is available
09:18NinerianUsing the namespace with (require 'xml-to-plist.util) and calling it with the prefix works. What is the difference between (require) an (ns .. (:require)) ?
09:20justin_smiththere is none
09:20justin_smiththe best approach generally is (:require [foo.bar :as bar]) and then call foo.bar/baz as bar/baz
09:21justin_smithwell, actually there is the difference that (ns ...) is a macro, so you don't need to quote things inside it
09:21justin_smithbut require can do everything that :require in an ns form can do, and visa versa
09:29yazirianIn the cljs case, the difference is where and when it's executed; you mention browser-repl so I assume that the real difference here is that (ns .. (:require)) is taking place in a file, whereas you may be typing (require ..) into a browser repl.
09:29yaziriancljs, unlike clj, does not have access to its compiler
09:29yazirian(if that isn't what you were doing -- i can't really tell from the question -- then nevermind :)
11:06thheller@dnolen_ what do you mean if you say :foreign-libs? is that non-closure compliant JS, or closure compliant but not in deps.js?
11:06dnolen_thheller: non-closure compliant JS
11:07dnolen_thheller: it's been there since the beginning so you can at least load foreign libs
11:07dnolen_thheller: but it was never that useful because it predated preamble
11:07dnolen_thheller: but if foreign libs supply their :requires and we preamble them - everything will just work
11:07thhelleryou mean provides?
11:08dnolen_thheller: no, foreign already have to say what they provide
11:08dnolen_thheller: that's how goog.require can work w/ them
11:08thhellerah but they may require CLJS code
11:08thhellergot ya
11:08dnolen_thheller: foreign libs requiring CLJS code doesn't seem likely
11:09dnolen_foreign libs are exactly that, foreign JS stuff that Closure can't understand
11:09thhellerok, but one foreign lib may depend on another
11:09dnolen_thheller: so foreign libs should alway supply {:provide ... :requires ... :externs ...}
11:09dnolen_thheller: are you skipping over what I am saying? :) *:requires*
11:10dnolen_thheller: actual dependency resolution happens via Maven as usual
11:10thhellerwell, I meant to sort the preamble
11:12thhellerforeign jquery, provides jquery, requires []
11:12dnolen_thheller: sorting the preamble is solve via :requires just like everything else
11:12thhellerforeigh jquery-ui, provides jquery-ui, require jquery
11:12thhellersomething like that
11:12dnolen_thheller: how is this in conflict w/ what I just described?
11:13dnolen_{:provides "jquery.ui" :requires ["jquery"] :externs ["jquery.ui.externs.js"]}
11:13thhellerno conflict, just making sure I understand correctly ;)
11:15thhellerjust thinking it is a bit tricky on the integration side
11:16thhellerthe CLJS code must somehow express that it depends on something foreign
11:16thhellerotherwise the JS file will ALWAYS be preamble'd
11:17thhellerbut (ns my-ns (:require [jquery-ui])) won't work unless we do special tricks
11:17thhellercause goog.require('jquery-ui') doesn't work
11:17dnolen_thheller: yeah ok, I think you just don't understand that already works :foreign-libs is not well understood
11:17dnolen_thheller: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html
11:18dnolen_thheller: always being preambled is what you want for release builds anyway
11:18dnolen_thheller: anyways think about it some more, after you have a solid sense of what I'm talking about feel free to chime on ticket about issues
11:19thhellerI'm pretty sure I got it, we just misunderstand each other
11:19thhellerI'm talking about :foreign-libs in JARS via deps.clj
11:19dnolen_thheller: no tricks required for the require to work, it already works
11:20dnolen_thheller: just scan the classpath for deps.clj that matches
11:20dnolen_bbiab
11:55thhellerdnolen_: I don't see how this is working with :advanced right now. if deps/-foreign? create a javascript file, prepend goog.provide statements and slurp the source of the foreign file. which we then treat like any JS file and pipe it into Closure Compiler which would then optimize it?
11:55thhellercreated a demo but that just fails with a nullpointerexception
11:56thhellermaybe I'm doing it wrong
11:58martinklepschthheller: I think you'd still need some combination deps.clj with an :externs key to do that
12:01thhellerno I mean the process, we can't pipe a react.min.js into the Closure Compiler which the code is doing
12:01thhellerunless I'm totally wrong
12:01thhellersure it all works in :none
12:01dnolen_thheller: read the ticket updated, you don't need to supply goog.provide because we will sort and insert between :preamble and the build
12:01dnolen_thheller: yes that the part that just broken anyway if it's doing that, foreign libs can't go into Closure
12:04thhelleryeah thats what confusing me
12:04dnolen_thheller: just a bug
12:04thhellercan't even get a simple example to compile
12:04thhellernot even :none because of some weird path
12:05thhellerwell ok, anyways just wanted to make sure I understand correctly before I add something like that to shadow-build
12:06sdegutisOn the "benchmark game" website it appears Java is only marginally faster than Clojure, but in here I've hear it's significantly faster. What accounts for this discrepancy?
12:12Bronsa,((fn [& args] (apply (fn [a & b] (apply list b)) args)) 1 2 3)
12:12Bronsa&((fn [& args] (apply (fn [a & b] (apply list b)) args)) 1 2 3)
12:12lazybot⇒ (1 2 3)
12:15sdegutisThanks in advance.
12:17justin_smithsdegutis: reading the benchmarked code should offer a hint - fast clojure is not always the same pretty immutable clojure we know and love
12:18clgvjustin_smith: but efficient clojure can be pretty idiomatic clojure as zach tellmans libraries can show you ;)
12:20thhellersdegutis: all things being equal clojure cannot be faster than java since it runs on the same jvm
12:20justin_smithcan be, yes - but it's easy to sacrifice speed for beauty, or visa versa
12:22sdegutisthheller: that seems incorrect, since both Java and Clojure compile to JVM bytecode
12:22thheller"all things beeing equal" ...
12:22thhellerif the clojure impl of the benchmark uses a different algo than the java version
12:23thhellerthe better one wins
12:24nuwanda__well, I don't see how "all things" will ever be equal :)
12:25thhellerthat's why benchmarks like that are pretty useless ;)
12:25sdegutis∞ == ∞
12:29thhellerdnolen_: should I open an issue or comment on CLJS-965? :foreign-libs definitly does not work correctly with :advanced. well you might get lucky if the file actually survives :advanced compilation ;)
12:30dnolen_thheller: lol might as well open a separate actionable ticket, it's something I've been meaning to fix for a while now
12:31thhellerhttps://github.com/thheller/cljs-foreign-bug
12:31tbaldridgesdegutis: even the benchmark game site admits that their benchmarks really don't mean anything
12:32thhellermaybe I configure it wrong but the source of js/sample.js ends up in the output, advanced optimized
12:33EvanR-workknow what a cool benchmark game would be, measure the time it takes people develop the "benchmark application" using that language (implementation irrelevant!)
12:33EvanR-worki think most will not complete
12:36seangrovednolen_: Wanted to ping you here before I open an issue on Mori - was going to propse 2 things for Mori
12:37dnolen_seangrove: l'm listening
12:37seangrove1. A mori.chainable ns, that looks like the snippet I posted the other day. Has obvious perf implications, but it's a nice way of onboarding js devs by making it looks like underscore or immutable, just with a much more mature implementation and broader set of functionality
12:38seangrove2. A set of sweetjs macros... somewhere in the repo that would add a -> like macro, and literals for vectors, hashmaps, and sets
12:39seangrove#2 would obviously be much nicer in terms of both perf, syntax, and return semantics. Not everyone is going to use it, but it would be nice to have out of the box
12:41soulman_hi
12:42soulman_=> (javax.swing.KeyStroke/getKeyStroke (int java.awt.event.KeyEvent/VK_UP))
12:42soulman_IllegalArgumentException No matching method found: getKeyStroke clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
12:42seangroveBoth are pretty small, and since mori moves pretty slowly, I should be able to maintain them if it's too much hassle for you
12:42soulman_=> (javax.swing.KeyStroke/getKeyStroke java.awt.event.KeyEvent/VK_UP)
12:42soulman_IllegalArgumentException No matching method found: getKeyStroke clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
12:43soulman_any ideas why the KeyStroke.getKeyStroke(int) method is not found?
12:44hiredmanhave you checked the java docs?
12:44soulman_hmm, because there is only a KeyStroke.getKeyStroke(char) method
12:45soulman_classical case of rubber ducking :-(
12:51EvanR-worksoulman_: 🐥
13:06seangrovednolen_: Wanted to get your thoughts before I did it in the Mori repo vs a separate wrapper project
13:09dnolen_seangrove: 1) is fine, 2) is not hardly anyone uses sweet.js from what I can tell and it's not properly maintained
13:11seangrovednolen_: Ah, bummer re #2. Was just hoping to bring Mori as close to possible to JS devs
13:12dnolen_seangrove: I don't see how it's going to bring it closer to JS people - they don't use sweet.js
13:12seangrovednolen_: Thought some might. I'd like to see it in JSX as well, tbh
13:13dnolen_seangrove: if JS people use anything it's ES6 transpilers, that has some traction
13:13dnolen_macros do not
13:18seangrovednolen_: Fair enough. JS is the perfect example of being between a rock and a hard place with its limitations and choices, so that you have to choose between expression, elegance, performance, and sanity
13:22andyfsdegutis: Re: benchmarks game, my 2 cents. Anyone who relies only on those results to compare languages is ignoring facts. Anyone who says the results are meaningless is, I think, also ignoring facts. Those are measurements of *something*, but they are not necessarily relative time measurements you will get if you implement application A in language B and C.
13:22andyfTypical Clojure code allocates a lot more memory that is then garbage collected than the Clojure programs in the benchmarks, which are often written to use mutable data specifically to help make them faster.
13:23sdegutisandyf: that sucks
13:23sdegutisThey should use idiomatic code only.
13:23dnolen_seangrove: this is not our problem ;)
13:24andyfsdegutis: Web site owners get to decide what is published.
13:24sdegutisfæir
13:24seangrovednolen_: Only when trying to bring some of the pleasantries to JS-land...
13:24andyfNew web sites are simple to create a domain name for, but time consuming to maintain over time.
13:25dnolen_seangrove: this is assuming they will even accept them
13:25dnolen_seangrove: Mori was out there for 2 years - only React.js made people pay attention
13:26seangrovednolen_: It is, yeah. But projects like immutable.js and underscore make me slightly sad
13:26dnolen_seangrove: JS people still cannot grok the utllity of macros
13:26dnolen_seangrove: thus stupid crap like AtScript (puke)
13:27dnolen_seangrove: bask in the abomination http://eisenbergeffect.bluespire.com/all-about-angular-2-0/
13:30andyfsdegutis: Also, finding a set of people that can decide what is idiomatic in 20 different programming languages and what is not, when comparative measurements between languages is on the line, would turn into a big time sink on mediating arguments of what is idiomatic. If a web site purported to publish such findings, many would likely dismiss it as ?well, my favorite language could be much better, but they judged language featu
13:30andyfas non-idiomatic for that problem, so we are hamstrung?
13:31hiredmanidioms are also domain dependent not just language dependent
13:31sdegutisok
13:36tbaldridgesdegutis: that's the problem with the benchmark games in general. Take all the pi-digits programs. Almost all of them just do FFI to libgmp. So that benchmark is a benchmark of libgmp not of the languages.
13:37tbaldridgeNotice how both the Java and Clojure version of that program to directly emit JVM bytecode.. So yeah, if you ever need to calculate pi-digits really fast, that might be the way to do it.
13:37tbaldridgeBut you're not really measuring anything of worth there.
13:38andyftbaldridge: That is the one that all critics focus on first :)
13:38andyfand I would agree with that criticism
13:38stuartsierraThere are lies, damned lies, statistics, and then there are benchmarks.
13:38andyfI wouldn't say it applies equally well to the other problems.
13:38TimMc:-)
13:42tbaldridgeI think something like the Om benchmark numbers are a good example of the big wins that can come by re-thinking an approach to a problem. That's the issue I have with the benchmark game, it's too restrictive.
13:43seangrovetbaldridge: Or has a lot of expectations baked in, certainly
13:43tbaldridgeThe game may say something like "how fast can your language make 100,000 updates to the DOM"? But if you use something like React with Om, you may not ever need to do something like that in real life.
13:43seangroveexpectations/assumptions
13:48puredangerthe only reason (at this point) for pi-digits to be doing bytecode gen rather than deftype is lack of marking native methods
13:49puredangersorry, not deftype, gen-class
13:49puredangerwhich is logged here http://dev.clojure.org/jira/browse/CLJ-1409
13:50puredangerbut I agree with the original point that these benchmarks are all doing effectively the same thing in different forms
13:50stuartsierraLet's just find wherever they keep the Java code and call it.
13:51stuartsierra:P
13:51csd_Is there any way to use clojure's mrn (e.g. 2r16) representation of numbers where the, for example, 16 is an input from a function
13:51puredangeryes, works same
13:52puredangeror rather the literal form works the same - what do you mean as input?
13:52puredanger,2r16
13:52clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "16">
13:52csd_I want a (fn [n] 2rn)
13:53puredangerso you want to interpret a decimal number as if it was a binary number?
13:53csd_yeah
13:53puredangerdo you want the result as a string?
13:54csd_i want ultimately to compute the hamming distance, where the bits differing between two strings of bits are counted. so, yeah string is fine
13:54NinerianHello
13:54puredangeroh, well there are better ways to do that probably
13:55stuartsierraXOR and count the 1 bits, or something like that
13:55NinerianHow can I filter a list by using contains? '(filter #(.contains % ".xml") "asdasd.xml")
13:55csd_ more just looking for an easy way to cast to binary
13:56puredangerNinerian: try .indexOf instead of .contains
13:56csd_Integer/toString seems my best bet
13:56puredangercsd_: there's toHexString
13:56puredangersorry toBinarySting
13:56Ninerianpuredanger No matching method found: indexOf for class java.lang.Character
13:56puredangerhttp://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#toBinaryString(long)
13:57Ninerianpuredanger: No matching method found: indexOf for class java.lang.Character
13:57puredangerNinerian: just (>= (.indexOf "asdas.xml" ".xml") 0)
13:58godd2Ninerian you need to filter over a collection
13:58lasergoatwhat's wrong with contains? i feel like the problem is the collection
13:58lasergoat,(some #(.contains % ".xml") ["asdasd.xml"])
13:58godd2&'(filter #(.contains % ".xml") '("asdasd.xml"))
13:58clojurebottrue
13:58lazybot⇒ (filter (fn* [p1__45387#] (.contains p1__45387# ".xml")) (quote ("asdasd.xml")))
13:59godd2&(filter #(.contains % ".xml") '("asdasd.xml"))
13:59lazybot⇒ ("asdasd.xml")
13:59puredangerthat's fine, you're right
14:00puredanger,(Long/toBinaryString 42)
14:00clojurebot"101010"
14:00NinerianOkay, thank you
14:01lasergoatwhat are the relative advantages of lazybot vs clojurebot?
14:02sdegutisnone
14:02sdegutis~guards
14:02clojurebotSEIZE HIM!
14:02sdegutisclojurebot can do that, lazybot cant
14:02puredangerthey're both surly
14:02sdegutisbut that's not an advantage
14:03noonianits nice having two bots when one of them stops working
14:03puredanger,2r101010
14:03clojurebot42
14:03lasergoatgot it
14:03puredangerplus you can make them fight for your amusement
14:05lasergoatthe little arrow in front of the lazybot results doesn't prevent that
14:05lasergoat?
14:05mdrogalispuredanger: Same with your children.
14:05mdrogalisBad parenting advice brought to you by Mike.
14:05puredangerthey just do that automatically :)
14:06mdrogalis:)
14:06lasergoat,(str "&(+ 1 1)")
14:06clojurebot"&(+ 1 1)"
14:06lasergoatyeah, see, i don't know how to make them fight
14:06puredangerI was just kidding :)
14:07puredangerit was an AI joke - enjoy 'em now before the singularity
14:08SagiCZ1does java save anywhere how much memory do primitive types? is it even consistent? across platforms or JVMs?
14:08yazirianyou suggest the singularity hasn't already happened -- personally, i feel like it explains a lot about where tv programming has gone in the last decade
14:08SagiCZ1or is there a way to find out how many bits for example takes up?
14:09OscarZwith java interop you can do (.myMethod some-object), how could i pass object and method to some generic function and call method inside the function ?
14:09puredangerSagiCZ1: it's defined to some degree by the JVM spec
14:09SagiCZ1jesus my english tonight.. -.- sorry
14:09OscarZi tried passing .myMethod directly but i guess its some special form
14:09mdrogalispuredanger: Really nice stuff on your new blog btw. Enjoying it.
14:09lasergoatif there's a tech singularity out there controlling tv and its output is "the bachelor", consider me worried
14:09puredangermdrogalis: thx :)
14:10yazirianfive dozen cop procedurals? sounds like neural net learning to me
14:10puredangerOscarZ: method in the form of what? a String? a java.lang.reflect.Method?
14:10yazirianiterating on the perfect CSI
14:10SagiCZ1OscarZ: you can wrap the interop call like this #(.myMethod %) and then use it as any other clojure function
14:10puredangeror use a macro
14:10OscarZcool, thanks guys.. i guess string is fine
14:11OscarZout of curiosity, would it possible to pass it in form .myMethod somehow ? i also tried '.myMethod
14:11yazirianOscarZ: also . itself is callable
14:11puredanger. is a special form
14:11yazirian,(. 1 toString)
14:11clojurebot"1"
14:12OscarZcool
14:12puredanger.method is sugar over the special form
14:12puredangerhttp://clojure.org/java_interop#dot
14:15puredangerSagiCZ1: the primitive types are defined here: https://docs.oracle.com/javase/specs/jvms/se5.0/html/Overview.doc.html#22239
14:15stuartsierraAnd no, you can't do (fn [method] (. object method))
14:16SagiCZ1puredanger: thanks!
14:16OscarZstuartsierra, i was just tryin :)
14:19puredangeryou can use a macro though with something like this (defmacro call [o method] (list '. o (symbol method))) (prob not the best way to say that)
14:19lasergoatSagiCZ1: this might be useful: https://github.com/twall/jna/blob/1e071d9ca139245b9c2ecf557010aac588732e04/src/com/sun/jna/Native.java#L1102
14:20SagiCZ1lasergoat: thanks! i was just writing something like this
14:20OscarZpuredanger, yes i thought maybe i'd need to use macro here but havent looked at macros yet.. maybe this is simple enough to learn some macros :)
14:21puredangerwith that one you could do (call 5 toString) for example. not sure what you want exactly, but it's totally possible. really, you're just ultimately tapping into the bytecode generating capabilities of the Clojure compiler in the end
14:23stuartsierraThat's still not going to let you do (fn [method] (call 5 method))
14:23OscarZim trying to make a simple helper function that would wrap the usage of to-java and from-java .. so i could do something like (call obj method {:id 303 :name "fooo"})
14:24OscarZand it would convert the map to object before the call
14:24puredangerOscarZ: you might want to look at what I did at http://stackoverflow.com/questions/27308061/whats-the-idiomatic-way-to-do-this-java-function-in-clojure/27308254#27308254
14:24puredangertakes a map of vals and calls appropriate setters on an obj
14:25puredangerkind of the inverse of bean
14:27yazirianOscarZ: memfn might also help you here, if you can wrap your method name it becomes a normal callable fn
14:28OscarZcool, whats the gensym thingy? is that something you often use with macros?
14:30puredangerhttps://clojuredocs.org/clojure.core/gensym
14:30puredangeryes
14:32OscarZwhy cant you work on options and obj directly but you need to create new symbols and assign options and obj to them ?
14:35nooniani think in his example he is just doing that so he has a more concise name to use in the body of the macro but still takes an argument with a name that conveys what is should be
14:35OscarZok
14:36OscarZi better read up on macros anyway :)
14:37puredangerno, it's more important than naming - it has to do with what runs at compile time vs in the generated code
14:37puredangerI am not an expert macrologist btw - there are far better people for that on this channel
14:37OscarZdo you have any recommendations for some good articles on that black magic?
14:38noonianah right, since obj could be an expression that returns an object and you wouldnt want that to run more tahn once
14:38puredangerthere's a new prag press book
14:38sdegutisWould a Clojure file that only uses Java objects and Java method calls have the same performance as the equivalent Java file?
14:38puredangersdegutis: the generated bytecode is not identical, but it's very similar
14:38sdegutisMy theory is that, since it would only use Java classes and no Clojure (clojure.core or anything else) constructs, it should be equivalent to the Java code in terms of performance.
14:38stuartsierrasdegutis: In a contrived microbenchmark, no. In real-world application code, yes.
14:39puredangerit's similar
14:39sdegutisI suppose the main problem is in using Clojure literals that have a Java box instead of a Java scalar.
14:39sdegutis(Which would thus rely on some of the Clojure runtime)
14:39amalloyyou can use primitives if you're careful
14:39amalloyas long as you only want long and double
14:39csd_puredanger: thx Long/toBinaryString made things a lot easier
14:40puredangeramalloy: which can be particularly challenging in interop with Java apis that rely on int (like String, collections, etc)
14:40puredangerI have even seen the number of checkcast bytecode calls make a difference in a hot loop, and I think in some cases the Clojure compiler overdoes that
14:42puredangerI ran into that on Alioth comparing effectively the same bytecode generated from Java, Scala, and Clojure
14:42amalloyyeah, it casts every time it needs to call a method instead of once at the beginning of a loop or whatever
14:42clojurebotPardon?
14:44amalloypuredanger: i always forget, you can actually even get a lot done with primitive ints if you don't mind a lot of extra typing
14:44puredangerif you're careful, yes :)
14:44puredangerif you happen to let an (int …) the compiler will really make an int and use it inside the let iirc
14:45stuartsierraI thought that stopped working after invokePrim was added?
14:45puredangerstuartsierra: it works in a very narrow scope of cases
14:46puredangermight even be accidental for all I know
14:46stuartsierra:)
14:46amalloypuredanger: you can definitely do it, but in that case the compiler still emits calls to Numbers/addInt or whatever
14:46amalloybut if you're very nice, you can get primitive bytecode ops like iadd: (fn [] (unchecked-multiply-int (unchecked-add-int (unchecked-int 1) (unchecked-int 1)) (unchecked-int 1)))
14:47amalloydisassembles to https://www.refheap.com/36dd6bcd14ac1e257f399c702
14:47puredangeryeah, I'm talking about making a call into a Java method
14:47puredangeryes, I've done some of that too :)
14:47stuartsierra(no-really-clojure-i-want-an-int 42)
14:47amalloy(inc stuartsierra)
14:47lazybot⇒ 15
14:48stuartsierraArray indices, that was the one that I ran into.
14:52puredangeryeah, calling into the string, array, and collection apis are the ones I see all the time
14:52puredangerand really, the jvm does a super job of optimizing away l2i. but it's not free.
14:53puredangerI fought this byte-related one and lost in alioth - http://dev.clojure.org/jira/browse/CLJ-1342
14:55seangrovednolen_: First pass at chainable in cljs - works nicely, probably some bugs but have to run https://www.refheap.com/95854
15:37dagda1_can anyone improve this syntax for me (apply str (vec (re-seq #"[A-Z]" s)))
15:38dagda1_what I have works but using apply str and vec seems verbose
15:39justin_smithwhy do you need vec?
15:39SagiCZ1dagda1_: you can do str/join
15:39SagiCZ1instead of apply str
15:40dagda1_SagiCZ1 great, thanks and I don't need the vec
15:40hiredmanwhat is that supposed to do?
15:40dagda1_hiredman: return a string with only capitals
15:40hiredmanfiltering?
15:40dagda1_hiredman: you could use filter
15:41justin_smith&(apply str (re-seq #"[A-Z]" "This Is A Test"))
15:41lazybot⇒ "TIAT"
15:41Muonicis anyone familiar with paredit.vim? I am wondering if it it is possible to type array classes like [B?
15:41Muonici can't get rid of the closing square bracket
15:42justin_smithMuonic: it does that even inside a string?
15:42Muonicbut then its inside a string
15:42justin_smithit should be
15:42justin_smithdoes [B work as a type hint outside a string?
15:43justin_smithI would think the reader would choke on it
15:43justin_smithI know it works as a string as a type hint
15:43amalloyjustin_smith: you can't use it outside of a string
15:43MuonicI actually want to use type as a multimethod switch
15:43Muonicon type
15:43justin_smithamalloy: yeah, that's what I thought
15:43justin_smithMuonic: then you need ##(Class/forName "[B")
15:43lazybot⇒ [B
15:44Muonick, thx
15:44justin_smithbut case won't like that, as it's not a literal, but cond will still work
15:44justin_smithalso, if you are switching on class, consider using a multimethod instead
15:45amalloyjustin_smith: Muonic said multimethod already
15:48justin_smithamalloy: d'oh
15:52celwellHi, can't figure out why I'm able to run fine with 'lein ring server', but 'lein ring uberwar' is throwing a NullPointerException. I've narrowed it down to a particular dependency (clj-facebook-graph), but I'm at a loss to correct the issue. Any thoughts?
15:54gfrederickscelwell: do you have a stacktrace?
15:55celwellgfredericks: https://gist.github.com/celwell/807005f39cd15ae20be5
15:57justin_smithcelwell: what is "purple" ?
15:57celwellproject name
15:58celwellthis is that namespace that is listed in the trace: (ns purple.users
15:58celwell (:use clj-facebook-graph.auth
15:58celwell gapi.core)
16:01hiredmandagda1_: I don't think I would do that with a regex, I would likely do something like (apply str (filter #(Character/is %) "..."))
16:01hiredmanCharacter/isUpperCase or whatever the static method is
16:02hiredmannot that there is anything wrong with the regex
16:08celwelljustin_smith: I can paypal/venmo you some $ if you can fix it today/tomorrow. Whatever you think is fair. I'll give you repo access. Not sure if appropriate to solicit on irc?
16:11justin_smithwell, usually that would be done via /msg
16:11celwellI'm not experienced in irc, whoops
16:15amalloyi've never heard of venmo. am i an old person now, out of touch with the newfangled hophip gizmos?
16:15hellofunkjustin_smith: that shipment of powder you asked for came in but Sally said she wasn't feeling well and the cops were everywhere, so we are delaying
16:16hellofunkjustin_smith: whoops, sorry. supposed to be a /msg
16:16celwellamalloy: it's great for small transfers no fee
16:16celwellhellofunk: hey don't make fun of me ;)
16:17hellofunkcelwell: ;)
16:26puredangerlol
16:30justin_smithcelwell: did you see my reply to your /msg or are you having continued unfamiliarity with your irc client?
16:31celwelljustin_smith: ha, apparently I am. maybe M-x irc is bad or i am. can you email me at elwell dot christopher on gmail?
16:33justin_smithI'll get in touch, sure thing
16:42sdegutisWhat's a reasonable way to make state implicit in Clojure?
16:43weavejestersdegutis: should state be implicit?
16:43hellofunksdegutis: what does that mean?
16:43mi6x3m-altsdegutis: don't say implicit state in this channel :)
16:43tbaldridge~gourds!
16:43clojurebotNo entiendo
16:44SagiCZ1~guards!
16:44clojurebotexcusez-moi
16:44hellofunk~gorbachev!
16:44clojurebotNo entiendo
16:44mi6x3m-altsdegutis: http://clojure.org/transients
16:45sdegutisThere are many times when I want to write a convenience layer around some functionality, and in more OOP-focused languages, I would put the shared state in an immutable instance variable that can be given in the constructor.
16:45hiredman~gourds
16:45clojurebotSQUEEZE HIM!
16:45amalloyhiredman: ~guards excited people so much they remember it with an exclamation point, it seems
16:45SagiCZ1you can keep state in some atom
16:45sdegutisFor an example, I want to operate on a database from within many related functions, and in Clojure, I must add an extra database parameter to them all. Whereas I would typically put that in an instance variable on a class for the related functions, and make these into methods.
16:46stuartsierrasdegutis: Function arguments are good for you. https://github.com/stuartsierra/component
16:46SagiCZ1sdegutis: you could also utilise closure..
16:46tbaldridgesdegutis: that's why I like stuartsierra's component lib, you get "implicit" state in a natural way
16:46sdegutisstuartsierra: Thank you for the advice. I have been using Clojure very idiomatically for a few years now, and have not found the popular style to be a good one in my experience.
16:46hiredmanit is exciting
16:46sdegutisSagiCZ1: Ah, that is a reasonable idea, thank you very much.
16:47tbaldridgesdegutis: with something like component you get polymorphism combined with "implicit state". It ends up being quite natural and easy to extend.
16:48sdegutisIt looks like defrecord may even possibly be what I'm after.
16:48sdegutisBut I'll check out component nonetheless.
16:49justin_smithdefrecord defines an immutable record datatype, I don't see what would be so stateful about that on its own
16:49sdegutisI am usually skeptical of using third party libraries however, as they can become discontinued and unsupported at any given time.
16:49sdegutisjustin_smith: I don't care about mutating its state, only making it accessible while generally implicit.
16:49hellofunksdegutis: libraries do not disappear from clojars, even if authors don't do anything with them any more.
16:50amalloyhellofunk: that's generally my opinion too, but being supported is not nothing: future bugs being fixed is nice
16:50sdegutishellofunk: but they will not receive potential bugfixes and upgrades for future Clojure compatibility and other such things they may need; thus by adopting one, I make my employer have full but implicit ownership of it
16:50justin_smithsdegutis: if it never mutates, just put it in a var, but I don't know why you'd even call that state
16:50sdegutisjustin_smith: I mean per-instance
16:51SagiCZ1i have a big java project and i want to build gui for it in clojure.. the project is managed by maven.. what is the best way to put clojure there? i would probably try to stick with calling java from clojure as the gui is the entry point of the application
16:51hellofunkamalloy: of course, but i'd be much more concerned if a library that served important functionality had the possiblity of just evaporating and no longer being available in lein builds
16:51sdegutisjustin_smith: Think of an immutable property on a class instance which is only set in the initializer/constructor but can be used in instance methods -- this is what I want in Clojure.
16:51tbaldridgesdegutis: component is like 100 lines of code...it's not that hard to maintain.
16:51justin_smithsdegutis: yeah, defrecord
16:51justin_smithor just a map
16:52sdegutistbaldridge: ah I see; then I may simply incorporate it wholesale into our application, if its license permits
16:52hellofunkSagiCZ1: these days i'm convinced that all GUIs should be cljs front ends :)
16:52SagiCZ1hellofunk: not sure what you mean.. i was thinking seesaw.. i liked it in my last project
16:52sverihellofunk: +1
16:53tbaldridgesdegutis: or just don't worry about it at all, if someday it becomes a problem it's not going to be hard to rewrite it from scratch or maintain it on your own.
16:53hellofunkSagiCZ1: i mean, your clojure code runs on the web server, even if it is a local server on your laptop or whatever. your GUI runs in a web browser and communicates with it. you get much better GUIs with the web these days then you will ever get with seesaw
16:54SagiCZ1hellofunk: wow that sounds bizzare.. so it would run in a browser<
16:54hellofunkSagiCZ1: the question: would you rather write Java for your GUI in yucky seesaw, or write awesome clojurescript for a much better GUI ?
16:54hellofunkSagiCZ1: you realize that many of the apps you are probably using these days are actually web technologies. there is nothing bizarre about it.
16:54tbaldridgeI'd take swing/javafx any day over the crap that is HTML/CSS </rant>
16:55hellofunkSagiCZ1: take Light Table for instance. or many other code editors now. they are shallow web shells that are really just browsers
16:55sveriSagiCZ1: hellofunk maybe you know this one? http://www.kalzumeus.com/2009/09/05/desktop-aps-versus-web-apps/ its pretty convincing
16:55hellofunktbaldridge: Om and cljs changed my opinion real fast on that
16:55tbaldridgeOm and cljs have nothing to do with HTML and CSS
16:55SagiCZ1hellofunk: but lighttable does not run in a browser!.. the main portion of the app will be a viewport window with javas LWGJL 3d engine.. is that a problem?
16:55tbaldridgeThe layout and page oriented nature of HTML is what's horrible.
16:55hellofunktbaldridge: my point is that you can write solely in cljs and get a great GUI experience
16:56mi6x3m-altsveri: just one side of the story
16:56hellofunkSagiCZ1: whether it is in a real browser or a shell like LT is up to you, but it's a concept worth exploring before you give yourself whole hog to seesaw
16:56tbaldridgeI spent quite a lot of time doing Silverlight/WPF programming (close to JavaFX), and the layout, and rapid development that those platforms offer blows HTML/CSS away.
16:57sverimi6x3m-alt: of course
16:57hellofunktbaldridge: naw, single-page apps that emulate desktop apps even though there is no real page switching is the way many of us work now.
16:57SagiCZ1hellofunk: thanks for the ideas, sounds great.. what should i google to learn more?
16:57tbaldridgeSagiCZ1: I'd take a look at JavaFX2 if you want a desktop app, it's pretty fast, and comes standard with Java8
16:57hellofunkSagiCZ1: clojurescript
16:58sdegutisAt the top of its introduction page, [component] says it is "for managing the lifecycle of software components" -- this sounds like it has nothing to do with accessing state, and I'm very confused why it would label itself this way if that is what it's good at.
16:58mi6x3m-altsveri: for instance a desktop app is a desktop app, it requires no connection, you leave no trace and you do not need to fire up a password manager to use it first
16:58mi6x3m-altyou also own it
16:58SagiCZ1tbaldridge: javafx has no clojure wrapper :(
16:58mi6x3m-altSagiCZ1: seesaw then
16:58SagiCZ1yeah thats my plan
16:58mi6x3m-altseesaw is great
16:59sverimi6x3m-alt: thats true, but thats only value for the customer, and tbh, most people are accustomed to enter a password somewhere
16:59tbaldridgeSagiCZ1: and I built a wrapper in about a week. But yeah seesaw is good
16:59tbaldridgesdegutis: component lifecycles and implicit state are very closely linked.
16:59mi6x3m-alttbaldridge: usable wrapper around javafx in a week? interesting...
17:00SagiCZ1how can cljs run outside of browser?
17:00tbaldridgeif you have state you need a way to create/destroy that state, that's called lifecycle management
17:00sveriOTOH an autoupdate solves some of the problems desktop apps have
17:00sdegutisThe "A component is similar in spirit" paragraph should be *way* higher.
17:01mi6x3m-altsveri: you cannot convince me but I'm on the other extreme. I do not use web apps
17:01hellofunkSagiCZ1: look at how LT does it if you want. LT is basically a web browser that is running standalone so it doesn't "looK" like a browser
17:01mi6x3m-altI understand the point though
17:01SagiCZ1hellofunk: so is it a modified firefox or whatnot?
17:01sverimi6x3m-alt: it's ok, I don't want to convince you, just showing the positive sides of web apps
17:01mi6x3m-altSagiCZ1: you want a browser component?
17:01hellofunkSagiCZ1: Adobe's new Brackets editor, which i LOVE for HTML/CSS stuff is also another example, open source, of a browser that looks like a desktop app, running standalone
17:02SagiCZ1mi6x3m-alt: no i dont.. i just want a regular offline desktop app.. but hellofunk is suggesting that writing the GUI in clojurescript would be better
17:02sdegutis/cc stuartsierra
17:03hellofunkSagiCZ1: i'm just saying, consider your options. cljs is really amazing these days, and Om and the billions of industry dollars taht have been spent to make browsers powerful runtimes is not trivial
17:03sveriAnd, as always, it depends, I would not want to build a full stack IDE like intellij in the browser
17:03dagda1_why is this false (seq? [4 [5 6]])
17:03SagiCZ1hellofunk: yeah it sounds interesting, i am just trying to grasp the idea, because i would never think of something like that possible.. as in running an app in a browser that looks like regular desktop app
17:03hellofunksveri: yet, you could!
17:04SagiCZ1, (seq? [4 [5 6]])
17:04dagda1_coll? works but I'm confused as to what seq? is
17:04mi6x3m-altjust embed a browser in a desktop app, have the page available in the resources, DONE
17:04clojurebotfalse
17:04hellofunkSagiCZ1: oh man there are sooo many appos these days that are developed that way
17:04sverihellofunk: true, someone wants to work on it? :D
17:04SagiCZ1hellofunk: sounds like living under a rock I have been
17:05SagiCZ1whats the learning curve though? i kinda know about seesaw a little.. would it delay my project a lot?
17:05sveriSagiCZ1: did you code javascript before?
17:05SagiCZ1sveri: a little bit of js with jquery, yeah
17:05amalloydagda1_: seq? tests, basically, whether something would print with ()s
17:06hellofunksveri: SagiCZ1: i know very little JS. you don't need JS. cljs is all you need. cljs is totally amazing
17:07SagiCZ1hellofunk: YOU EXCITE ME! LETS DO THIS! haha
17:07hellofunkyou know how amazing cljs is? i started a huge project a year ago with the intention that cljs would be my front end, clj on server my back end. guess what? turns out cljs is so great, i've got nearly ALL of it running in the browser instead!
17:07sveriSagiCZ1: ĥellofunk but you might need some js interop, It took me quite some time to integrate some js libraries like a calendar for instance, I mean, if you know how to do it, it's easy, but there is not much docs about this out there
17:07hellofunksveri: interop is not big deal. once you learn the little techniques, it's easy. #clojurescript is there to help
17:08sverihellofunk: that's what I basically said, still, there will be some delay in the beginning
17:08SagiCZ1but can i call my ugly java from cljs?
17:08tbaldridgehellofunk: you're missing the big problem though. To write a good GUI with cljs you need to know CSS and HTML as well.
17:08hellofunkSagiCZ1: well, you can call down to the server, which is clj, and that can run Java if you need it.
17:09tbaldridgeIf you don't know those, or don't know them well, that can be a problem.
17:09hellofunktbaldridge: any GUI requires some help from someone who knows how to make things look pretty.
17:09SagiCZ1hellofunk: what about browser compatiblity? is that not an issue?
17:09tbaldridgehellofunk: not if layout has sane defaults, hence why I recommend stuff like seesaw for quick and dirty client GUIs
17:09hellofunkSagiCZ1: if you are looking for a standalone desktop-like app, then compatibility is no issue at all because no one will ever run your app in an actual browser like Chrome, Firefox, etc
17:09tbaldridgeno need for all the complexity of a "browser acting like a desktop app"
17:10hellofunktbaldridge: you can learn the basics of HTML layout in 1 day that will cover nearly any interface of moderate complexity
17:10tbaldridgeHAH!
17:10SagiCZ1hellofunk: and would it be possible to run that 3d viewport in it and interact with it?
17:10tbaldridgeyou jest
17:10amalloy<table>
17:10hellofunktbaldridge: no i don't, BUT you have to actually want to learn it
17:10nooniani believe cljs is compiled to js that runs fine on older browsers
17:10hellofunkSagiCZ1: have you seen all the 3d games using WebGL on the web today?
17:11sdegutisWhy does the docs for "clojure.core/defrecord" say "Alpha - subject to change" ?
17:11hellofunkyou get hardware accelerated graphics now in the browser!!
17:11noonianbut i agree that if you just want a simple gui then seesaw is probably a quicker route
17:11SagiCZ1hellofunk: they look nothing like desktop apps with 3d viewports such as 3dsMax and the like..
17:11SagiCZ1and anything more demanding requires unity plugin
17:12hellofunkSagiCZ1: all the good WebGL demos I've seen are quite high quality and stand up close to lots of desktop apps. are they like a game console? not quite yet, but getting there
17:12tbaldridgehellofunk: name me one commercial game written in WebGL
17:12amalloy$google one commercial game written in WebGL
17:12lazybot[30 amazing examples of WebGL in action | 3D | Creative Bloq] http://www.creativebloq.com/3d/30-amazing-examples-webgl-action-6142954
17:12hellofunktbaldridge: commercial? i don't know, i'm not a big gamer. i think that's missing the point though
17:12SagiCZ1hellofunk: but the 3d part and rendering is already done and it is using java's LWGJL engine.. i am not sure i can display that viewport using browser.. i think the server would have to send every frame to cljs
17:13hellofunkSagiCZ1: well loooook, i'm not trying to tell you how to write your app. you haven't paid me for that. but i'm just saying, people need to be aware of what is happening right now with browser and cljs, because it warrants serious consideration
17:13SagiCZ1LWGJL is using OpenGL can I run that in a browser? but maybe there is a WebGL alternative.. i dunno
17:14tbaldridgeSagiCZ1: and I'm saying that if all you want is a GUI, and you already know Clojure on the JVM, minimize your risk, keep it all on the JVM.
17:14hellofunkSagiCZ1: just do your research if you are interested. something to think about.
17:14SagiCZ1hellofunk: ok sorry
17:14SagiCZ1tbaldridge: thanks for your opinion.. i will have to do some research
17:15tbaldridgeyep, in the end you're the only one who can answer these questions
17:15hellofunkbtw dnolen has been tearing it up with cljs over the last couple weeks. it is a true platform for the future!
17:16tbaldridge(for a certain sub-set of all computing problems)
17:18sdegutisThe [component] lib doesn't seem to hide any state within the functions you use it in -- you still have to pass the component around.
17:18tbaldridgesdegutis: hidden state is invisible (and un-debuggable) state. Also you get polymorphism for free with component. It's trivial to swap in a new DB because everything goes through a component.
17:19sdegutisI have a ton of functions that take "db" as the first parameter, and I'd like to get rid of this parameter while still being able to access the "db" from each of them.
17:19noonianyes, but using the dependency injection system it provides you will just need to pass in a single argument that has all the state you need
17:19dnolen_SagiCZ1: atom-shell might get there eventually wrt doing traditional UI work w/ CLJS, https://github.com/daveray/seesaw might be better a safe bet
17:19sdegutisThe two solutions I can think of are closures and currying.
17:19tbaldridgeboth hide state...you really don't want to do that
17:19dnolen_SagiCZ1: mfikes work w/ JavaScriptCore & Objective-C demonstrate for OS X stuff can def be productive w/ CLJS, esp. if Java isn't an option and you're OK w/ just OS X
17:19amalloyi don't think currying is relevant here
17:19sdegutisBut currying (i.e. partial functions) seems to work in the reverse, giving convenience to the function's caller, not the function definitino.
17:19amalloyit's just another word to say closure
17:20sdegutistbaldridge: Why do you insist that I don't want to do this?
17:20nooniancould also write a with-db macro which is basically thread-first
17:20tbaldridgesdegutis: because when you hide state it's super, super hard to debug/maintain code.
17:20tbaldridgeWould you rather have this:
17:21tbaldridge, {:state 42}
17:21tbaldridgeor this:
17:21clojurebot{:state 42}
17:21SagiCZ1dnolen_: who is OK with just OS X? I am not ok with that at all haha.. thanks for suggestions though
17:21tbaldridge,(fn [] {:state 42})
17:21clojurebot#<sandbox$eval49$fn__50 sandbox$eval49$fn__50@5a9f8e82>
17:21noonianits just so much easier to reason about and compose pure functions than ones that rely on some sort of stateful context
17:21dnolen_SagiCZ1: lots of people are, no idea what your goals are - just free suggestions
17:22amalloytbaldridge: by the way, you can evaluate things in the middle of a message, eg ##(fn [] {:state 42})
17:22lazybot⇒ #<sandbox11388$eval45518$fn__45519 sandbox11388$eval45518$fn__45519@467f4f6f>
17:22sdegutistbaldridge: that anonymous function seems irrelevant
17:22SagiCZ1dnolen_: thank you
17:22tbaldridgebut that's exactly what you are trying to do with talk about closures, you're hiding state inside functions.
17:22sdegutisnoonian: I'll have to respectfully disagree.
17:23tbaldridgesdegutis: you can disagree, that doesn't make you right.
17:23sdegutistbaldridge: Right. But I see no problem with that. We have a comprehensive test suite that gives us full assurance of our code.
17:24sdegutistbaldridge: I have reasons behind my opinion just like you have reasons behind yours. Neither of us is right or wrong.
17:24tbaldridgehttp://s2.quickmeme.com/img/67/671256e55e7b94c478f77c4dd2aa2641afb98ec711bc9be66307aab25cd881fe.jpg
17:24SagiCZ1i think that sdegutis is right in that passing the "state" around in every function can be become very tedious
17:24sdegutisNot only tedious, but it precludes certain patterns.
17:25nooniantests can only prove the existence of bugs, not prove that they don
17:25sdegutisIf I have a "db" argument in the beginning of my function, I can't idiomatically use that function with certain other clojure.core functions.
17:25nooniandon't exist
17:25tbaldridge"we have a comprehensive test suite for that..." that's called guard-rails programming...
17:25sdegutisHow long have I been in #clojure?
17:25tbaldridgesure you can, you just use (partial foo db) whenever you need to do that.
17:25sdegutisTo how many people have I said the very same things you're now saying to me?
17:26sdegutisAm I ignorant of this philosophy you're trying to explain to me?
17:26tbaldridgeapparently :-)
17:26sdegutisIt's clear that I'm not. So there must be some other reason I've changed my mind about it.
17:26sdegutisSo just give me the benefit of the doubt.
17:27tbaldridgeI'm well aware that you've decided to throw out certain aspects of FP. So I guess I'll exit the conversation now as it's pretty pointless.
17:27nooniani agree that explicitly passing arguments can get out of hand if each dependency is an argument, but the component lib addresses that so that you never will need more than one argument with all the stateful deps in it
17:28SagiCZ1noonian: cant you achieve the same thing simply by having a simple state map that has all the state variables in it?
17:28tbaldridgeYou're programming in a functional language. So perhaps try to just stick with pure functions. It's worked out quite well on all the (rather large) codebases I've worked on for some time.
17:29tbaldridgeSome people like stuartsierra have invested years of their lives into research and development of libraries that address these exact issues, and component is the result. Now it's a free country and you're free to reject all this research after only reading up on it for about half an hour. But I'll say its foolish to do so.
17:29tbaldridgeAnd I'm done.
17:29noonianSagiCZ1: yeah, thats basically what component is doing; the protocols and lib functions allow you to create and manage the lifecycle of your state without having to use clojure reference types except once at the top level in your app where you hold the entire state of your system. and don't even need mutability there if you start it and never stop it
17:30SagiCZ1noonian: that actually does sound pretty handy, glad i bookmarked it
17:30sdegutisnoonian: I see how that can be helpful, but it requires monolithic adoption which makes it a very unlikely choice for my situation, plus it does not get rid of the function argument itself, it merely combines several parameters into one, and that's all.
17:31SagiCZ1does clojure's map implement java.util.Map?
17:31tbaldridgeyes
17:31SagiCZ1so cool
17:31arohner,(ancestors (class {}))
17:31clojurebot#{clojure.lang.IPersistentMap java.lang.Iterable clojure.lang.APersistentMap clojure.lang.MapEquivalence clojure.lang.IObj ...}
17:32sdegutistbaldridge: You're apparently taking great offense at my philosophy and I have no idea why. This isn't religion, it's just programming.
17:32poppingtonicdnolen_: I'm reading your article http://swannodette.github.io/2015/01/02/the-essence-of-clojurescript-redux/ but whenever I start a repl with ./scripts/repl I run into a "java.net.ConnectException, Connection refused".
17:32dbacarHi, did anyone here encounter a FilenotfoundException during (refresh) while using tools.namespace? Any ideas why?
17:32nooniansdegutis: you're right; if you really can't stand an extra argument for your functions stateful dependencies then you will need to use another solution
17:33stuartsierradbacar: Known issue, use `refresh-all` to fix.
17:33noonianit sounds like you want dynamic vars, but then you start having the problems that component and functional programming strive to avoid
17:33SagiCZ1sdegutis: you mentioned you could do something like this via constructor in java.. couldnt you imitate classes with namespaces? and use maybe multimethod dispatching and things like that?
17:34sdegutisSagiCZ1: hmm maybe, good idea
17:34sdegutisRight now I'm mostly leaning towards building closures.
17:34_KryDos_Hi guys. I'm trying to learn Clojure and at the moment I'm trying to rewrite socket server, which was written in Node.JS, to Clojure. In Nodejs' socket server I had a special array where I'm storing all active connections. My question is how can I implement it using Clojure? I thought, in Clojure, I have no ability have global array with all connections
17:35_KryDos_And how can I change it? Of course I can't. Can I use Actors for this? This is good solution?
17:35exaptic_KryDos_: well, you do but global state is generally a bad idea
17:36_KryDos_exaptic: exactly... and I just can't understand how should I solve this problem using Clojure
17:36exaptic_KryDos_: these are web sockets or the old school kind?
17:36poppingtonic_KryDos_: what do you want to use Actors for?
17:37_KryDos_exaptic: old school kind
17:37SagiCZ1,(byte 0xFF)
17:37clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for byte: 255>
17:37exaptic_KryDos_: only just googled this up, but could be useful: https://github.com/tonsky/net.async
17:37poppingtonicwhat particular subproblem of 'writing a socket server' would you solve with them?
17:38SagiCZ1(byte) 0xAC works in java but (byte 0xAC) does not work in clojure, what am i doing wrong?
17:39amalloy,(unchecked-byte 0xac)
17:39clojurebot-84
17:39amalloythe byte function does bounds checking
17:39noonian_KryDos_: you could use an atom to store the global connections if you can't figure out how to do it without global state
17:39_KryDos_exaptic: thank you. I'm already have a library for sockets. In my application I have many connections. And one of them can send message to the socket server with a special parameters. I want read these parameters and send a message to the particular socket-connection (which I'm going to get from list/map/vector)
17:39_KryDos_noonian: thank you so much. I will try
17:39SagiCZ1amalloy: thanks
17:39sdegutistbaldridge: and I never meant to show any lack of respect to stuartsierra and his work, I'm sure it's very valuable to those who have use for it, so I don't know where that part of your rant came from
17:40justin_smith_KryDos_: in many cases, keeping a list of active connections is a workaround for the fact that you can't simply have a separate asynchronous task handling each connection
17:40SagiCZ1cfleming: are you around by any chance?
17:40_KryDos_justin_smith: hm... sound reasonable...
17:40justin_smith_KryDos_: we have actual threads, so often we can skip the global list of things that are active, and just spawn something that handles it as long as it is active
17:41dbacarstuartsierra: In repl I executed (require '[clojure.tools.namespace.repl :refer [refresh refresh-all]]) and then (refresh-all) without restarting repl, but i get the same error.
17:41justin_smithwhich doesn't have to mean one thread per request - there can be a thread pool or something like core.async
17:41_KryDos_justin_smith: but how can I organise messaging between connections? (sorry I'm just keeping think OOP way)
17:42nooniani'm not sure if that would fix his problem since he will need the list of active connections in order to route the incomming messages to the correct open sockets
17:42justin_smith_KryDos_: core.async uses channels
17:42sdegutisIs it possible to bind a name in a macro, like so? (defmacro foo [& body] `(let [f 3] ~@body)) (foo (println f))
17:42stuartsierradbacar: Try restarting the REPL. The state-tracker isn't perfect. If there's still an error after a clean REPL restart, there's something wrong with your file names or ns declarations.
17:42exaptic_KryDos_: yeah what justin_smith is saying -- that way you don't need to manually juggle which state goes with which connection
17:42justin_smith_KryDos_: which are an abstraction over queues, there are a few options using queues directly as well
17:42_KryDos_exaptic, justin_smith you guys are awesome
17:42nooniansdegutis: yes but it is frowned upon unless the macro consumer supplies the name
17:42amalloysdegutis: ~'f, but of course be careful, this sort of thing leads to muddy code
17:42_KryDos_thank you so much. I will try your solutions
17:43sdegutisGood points. I'm not likely to use it, mostly just curious.
17:43justin_smith_KryDos_: mind you, with threads or async blocks or whatever, there is still per-client state, it's just that there is an abstraction in place (the thread pool, the worker group, whatever) that handles the bookkeeping and details for you
17:45justin_smith_KryDos_: I'd compare talking about per-connection state and callbacks in clojure to talking about goto and labels in any modern language: we have good abstractions that make it so you usually don't need to think at that level
17:46justin_smithsometimes you need to mess with it, but usually you can think in simpler terms (functions, thread pool, async tasks, channels)
17:47_KryDos_sounds hard... but, I will definitely try
17:47_KryDos_thank you so much
17:47exapticgl =)
17:47dbacarstuartsierra:Same error, in exception message it says it cant find "hello_world/core/views_ordered.clj on classpath:" , in fact the file is named views-ordered.clj with dash not underscore, do you thnk it may be a problem with dashes in filenames?
17:47stuartsierradbacar: Yes, that's a problem for Clojure generally, not tools.namespace.
17:49dnolen_poppingtonic: are you on a slower machine? There's an outstanding issue to remove the timeout
17:51poppingtonicdnolen_: yes my machine is a slow 1.33GHz Atom. Could you post a link to the issue, please?
17:53andyfdbacar: Clojure lint tool Eastwood can help quickly find file name / namespace mismatches like that, among other things. http://github.com/jonase/eastwood
17:53dbacarstuartsierra:Thanks a lot, "replace hyphens with underscores in filenames", thank you for tools.namespace, real lifesaver.
17:53stuartsierradbacar: You're welcome, glad to hear it's helpful.
17:54dbacarandyf:Thanks a lot, I will certainly give it a try
18:05dnolen_poppingtonic: there might not be a ticket at the moment, the issue is we just use a timeout instead of reading from std out of node process to know it's ready to connect, please open ticket - patch also welcome
18:19justin_smithwhen (.printStackTrace *e) ends with "... 25 more" - what is the most straightforward way to see the 25 more?
18:20poppingtonicdnolen_: doing that.
18:24amalloyjustin_smith: scroll up. they're just the same stacktrace elemnts in one of the parent exceptinos
18:25justin_smithwell that sucks
18:25justin_smiththanks
18:25amalloylike: Exception: foo at a\nb\nc\n Caused by: Exception: bar at x\ny\n... 2 more, the "2 more" there are uh...either a+b or b+c, i forget
18:25justin_smithgot it
18:26justin_smithone of thse stack traces that refuses to map cleanly to my mental model of my code
18:26andyfjustin_smith: If clojure.repl/pst's modifications are acceptable, you can call it with 2nd arg nil
18:26justin_smithnow to track down when and where things are actually helping
18:27justin_smithyeah, pst is much worse than .printStackTrace was in this case
18:30andyfAnd I was wrong about nil, too. Long/MAX_VALUE is closer
18:30justin_smithaha
18:31justin_smithso it turns out I fed transaction data to datomic that makes it get an indexOutOfBoundsException
18:32justin_smithso now I guess I shrink the transaction until I can turn it into a bug report for datomic (at least suggesting they give a cogent error message rather than throwing an exception on my data)
18:37poppingtonicdnolen_: where do you set the timeout?
18:52ghadishaybanandyf: Do you have any scripts I could look at that take patches from JIRA and apply them to a local git repo? There are several "clusters" of bugs around AOT and reducers, would be nice to run tests against the clusters
18:53ghadishaybanandyf: right now my process is manual
18:55andyfghadishayban: I have a semi-hairy Clojure program that automates downloading all patches, and applying each one, one at a time, to a given Clojure source tree, trying to build and test each one, but it doesn't do sets of patches applied at once.
18:56dnolen_poppingtonic: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl/node.clj#L94
18:57dnolen_poppingtonic: you will need to change line 85 to redirect to a buffer and will want to wait on that buffer until you see the server started string produced by https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl/node_repl.js
18:58andyfI can test and write a few instructions for the download-all-patches part, with one example bash script applying 2 or 3 of them, if that would be useful
19:00ghadishaybanandyf: i feel like that would be useful beyond my purposes. being able to apply everything tagged 'aot' or 'reducers' could really help (speed up) testing
19:00ghadishaybanandyf: i bet puredanger would be interested
19:01andyfGotta go now, but please send me an email at andy.fingerhut@gmail.com to remind me to look at that tonight
19:20irctcis there a function that acts as an inverse to partition? so that (--> orignal-seq (partition 4 1) (inverse-partition-func 4 1)) = original-seq?
19:23irctcI get that there is a flatten and take-nth but I'm running into those quite a bit
19:24[blake|I'm trying to figure out Compojure wrap-session middleware. I've got my user logging in, and in my main route file, I see the :user name set. But I don't see where this happens.
19:24[blake|A refheap explaining: https://www.refheap.com/95861
19:26weavejes_[blake|: You might be running into problems because you apply the session middleware twice. Once directly, once via handler/site.
19:28[blake|weavejes_: Yeahhhhhh...so....huh.
19:30[blake|weavejes_: Maybe I'm going about this the wrong way, then. I just wanted to see who the current user was at any point so I could update a value on screen.
19:31weavejes_[blake|: Your example doesn't really explain the problem... All I can see wrong with it is that you have two session middlewares, which will likely cause problems.
19:31[blake|I would've thought middleware would be the way to go, but if the session-wrap is occurring inside handler/site, I never see it.
19:32[blake|weavejes_: Well, I've got all these routes in my app-routes routine, but no matter what, I want the current user to be updated/reflected on the page.
19:32weavejes_[blake|: Is "sesh/wrap-session" the Ring session middleware?
19:32weavejes_[blake|: Maybe I've misunderstood your example.
19:34[blake|weavejes_: Yes, sesh is ring.middleware.session.
19:34[blake|I took it out and it made no difference, so I guess I didn't need it...
19:35weavejes_The handler/site function already includes the session middleware.
19:36weavejester[blake|: How are you setting the session?
19:37[blake|Like "(assoc (resp/redirect "/") :session {:user username})"
19:37[blake|After a successful login with that username.
19:48warznew to clojure here. what's the best way to find clojure libraries? im looking for possible couchdb libs.
19:49[blake|I usually just google but there is...cross-clj?
19:50bridgethillyerAnd http://www.clojure-toolbox.com/
19:50bridgethillyerAnd https://clojars.org/
19:57warzso lets say my objective is to locate the most-used and actively maintained postgre clojure client library
19:57warzwhere's the best place to do that
19:58amalloyclojure.java.jdbc
19:58amalloyfin
19:59warzok so clojure provides that, but what about my original one of couchdb or something? best place to find that?
19:59hiredmanwarz: I would just google clojure couchdb
19:59hiredmanthen look through the hits for something good
20:02hiredmanif you don't know clojure well it may difficult to make a decision about what is good from a page of google results
20:02hiredmanyou'll be able to make better solutions as you learn and use the language more
20:02warzso there's no go-to place to find the answer to "what are the top few most actively maintened and used libraries for X"?
20:02hiredmanuntil then the best answer is to ask someone who you think knows more
20:03amalloy(inc hiredman)
20:03lazybot⇒ 66
20:03hiredmanwarz: lots of people have made various websites and directories and what not
20:03hiredmanand I have never found them to useful at all
20:03hiredmanto be
20:04bridgethillyerAsking here is perfectly acceptable
20:04bbloomwell there is http://www.clojuresphere.com/
20:05bbloombut yeah, i dunno, arbitrary rankings aren't that useful
20:05hiredmanugh
20:05hiredmanmidje, ye gawds
20:05bbloomyeah, popular means bad just as often as it means good
20:05warzthey're useful imo. can see if a lib has like 1000 downloads versus another that has none.
20:06bbloomlooks like clojuresphere was last indexed in feb 2013
20:06bbloomsooo that's old
20:06warzah, dang
20:06bbloomit's dead b/c it's not useful. more downloads doesn't mean good
20:06bbloomand more "actively maintained" means "less stable"
20:07bbloomyou have to evaluate individual projects for your criteria and evaluate maintainers for yourself
20:07warzi know it doesnt mean good, but it does mean there might be more people who know about it, etc
20:07bbloomor ask ppl who know
20:07bbloommost good clojure libs are small enough that you can help yourself
20:07bbloomif you can't help yourself, the lib is no good :-)
20:18joshua___Anyone know where to find what happened to these? http://dosync.posterous.com/sudoku, http://dosync.posterous.com/friendlier-shorter ... I didn't see them in a list of articles on swans's github.io
20:20amalloyjoshua___: dnolen_'s posterous articles are, as i understand it, irretrievably lost
20:21TEttingerarchive.org?
20:21amalloyit's possible i misunderstood though, so of course dnolen_ is the final authority
20:22hellofunkamalloy: joshua___ i have heard the same, they were not backed up and they did not provide a backup to him
20:22joshua___that really sucks...
20:23amalloybut you're right, it's on archive.org
20:23amalloyhttp://web.archive.org/web/20130511050735/http://dosync.posterous.com/sudoku
20:23amalloyor some of it, at least. i don't know if that's the full article; seems pretty short
20:24joshua___Nevertheless, thanks. I probably should have checked archive.org myself, but I had expected him to have exported his stuff and thought I just was missing the right blog somehow.
20:27hellofunkjoshua___: it was posterious fault.
20:43kevinfish I installed this in chrome on my chromebook and now I can't find how to start it. It seemed to me at one point I found it on the tools menu. Can anyone help me fix it?
20:43kevinfishhttps://chrome.google.com/webstore/detail/clojurescript-repl/lmjjlapjpjeodaadkljnmdfbjpfddchm?utm_source=chrome-app-launcher
20:43kevinfishI have a javascript console on the more tools menu and I think it was right there next to it.
20:47gfredericksamalloy_: it probably linked to a gist originally? just a guess
20:51sdegutisIs there any way to make a Clojure object that's callable by writing pure Clojure code?
20:52gfredericks,((reify clojure.lang.IFn (invoke [_] :hey)))
20:52clojurebot:hey
20:54sdegutisCool thanks.
20:57justin_smith$mail irctc use apply concat instead of flatten
20:57lazybotMessage saved.
21:01hellofunkjustin_smith: that mail business is not a standard irc feature, right? a feature of lazybot just in this room?
21:02justin_smithhellofunk: yes, it's a lazybot plugin, the bot tracks who shows up and sends /msg if you have mail
21:03hellofunkjustin_smith: a while back on #emacs someone was telling me that irc has as mail feature in general
21:03justin_smith$mail hellofunk it's haandy
21:03lazybotMessage saved.
21:04justin_smithoh does it? I don't know of it
21:04hellofunki could be wrong
21:08kenrestivo$mail mail mail
21:08lazybotMessage saved.
21:45travisrodmandoes 1.7 allow annotations on proxied classes?
21:52justin_smithtravisrodman: out of curiosity, what do you need the annotations for?
21:52travisrodmani am writing a dsl, and the proxied classes are consumed by a system that is looking for class-level annotations
21:54travisrodmani am about to start writing the functionality into the proxy code, but before i started, i wanted to double-check that the functionality was not available somewhere, and i was just missing it
21:55justin_smithtravisrodman: that system being some java lib I assume
21:55travisrodmanyes...
21:57justin_smithand so you need to either use gen-class, which allows annotations (or a shim class or...) else you need to re-implement stuff that is already in the java lib
21:57justin_smith?
21:59travisrodmanyeah, I am avoiding gen-class, since I want the functionality to be repl-available, avoiding the fixed classloading behavior once a gen-class is constructed.
22:00travisrodmanjustin_smith: I have seen the behavior available there, but trying to maintain the availability of the code for repl modification
22:01justin_smithright - what about a gen-class shim thhat calls things you can redefine in the repl?
22:01justin_smithclearly not ideal, but maybe workable
22:03travisrodmanjustin_smith: hmm... that is possibly an idea, i had considered it previously from a class perspective, but annotations not being inheritable, that was a no-go, it is an interesting idea
22:04travisrodmanjustin_smith: i could see some issues with code bloat though...
22:04travisrodmanthe dsl produces a dag, and wrapping every class with another class to get annotation faciltiy would be pretty sub-optimal
22:05travisrodmanjustin_smith: i do appreciate the alternative perspective though...
22:08justin_smithyeah, fair enough
22:19TimMc$mail $mail $mail
22:19lazybotMessage saved.
23:24lodinAnyone know of a library that provides a multimethod-like interface to core.match?
23:26sdegutisI have a recursive problem.
23:27sdegutisI want to merge a map with another map which references the new map after the merge within a partial function.
23:28sdegutisThis is what I have so far: https://gist.github.com/sdegutis/06e73ca38f22c7e5673d
23:29sdegutisThis is the one-line version of it: (let [self {:age 29}] (merge self (into {} (for [[nm func] imethods] [nm (partial func self)]))))
23:30justin_smithsdegutis: the easiest way to express a cyclic structure (ie. not a tree, has paths that lead to other parts of the same structure) is an adjacency list
23:30sdegutisIs there any way to somehow make the functions used within the merged map have a reference to "self" being the result of the merge?
23:30sdegutisjustin_smith: Hmmm, thanks I'll look at that word in Google.
23:31justin_smithotherwise you could use promises that deref to other parts of the same structure
23:31sdegutisAnother option I was thinking of was to make it a ref, and deref it at the time of calling the function (within an anonymous function)
23:31justin_smithbut adjacency list form is much cleaner
23:31sdegutisjustin_smith: What would be the benefit of a promise over a ref/atom?
23:31sdegutisjustin_smith: also how is a.l. cleaner?
23:32justin_smithyou knoww a promise is never reassigned
23:32sdegutisjustin_smith: the main benefit of promise/ref/atom over using an adjacency list is that I don't know how to make or use an adjacency list.
23:33justin_smithan adjacency list can have arbitrary loops in its structure and does not need any derefs to represent it
23:34justin_smithyou cann represent super complex networks without tying your code in a knot with recursive refs
23:34sdegutisOh.
23:34lodinsdegutis: Think about how you would write the structure down on paper and draw arrows when a map points to another map. Then have one data structure for the maps, and another for the arrows between the maps.
23:34sdegutisOoooh, I see: I would simply use several maps to represent things.
23:35lodin(Then you can effectively shove this into one structure.)
23:35justin_smithlodin: yeah, that is pretty close to what an adjacency list is, but they are super well descriibed in graph theory
23:36sdegutisThis is the context I plan to use this within, btw: https://gist.github.com/sdegutis/a331db340c6cc3e94b67
23:36lodinjustin_smith: I fear a monad sneaking up on us in this conversation. ;-)
23:36justin_smithsdegutis: adjacency list is one structure, each key is an id, each value contains at least aa list of ids of all children
23:36justin_smithand can contain any othher data you wish
23:37justin_smithlodin: no monads needed I hope
23:37sdegutisIn short: I'm writing a small object-oriented system for Clojure.
23:37justin_smithrofl
23:37justin_smithhave ffun
23:38justin_smiththis bluetoooth keyboard attacheed to my phone keeps repeeating keys
23:38sdegutisThe main goal is to be able to access the method from the object itself, that is, the object would be a map containing its own methods and state.
23:39sdegutisAnother goal is to be able to allow you to access unbound methods from within the class map, and call them by passing an instance as the first parameter.
23:39lodinsdegutis: Prototype objects. Super easy in Clojure.
23:39sdegutislodin: how do you recommend it?
23:39justin_smithstandard solution is to always pass the obbject to the method as the first arg
23:39sdegutisjustin_smith: right, that's what I'm out to fix
23:40sdegutisjustin_smith: I want to be able to use "bound methods" as functions with an implicit self, so that I can pass them to other functions that take a 1-fewer arity
23:40justin_smithI doubt you will find anything simpler, more efficient,or easier to work wiith
23:40sdegutisSimpler or more efficient, you're right. Easier, I dunno.
23:41justin_smithtyping lag: I mean that passing the instance is simpler, efficient, easier to be clear
23:42lodinsdegutis: I'm not sure I get the problem you're trying to fix.
23:42sdegutislodin: One problem is that many of my functions take a first parameter of "db" which is noisy.
23:42justin_smithis it a yak disguised as
23:43sdegutislodin: In an OOP language, I would make that an instance variable and only pass it during initialization.
23:43justin_smith"intuitive"?
23:43sdegutisjustin_smith: I'm well aware that you think my idea is stupid and you think I don't have the faintest clue what I'm talking about. So let's move on.
23:43lodinsdegutis: You can store it in the map. No?
23:43sdegutislodin: what do you mean? are you talking about within the context of plain Clojure, or using an OOP system built in Clojure, or what?
23:44lodinsdegutis: (let [obj {:db the-db-conn :a-method (fn [self] ...)}] ((:a-method obj)))
23:45lodinErr, missed to pass obj.
23:45sdegutislodin: yeah that's basically my implementation right now
23:46sdegutislodin: see https://gist.github.com/sdegutis/a331db340c6cc3e94b67
23:47lodinAh. yes. In :new.
23:48sdegutisThis code was *almost* working fine.
23:48lodinI'd add a (defn call [obj method & args] (apply (get obj method) obj args)), btw.
23:48sdegutisThe problem came when I tried to access an instance method from within another instance method.
23:48lodinHuh?
23:48sdegutisIt did not have a "self" that contained instance methods, because during the merge in :new, the partial took the plain version of self.
23:49sdegutisSo line 4 failed since (:proper-name self) was nil.
23:49sdegutisI was hoping to find a way to do this without splitting it into multiple maps, one for state and one for methods. But I think that's impossible.
23:50lodinWhy not just use (call bob :greet) everywhere?
23:50sdegutisBecause I want to be able to pass (:greet bob) as a function that takes 0 arguments, into something else.
23:50lodinsdegutis: That's where you use partial.
23:51sdegutisBut I am using partial on line 12 -- oh wait this version isn't.
23:51sdegutisYeah I was using partial at first. No difference.
23:52lodinSo you want to call an instance method from where you only have access to the zero-arity function?
23:52lodinsdegutis: I mean like (defn method->func [obj method] (partial (get obj method) obj)).
23:54sdegutisRight, basically.
23:55sdegutisAlso I want access to the function from the object itself, as a field or map key.
23:55lodinSo when you need to pass (:greet bob) as a function, you pass (method->func bob :greet) instead.
23:56sdegutisThat's a good idea.
23:56sdegutisAlthough I'd prefer to have no need for external functions like method->func.
23:56lodinsdegutis: Yes you do. ;-)
23:56sdegutishm?
23:57sdegutisI do have need you mean?
23:57lodinI would think so.
23:57sdegutisI am determined to figure out a way to allow (:greet bob) give me a partialed function.
23:58sdegutis(which includes itself as the first value)
23:58lodinI mean, you could get creative by defining your own type and implement IFn or whatever.
23:58sdegutisHow? Using reify?
23:58lodinsdegutis: You can do it like (bob :greet) then.
23:58sdegutisThat would be so cool.
23:59lodinThe reason (:foo m) works is because clojure.lang.Keyword implements IFn or whichever interface it is.
23:59lodinAnd maps implement the function interface too, which is why (m :foo) works.