2014-01-30
| 00:01 | akurilin | bbloom: not 100% sure what you're referring to |
| 00:01 | bbloom | (def ^:private cleanup-process (future (let [cleanup myns/cleanup] (loop [] (when (= cleanup myns/cleanup) (cleanup) (recur))))) |
| 00:01 | bbloom | er stick a @ on that |
| 00:01 | bbloom | or rather no @ sorry ignore me |
| 00:02 | bbloom | the future won't run w/o somebody demanding it, right? so you need to spin up a thread somewhere |
| 00:02 | bbloom | can also just use stupid agents: |
| 00:03 | bbloom | (def cleanup-agent (agent nil)) .... (send-off (fn rec [_] sleep (cleanup) (send cleanup-agent rec))) |
| 00:03 | bbloom | make that (Thread/sleep whatever) |
| 00:03 | bbloom | and send vs send-off i always forget |
| 00:03 | bbloom | but the idea is the same |
| 00:04 | bbloom | rely on the agent thread pool |
| 00:04 | bbloom | uses the agent as a trampoline for tail recursion |
| 00:04 | akurilin | Brain's melting a little bit. |
| 00:05 | akurilin | I think I'm going to roll with the var version first |
| 00:09 | elarson | are there any tutorials or anything that provide a good overview of testing in clojure using emacs, clojure test mode and cider? |
| 00:09 | elarson | this is based on a lein new app based project |
| 00:10 | technomancy | elarson: apart from recommending the starter kit, the clojure-doc emacs tutorial is pretty good http://clojure-doc.org/articles/tutorials/emacs.html |
| 00:10 | technomancy | or at least it was last I checked |
| 00:11 | elarson | technomancy: I'm pretty sure I'm doing something pretty similar to the starter kit. my emacs config is a bit to personalized (IMHO) to start from scratch |
| 00:11 | elarson | that said, I'll will take a closer look |
| 00:11 | technomancy | yeah, that's a good thing =) |
| 00:12 | elarson | assuming I did use the starter kit though, is C-c , the only way to run the tests? |
| 00:12 | technomancy | no, just the quickest |
| 00:12 | technomancy | you can always invoke them manually in the repl with (run-tests) |
| 00:12 | elarson | in python I used my pytest.el mode which did the test run in a compile buffer so I was able to jump through the trace, so I didn't know if there was something similar |
| 00:12 | elarson | ah |
| 00:12 | elarson | that is good to know |
| 00:13 | elarson | technomancy: is it normal that you have to re-eval the clojure files in order to get the tests to find changes in the tests and/or file being tested? |
| 00:14 | technomancy | yeah, run-tests does not reload things for you |
| 00:24 | gtrak | hrm... any chance we can get file info from cljs-repl eval? it seems to have line, but not file. |
| 00:28 | dnolen | gtrak: you would need to give the repl file info, the repl doesn't know |
| 00:29 | gtrak | I'm looking at the impl of cljs.repl |
| 00:30 | akurilin | If I want to atomically look at the value of a var and decide whether I want to update it or not, returning what exactly I did, should I use a ref rather than an atom? |
| 00:30 | gtrak | seems like it's gotta bootstrap from some manner of source files... looking at 'assoc in the analyzer output. |
| 00:30 | akurilin | Doesn't look like swap! has semantics to inform the caller whether anything was done to the atom or not. |
| 00:33 | dnolen | gtrak: I don't know what leads you to think this |
| 00:33 | gtrak | dnolen: not sure :-), just scratching the surface of how it bootstraps a repl.. |
| 00:33 | dnolen | gtrak: anyways, evaluate-form take an optional filename |
| 00:34 | gtrak | was surprised to find no file info for builtins |
| 00:34 | dnolen | gtrak: you have to *give* it |
| 00:37 | gtrak | huh odd. seems like it oughta work, then, rhino repl calls load-file with "cljs/core.clj", calls load-stream, which calls evaluate-form with same |
| 00:38 | gtrak | core.cljs, sorry |
| 00:39 | gtrak | I will trace it through at some point |
| 00:42 | dnolen | gtrak: where are you expecting :file info? on the meta of a form or something? |
| 00:43 | gtrak | in the analyzer env, there's a :file key for assoc but it's got a nil value. |
| 00:43 | gtrak | (-> env :cljs.analyzer/namespaces (get 'cljs.core) :defs (get 'assoc) :line) |
| 00:43 | gtrak | oddly it's got a line number, :file is nil |
| 00:45 | dnolen | gtrak: k I follow now, yeah that is weird |
| 00:45 | gtrak | I'm hacking piggieback to get to this... I can investigate more in the morning, good to know you think it should work. |
| 00:47 | dnolen | gtrak: actually looks like a simple problem |
| 00:47 | dnolen | gtrak: line 242 in analyzer.clj |
| 00:47 | dnolen | gtrak: we check *cljs-file* instead of first checking that :file isn't present env |
| 00:49 | dnolen | gtrak: hrm, actually *cljs-file* should be bound, dunno, something subtle going on |
| 00:51 | gtrak | maybe it's bound to nil? :-) |
| 01:05 | gtrak | dnolen: nothing's actually calling analyze-source, from what I can tell. |
| 01:07 | gtrak | rhino-setup calls repl/load-file directly, but repl/repl actually calls analyze-source which populates the path info. |
| 01:11 | gtrak | piggieback doesn't call repl/repl either |
| 01:13 | gtrak | so... I think I can hack something together now. |
| 01:53 | sm0ke | hello anyone know of a sane ctags file for clojure syntax? |
| 03:21 | sm0ke | hmm its awfully quiet today in here |
| 03:34 | quizdr | interesting article that suggests coffescript is the most expressive of the major languages. clojure and haskell close behind: http://www.infoq.com/news/2013/03/Language-Expressiveness |
| 03:49 | TEttinger | quizdr, I saw that. not sure how effective their metrics are. |
| 03:51 | cark | that's pretty stupid, javascript is actually very expressive |
| 03:52 | cark | this measure the habits of a population rather than the languages |
| 03:55 | fredyr | expressiveness is a really weird metric isn't |
| 03:55 | fredyr | it |
| 03:56 | cark | yes |
| 03:59 | atyz | Is anyone here familiar with core.async? I have a function for validating entities (that calls an external service) however it takes the same amount of time as if I was doing it synchronously. I feel like I"m missing something. https://www.refheap.com/29715 . Any guidance would be greatly appreciated |
| 03:59 | dsrx | using LOC to measure anything, especially across languages, is absurd |
| 04:00 | quizdr | am i thinking correctly that having an explicit recur form is actually a win for clojure, rather than tail recursion being automatic? reading scheme, for example, the syntax for optimized tail recursion (iterative recursion) vs. linear recursion (memory-consuming) are not different, therefore you must look more closely to see if scheme will actually optimize it |
| 04:03 | cark | i seem to remember ritch saying that even if we had TCO he would keep recur in the language |
| 04:03 | cark | might be wrong tho |
| 04:04 | cark | i kinda disagree there |
| 04:04 | cark | you learn to see tail recursion at a glance |
| 04:04 | cark | if you can't see that, you certainly didn't understand the function at all |
| 04:05 | cark | so you might as well just not read it ! |
| 04:05 | cark | =) |
| 04:05 | quizdr | if you use recur at least you know that, if it works, you have used it properly. if you had normal TCO you could still have a working function, even if it wasn't optimized, due to an error of logic |
| 04:06 | cark | atyz: i don't even understand how that would run, isn't <!! supposed to be in a thread block or something ? |
| 04:07 | cark | quizdr: seriously, there is no added cognitive load with tail recursion, and i say that as a fairly limited person =) |
| 04:07 | atyz | cark: I think you can run that ona channel |
| 04:08 | cark | you'll get bitten by it once or twice as a newbie, then never again |
| 04:08 | atyz | however, I'm very lost at the moment |
| 04:08 | d11wtq | Have to agree. Having previously done Scheme and Erlang, TCO is just something you learn. |
| 04:08 | deadghost | I like clojure because it is very good for cognitively challenged people like myself |
| 04:09 | d11wtq | A deadghost would be fairly cognitively challenged, one would assume :) |
| 04:09 | cark | atyz: hum but you're blocking your full thread aren't you ? i'm usually using <! myself (single !) that must go in a go block |
| 04:09 | cark | hum wrong person |
| 04:09 | atyz | cark: it seems that way. |
| 04:10 | atyz | are you suggesting (go (<!! (async/into [] validated)))? |
| 04:10 | cark | nope |
| 04:11 | atyz | sorry (go (<! (async/into [] validated))) |
| 04:11 | cark | i'd put the while thing in a go block ... but this is not his problem i think |
| 04:12 | cark | quizdr: what's coming in the assets parameter ? |
| 04:12 | cark | what's in this collection ? |
| 04:12 | cark | and what does f ? is it just a predicate? |
| 04:13 | quizdr | cark: not sure what you are talking about |
| 04:13 | atyz | cark: this is just a collection of entitys '({:some :key :anoter :key}). The function would be something that validates that collection. in this case. valid-asset? which acceps an asset |
| 04:14 | cark | atyz: that's not how it works |
| 04:14 | cark | you should first map your collection of entities to a collection of channels |
| 04:14 | lvh | so, are there any decent string interpolation things that do *NOT* work at compile time? I am interpolating some templates only available at runtime. |
| 04:14 | lvh | (They're markdown templates.) |
| 04:15 | atyz | Oh. so you want a channel for each entity? |
| 04:15 | lvh | I am aware of format, but I'd like something with named parameters, and hopefully also code eval. |
| 04:15 | cark | atyz: then you may filter it with filter< |
| 04:15 | cark | atyz: yes |
| 04:15 | cark | atyz: your goal is to have those requests done in parallel ? |
| 04:15 | atyz | cark: yep |
| 04:16 | atyz | Sec, just looking up something in the api |
| 04:16 | cark | don't use map< that's not it |
| 04:16 | atyz | So filter only takes one channel at a time |
| 04:17 | atyz | I will have to doseq over every channel and call filter on that? |
| 04:18 | cark | atyz : nope you can do it declaratively ...f |
| 04:18 | cark | first you need a function that initiated a request, returning a channel that will contain the requested data |
| 04:18 | cark | initiates* |
| 04:19 | cark | let's call it request-chan |
| 04:19 | cark | then you can do this : (map request-chan assets) |
| 04:20 | cark | that will give you the list of channels |
| 04:20 | cark | that's the standard clojure map |
| 04:20 | atyz | Ok |
| 04:21 | cark | then i *think* you need to use (async/map identity asset-chans) |
| 04:22 | cark | and finally you can filter like you did, only using a simple predicate |
| 04:22 | atyz | https://www.refheap.com/29715 |
| 04:22 | atyz | Something like that |
| 04:22 | atyz | ? |
| 04:23 | cark | i don't see where you initiate your request in there |
| 04:23 | cark | you would do that in request-chan |
| 04:23 | atyz | Oops it was meant to be to-chan |
| 04:24 | cark | let me fork and write soemthing |
| 04:24 | atyz | So if you look now, request chan will take an asset and add it to a chan |
| 04:27 | quizdr | Is there anyway to somehow save or dump all the various definitions including functions that you've created while working at the repl? |
| 04:27 | atyz | quizdr: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-publics |
| 04:28 | atyz | Would that be what you're looking for? |
| 04:28 | atyz | you could also probably use ns-map |
| 04:29 | atyz | cark: heh I keep killing my repl :\ |
| 04:29 | cark | atyz: https://www.refheap.com/29723 |
| 04:29 | quizdr | atyz: well, except that the mapping only shows function names, not contents; I guess the funcitons are immediately compiled and don't exist as code any more, unlike a data type which can be printed exactly the same way as you'd need to recreate it |
| 04:30 | cark | atyz: there might be a sinpler way to do that async/map part |
| 04:31 | quizdr | i guess one potentially bizarre but maybe useful workaround would be to have a macro that i'd use to define functions; you pass the function body etc as normal and the function is created, but the source for your function is also stored to an atom or something. you could then print out the atom to get all the source you came up with for various improvised functions, and then read them back in |
| 04:31 | cark | atyz: ah indeed looks like async/merge will do it |
| 04:33 | cark | atyz: there you go https://www.refheap.com/29723 |
| 04:34 | atyz | cark: sorry this is a dumb question, but I'm not sure what the initiate request function is doing? |
| 04:34 | cark | at some point you need to call your service |
| 04:34 | cark | i don't know how you do it, you didn't say |
| 04:34 | atyz | that would be done through a library I've written that is encapsulate int eh validate-function |
| 04:35 | atyz | so the function I'm passing (f) encapsulates all of that |
| 04:35 | cark | well, that's bad style =) |
| 04:35 | atyz | Might I ask why? |
| 04:35 | cark | what does that function return ? |
| 04:35 | atyz | Its part of a library I've written |
| 04:35 | atyz | It returns true or false |
| 04:36 | cark | well, it "complects" doing the request and validating it |
| 04:36 | cark | or rather validating the result |
| 04:36 | cark | these are 2 different concepts : 1 network request, 2 data validation |
| 04:37 | cark | if your service is doing the validation, you may put it all in request-chan |
| 04:38 | cark | let me do it |
| 04:38 | zoldar | anybody working with cloact/reagent here? |
| 04:38 | cark | your function returns a chan ? or does it use a callback ? |
| 04:39 | cark | or is it blocking >< |
| 04:39 | atyz | I suppose I see that, its that this library is being used in several places and I dont liek the idea of moving teh service network request to this file. However I suppose I could this async code into the library |
| 04:39 | atyz | It would be a http request |
| 04:39 | atyz | So blocking |
| 04:39 | cark | well then, there is you bottleneck |
| 04:39 | cark | let me fix that |
| 04:40 | atyz | Yeah its a huge bottleneck |
| 04:40 | zoldar | I have an issue where I'm rendering a component being a table row (tr). The problem is, I want to conditionally render additional row in the the same component. Reagent seems to require the subcomponents being wrapped in another component, however I can't nest tbody inside already existing tbody. |
| 04:41 | zoldar | React.js itself is perfectly fine with putting components in a simple array, whereas Reagent seems to always require a component at the top level. Maybe I'm missing something. |
| 04:44 | cark | atyz: https://www.refheap.com/29723 |
| 04:44 | cark | atyz: actually it's not bad style if it's the service doing the validation |
| 04:44 | zoldar | my temporary workaround for that is using mapcat instead of map a level higher and wrap the rendered component in a vector. |
| 04:45 | atyz | cark: I"m confused. filter returns the channel? |
| 04:46 | atyz | There is nothign on any channels? |
| 04:46 | cark | hum |
| 04:46 | cark | what does your validation function return exactly ? |
| 04:46 | cark | is it a boolean ? |
| 04:47 | atyz | it is |
| 04:47 | cark | https://www.refheap.com/29723 |
| 04:49 | cark | assuming my-lib-validation-func is blocking, the validate function would return a serie of filtered maps all having :valid? true |
| 04:49 | atyz | It is |
| 04:49 | cark | merge is async/merge |
| 04:49 | cark | map is clojure.core/map |
| 04:49 | cark | filter< is async/filter< |
| 04:49 | atyz | async/merge takes a collection of source channels |
| 04:50 | atyz | But we're not creating any? |
| 04:50 | cark | map creates a collection, right ? |
| 04:50 | atyz | It does |
| 04:50 | cark | the request-chan function creates a channel, right ? |
| 04:50 | atyz | no? |
| 04:50 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 04:50 | atyz | OH wait |
| 04:50 | atyz | Thread returns a channel |
| 04:50 | cark | the thread macro returns a channel, that will contain the result of the body, then close it |
| 04:51 | atyz | Ahh I understand |
| 04:51 | atyz | I just have to move some code around then I'll give this a shot! |
| 04:52 | cark | heh good luck |
| 04:52 | atyz | Thanks so much - I feel like I understand this better |
| 04:52 | cark | cool! |
| 04:52 | atyz | So if I was to take this a step further? What shoudl I look at? |
| 04:53 | cark | well you have to get the data out of this channel, and do something with it =) |
| 04:53 | cark | maybe just print it at firsty |
| 04:53 | atyz | can't I use (async/into [] result-of-filter) ? |
| 04:53 | cark | test it with some valid and invalid data |
| 04:54 | atyz | I have those tests setup already for when it was working "synchronously) |
| 04:54 | atyz | *"synchronously" |
| 04:54 | cark | well no |
| 04:55 | cark | into will give you a channel with a collection of maps ....just what you had before |
| 04:55 | atyz | Thast what I need |
| 04:55 | cark | ah let me show you |
| 04:55 | cark | second |
| 04:59 | cark | atyz: https://www.refheap.com/29723 |
| 05:00 | atyz | *looks up take* |
| 05:00 | cark | forgot the recur ...but you get the drift |
| 05:01 | cark | https://www.refheap.com/29723 |
| 05:03 | atyz | why are both the as-you-wanted and print-results calling the validate function? |
| 05:03 | cark | that's 2 ways to do about the same thing |
| 05:05 | cark | that's how you get the data out of the chan in the end |
| 05:05 | atyz | Oh wow |
| 05:05 | atyz | This is like 100 times faster |
| 05:05 | cark | ahwell... must not be working then =) |
| 05:06 | atyz | And I understand how its working! |
| 05:06 | cark | great ... i'll go back to AFK then =) |
| 05:06 | cark | good luck ! |
| 05:06 | atyz | thank you! :) |
| 05:12 | SNBarnett | cs |
| 05:17 | tim_ | hi, i'm new to emacs http://elpha.gnu.org seems to be unavailable for at present, is there an alternative repo apart from marmalade as trying to install cl-lib-0.3? |
| 05:24 | no7hing | binding apparently only works in the lexical scope - is there a way to use a binding in calls to other functions without using alter-var-root? |
| 05:24 | cark | no7hing: that's not true |
| 05:25 | no7hing | then i must've made a mistake |
| 05:26 | cark | it works in the dynamic scope |
| 05:26 | cark | that means in all the functions that are called inside the binding form, and the ones called by those |
| 05:27 | cark | but you might want to declare you var this way : (def ^:dynamic myvar "hello") |
| 05:28 | cark | your* |
| 05:29 | cark | also there are a few gotchas with lazy sequences |
| 05:33 | no7hing | thatoh |
| 05:33 | no7hing | looking into this, as then binding stops working some function calls deep |
| 05:34 | cark | are you returning a sequance out of the binding form ? |
| 05:34 | cark | sequence* |
| 05:37 | no7hing | actually yes |
| 05:38 | cark | that's a common problem |
| 05:38 | cark | use doall on those sequances that will go out |
| 05:38 | cark | sequences* .. |
| 05:38 | no7hing | is there a way so solve/circumvent it? |
| 05:38 | no7hing | i'll try that |
| 05:39 | no7hing | now i got it, sorry for being so thick |
| 05:39 | cark | np |
| 05:48 | doody1 | how does one reload changed code referenced from checkouts folder in repl? Is restart necessary? |
| 05:50 | cark | require and :reload-all |
| 05:54 | doody1 | can this be automated? |
| 05:55 | cark | i guess, that's not part of my workflow .... usually i edit a file, then evaluate it from my editor, which knows how to send it to the repl |
| 06:01 | doody1 | hmm, I edit a referenced source (the doc of a ns) and evaluate it in cider, but it seems repl does not see it |
| 06:02 | cark | hum did you start the repl with cider-jack-in ? |
| 06:03 | doody1 | hmm using emacs live, there's nrepl not cider, i did connect to a running repl |
| 06:03 | cark | mhh i can't help at all with emacs-live. never tried it |
| 06:03 | doody1 | thanks |
| 06:07 | doody1 | its the same thing with nrepl instead of cider |
| 06:08 | doody1 | ahh interesting, when I change the doc for a function it does show the changed doc |
| 06:08 | doody1 | but not so with the doc of a ns expression |
| 06:27 | AeroNotix | what's that error handling library? |
| 06:27 | AeroNotix | slugger? |
| 06:27 | AeroNotix | something like that |
| 06:29 | AeroNotix | slingshot! |
| 06:35 | noncom | doody1: namespaces are strange in clojure |
| 06:35 | noncom | they are different from everything else |
| 06:40 | silasdavis | how can I pass an unbound var as a function argument? |
| 06:40 | silasdavis | I should say a possibly unbound var |
| 06:43 | CookedGryphon | silasdavis: do you mean so if the var changes the function changes with it? |
| 06:43 | CookedGryphon | just wrap it in (var my-defnd-fn) |
| 06:43 | CookedGryphon | and it'll look up the var every time, var implements ifn |
| 06:47 | noncom | i am trying to parse xml with clojure.data.xml/parse and i get this exception: https://www.refheap.com/29786 |
| 06:47 | noncom | what am i to do with that? |
| 06:54 | gko | what's the equivalent of clojure.contrib.repl-utils.show in 1.5.1? |
| 06:54 | rurumate | how to do a 'select distinct' in cascalog? |
| 06:57 | rurumate | ok found it, it's (:distinct false) |
| 06:57 | vijaykiran | gko: http://stackoverflow.com/questions/5821286/how-can-i-get-the-methods-of-a-java-class-from-clojure |
| 06:58 | gko | vijaykiran Thanks! |
| 07:04 | bordatoue | hi just a quick question why does (= 1 1.0) return false in clojure |
| 07:04 | bordatoue | (= 1 1.0), |
| 07:05 | clgv | ,(== 1 1.0 |
| 07:05 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 07:05 | clgv | ,(== 1 1.0) |
| 07:05 | clojurebot | true |
| 07:05 | clgv | ,(doc ==) |
| 07:05 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false" |
| 07:06 | bordatoue | clgv: what is difference between = and == in clojure |
| 07:06 | bordatoue | thanks clgv |
| 07:07 | clgv | numerical comparison is == |
| 07:08 | clgv | $source == |
| 07:08 | lazybot | == is http://is.gd/XeIlE5 |
| 07:08 | bordatoue | clgv: but in the doc it says = can be used for numerical comparison |
| 07:08 | clgv | translates to (. clojure.lang.Numbers (equiv ~x ~y)) when used as call |
| 07:09 | clgv | bordatoue: well it works if they have the same type. the docs should be more specific there |
| 07:09 | clgv | usually it is no good idea to compara floating point numbers via equals |
| 07:10 | bordatoue | clgv: when it says comapres numbers what are they actually refering to |
| 07:11 | clgv | bordatoue: there are also known bugs in clojure <=1.5.1 with respect to comparisons of big integers or big decimals |
| 07:12 | clgv | bordatoue: will be fixed in 1.6 afair |
| 07:12 | bordatoue | could you please explain when it says in the document it compares numbers what kind of numbers are is it mentioning |
| 07:13 | Bronsa | bordatoue: with = you can only compare integer types with integer types (Integer, Long, BigInts) or floating types with floating types (Float, Double, BigFloat) |
| 07:13 | clgv | integers |
| 07:13 | Bronsa | with == you can compare integers with floating types too |
| 07:13 | clgv | right, what Bronsa said ;) |
| 07:14 | bordatoue | I'm getting confused it says in the doc in a type-independent manner |
| 07:14 | bordatoue | for "=" |
| 07:14 | clgv | bordatoue: as I said, the docs should be more specific there |
| 07:15 | bordatoue | so clgv, with "=" we can compare numbers in a type dependent manner is it correct |
| 07:15 | clgv | bordatoue: maybe there is a jira issue for that otherwise you should create one, since it is documentation only chances should be good for inclusion in 1.6 |
| 07:16 | clgv | yeah |
| 07:16 | Bronsa | actually looks like with = you cannot compare a Float/Double with a BigDecimal |
| 07:16 | bordatoue | ok, thanks very much |
| 07:16 | Bronsa | ,(= 1.2M 1.2) |
| 07:16 | clojurebot | false |
| 07:16 | clgv | Bronsa: thats a bug being fixed in 1.6 though |
| 07:16 | bordatoue | Bronsa: they are different type |
| 07:17 | lvh | Hi! could someone review my couple of lines? I'm afraid I might be committing Abominations Unto Rich: https://github.com/lvh/fomp/blob/master/src/fomp/core.clj#L12 |
| 07:17 | Bronsa | clgv: nope |
| 07:17 | lvh | (ignore make-body; I know it's broken) |
| 07:17 | Bronsa | clgv: at least, hasn't been pushed yet |
| 07:18 | clgv | Bronsa: damn, I remembered some dicussion about it... |
| 07:18 | Bronsa | yeah clgv the bug has been fixed for == |
| 07:18 | clgv | but you are right it is not in the current changelog |
| 07:18 | bordatoue | clgv: Bronsa , are you saying with version 1.6 it would be possible to compare different type using "=" |
| 07:19 | lvh | I'm also thinking that maybe recipients should be part of params :) |
| 07:19 | clgv | bordatoue: no probably not |
| 07:19 | clgv | bordatoue: I jsut stated you could try to get the docs adjusted |
| 07:20 | Bronsa | clgv: ok looks like it's expected behaviour as BigDecimal is considered in the decimal category, not in the floating |
| 07:20 | bordatoue | clgv: you mentioned to Bronsa it is an issue fixed in 1.6 (= 1.2M 1.2) |
| 07:21 | Bronsa | bordatoue: he was mistaken |
| 07:21 | sm0ke | can i lauch lein repl with some jvm properties ? |
| 07:21 | sm0ke | -Dxyz=1 |
| 07:21 | bordatoue | ok thanks guys |
| 07:21 | clgv | bordatoue: yeah, but that was an error. the discussion I remembered was obviously around == |
| 07:21 | clgv | bronsa corrected me |
| 07:21 | Bronsa | bordatoue: https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/numbers.clj#L68-L79 |
| 07:22 | Bronsa | the comment there explains nicely how = is supposed to work for numbers |
| 07:23 | pyrtsa | ,[(== 11/10 1.1) (== 1.1 1.1M) (== 1.10M 1.1) (== 1.10M 1.1M)] |
| 07:23 | clojurebot | [true true true true] |
| 07:23 | pyrtsa | Oh, so that got fixed as well. (Returns [true true true false] on Clojure 1.5.1.) |
| 07:23 | emlyn | sm0ke: add :jvm-opts ["-Dxyz=1"] to project.clj |
| 07:24 | sm0ke | emlyn: is there another way |
| 07:24 | sm0ke | changing file is not very friendly |
| 07:25 | deadghost | so if I'm reading this right |
| 07:25 | emlyn | sm0ke: I'm not sure, sorry |
| 07:25 | deadghost | I shouldn't be using jquery with cljs |
| 07:25 | deadghost | or maybe I should |
| 07:26 | sm0ke | emlyn: i think i can set JVM_OPT |
| 07:27 | clgv | ,*clojure-version* |
| 07:27 | clojurebot | {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"} |
| 07:27 | clgv | pyrtsa: ^^ |
| 07:28 | pyrtsa | clgv: Thanks, I knew that. Just didn't know how = and == behave in 1.6.0. |
| 07:29 | emlyn | sm0ke: yes I think that should work too |
| 07:32 | pyrtsa | Numbers in Clojure are a mess. I think Clojure should've done something to help those poor programmers who believe that comparing equality of a Double against a BigDecimal is an okay thing to do. :/ |
| 07:33 | pyrtsa | ,(BigDecimal. 1.1) |
| 07:33 | clojurebot | 1.100000000000000088817841970012523233890533447265625M |
| 07:33 | clgv | pyrtsa: that only bytes you when comparing nested data structure, afaik |
| 07:34 | clgv | when you really care for numbers in computation then you have them "in hand" and compare them via == |
| 07:35 | deadghost | hmm so there's domina, dommy, jayq for dom manipulation |
| 07:35 | pyrtsa | ,(doc ==) |
| 07:35 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false" |
| 07:35 | pyrtsa | ,(nil? false) |
| 07:35 | clojurebot | false |
| 07:35 | deadghost | are any of them the generally recommended choice? |
| 07:38 | clgv | deadghost: arent there plenty blog posts on that topic - I feal as if the people using clojurescript were really chatty about the technologies in the last half year |
| 07:39 | lvh | is there an easy way to turn abitrary strings into something that looks like an easy to type keyword |
| 07:39 | lvh | ie a valid keyword literal? |
| 07:40 | lvh | I have a CSV file with a header that has a bunch of stuff in it like single quotes and spaces that don't work for keywords |
| 07:41 | clgv | lvh: you could use clojure.string/replace for conversion |
| 07:41 | lvh | clgv: Cool, thanks :) |
| 07:45 | lvh | The compiler appears to be complaining about: [:require clojure-csv.core :refer [parse-csv]] ; saying Exception :only/:refer value must be a sequential collection of symbols clojure.core/refer (core.clj:3840) |
| 07:45 | lvh | I don't understand why [parse-csv] doesn't count |
| 07:47 | llasram | lvh: You need [:require [clojure-csv.core :refer [parse-csv]]] -- one more set of nesting |
| 07:48 | lvh | oh, derp. okay :) |
| 07:56 | atyz | Hey all. so I'm doing some work wiht core.async but its not behaving as I would expect. Many of the results I'm receiving are nil and it seems to be giving me a random subset of correct answers and I suspect this is because the channel has been closed. https://www.refheap.com/29811 |
| 07:58 | sobel | what's a zipper? |
| 07:58 | sobel | i find myself more lost in clojure land than most languages because it doesn't have much baggage from java OR native libs typically bound to python/perl/ruby wrappers |
| 07:59 | sobel | nomenclature-lost. the language is fine. :) |
| 08:13 | locks | sobel: a zipper is a functional data structure http://en.wikipedia.org/wiki/Zipper_(data_structure) |
| 08:17 | AeroNotix | does cider support "find callers of this function" ? |
| 08:17 | AeroNotix | kind of like the reverse of M-. |
| 08:22 | hyPiRion | AeroNotix: So functions calling the function, essentially? |
| 08:23 | AeroNotix | hyPiRion: yep |
| 08:29 | sobel | well, i wasn't quite getting it until wikipedia explained it in terms of decategorification. seems my feeble math background still pays off. |
| 08:29 | sobel | thx locks, that pretty much hit the spot |
| 08:33 | sobel | what's the clojure idiom for coalasce? i'll get a value or a nil from a function, and i'm hoping/assuming there's a common expr/macro for "value or default-if-nil" |
| 08:34 | gtrak | cemerick: I nearly got file/line working yesterday, but I think piggieback needs a fix, any thoughts? https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl.clj#L181 repl/repl calls analyze-source, which calls analyze-file, which is where the file info comes from in the first place, but piggieback never makes it through that part of the code. |
| 08:34 | sobel | better question: is 'if' the best idiom for value-or-default? |
| 08:34 | llasram | ,(or nil :default) ;; sobel |
| 08:34 | clojurebot | :default |
| 08:35 | sobel | ah ok |
| 08:37 | cemerick | gtrak: isn't it just a matter of analyze-path being truthy? |
| 08:38 | gtrak | it needs to be given the file path to the core.cljs somehow |
| 08:38 | gtrak | yea, analyze-path is the key |
| 08:41 | marcschwartz | Anyone have any advice on the best way to find freelance Clojure developers? |
| 08:43 | goodger | they probably all hang out here, marcopol_ |
| 08:43 | doody1 | how to jump to definition of a function in emacs |
| 08:43 | goodger | by which I mean marcschwartz |
| 08:43 | doody1 | if its in another namespace |
| 08:44 | doody1 | or file |
| 08:48 | marcschwartz | goodger: Thanks. I'll just put the description of the project on the web somewhere and post the link here every couple days. |
| 08:49 | mdrogalis | marcschwartz: You have a PM. :P |
| 08:51 | stuartsierra | doody1: M-. if the Clojure code has been loaded by CIDER. |
| 08:51 | silasdavis | how can i get the name of a var? |
| 08:52 | silasdavis | as in (declare foo), (name-of (var foo)) |
| 08:53 | stuartsierra | silasdavis: indirectly, via (meta (var foo)) |
| 08:53 | noncom | is there any ready tool to count top-level forms in clj files allover my project? |
| 08:53 | silasdavis | stuartsierra, is that the way to do it? |
| 08:53 | silasdavis | the only way? |
| 08:53 | noncom | just wanna estimate how much unit testing be pain in the ass |
| 08:54 | doody1 | stuartsierra: connected to lein repl via nrepl in emacs, i guess that does not count as being loaded by CIDER |
| 08:54 | stuartsierra | doody1: Compile/load the file you're looking at with C-c C-k and it should work. |
| 08:55 | silasdavis | strange that Vars aren't Named |
| 08:59 | quizdr | in general is it better to look up a key in a map using the key or the map as the function? |
| 08:59 | Anderkent | quizdr: key, it works with nil maps then |
| 09:00 | stuartsierra | quizdr: If the key is a keyword literal, use that as the function. |
| 09:00 | stuartsierra | If either the key or the map could be nil, use `get` |
| 09:00 | quizdr | i suppose one reason to use the collection as the function is then it would be more general in case you use a vector instead of a map and search on key of index |
| 09:01 | Anderkent | Well yes if your keys arent literal keywords then use get or the collection |
| 09:02 | quizdr | Andrekent if the map has nothing in it (is nil?) then it still seems to work whether you search by key or map -- or are you saying that if you search by key you can specify the default return value? |
| 09:02 | Anderkent | quizdr: no, if someone passes nil as the map trying to use it as a function will NPE |
| 09:03 | Anderkent | ,(let [mp nil] (mp :foo)) |
| 09:03 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 09:03 | quizdr | ah i see. regarding keys that aren't keyword literals, using a symbol as a function for a map seems to also work fine |
| 09:03 | Anderkent | uh that depends on what the symbol 'points to' |
| 09:04 | Anderkent | ,(let [key :keyword] (key {:keyword :yes})) |
| 09:04 | clojurebot | :yes |
| 09:04 | quizdr | ,('a {'a 5}) |
| 09:04 | clojurebot | 5 |
| 09:04 | Anderkent | ,(let [key 3] (key {3 1})) |
| 09:04 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 09:05 | Anderkent | oh you mean a literal symbol. I didn't know that |
| 09:05 | lvh | hi, is there a standard for clj docstrings |
| 09:05 | quizdr | yeah |
| 09:10 | quizdr | maps must do some sort of implicit lexical binding or something if you use them as a function, right? for example: |
| 09:10 | quizdr | ,(let [bbb 5] ({bbb 6} bbb)) |
| 09:10 | clojurebot | 6 |
| 09:10 | quizdr | obviously the keyword is overriding the binding of bbb to 5 |
| 09:11 | Anderkent | quizdr: that's just equivalent to ({5 6} 5) |
| 09:11 | quizdr | oh i see. the bbb form is evaluated prior to its insertion in the map |
| 09:43 | mdrogalis | stuartsierra: Vagrant set up you posted is nice. There's some good stuff in there. |
| 09:43 | stuartsierra | mdrogalis: thanks! |
| 09:43 | mdrogalis | Especially the Emacs24 thing. It's a pain every time you gotta do it. |
| 09:44 | cemerick | dnolen: I ran into some difficulty trying to use :as to bind the result of an :or match; I expected either of the first expressions to work, and was surprised that the third did. Bug, or are :or and :as not necessarily supposed to work together? https://gist.github.com/cemerick/6b7bb333293fd11855d9 |
| 09:44 | lvh | I have a bunch of n-vectors; what's the idiomatic way to filter out all the ones where all the elements are empty strings |
| 09:46 | lvh | I guess I want (all (map empty? vec)) where all is reduction with and? (is that a core function?) |
| 09:46 | stuartsierra | lvh: `remove` and `every?` should do it |
| 09:48 | dnolen | cemerick: interesting open a ticket though I can't say when I'll get to that. patch welcome |
| 09:49 | lvh | stuartsierra: Thanks! |
| 09:49 | cemerick | dnolen: Will do. I may take a whack at a patch, depends. What *should* happen? |
| 09:49 | stuartsierra | lvh: you're welcome. |
| 09:50 | dnolen | cemerick: the first one looks like sugar to me, so I don't really care whether that works or not. |
| 09:50 | dnolen | cemerick: the other 3 should all work |
| 09:51 | cemerick | dnolen: thanks |
| 09:54 | lvh | Can I do destructuring def? |
| 09:54 | lvh | I guess I don't really need it |
| 09:55 | stuartsierra | lvh: def does not support destructuring |
| 09:56 | octane-- | stuartsierra, mdrogalis: could you please repeat that about the vagrant setup? |
| 09:57 | Anderkent | lvh: not without a non-core macro. (let [[x y & rest] (def x x) (def y y) (def rest rest)) kinda works, but i'd avoid it if at all possible |
| 09:57 | stuartsierra | octane--: https://github.com/stuartsierra/devbox |
| 10:04 | edbond | cemerick, changed lein-cljsbuild to 1.0.2 and got NPE - https://www.refheap.com/29856 1.0.2-SNAPSHOT works fine. |
| 10:09 | edbond | cemerick, to reproduce -> "lein new mies-om ommm", change lein-cljsbuild version to "1.0.2" in project.clj and "lein cljsbuild once" |
| 10:09 | cemerick | edbond: I think you've somehow gotten a stale cljsbuild dependency in there; try `rm -r ~/.m2/repository/lein-cljsbuild/cljs-compat`, and rerun lein |
| 10:10 | edbond | cemerick, yes, that helped. Thanks a lot! |
| 10:10 | edbond | (inc cemerick) |
| 10:10 | lazybot | ⇒ 15 |
| 10:11 | cemerick | edbond: thanks for the report, I'll make it so that won't happen again |
| 10:12 | edbond | now I can switch to 1.0.2 without SNAPSHOT. Nice. |
| 10:16 | noncom | is there a simple way to know if a string can be parsed into a, say double or integer, without try-catch or regexps? |
| 10:21 | fredyr | ,(doc re-matches) |
| 10:21 | clojurebot | "([re s]); Returns the match, if any, of string to pattern, using java.util.regex.Matcher.matches(). Uses re-groups to return the groups." |
| 10:21 | octane-- | stuartsierra: lovely, thank you. |
| 10:21 | fredyr | noncom: oh, misread |
| 10:22 | fredyr | noncom: so nvm me |
| 10:23 | fredyr | noncom: i think try-catch is the way |
| 10:23 | noncom | i better go with regexps then :) |
| 10:25 | fredyr | hah |
| 10:27 | john2x | what could cause clojure.walk to not be found? https://www.refheap.com/29863 |
| 10:28 | stuartsierra | john2x: If the namespace being loaded uses clojure.walk without requiring it. |
| 10:31 | john2x | indeed.. a bug in revise? strange, I tried the same version in another project a few days ago and didn't get the issue. |
| 10:31 | wei__ | anyone know a good method for specifying config variables through a file? kind of like leiningen's profiles.clj, but it has to work when running from an uberjar |
| 10:32 | Anderkent | wei__: edn? is the config file supposed to be *in* the uberjar or not? (depending on that, read it as a resource or filesystem url) |
| 10:32 | wei__ | Anderkent: good question. it's supposed to be outside the uberjar |
| 10:32 | wei__ | but in the same directory (on the classpath) |
| 10:33 | Anderkent | wei__: if you'd rather not have your config file be lisp syntax (picky users), you can use java.util.Properties. to parse a java properties file and then read that into a map |
| 10:33 | Anderkent | I'm not sure if the current directory is actually guaranteed to be on the classpath |
| 10:34 | wei__ | "slurp" seems to always check in the current directory |
| 10:34 | wei__ | i think java properties will work, thanks! |
| 10:34 | wei__ | (inc Anderkent) |
| 10:34 | lazybot | ⇒ 6 |
| 10:35 | Anderkent | wei__: check out https://github.com/michaelklishin/propertied |
| 10:36 | wei__ | perfect. it's clojurewerkz too, which i know writes good stuff |
| 10:40 | noncom | what would be the regexp to check if a string can be parsed into a double? |
| 10:41 | Anderkent | noncom: (try (Double. str) (catch NumberFormatException) |
| 10:42 | edbond | noncom, (if (re-find #"\." s) :double :integer) |
| 10:42 | Anderkent | edbond: "asdf.fdsa"? |
| 10:42 | fredyr | and ".5" and "1e-1000" |
| 10:42 | fredyr | etc |
| 10:43 | Anderkent | in short - why regex, who needs two problems? |
| 10:43 | edbond | it's quite complicated, consider localization (, . etc) |
| 10:43 | fredyr | it can easily get kinda hairy |
| 10:44 | edbond | ,(Double/parseDouble "1e-100") |
| 10:44 | clojurebot | 1.0E-100 |
| 10:44 | edbond | ,(Double/parseDouble "123") |
| 10:44 | clojurebot | 123.0 |
| 10:45 | Anderkent | if you don't want integers as doubles (but why not?!), you can do (try (Integer. str) (catch NumberFormatException (try (Double. str) (catch NumberFormatException (throw+ :nope |
| 10:51 | noncom | thanks! |
| 10:51 | lvh | hi |
| 10:52 | lvh | Im trying to use atoms and failing :( |
| 10:52 | lvh | https://gist.github.com/8711482 |
| 10:52 | lvh | interesting function starts at 13 |
| 10:52 | lvh | so I am returning an atom and a function closed over it from that function at line 13 |
| 10:52 | lvh | when I call the returned function with 2 args, itcomplains that I'm only calling it with 1 |
| 10:53 | lvh | fomp.core-test> ((second test-send) :a :b) -> ArityException Wrong number of args (1) passed to: ... |
| 10:53 | Anderkent | lvh: you're using swap wrong |
| 10:53 | Anderkent | lvh: it should be (swap! sent #(into % [recipients body])) |
| 10:53 | Anderkent | swap gives your function one argument - the current value of the atom |
| 10:53 | Anderkent | you don't need to reference the atom inside of your function |
| 10:55 | lvh | oh, okay; that actually makes more sense. Swap takes a function that maps the current value to the next one? |
| 10:57 | `cbp | If I use a var from another namespace and properly qualify it do I still have to require the namespace? |
| 10:57 | `cbp | It seems to work without requiring it |
| 10:57 | `cbp | most of the time.. |
| 10:58 | Anderkent | lvh: yeah |
| 10:58 | luxbock | hello, I want to create a function that takes a vector of ints, e.g. [3 2 2] and creates a sequence between [1 1 1] and the input vector based on the following rule: try to increment the leftmost number until it matches the one in the input vector |
| 10:58 | Anderkent | `cbp: yes you do. It will work if some other already laoded namespace required the one you refer to, but there's no reason to depend on that |
| 10:58 | luxbock | so with my example the first steps would go: [1 1 1] [2 1 1] [3 1 1], then reset back to 1 and increment the second leftmost number: [1 2 1], and now continue incrementing the leftmost number again until we hit a limit: [2 2 1] [3 2 1] [3 3 1] etc. until we reach the input vector [3 2 2] |
| 10:59 | luxbock | but I can't think of how to do this, any help? |
| 10:59 | Anderkent | luxbock: I'd try a recursive solution. First think of a function that will take the current vector and the 'max' values, and generate the next entry |
| 10:59 | Anderkent | then wrap that in a lazy-seq |
| 11:00 | Anderkent | ooor you can just use for |
| 11:01 | luxbock | how would for work for that? the order of the sequence matters |
| 11:01 | Anderkent | just reverse the order in for |
| 11:02 | llasram | I think `iterate` is the way to go |
| 11:02 | Anderkent | ,(for [z (range 1 3) y (range 1 3) x (range 1 4)] [x y z]) |
| 11:02 | clojurebot | ([1 1 1] [2 1 1] [3 1 1] [1 2 1] [2 2 1] ...) |
| 11:02 | Anderkent | that looks right to me? |
| 11:03 | luxbock | yeah that's right, but I would also like it to work for an input vector of any size |
| 11:03 | llasram | Actually, more state is nice -- an explicit lazy-seq is probably better |
| 11:04 | Anderkent | yeah, for arbitrary length vectors a lazy-seq would probably turn out nicer |
| 11:04 | TimMc | "more state is nice" |
| 11:04 | TimMc | ~guards |
| 11:04 | clojurebot | SEIZE HIM! |
| 11:04 | llasram | heh |
| 11:04 | luxbock | how does the call to lazy-seq look like if the fn that creates a new vector is called myinc ? |
| 11:04 | llasram | TimMc: I didn't say *mutable* state :-p |
| 11:04 | TimMc | Oh! OK. |
| 11:05 | TimMc | ~unguards |
| 11:05 | clojurebot | Titim gan éirí ort. |
| 11:05 | Anderkent | (def vector-seq [cur limit] (cons cur (lazy-seq (vector-seq (my-inc cur limit) limit)))) |
| 11:05 | Anderkent | then just a wrapper fn that gives [1 1 1] for cur |
| 11:05 | Anderkent | (or you know, arities) |
| 11:05 | luxbock | cool, thanks |
| 11:08 | noncom | yea, try catch seems more versatile for doubles parsing from strings |
| 11:12 | llasram | ,((fn [v] (->> v (map-indexed vector) (mapcat (fn [[i x]] (map #(-> [i %]) (range 2 (inc x))))) (reductions (fn [v [i x]] (assoc v i x)) (vec (repeat (count v) 1))))) [2 1 4]) |
| 11:12 | clojurebot | ([1 1 1] [2 1 1] [2 1 2] [2 1 3] [2 1 4]) |
| 11:13 | Anderkent | llasram: nah, it should reset to [1 1 2] after [2 1 1] |
| 11:13 | ambrosebs | ,(def foo (fn [] `bar#)) |
| 11:13 | clojurebot | #'sandbox/foo |
| 11:13 | llasram | Oh, I missed that |
| 11:13 | Anderkent | also, I find the lazy-seq version much easier to read / reason about |
| 11:14 | ambrosebs | ,(def foo (fn [] `bar#)) |
| 11:14 | clojurebot | #'sandbox/foo |
| 11:14 | ambrosebs | (foo) |
| 11:14 | ambrosebs | ,(foo) |
| 11:14 | clojurebot | bar__49__auto__ |
| 11:14 | ambrosebs | ,(foo) |
| 11:14 | clojurebot | bar__49__auto__ |
| 11:14 | Anderkent | ambrosebs: sounds like you want (gensym) |
| 11:14 | ambrosebs | Bronsa: does tools.reader have that behaviour with syntax quote? |
| 11:14 | Anderkent | nvm :) |
| 11:15 | ambrosebs | Anderkent: well I assumed they were interchangeable.. |
| 11:15 | Anderkent | hm, I think `# runs on read time |
| 11:16 | ambrosebs | Anderkent: yes. I assumed it expanded to (let [gsym (gensym bar)] `~bar) |
| 11:17 | ambrosebs | rather ##(let [gsym (gensym 'bar)] `~gsym) |
| 11:17 | lazybot | ⇒ bar11970 |
| 11:17 | jazzorn | (+ 1 2) |
| 11:17 | clojurebot | 3 |
| 11:17 | jazzorn | ;-) |
| 11:17 | Anderkent | of course you have to be careful about manually using gensyms |
| 11:18 | Anderkent | ,(let [goal (gensym "f1")] (loop [s (gensym "f")] (if (= s goal) [goal s] (recur (gensym "f"))))) |
| 11:18 | clojurebot | [f1123 f1123] |
| 11:18 | Bronsa | ambrosebs: yes |
| 11:18 | ambrosebs | Bronsa: do you know if it's by design? |
| 11:18 | Bronsa | the gensym is done at read-time, not run-time |
| 11:21 | ambrosebs | Bronsa: could the run-time behaviour be implemented? |
| 11:22 | ambrosebs | a reader macro can emit code as well, right? |
| 11:22 | Bronsa | it most definitely could, sure |
| 11:23 | ambrosebs | Bronsa: ok. |
| 11:24 | Bronsa | ambrosebs: you could implement it as a tagged literal if you need it |
| 11:24 | ambrosebs | Bronsa: I just want to fix syntax-quote for everyone. |
| 11:25 | Anderkent | I still don't see how it's broken |
| 11:25 | llasram | ambrosebs: Why do you want autogensyms to emit code instead of read-time gensyms? |
| 11:25 | Bronsa | ambrosebs: making run-time gensym the default behaviour of `a# would be problematic |
| 11:26 | ambrosebs | Bronsa: I haven't thought about it. Go on. |
| 11:28 | ambrosebs | llasram: I assumed that's how syntax-quote worked. |
| 11:28 | ambrosebs | llasram: haven't thought of an example which it makes a difference, but it still disturbs me. |
| 11:29 | llasram | ambrosebs: Interesting. I've definitely always thought of it as read-time behavior, and the thought of it generating new symbols on subsequent evaluation disturbs me :-) |
| 11:29 | ambrosebs | Bronsa: the biggest problem I can see is the implementation burden of bookkeeping the current gensyms for the same syntax-quote expression. |
| 11:29 | Bronsa | suppose you are doing `(let [a# 1] (some-macro a#)). with the current read-time behaviour you'd get (let [a__whatever 1] (some-macro a__whatever 1)) |
| 11:30 | Bronsa | with the run-time, you couldn't even bind the let |
| 11:31 | ambrosebs | Bronsa: I guess I mean macroexpand time then? |
| 11:32 | Bronsa | ambrosebs: that doesn't do it for special forms |
| 11:32 | ambrosebs | Bronsa: ok. |
| 11:32 | jph- | anyone know if i can get a request uri from within a (selmer) template? |
| 11:32 | Bronsa | (let [(macro) 1]) the call to macro won't get macroexpanded |
| 11:33 | Bronsa | ambrosebs: I'd guess there could be a way to make it work, just not as simple as just expanding to a run-time call to gensym |
| 11:33 | noncom | ,(= 100 100.0)4 |
| 11:33 | clojurebot | false |
| 11:34 | noncom | why is not 100 == 100.0 ? |
| 11:34 | llasram | noncom: It is |
| 11:34 | noncom | how do i check properly |
| 11:34 | llasram | ,(== 100 100.0) |
| 11:34 | clojurebot | true |
| 11:34 | noncom | oh |
| 11:34 | llasram | It just isn't the case that 100 = 100.0 :-) |
| 11:34 | noncom | )) |
| 11:35 | Anderkent | eh, isn't = supposed to be type-independent for colections and nums? |
| 11:35 | Anderkent | ,(doc =) |
| 11:35 | clojurebot | "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison." |
| 11:35 | Anderkent | i'd call that a bug |
| 11:35 | Anderkent | ,(= 100.0f 100.0d) |
| 11:35 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: Invalid number: 100.0f> |
| 11:35 | Anderkent | oups |
| 11:36 | llasram | (doc ==) |
| 11:36 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false" |
| 11:37 | Anderkent | I guess it's just a documentation error? |
| 11:38 | llasram | ,[(= (int 100) (long 100)) (.equals (int 100) (long 100))] |
| 11:38 | clojurebot | [true false] |
| 11:49 | BobSchack | is there a good technique or collection to get the neighbors of an element (the elements to the left and right of it)? |
| 11:50 | sdegutis | BobSchack: I can't figure out how that question would make sense. |
| 11:51 | bbloom | Bronsa: you mean you have a sequence and want to have a cursor in to that collection and move left or right? |
| 11:51 | sdegutis | Like, you're never *in* a collection. You always just have some data-path that you're using to access deep within a collection. In which case, sure, you can adjust that. |
| 11:51 | bbloom | BobSchack: whoops, that was for you, not Bronsa |
| 11:51 | BobSchack | bbloom: yes |
| 11:52 | Anderkent | Biohazard: something like |
| 11:52 | Anderkent | ,(let [f (fn [pre cur next] [pre cur next]) cl [1]] (map f (cons nil cl) cl (concat (next cl) [nil]))) |
| 11:52 | clojurebot | ([nil 1 nil]) |
| 11:52 | Anderkent | woups |
| 11:52 | Anderkent | wrong name |
| 11:52 | Anderkent | BobSchack: that's for you |
| 11:52 | gfredericks | Anderkent: it's just subtle; = is type-independent for numbers, but won't compare exact with inexact |
| 11:52 | bbloom | BobSchack: two man choices: 1) hold on to the pointer to the root of the collection and pair it with an index or path or whatever |
| 11:52 | BobSchack | I should get a new name :) |
| 11:52 | gfredericks | Anderkent: e.g., ##(= 3 3N) |
| 11:52 | lazybot | ⇒ true |
| 11:52 | Anderkent | gfredericks: yeah I looked inton Numbers/equal and saw the category() calls |
| 11:53 | bbloom | BobSchack: 2) alternatively, use something like a zipper (look it up, but not necessary the clojure.zip api) |
| 11:53 | gfredericks | Anderkent: it's perhaps similar to why #(= [1 2 3] (sorted-set 1 2 3)) |
| 11:53 | BobSchack | Yeah I'm looking at zippers right now |
| 11:53 | gfredericks | &(= [1 2 3] (sorted-set 1 2 3)) |
| 11:53 | lazybot | ⇒ false |
| 11:53 | Anderkent | hah. |
| 11:53 | BobSchack | bbloom is there a good zipper non clojure.zip zipper impl out there? |
| 11:54 | bbloom | BobSchack: not general purpose, but the reason i say to study zippers & not necessarily the API is b/c for a sequence, zippers are trivial |
| 11:54 | bbloom | for example if you have [1 2 3 4 5] and you have a "zipper" at 3, then you can define it simply as [(3 2 1) (4 5)] |
| 11:55 | bbloom | BobSchack: but generally just use an index: [[1 2 3 4 5] 2] ; would be at the three |
| 11:55 | bbloom | or better yet: {:vector [1 2 3 4 5] :index 2} ; this is all you need |
| 11:56 | BobSchack | Well I'm trying to implement the borderline sequence of Fortune's algorithm (http://blog.ivank.net/fortunes-algorithm-and-implementation.html) |
| 11:57 | drorbemet | Hi, can clojure.data.xml be used to roundtrip xml, or has it some unresolved issues? |
| 11:57 | drorbemet | It is based on stax parser that's nice. |
| 11:57 | drorbemet | But I am getting an error when trying to partition large xml file into chunks of smaller xml files |
| 11:57 | drorbemet | XMLStreamException Prefix cannot be null |
| 11:57 | drorbemet | com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeAttribute (:-1) |
| 11:58 | BobSchack | which calls for getting a point in a sequence and it's neighbors quite frequently |
| 11:59 | drorbemet | I am back in about 10min |
| 12:00 | Anderkent | BobSchack: sounds like you maybe want a different structure than a list? |
| 12:00 | bbloom | BobSchack: clojure's data structures don't get you out of the business of considering and creating your own data structures.... it simply delays that so far that often you don't have to do it :-) |
| 12:01 | bbloom | BobSchack: get the algorithm working (however slowly) with the dumbest thing that can work, then decide if you need to tune and whether or not that tuning requires custom data structures |
| 12:01 | BobSchack | bbloom: thats what I figured. I was hoping someone knew a clojure corner I didn't |
| 12:01 | BobSchack | I'll go do the naive impl first then go back later thanks everybody. |
| 12:04 | zoldar | is there a library similar to flatland/ordered but for clojurescript? I need a map that maintains insertion order |
| 12:05 | lvh | hi |
| 12:05 | lvh | to do autocomplete in emacs, should I get ac-cider-compliment or ac-nrepl |
| 12:07 | drorbemet | I am back in about 60min |
| 12:10 | sdegutis | devn: I'd love to see how we could use Julia types to represent token types in the lexer and parser. That might be really cool. |
| 12:11 | gfredericks | is compojure the most egregious violation of halloways "data-model > API > DSL" pyramid in the clojure-oss-world? |
| 12:14 | gfredericks | now I know why ratios auto-convert to bigints |
| 12:15 | gfredericks | ,(= 3 (clojure.lang.Ratio. (biginteger 3) (biginteger 1))) |
| 12:15 | clojurebot | false |
| 13:09 | sdegutis | Someone should name their next project Dragicorn. |
| 13:09 | sdegutis | That'd be pretty sweet. |
| 13:28 | aaronj1335 | hey folks, is there a way to drop into a clojure repl in the middle of a program? |
| 13:28 | aaronj1335 | kinda like `import pdb; pdb.set_trace()` if you're familiar w/ python... |
| 13:31 | bbloom | aaronj1335: there are a few things in that category around... |
| 13:31 | aaronj1335 | this seems like it might b the thing i'm thinking of: http://georgejahad.com/clojure/debug-repl.html |
| 13:36 | stompyj | #clojurecorner |
| 13:36 | stompyj | love it |
| 13:37 | aaronj1335 | stompyj yea? sounds like #clojure but in a leisure suit |
| 13:37 | aaronj1335 | (which sounds awesome) |
| 13:38 | stompyj | haha someone wrote clojure corner up in the chat earlier, and that sounds awesome. If I give a talk on clojure, I'm going to call it the #clojurecorner |
| 13:38 | srruby | How do I send commands via the Linux command line to a clojure repl or nrepl ? I want to do something like $ echo "(+ 1 1)" | ???? to pipe some commands to the repl process |
| 13:39 | technomancy | srruby: grenchman does that |
| 13:39 | technomancy | there might be a python thing too maybe? |
| 13:39 | SegFaultAX | srruby: Plus the nrepl protocol isn't that complicated. It's described on the github project page. |
| 13:40 | SegFaultAX | Yea, there is a Python impl of the nrepl protocol. |
| 13:40 | technomancy | ocaml's so much cooler than python though |
| 13:41 | SegFaultAX | technomancy: Lots of things are cooler than Python. |
| 13:41 | srruby | Thanks. |
| 13:43 | sdegutis | technomancy: I've heard great things about Haskell from many people but not OCaml. Have you done a comparison of them on your blog? |
| 13:44 | hyPiRion | sdegutis: no, but I'm sure bitemyapp would help you with that |
| 13:44 | hyPiRion | Oh, he's not here |
| 13:44 | sdegutis | callen's gone. |
| 13:44 | technomancy | sdegutis: probably the biggest difference is you can learn ocaml in a week no problem |
| 13:44 | llasram | sdegutis: Forever? |
| 13:44 | technomancy | it's really simple |
| 13:44 | stompyj | I have a buddy who's a huge haskell guy. We gently argue about who's made the right choice. :) |
| 13:45 | sdegutis | technomancy: Haskell isn't as simple? |
| 13:45 | technomancy | sdegutis: ocaml is more like clojure in that it has facilities for imperative programming when necessary |
| 13:46 | sdegutis | I see. |
| 13:46 | sdegutis | llasram: Probably. |
| 13:46 | SegFaultAX | sdegutis: Why? |
| 13:46 | SegFaultAX | I know Chris IRL but I haven't been around much since I've been on vacation. Did something happen? |
| 13:46 | sdegutis | SegFaultAX: No. He's fine. |
| 13:47 | sdegutis | He just moved on from Clojure. |
| 13:47 | stompyj | that sounds ominous :) |
| 13:47 | sdegutis | Sorry to phrase it poorly at first. |
| 13:47 | SegFaultAX | Oh, probably switching to Haskell full time. |
| 13:47 | sdegutis | He's in #haskell, you can ask him. |
| 13:48 | sdegutis | I'm writing a terrible admin section in Hiccup right now. No idea what I'm doing. |
| 13:48 | sdegutis | Kinda wish I could just write native apps. I'm sick of "web as a platform". It's so easy to mess something up catastrophically. |
| 13:48 | technomancy | sdegutis: it's actually a lot nicer than clojure at isolating side-effects since the type system will ensure they're all returning unit |
| 13:49 | sdegutis | technomancy: OCaml? |
| 13:49 | sdegutis | Sweet. |
| 13:49 | technomancy | haskell goes further by requiring side-effects run in a monad, but I find that OCaml's approach is a really pleasant middle ground |
| 13:50 | yazirian | the "web as a platform" is an elaborate plot to prevent programmers from taking over the world |
| 13:50 | technomancy | (inc yazirian) |
| 13:50 | lazybot | ⇒ 2 |
| 13:50 | yazirian | why else would it be so awful? |
| 13:50 | stompyj | don't say that on hacker nes |
| 13:50 | stompyj | news* |
| 13:50 | stompyj | or bye bye karma |
| 13:51 | yazirian | lucky for me i don't say anything there, and in fact dumped the RSS feed even just last week! |
| 13:51 | yazirian | i prefer more linear jerks |
| 13:51 | sdegutis | yazirian: we so could have done it by now if not for CSS/JS :'( |
| 13:51 | SegFaultAX | yazirian: LtU |
| 13:51 | yazirian | I think so! |
| 13:51 | sdegutis | stompyj: speaking of which |
| 13:51 | sdegutis | What IRC would look like in 2014: https://news.ycombinator.com/item?id=7147396 |
| 13:52 | sdegutis | the only difference being that there are no chanops |
| 13:52 | llasram | Is submitting links to hacker news to hacker news a new meme or something? |
| 13:52 | sdegutis | llasram: no, I just invented this idea just now. |
| 13:53 | stompyj | hahahahahahahahah |
| 13:53 | sdegutis | llasram: (well, 20 hours ago) |
| 13:53 | technomancy | sdegutis: check out the free book at http://realworldocaml.org if you want to dig in; I find it a great fit for small native distributables that clojure is bad at |
| 13:54 | sdegutis | well, not always small, according to your blog |
| 13:54 | technomancy | right, if size is a priority you have to choose your libs carefully |
| 13:54 | hyPiRion | yeah |
| 13:54 | hyPiRion | `-import core async` and then bam |
| 13:55 | technomancy | the author of the book told me they were working on improved tree-shaking for an upcoming version that would solve that |
| 13:55 | technomancy | sdegutis: nevar |
| 13:55 | yazirian | which reminds me again of the web as a platform and the horror of a cljs/pedestal/om 'hello world' app downloading over a megabyte of js to run |
| 13:55 | sdegutis | technomancy: it had a beginning, it must have an end |
| 13:55 | technomancy | sdegutis: I will take it with me to the grave |
| 13:55 | hyPiRion | sdegutis: so uh, you're betting on when technomancy will... die? =/ |
| 13:56 | hyPiRion | oh, he beat me to it too, argh |
| 13:56 | sdegutis | hyPiRion, technomancy: i doubt http://technomancy.us/ will even be a valid URL in 15 years |
| 13:56 | technomancy | sdegutis: what with the fall of the US? |
| 13:57 | technomancy | *impending fall |
| 13:57 | sdegutis | and im assuming by then we'll be using XAML or something instead of html/css/js |
| 13:57 | TimMc | LaTeX |
| 13:57 | stompyj | clojure is the first language I've worked in where I feel like i could use a tutor at times |
| 13:57 | TimMc | LaTeX everywhere |
| 13:58 | bbloom | sdegutis: latex scares you but xml-based object initialization syntax is A-OK? |
| 13:58 | ToxicFrog | LaTeX \o/ |
| 13:58 | sdegutis | anyway, in all seriousness, i think https://news.ycombinator.com/item?id=7147396 is actually a pretty good joke |
| 13:58 | bbloom | there are some brilliantly designed bits of WPF, but the decision to use XML for XAML was political & brain dead |
| 13:58 | yazirian | sdegutis: it'll be Dart, and the runtime will inject ads into your source |
| 13:59 | sdegutis | bbloom: im not that picky about syntax tbh |
| 13:59 | sdegutis | yazirian: of course, how else will chromium os make its money? |
| 13:59 | technomancy | Sergei gots to eat, son. |
| 13:59 | bbloom | sdegutis: xml's verbosity is only half the problem. the other half is that it has horribly broken semantics that clash with the desired semantics for UIs |
| 14:00 | sdegutis | oh? |
| 14:00 | sdegutis | bbloom: can you cite a paper demonstrating this please? |
| 14:00 | bbloom | sdegutis: no b/c i haven't written such a paper yet :-P |
| 14:00 | sdegutis | (i only read papers these days, it's the only way i can sleep at night now that i have a HN account) |
| 14:01 | stompyj | hey bbloom I missed the last clojure meetup where you gave your talk. is the video online? |
| 14:01 | bbloom | stompyj: http://www.hakkalabs.co/articles/clojure-software-dendrology |
| 14:01 | sdegutis | (that joke came out wrong, i meant it to be a joke about how HN is fine with random articles on the web, not a description of how i fall asleep) |
| 14:01 | stompyj | much appreciated! |
| 14:06 | sdegutis | ,[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]] |
| 14:06 | clojurebot | [[[[[[[[[[#]]]]]]]]]] |
| 14:07 | sdegutis | wat |
| 14:07 | hyPiRion | ,*print-depth* ;; I guess |
| 14:07 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *print-depth* in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:08 | hyPiRion | ah, *print-level* it is |
| 14:10 | sdegutis | ##[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]] |
| 14:10 | lazybot | ⇒ [[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]] |
| 14:11 | egghead | why does edn make a distinction between vector and list? |
| 14:11 | technomancy | egghead: because it's secretly clojure |
| 14:11 | sdegutis | ##(repeat 500 nil) |
| 14:11 | lazybot | ⇒ (nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ni... https://www.refheap.com/29927 |
| 14:11 | technomancy | don't tell anyone |
| 14:11 | sdegutis | neat. |
| 14:11 | sdegutis | ,(repeat 500 nil) |
| 14:11 | clojurebot | (nil nil nil nil nil ...) |
| 14:11 | sdegutis | okay, lazybot it is |
| 14:12 | egghead | technomancy: it seems like for edn that would make sense as a tagged literal |
| 14:13 | technomancy | egghead: I'm not entirely convinced EDN is anything but a sneaky way to get people to write datomic libs for other platforms |
| 14:13 | sdegutis | Clojure's destructuring is probably the number one feature I miss in other languages. Some of them get kinda close, but not nearly as convenient as Clojure. |
| 14:13 | sdegutis | (In other high-level languages, i.e. Ruby and Python) |
| 14:13 | egghead | sdegutis: sml? :p |
| 14:14 | egghead | OH |
| 14:14 | hyPiRion | OCaml's good at that. And Erlang, although it lacks both map and sets, which is super annoying. |
| 14:14 | technomancy | that's funny; destructuring just seems so limited compared to pattern matching |
| 14:14 | hyPiRion | oh, right. that's pattern matching, not destructuring. |
| 14:15 | sdegutis | technomancy: i.e. OCaml? |
| 14:15 | technomancy | sdegutis: or any FP language that isn't clojure, basically |
| 14:15 | sdegutis | Ah. |
| 14:15 | egghead | ya technomancy |
| 14:16 | sdegutis | I started using a pattern of functions that update the database returning [db val], and functions that update an entity taking [db val] as their first argument. |
| 14:16 | sdegutis | That way I can do chaining with ->, i.e. (-> (create-episode ...) (set-episode-title ...)) etc |
| 14:17 | sdegutis | Pretty handy for carts when writing tests: (-> (open-cart db user) (add-license-to-cart ep1) (receive-stripe-payment ...)) |
| 14:18 | sdegutis | That's where I'm loving destructuring the most right now. I can access either the db or the val in a let block in my tests without using an extra (first ret-val) line. |
| 14:18 | srruby | technomancy: Is there a 32 bit version of grenchman? I'm on Linux wheezy |
| 14:19 | CaptainLex | So I see there is no true literate programming engine for Clojure. Is this because a) true literate programming is overrated? b) true literate programming is not as useful for FPs? or c) language-agnostic FP tools are good enough? |
| 14:19 | llasram | Do they still make 32-bit computers? |
| 14:19 | technomancy | srruby: no, sorry; |
| 14:19 | sdegutis | CaptainLex: what does literate programming mean to you? |
| 14:19 | technomancy | all the precompiled stuff is 64-bit |
| 14:20 | CaptainLex | sdegutis: The kind of thing described by Knuth, with compile-time reordering of content, macro-substitution, &c &c |
| 14:20 | hyPiRion | CaptainLex: most likely it's because noone has bothered to make one yet. |
| 14:20 | sdegutis | CaptainLex: I haven't found a need for one. |
| 14:20 | CaptainLex | sdegutis: It's mostly useful when making a large codebase that many people will have to poke around in |
| 14:20 | sdegutis | Well-written Clojure reads like English to me. |
| 14:20 | hyPiRion | Whether that is the cause of a, b, c or some unknown x I'm unsure of. |
| 14:20 | CaptainLex | i.e. where documentation is the most important part of the software |
| 14:21 | dkinzer | llasram: I've seen plenty of 32-bit VMs |
| 14:21 | TimMc | CaptainLex: I don't see what FP has to do with it. |
| 14:21 | sdegutis | llasram: we bought a 32-bit PC from a local shop for like $100 last year |
| 14:21 | sdegutis | it has MS-DOS 6.22 on it |
| 14:22 | CaptainLex | Oops, C was supposed to read "language-agnostic LP tools" |
| 14:22 | sdegutis | my son's been trying to make games using QBasic on it |
| 14:22 | CaptainLex | TimMc: Well, maybe FPs are more readable. Not really, though :P |
| 14:22 | TimMc | ah |
| 14:22 | sdegutis | <3 |
| 14:22 | CaptainLex | I was just imagining responses from the peanut gallery, and I could see someone saying "Well, literate programming is mostly useful for spaghetti code" or some such a thing |
| 14:24 | devn | hmmm, anyone in here know anything about iota and reducers? |
| 14:25 | devn | I want to use iota in combination with clojure.data.csv. What's the best way to go about doing something like this? Perhaps extending the Read-CSV-From protocol to iota.FileVector? |
| 14:25 | technomancy | CaptainLex: I would suspect it might be because people value a literal and clear mapping of files on disk to namespaces. |
| 14:25 | devn | Is this a foolish thing to do in any case? |
| 14:25 | technomancy | people are rightly suspicious of anything that gets in between them and the compiler |
| 14:26 | devn | clojure.data.csv just doesn't work for the size of files I'm dealing with |
| 14:26 | CaptainLex | technomancy: Makes sense. I haven't written any LP stuff, but it sounds interesting! |
| 14:27 | drorbemet | XMLStreamException Prefix cannot be null |
| 14:27 | drorbemet | I think I found the cause of the error |
| 14:27 | drorbemet | I don't declare namespaces in the new xml file in which I copy the xml chunks |
| 14:27 | drorbemet | I read about a repairing mode in |
| 14:27 | drorbemet | http://jira.codehaus.org/browse/WSTX-170 |
| 14:27 | drorbemet | can I use repairing mode with clojure.data.xml/emit? |
| 14:28 | tmciver | If anyone is interested in a Clojure job in Framingham, Massachusetts, feel free to PM me. |
| 14:28 | CaptainLex | tmciver: Were that it were five months from now! |
| 14:29 | llasram | devn: Are you sure that's the problem? data.csv should be producing a lazy sequence of the rows in your CSV input file |
| 14:29 | llasram | devn: Are individual rows too large to fit into memory? |
| 14:29 | shep-werk | tmciver: got anything in Pittsburgh? ;-) |
| 14:29 | tmciver | shep-werk: sorry, no. :( |
| 14:29 | shep-werk | tmciver: time to open a remote office |
| 14:30 | tmciver | Hey, man! |
| 14:30 | tmciver | o/ |
| 14:30 | TimMc | \o |
| 14:30 | tmciver | Missed you at the last Boston Clojure meet up. |
| 14:30 | TimMc | Oh! Yeah, things have been busy. |
| 14:31 | TimMc | I have too many projects and too much ADHD. |
| 14:31 | tmciver | Tell me about it. |
| 14:31 | tmciver | Going to the next meet up? |
| 14:32 | tmciver | TimMc: ^ |
| 14:33 | TimMc | I hope so. |
| 14:34 | TimMc | I've been getting into electronics, so reading up on circuits has been occupying me some nights. |
| 14:35 | tmciver | Cool. Yeah, I have an Arduino project in my basement collecting dust. |
| 14:35 | technomancy | TimMc: what kind of projects? |
| 14:37 | devn | llasram: hmmm, maybe I was mistaken? I think I know the issue. walk/keywordize-keys across my data. |
| 14:38 | llasram | Yeah -- that's probably forcing full realization in memory |
| 14:40 | tjd | philosophical question: (map some-f some-seq), if some-f throws an exception, what ought happen? swallow it and map to nil? raise the exception? |
| 14:43 | technomancy | exception hiding is pretty evil |
| 14:43 | shep-werk | tjd: mu |
| 14:44 | hyPiRion | tjd: Whenever the value is calculated, the exception is thrown. |
| 14:45 | hyPiRion | so for example ##(do (map #(< 10 %) (concat (range 1 100) [nil])) nil) will not throw |
| 14:45 | lazybot | ⇒ nil |
| 14:45 | hyPiRion | but ##(map #(< 10 %) (concat (range 1 100) [nil])) will. |
| 14:45 | lazybot | java.lang.NullPointerException |
| 14:45 | sdegutis | technomancy: evil is such a strong word. how about "malutile"? |
| 14:45 | hyPiRion | (because it attempts to print the value) |
| 14:45 | technomancy | sdegutis: maybe "reprehensible" |
| 14:45 | sdegutis | actually im gonna coin malutile. |
| 14:46 | technomancy | more power to you |
| 14:46 | sdegutis | technomancy: that phrase is so malutile |
| 14:46 | devn | llasram: is there anything decent that i can do with iota to deal with that? basically I want to create a map out of every row, by zipmapping the headers across all of the rows, and keywordizing the keys on those maps |
| 14:46 | mmitchell | stuartsierra: I've been playing around with your component lib/idea. Question... for web apps, how are you getting the "system" into your handlers? Or are the handlers reaching out the the "system" var? |
| 14:47 | llasram | devn: I don't know iota, but that isn't anything you shouldn't be able to do with lazy seqs. The headers are just the first row, right? |
| 14:51 | stuartsierra | mmitchell: construct the handlers when you start your app |
| 14:51 | stuartsierra | Compojure makes this awkward but still doable. |
| 14:52 | devn | llasram: yeah, im trying it out, doesn't seem to make much of a difference with reducers and iota |
| 14:53 | mmitchell | stuartsierra: Right, so (GET _ #(my/handler system %)) etc.? |
| 14:53 | devn | i find it a bit annoying clojure.data.csv keeps read-cell and so on private fns |
| 14:53 | TimMc | technomancy: I want to build a Joule Thief or five, and then start playing with high-power LEDs. |
| 14:54 | llasram | devn: So data.csv returns a lazy seq of the rows, right? So you get (let [rows ...] ...) at some point. Then you just: (let [headers (map keyword (first rows)), data-rows (map (partial zipmap headers) (rest rows))] ...) |
| 14:55 | llasram | Then data-rows is a lazy sequence of your keyworded maps |
| 14:55 | technomancy | TimMc: cool |
| 14:55 | stuartsierra | mmitchell: no, don't use defroutes at all. Do something like (defn make-app [… service components …] (routes …)) and call it from your app component's start method. |
| 14:55 | stuartsierra | The handler functions are no longer top-level defns. |
| 14:55 | llasram | devn: Any processing you do on that sequence, including reducers, you just need to make sure you don't realize the whole thing into memory at once |
| 14:55 | TimMc | technomancy: I'd really like to make my own LED grow light, but to get to the point of making the necessary constant-current mechanisms I need for learnin'. |
| 14:55 | TimMc | s/for/more/ |
| 14:56 | mmitchell | stuartsierra: Ahh I see. Is there any example of this (a ring web app) somewhere? |
| 14:56 | stuartsierra | mmitchell: no |
| 14:57 | stuartsierra | But it's not hard. |
| 14:57 | mmitchell | OK, I'll give it a try |
| 15:08 | dobry-den | i have a user-upload avatar system that saves avatars to "/public/avatars/custom/{{user-id}}.{{gif/png/jpg}}". even though i cache the path, i'm having trouble figuring out performance without the cache. |
| 15:08 | dobry-den | is it faster to try 42.gif, 42.png, 42.jpg and pick the one it finds. or is it faster to search the file-seq for a match on 42.png/gif/jpg? |
| 15:09 | Raynes | gf3: You live outside the snapchats! |
| 15:09 | gf3 | Raynes: YOU HUSH |
| 15:09 | gf3 | SHOOSH YOUR MOUTH, Raynes |
| 15:11 | mdrogalis | Man, the last time you guys were talking about Snapchatting, there was a helicopter incident involved. |
| 15:14 | AeroNotix | how likely is it that Clojure would get fully preempted user space threads? |
| 15:16 | sobel | like Java's? |
| 15:16 | mdrogalis | AeroNotix: What does that mean? |
| 15:17 | lvh | I'm having some problems with clj-postal; it's reporting success with or without metadata (so SMTP server info) and in no case is any mail actually getting sent. |
| 15:17 | sdegutis | lul i trull u |
| 15:17 | sobel | given the clojure concurrency model, i am not really seeing why or how it makes sense to use a preemptive process model in clojure |
| 15:18 | AeroNotix | sobel: like Go's |
| 15:18 | AeroNotix | sobel: Java doesn't have user space threads anymore |
| 15:18 | AeroNotix | afaikt |
| 15:18 | llasram | AeroNotix: You mean like core.async then? |
| 15:18 | AeroNotix | llasram: no, that's cooperatively scheduled. |
| 15:19 | llasram | In what sense? |
| 15:19 | sshack | So what libraries are people using to do graphs in their web apps? |
| 15:19 | AeroNotix | llasram: you know what preemptive scheduling is, right? |
| 15:19 | sobel | sshack: http://d3js.org/ |
| 15:19 | AeroNotix | If I make a go block which literally blocks, it blocks that thread completely. |
| 15:20 | ToxicFrog | llasram: basically he wants preemptive greenthreads rather than preemptive kernel threads or coroutines. |
| 15:20 | AeroNotix | ToxicFrog: exactly |
| 15:20 | sshack | sobel: Ahh, so you're just emitting json and letting the fronted take care of it? |
| 15:20 | ToxicFrog | AeroNotix: what does that get you over just using kernel threads? |
| 15:20 | sobel | sshack: bingo |
| 15:20 | AeroNotix | ToxicFrog: a lot |
| 15:20 | AeroNotix | ToxicFrog: kernel threads are not cheap, for one. |
| 15:20 | ToxicFrog | AeroNotix: I've never used greenthreads before, so I don't know the implications |
| 15:21 | sobel | they're cooperatively scheduled |
| 15:21 | AeroNotix | e.g. in Go/Erlang a green thread is very, very small. |
| 15:21 | AeroNotix | sobel: we've been saying this |
| 15:21 | AeroNotix | but the preemptive scheduling is what does it |
| 15:21 | AeroNotix | does it for me * |
| 15:22 | AeroNotix | since it means you have no real rules about what a thread can do |
| 15:22 | sobel | are they green threads or process threads? |
| 15:22 | sobel | one is preemptive and one depends on the language vm |
| 15:22 | lvh | can someone please explain what the difference is in this example between send-message2 and send-message3? (this is a clj syntax question) https://github.com/drewr/postal/issues/22#issuecomment-5220583 |
| 15:22 | AeroNotix | sobel: right, I'm asking how likely is it that clojure could have this |
| 15:22 | AeroNotix | sobel: these things are baked into languages, so they're not trivial things to implement overnight. |
| 15:22 | llasram | AeroNotix: It's not clear to me that go employs any sort of preemptible user-level threads. Reference? |
| 15:23 | sobel | unless you are speaking strictly from the VM perspective, then i guess you can call green threads preemptive with the VM as the preemptor but i don't get the use case for making that distinction |
| 15:23 | AeroNotix | llasram: They're coming |
| 15:23 | ToxicFrog | sobel: java (and thus clojure) already supports process/kernel threads. The question is about support for green threads with preemptive scheduling, which it doesn't currently have. Java used to, but it was dropped from the JVM in 1.2, IIRC. |
| 15:23 | llasram | AeroNotix: Reference? |
| 15:23 | sobel | AeroNotix: i more than get the 'baking in' aspect. |
| 15:23 | AeroNotix | llasram: second |
| 15:23 | ToxicFrog | sobel: the distinction is that you can treat them like preemptive threads and not have to worry about whether the preemption is handled by the kernel or the VM. |
| 15:23 | stuartsierra | AeroNotix: Not exactly what you're asking, but some of the latest Fork/Join thread pools can detect blocked threads and expand the thread pool. That combined with core.async can prevent a real blocking action in a `go` block from blocking other work. |
| 15:23 | AeroNotix | llasram: https://code.google.com/p/go/issues/detail?id=543 |
| 15:24 | AeroNotix | llasram: not perfect preemption, but a start. |
| 15:24 | ToxicFrog | sobel: whereas with coroutines scheduling is handled by the coroutines themselves |
| 15:24 | AeroNotix | stuartsierra: gah what's the point of a pool (limited, bounded etc) when you just grow it? |
| 15:25 | stuartsierra | AeroNotix: I assume there are still limits, it's just slightly more flexible than a fixed-size pool. |
| 15:25 | AeroNotix | Go has a similar tactic for IO fwiw |
| 15:25 | AeroNotix | when a goroutine blocks on IO, another kernel thread starts. AFAICR |
| 15:26 | AeroNotix | stuartsierra: the point is, core.async isn't exactly perfect |
| 15:27 | stuartsierra | nobody said it was |
| 15:27 | AeroNotix | stuartsierra: I know :) |
| 15:27 | bbloom | it's kinda amusing to me to watch language VMs reinvent OS stuff, even when the VM designers are OS people :-) |
| 15:27 | hyPiRion | AeroNotix: I would guess that's a limitation with the JVM. (Disclaimer: I know how hard it is to predict when IO will block the thread) |
| 15:27 | sdegutis | Some days, I want to just quit programming for 20 years and come back when everything's not so insane. |
| 15:28 | AeroNotix | hyPiRion: therein is kind of my question, really. How hard does the JVM make preemption of user-space threads? |
| 15:28 | bbloom | sdegutis: add a zero |
| 15:28 | AeroNotix | bbloom: what's the alternative? |
| 15:28 | AeroNotix | bbloom: we all just use threads? |
| 15:28 | sdegutis | bbloom: 020 years? I don't know octal. |
| 15:28 | bbloom | sdegutis: :-P |
| 15:28 | llasram | AeroNotix: Reading that issue, I believe that you have somewhat mistaken ideas about what Go is changing, and what is possible. What mechanism do you see allowing for user-level threads engaged in blocking kernel operations to be preempted? |
| 15:28 | sdegutis | Oh, 020 = 16. |
| 15:29 | stompyj | (inc bbloom) |
| 15:29 | lazybot | ⇒ 26 |
| 15:29 | sdegutis | Right, that makes sense. Only 8 digits, so 8 * 2 |
| 15:29 | AeroNotix | llasram: it's just a better tactic for preempting goroutines |
| 15:29 | AeroNotix | before they were preempted just on chan blocks |
| 15:29 | sdegutis | lulul i truuul u |
| 15:31 | llasram | AeroNotix: That's my reading as well. Which is where I'm confused as to where you're getting this user-level preemptive threading thing from. If code makes a system call which blocks the kenel thread, then there's nothing you can do to preempt it |
| 15:31 | AeroNotix | llasram: it's better than just requiring everything use channels everywhere |
| 15:31 | sobel | sdegutis: it will be insane in 20 years, too. |
| 15:31 | AeroNotix | sobel: probably moreso |
| 15:32 | sobel | if the past 20 are any sort of a blunt hint |
| 15:32 | ToxicFrog | llasram: typically this is done at the VM level - the VM knows when you're making a blocking call and replaces with an asynchronous call and reschedule under the hood |
| 15:33 | sobel | my time-travel fantasy is pretty much limited to delivering a MacBook Retina to my 12 year old self |
| 15:33 | ToxicFrog | Or it just doesn't make synchronous IO available at all, or does so with a "this will break greenthreads" caveat |
| 15:33 | sobel | loaded with software, patents, stock charts, MLB scores... |
| 15:33 | sdegutis | sobel, AeroNotix: I'm not so sure of that. Professional OSes are moving towards really good architectures, the only thing holding them back is backwards compatibility, which isn't that hard a problem to solve when you have virtualization. |
| 15:34 | AeroNotix | sdegutis: which are the professional OSes/ |
| 15:34 | AeroNotix | ? |
| 15:34 | sobel | with WinXP as my example, i disagree that virtualization the problem of backward compatibility holding OSes back |
| 15:34 | sdegutis | AeroNotix: Windows 8, Mac OS X, etc |
| 15:34 | sobel | solves |
| 15:34 | technomancy | lol |
| 15:34 | AeroNotix | sdegutis: how do you know anything about their architectures? |
| 15:35 | sdegutis | Also Ubuntu. |
| 15:35 | sdegutis | AeroNotix: I dunno. Programming? |
| 15:35 | AeroNotix | sdegutis: but it's not kernel level hacking though is it |
| 15:35 | sdegutis | not usually, no |
| 15:36 | sdegutis | so? |
| 15:36 | AeroNotix | So how do you know what their architecture is like? |
| 15:36 | sdegutis | AeroNotix: I dunno. Programming? |
| 15:36 | AeroNotix | sdegutis: you keep saying that |
| 15:36 | sdegutis | No, you keep saying that. |
| 15:36 | Notte | troll... |
| 15:36 | llasram | AeroNotix: Friendly reminder: IRC is not a contest |
| 15:36 | AeroNotix | llasram: I know this |
| 15:37 | sdegutis | AeroNotix: I don't care about the kernel, I wasn't talking about the kernel. |
| 15:37 | sdegutis | AeroNotix: I was talking about userland libraries and available tools. |
| 15:37 | AeroNotix | sdegutis: you mentioned architecture, usually this is used with kernels. Never mind then friend. |
| 15:37 | sdegutis | AeroNotix: Also I really liked the paper I read on MS's Singularity. |
| 15:37 | dobry-den | I'm running a Compojure app behind Nginx with proxy_pass. How do you prevent the runaway spiral of users f5'ing when load is high? |
| 15:38 | sshack | sobel: So, coming from Mathematica, D3 is an utter nightmare. two pages of code to do a bilevel partition pie chart that takes one in Mathematica. |
| 15:38 | AeroNotix | dobry-den: have you had this problem already? |
| 15:39 | bbloom | sdegutis: for all the things i hate about browsers, they do provide an opportunity to escape the backwards compat nightmare when coupled with virtualization |
| 15:40 | bbloom | sdegutis: at least at the user application level |
| 15:40 | sdegutis | AeroNotix: When I made my comment, I was mostly thinking of LightTable. While I kinda like the app in itself, I think it's insane that HTML/CSS/JS is the best we can do for cross-platform GUI programming right now. |
| 15:40 | dobry-den | AeroNotix: yeah. and so far my comical solution is to `sudo service nginx stop` until server catches up |
| 15:40 | AeroNotix | sdegutis: there's Qt, I've had great success with that |
| 15:40 | sshack | dobry-den: Does nginx have rate limiting? |
| 15:41 | AeroNotix | dobry-den: so what's your load? Req/s? |
| 15:41 | sdegutis | AeroNotix: True, I did have a hello-world in Qt that I haven't seriously investigated yet. |
| 15:41 | sshack | A hack, yes, but sometimes simple solutions are the best. |
| 15:41 | sdegutis | Although they dropped Qt-Jambi, which means Clojure integration won't be so pleasant. |
| 15:41 | AeroNotix | sdegutis: I used pyqt mostly, very nice. Moved some stuff to C++ from Python if you can believe it. |
| 15:41 | sdegutis | bbloom: They're their own backwards compatibility nightmare in terms of browser support. |
| 15:42 | dobry-den | AeroNotix: nginx reports 50 req/sec. |
| 15:42 | AeroNotix | dobry-den: and it dies on 50/s/????? |
| 15:42 | AeroNotix | can anyone confirm that this is all Compojure can do? |
| 15:42 | dobry-den | yeah, there's a bottleneck i'm working on |
| 15:43 | sdegutis | llasram: yes it is and i win |
| 15:43 | sshack | dobry-den: Is it io constrained on a DB or something? |
| 15:43 | dobry-den | AeroNotix: it's a dynamic website. doesnt really have much to do with compojure |
| 15:43 | sdegutis | I also think we could do a lot better with IPC. I was impressed by Singularity's solution for a simpler and faster IPC model. |
| 15:44 | AeroNotix | dobry-den: but like.. 50/s, that's pretty poor. |
| 15:44 | sdegutis | It might make it a little more feasible to have Clojure running in the background and a C app just communicate with it over nREPL or something, for use with scripting. |
| 15:44 | dobry-den | sshack: i've found the bottleneck, i just dont want the server to get stuck in a cpu-load spiral every time |
| 15:44 | dobry-den | AeroNotix: yeah, well, the idea is to optimize as i go |
| 15:44 | AeroNotix | hmm ok |
| 15:45 | dobry-den | the bottleneck is actually the use of a swap! on the homepage |
| 15:46 | AeroNotix | dobry-den: huh, what for? |
| 15:47 | sdegutis | bbl |
| 15:47 | dobry-den | AeroNotix: my introspection skills are pretty poor, but it seems that my naive use of noir.util.cache will make everyone halt on the homepage when any of the cache! are invalidated |
| 15:48 | dobry-den | i've been replacing it with a simpler atom where a cache recomputed in another thread (scheduled) |
| 15:48 | AeroNotix | dobry-den: what are you caching? |
| 15:49 | dobry-den | AeroNotix: it's a forum homepage. so the latest-post of each forum, forum stats, total-posts in each subforum. |
| 15:49 | AeroNotix | dobry-den: ever heard of memcached? |
| 15:49 | AeroNotix | or redis |
| 15:49 | dobry-den | well, that's unnecessarily complexity that doesn't address this particular problem |
| 15:50 | AeroNotix | Oh I assure you it will |
| 15:50 | dobry-den | i believe the problem is that the recalculation function is inside the swap! that the user has to wait on |
| 15:51 | dobry-den | i've fixed it by scheduling the swap myself and letting all users simply deref it, which is how it should be for such trivial cache |
| 15:52 | AeroNotix | dobry-den: what's the calculation? |
| 15:53 | dobry-den | it makes a db call and there seems to be some sort of blocking contention when multiple people land on an invalidated homepage |
| 15:54 | AeroNotix | dobry-den: depending on the application you can forgo atomic changes, if the later calculations don't depend on the previous ones... |
| 15:54 | AeroNotix | e.g. "latest forum post" |
| 15:54 | stompyj | Is it terrible practice to have a configuration namespace where you declare vars that other namespaces may need? |
| 15:54 | AeroNotix | you'd just use memcache and overwrite a key |
| 15:54 | stompyj | (trying to get myself out of circular dependency hell) |
| 15:54 | AeroNotix | and cache the ARSE out of that |
| 15:55 | AeroNotix | because you only need to invalidate the cache when new posts are created, I'd have middleware on the routes which create posts to invalidate caches. |
| 15:55 | AeroNotix | because if you're using TTL, it's just stupid |
| 15:55 | hiredman | yes |
| 15:56 | hiredman | stratify your code |
| 15:56 | dobry-den | AeroNotix: right, i invalidate the cache on new posts. but it seems better to swap the new latest-post myself instead of make users trigger it |
| 15:56 | dsrx | move your code into the highest strata - rewrite it in Haskell |
| 15:56 | dobry-den | but i dont see how it matters if i use memcached, redis, or an atom. |
| 15:57 | AeroNotix | dobry-den: then test it |
| 15:57 | AeroNotix | dobry-den: I don't see anywhere where you mentioned testing |
| 15:57 | dobry-den | well, i didnt even mean to talk about the issue because it actually turns out i dont need to cache it (the cache introduced a block). i was just asking about nginx |
| 15:59 | sdegutis | gfredericks: you guys ever file that speclj bug? |
| 16:00 | dobry-den | AeroNotix: funnily enough, the only reason i hastily cached it (incorrectly) was because i was hastily trying to resolve a load issue that was actually caused by -- wait for it --- running lein-ring in dev mode |
| 16:00 | AeroNotix | ah |
| 16:00 | dobry-den | which i dont recommend |
| 16:01 | AeroNotix | i didnt even know dev mode was a thing |
| 16:02 | arohner | is there a library/trick for generating ring session cookies, for use w/ clj-http cookie-store? |
| 16:03 | arohner | I would like to directly add cookies to clj-http, that look like they've been signed by ring |
| 16:04 | hiredman | isn't the whole point of signing cookies to avoid that? |
| 16:07 | akurilin | For my integration tests I just have a couple of hardcoded cookies lying around |
| 16:08 | AeroNotix | same |
| 16:08 | akurilin | I think there might be an issue with generating cookies procedurally on machines that don't get a lot of entropy |
| 16:08 | akurilin | my dev boxes can get stuck waiting for entropy for something like 10s |
| 16:09 | stuartsierra | akurilin: This can be a problem in virtualization containers. |
| 16:10 | akurilin | stuartsierra: what's an example? |
| 16:10 | stuartsierra | akurilin: dunno, just heard that as conventional wisdom |
| 16:11 | akurilin | I remember filing a bug against ring about those stalls back in the day and weavejester pointed out it was nothing he could do on his end. |
| 16:11 | akurilin | I still need to come up with a way of bypassing this issue in my integration test suite :( |
| 16:11 | akurilin | stuartsierra: fair enough |
| 16:14 | akurilin | So, mixing dosync and clojure jdbc transactions can be potentially a bad idea, huh? |
| 16:14 | stuartsierra | akurilin: Yes. JDBC is a side effect. Don't put side effects in dosync transactions. |
| 16:15 | akurilin | I have a shared map in memory that I want to run some checks against and then runthe transaction (which can also fail) |
| 16:15 | akurilin | meaning that ideally I could roll back both |
| 16:15 | shep-werk | akurilin: if you can guarantee that that machine is only used for tests, you could probably set a kernel option to use a PRNG instead of a crypto-hard one |
| 16:15 | shep-werk | which might be easier in a virtualized env |
| 16:16 | akurilin | shep-werk: this is pretty much exclusively on my dev machine which is on bare metal, I think the issue is that I might not have enough network traffic to it to generate enough entropy |
| 16:16 | arohner | hiredman: this is for integration tests. I want to set up the ring session in a certain state, and then bang on the server |
| 16:16 | akurilin | shep-werk: but yeah that's a good idea, I'll try that perhaps |
| 16:17 | arohner | hiredman: looks like it's not too hard to reach into the ring middleware, I was just checking if there was a lib to do this already, because I remember a few ring / clj-http testing libs |
| 16:18 | akurilin | Regarding the dosync / jdbc transaction issue: it seems that the least error prone way would be to start a JDBC transaction, do all the DB operations without committing, then run the dosync and use the result of it to decide whether to rollback JDBC or not. |
| 16:18 | akurilin | Which sounds incredibly convoluted, but probably isn't. |
| 16:20 | stuartsierra | akurilin: yes that should work |
| 16:21 | shep-werk | akurilin: if it's your dev machine i'd be surprised - I'd expect keyboard / mouse input to also go into entropy pool |
| 16:21 | shep-werk | unless you enter code by force of will ;-) |
| 16:24 | akurilin | stuartsierra: thanks for confirming, apprecaited. |
| 16:24 | akurilin | *appreciated |
| 16:25 | akurilin | shep-werk: yeah I really need to find time to drill deeper into what exaly is stalling in the process, have yet ot figure out how to "break" in clojure |
| 16:25 | akurilin | to see what's waiting |
| 16:26 | shep-werk | akurilin: just do a JVM thread dump :-) |
| 16:27 | akurilin | shep-werk: any particular tools you'd recommend? |
| 16:28 | shep-werk | TBH, I haven't done much specific to Clojure, but I'd start with just sending a SIGQUIT to the JVM when it's slow and browse the result |
| 16:29 | shep-werk | or use something like (J)VisualVM and attach to it |
| 16:30 | gfredericks | sdegutis: not that I know of |
| 16:30 | sdegutis | my coworker writes it, so i may be able to help get the ticket some attention |
| 16:32 | gfredericks | sdegutis: okay, I'll probably pull one together |
| 16:33 | gfredericks | sdegutis: it would basically involve reverting an earlier accepted PR |
| 16:33 | sdegutis | gfredericks: make sure to put in the explanation for what bug it caused |
| 16:33 | sdegutis | he's understanding, but very skeptical and untrusting of anyone but himself. |
| 16:34 | sdegutis | (he said this himself; i am not slandering) |
| 16:34 | sdegutis | in other words, be sure to give a good argument that it really did cause the bug you saw |
| 16:34 | gfredericks | oh I wonder if that approach means running with an old version of clojure? |
| 16:38 | gfredericks | indeed it does |
| 16:38 | gfredericks | how does that not damn it all by itself? |
| 16:41 | gfredericks | oh technomancy commented on the original PR |
| 16:49 | technomancy | "technomancy will yell at you unless you revert this commit" <- good argument? |
| 16:49 | ddima_ | depends on how badly you can yell |
| 16:49 | sdegutis | technomancy: doubtful, unless you also wag your finger |
| 16:49 | sdegutis | in which case maybe |
| 16:49 | gfredericks | sdegutis: https://github.com/slagyr/speclj/issues/7 |
| 16:49 | gfredericks | E |
| 16:49 | gfredericks | um |
| 16:49 | gfredericks | https://github.com/slagyr/speclj/issues/78 |
| 16:50 | gfredericks | is what I failed to paste somehow |
| 16:50 | sdegutis | Thanks. |
| 16:50 | technomancy | sdegutis: I can do M-x look-of-disapproval if that helps |
| 16:51 | sdegutis | gfredericks: most excellent, theophilus. thank you. |
| 16:51 | AeroNotix | technomancy: so lame, I have that on C-x M-l d |
| 16:51 | brehaut | hiredman: what was the aphyr video you were talking about yesterday? |
| 16:51 | technomancy | AeroNotix: hehe |
| 16:51 | sdegutis | AeroNotix: why not just have it auto-run inside init.el and save time |
| 16:52 | AeroNotix | SERIOUSLY though (= (+ :clj-refactor :cider-mode) :omfg-amazing) |
| 16:52 | AeroNotix | sdegutis: one needs to do it on demand |
| 16:52 | sdegutis | AeroNotix: i'd try it but my setup is pitifully fragile |
| 16:53 | AeroNotix | sdegutis: Why? |
| 16:53 | AeroNotix | I *do* spend a lot of time on my .emacs stuff |
| 16:53 | AeroNotix | https://github.com/AeroNotix/dotfiles/blob/master/.emacs |
| 16:54 | sdegutis | AeroNotix: why is mine fragile? |
| 16:54 | technomancy | if it were scheme I'd recommend switching all your parens to [] |
| 16:54 | technomancy | more structurally stable |
| 16:56 | sdegutis | AeroNotix: last time i tried to upgrade a dep from melpa, it broke and was a pain to revert. this is cuz melpa builds off master, which is a bad idea. so i stopped using melpa and froze my dependency graph in fear of breaking anything else. |
| 16:56 | AeroNotix | sdegutis: yes |
| 16:56 | AeroNotix | sdegutis: put your .emacs/.emacs.d into a repo |
| 16:56 | AeroNotix | I regularly just rm -r elpa/* stuff just to see what breaks |
| 16:56 | sdegutis | AeroNotix: also, any time i touch my init.el i get sucked in for hours. constantly changing, reverting changes, trying new things, etc. its a black hole of experimentation. |
| 16:56 | AeroNotix | sdegutis: Yes, this is emacs. |
| 16:57 | sdegutis | its in a repo already. |
| 16:57 | sdegutis | but i took it off github cuz no one wants to see that stuff. its like underwear. |
| 16:57 | AeroNotix | sdegutis: nah, the guys at work usually steal stuff from mine, and I theirs. |
| 16:58 | technomancy | sdegutis: melpa is fragile by design |
| 16:58 | sdegutis | AeroNotix: i have no "the guys at work". nobody knows about my github repos. im the only employee in this company, i work from home, sole developer on this project. |
| 16:58 | sdegutis | technomancy: yes. |
| 16:58 | technomancy | do not want |
| 16:58 | sdegutis | the only dependency manager ive seen done well is whatever leiningen uses. |
| 16:59 | AeroNotix | technomancy: it's better than what it was |
| 16:59 | technomancy | sdegutis: aether still screws up version ranges pretty badly |
| 16:59 | technomancy | but that's relatively easy to avoid |
| 16:59 | technomancy | well... it took a couple years, but we mostly squashed the issues |
| 16:59 | sdegutis | ive had a lot of trouble with pip and bundler. havent used npm so cant say much there. |
| 17:00 | sdegutis | and i refuse to use cocoapods on principle (its not ruby dangit, its objc!) |
| 17:00 | AeroNotix | one must say that I'm postively happy about lein. It Just Works. |
| 17:00 | AeroNotix | end of story. |
| 17:00 | sdegutis | only one i havent had trouble with is whatever leiningen uses (nobody knows what its called) |
| 17:00 | AeroNotix | Coming from Erlang/Rebar+Python/PIP it's a whole new world. |
| 17:00 | jacortinas | sdegutis: Maven? |
| 17:01 | sdegutis | no, clojars |
| 17:01 | sdegutis | or whatever |
| 17:01 | zerokarmaleft | npm got a lot of things right |
| 17:01 | technomancy | jacortinas: Maven and Leiningen both use Aether |
| 17:01 | jacortinas | ah ok |
| 17:01 | sdegutis | oh, aether. |
| 17:01 | insamniac | make up your mind! |
| 17:01 | sdegutis | why not name it Dragicorn? |
| 17:01 | technomancy | zerokarmaleft: having JS modules be first-class data structures helps a lot there |
| 17:01 | technomancy | (the one thing JS does better than clojure) |
| 17:02 | sdegutis | http://bit.ly/1nrYLp0 |
| 17:02 | insamniac | This channel makes me feel dumb all day. |
| 17:02 | sdegutis | insamniac: isnt it awesome? |
| 17:02 | technomancy | sdegutis: you can suggest a rename: https://bugs.eclipse.org/bugs/buglist.cgi?query_format=specific&order=relevance+desc&bug_status=__open__&product=Aether |
| 17:02 | insamniac | It's refreshing, but I kind of like feeling like a hero at work all day too. |
| 17:02 | sdegutis | cant. |
| 17:03 | technomancy | sdegutis: you can if you believe in yourself |
| 17:04 | insamniac | You forgot to drop the mic. |
| 17:04 | sdegutis | ha |
| 17:04 | sdegutis | back to manipulating the DOM directly via clojurescript |
| 17:05 | technomancy | modern technology is getting to the point where it can glare back |
| 17:05 | technomancy | dammit |
| 17:05 | sdegutis | ha |
| 17:05 | insamniac | anyone here use parkour? |
| 17:05 | insamniac | we have some hadoop project coming up |
| 17:06 | bbloom | technomancy: javascript's modules are only first class because javascript doesn't have anything even approaching modules |
| 17:06 | bbloom | technomancy: it's easy to make something first class if it's also practically useless :-P |
| 17:07 | ddima_ | insamniac: no idea about parkour, but another solid alternative would be cacalog |
| 17:07 | ddima_ | err, cascalog |
| 17:07 | rhg135 | modules are maps there |
| 17:07 | technomancy | bbloom: well, there's a silver lining to that cloud |
| 17:07 | insamniac | i like caca log |
| 17:07 | ddima_ | it's the best |
| 17:07 | insamniac | i just mean i like the typo. never heard of it! |
| 17:08 | insamniac | I won't be able to sell anyone on using anything but Java probably anyhow. |
| 17:08 | ddima_ | i knew you meant the typo :) |
| 17:08 | insamniac | i knew you knew i knew |
| 17:08 | ddima_ | insamniac: once they see what a job of moderate complexity looks like in java they will at least go for pig probably |
| 17:09 | ddima_ | one could use cascading though, but then jumping to cascalog is not a big step anymore. It's not that pig is much easier to grasp than some clojure dsl. |
| 17:12 | seangrove | Wish there was a gofmt for clojure |
| 17:12 | seangrove | erm, and cljs |
| 17:14 | hyPiRion | but there is |
| 17:15 | hyPiRion | seangrove: alias cljfmt='emacs --batch -l ~/.emacs.d/init.el --eval='(clojure-mode)' --eval='(indent-region (point-min) (point-max) nil)' -f save-buffer' |
| 17:15 | locks | and I bet it’s even customizable |
| 17:15 | seangrove | |
| 17:15 | seangrove | hyPiRion: Clever. But not all the way there |
| 17:16 | seangrove | Also looking to enforce things like "one line of separation between defs" |
| 17:18 | technomancy | knowing where to add \n can be tricky too |
| 17:18 | sshack | Are there any tutorials.examples of web apps using friend with an sql backend? |
| 17:18 | arkh | anyone know what causes the following on perfectly valid ns syntax: "ArityException Wrong number of args (2) passed to: namespaces$import-fn clojure.lang.Compiler.macroexpand1 (Compiler.java:6473)" |
| 17:19 | arkh | in one project, it give me that error but in another project, essentially the same syntax, it doesn't error |
| 17:19 | arkh | *gives |
| 17:21 | turbofail | it'd probably help if you showed us the syntax |
| 17:22 | arkh | (ns foo.bar.baz (:use [vertigo.structs])) |
| 17:23 | arkh | from 'lein repl', if I (load-file "src/foo/bar/baz.clj) I get that error but not in another project |
| 17:23 | arkh | sorry ... long day and it makes no sense |
| 17:35 | hiredman | brehaut: it was basically a recap of his strangeloop presentation, with a little more focus on cassandra |
| 17:35 | brehaut | hiredman: thanks |
| 17:38 | bbloom | dnolen: do you know of a handy list of X where there exists a CLP(X) ? |
| 17:39 | dnolen | bbloom: hmm, I don't - and people implement new domains fairly regularly |
| 17:39 | bbloom | dnolen: i figured that they did, but i was hoping to see a list of like "here's ones that people agree are generally worth studying or knowing of" |
| 17:40 | tbaldridge | CLP(all-the-things) |
| 17:40 | bbloom | a friend of mine is doing some procedural generation for a game & he's trying to improve the uniqueness of the results without creating totally alien impossible things |
| 17:41 | bbloom | i was wondering if CLP of some sort might be helpful |
| 17:44 | seangrove | Who's generally taking care of clojars these days? I suppose it's not the same burden as npm given it's able to ride off of maven repos, but it still seems like npm struggles *a lot* more |
| 17:45 | bbloom | seangrove: npm struggles for a few reasons 1) a totally unscalable design 2) massive abuse of a central repository (seriously people, host your own packages for production) 3) crazy unjustified popularity of javascript ... etc |
| 17:46 | stompyj | I think the difference is that clojars is written in clojure, and npm is written in node *cough* |
| 17:46 | stompyj | jk |
| 17:46 | bbloom | stompyj: lol but no seriously, you're not that far off |
| 17:46 | technomancy | bbloom: no, it is |
| 17:46 | technomancy | it's the difference between couchdb and nginx |
| 17:47 | brehaut | couchdb O_O |
| 17:47 | bbloom | technomancy: sure |
| 17:47 | technomancy | actual downloads of packages don't hit any dynamic code in either case |
| 17:47 | technomancy | brehaut: it actually makes mirroring really easy |
| 17:47 | technomancy | but no one uses mirrors because it's easier to just hammer the central repo |
| 17:47 | brehaut | technomancy: win! |
| 17:50 | sdegutis | technomancy: btw, have you seen that guy's response to your response to my response on HN about the problem with Marmalade? |
| 17:51 | sdegutis | https://news.ycombinator.com/item?id=7114490 |
| 17:51 | technomancy | sdegutis: somehow I remain unconvinced =) |
| 17:52 | technomancy | actually that's crap anyway; with marmalade you try to get teh original authors to submit too |
| 17:52 | sdegutis | seems like a major flaw to me, that anyone can push to any given marm package |
| 17:52 | technomancy | yeah, if someone squats on a package with a fork and the original author comes along, the marmalade guy will give them the name |
| 17:53 | sdegutis | oh |
| 17:53 | sdegutis | bbloom: #3 is totally right on |
| 17:54 | sdegutis | in it self it just mystifies me |
| 17:54 | bbloom | i mean, node has its (limited) uses & i'm glad it exists and is maturing |
| 17:54 | bbloom | i'm just glad that other suckers are trying to build scalable infrastructures on it so that my puny use cases for it aren't problematic |
| 17:55 | seangrove | bbloom: Hrm, what're your use cases? |
| 17:55 | technomancy | the npm guys don't really understand couch all that well either |
| 17:55 | brehaut | technomancy: being one of the people melpa crapped on, i agree with your position ;) |
| 17:55 | technomancy | they were putting password hashes in unprotected fields for years, and then also http://writing.jan.io/2013/12/19/understanding-couchdb-conflicts.html |
| 17:55 | bbloom | seangrove: pretty much just builds for front end code |
| 17:56 | seangrove | bbloom: Ah, so compilation tooling, more or less? |
| 17:56 | technomancy | well, they didn't understand it when they originally designed it. they probably understand it better now. |
| 17:56 | bbloom | seangrove: primarily, which also includes to a limited extent something like react-page |
| 17:56 | bbloom | seangrove: https://github.com/facebook/react-page |
| 17:56 | bbloom | seangrove: but there are alternatives that are preferable there: like clojure + clojurescript |
| 17:57 | sdegutis | brehaut: you mean you were bit by it too? |
| 17:57 | brehaut | sdegutis: i was part of the stream of people technomancy helped because i had melpa in my config when i didnt want it |
| 17:57 | sdegutis | :) |
| 17:57 | sdegutis | was this back when Magit broke? |
| 17:57 | technomancy | "My Emacs is broken" / "Are you using melpa?" / "Yes" / "Well then." |
| 17:58 | sdegutis | i was bit hard by that. |
| 17:58 | technomancy | ^ basically a weekly theme either in here or #emacs |
| 17:58 | brehaut | technomancy: followed by "what is melpa?" |
| 17:58 | technomancy | brehaut: those are the worst, yeah =/ |
| 17:58 | brehaut | technomancy: sorry :( |
| 17:58 | technomancy | brehaut: not your fault |
| 17:58 | sdegutis | Another reason I don't touch my init.el is because I'm afraid of breaking muscle memory. |
| 17:58 | technomancy | brehaut: it's people putting "just copy/paste this snippet into your config" in their readme without explaining it |
| 17:59 | sdegutis | For example, newer versions of Magit changed the shortcuts, so it's doing all sorts of things I don't expect or even want. |
| 17:59 | brehaut | technomancy: weell, i should know by now not to just cargo cult |
| 17:59 | sdegutis | brehaut: cargo-culting is a legitimate and time-honored way to get started with emacs |
| 17:59 | deadghost | cargo culting is a good way to begin in a lot of things |
| 17:59 | brehaut | sdegutis: and still wrong ;) |
| 18:00 | technomancy | I think it's feasible to limit the cargo-culting to "install this set of packages" |
| 18:00 | sdegutis | brehaut: it's impractical to start learning everything about how emacs works when you're just getting started. You just copy bits/pieces from other people's configs that make your stuff work right, and learn why afterwards. |
| 18:00 | technomancy | if you install packages one at a time, you'll have a better chance of understanding what each one does |
| 18:00 | deadghost | 1. start using something 2. decide it sucks 3. recur |
| 18:01 | sdegutis | Speaking of deleting repos, does anyone want to fork https://github.com/sdegutis/LVReplClient ? |
| 18:01 | technomancy | deadghost: catch StackOverflowException -> become a carpenter |
| 18:01 | AimHere | Maybe there should be an emacs-from-scratch install, where it just gives you the lisp interpreter and the minimal set of lisp things and tells you to built it yourself from then on |
| 18:01 | technomancy | AimHere: no, start with SKI |
| 18:01 | technomancy | or maybe logic gates |
| 18:01 | brehaut | technomancy: SKI is for lazy people. Start with SK |
| 18:02 | sdegutis | I really want to see an Emacs Reboot. |
| 18:02 | technomancy | brehaut: touché |
| 18:02 | sdegutis | Like, a minimalist program with a similar language to Emacs Lisp, and a similar API for handling text, but with less 1980s baked in. |
| 18:02 | seangrove | sdegutis: It's pronounced "LightTable", I believe |
| 18:02 | bbloom | lol |
| 18:03 | seangrove | sdegutis: It just needs another decade or so to fully form |
| 18:03 | technomancy | sdegutis: rms goes back in time and prevents his past self from writing a lisp-2, creating an alternate timeline in which elisp is actually not a terrible language for doing FP |
| 18:03 | technomancy | except there are romulans and stuff |
| 18:03 | turbofail | needs moar borg |
| 18:03 | deadghost | I'd watch that movie |
| 18:03 | sdegutis | seangrove: Something about compiling Lisp into JS and running it inside a WebView just makes me feel all weird inside. |
| 18:03 | brehaut | technomancy: how could you tell which is evil RMS though? the tiny beard is going to be lost in wild hill man beard |
| 18:04 | brehaut | or does the beard have a beard? |
| 18:04 | technomancy | brehaut: mind_blown.gif |
| 18:04 | AimHere | RMS is beard all the way down |
| 18:04 | seangrove | sdegutis: Well, give it time |
| 18:04 | sdegutis | seangrove: I thought the ClojureScript route was only for prototyping, and then it suddenly became the official thing. That confused me. |
| 18:05 | technomancy | sdegutis: it sounds like embracing the madness of the modern stack instead of staunchly insisting on DTRT |
| 18:05 | sdegutis | seangrove: Plus I'm very skeptical of any API design. But simpler always seems better, and LT's API seems complex right off the bat. |
| 18:05 | technomancy | problem is that staunchly insisting on DTRT leads you to either loper-os or opengenera |
| 18:05 | dnolen | sdegutis: it's actually an incredibly simple system. |
| 18:06 | sdegutis | dnolen: Oh? Can you recommend a specific write-up describing it? |
| 18:06 | dnolen | sdegutis: http://www.chris-granger.com/2013/01/24/the-ide-as-data/ |
| 18:06 | dnolen | sdegutis: writing a hello world plugin is ridiculously easy |
| 18:06 | sdegutis | dnolen: Sweet. |
| 18:07 | dnolen | sdegutis: all the hard stuff is interacting with Node, WebKit, CodeMirror |
| 18:07 | sdegutis | My only other objection was arrogance (I didn't write the IDE myself) and that one has to go cuz it ain't founded in any kind of sanity. |
| 18:07 | arkh | I finally have my problem down to the simplest case: 1) do a 'lein new baz' 2) in your new project.clj, add as dependencies [aleph "0.3.0"] and [vertigo "0.1.1"]. 3) make this the contents of your src/baz/core.clj "(ns baz.core (:require [vertigo.structs :as vs]))" 4) breaks when loaded |
| 18:07 | sdegutis | dnolen: That sounds kinda painful. I've been writing ClojureScript interacting with the DOM this afternoon and it's not pleasant at all, even with Dommy. |
| 18:08 | seangrove | sdegutis: It also seems like ibdknox's approach of allowing plugins to fundamentally change anything means it'll grow along the lines of emacs |
| 18:08 | technomancy | drracket might qualify on the "staunch dtrt" front actually |
| 18:08 | technomancy | reading about racket's approach to image handling just made me sad about quil |
| 18:08 | dnolen | sdegutis: Dommy doesn't really try to fix anything, nor does LT fundamentally |
| 18:08 | dnolen | sdegutis: try React, Reagent, or Om for something more sensible |
| 18:08 | sdegutis | dnolen: Sounds like it needs some good third party wrapper APIs. |
| 18:08 | sdegutis | Oh. |
| 18:09 | sdegutis | Thanks for the recommendations, I'll check them out dnolen. |
| 18:09 | TEttinger | arkh, what kind of breaks? |
| 18:09 | arkh | TEttinger: ArityException Wrong number of args (2) passed to: namespaces$import-fn clojure.lang.Compiler.macroexpand1 (Compiler.java:6473) |
| 18:10 | seangrove | We should probably find someone local who can talk on reagent |
| 18:10 | seangrove | Then we can divide the next meetup into three talks: React, Om, Reagent |
| 18:10 | arkh | Tettinger: I did a (load-file "src/baz/core.clj") at a repl |
| 18:10 | dnolen | Hoplon looks cool too, though I haven't looked at it closely enough to understand how you model components or if the model more less obviates them |
| 18:11 | insamniac | s/re le/re or le/ |
| 18:12 | sdegutis | technomancy: dtrt = do the right thing? |
| 18:12 | TEttinger | arkh, I'll try to reproduce |
| 18:12 | arkh | Tettinger: awesome! |
| 18:12 | sdegutis | technomancy: opengenera exists!? |
| 18:13 | technomancy | yeah |
| 18:13 | technomancy | clojurebot: DTRT is do the right thing |
| 18:13 | clojurebot | In Ordnung |
| 18:13 | technomancy | opengenera ... mostly exists? |
| 18:16 | TEttinger | arkh, I can reproduce. |
| 18:16 | ztellman | arkh Tettinger: this is my fault? |
| 18:16 | TEttinger | I am guessing it's a problem in a lib |
| 18:17 | TEttinger | ztellman, is vertigo yours? |
| 18:17 | ztellman | yup |
| 18:17 | TEttinger | I guess I should have checked the google ads |
| 18:17 | arkh | ztellman: I was going to try to contact you next : ) |
| 18:17 | ztellman | vertigo is one I haven't used in a production context yet |
| 18:17 | arkh | TEttinger: thank you for trying it |
| 18:17 | ztellman | just a sec |
| 18:17 | TEttinger | no prob arkh |
| 18:19 | TEttinger | ztellman, it looks like you need a new version! https://github.com/ztellman/vertigo/compare/0.1.1...master |
| 18:20 | ztellman | TEttinger: coming to that conclusion, yeah |
| 18:20 | TEttinger | or could arkh use the snapshot, is it published? |
| 18:22 | ztellman | 0.1.2-SNAPSHOT should be there, but it's also marginally out of date |
| 18:25 | aperiodic | technomancy: what were you reading about racket's image handling that made you sad about quil? |
| 18:25 | technomancy | aperiodic: the first chapter of htdp.org, oh man |
| 18:26 | technomancy | it starts with numbers and how to do arithmetic |
| 18:26 | technomancy | then it goes on to strings and how to append them, upper-case them, etc |
| 18:26 | technomancy | but how they're all just values you call functions on |
| 18:26 | technomancy | then it's all «oh yeah, and you can do "arithmetic" with images too» |
| 18:27 | technomancy | they're first-class values that display in the repl; you can compose them like data |
| 18:27 | technomancy | quil is all "here's a function to draw a line on the screen" or whatever; very imperative and primitive =\ |
| 18:27 | hiredman | overloading math :( |
| 18:27 | technomancy | hiredman: it doesn't overload the actual symbols |
| 18:28 | technomancy | it's just a way of saying "these are all values you can do things with" |
| 18:28 | aperiodic | yeah, i understand pragmatically the motivation to build on top of processing, but it's basically impossible to escape its imperative paradigm |
| 18:29 | aperiodic | everything you do is a side-effect on a graphics buffer |
| 18:32 | sdegutis | "oh, camel! you so silly!" |
| 18:32 | arkh | ztellman: looks like vertigo 0.1.2-SNAPSHOT does the same. I'll just have to wait for the next version! Thank you |
| 18:32 | sdegutis | I don't think there's actually a topic for this channel, right? It's just kind of like, in-general programming-ish, right? |
| 18:33 | technomancy | sdegutis: maybe you're thinking of #emacs |
| 18:33 | technomancy | this was the "argue about haskell" channel until like a week ago |
| 18:33 | sdegutis | When will it be the argue-about-ocaml channel? |
| 18:33 | arkh | I thought that was just that one guy, instigating problems |
| 18:33 | technomancy | arkh: well yes |
| 18:35 | TimMc | eternal haskember |
| 18:37 | TimMc | hahaha |
| 18:40 | TimMc | I should really have irssi write my logs file-per-day |
| 18:40 | TimMc | My log for this channel is over 1000000 lines long. |
| 18:41 | xuser | so bitemyapp finally ditch clojure for haskell? |
| 18:42 | `cbp | I believe he uses clojure at work |
| 18:43 | sdegutis | But Haskell is more fun. |
| 18:43 | `cbp | ~guards |
| 18:43 | clojurebot | SEIZE HIM! |
| 18:44 | sdegutis | I started reading Learn You a Haskell, and so far it's just Clojure, but without parentheses, and everything is wrapped in an implicit (fn ...) |
| 18:45 | Raynes | You haven't read much then. |
| 18:45 | sdegutis | Oh right, it also does static typing. |
| 18:54 | AeroNotix | sd |
| 19:04 | ztellman | arkh: try vertigo 0.1.3 |
| 19:04 | ztellman | 0.1.2 was tragically lost in a dependencies mishap |
| 19:11 | TEttinger | same error ztellman |
| 19:11 | ztellman | ! |
| 19:11 | TEttinger | I'll try cleaning first? |
| 19:12 | TEttinger | it's an arity issue still. |
| 19:12 | TEttinger | ArityException Wrong number of args (2) passed to: namespaces$import-fn clojure.lang.Compiler.macroexpand1 (Compiler.java:6473) |
| 19:12 | ztellman | why is the test suite not catching that |
| 19:12 | ztellman | ok, back to the drawing board |
| 19:14 | TEttinger | oooh |
| 19:15 | TEttinger | ztellman, if I use the ns that requires vertigo.structs (might have spelled it wrong): Exception namespace 'vertigo.primitives' not found clojure.core/load-lib (core.clj:5380) |
| 19:15 | ztellman | ... |
| 19:16 | ztellman | I mean, it's there |
| 19:16 | ztellman | that's also something which uses import-fn, so maybe it's related |
| 19:23 | ztellman | arkh: ok, figured out your issue, which wasn't the one I was tracking down |
| 19:23 | ztellman | add [potemkin "0.3.4"] to your depdnencies |
| 19:23 | `cbp | Man I thought compiling c was hard but then i stumbled upon clojurescript |
| 19:23 | ztellman | or exclude potemkin from the aleph dependencies |
| 19:24 | mikerod | Haskell is just like Clojure, without all of the awesome |
| 19:25 | `cbp | without all of the java? ;) |
| 19:25 | mikerod | i.e.: (remove the-awesome Clojure) ;= Haskell |
| 19:25 | egghead | huh... |
| 19:25 | mikerod | just joking, I don't know enough to say that :) |
| 19:25 | technomancy | (remove NullPointerException Clojure) |
| 19:25 | brehaut | remove the-awesome Clojure #= haskell ;) |
| 19:25 | egghead | mikerod: clojure is just like haskell.. without all the types? |
| 19:25 | mikerod | technomancy: that was a good one. haha |
| 19:27 | tjd | i'm looking for a way to "map |
| 19:27 | tjd | "map" a hash map, something like (defn f [k v] [k (+ v 1)]) then (map f {:a 1 :b 2}) and have the result be {:a 2 :b 3} |
| 19:28 | `cbp | Am I missing something? I can't seem to find docs for cljs compiler options |
| 19:31 | TEttinger | tjd, I think that's kvmap? |
| 19:33 | tjd | TEttinger: i can't find taht in standard library |
| 19:34 | TEttinger | yeah I was confused |
| 19:34 | TEttinger | you can map over hashmaps, it just has entries |
| 19:34 | TEttinger | tjd: ##(letfn [(f [[k v]] [k (+ v 1)])] (map f {:a 1 :b 2})) |
| 19:34 | lazybot | ⇒ ([:a 2] [:b 3]) |
| 19:35 | tjd | yeah, and i can reconstitue the result of that map into a hashmap, its just kind of a pain in the butt |
| 19:35 | TEttinger | tjd: ##(letfn [(f [[k v]] [k (+ v 1)])] (into {} (map f {:a 1 :b 2}))) |
| 19:35 | lazybot | ⇒ {:a 2, :b 3} |
| 19:35 | whilo | `cbp: have you had a look at: https://github.com/clojure/clojurescript/wiki/Quick-Start ? |
| 19:36 | mikerod | ,(into {} (map (juxt key #(inc (val %))) {:a 1 :b 2})) |
| 19:36 | clojurebot | {:a 2, :b 3} |
| 19:36 | mikerod | (into {} (map (juxt key (comp inc val)) {:a 1 :b 2})) |
| 19:37 | mikerod | ,(into {} (map (juxt key (comp inc val ) {:a 1 :b 2})) |
| 19:37 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 19:37 | whilo | ztellman: at euroclojure we talked briefly. with critical theory and frankfurt school i meant especially http://books.google.de/books?id=l-75zLjGlZQC&printsec=frontcover&hl=de#v=onepage&q&f=false |
| 19:37 | TEttinger | you could just declare a function that does this. (fn [f coll] (into {} (map #(f (first %) (second %)) coll))) |
| 19:37 | mikerod | ,(into {} (map (juxt key (comp inc val)) {:a 1 :b 2})) |
| 19:37 | clojurebot | {:a 2, :b 3} |
| 19:37 | whilo | don't know if you know it, just for reference |
| 19:38 | TEttinger | ,(defn map-map [f coll] (into {} (map #(f (first %) (second %)) coll))) |
| 19:38 | `cbp | whilo: yeah. I still can't figure out how to add .js libraries though |
| 19:38 | clojurebot | #'sandbox/map-map |
| 19:38 | tjd | awesome! |
| 19:38 | tjd | i learned something |
| 19:38 | `cbp | (even though they're supposed to work with closure) |
| 19:38 | TEttinger | ,(map-map + {1 10 2 20}) |
| 19:38 | clojurebot | #<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: java.lang.Long {:instance 11}> |
| 19:38 | TEttinger | uhhhh I might have screwed up |
| 19:39 | mikerod | tjd: my example was just trying to use all built ins to do the job |
| 19:39 | whilo | `cbp i am not very experienced. the easiest i found was to include the js somewhere on the html page, use whitespace compilation and exploit the fact that symbols are not munged, so you can reference js objects just by their name |
| 19:40 | whilo | if your js library supports google closure you can compile it in, there was fairly little information on that. the easiest is to grab (or create) some extern file for your library, reference that once you move from whitespace compilation to optimized js |
| 19:40 | mikerod | ,(reduce (fn [m [k v]] (assoc m k (inc v))) {} {:a 1 :b 2}) |
| 19:40 | clojurebot | {:b 3, :a 2} |
| 19:41 | sdegutis | AeroNotix: Yes? |
| 19:43 | sdegutis | mikerod: or maybe (->> clojure :features (remove awesome?)) |
| 19:43 | tjd | thank you mikerod and TEttinger. i'm still learning and stuff like this really helps. cheers. |
| 19:43 | mikerod | sdegutis: indeed :P |
| 19:46 | TEttinger | ah, here we go. |
| 19:46 | TEttinger | ,(defn map-map [f coll] (into {} (map (fn [[k v]] [k (f v)]) coll))) |
| 19:46 | clojurebot | #'sandbox/map-map |
| 19:46 | TEttinger | that one takes a function and a map, calls the fn on each value of the map, and keeps the same keys |
| 19:47 | TEttinger | there's a way to do that with juxt too, but it's uh not as easy |
| 19:47 | devn | suggestions on how to do this more efficiently: https://gist.github.com/devn/cf948a57216bb8eb83c6 |
| 19:48 | devn | the ref need not be there, fwiw |
| 19:48 | devn | this is a CSV file that is around 200MB |
| 19:48 | devn | I want to very quickly find all distinct values for each column within that file |
| 19:49 | TEttinger | devinus, hm? (dosync (alter r assoc header-name distinct-vals)) is at the last line, and r is the ref? |
| 19:49 | TEttinger | ^ devn |
| 19:49 | devn | r is the ref there, yes |
| 19:49 | devn | but i mean, try and use reducers, whatever |
| 19:49 | TEttinger | oh ok |
| 19:49 | devn | i dont care how i do it, but i've been playing with solutions and am hitting a roadblock |
| 19:50 | devn | I think maybe loading this into a database is a requirement |
| 19:50 | llasram | devn: Do you known that all distinct values for all columns will fit into memory? |
| 19:50 | TEttinger | well are you sure of what the core.data.csv fns return? |
| 19:50 | devn | llasram: I do not. |
| 19:50 | devn | My motivation for writing this is: I have 100 CSV files, from 1k to 1.2GB |
| 19:51 | devn | I know for a fact there are relationships between the data, but they are fuzzy connections |
| 19:51 | llasram | devn: Also, trying to create a lazy seq which holds on to resources and releases them when the seq is exhausted pretty much guarantees that you'll have resource leaks |
| 19:51 | devn | the column names do not match, for instance |
| 19:52 | devn | so I want to accrete all the discrete values for each colum, and when the number of discrete values for a column is more than 90% of all values found for a column (excluding empty? vals) |
| 19:52 | devn | so I can try and test whether or not they're related CSV files |
| 19:52 | devn | to find a common unique value between them |
| 19:52 | devn | to basically sniff out "ID"-esque columns |
| 19:53 | devn | llasram: yeah, im finding this out. again, looking for suggestions on a good approach |
| 19:54 | devn | TEttinger: I'm not realizing the core.data.csv result |
| 19:54 | devn | I'd have to do (doall ...) around it to realize it |
| 19:54 | devn | im running with Xmx2g and -server |
| 19:54 | TEttinger | I actually wrote my own (tab) separated value parser not long ago. |
| 19:55 | TEttinger | it wasn't hard |
| 19:56 | devn | yeah, it really isn't, but i've looked at core.data.csv and it looks fine |
| 19:56 | devn | i dont think that's where the problem is |
| 19:57 | llasram | devn: Actually taking a look at your code, you are definitely forcing the whole CSV to be realized in memory at once |
| 19:58 | llasram | You bind the CSV to `rows`, then in the `doseq` iterate by column. After you finish the first column, `rows` can't be cleared (because you need it for the next column), but has been fully realized (because you've walked all the rows) |
| 19:58 | devn | llasram: that used to be a for |
| 19:59 | devn | the doseq |
| 19:59 | llasram | Same problem |
| 19:59 | llasram | You still need to realize the entire CSV in order to produce the results for a single column |
| 19:59 | devn | right, because i need distinct values |
| 19:59 | llasram | You need to structure your code so that you walk the CSV row-wise, holding only a single row at once, and accumulating the results for all columns at the same time |
| 19:59 | devn | ah, i see |
| 19:59 | devn | right that makes sense |
| 20:00 | devn | so i should reduce over it maybe |
| 20:00 | devn | and check whether i have that value or not |
| 20:00 | devn | and then continue walking |
| 20:00 | llasram | Or just add to sets |
| 20:00 | devn | yeah, good idea |
| 20:00 | devn | thanks llasram. much appreciated. |
| 20:00 | llasram | np and good luck |
| 20:04 | ztellman | whilo: thanks, I'll give it a look |
| 20:04 | kristof | All this talk about walking csv's feels eerily familiar |
| 20:07 | turbofail | also make sure you don't hold on to the CSV sequence's head anywhere. if it's in a local variable, that will force the whole thing to remain in memory |
| 20:07 | devn | kristof: :) |
| 20:08 | kristof | devn: Was that you? |
| 20:08 | kristof | A few days ago, maybe a week ago |
| 20:08 | devn | kristof: i have a TON of legacy data I'm trying to form relationships between |
| 20:08 | kristof | Legacy code SUCKS, YUCK |
| 20:08 | devn | kristof: perhaps. i've been mucking around with csv transformations |
| 20:08 | devn | kristof: it's kind of fun FWIW |
| 20:08 | devn | just daunting |
| 20:08 | devn | which is why i want to write a tool to do this |
| 20:09 | kristof | devn: Give me an example of what you're doing |
| 20:09 | devn | a.csv is a 500MB file of information, like first name, last name, a, b, c, d, e, etc. |
| 20:10 | devn | e is actually concatenated from a c d, it serves as a key |
| 20:10 | devn | in all other tables, i want to check to see if the value in e exists, and if it does, i want to form a relationship to that table from my table+column, to its table+column |
| 20:11 | devn | kristof: ^ |
| 20:11 | safety | is there a way to get a running total of a vector without using loop? e.g. [1 2 3] -> [1 3 6] |
| 20:12 | devn | safety: reductions |
| 20:12 | safety | not sure how to reduce to a vector |
| 20:12 | kristof | into |
| 20:13 | kristof | er |
| 20:13 | turbofail | ##(into [] (reductions + [1 2 3])) |
| 20:13 | lazybot | ⇒ [1 3 6] |
| 20:13 | kristof | "reducing to a vector" makes no sense. reduce is a mapping from a collection of a's to an a |
| 20:13 | kristof | or some b, actually |
| 20:13 | kristof | ah right reductions |
| 20:13 | technomancy | whut |
| 20:13 | safety | turbofail: thanks! |
| 20:13 | kristof | technomancy: where's the what coming from |
| 20:13 | devn | ,loop |
| 20:13 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/loop, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:13 | devn | whoops |
| 20:13 | devn | ,([] [1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5]) |
| 20:13 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (5) passed to: PersistentVector> |
| 20:14 | devn | ahhh! |
| 20:14 | devn | ,(reductions (fn [res x] (conj res x)) [] [1 2 3 4 5]) |
| 20:14 | clojurebot | ([] [1] [1 2] [1 2 3] [1 2 3 4] ...) |
| 20:14 | technomancy | "reduce is a mapping from a collection of As to an A" |
| 20:14 | kristof | technomancy: corrected in the subsequent statement since the return value can be of any type, the point being that it's always a single value |
| 20:14 | turbofail | a single value that might be a sequence of values |
| 20:15 | kristof | I can't think of a scenario where you reduce over something and end up with a collection |
| 20:15 | technomancy | I literally just did that a few hours ago |
| 20:15 | kristof | what was the scenario? |
| 20:15 | technomancy | well, it was erlang |
| 20:16 | kristof | still relevant |
| 20:16 | technomancy | it was in order to map and filter in a single pass |
| 20:16 | brehaut | ,(reduce conj () [1 2 3]) |
| 20:16 | clojurebot | (3 2 1) |
| 20:16 | devn | brehaut: i like to keep it verbose :) |
| 20:16 | technomancy | but I reduce into maps in clojure fairly frequently |
| 20:16 | kristof | brehaut: I meant something useful :P |
| 20:17 | kristof | technomancy: oh, that's a good point |
| 20:17 | kristof | I think I was just thinking of lists and vectors |
| 20:17 | devn | kristof: if you never ended up with a collection |
| 20:17 | devn | why would reduce-kv even exist? |
| 20:17 | devn | i suppose that's /over/ |
| 20:17 | devn | nevermind |
| 20:17 | devn | but yeah, i build collections all the time with it |
| 20:17 | devn | it's not uncommon at all |
| 20:18 | kristof | hmmm |
| 20:18 | kristof | oh, related: is there an unfold/unreduce in clojure? |
| 20:18 | devn | not that im aware of |
| 20:19 | hyPiRion | kristof: I think the confusion is partially coming from the reduction definition in parallel programming terms is usually considered to be to a single A. |
| 20:19 | devn | yeah, that's a good point |
| 20:19 | kristof | hyPiRion: yeah |
| 20:19 | devn | and frankly, i remember learning reduce |
| 20:19 | devn | the canoncial example was reduce + [1 2 3 4 5 6] |
| 20:19 | brehaut | kristof: if you discard returning collections from reduce you have just made map, filter… a lot harder to write |
| 20:20 | kristof | brehaut: Are those implemented in terms of reduce? I had no idea! |
| 20:20 | devn | it's a building block |
| 20:20 | brehaut | kristof: well they can be. i think they may be a big squirrly maze for performance reasons |
| 20:20 | brehaut | kristof: reduce is just 'primative recursion' abstracted as a function |
| 20:21 | jajaja | Anyone using Clojure on a VM with 1GB RAM or less? |
| 20:21 | brehaut | jajaja: yes |
| 20:21 | devn | filter isn't written in terms of reduce |
| 20:21 | jajaja | Wondering how pared down you can get the JVM if tuned properly |
| 20:21 | brehaut | jajaja: i run two clojure apps on a VPS with only half a gig |
| 20:21 | turbofail | devn: it could be |
| 20:21 | brehaut | theres room to spare |
| 20:21 | devn | turbofail: sure |
| 20:21 | devn | im just saying it isn't |
| 20:21 | devn | i believe the same is true for map |
| 20:21 | devn | because it defers to applyTo |
| 20:21 | jajaja | brehaout Great! I'm new and had my doubts |
| 20:21 | devn | inside apply |
| 20:22 | jajaja | brehaout Also room for db and mailserver? |
| 20:22 | brehaut | jajaja: i have no idea about mailserver because im not crazy / have copious spare time but yes. ive run postgres and couch concurrently with those two apps |
| 20:22 | devn | brehaut: 16g is a lot |
| 20:23 | devn | err, jajaja |
| 20:23 | jajaja | brehaout Did you need to tune your JVM a lot? |
| 20:23 | brehaut | jajaja: i didnt tune it even a bit |
| 20:24 | brehaut | it'll obviously depend on your app / load whether thats necessary |
| 20:24 | brehaut | jajaja: surely your irc client autocompletes nicks? |
| 20:24 | jajaja | brehaout What's the first thing that happens when a JVM runs out of memory? |
| 20:24 | brehaut | i dont know. its never run out of memory |
| 20:25 | jajaja | brehaout Does it handle the situation gracefully? |
| 20:25 | turbofail | it throws an exception |
| 20:25 | brehaut | how would i know this |
| 20:25 | turbofail | and then dies |
| 20:25 | jajaja | turbofail So not quite so graceful |
| 20:26 | kristof | jajaja: Why don't you try it? |
| 20:26 | turbofail | i don't think any system really handles running out of memory gracefully |
| 20:26 | turbofail | if you can't garbage collect anymore, what else are you going to do? |
| 20:26 | devn | monit |
| 20:27 | devn | that's what you do in that case |
| 20:27 | devn | monitor it and fire an alert |
| 20:27 | jajaja | Swap to disk? |
| 20:27 | turbofail | jajaja: well you can do that by just giving java a max heap size larger than your physical memory and enabling swap in the OS |
| 20:27 | devn | jajaja: load test it |
| 20:27 | jajaja | turbofail That could be handy to know |
| 20:28 | jajaja | Better than dying, maybe |
| 20:28 | devn | give it an order of magnitude more queries/connections/whatever, and run some tests |
| 20:28 | turbofail | that said without an SSD (or maybe even with an SSD) relying on swap is probably not going to be a great experience |
| 20:28 | jajaja | devn Will do |
| 20:29 | jajaja | turbofail Thinking more of a last resort, obviously |
| 20:30 | devn | taking the time to verify your stuff works in production under load is so important when you get an alert that's like: "OMG I'm dying!" |
| 20:30 | `cbp | whilo: hi, just read your comment. Yeah I think I need to make an extern file. Need to figure that out somehow. I'm trying to compile react + om with advanced optimizations. Thanks for your help |
| 20:31 | aperiodic | you can definitely run two clojure webapps, postgres, and a mailserver all with less than a gig of RAM |
| 20:31 | aperiodic | In fact, this box is running four clojure webapps, postgres, a mailserver, and irssi |
| 20:31 | devn | aperiodic: depends on the traffic |
| 20:31 | jajaja | aperiodic Good to know. I have a number of clients who run everything on VMs with 1GB RAM |
| 20:32 | aperiodic | devn: yeah, none of them get very much traffic. YMMV |
| 20:32 | devn | aperiodic: i've run lots of stuff on a tiny VPS before |
| 20:32 | devn | but i've also watched kingdoms crumble when GC limits got hit |
| 20:32 | devn | more time spent in reclamation than performing tasks |
| 20:33 | turbofail | look upon my heaps, and despair! |
| 20:33 | devn | :D |
| 20:33 | jajaja | aperiodic devn: I read somewhere that beyond the startup memory allocation the JVM is more efficient under load than, say a Rails app because it doesn't have to spawn a new process for every request |
| 20:34 | turbofail | hm, looks like i left out "ye mighty" |
| 20:34 | kristof | devn: Is there an implementation strategy for really, really large applications where you almost entirely decouple two big chunks of a program and garbage collect them separately? |
| 20:34 | kristof | ...I think I just described distritubed computing. |
| 20:34 | aperiodic | devn: did you ever explicitly set the max heap size and have the JVM die on OOM? |
| 20:37 | aperiodic | that's what we used to do when we were running HBase on AWS machines with crappy disks at my old job, and it really helped to avoid instances getting bogged down in GC |
| 20:45 | quizdr | I can't understand why (map #(-> (% 2 4)) '(+ - *)) doesn't simply return the value of the function (-> (% 2 4)) for each fn in the map, as you'd expect a map to do. |
| 20:45 | quizdr | ,(+ 2 4) |
| 20:45 | clojurebot | 6 |
| 20:45 | quizdr | ,(map #(-> (% 2 4)) '(+ - *)) |
| 20:45 | clojurebot | (4 4 4) |
| 20:49 | quizdr | i'd have expected 6 for the first value in the map's return, for example |
| 20:51 | aperiodic | quizdr: i can't understand either. i suspect it has something to do with the fact that you're mapping over symbols, since ##(map #(% 2 2) [+ - *]) does what you'd expect |
| 20:51 | lazybot | ⇒ (4 0 4) |
| 20:52 | aperiodic | quizdr: and so does ##(map #((resolve %) 2 4) '(+ - *)) |
| 20:52 | lazybot | java.lang.SecurityException: You tripped the alarm! resolve is bad! |
| 20:53 | quizdr | hm, that's interesting. very curious why that happens. |
| 20:53 | aperiodic | but i don't understand what exactly is going on in the example you provided |
| 20:54 | sdegutis | This is a weird client. |
| 20:55 | aperiodic | quizdr: ##(map #(% 1 2 3) '(+ - *)) |
| 20:55 | lazybot | clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol |
| 20:57 | hyPiRion | quizdr: It's because symbols are ifns themselves |
| 20:57 | hyPiRion | It's a weird thing |
| 20:57 | hyPiRion | ,('foo 'a 'bar) |
| 20:57 | clojurebot | bar |
| 20:58 | quizdr | what is "ifns" ? |
| 20:58 | hyPiRion | Well, I say "weird". They work just like keywords. |
| 20:58 | quizdr | ,('+ 4 5) |
| 20:58 | clojurebot | 5 |
| 20:58 | hyPiRion | ifns are values which are also functions. E.g. sets, maps, vectors, keywords and symbols are all IFns. |
| 20:58 | turbofail | ,('+ {'+ 8} 5) |
| 20:58 | clojurebot | 8 |
| 20:59 | quizdr | so what exactly is happening with '+ as the operator? |
| 20:59 | turbofail | quizdr: see above |
| 20:59 | hiredman | '+ is the quoted symbol + |
| 21:00 | turbofail | it's roughly similar to (get 4 '+ 5) |
| 21:00 | hyPiRion | quizdr: it tries to look itself up in the first argument, and if the first arg is not a map or doesn't contain the symbol, it returns the second value (or nil, if none is passed). |
| 21:00 | hyPiRion | yeah, turbofail got it |
| 21:00 | quizdr | ah |
| 21:00 | quizdr | the final value is the "if not found" value |
| 21:00 | hyPiRion | yes |
| 21:01 | quizdr | ok that explains, man, thanks a lot. that was going to bother me all day |
| 21:01 | quizdr | (inc hyPiRion) |
| 21:01 | lazybot | ⇒ 32 |
| 21:01 | hyPiRion | :D |
| 21:06 | quizdr | (inc turbofail) |
| 21:06 | lazybot | ⇒ 1 |
| 21:15 | fortruce | is there a clean idiomatic way to re-bind a local based on a predicate without dealing with dynamic, it seems like there should be an easy way to accomplish this (https://gist.github.com/fortruce/8725445) without repeating '(format)' in an if |
| 21:17 | brehaut | 'rebind' a local? |
| 21:18 | brehaut | you cant rebind a local, clojure is a single assignment language (for locals). you can shadow it however, but thats practically identical to introducing a new local |
| 21:18 | brehaut | ztellman might have a library for you though |
| 21:19 | fortruce | i'm sure my terminology is off, if you look at my gist, i am wondering if it is necessary to repeat my format command |
| 21:19 | brehaut | fortruce: however, you could simply move your let and if inside the format (or bind s' outside) |
| 21:19 | llasram | fortruce: Are you looking for `cond->` ? |
| 21:19 | alandipert | fortruce: https://www.refheap.com/30118 is another way |
| 21:19 | llasram | (or `as->`) |
| 21:20 | brehaut | what alandipert just said |
| 21:20 | fortruce | alandipert: thats exactly the easy solution I can't believe I missed, thanks |
| 21:21 | brehaut | fortruce: fwiw a pluralizer without an optional plural form is broken by design ;) |
| 21:22 | fortruce | brehaut: thats a good point, i'll add another arity to let you specify the plural form :p |
| 21:22 | brehaut | yup |
| 21:22 | brehaut | english is to wacky to be cattered to by simple functions |
| 21:24 | fortruce | thanks for the help |
| 21:25 | Bronsa | fortruce: or you could just use cl-format |
| 21:26 | Bronsa | ,(clojure.pprint/cl-format nil "~r car~:p" 1) |
| 21:26 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint> |
| 21:26 | Bronsa | ,(require 'clojure.pprint) |
| 21:26 | clojurebot | nil |
| 21:26 | Bronsa | ,(clojure.pprint/cl-format nil "~r car~:p" 1) |
| 21:26 | clojurebot | "one car" |
| 21:26 | Bronsa | ,(clojure.pprint/cl-format nil "~r car~:p" 2) |
| 21:26 | clojurebot | "two cars" |
| 21:30 | fortruce | Bronsa: I'll keep that in mind, the docs for it are a little overwhelming atm |
| 21:30 | ztellman | cl-format is such a clown car |
| 21:32 | sobel | is nil a value? |
| 21:33 | brehaut | clojurebot: cl-format is such a clown car |
| 21:33 | clojurebot | In Ordnung |
| 21:33 | sobel | i want to say no, since there is a special function to test for it |
| 21:33 | brehaut | ~cl-format |
| 21:33 | clojurebot | cl-format is such a clown car |
| 21:33 | llasram | sobel: But then what of `zero?` |
| 21:34 | sobel | llasram: wait until you see my code for ... `seven?` |
| 21:35 | sobel | all seriousness aside, zero? is syntax-sugar, right? |
| 21:35 | llasram | heh |
| 21:35 | llasram | But how is it less so than `nil?`? |
| 21:35 | llasram | Or more so |
| 21:35 | llasram | Whatever |
| 21:35 | sobel | i guess it works out the same if nil? is shorthand for (= % nil) (i may have butchered that expression...new at clojure) |
| 21:36 | sobel | but the reason i asked, is it's really handy for nil<>nil |
| 21:36 | brehaut | ,(source nil?) |
| 21:36 | clojurebot | Source not found\n |
| 21:36 | brehaut | (source nil?) |
| 21:36 | sobel | i use this in SQL land a lot |
| 21:36 | sobel | i am translating nil as NULL |
| 21:36 | llasram | ,(= nil nil) |
| 21:36 | clojurebot | true |
| 21:37 | sobel | in theory, null is not a value. = is not defined on not-a-value. the result is not a value. |
| 21:37 | sobel | (relational) |
| 21:38 | llasram | Yeah, that's not the case on the JVM or in Clojure |
| 21:39 | sobel | well, it's complicating my recursive sexpr :) |
| 21:39 | llasram | Oh? |
| 21:39 | fortruce | brehaut: https://www.refheap.com/30125 |
| 21:39 | sobel | i'm sure it's nothing interesting, i'm just doing 4clojure tutorials |
| 21:39 | sobel | thinking like a sql guy |
| 21:40 | brehaut | fortruce: sure |
| 21:40 | sobel | buuuut this is functional not declarative, so i'm sorta grappling |
| 21:40 | brehaut | who said functional isnt declarative? |
| 21:40 | brehaut | the terms arent mutually exclusive |
| 21:42 | sobel | fair nuff |
| 21:52 | technomancy | ...? |
| 21:53 | technomancy | would you expect zsh to look in .bashrc? |
| 21:54 | talios | no - but if you're going to put things in "the local maven repository", that's not a hard coded value. |
| 21:54 | arkh | ztellman: thanks! I'll try that tomorrow |
| 21:54 | technomancy | talios: of course not |
| 21:54 | technomancy | just set :local-repo in your user profile |
| 21:54 | talios | does that eval environment variables? |
| 21:55 | talios | or... can it? |
| 21:55 | talios | I'm doing dynamically located local repositories. |
| 21:57 | talios | mmm, I guess I can get around it with symlink love actually |
| 21:58 | technomancy | you can use ~(System/getenv "STUFF"), sure |
| 21:59 | technomancy | there is no aether-wide config file though |
| 22:01 | talios | mmm, actually - I don't need to. I misread arbscht's code review comment. |
| 22:02 | talios | getting jenkins to do adhoc pipelining of builds based on the gerrit review branch/topic |
| 22:02 | talios | working quite well. will need to do the :local-repo thing at some point I suspect tho. |
| 22:15 | hola_ | Really basic question about immutable data: if in a large app some part can modify a data structure what does it matter whether a new copy is created or the original is mutated? |
| 22:16 | hola_ | You can still end up with unexpected changes whether via re-bindig or mutation |
| 22:19 | brehaut | i think you are going to have clarify your question a lot. |
| 22:20 | hiredman | hola_: it depends on what you mean, but if you have an immutable structure, and it is immutable, someone else can do whatever, but your structure is fine |
| 22:22 | hola_ | As I understand it Clojure's immutable data structures are a bit like git commits ie. the latest version is the earlier version plus the last change, no? |
| 22:23 | hola_ | Rich Hickey is selling the advantages of immutable data structures based on retaining historicity but as I understand you can only ever reference the current version of a Clojure data structure, not earlier versions |
| 22:23 | hiredman | hola_: but if you want to keep the old versions, you can, but for example, with a mutable hashmap, if you put a new value in, you have destroyed the old version |
| 22:23 | hola_ | You can't roll back, say, a few changes to a vector once you've added something to it |
| 22:24 | hiredman | ,(let [x {:a 1} y (assoc x :a 2)] [x y]) |
| 22:24 | clojurebot | [{:a 1} {:a 2}] |
| 22:24 | hiredman | ,(let [x (doto (java.util.HashMap.) (.put :a 1)) y (doto x (.put :a 2))] [x y]) |
| 22:24 | clojurebot | [{:a 2} {:a 2}] |
| 22:26 | hola_ | I'm aware there are data structures to handle mutability (eg. records). It's just that I don't quite undertand how the basic immutable data structures in Clojure save you from all the unintended consequences Rich claims they circumvent. |
| 22:28 | brehaut | hola_: perhaps you need to suggest some specific examples that you dont understand rather than waving an abstract cloud of "all" around? its hard to refute or discuss a vaguery |
| 22:28 | hola_ | If I add an element to a vector, for example, and don't rebind it to a new variable I end up, effectively, with the same result as an assignment in a non-functional programming language |
| 22:28 | john2x | how do I update my dependencies, other than visiting each project's page to check if my they're are up to date? |
| 22:29 | brehaut | if nobody else holds a reference to the original vector thats true |
| 22:30 | hiredman | john2x: don't update deps unless you need to |
| 22:30 | brehaut | hola_: however, that vector cant be changed at a later date by a black box function you call at a later date, whereas if it were an arraylist it could |
| 22:32 | brehaut | its always up to you if you discard your old state, not a callee you need to pass that state too |
| 22:33 | hola_ | (def arr [1 2 3 4]) (def arr (cons 5 arr)) |
| 22:33 | brehaut | hola_: def is a dev time feature; you dont rebind vars as part of the operation of a running program |
| 22:33 | srruby | What are the advantages of using zippers vs postwalk? So far I've just been using postwalk. |
| 22:35 | hola_ | brehaut I can save prior state in any language if I choose to by creating new variables so what's the big win with Clojure? See my example. |
| 22:36 | brehaut | what example |
| 22:37 | hola_ | I'm not trolling. The penny just hasn't dropped as to how immutable data structures automatically save you from anything. |
| 22:37 | brehaut | hola_: nevertheless, what example are you talking about |
| 22:37 | hola_ | (def arr [1 2 3 4]) (def arr (cons 5 arr)) |
| 22:37 | hola_ | The end result is just the same as mutating a variable in, say, Ruby |
| 22:38 | brehaut | hola_: that is not remotely idiomatic clojure. dont use def for storage. |
| 22:39 | brehaut | even with (let [a [1 2 3 4] b (conj a 5)] …) its not the same as in ruby |
| 22:39 | brehaut | because functions you call cannot mutate that vector |
| 22:39 | hola_ | arr = [1, 2, 3, 4] ; arr.unshift 5 |
| 22:40 | hola_ | brehaut There are plenty of tutorials using def for storage |
| 22:40 | brehaut | (let [a [1 2 3] _ (any-function-ever a)) (= a [1 2 3])) ;; true. its completely invariant |
| 22:40 | hola_ | .. and books |
| 22:40 | dsrx | arr = [1, 2, 3, 4]; arr2 = arr; arr.unshift 5 |
| 22:40 | brehaut | hola_: then there are plenty of tutorials that are wrong |
| 22:41 | brehaut | hola_: its useful in a tutorial to explain repl exploration (as i said previously, dev time) but that is in no way how you write a program |
| 22:41 | fortruce | using def to set up initial state for an example is a lot different than using def to change state in the middle of code... |
| 22:42 | hola_ | I can understand if it's idiomatic but what I'm getting at is that the language itself, ie. immutable data structures, doesn't protect you from unintended consequences as Rich Hickey claims. What you're saying is .. only if you know how to write idiomatic Clojure |
| 22:42 | chippie | Can I use (iterate ...) to create a finite lazy-sequence? I have an extremely large sequence of dates, but it is not infinite. Aside from using lazy-seq directly, would the idiomatic way to do this in Clojure be to use (iterate ...), but return nil (or some other "end" marker) once the sequence end is reached, then wrap that with something like take-while? (take-while (complement nil?) (iterate ...)) |
| 22:42 | brehaut | hola_: consider the following JS: var a = [1, 2, 3]; any_function_ever(a); a == [1, 2, 3]; // no way to know if this is true or false |
| 22:43 | brehaut | hola_: go ahead, write all your programs with mutable global storage. its no skin of my nose. |
| 22:44 | hola_ | brehaut If you insert my example in the middle of this in Clojure the result would be the same |
| 22:44 | dsrx | hola_: nobody should or would write code the way you did in that example |
| 22:44 | brehaut | hola_: no, it wouldnt. i used let. let introduces local, signal asignment bind. there is exactly no way in which you could change it |
| 22:44 | brehaut | s/signal/single/ |
| 22:44 | brehaut | anyway its 4:30 on a friday. why am i on the computer |
| 22:44 | hola_ | If you didn't use let it would blow up just the same |
| 22:45 | brehaut | no it wouldnt |
| 22:45 | hiredman | people coming from scheme often think def and let must do the same thing, but in clojure they are very different |
| 22:45 | brehaut | you are welcome to disagree of course, but you'll be wrong |
| 22:46 | alandipert | chippie: i find take-while+iterate pretty common, and use this myself: https://www.refheap.com/30149 |
| 22:46 | chippie | alandipert: Thanks! :) |
| 22:47 | chippie | alandipert: Ah nice pattern |
| 22:48 | alandipert | chippie: i guess it's the same as (take-while pred (iterate f x)), which is a little more straightforward |
| 22:49 | chippie | Nobody really talks about design patterns in functional languages (or at least, there's not a lot of literature out there about them), but they clearly exist. |
| 22:51 | quizdr | I'm getting a null pointer exception on this little code snippet, don't know why: https://gist.github.com/quizdr/8726329 |
| 22:53 | quizdr | if r is nil, then using (r) as a cond should not run that branch in the cond, right? |
| 22:54 | alandipert | ,(nil) |
| 22:54 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)> |
| 22:55 | alandipert | ,(let [x nil] (x)) |
| 22:55 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 22:55 | quizdr | oh my |
| 22:55 | quizdr | ok, thanks |
| 22:55 | quizdr | whoops |
| 22:56 | alandipert | np |
| 22:57 | quizdr | lol I fixed it by doing (not (nil? r)) before realizing that just r by itself would suffice |
| 23:01 | gtrak | anyone know elisp here? #emacs is no help.. . trying to debug a cider thing. read-from-string seems to inexplicably kill further execution. |
| 23:30 | johnjelinek | hihi all, how's it goin'? |
| 23:31 | quizdr | keeping it real, johnjelinek |
| 23:31 | johnjelinek | way to be :) |
| 23:31 | dsrx | i'm keeping it complex, personally |
| 23:31 | johnjelinek | had a question -- are you familiar with clojure.tools.namespace.repl/refresh? |
| 23:31 | quizdr | dsrx well at least you aren't imaginary |
| 23:32 | johnjelinek | I get errors when I try to do (clojure.tools.namespace.repl/refresh) |
| 23:33 | johnjelinek | here's a pastebin of the error: http://pastebin.com/BYxuEB9M |
| 23:33 | johnjelinek | does that look familiar to you? |
| 23:34 | seangrove | Hrm, I'd like to write an html parser in ClojureScript |
| 23:35 | seangrove | Actually, I'd like to use an html parser written in ClojureScript, but I haven't seen any |
| 23:35 | seangrove | Any recommendations for writing a parser in cljs? |
| 23:44 | dsrx | (defn parseHtml [s] (.parseFromString (DOMParser.) s "text/html")) :P |
| 23:44 | dsrx | er parse-html |
| 23:44 | dsrx | ack |
| 23:47 | seangrove | dsrx: Yeah, but I don't want to instantiate any html objects, I only want clojure data structures |
| 23:49 | dsrx | seangrove: ah, i see. there's hickory as well but in cljs it just uses DOMParser internally I think, but only ever returns clojure data structures |
| 23:50 | seangrove | dsrx: Ah, interesting, that looks like exactly what I'd like, but skipping the DOMParser bit. I wonder how the jvm-clj side it handled. Thanks! |
| 23:53 | seangrove | Ah, Jsoup. Damn. |
| 23:58 | cark | parsing html isn't easy considering most of it is malformed |
| 23:59 | seangrove | cark: Yeup. But we'll approach it iteratively |