#clojure logs

2014-12-03

00:00kenrestivoso (assoc feh :meh "stuff!") makes more sense, you'll get {:meh "stuff!" ...}
00:00TEttingerlazybot?
00:00clojurebotlazybot is a lazybut
00:00kenrestivohahaha
00:00justin_smithkenrestivo: right, and the ->> macro is supplying that arg
00:00justin_smithkenrestivo: see my code above which was the subject of that exchange
00:00TEttingeryou meant lasericus I hope, but he quit
00:00kenrestivooh, well.
00:07dviramonteshi anyone know what the equivalent of swap is for om ?
00:07dviramontesswap!*
00:08dnolen_dviramontes: transact!, you can also swap! the atom, not you'll miss out on some things - may or may not matter future.
00:11dviramontes@dnolen_ thanks!
00:15dviramontes@dnolen_ pretty new to cljs / om. When i do om/transact! my updates stop working - when i switch back to swap! it works again. Could it be because the atom is too simple of a data structure ? meaning : (def app-state (atom {:value "text"})
00:16dnolen_dviramontes: how are you using transact! ? the signature is unfortunately different from swap!
00:16dviramontesohhh that might be why
00:17dviramontesupdate function looks like this : (om/transact! app-state assoc :value data)
00:18dnolen_dviramontes: transact! doesn't take an atom, it takes a cursor into the app-state
00:18dnolen_dviramontes: I really recommend going through the tutorial, it will be much easier going
00:19dviramonteslol, yeah you're right. Thanks for the help!
01:27kenrestivoare there any special gotchas when making function calls outside of a go-loop?
01:54andyfI?ve not used core.async, but I thought all of the gotchas were inside of the go loops. Well, and that some core.async-specific calls can only be made inside of go loops
01:59kenrestivoit's been fascinating. i'm now considering using async chan so serialize access to a resource instead of using agents
02:00kenrestivos/so/to/
02:08kenrestivoyeah, i'm making calls from inside a go-loop, to functions outside the go-loop, and i have a feeling this could end in tears.
02:33dysfunanything involving asynchronicity will usually end in tears. could be worse, you could be using a language that does it less well :)
03:01Empperireally?? https://github.com/vbauer/lein-jslint/blob/master/src/lein_jslint/core.clj#L71
03:01Empperidefault configurations override what you define?
03:01Empperiman
03:03rritochkenrestivo: I haven't yet run into an opportunity to use core.async but it seems that if your concerned about an external call it should be possible to setup a function which sets up an atom change listener which writes the change back to the channel and then launching your extern function in a "future" to write the results back to the atom. At least that is what I'd try.
03:04kenrestivoyeah using atoms/agents/listeners is what i'm used to. this async method is new to me.
03:05kenrestivoi already see a few places where i might rip the async channels out and go back to agents/atoms. but others i'll keep.
03:08rritochkenrestivo: In the "early-days" of asynchronous programming (LPC) long proceses (over 2 seconds) would automatically end in a fatal error so loops would need to monitor time and maintain state variables and a "call later" queue, so if a loop doesn't have time to finish it could resume later when the next "heartbeat" came. All IO would need to be no-blocking though.
03:09rritochkenrestivo: Now you can assume most machines have multiple processors, so sending blocking or potentially blocking code into it's own execution thread is fairly reasonable.
03:09echo-arearritoch: When was the "early-days"?
03:09kenrestivocore.async is only a year old :-)
03:09ddellacostaanyone know how to do a prepared statement in clojure.java.jdbc w/an in where clause?
03:10ddellacostalike, where id in (1, 2, 3, 4) ...I would ideally not have to take my vector and turn it into a string, but if that's the only way...
03:10rritochecho-area: This was about 20 years ago, but as far as I know LPC was the first "engine" that utilized asynchronous programming
03:13rritochhttp://www.mars.org/home/rob/docs/IntermediateLPC/chapter2.html#set_heart_beat
03:14dysfunddellacosta: clojure.java.jdbc is a bit low level. are you sure you don't want something like korma?
03:14ddellacostadysfun: I am using HoneySQL, which does not support the "create table ..." sql I want to use, unfortunately
03:14ddellacostadysfun: and I'm not going to use Korma just for this (or for any reason)
03:14rritochThat link is the core of how it was done back then and may provide some clues of easier ways to do things now. These engines were run on machines with less speed than todays smartphones, so any code that worked then, would be high-performance today.
03:15ddellacostaalas, I just ended up doing join and turning it into a string
03:15ddellacostahopefully that will scale...
03:16ddellacostaprobably will be fine
03:18dysfun"hopefully that will scale". why would joining strings not scale?
03:18dysfuni mean it's hardly nice, but *shrug*
03:22rritochPer the copyright notice that documentation was written exactly 21 years ago. I am not familiar with any asynchronous code before then, but that doesn't mean it doesn't exist.
03:51andyfrritoch: if one?s definition of asynchronous code includes the kinds of programs written in Erlang, it appears early experiments in Erlang go back to the late 1980s.
03:58rritochandyf: Until you mentioned it I've never heard of Erlang, but from what I can see Erlang was used in a lot of proprietary systems. It would be helpful code if any of it has been open sourced. All of LPC was open source though so it is a better refrence. The developers of LPC forbid it's use via the copyright for business purposes so much of the code written in it was published open-source.
03:59whodidthisim sure yesql supports even create table, it's 100% goodtimes
03:59andyfThere are open source Erlang implementations and significant libraries, but still closed-source applications developed using it, as there are closed-source applications developed in most languages.
04:06fairuzHi guys
04:07andyfhowdy
04:10fairuzI have (into [] (map X list-A)). But I need to do dissoc to the result of X. How can I do this?
04:11rritochandyf: I found a decent article comparing Erlang to Go, core.async is based on Go. http://joneisen.tumblr.com/post/38188396218/concurrency-models-go-vs-erlang , As far as I can tell it appears that LPC used functionality more similar to Go as LPC only had one thread, and no virtual threadding.
04:12andyffairuz: You could do (into [] (map (fn [o] (dissoc (X o) :key-to-dissoc)) list-A))
04:12andyfOr some people prefer using comp to compose two functions and create a new one, e.g.
04:12razum2um1is clojure hyphen(-) is preffered to name variables, but in database likely have convention to use underscores - how do you stick with it? (e.g. for example in ruby-land there are usually converters from camelCase in xml to underscores as readability matters more than speed)
04:13andyf(into [] (comp #(dissoc % :key-to-dissoc) X) list-A))
04:13scottjrazum2um1: https://github.com/qerub/camel-snake-kebab maybe
04:14fairuzandyf oh yeah. I'll go to the former first
04:14fairuzthe second is still a bit alien to me :)
04:15andyfThe comp form makes me stop and think a little longer, since it still isn't natural for me after seeing it many times.
04:24razum2um1scottj: thanks
04:28kralnamaste
04:46rritochandyf: It took me a good amount of time to find asynchronous examples in erlang. Erlang is multiprocessing so asynchronous patterns would only be used for optimizations. http://krondo.com/?p=2692 , As far as I can tell Erlang asynchronous development was identical to what I suggested to kenrestivo, launching separate processes from the asynchronous code.
04:57clgvhow do you create a single instance of a typed-struct with vertigo?
05:03rritochDoes rich hickey (the developer of clojure) ever come to this channel? I don't believe I've ever seen him here
05:03SagiCZ1rritoch: he used to
05:03clgvrritoch: very seldom, haven seen him lately
05:03SagiCZ1if you checked out very early ~lazy-logs you can see he was pretty active
05:03clgv$seen rhickey
05:03lazybotrhickey was last seen quitting 76 weeks and 1 day ago.
05:03rritochHmm
05:04SagiCZ1what drove him away? ... guys?
05:04clgvbeing busy? ;)
05:04winkI wouldn't call him "the developer" though. creator, yes :P
05:05rritochWell, I did a lot of research into this problem of running multiple runtimes. I discovered that my OSGi code wasn't creating multiple runtimes no matter what I did since the "import" functionality of OSGi leads to any refrences to RT being resolved by the same classloader
05:05SagiCZ1wink: so do we believe in Clojure creationism?
05:05winkSagiCZ1: that's a good question. afaik it didn't evolve from another language ;)
05:06rritochI found some solutions to the issue, all of which involved making custom classloaders based on functionality in clojure's core that isn't guaranteed to persist into future versions
05:06clgvrritoch: you could use an approach similar to classlojure but be aware that there might be some issues with memory leaks left (maybe they got all fixe dwith 1.6, didnt check)
05:06SagiCZ1wink: no? i thought it was heavily inspired by lisp
05:06clgvSagiCZ1: lol, but it was created, right?
05:06rritochYes, I see everyone ends up with probelems when it comes to data sharing
05:07winkSagiCZ1: I think you should read up on genetics ;)
05:07clgvrritoch: does OSGi support external processes?
05:07SagiCZ1wink: it's a hobby of mine, so i read quite a lot.. i am also fascinated by evolutionary algorithms and genetic programming
05:07clgvrritoch: having the different clojure instances as external processes might be beneficial performance wise as well
05:08rritochclgv: I suppose, but only in the ways that the Java runtime does, by using Pipes, or sockets.
05:09rritochAnyhow, as far as I can tell the need for multiple runtimes boils down to one key feature of clojure, the clojure.lang.Namespace object
05:09winkSagiCZ1: just saying that if you want to have that limping analogy, I think it needs to be a fork or at least share common roots, not ideas.
05:09SagiCZ1wink: i see what you mean, yeah that makes sense
05:10clgvrritoch: you cant have different versions of clojure within the same classloader neither
05:10rritochI'm not sure what the "cost" would be, but if clojure.lang.Namespace was refrenced as an object, and the object associated to the threads via a dynamic variable, I believe it would become possible to have multiple runtimes (each with their own namespace) that would still be able to share data without any problems.
05:11clgvrritoch: sharing data is not a big issue. you can easily share through edn serialization
05:11rritochThis would avoid any classloader trickery, and create multiple (virtual) runtimes, each with their own namespace.
05:11clgvrritoch: I am not convinced how this should work
05:12rritochclgv: Basically, every function in clojure, such as future, which starts a new thread, would "copy" the namespace object refrence into the new thread.
05:13rritochclgv: So starting a new runtime would simply require creating a new namespace object, and replacing the current namespace object refrence with the new one, and any threads spawned from that thread would then use the new namespace object.
05:14rritochclgv: As far as I can tell, vars can have a default value, so any threads without a namespace object refrence could fallback to a root (master) namespace.
05:15rritochSo to get to the point, even if I were to make something like that it would "fork" clojure which is why I'd like to bring up the idea to rich hickey and see what he thinks about it.
05:15clgvrritoch: you are talking of one "namespace" object all the time? do you mean something like a "namespace registration" that holds all defined clojure namespaces?
05:16rritochclgv: Yes
05:16SagiCZ1rritoch: i think there are ways to reach him with such idea
05:16rritochclgv: Currently namespace registration is implemented via static calls to the namespace class.
05:16clgvrritoch: but you wont be able to support different clojure versions anyway, because of the java implementation part
05:18rritochclgv: That is true, it would only have one version of clojure available, but you could still have multiple "namespaces" available to provide multiple runtime environments (of the same version).
05:19rritochclgv: Having multiple versions of clojure communicating with eachother directly would always lead to complications anyhow
05:19rritochclgv: I'm simply looking for a way to isolate modules so they don't have conflicts with namespaces from other modules.
05:20clgvrritoch: I think if the classloader apporach does not suite you, the multiple process approach using EDN to pass data is the simplest/easiest
05:20clgvrritoch: immutant uses the classloader approach for that
05:21rritochclgv: My only problem with the classloader approach is that there's no guarantee of compatiblility with future versions of clojure, and eventually the classloader would end up filled with logic controls based on the clojure version being loaded.
05:21clgvrritoch: why should that be?
05:23clgvrritoch: have a look at how immutant does it - afair there is no clojure version specific stuff
05:23clgvrritoch: except from maybe cleaning up memory leaks of previous clojure versions
05:24rritochclgv: immutant uses shim, I looked into that already, and am considering that as a solution but all shim does is juggle the classloaders
05:25clgvrritoch: yes, but independently of which clojure version is used
05:25rritochclgv: This creates a lot of overhead since each runtime ads 1 second overhead, and you end up with multiple copies of the entire clojure runtime in memory. I believe the footprint of simply having separate namespace registries would be MUCH smaller.
05:27clgvrritoch: but is pretty unlikely to be introduced anytime soon
05:27rritochclgv: As of now I took the easy way out, and avoided the issue all-together. I'm maintaining a registry of classloaders for each module, and switching to the appropriate classloader manually each time a call needs to cross a module boundary.
05:27clgvrritoch: except you fork clojure and do it yourself
05:27clgvwith all the problems associated to that
05:28clgvrritoch: you probably need security managers as well, right?
05:28rritochclgv: Exactly why I'd like to talk to Rich, if I could establish a fork which does this without any new overhead, would he be willing to merge it into the language.
05:30clgvrritoch: you could ask on the mailing lists as well. lots of clojure devs read it
05:31rritochclgv: I'm not sure about the security managers. I haven't yet run into a situation where I needed to use one.
05:32rritochclgv: OSGi provides a list of all modules, and I'm registering the namespace objects of the modules as services so the process is to use OSGi to locate the appropriate model, switch to the classloader registered for that module, and call the functions in that registered namespace that need to be called.
05:33rritochclgv: With this structure though, any module can manipulate namespaces from other modules as soon as those namespaces have been loaded, which is much less than ideal.
05:34rritochclgv: Namespace collissions between modules would be catostrophic.
05:37rritochclgv: My main application is exporting clojure, so no modules need to contain their own runtime, reducing load times significantly, but I realized that because of this the bundle classloader is falling back to the application classloader, so using a shim alone woudln't solve the problem. I would also need a custom classloader to take ownership of all classes required by the clojure RT & Compile
05:38fairuzhye guys. I have something like this. (if-not (nil? A) (B C D) (B X D)). Can I simplify this better? since the only difference is the C and X part
05:38fairuzon nvm
05:38andyffairuz: You can also use (B (if-not (nil? A) C X) D)
05:38fairuzI can just put the test inside
05:39fairuzyeah andyf. sorry
05:39rritochFrom what I've seen so far, assuming you don't need multiple versions of clojure, the most effecient means of managing it would be to change how namespaces are registered. Currently they're registered as static calls to the clojure.lang.Namespace classs.
05:41andyfrritoch: The problem you are trying to solve is making it more memory-efficient to run Clojure code that uses conflicting versions of common namespaces?
05:41rritochTechnically switching environments could be achieved via a simple hack of clojure.lang.Namespace, removing "final" from the declaration of the namespaces static property.
05:42rritochandyf: Yes, basicaly, but I would also want modules to have all of their namespaces hidden from other modules, other than those which hey specifically decide to export.
05:43rritochEither way, simply removing final from clojure.lang.Namespace would still require juggling that object so it seems using thread-local memory for the namespace registrations makes the most sense.
05:47rritochRemoving the final from the namespaces property also creates the potential of making an extremly unstable environment, since any module and/or process could freely change it. Containing changes of the registrations to thread-local memory is what makes the most sense to me.
05:58rritochWhere is clojures official mailing list?
06:00hyPiRionhttps://groups.google.com/forum/#!forum/clojure
06:00rritochhyPiRion: Thanks :)
06:00hyPiRionnp =)
06:24clgvswitching from strings to keywords was a great solution to save memory thanks to interning
06:24clgvand since keywords are fine for all the associated use cases
06:26rritochclgv: What about keywords with spaces? That is a common case where I've had problems with keywords and http forms (clj-http)
06:29rritochclgv: What I find odd is that clojure happily makes keywords out of them, But other than using ##(keyword "My Keyword") in each usage there doesn't seem to be any way to properly handle them.
06:29lazybot⇒ :My Keyword
06:30clgvrritoch: there are no spaces in this scenario. otherwise I would run into trouble with further analysis
06:30rritochclgv: Here is where If ind the problem....
06:30rritoch,(read-string (pr-str (keyword "My Keyword")))
06:30clojurebot:My
06:30clgvrritoch: the missing checks in the `keyword` function are very likely a performance tradeoff
06:32rritochclgv: Well, either way, I didn't realize keywords were more memory efficient, I just use them because my boss prefers them, but I constantly run into problems when there are spaces or reserved symbols invovled
06:32rritoch,(keyword "WebArray[]")
06:32clojurebot:WebArray[]
06:33clgvrritoch: they use interning and hence each keyword exists only as one instance
06:34clgvrritoch: you can achieve the same via fly-weight pattern, but then you have to implement that manually - though it is not that had but it is an additional effort -
06:34clgv*hard
06:49rritochclgv: That would be a good solution to memory management issues. I'm just not a big fan of how keywords deal with various characters. Persionally I think a reversable process of generating keywords would have been better, such as URLEncoding the string, replacing all underscores with %5F, and then replacing all % with underscores.
06:51rritochclgv: I've avoided that because I didn't see any advantage to it, but I recently became aware of the interning, and since there is a memory advantage to it I think I may need to make my own wrapper to the keyword function to provide more complete coverage of all possible strings, since it provides a memory management benefit.
06:51rritochclgv: Unfortunatly it still won't help me much when interfacing with third party libraries.
06:53rritochI ran into interning when trying to figure out ways to produce multiple runtimes environments
06:56clgvrritoch: well the keywords with spaces and similar are not valid keywords according to the "spec"
06:57clgvrritoch: `keyword` just doesn't fail for them
06:57rritochclgv: Well, now that you mention it, a lot of the articles I saw about using classloading tricks to get multiple runtimes running, they ended up having problems with the keywords. One went as far as forking clojure to resolve the issue.
07:23clgvrritoch: which keyword problems did they have?
07:26rritochclgv: I can't find the original article about it, but I found where they posted the fork to the mailing list https://groups.google.com/forum/#!topic/clojure/0AgUIiY8BQ8
07:26rritochclgv: I'm not sure if that has been merged in or not
07:29rritochOk, that is the article, but you have to expand the original email which explains the problems with keywords
07:30clgvrritoch: well, there is one point in the beginning you do not have to share the data structure implementations or their interfaces to share data - as long as the overhead of serialization to EDN (binary with fressian) is acceptable
07:33clgvrritoch: if really large amounts of data need to be shared, you probably need a database service anyway, right?
07:35rritochclgv: I suppose that depends, a common case, for me at least, would be web based chat system, if for example it supported file transfers, the file transfers may be provided by its own module in a separate runtime.
07:36rritochclgv: It would be more efficient to stream the data between the users than to cache it in the filesystem or a database.
07:44rritochclgv: In this case keywords would often be used as chat commands, and the user commands would need to be understood by any module processing the transaction. After seeing these issues though it still seems that having separate namespace registrations would be more efficient, even if it does require some hacking into clojures core.
07:45rritochclgv: I'm also now considering the possiblity of simply extending clojure to provide those features, a solution similar to the shim, accept taking over the operations of all core classes and modifying clojure.core to use the new class names.
07:47rritochclgv: Ideally no clojure apps should be directly manipulating clojure core classes, so technically it should work.
07:49rritochclgv: In theory at least, I for one have code which manipulates clojure core classes to squeeze out new functionality, but that code was never expected to be upgrade-safe.
07:50clgvrritoch: as long as the big effort pays off... I guess I'd stop at this point
07:50rritochclgv: If I was in it for the money I would have quit a long time ago :)
07:50justin_smithrritoch: wouldn't using strings instead of keywords save a lot of problems?
07:51clgvrritoch: ah so this is hobby project?
07:52rritochclgv: Not exactly, I hope to eventually be able to use this for production environments, and clients
07:52rritochclgv: But there's no real loss if it's not successful, since I can always go with alternative platforms, such as ruby
07:55clgvrritoch: when you are working with the namespaces you could take care of transactional loading of namespaces - which clojure does not
07:56clgvrritoch: just in case you need to require namespace dynamically at runtime from more then one thread ;)
07:59rritochclgv: Hmm, so you want namespaces to automatically uninstall after the transaction completes?
07:59clgvrritoch: no. just that they can be loaded safely ;)
08:00clgvrritoch: the process of loading clojure namespaces is not thread safe
08:01rritochclgv: I see, I've never run into a problem with that, but I always use on-demand namespace loading, I first check find-ns before using require in cases of runtime namespace loading.
08:02justin_smithrritoch: require already checks if a namespace is loaded, and that method is still vulnerable to race conditions
08:04joegalloyeah, iirc, the ns exists pretty early in the require process, but before all the code has necessarily been read and loaded into it
08:05yguanhi genius. is there a parallel filter like pmap?
08:05joegalloso thread a could still be loading code into the relatively empty ns, while thread b is off to the races trying to execute against vars that aren't there...
08:07vijaykiranyguan: http://clojure.org/reducers
08:08yguanvijaykiran: thanks!
08:08vijaykiranyguan: I think more appropriate question would be why do you want a parallel filter ?
08:10yguanvijaykiran: i assume if each test is indepedent to each other, they can do the job in parallel. plus if i don't care the order but only the value returns true?
08:10justin_smithvijaykiran: it would make sense if you have a massive sequence of items, and only want to keep a small percentage of them
08:11justin_smithotherwise the coordination of threading will be more expensive than the gains of going parallel
08:13vijaykiranjustin_smith: yes, that's why I was more interested in the problem yguan is solving
08:15rritochThere are multiple ways to load namespaces though, some go through RT some through Compiler so I'm not entirely sure there would be a thread-safe way of loading namespaces and still maintain clojure as dynamic and relatively decent speed.
08:15yguanvijaykiran: i'm given a vec as pixel of image, try to apply a function to find pixels with interesting feature.
08:17rritochYou can also have various threads doing crazy things, such as constructing namespaces at runtime using in-ns.
08:17clgvrritoch: that wont safe you as far as I know
08:18vijaykiranyguan: looks like it fits into "when to use" on the reducers page :)
08:19clgvrritoch: the problem is, that a namespace is found or is marked as existing as soon as the ns-declaration is finished. but at this point its variables do not necessarily exist or do not necessarily refer to the functions they are supposed to
08:20rritochclgv: But that will always be the case since you can always add and remove symbols to/from the namespace at runtime
08:20yguanvijaykiran: ok, first two checked, i'm not sure around 2000000 pixel is "large"...
08:21rritochclgv: It should be the namespace-user's responsiblity to ensure the symbols they need are available.
08:21clgvrritoch: sure. but you'd expect to be able use the functions defined in that namespace file after `require` returns - which is not the case when loading dynamically in parallel
08:22rritochclgv: So basically you want a version of require that hangs, possibly forever, until the symbols it needs are available?
08:23rritochclgv: ex. (require 'some-ns ['sym1 'sym2 ...])
08:25clgvrritoch: no.
08:26clgvrritoch: when you use require to load a namspace dynamically only from one thread, you have the guarantee that as soon as require returns you can use all variables of the namespace
08:27clgvrritoch: and this is not true anymore when you do it in parallel. I have a small lib that fixes that already
08:27rritochclgv: Than don't use require, use load
08:28clgvrritoch: that is no solution
08:28clgvrritoch: then I get different class incarnations with the same name for deftypes and defrecords
08:29clgvrritoch: it's true that there are not that many use cases for loading namespaces dynamically in parallel - but I had one...
08:33rritochclgv: Well, no matter how you slice it, clojure namespaces are dynamic so they won't be thread-safe. Verifying the existance of the symbols you need I believe is the only sure-fire solution. Using require without :reload-all doesn't provide any guarantees
08:33rritochclgv: A in-ns statement, before a require, should be enough to ensure that the symbols you want never get loaded.
08:34justin_smithverifying the existence doesn't suffice if they use declare
08:35clgvrritoch: in my scenario the namespaces to load are all static. there is nothing added or removed at runtime
08:35rritochclgv: Do you have control over the source code that is being loaded?
08:36clgvrritoch: yes. it's deployed as jar
08:36clgvrritoch: well, the problem is solved by making require transactional
08:36rritochclgv: If so I suppose you could alter the metadata as the last part of the source file, then after your require enter an infinite loop that waits for that metadata to be available.
08:37clgvno need to
08:41rritochclgv: Wouldn't making require transactional drastically increase the load time of any application with a lot of dependencies?
08:43clgvrritoch: with the my current fix there is is only a small overhead if only one thread is loading these namespace. I should probably make a benchmark for it
09:47justin_smith$ping
09:47lazybotjustin_smith: Ping completed in 0 seconds.
09:49otfromI'm trying to use flambo 0.3.3 and 0.4.0-SNAPSHOT and I get the following error: #<CompilerException java.lang.ClassNotFoundException: flambo.function.Function, compiling:(flambo/function.clj:56:1)> works fine in 0.3.2. Any flambo/spark people here today with an example project using > 0.3.3?
09:52clgv$ping justin_smith
09:53clgvotfrom: you are trying to use both in the same project?
09:54otfromclgv: more than one version of flambo? No, just one, but I'd like to use the latest release or the latest snapshot if possible.
09:54otfromclgv: are you thinking I have a classpath clash problem?
09:56clgvotfrom: you can check via "lein deps :tree"
09:57craigglennieGood morning all. I have a function that takes a URL, downloads a file to disk, and returns the path to the file. Is it okay (in terms of best practices / style) to use a function with side-effects like this one in a “let”?
09:58clgvotfrom: it is using gen-class to create flambo.function.Function - so you need to AOT flambo.function
09:58justin_smithcraigglennie: absolutely fine. let is a procedural construct.
09:59otfromclgv: only clashes are with commons-codec
09:59craigglenniejustin_smith: Cool, thanks
09:59clgvotfrom: see above
09:59otfromso in my client lib I need to aot the namespace with the main in my project and flambo.function?
10:00clgvotfrom: complain to the devs ;)
10:00otfromlol
10:00otfromI believe the appropriate response to my complaint would be: submit a PR. ;-)
10:00noncom|2what is the best library for xml for clojure ?
10:01noncom|2i find that clojure.data.xml can't parse/unparse xml elements as clojure datastructures.. is there any lib that does that ?
10:02justin_smithnoncom|2: I have never seen clojure.data.xml output anything but clojure datastructures. Maybe I misunderstand you.
10:02clgvotfrom: https://github.com/yieldbot/flambo#aot
10:03noncom|2justin_smith: ymm, i guess you're right.. i mixed things up, it really does :)
10:03otfromclgv: giving that a try now
10:07otfromclgv: that did it. Thanks!
10:07mumrahhow can i point leiningen at a local jar?
10:07mumrahor alternatively, how can i change the location of maven's ~/.m2 dir?
10:08justin_smithmumrah: easiest is lein install
10:08mumrahlein install is akin to mvn install, yes?
10:08justin_smithmumrah: or you could explicitly add the jar's location to the classpath via project.clj
10:08justin_smithmumrah: yeah, it will put the artifact into .m2, and can generate a pom for it if needed
10:09mumrahjustin_smith: have an example of adding a jar to the classpath handy?
10:09mumrahthat sounds like my ticket
10:11justin_smithmumrah: you should be able to add the full path to the jar to the :source-paths vector
10:11mavbozoleiningen generates command like "/usr/bin/java -classpath :/Users/mavbozo/.lein/..."
10:11mavbozohow can i see the generated commands?
10:12justin_smithmavbozo: what OS? with linux/osx you can see the full command line via ps x, or you can just see the classpath generated with lein cp
10:13mavbozojustin_smith: windows, linux, osx
10:13mavbozojustin_smith: no leiningen command to debug?
10:13justin_smithmavbozo: "lein cp > class_path; java -cp $(cat class_path) clojure.main" is a fun startup time hack
10:14justin_smithto just see the classpath there is "lein cp" but thanks to plugins especiallly lein can do a lot more than just create a classpath
10:14justin_smiththere is also :eval-in pprint
10:14mavbozojustin_smith: i want to see the full 'java -jar ... ' command
10:14justin_smithmavbozo: in my experience the full command does not use -jar at all
10:15justin_smithit is java -cp [classpath] main-class
10:15justin_smithwhere that classpath has many jars, of course
10:17justin_smithand main class will be clojure.main -m your-main-ns
10:17mavbozothe problem is, i get lots of "Unable to resolve symbol" or "Class not found" in some of my projects in windows
10:18justin_smithmavbozo: I am sure there is some way to look at the command line of a running process on windows. I just down't know what it is, I haven't had a windows machine since win98
10:18pepijndevosHow do I write fast and working Clojure these days? (debugging, profiling, etc.)
10:18justin_smith*don't
10:18mavbozoi suspect those problem happens because the command generated by leiningen exceeds windows cmd max string length
10:18mikerod,(clojure.reflect/reflect (fn []))
10:18clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.reflect>
10:18mikerodI found this error interesting
10:19mikerodIf I do (very ugly in one line):
10:19mikerod,(let [f (fn []) r (clojure.reflect/->JavaReflector (.getClassLoader (class f)))] (refl/do-reflect r (class f)))
10:19clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.reflect, compiling:(NO_SOURCE_PATH:0:0)>
10:19noncom|2justin_smith: what is the recommended way to decend a parsed xml tree in data.xml ? i find that on every node i have to ask for the :tag before going down inside the content ?
10:19mikerodoh boo
10:19mikerodno clojure.reflect loaded
10:19mavbozobecause when I move the project directory to C:\ (shorter path name), the problem gone
10:19justin_smithpepijndevos: jvisualvm works good for profiling, the cursive plugin for intellij idea probably has the most complete debugging / profiling integration in the environment
10:19puredangerpepijndevos: I've been pretty happy with Cursive for debugging lately. I use YourKit and Criterium for profiling (depending what I'm doing)
10:20justin_smith&(require '[clojure.reflect :as reflect])
10:20lazybot⇒ nil
10:20noncom|2justin_smith: also, while trying to traverse the tree of elements, i always get ClassCastException clojure.data.xml.Element cannot be cast to java.util.Map$Entry
10:20noncom|2so the returned structure is *not* a native clojure data structure
10:20mikerodSo to demonstrate without clojurebot help: `(clojure.reflect/reflect (class (fn [])))` ;= ClassNotFoundException <some-ns-here>$eval130048$fn__130049 java.net.URLClassLoader$1.run (URLClassLoader.java:202)
10:21mikerodSo the issue is that clojure.reflect/reflect defaults to using the context class loader
10:21justin_smithnoncom|2: is that in a clojure.walk/postwalk call?
10:21pepijndevosDo people actually pay hundreds of dollars for YourKit?
10:21justin_smithmikerod: I just demonstrated how to load clojure.reflect above btw
10:21puredangerpepijndevos: I have, several times. It's worth it.
10:21noncom|2justin_smith: no.. actually i just try to replace one tiny value in an xml file
10:21mikerodHowever, if I make my own JavaReflector: `(let [f (fn []) ] (clojure.reflect/->JavaReflector (.getClassLoader (class f))))`
10:21justin_smithpepijndevos: I think most of us use the open source license
10:22mavbozoso, I suspect if the command line generated by leiningen exceeds OS's command length limitation, the leiningen command fails to run
10:22puredangerpepijndevos: actually, jvisualvm is pretty good too for basic method profiling
10:22noncom|2justin_smith: there is no similar problems with json, through cheshire.. it just goes very natural.. however, this xml thing is strange
10:22justin_smithnoncom|2: OK. I never ran into that because I was just reading from the xml, not trying to modify it at all.
10:22mikerodI can use (clojure.reflect/do-reflect r (class f)) to get some reflection.
10:23mikerodjustin_smith: I didn't see you post about that
10:23justin_smith,(require '[clojure.reflect :as reflect])
10:23clojurebotnil
10:23pepijndevosI can't claim any of my clojure things have an active community...
10:23mikerodjustin_smith: I didn't know we could use something like `require` here
10:23mikerod,(reflect/reflect 1)
10:23clojurebot{:bases #{java.lang.Comparable java.lang.Number}, :flags #{:public :final}, :members #{#clojure.reflect.Method{:name toOctalString, :return-type java.lang.String, :declaring-class java.lang.Long, :parameter-types [long], :exception-types [], ...} #clojure.reflect.Method{:name compareTo, :return-type int, :declaring-class java.lang.Long, :parameter-types [java.lang.Object], :exception-types [], ......
10:24mikerodnice
10:24noncom|2justin_smith: alright.. well, clojure.data.xml.Element is a (defrecord).. aren't they supposed to behave like {}s when being queried?
10:24justin_smithpepijndevos: well, jvisualvm works (I am sure it is not as fancy as yourkit though)
10:24mikerod,(reflect/reflect (class (fn [])))
10:24clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: sandbox$eval120$fn__121>
10:24pepijndevosok :(
10:24mikerod,(let [f (fn []) r (clojure.reflect/->JavaReflector (.getClassLoader (class f)))] (refl/do-reflect r (class f)))
10:24clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: refl, compiling:(NO_SOURCE_PATH:0:0)>
10:24justin_smithnoncom|2: yes, they should, what were you doing to it that provoked that error?
10:24mikerod,(let [f (fn []) r (reflect/->JavaReflector (.getClassLoader (class f)))] (reflect/do-reflect r (class f)))
10:24clojurebot{:bases #{clojure.lang.AFunction}, :flags #{:public :final}, :members #{#clojure.reflect.Method{:name invoke, :return-type java.lang.Object, :declaring-class sandbox$eval171$f__172, :parameter-types [], :exception-types [], ...} #clojure.reflect.Constructor{:name sandbox$eval171$f__172, :declaring-class sandbox$eval171$f__172, :parameter-types [], :exception-types [], :flags #{:public}}}}
10:24noncom|2justin_smith: i did (keys) on it
10:25noncom|2justin_smith: also (:key element) always returns nil
10:25justin_smithnoncom|2: yeah, I would think keys would work on a defrecord
10:25xeqipepijndevos: I had a company buy a license and used it many years ago. Saved a bunch of time in that case
10:25justin_smithnoncom|2: well, you want (key element) not (:key element)
10:25justin_smithif the element is a hashmap entry
10:25xeqitoday I'd try jvisualvm as a first step though
10:26noncom|2from the source: (defrecord Element [tag attrs content])
10:26pepijndevosxeqi, yea, I assume that once you make serious money using the JVM, yourkit can make you some extra.
10:26noncom|2so i try (:tag my-element)
10:26noncom|2and it returns nil
10:26justin_smithxeqi: pepijndevos: yeah, seems like it wouldn't be hard to convince your company that better profiling would pay off fast
10:26noncom|2whatever i try, it is always nil
10:26noncom|2and (keys my-element) just fails
10:26puredangerare you sure my-element is actually an Element ?
10:27pepijndevosAt the moment I have not much comany to speak of.
10:28noncom|2puredanger: wow! (type my-element) returns lazy-seq!
10:28justin_smithnoncom|2: hah, so it was a different datatype than you expected
10:29puredangerso it's probably a sequence of Element or something like that
10:29noncom|2but (keys my-element) says ClassCastException clojure.data.xml.Element cannot be cast to java.util.Map$Entry
10:29noncom|2aaaaaaaaand the source says "(defrecord Element [tag attrs content])"
10:29noncom|2so, where is the truth out there? :)
10:29puredangerkeys expects a seqable thing (a sequence of MapEntry)
10:29Bronsa,(keys (1))
10:30clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
10:30justin_smithnoncom|2: here is my universal trick - in a repl I start with (-> unknown type) then based on type I up-arrow and do (-> unknown keys) or (-> unknown first), then I do (-> unknown :first-key type) etc. etc.
10:30justin_smithnoncom|2: that way I typically find what I am looking for very fast
10:30noncom|2justin_smith: yea, i just basically just fololowed in your steps a couple of secs ago..
10:30justin_smithit works!
10:30noncom|2for some reason it (first) returns the element
10:30noncom|2oh well..
10:39pepijndevosWhen do you use reducers or transducers?
10:40puredangerreducers are particularly useful if you want to parallel fine-grained data transformation
10:41puredangertransducers can really be used anywhere you use sequences today but offer better performance in many cases, eager evaluation (with optional lazy evaluation via sequence), clearer scope for resources, and the ability to stay "in collections" (vector -> vector, etc)
10:42puredangereventually there will be a parallel story with transducers too, most likely in 1.8
10:46pepijndevosgreat.
10:46pepijndevosvisualvm just crashes when profiling my code.
10:47justin_smithweird, I have never seen that
10:47justin_smithis it the same visualvm version as the jvm version you are using?
10:48pepijndevosI don't know... just downloaded it from their site
10:48justin_smithpepijndevos: jvisualvm ships with the jdk
10:48justin_smithuse the same one that came with the jdk that you are using
10:48pepijndevoshuh.. so where is it?
10:49pepijndevos(mac)
10:49justin_smithpepijndevos: depends, where did your OS put your jdk install?
10:50pepijndevosin /usr/bin/java :D no idea where the actual classes and things live
10:50justin_smithhmm, if you have the jdk via a standard method on the mac, jvisualvm should end up in your path in a shell (regardless of where it put the actual files)
10:50pepijndevosah, it does
10:52pepijndevosokay, this works so far
10:53pepijndevosuuuhm, nope, hanging again...
10:56Glenjaminthe jvisualvm you can download is a bit newer/shinier than the bundled one though
11:00justin_smithGlenjamin: I was just guessing that the one that comes with your vm would be less likely to hang or crash
11:20LizardSquadYou Guys Ready to rumble
11:20LizardSquadLizard Squad Will strike today
11:20LizardSquadAnd all of you will suffer
11:21LizardSquadsd
11:21LizardSquadsd
11:21LizardSquadsdsd
11:21LizardSquadd
11:21LizardSquadsd
11:21LizardSquads
11:21LizardSquadasd
11:21LizardSquadsa
11:21LizardSquadsd
11:21LizardSquadsd
11:21LizardSquadasd
11:21LizardSquadds
11:21LizardSquadsd
11:21LizardSquaddas
11:21LizardSquadsd
11:21LizardSquadds
11:21LizardSquadsd
11:21LizardSquadsd
11:21LizardSquadd
11:21LizardSquadsds
11:21LizardSquadadsa
11:21LizardSquadsd
11:21LizardSquadsd
11:21LizardSquads
11:21LizardSquadds
11:21LizardSquaddsssssssssssssssssss
11:21LizardSquadsd
11:21LizardSquadsdsdd
11:21LizardSquaddsasd
11:21LizardSquadasd
11:21LizardSquadasd
11:21LizardSquadsda
11:22jonathanjis there a clojure.java.jdbc command to generate "CREATE INDEX" ddl?
11:23justin_smithjonathanj: definitely. One minute I'll see if I can look it up.
11:24justin_smithjonathanj: if nothing else you could create the statement freeform and put it in a db-do-commands call
11:25jonathanji found this http://dev.clojure.org/jira/browse/JDBC-62 but it doesn't seem to correlate with reaility
11:25benmossyeah, was looking at that too
11:25jonathanj(or that reality has since dissolved)
11:26jonathanjjustin_smith: then i have to manually figure out quoting and stuff, is there a way i can use ? placeholders and specify the values literally?
11:26justin_smithjonathanj: so you are doing ddl based on user input?
11:26benmossah, https://github.com/seancorfield/jsql is what you ant
11:26benmosshttps://github.com/seancorfield/jsql/blob/master/src/java_jdbc/ddl.clj#L54
11:27jonathanjjustin_smith: not in this case, no, but i don't see any reason to assume i will never make a mistake
11:28jonathanjbenmoss: thanks, that looks useful
11:30benmossno prob
11:30otfromanyone doing any pre-clojurex gettogethers tonight?
11:31pepijndevosI'm failing at transducers... https://www.refheap.com/94360
11:33justin_smithpepijndevos: comp on transducers is backwards
11:33puredangeralso why the eduction in there?
11:34justin_smithtry (comp words numbers node-group)
11:48pepijndevosjustin_smith, ahhhh, why on earth... well
11:48gdeer81trying to get clojure introduced at work by doing all the testing in Clojure. gradle is killing my efforts. I can't seem to find a mapping of which versions of gradle are compatible with clojuresque 1.6
11:49jonathanjhrm, so clojure.java.jdbc/db-do-commands wraps each command in a transaction by default
11:49SagiCZ1gdeer81: is testing non-clojure code in clojure easier?
11:50puredangerpepijndevos: transducers are a stack so you compose them inside-out
11:50pepijndevospuredanger, not sure about the eduction, but I map a mapping function, because it's a seq of seqs.
11:51gdeer81SagiCZ1, testing java with clojure is pretty fun
11:51puredangerpepijndevos: I get that, but eduction will re-apply the transformation on each use. there seems to be no reason for that here?
11:52pepijndevosSo what would I do instead?
11:52SagiCZ1gdeer81: is there some clojure api that focuses on that?
11:53gdeer81SagiCZ1, no, the ability to test java is available in core...interop
11:53puredangerpepijndevos: you're basically just mapping right? so anything that uses reduce there. (into [] (map to-int) %) or something ?
11:54pepijndevoshmmm, maybe...?
11:54puredangerif split was reducible, you could compose that into the splitting transformation which would be pretty nice
11:54jonathanjhrm, i'm running a CREATE TABLE and a CREATE INDEX in a bare db-do-commands form
11:55jonathanjmy CREATE INDEX had a typo in it, so it failed to execute but the CREATE TABLE had already executed
11:55jonathanjfixing the typo and running the commands again results in an error about my table already existing
11:56puredangerpepijndevos: into has the benefit of utilizing a reducible source (not valid here) and using transients to produce the output collection. you could also just map around your split.
11:56jonathanjwhich is weird because i expected the failing CREATE INDEX to rollback the transaction
11:58pepijndevosI don't get that (into [] (map to-int) %)
11:58puredangerpepijndevos: so words could be (map (map (fn [s] (Integer/parseInt s)) (s/split % #" ")))
12:00puredangerbasically combine the words and numbers steps together. I'm not really sure which path yields the fastest result here; would require some testing with real data.
12:01puredangerbut I don't think there's any good reason to use eduction here
12:02pepijndevosok
12:07pepijndevosWhat does partition-by do as a transducer? Does it produce a transducer of transducers, of a transducer of collections?
12:09puredangerI'm not sure that question makes sense
12:09pepijndevoshehe
12:10puredangerit produces a transducer that has a reducing function that takes elements and invokes the next reducing function with vector partitions
12:11pepijndevos(into [] (comp (map #(what is %)) (partition-by odd?)) (range 100))
12:11pepijndevosright, so it produces vectors
12:11puredangeryes, which differs from the seq version
12:12pepijndevosIs there any useful way to transducify the to-map part in https://www.refheap.com/94360 ?
12:14edwAfter the following is evaluated, will the storage for the :b key and its associated value be retained indefinitely? (def x (-> {:a 1 :b 2 :c 3} (dissoc :b) (assoc :d 42)))
12:15puredangerpepijndevos: well you could rewrite it as a single reduce where the merge is done on the accumulator
12:16pepijndevosedw, uuuhm, maybe because interning, but otherwise they would be GC'd, no?
12:17puredangeredw: as things are "removed" from the map, if no one else is referring to them, they are eligible for GC
12:18puredangerthat includes something holding a reference to the "before" version of the map
12:19puredangerhere you are actually storing a function on a literal map, so it's kind of a different case than in normal code
12:56leylujyoooooo clojurerrs?
13:06timpaniAnyone else have trouble trying to port install leiningen on a mac? I get ":error:build org.macports.build for port maven-ant-tasks returned: command execution failed" and, being clueless about ports (and maven), am not having luck with the suggestions on https://trac.macports.org/ticket/30060. Any help would be appreciated, thanks.
13:06kenrestivowhy not just install the script?
13:06joegalloyeah, seriously. i know this sounds like flippant advice, but i promise it's not. just install the script yourself, don't use macports for this.
13:06arrdemit is strongly encouraged to install leiningen directly via the posted script rather than via a package manager.
13:07arrdemand by strongly I mean technomancy will just tell you that all the packages are broken, unofficial and unsupported.
13:07kenrestivoi'm usually super-conservative about sticking to package managers (i'm a debian guy, ffs), and have only a handful of things in /usr/local, but lein is one of them
13:12timpaniScript advice worked like a charm. Thanks, all.
13:14justin_smithlein is one of the few self-managing dependency managers that is guaranteed to be better at managing itself than what your OS provides
13:15TimMcjustin_smith: Except it doesn't tell you when there are updates available.
13:15justin_smithTimMc: that's true
13:15TimMcOther than that I'd agree.
13:16justin_smithI didn't think of that because I prefer to explicitly check my dependency manager for updates
13:24TimMcjustin_smith: I run Debian Stable so I pretty much only get security updates, and I'd rather be prompted for those. :-)
13:35justin_smithfair enough
14:15michhey
14:16michaelr525anyone knows why iterate-table from cassaforte repondes as expected to (take) but hangs when used with (doall)?
14:17kenrestivowow this ecosystem is amazing. it's eerie, 10 minutes after i realize i need something, before i can write it, i do a quick search and someone has like an hour ago released a library or posted an example which does it
14:17kenrestivonot just that everything i need is already there, but it was written anywhere from hours to days before i need it
14:20ppppaulwhat is the lighttable channel?
14:27arrdem#lighttable
14:27arrdemppppaul: ^
14:27arrdemideas for tokenizing a ~500 word subset of english?
14:27arrdemopennlp looks like massive overkill
14:28amalloymichaelr525: if iterate-table is anything like iterate, it produces an infinite sequence, and running doall on that is not a recipe for success
14:29ppppaul^_^
14:29amalloyarrdem: slap all the words together with |, and then call re-pattern + re-seq or s/split?
14:41edw,42
14:41clojurebot42
14:53gfredericksquestion about component
14:53gfrederickssentence fragment
14:54gfredericksum so a lot of IO libraries will e.g. take a connection as the first arg in most of their API
14:54gfrederickswhich goes well with component to an extent
14:54arrdemamalloy: yeah I'll give that a shot
14:55gfredericksbut for some ways of structuring your code you end up wanting to write a wrapper for the API that can take your Database record (say) as the first arg and will pull out the connection and then call the real API
14:55amalloyarrdem: you might map Pattern/quote over the words too, just in case there are some metacharacters in there
14:55gfredericksone way to "solve" that would be to change the library to have an IConnectionHaver protocol
14:55gfrederickswhich the record could implement
14:56gfredericksis this good? or bad? or what?
15:00michaelr525what's a faster serializer/reader nippy or transit?
15:04timpaninewbie(-ish) question: why can't I instantiate a type defined in a namespace I use? Namespace N defines type T, but the constructor (T.) doesn't seem to visible in the repl.
15:05arrdemtimpani: did you require N?
15:05arrdem* or otherwise load N
15:06hiredmantimpani: what is returned when you evaluate *ns* in the repl?
15:06hiredmanwhat repl are you using?
15:07hiredmanhave you loaded the namespace?
15:07pw4everis there a way to call Java base class's consturctor (i.e., "super(args)" in Java) with "proxy"?
15:07hiredman(if you have loaded the namespace code, what did you do that makes you think you did?)
15:07razum2umis there any progress library like clj-progress which indicates mapping over some lazy-seq? (i.e. it just counts steps every N, show time since start and draws progress like wget does when content-length is undefined) ?
15:07timpaniarrdem: yes. hiredman: *ns* returns another namespace, but one that uses N.
15:08hiredmantimpani: so?
15:08timpanihiredman: I thought require would make the type available.
15:08timpanibut it doesn't seem to be, not even when prefixed with its namespace.
15:09hiredmantimpani: I suggest not using defrecord/deftype until you have your sea legs with the langauge and the tools
15:11hiredmanthere can be some subtle issues with defrecord and deftype that are challenging to debug via irc, so it would be easier if you were further along and could self debug to some extent
15:19pw4everthe answer to proxy super class args is right there in the doc. my bad.
15:28pepijndevosWhat is the most efficient way to update a bunch of record fields?
15:29pepijndevosJust create a new record with the old fields?
15:29mgaarepepijndevos: assoc and update-in both work on records
15:30pepijndevosmgaare, but doing more than one update creates a bunch of intermediate records, right?
15:30pepijndevosSo in that case I might be better of using a new record
15:32mgaarepepijndevos: benchmark it both ways and see if there's any performance gain
15:32pepijndevoswill do
15:45EvanRwhats the preferred way to run an IO function on a list of items, and get the corresponding list of results, and force it to happen right now, not later via lazy seq
15:45arrdemEvanR: mapv could do that..
15:46stuartsierratimpani: defrecord/deftype create both Java classes and Clojure Vars. The Vars are the constructor functions `->RecordName` (both deftype and defrecord) and `map->RecordName` (only defrecord).
15:46EvanRok
15:47mikerodIs there anyway to prevent macros from throwing exceptions about negative arity at macro expansion time?
15:47arrdemEvanR: it may be more idiomatic to manually loop with an accumulator here... using map for side effects isn't great.
15:47stuartsierratimpani: `(ns … (:require [… :refer …])` or `(ns … (:use …)` can make the Vars visible in another namespace, but not classes.
15:47EvanRarrdem: why?
15:49bbloomEvanR: doseq if you want effectfully use the results, mapv if you want to just hold on to them.
15:49EvanRdoseq returns nil
15:50bbloomEvanR: then mapv is fine
15:50amalloymapv for side effects doesn't make me happy. it doesn't make it clear to the reader that running it now for side effects is important; it might be that you need a vector because it's the right data structure, or because it's faster and performance matters
15:50EvanRwell "functions" for side effects dont make me happy, but i dont think theres any way around this one either
15:51EvanRalso im trying to write a front-effect, rather than a side effect
15:51bbloommapv is fine if it's clear from context, but in general it doesn't really make that much sense to linearly execute a bunch of side effects for a bunch of incremental results
15:51amalloypepijndevos: making a new record with the old fields is really the only way to make a new record, period, of course
15:51bbloomi haven't run in to that situtation... ever really...
15:51EvanReh?
15:51stuartsierraI always advise not to mix sequence functions with side-effecting operations. Laziness and chunking can lead to confusing effects.
15:52pepijndevosamalloy, hehe... true
15:52bbloomEvanR: why do you need the sequence of results?
15:52EvanRstuartsierra: hence my question, mapv is the answer
15:52stuartsierraor doall
15:52EvanRdoall drops the results
15:52stuartsierrano, that's dorun
15:52bbloom(doc doall)
15:52clojurebot"([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."
15:53EvanRoh well, (doall (map ... might be what i want then
15:53amalloypepijndevos: https://github.com/flatland/useful/blob/develop/src/flatland/useful/datatypes.clj#L87 has a macro that does this in an efficient way with a semi-reasonable syntax; it's not my favorite, but it could be clearer than writing (Foo. (f (:x foo)) (g (:y foo))) yourself
15:54bbloomi always forget about doall... i don't really use it in my programs b/c, again, i haven't really felt the need to get intermediate results effectually unless i need to thread a result through, in which case reduce is what you want
15:54pepijndevosah.. useful :)
15:54amalloyusing it looks like https://github.com/flatland/useful/blob/develop/test/flatland/useful/datatypes_test.clj#L46-L51
15:54bbloomand even if i do want each of the individual results, i almost always do want to ALSO calculate some aggregate value, so you can just use reduce and do both the aggregation and "logging" at once
15:54EvanRbbloom: in general, an IO action has some result. for instance http-post could give a numeric status code, read-file gives you a string. now if i have a list of urls or filepaths, i might want to execute them all and get the list of results, this comes up a lot
15:55bbloomEvanR: but map really isn't appropriate for IO in any way
15:55EvanRbut in clojure so far, i have gotten bitten by lazyseq, so maybe doall
15:55bbloomEvanR: instead of doing the IO in your map function, why not create a sequence of "instructions" and then do the IO at the top level?
15:56EvanRwhat?
15:56clojurebothttp://paste.lisp.org/display/74305
15:56bbloombasically instead of mapping over a bunch of side effectful calls, map over raw data that describes the side effects to have
15:56bbloomthen do the side effects in a doseq or a reduce
15:56amalloyclojurebot: forget what |is| <reply> http://paste.lisp.org/display/74305
15:56clojurebotI forgot that what is <reply> http://paste.lisp.org/display/74305
15:56bbloomthe advantage of that is you can also do a dry-run sort of thing
15:56bbloom,(def x (atom 0))
15:57EvanRbbloom: so, use body of an implementation of map?
15:57clojurebot#'sandbox/x
15:57bbloom,(doseq [f [inc dec inc]] (swap! x f))
15:57clojurebotnil
15:57bbloomx
15:57bbloom,x
15:57clojurebot#<Atom@ef1280: 1>
15:58amalloyman, clojurebot has a lot of totally useless facts mapped to "what"
15:58bbloomEvanR: note that the sequence is data which describes which operations to perform, rather than performing the operations itself
15:58EvanRif you could imagine a foreach loop in an imperative language, but one that gives you the array of results rather than having to manually accumulate them in the body of the loop, this is the same advancement from the equivalent manual mapping strategy in such languages
15:59EvanRbbloom: yeah, and the sequence of operations is constructed with something like map post urls
15:59bbloomEvanR: i understand what you want, and either mapv or doall will get the job done for you, but i'm telling you why i don't particularly feel a need for that -- i prefer effects be representable as printable data
15:59EvanRdoseq would drop the results, and so doall would be better in this case
16:00bbloomEvanR: right but you can have {:method :post :url "http:/...} instead of #<some-opaque-function>
16:00EvanRor '(:post "http:///...&quot;)
16:00bbloomor that
16:00EvanRwhich is good but is this idiomatic
16:01EvanRor warranted in the middle of obviously IO code
16:02EvanRon the subject of when IO makes sense at all, im also sequencing my IO actions using the let binding form. [a (dox) b (doy x) c ...]
16:02EvanRto me this has the same issues as map
16:02EvanRer
16:03EvanR(let [a (do-x) b (do-y a) c (do-z b) ...
16:03EvanRin a pure context no one would expect a let binding to do IO
16:17sdegutisIs it by any means possible to delete/destroy a var so that referencing it once again results in an exception?
16:18llasramsdegutis: you mean remove it from an NS, as via `ns-unmap`?
16:18sdegutisRight! Thanks!
16:18sdegutisYou win llasram.
16:20EvanRrigging a var to explode if disturbed ;)
16:20EvanRassign TNT
16:22sdegutisI am using intern and eval and ns-unmap to run a Clojure form that has access to free-floating "variables".
16:23EvanRi cast "floating variable"
16:27sdegutisSo I can do this: (eval-template '(inc foo) {:foo 2}) and it'll return 3.
16:27sdegutisGreat, right?
16:30amalloysdegutis: {:foo 2} seems like a terrible interface choice for that: i'd much prefer '{foo 2}
16:31amalloyobviously it's just nitpicking, but implicit conversions from keyword to symbol make me sick to my stomach
16:32pepijndevosWhere can you place type hints?
16:32pepijndevosother than the argument vector...
16:33amalloypepijndevos: that is a very broad question that sounds like it comes from a much more specific problem
16:33amalloyand the correct answer ("almost anywhere") is unlikely to help you much
16:34pepijndevosWell, can I just put them anywhere, to hint at the return of a function call, or do I need to let that valueQ
16:34pepijndevos?
16:35amalloywelllll, if it's actually a function call, you can hint the function invocation
16:35tbaldridgeyou type hint the return value of a function via the vector
16:35amalloybut you're better off let-binding it and hinting the name
16:36amalloytbaldridge: pepijndevos asked how *else* to do it
16:36pepijndevoshhmmm, seems to work... yay
16:36amalloyand you can't actually hint a return value of anything but Object/long/double on the argvec
16:37tbaldridgeamalloy: really? I seem to remember doing stuff like ^IFoo
16:37amalloytbaldridge: sure, you can *do* it, but it has no effect
16:38amalloyhinting the argvec is for passing and returning primitives, not for hinting what reference type to expect
16:38hiredmanamalloy: I think there was some work to unify that, but I vaguelly recall it not being very thorough
16:39amalloyhm, maybe it does do something now. interesting
16:40amalloyit didn't in 1.4, when hinting the argvec was introduced
16:40tbaldridgeactually I just tried it, it doesn't work. I think it does for protocol methods though
16:40tbaldridgethat's probably why I was confused
16:40amalloytbaldridge: really? i just tried it and it works
16:41amalloyoh, interesting
16:41amalloy(defn f ^String [x] "true") works, but (defn f ^String [^long x] "true") doesn't
16:41tbaldridgethis gives a reflection warning in 1.6
16:41tbaldridge,(do (set! *warn-on-reflection* true) (defn foo ^String [] "foo") (.toUpper (foo)))
16:41clojurebot#<IllegalStateException java.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set>
16:42amalloytbaldridge: because .toUpper doesn't exist
16:42tbaldridgeWell then......
16:42ppppaulanyone here have an exceptionally good experience with lighttable and cljs?
16:42hiredmanit is kind of a mess
16:42tbaldridgelol, okay so it does work.
16:42amalloytbaldridge: well as i said, it *kinda* works - look at my two examples
16:43tbaldridgeThe nasty bit is that IIRC something with java interop demands that the hint by on the symbol.
16:43tbaldridge*be on
16:44amalloyanyway, this is why i recommend let-binding the result and typehinting that name
16:48dbaschppppaul: I think most people here haven’t been very impressed with lighttable
16:48bbloomdnolen_: (or other cljs folks) is there a reason deftype* doesn't emit named constructor functions?
16:48bbloomwould be nice for debugging if no other reason to be able to (.. x -constructor -name)
16:49bbloomdnolen_: seems like a simple extra (munge t) would do the trick, but i'm not sure if there's any fallout from that
16:51EvanRhow i learned to stop worrying and learn to love reflection
16:52ppppauli worry about learning how to stop worrying
16:53ppppaulalso, i'm going to start using emacs again... spent a week with light table, and i can't get anything done with it in cljs
16:54ppppaulalso, EvanR... how did you learn to stop worrying? did you add more carrots to your diet? i've always thought i haven't been eating enough carrots...
16:55EvanRby struggling with the type hints
16:55ppppaulbut, what if they lie?
16:56ppppaulcan one trust a type hint in this day and age?
16:57EvanRdynamic types never lie
16:58sdegutisamalloy: thx for advice
16:59dnolen_bbloom: haven't bothered w/ it since the best debugging environment (Chrome) just does the right thing in this case usually.
17:00atyzHey all. I've written a macro and feel like there must be a better way to write it. Anybody willing to look at it?
17:00atyzhttps://www.refheap.com/94370
17:00dnolen_bbloom: FireFox too
17:00weavejes_atyz: What's the reason for making it a macro? Would a function do?
17:02weavejesteratyz: You could write: (some (fn [f] (f entity)) fields)
17:07bbloomdnolen_: what does "does the right thing" mean?
17:08bbloomdnolen_: anyway, here's a patch for it: http://dev.clojure.org/jira/browse/CLJS-902
17:08dnolen_bbloom: the debugging tools know
17:08bbloomdnolen_: really? i'm not seeing that, but i'm also trying to print string representations of things, rather than mouse over etc in the console
17:09amalloyweavejester: you have to be careful about chunking and such if you do it that way
17:09dnolen_bbloom: ctors have always been printable via (type x)
17:09amalloyobviously it's still right to do it as a function, but more care than just using 'some is warranted
17:09dnolen_bbloom: not the constructor function itself of course, but like I said Chrome/FF display this
17:10dnolen_bbloom: thanks for the patch will think about it
17:10bbloomdnolen_: i don't understand how the `type` function helps? it returns the ctor function, but that doesn't toString right
17:10dnolen_bbloom: I don't know what you are doing so I don't yet care :)
17:11bbloomdnolen_: ooooooh you're pr-str works
17:11bbloomyou're saying*
17:11bbloomon the type
17:11bbloomhm
17:11bbloom (set! (.-cljs$lang$ctorPrWriter ~t) (fn [this# writer# opt#] (-write writer# ~(core/str r))))
17:11bbloomi didn't realize that
17:12dnolen_yeah
17:12dnolen_I got sick of this problem like 1 1/2 years ago :D
17:12bbloomdnolen_: ok, that's helpful, but still doesn't 100% solve my problem since i'm using js libs that don't respect pr-str
17:14bbloomdnolen_: one other thing is that if you don't want to give the ctor a name, you can also just stick ac omment string in the generated code -- /* some.ns/SomeType */ will print in the tostring, but surely get removed in advanced optimizations
17:14bbloomdnolen_: thanks though
17:22arrdemamalloy: heh after some munging to figure out my language, the huge generated regex works a treat. cheers.
17:28dmahantafrom this ({:a 1 :b 2}{:a 3 :b 4}) how do i get jus the values of a (1,3)
17:28amalloydmahanta: (map :a ...)?
17:28dmahantaamalloy thanks now it makes sense
17:29AeroNotixUsing the clojure-metrics library, what do I want to get "How many of a particular event in the last 60s" ?
17:50david234567Hello! I am having problems with core.async. What I'm trying to do is have two go routines read and write to a socket depending if channels have stuff in them, but it doesn't seem to be working right
17:50david234567Here's the code:
17:50david234567https://gist.github.com/iMultiPlay/e4fa0258c9be16f24248
17:50david234567The function starts on line 36
17:52david234567thank you :3
17:53amalloydavid234567: "<this giant code dump> doesn't work" is not a problem that is easy to solve. what doesn't work? what happens instead? can you find a smaller program that exhibits the same problem?
17:54dbaschalso, it’s “receive”
17:55dbaschfix that spelling mistake and the program will magically work
17:55kenrestivoi could say, here's code dump that works, why not use this instead? http://crossclj.info/ns/com.gearswithingears/async-sockets/0.1.0/project.clj.html
17:55amalloy(inc kenrestivo)
17:55lazybot⇒ 2
17:56dbaschone thing that’s very suspect: two nested “while true” loops
17:57amalloydbasch: well, they're not exactly nested
17:57dbaschtrue, one is in a go loop, never mind
17:57dbaschstill looks strange
17:58david234567emacs crashed, so I guess the receive thing worked lol. The double while (one in go) was a desperate hack to get it to work
17:58kenrestivoi tried to write my own too. i gave up and just used asyncsockets instead.
17:59kenrestivoit works, and it's fun to use.
18:01kenrestivocaution though: i found a bug, submitted a pull request, and saw another pull request fixing another bug sitting there, apparently both are still not merged, so not sure if it's abandoned or not
18:03david234567that library seems promising, thank you! (it's not very serious so I'll just live with the bugs)
18:05kenrestivoquick community question: what's the "right thing to do" if i need a library, need to fix bugs in it, want to deploy the bugfixed version to production (which means clojars), but the author isn't respondin to pullrequest/issues? just fork it? do i change the artifact to my own name? what's the polite thing to do?
18:07kenrestivoi mean, do i want to pollute clojars with [kens.bufixed.fork/some-library "0.1.clash-with-future-upstream-version-number"
18:07kenrestivo?
18:08{blake}I'm trying to pass a "true" into a Java routine. I'm assuming Clojure's "true" maps. Is that correct?
18:08dbasch{blake}: correct
18:08dbaschof course true without quotes
18:08{blake}dbasch: Dammit. That would've been an easy fix if I had been wrong.
18:09dbasch,(type true)
18:09clojurebotjava.lang.Boolean
18:09{blake}Yeah, I debated denoting it with some other symbol or TRUE or whatevs. But I knew you'd know.
18:10{blake}OK, so maybe it's this: I've translated <<System.setProperty("poi.log.level", POILogger.INFO + "");>> into <<(System/setProperty "poi.log.level" (str POILogger/INFO ""))>> but...meh, that seems to be right.
18:12david234567Sorry for all the questions, but it seems that the async-sockets library refuses to be found on the class path (added it to profiles.clj and ran lein deps and restarted repl)
18:13amalloykenrestivo: yes, pollute clojars with an artifact that has a groupid you own
18:15CaptainLexWhat's the best way to do a grid-type data structure in Clojure? I'm storing binary data about a square grid
18:15CaptainLexRetrieval time is exponentially more important than update time
18:15CaptainLexNested vectors?
18:15amalloyyes
18:16dbaschunless it’s sparse
18:16CaptainLexdbasch: It'll be sparse in 1s, but dense in data. No undefs
18:16amalloyalso, i'd just like to register a complaint about "exponentially more" being used as a vague intensifier
18:16CaptainLexamalloy: Noted :)
18:17dbaschyes, it’s only constantly more important
18:18CaptainLexdbasch: Is that the kind of sparseness you meant?
18:19dbaschif you need all the 0s and 1s and are not bothered by memory usage then sure, nested vectors is the way to go
18:19dbaschit it were sparse I’d have a map of maps with the set values
18:20CaptainLexdbasch: Okay, good to know. Actually I might end up needing to encode grids differently based on their use case
18:20CaptainLexIt's an AI project
18:20amalloyyou could also just have a single vector and address it with multiplication, like the olde days in C; that probably gets you a slight speedup due to the increased structural sharing, but nothing too exciting
18:20CaptainLexthere'll be the "objective" grids that describe the terrain
18:21CaptainLexand then grids that describe what the agent has learned about the terrain
18:21EvanRCaptainLex: or a 2d java array
18:21CaptainLexIt may end up the latter grids would be sparse, and best encoded as maps like dbasch suggested
18:22EvanRwhich might be exponentially more clucky to use from clojure
18:22EvanRklunky
18:22kenrestivothere are exponentially a few matrix libraries for clj and java
18:22EvanRlol
18:23CaptainLexkenrestivo: Oh yeah oops!
18:23CaptainLexI was originally writing this for CLJS
18:23kenrestivotoday is Exponential Abuse day
18:23CaptainLexbecause I want to incorporate it into a personal project
18:23CaptainLexbut I decided for time's same I'll do in Clojure and port it later
18:23amalloykenrestivo: i had an exponentially burrito for lunch
18:23CaptainLexso I could definitely use core.matrix or whatever
18:23kenrestivoburrito... cubed!
18:24dbaschI had an Indian burrito, which is exponentially more exponential than a regular one
18:24kenrestivoyeah core.matrix would be the first place i'd look
18:24EvanRdoes core.matrix work in cljs?
18:25CaptainLexEvanR: There's rumbling of an attempt to port, but not at present
18:25kenrestivohttps://github.com/mikera/core.matrix/issues/81
18:26kenrestivowhich leads to http://0fps.net/2013/05/22/implementing-multidimensional-arrays-in-javascript/, which leads me to quit procrastinating on irc and try to get some work done
18:30CaptainLexOh wait
18:30CaptainLexbefore I write too much code and commit myself to Clojure
18:30CaptainLexperformance monitoring is a part of my project
18:30AeroNotixCaptainLex: riemann and graphite
18:30CaptainLexAeroNotix: Thanks!
18:33supersymmetrylol
18:41EvanRcan you implement a protocol on another protocol
18:41danielcomptonEvanR: IP -> TCP -> HTTP
18:42EvanRso funny i forgot to laugh
18:43amalloyi don't think i've heard "so funny i forgot to laugh" since middle school. what a surprising throwback
18:43EvanRi know
18:44CaptainLexLast time I heard it was from the mouth of Pee Wee Herman
18:50{blake}OK, "return string if not blank otherwise return nil"--I think I can do this without an "if", right?
18:50{blake}Or do I need to write my own func?
18:51supersymmetrySigh... such a shame Clojure is too unfamiliar here in the Netherlands
18:51EvanR,(not-empty "")
18:51clojurebotnil
18:51supersymmetryNear impossible to find any work in programming clj anyway,...
18:51EvanR,(not-empty "abc")
18:51clojurebot"abc"
18:52supersymmetry... I'll be damned to take up 'PHP' for a profession though, there's simply just lines one does not cross
18:53EvanRprofessional PHP, specifically
18:54{blake}Thanks, EvanR!
18:54supersymmetryAmsterdam Clojurans meetup has about 20 people .. that is, the entire country - yay. Amazing how many 'Are you HOT for PHP'-like vacancies too ("Erh. No! And why would anyone?")
18:55CaptainLexsupersymmetry: Try being a front-end developer and slowly convincing your superiors to let you use CLJS
18:55supersymmetryEvanR: yeah although I wonder if there ever is a real difference: seen too many 'professional' coders omit { and } for that
18:55EvanRPHP is currently like the bud light of programming jobs, deployment
18:56CaptainLexThat's what I'm trying
18:56arrdem(inc EvanR)
18:56lazybot⇒ 6
18:56arrdemEvanR: it's still piss at any temperature :P
18:57EvanRits cheap, ubiquitous, and terrible
18:57hyPiRionsupersymmetry: hey, you actually have a meetup at least
18:57supersymmetryCaptainLex: Indeed, it would be easier too smuggle in. Or learn e.g. Seeshaw and go that way
18:58CaptainLexI must side with hyPiRion; the USA is too big for us ALL to meet in one place, the place where I live hasn't got a group at all
18:58arrdemI've got one... :D
18:58arrdemmay even make it to the meeting this monday..
18:58hyPiRionCaptainLex: I'm not located in the USA
18:58supersymmetrywhich makes me ask the question (since I'm not too deep in on the low level bindings stuff): does clojure generate Java besides gen-class or only bytecode?
18:59supersymmetryhyPiRion: where were you from again?
18:59CaptainLexhyPiRion: I was just siding with you on how having a small one is better than not having one
18:59hyPiRionNorway
18:59hyPiRionCaptainLex: ah, right – yeah indeed
18:59arrdemsupersymmetry: Clojure never generates Java code. Everything goes straight to bytecode.
18:59supersymmetrytrue...and although other side of the country (not that big heh) I'll go and check it out next time
18:59TimMcsupersymmetry: Clojure doesn't generate any Java, just JVM bytecode.
18:59supersymmetrythey had new+veteran match up and do coding contests which is fun + educational I guess
19:00supersymmetryright
19:02supersymmetrylol@bud-light btw... so what does that make clj? Sam Adams? Thought that was a nice brew when I was in the states last time :)
19:03CaptainLexMy understanding from my beer-snob friends is that any beer as good as Clojure
19:03CaptainLexprobably isn't well-known or mass-produced
19:06ajmccluskeyClojure is any beer brewed at Firestone in San Luis Obispo.
19:07ajmccluskeyNot only is their beer some of the tastiest I've ever had, the design and thought they put into their brewing is impressive.
19:07ajmccluskeyVery Clojurian :p
19:09supersymmetryCaptainLex: true
19:10TEttingerajmccluskey: firestone, the SUV-killing tire manufacturer?
19:11ajmccluskeyTEttinger: haha, I very much hope they're not related. AFAIK they're just a boutique brewery that happen to share the same name.
19:11ajmccluskeyTEttinger: actually, I think their full name is "Firestone Walker", so almost certainly not
19:11TEttingerfirestone driver would be more of a concern
19:19supersymmetry.. and I know perl. Damn. I feel like Neo sometimes after learning Clojure ^^
19:19supersymmetry2.5 hours to fully grok it
19:22supersymmetryalso said one of the best paying skills to have, perl, yet extremely little vacancies here... it seems to me a lot of these *nix skilled jobs are just done with Puppet and such as much as they can
19:22supersymmetryand companies using sharepoint or asp (backs away quickly)
19:35wildnuxhi,
19:35TEttingerhey wildnux
19:35wildnuxhow can we accumulate values in a vector that is outside the when-let block?
19:36TEttingeryou mean mutating the vector? you may be looking for a non-clojure data structure
19:36wildnuxsay we have (let [acc []) (when-let [s (even? (range 0 10)] (.....??.... acc s)) acc)
19:37wildnuxso after it iterates through the when-let values, the values are accumulated in acc
19:37TEttingeruh, there's a lot of problems there
19:37TEttingerthe let already ended by the time you start using acc
19:37wildnuxTEttinger: actually that is a typo, i just typed it here only
19:38TEttingeroh ok
19:38TEttinger,(even? (range 0 10)
19:38clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
19:38wildnuxTEttinger: but, you got the idea right, acc is outside when-let, and i want to add values to it so that after iterating throught the range, i have them accumulated,
19:38TEttinger,(even? (range 0 10))
19:38clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Argument must be an integer: clojure.lang.LazySeq@9ebadac6>
19:39wildnux,(even? (range 10))
19:39clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Argument must be an integer: clojure.lang.LazySeq@9ebadac6>
19:39TEttingerok, well the idiomatic way is to return a new list
19:39TEttingeror new vector, or whatever
19:39TEttingerwhat is this code supposed to accomplish?
19:40TEttingerlike what's a typical return
19:40EvanRwildnux: you cant mutate a vector, as far as i know
19:40wildnuxTEttinger: basically, i want to iterate through a list/sequence, and for each element, i want to accumulate the result of applying some funtion to that element, only if it meets certain critera
19:40TEttingersounds like a reduce
19:41EvanRyou might be thinking of using a var or an atom to hold the current accumulator, then something can replace it with a side effect
19:41wildnuxto simplify what is the idiomatic way to write the following in clojure?
19:42TEttinger,(reduce #(if (even? %2) (conj %1 (inc %2)) %1) [] (range 10))
19:42clojurebot[1 3 5 7 9]
19:42wildnuxList<Object> l = new ArrayList(); for (Object o : objectsFromExternalSources) { if (satisfiesSomeCond(o) { l.add(o);}}
19:43amalloyTEttinger: better, (reduce conj (map inc (filter even? xs)))
19:43amalloywell, (reduce conj [] ...), rather
19:43TEttingerright, that works better, amalloy
19:43amalloyand actually, why are we reducing at all if we are conjing
19:44amalloywildnux: that is just a filter
19:44amalloy(filter some-cond some-objects)
19:44TEttingeryeah, that seems like the best way then
19:44EvanRfilter and map can both be implemented with reduce, both are more clear when thats what youre trying to do
19:44EvanRreduce is more general
19:45wildnux(filter #(someCond %) objectsFromExternalSource)
19:45wildnux?
19:45TEttinger(filter someCond objectsFromExternalSource) also works
19:45amalloywildnux: #(some-cond %) is just some-cond
19:46wildnuxamalloy: :) i see it now, rookie mistake :P
19:54kenrestivoi really should be using a database, but just for grins, how would i flatten out a nested map {:k1 {:k2 {:k3 1 :k4 2}}} to be: [[:k1 :k2 :k3 1] [:k1 :k2 :k4 2]] ? was thinking i could abuse reductions for this purpose, but that felt kinda hacky to me
19:56EvanRwhat is going on... im calling a function of 2 args, with 2 args. the error says "passed 1 arg". so i changed it to pass 3 args. error "3 args". 4 args "4 args". back to 2 args "1 arg"
19:58kenrestivoEvanR: source?
19:58kenrestivopretty sure i've seen that, it was pilot error, for sure.
19:59EvanR,((fn [a b]) 1)
19:59clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval25/fn--26>
19:59EvanR,((fn [a b]) 1 nil)
19:59clojurebotnil
20:02kenrestivoright, a b are the two args, you passed it 2 args, 1 and nil, no problem.
20:02EvanRkenrestivo: https://www.refheap.com/f4ff22de5030335b7d194abc1
20:03kenrestivothat postwalk callback is the one giving you trouble?
20:04kenrestivomaybe [[k v]] not [k v] ?
20:04EvanRok, im misinterpreting where the error is coming from
20:04EvanRthe tracebook in the postwalk isnt pretty
20:04EvanRback
20:04kenrestivoclojure tracebacks are.... an acquired taste.
20:05EvanRtrying your fix
20:05kenrestivoalso acquired taste: putting closing parens all on one line.
20:05EvanRwhen i do its hard to put something in between them in the right place
20:06EvanR(with vim)
20:06kenrestivoi'm pretty sure vim supports paren matching, even completion
20:06EvanRi need to put something somewhere in a ))))))))
20:06EvanRfor example
20:07EvanRit will show me the matching paren on the left, but its either-or, not clear
20:07EvanRalso known as i suck at lisp
20:07kenrestivoeveryone sucks at everything until they get good at it.
20:09ajmccluskeyEvanR: paredit mode in Vim is decent for managing parens. That and paren highlighting are enough for me. Obviously takes a little time getting used to it, but Vim/Emacs users are used to that.
20:10EvanRim using vim-sexp which i gather is the cousin to paredit we dont talk about
20:12EvanRwell my problem was in the arguments of the postwalk function
20:12ajmccluskeyHmm, I've never looked at vim-sexp. Think I'm too used to paredit now to change without a compelling reason.
20:14ajmccluskeyIt might well be true, but I keep having to tell myself I'm not stupid despite how much trouble implementing a basic graph in Clojure is giving me.
20:14kenrestivoyeah, i didn't look closely at the code but that kind of popped out at me. a common error i make: [k v] instead of [[k v]], and the "two arguments supplied" error pointed at that
20:14fowlslegsSay I accidentally started an infinite loop in a REPL. Is there a way to kill it w/o closing the REPL?
20:14ajmccluskeyCtrl-C works for me
20:16EvanRctrl-c, if youre lucky
20:16fowlslegsajmccluskey: Do you run that in the terminal you started lein from?
20:16EvanRajmccluskey: a basic graph. a map from node id to node id?
20:17EvanRor, set of node ids
20:17fowlslegsDidn't work for me.
20:17ajmccluskeyfowlslegs: I hit that in the repl that's infinite looping
20:17ajmccluskeyfowlslegs: if that fails, I kill the java process that's chewing CPU more than the others :p
20:18fowlslegsDoes killing that java process kill Leiningen as well?
20:18ajmccluskeyEvanR: Maybe it's slightly more than basic. It's a directed graph, and I have to collapse equal nodes at some point
20:19EvanRequal nodes?
20:19justin_smithajmccluskey: look at the adjacency-list representation, that's the right way to do it with immutable values
20:19ajmccluskeyfowlslegs: it'll kill the `lein repl` session that you started
20:19justin_smithajmccluskey: don't try to do it as nested data structures with clojure data structures, that's doomed
20:20ajmccluskeyEvanR: nodes that have an equal value. It's a bioinformatics problem and I need to collapse all nodes with the same value onto one node, while cumulating all of their edges.
20:20justin_smithajmccluskey: http://en.wikipedia.org/wiki/Adjacency_list
20:20fowlslegsajmccluskey: I just ran `exit` in the REPL since the process was sent from CIDER. Is there a ctrl+c equivalent in CIDER?
20:20justin_smithfowlslegs: C-c C-c
20:20ajmccluskeyjustin_smith: I think I got burned trying that last time (and this time). I'll go back to thinking harder. Thanks.
20:21fowlslegsjustin_smith: danke
20:21justin_smithajmccluskey: got burned doing what?
20:21ajmccluskeyjustin_smith: last time I was trying to store my graph as a map containing a list of nodes, and each node a list of its incoming and outgoing edges
20:22justin_smithajmccluskey: yeah, that is provably impossible with immutable data structures if the graph has any cycles
20:22justin_smithalso, adjacency lists are easier to work with even if you don't have cycles
20:23ajmccluskeyjustin_smith: I think I got it working, but as the algorithms course got harder my graph got very slow and unruly. I gave up and moved to Java after that.
20:23justin_smithin conclusion: adjacency lists!
20:25ajmccluskeyjustin_smith: I thought I was going for an adjacency list :(
20:26pataprogrammingajmccluskey: aysylu/loom implements basic graph data structures. Looking at the internals may be helpful if you're spinning your own.
20:27ajmccluskeymy design was a vector with nodes referenced by their index in the vector, and each node containing 3 items - value, indexes of nodes pointing to it, indexes of nodes its pointing to
20:28ajmccluskeypataprogramming: thanks. will check it out. Given it's for a course and I'm trying to get more Clojure under my belt, I'm spinning my own, but something to look at would be helpful.
20:48tufti used loom on a school project. pretty handy
20:48ajmccluskeypataprogramming: loom is perfect for me to look at. Thanks again. I feel vindicated that our designs seem to be in the same ballpark
20:54arrdemalexyakushev: ping
20:59alexyakushevarrdem: sup
21:01kenrestivoi hate this function very much, but it works, and i'm not sure how to approach making it less ugly: https://www.refheap.com/943773
21:01arrdemalexyakushev: two things.. first is "getting started" reading on skummet's internals? realized we're wasting effort getting the same place two ways.
21:02amalloykenrestivo: that is a 404?
21:02amalloyyou appear to have meant https://www.refheap.com/94377
21:02alexyakushevarrdem: indeed, I was saying that back in spring:)
21:03kenrestivohttps://www.refheap.com/94379
21:03arrdemalexyakushev: hehe so was I but oh well.
21:03kenrestivoactually https://www.refheap.com/94380
21:04amalloykenrestivo: so like, the most basic improvement is that all these nested fors and apply concats should just be a single for
21:04pataprogrammingajmccluskey: Cheers.
21:04kenrestivoamalloy: i'm not following. how could that be possible?
21:05kenrestivobecause, that'd be a huge improvement, maybe could just call it done at that point
21:05amalloykenrestivo: vaguely like https://www.refheap.com/426385e142aa84e8a86424855
21:06kenrestivooh cool, abusing :when
21:06amalloyabusing????
21:06kenrestivook, properly using, in a way i've never seen before
21:06amalloykenrestivo: how is it any different from the way you were already using it?
21:07kenrestivoi didn't know you could nest the bindings like that.
21:08kenrestivothat's really neat, thanks
21:09kenrestivo(inc amalloy)
21:09lazybot⇒ 200
21:09amalloyyou're welcome
21:09kenrestivohey! round number!
21:09amalloy256 or bust
21:09kenrestivo-127 or bust THIS IS JAVA
21:09CaptainLexSo out of curiosity, why is numeric-tower in contrib? Why is exponentiation not in clojure.core?
21:10amalloyCaptainLex: because it's in java.lang.Math
21:10amalloyif you want to use doubles, anyway. and if you want to use ints, it's trivially easy to do yourself: (apply * (repeat n b))
21:10CaptainLexamalloy: So you mean best practice is actually to access it through that most of time?
21:11amalloysure, why not?
21:11CaptainLexYeah exponentiation is easy but I want square roots
21:11CaptainLexNo reason not
21:11CaptainLexjust making sure
21:14gfredericks,(Math/sqrt Math/PI)
21:14clojurebot1.7724538509055159
21:20FriedBobThis snippet was taken from a demo/tutorial on zippers, but I was wonder if this is generalyl considered the best way to load and parse an XML file? https://gist.github.com/llowder/a58fb6aa92251f6858f0
22:08gfredericks&(map int (.doFinal (doto (javax.crypto.Cipher/getInstance "AES/CBC/NoPadding") (.init javax.crypto.Cipher/ENCRYPT_MODE (javax.crypto.spec.SecretKeySpec. (byte-array 16) "AES"))) (byte-array 16)))
22:08lazybot⇒ (-121 -74 -27 113 108 -81 112 116 -43 -19 103 -34 -70 -73 -3 10)
22:08gfredericks&(map int (.doFinal (doto (javax.crypto.Cipher/getInstance "AES/CBC/NoPadding") (.init javax.crypto.Cipher/ENCRYPT_MODE (javax.crypto.spec.SecretKeySpec. (byte-array 16) "AES"))) (byte-array 16)))
22:08lazybot⇒ (83 -65 15 -94 97 -123 3 127 73 -38 -71 -43 -86 10 103 -77)
22:09gfredericksdoes anybody know enough about javax.crypto and/or AES to guess why ^that's nondeterministic?
22:11justin_smithgfredericks: It's an intentional feature of AES that two encryptions of the same plaintext with the same key don't give you the same result. Otherwise an attacker can make rainbow tables.
22:11justin_smithIt's all about making attempts to break your crypto as CPU expensive as possible.
22:12justin_smithIf you are testing an encrypted / hashed result, the right thing is to verify the hash, not compare two cyphers.
22:12gfredericksI learned AES back in the day and that doesn't sound familiar; and now I'm having trouble imagining how this can even work
22:12justin_smiths/cyper/cyphertext
22:13gfredericksI thought a block cipher was supposed to be a permutation
22:13jneenis there an obvious reason i'm missing that leiningen might ignore ~/.lein/profiles.clj ?
22:13justin_smithgfredericks: right, but there are multiple outputs that decrypt / verify identically
22:13jneeni added a profile there and it claims it doesn't exist
22:14gfredericksjustin_smith: isn't the output block the same size as the input block?
22:14fowlslegsgfredericks: Simple answer is that for symmetric encryption algorithms multiple messages are not secure in the presence of an eavesdropper when the algorithm is deterministic.
22:14justin_smithjneen: what happens if you try to load the file from a repl, any errors?
22:14justin_smithgfredericks: it is not about size, it's about the contents of the output being deterministic or not
22:14justin_smithgfredericks: as I said, otherwise you end up with rainbow tables
22:14gfredericksright but if you have to be able to get the input from the output then there has to be room for nondeterminism
22:15gfredericksif they're the same size then decryption would be ambiguous, no?
22:16fowlslegsgfredericks: The nonce used to encrypt each block is given as part of the ciphertext.
22:17justin_smithalso, the fact that it is called a nonce makes me happy
22:17gfredericksso Cipher is internally generating some random bits?
22:17fowlslegsIf you encrypt the same block with the same cipher and nonce, then the ciphertext will be the same.
22:17gfredericksI don't see any avenue for setting the nonce
22:17fowlslegsYeah, this depends on the mode AES is in.
22:17gfredericksin the API
22:17gfredericksI also don't understand why that gives me 16 bytes of output then -- seems like it's the same size as the input
22:18jneenjustin_smith: welp it was missing a delimiter
22:18jneen(which you'd think lein would warn you about...)
22:18jneenbut i fixed the missing delimiter and it's got the same behavior
22:19justin_smithjneen: indeed. silently swallowing errors is a plague.
22:19jneenso there must be some other error it's silently swallowing?
22:19justin_smithjneen: odd. can you share the file?
22:20gfredericksoh I see it's .getIV
22:20gfredericksI had tried that before but probably before calling .init so it came back nil
22:20fowlslegsgfredericks: I know nothing about the Java implementation, so I can't help you any more with that. I just know how it works abstractly. And like I said, there are different modes of operation for block ciphers and different methods to generate nonces, so that's another variable.
22:20gfredericksjustin_smith: fowlslegs: thanks
22:21fowlslegsgfredericks: glad I could help. Usually I'm the one getting help from you.
22:21gfredericks(inc fowlslegs)
22:21lazybot⇒ 2
22:22jneenjustin_smith: https://gist.github.com/jneen/5c5925ed3cc77707d9e1
22:22jneen; lein with-profile foo pprint
22:22jneen(Warning: profile :foo not found.)
22:23fowlslegsgfredericks: Didn't know about that bot feature and thanks. Is this value actually stored somewhere?
22:23gfredericks$karma fowlslegs
22:23lazybotfowlslegs has karma 2.
22:23gfredericksfowlslegs: in lazybot's database I assume
22:23justin_smithfowlslegs: it's in a mongodb store on lazybot's server
22:23fowlslegs$karma gfredericks
22:23lazybotgfredericks has karma 112.
22:24gfredericksamalloy made it to 200 today I Think
22:24justin_smithfowlslegs: lazybot is open source, and I did a huge refactoring to up some lib versions recently if you have any more specific questions about the impl
22:24justin_smith$karma amalloy
22:24lazybotamalloy has karma 200.
22:24justin_smithnice!
22:24gfredericksnot even for making a joke
22:24justin_smith$google github raynes/lazybot
22:24lazybot[Raynes/lazybot · GitHub] https://github.com/Raynes/lazybot
22:25justin_smith^^ official repo
22:25jneenjustin_smith: i'm literally copying from the docs at this point
22:26justin_smithjneen: I even scanned for hidden unicode chars that may be throwing it off, but it looks clean
22:27justin_smithand the file is in ~/.lein/profiles.clj?
22:27jneen; ls ~/.lein/
22:27jneenprofiles.clj
22:28TimMclein version?
22:28jneenlatest
22:28jneenjust ran lein upgrade
22:28jneento see if that would fix it
22:28jneenso that'd be 2.5.0
22:28TimMcTry lein upgrade 2.4.3 and re-try.
22:29jneeni had 2.4.2 before
22:29TimMcah, OK
22:29fowlslegsjustin_smith: Looks great! Don't have time to check out the code right now, but I starred it for later.
22:29jneeni can try 2.4.3 for lulz but i can't imagine it'd be much different
22:29TimMcI'm grasping at straws; 2.5.0 has some profiles weirdness, but it shouldn't affect this...
22:30jneenyeah me too
22:30TimMcyeah, don't bother
22:30jneenyeah 2.4.3 as well
22:31jneenis there some sort of like, "find the lein directory somewhere else" configuration i may have set accidentally?
22:31jneenmy lein script is at ~/.local/bin/lein
22:32jneenand i've got a ~/.local/lib/lein that's got a few things in it
22:32jneen; ls ~/.local/lib/lein
22:32jneenrepl-history self-installs/
22:32justin_smithjneen: try putting profiles.clj in that dir
22:33jneengiving that a go
22:33justin_smithbecause those things usually are in ~/.lein
22:33justin_smithso maybe it thinks that is your LEIN_HOME or something...
22:33jneenoh hey would you look at that
22:33jneen; echo $LEIN_HOME
22:33jneen/home/jneen/.local/lib/lein
22:33jneenw e l p
22:33justin_smithwell that would explain that!
22:33jneenthanks past jneen
22:35justin_smithsorry I didn't think of LEIN_HOME earlier
22:35jneenbam
22:35jneenthank you all
22:43TimMcfascinating
22:43TimMcI didn't even know that was a thing, but it makes sense.
22:57bridgethillyerjneen: phew!
23:18jneenbridgethillyer: ohai :)
23:18bridgethillyerhi!!!
23:25justin_smithhttp://i.imgur.com/v3KlJoc.gif perfect metaphor for my first ignorant attempts to use clojure