2015-02-19
| 00:00 | justin_smith | without the eval it looks OK |
| 00:00 | justin_smith | AHA |
| 00:00 | justin_smith | ,((fn [fname & args] (eval (conj () (conj args 'list) (read-string fname) 'apply))) "inc" 2) |
| 00:00 | clojurebot | 3 |
| 00:00 | justin_smith | super-weird |
| 00:00 | justin_smith | haha |
| 00:01 | TEttinger | a ha! |
| 00:01 | justin_smith | TEttinger: it was because you were creating '(2) and passing it to eval |
| 00:01 | TEttinger | ahhhhhh |
| 00:01 | TEttinger | ,((fn [fname & args] (eval (conj () (vec args ) (read-string fname) 'apply))) "inc" 2) |
| 00:01 | clojurebot | 3 |
| 00:02 | sm0ke | ,((fn [fname & args] (apply (eval (read-string fname)) args) "inc" 2) |
| 00:02 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 00:02 | justin_smith | the moral is: eval + conj on lists gets confusing when you have had enough vodka |
| 00:02 | TEttinger | ,((fn [fname & args] (eval (conj () (vec args ) (read-string fname) 'apply))) "+" 2 3 4) |
| 00:02 | clojurebot | 9 |
| 00:02 | sm0ke | ,((fn [fname & args] (apply (eval (read-string fname)) args)) "inc" 2) |
| 00:02 | clojurebot | 3 |
| 00:02 | TEttinger | ah, clever sm0ke |
| 00:02 | TEttinger | (inc sm0ke) |
| 00:02 | lazybot | ⇒ 8 |
| 00:02 | sm0ke | :) |
| 00:02 | TEttinger | ,((fn [fname & args] (apply (eval (read-string fname)) args)) "+" 2 3 4) |
| 00:02 | clojurebot | 9 |
| 00:02 | sm0ke | (inc justin_smith TEttinger ) |
| 00:03 | lazybot | ⇒ 1 |
| 00:03 | TEttinger | inc is still unary |
| 00:03 | sm0ke | hurmm who is getting all those karma points |
| 00:03 | justin_smith | ((fn [fname & args] (apply (resolve (symbol fname)) args)) "inc" 2) |
| 00:03 | justin_smith | (karma justin_smith TEttinger ) |
| 00:03 | sm0ke | (inc justin_smith ) |
| 00:03 | lazybot | ⇒ 6 |
| 00:03 | TEttinger | (identity justin_smith TEttinger ) |
| 00:03 | lazybot | justin_smith TEttinger has karma 1. |
| 00:03 | sm0ke | (inc TEttinger ) |
| 00:03 | lazybot | ⇒ 3 |
| 00:03 | justin_smith | TEttinger: it takes arbitrary strings |
| 00:03 | sm0ke | there you go |
| 00:03 | TEttinger | spaces |
| 00:03 | TEttinger | (identity TEttinger) |
| 00:03 | lazybot | TEttinger has karma 42. |
| 00:04 | justin_smith | notice that "justin_smith " has 1/20th my karma or so |
| 00:04 | justin_smith | (identity justin_smith) |
| 00:04 | lazybot | justin_smith has karma 189. |
| 00:04 | TEttinger | so you're at 195 abouts? |
| 00:04 | TEttinger | we're going to need a 200 karma party |
| 00:04 | TEttinger | (identity technomancy) |
| 00:04 | lazybot | technomancy has karma 162. |
| 00:04 | justin_smith | ,(/ 189.0 6.0) |
| 00:04 | clojurebot | 31.5 |
| 00:04 | TEttinger | (identity Raynes) |
| 00:04 | lazybot | Raynes has karma 55. |
| 00:05 | TEttinger | (identity rhickey) |
| 00:05 | lazybot | rhickey has karma 9003. |
| 00:05 | TEttinger | hahaha |
| 00:05 | justin_smith | oh, only 1/30th! |
| 00:05 | justin_smith | TEttinger: of course it would have to be over 9000 on this channel |
| 00:05 | sm0ke | (dec sm0ke) |
| 00:05 | lazybot | You can't adjust your own karma. |
| 00:06 | sm0ke | (+ 1000 justin_smith ) |
| 00:06 | sm0ke | :P i tried |
| 00:06 | TEttinger | you know, I've been making gfredericks memes, but any meme I made of myself would involve invisible BOMs so it would probably just be... well just as incomprehensible to outsiders |
| 00:07 | justin_smith | TEttinger: haha |
| 00:07 | sm0ke | gfredericks once pm'd me asking not to use offensive language in channel, and all is said was ~sex |
| 00:07 | sm0ke | lazybot: sex? |
| 00:07 | justin_smith | TEttinger: panorama picture of a cat so it looks like his head comes out of his tail "invisible BOM" |
| 00:07 | TEttinger | hahaha |
| 00:08 | TEttinger | ~sex |
| 00:08 | clojurebot | sex is off-topic and not appropriate for the channel |
| 00:08 | sm0ke | see |
| 00:08 | sm0ke | clojurebot: sex |is| never offtopic |
| 00:08 | clojurebot | Ok. |
| 00:08 | sm0ke | clojurebot: ~sex |
| 00:08 | clojurebot | Excuse me? |
| 00:08 | TEttinger | hha |
| 00:09 | TEttinger | no need to clojurebot: |
| 00:09 | sm0ke | ~sex |
| 00:09 | clojurebot | sex is never offtopic |
| 00:09 | sm0ke | quick learner is clojurebot |
| 00:09 | clojurebot | c'est bon! |
| 00:09 | sm0ke | ~clojurebot |
| 00:09 | TEttinger | clojurebot: sex |is| frequently offtopic |
| 00:09 | clojurebot | Ack. Ack. |
| 00:09 | clojurebot | clojurebot has a poetic soul |
| 00:13 | justin_smith | TEttinger: http://i.imgur.com/E5j8fwX.jpg?1 |
| 00:14 | sm0ke | what is BOM? |
| 00:14 | justin_smith | ~BOM |
| 00:14 | clojurebot | Cool story bro. |
| 00:14 | TEttinger | \ufeff |
| 00:14 | TEttinger | byte order marker |
| 00:14 | TEttinger | an invisible character that's legal in clojure and java identifiers |
| 00:17 | sm0ke | BUT then i ask how do you copy and type something which is invisible!!! |
| 00:17 | sm0ke | :D |
| 00:17 | justin_smith | that's exactly the problem |
| 00:19 | TEttinger | ,(let [bindings "should have an even number of forms" bindings "BETTER HAVE AN EVEN NUMBER OF FORMS" bindings] bindings) |
| 00:19 | clojurebot | "should have an even number of forms" |
| 00:20 | TEttinger | I made that with |
| 00:20 | TEttinger | ,(println ",(let [bindings \"should have an even number of forms\"\ufeff bindings \ufeff\"BETTER HAVE AN EVEN NUMBER OF FORMS\"\ufeff bindings] bindings)") |
| 00:20 | clojurebot | ,(let [bindings "should have an even number of forms" bindings "BETTER HAVE AN EVEN NUMBER OF FORMS" bindings] bindings)\n |
| 00:20 | sm0ke | ,(def a b 1) |
| 00:20 | clojurebot | #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)> |
| 00:21 | TEttinger | ,(def ab 1) |
| 00:21 | clojurebot | #'sandbox/ab |
| 00:21 | TEttinger | ,ab |
| 00:21 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ab in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 00:22 | TEttinger | ,ab |
| 00:22 | clojurebot | 1 |
| 00:22 | TEttinger | it's tricky business |
| 00:23 | sm0ke | i was trying to put a ufefs in between :P |
| 00:23 | TEttinger | and I did |
| 00:23 | sm0ke | NO!! |
| 00:23 | sm0ke | ,ab |
| 00:23 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ab in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 00:23 | TEttinger | ,(map char ",(def ab 1)") |
| 00:23 | clojurebot | (\, \( \d \e \f ...) |
| 00:23 | sm0ke | ,ab |
| 00:23 | clojurebot | 1 |
| 00:24 | sm0ke | nice one! |
| 00:24 | TEttinger | ,(map char "ab") |
| 00:24 | clojurebot | (\a \ \b) |
| 00:24 | TEttinger | it doesn't even print the visible character |
| 00:24 | TEttinger | ,(map int "ab") |
| 00:24 | clojurebot | (97 65279 98) |
| 00:25 | TEttinger | it gets crazier once you start needing to enter un-enterable, un-copyable characters |
| 00:25 | TEttinger | I believe some of the early, before space ascii characters have that property |
| 00:26 | sm0ke | imagine someone quietly sneaking these is clojure source code |
| 00:26 | TEttinger | clojurebot: BOM |is| http://i.imgur.com/E5j8fwX.jpg?1 |
| 00:26 | clojurebot | Ack. Ack. |
| 00:26 | TEttinger | ~BOM |
| 00:26 | clojurebot | BOM is http://i.imgur.com/E5j8fwX.jpg?1 |
| 00:26 | sm0ke | like in clojure.\ufeffcore |
| 00:26 | TEttinger | oh man |
| 00:26 | TEttinger | in C# it's even worse |
| 00:26 | TEttinger | you can overload the empty string |
| 00:27 | sm0ke | does github shows a diff for bom? |
| 00:29 | TEttinger | it must, it's different text |
| 00:29 | TEttinger | it would be +1 char |
| 00:29 | sm0ke | hmm lets hope so |
| 00:31 | TEttinger | ah, |
| 00:31 | TEttinger | typeof(string).GetField("Empty").SetValue(null, " "); |
| 00:31 | TEttinger | makes the empty string equal to " " |
| 00:31 | sm0ke | ,(= "ab" "ab") |
| 00:32 | clojurebot | false |
| 00:32 | TEttinger | and worse, that C# code can be stuck in a static constructor, making it run whenever that class is imported |
| 00:33 | sm0ke | i dont know much C# what are you trying to do there? |
| 00:33 | TEttinger | it's from an article on "Code Bombs" |
| 00:33 | TEttinger | things disgruntled employees could stealthily leave behind in code |
| 00:33 | TEttinger | and horribly break a running program |
| 00:34 | TEttinger | http://thedailywtf.com/articles/comments/The-Disgruntled-Bomb in comments |
| 00:34 | justin_smith | oh, the fucked up shit an angry clojurist could do... |
| 00:34 | sm0ke | ah i see! |
| 00:34 | sm0ke | justin_smith: i guess this can be sneaked everywhere |
| 00:35 | TEttinger | there's a good reason for it too |
| 00:35 | TEttinger | I actually added a bomb in some code I sent to a previous employer (in a different country), but I told them I had inserted the bomb, and would forward the source, without bomb, once payment cleared. This could be re-purposed. |
| 00:35 | justin_smith | sm0ke: in clojure there is very little you couldn't redefine out from under a running process, as a side effect of just loading your ns |
| 00:35 | prateekp | lein deps failed |
| 00:35 | prateekp | cannot find project.cljs |
| 00:35 | TEttinger | prateekp: lein deps :tree |
| 00:35 | TEttinger | oh |
| 00:36 | TEttinger | well that would be a problem then |
| 00:36 | justin_smith | project.cljs? |
| 00:36 | justin_smith | is that even a thing? |
| 00:36 | TEttinger | where are you putting your deps? |
| 00:36 | prateekp | the project.cljs is not in the root |
| 00:36 | TEttinger | it should be project.clj I would imagine |
| 00:36 | justin_smith | wait, lein can even use "project.cljs" I have never even heard of that |
| 00:36 | TEttinger | but I guess it can huh |
| 00:36 | justin_smith | and also why would you not put it in the root |
| 00:36 | prateekp | clj* |
| 00:36 | TEttinger | it needs to be in root |
| 00:37 | TEttinger | or wherever you're executing lein from |
| 00:37 | prateekp | its in the root of the client folder ... but travis cant access it as .travis.yml is in the root of the repo |
| 00:38 | TEttinger | is this on github or something where we can see it? |
| 00:38 | TEttinger | (the code I mean, prateekp) |
| 00:39 | prateekp | i am very sorry, the code is private actually |
| 00:39 | prateekp | but i can tell you |
| 00:39 | prateekp | the situation |
| 00:39 | justin_smith | prateekp: if the project.clj can't be in the root, can you tell travis to run lein from a subdirectory containing the lein project? |
| 00:40 | prateekp | ohh yeah but while i am doing cd folder/ && lein cljsbuild once in the .travis.yml |
| 00:40 | prateekp | its giving same error |
| 00:41 | sm0ke | TEttinger: and how do you know they wont be able to find it? |
| 00:41 | prateekp | justin_smith: is there other way to do it |
| 00:41 | sm0ke | TEttinger: you must have put it differently ? sounds very unprofessional |
| 00:41 | TEttinger | sm0ke, it's a quote from that article |
| 00:41 | TEttinger | err, comments |
| 00:42 | sm0ke | eh ok lol |
| 00:43 | TEttinger | sm0ke, he talks about how it slowly, over the course of 15-30 minutes, got slower and slower to the point of unusability. it let them verify the trial version, but not ship until payment cleared |
| 00:43 | justin_smith | prateekp: if you are having travis switch to the directory containing the project.clj, and lein doesn't find the project.clj, there is clearly something wrong that you haven't described yet |
| 00:43 | sm0ke | TEttinger: DRM is hight controvertial |
| 00:43 | sm0ke | highly* |
| 00:44 | TEttinger | yeah, but most people want to get paid, and some unscrupulous buyers won't pay if they think they can get away with cheating a foreigner |
| 00:44 | sm0ke | i would just prefer to deal with customers who can be trusted |
| 00:44 | justin_smith | prateekp: I assume the cd / lein commands are in one shell invocation? because usually each command is totally isolated |
| 00:46 | prateekp | i did like this |
| 00:46 | prateekp | language: clojure |
| 00:46 | prateekp | script: cd client && lein cljsbuild once && cd assets && compass compile |
| 00:46 | prateekp | these are two commands i am using |
| 00:47 | prateekp | in .travis.yml |
| 00:48 | justin_smith | and lein complains that it can't find project.clj? |
| 00:49 | prateekp | justin_simth: ^^ |
| 00:49 | prateekp | yes |
| 00:50 | justin_smith | prateekp: the line "language: clojure" tells travis to run lein test |
| 00:50 | justin_smith | you should take that out, it is causing your error |
| 00:50 | justin_smith | because of course lein test from the top level will fail |
| 00:51 | prateekp | ahh |
| 00:51 | prateekp | so i should keep only the script command |
| 00:51 | justin_smith | right, "language: clojure" is just a shortcut for some default things to do with clojure code |
| 00:51 | justin_smith | you may want to add what it would have done to your script |
| 00:52 | prateekp | ahh thanks |
| 00:56 | TEttinger | (inc justin_smith) |
| 00:56 | lazybot | ⇒ 190 |
| 00:58 | prateekp | while i am trying to run a project locally, i am getting an error - Could not locate leiningen/core/main__init.class or leiningen/core/main.clj on classpath |
| 00:58 | justin_smith | when using lein? |
| 01:00 | prateekp | yeah when building locally |
| 01:00 | justin_smith | sounds like a messed up config - can you run "lein help" outside your project dir? |
| 01:01 | prateekp | outside in the home folder, it gives out a list of commands |
| 01:02 | justin_smith | prateekp: yeah, probably something misconfigured in your project.clj |
| 01:02 | prateekp | and a error |
| 01:02 | prateekp | Problem loading: java.io.FileNotFoundException: Could not locate leiningen/core/main__init.class or leiningen/core/main.clj on classpath: (localrepo.clj:1) |
| 01:02 | justin_smith | OK, then disable lein localrepo |
| 01:02 | prateekp | it gives the same error outside |
| 01:02 | justin_smith | lein localrepo is nearly useless nowadays anyway |
| 01:02 | prateekp | how should i do that |
| 01:02 | prateekp | is there a coomad |
| 01:03 | justin_smith | it's a plugin, likely in your ~/.lein/profiles.clj |
| 01:04 | justin_smith | it's probably not compatible with newer lein versions - and AFAIK it isn't needed |
| 01:05 | prateekp | there is no profiles.clg |
| 01:06 | prateekp | though there was a plugin localpro tar which i deleted |
| 01:06 | prateekp | but still the same error persists |
| 01:07 | justin_smith | OK, something somewhere is telling lein to use localrepo |
| 01:07 | justin_smith | usually it would be ~/.lein/profiles.clj that set that up |
| 01:07 | justin_smith | what's your $LEIN_HOME setting in your shell? |
| 01:08 | prateekp | ahh i did echo $LEIN_HOME |
| 01:08 | prateekp | it says nothing |
| 01:09 | justin_smith | OK, that's normal, but that means I have no idea what would be trying to load localrepo |
| 01:10 | justin_smith | and that error clearly indicates localrepo |
| 01:10 | prateekp | hmm |
| 01:11 | prateekp | justin_smith : regarding the previous problem, it failed again saying lein not found |
| 01:11 | prateekp | should i write lein: lein in .travis.yml |
| 01:12 | justin_smith | prateekp: you should try to find out what "lang: clojure" does in travis.yml, and recreate that without the part where project.clj has to be at the top level |
| 01:17 | prateekp | justin_smith : now the error looks different - Could not locate leiningen/core/main__init.class or leiningen/core/main.clj on classpath: |
| 01:18 | prateekp | its not related to localpro |
| 01:18 | prateekp | its subproject.clj:1 |
| 01:19 | justin_smith | OK why do you keep getting errors with lein plugins when you claim that you don't have any profiles.clj? |
| 01:19 | justin_smith | subproject.clj is from lein-sub |
| 01:20 | justin_smith | what's your lein version? |
| 01:20 | prateekp | 1.7.1 |
| 01:20 | justin_smith | OK, do you have any reason to be using a version that old? |
| 01:21 | prateekp | just did sudo apt-get |
| 01:21 | justin_smith | don't use the apt-get version of lein, install lein 2.x and let it auto-update. Best place to install it is to ~/bin |
| 01:21 | justin_smith | 1.x is bad |
| 01:22 | prateekp | ok |
| 01:22 | justin_smith | lein is one of the few programs that manages it's own updates better than apt |
| 01:22 | justin_smith | because it is very self contained, and good at handling updates / rollbacks |
| 01:23 | justin_smith | as long as you install it locally / per -user |
| 01:24 | prateekp | what path should i choose to install lein |
| 01:24 | prateekp | any path is ok_? |
| 01:24 | prateekp | ? |
| 01:24 | justin_smith | your home bin/ dir is best I think ~/bin |
| 01:24 | justin_smith | but as long as it's in your PATH it will work |
| 01:24 | prateekp | is /bin ok |
| 01:25 | justin_smith | no, it should be owned by your user |
| 01:27 | prateekp | justin_simth |
| 01:27 | prateekp | how to run it |
| 01:28 | prateekp | i have saved and chmod 755 the lein file |
| 01:28 | prateekp | in the ~/bin floder |
| 01:28 | justin_smith | you need to add ~/bin to your PATH |
| 01:28 | justin_smith | some shells do this automatically when you log in if the directory exists |
| 01:28 | justin_smith | which file to edit depends on your current setup / shell |
| 01:29 | justin_smith | likely .login / .profile / .bashrc |
| 01:29 | justin_smith | one of those |
| 01:30 | prateekp | i have added path |
| 01:30 | prateekp | now how do i run it |
| 01:31 | justin_smith | lein |
| 01:31 | prateekp | ahh |
| 01:31 | justin_smith | if it's in your path, it's just lein |
| 01:31 | prateekp | hmm ] |
| 01:31 | prateekp | its running |
| 01:31 | prateekp | and thats it |
| 01:31 | justin_smith | yeah, probably doing a big self-install for its first run |
| 01:32 | prateekp | do i need any other thing now |
| 01:32 | justin_smith | you should be able to run your lein commands now |
| 01:32 | prateekp | hmm i have started the build |
| 01:33 | prateekp | lets see if it passes this time |
| 01:34 | prateekp | hmm its working |
| 02:16 | prateekp | i am sorry ... i am, asking the same problem which i asked before ... |
| 02:17 | prateekp | actually i am trying to run travis for clojure project |
| 02:18 | prateekp | for travis to run, we have to keep the .travis.yml file at the root but the project.clj file in in another folder |
| 02:19 | prateekp | so when i try to do script : cd folder/ && lein cljsbuild test |
| 02:19 | prateekp | the travis tells cannot find the file named project.clj |
| 02:19 | luxbock | thoughts on using the discard macro (#_) for documentation? |
| 02:20 | prateekp | is the command in travis.yml -- language: clojure is running something that calls project.clj |
| 02:20 | prateekp | how can i know what does this command do |
| 02:21 | luxbock | one could use it a bit like /* ... */ is used in Java, but without having to add *'s for each line |
| 02:31 | Kneiva | Java does not require * for each line |
| 02:32 | TEttinger | luxbock: since it's very similar to ; just for forms instead of until-end-of-line, I like #_ in general |
| 02:32 | TEttinger | and since ; is used for comments, I see no reason discard couldn't be adapted to comments |
| 03:26 | lxsameer_ | what testing framework is more popular in clojure community ? |
| 03:27 | slipset | lxsameer_: midje? |
| 03:27 | slipset | lxsameer_: or even test.check which is property based |
| 03:27 | slipset | I kinda like midje with its auto-test stuff |
| 03:27 | slipset | whenever you save your file, midje runs all your tests |
| 03:28 | Empperi | midje is nice but plain ol' clojure.test isn't that bad either |
| 03:28 | Empperi | midje has this problem about crapping the line numbers when your code throws an exception |
| 03:28 | Empperi | when it breaks on assertion then it's great |
| 03:32 | lxsameer_ | Empperi: slipset thanks guys |
| 03:38 | domokato | What is a possible reason for a NullPointerException on a java method call during compile time? |
| 03:38 | domokato | it's on the top-level of a namespace; is that okay? |
| 03:40 | TEttinger | domokato, one of the arguments or the object that you're calling it ob must be null somewhere |
| 03:40 | TEttinger | *on must |
| 03:41 | TEttinger | stick a println before it, see what the values are |
| 03:41 | domokato | but this is during compile time |
| 03:45 | domokato | oh, it actually runs the code during compile time...crazy |
| 03:45 | domokato | there's my problem |
| 03:45 | domokato | thx |
| 03:45 | TEttinger | cool! |
| 04:04 | mnngfltg | Has anyone tried persisting Clojure's persistent data structures on disk? |
| 04:09 | mnngfltg | Basically I'd like to keep a PersistentHashMap in an atom and, on swap!, commit changes to the map to disk |
| 04:09 | slipset | wouldn't that just be to prn it to a file? |
| 04:10 | slipset | if you add a watcher to the atom? |
| 04:10 | slipset | but, you will probably have some problems going that way because you can have several swaps before you finish writing to disk |
| 04:11 | slipset | sounds like you want a databse |
| 04:12 | mnngfltg | slipset, yes, I bsically want to implement my own embedded database |
| 04:12 | hyPiRion | mnngfltg: This sounds like a subset of Datomic |
| 04:12 | slipset | mnngfltg: now why would you want to do that? |
| 04:12 | hyPiRion | oh, embedded |
| 04:13 | mnngfltg | hyPiRion, I haven't loooked into datomic yet |
| 04:13 | mnngfltg | but yes, the idea would be to keep things as simple as possible |
| 04:13 | mnngfltg | sort of like sqlite or h2 but with the ability to persisten clojures's maps, vectors and sets |
| 04:13 | mnngfltg | slipset, I think it fills an interesting niche |
| 04:13 | hyPiRion | mnngfltg: I'd love to have something like an embedded datomic. I've looked at it and haven't found anything though |
| 04:14 | hyPiRion | after it* |
| 04:14 | mnngfltg | slipset, basically you could use it to power a simple multithreaded web server with a very flexible data model |
| 04:15 | mnngfltg | the whole dataset (app state) is in memory, in an atom, and each to you (swap!) the updates are committed to disk |
| 04:15 | mnngfltg | presumably using some kind of commit log, so if you restart the app can re-build its state |
| 04:17 | mnngfltg | hyPiRion, I've found http://www.mapdb.org/, which might be a nice base for a clojure-centric embedded db |
| 04:55 | dysfun | mnngfltg: i've got something going along those lines myself |
| 04:56 | dysfun | not using mapdb, doing basically what you described |
| 04:58 | piranha | what's the benefit of using ref instead of atom? I have a bit of code which uses ref, and I mostly used atoms (most of my clojure code was clojurescript), so I'm wondering what's the point |
| 04:59 | kungi | piranha: refs are coordinated atoms are not |
| 05:00 | piranha | kungi: and 'coordinated' means that I can change two refs at the same time in 'dosync', right? |
| 05:00 | piranha | that's the point of using a ref? |
| 05:00 | piranha | and if I only have a single ref, it could as well be an atom? |
| 05:01 | kungi | piranha: as far as i see. yes and yes |
| 05:01 | piranha | kungi: cool, thanks! |
| 05:01 | clgv | piranha: yeah consistence of modifications of multiple refs |
| 05:01 | kungi | piranha: when I think about refs I always think about bank accounts. Transfer money from account a to b |
| 05:02 | piranha | ok :) |
| 05:03 | ianhedoesit | the clojure.org pages on them (http://clojure.org/atoms and http://clojure.org/refs) give pretty good descriptions, I think. |
| 05:03 | clgv | ianhedoesit: the books do a better job ;) |
| 05:03 | ianhedoesit | I'd hope so, since the page on atoms is only three short paragraphs! |
| 05:04 | piranha | that's mainly why I asked :) |
| 05:04 | ianhedoesit | but for a quick "spot the difference" it's pretty useful, I think. |
| 05:05 | kungi | Until now I never had to use a ref ... |
| 05:05 | piranha | oh, I just found out why the code uses refs and it makes sense |
| 05:06 | piranha | it needs to 'return and remove first element of contents', atomically |
| 05:06 | clgv | ianhedoesit: I'd say that one serves better for that purpose http://clojure-doc.org/articles/language/concurrency_and_parallelism.html#clojure-reference-types |
| 05:06 | piranha | and with ref it's wrapped in dosync, which makes it work |
| 05:07 | ianhedoesit | clgv: that is pretty nice! definitely more detailed. |
| 05:07 | ianhedoesit | (well, with a quick glance) |
| 05:08 | clgv | they gathered a decent amount of clojure knowledge overthere |
| 05:08 | dysfun | piranha: return and remove is an atomic operation |
| 05:09 | piranha | dysfun: (let [x (first @pool)] (swap! pool rest) x) is not exactly atomic, is it? |
| 05:09 | clgv | dysfun: not really with Clojure atoms, as swap! returns what is written into the atom |
| 05:09 | piranha | dysfun: it makes it possible that two threads will get same item from pool simultaneously |
| 05:10 | dysfun | i didn't say it was the best option, merely that it's atomic |
| 05:10 | ianhedoesit | piranha: I don't think that's possible? |
| 05:10 | dysfun | and the swap! can be wrapped |
| 05:10 | dysfun | but yes, using refs here is a better option |
| 05:10 | piranha | ianhedoesit: why not? |
| 05:12 | ianhedoesit | I don't know. give me a minute to be silent until someone else says I'm wrong |
| 05:19 | julianleviston | If I want to access a piece of data in a map from multiple keys, is a good way to do that just to assoc the data in (inside a map which includes all the keys) multlpe times, once against each of the keys? |
| 05:19 | clgv | dysfun: you'd need a modified swap! implementation that lets you choose which value to return on successfull modification of the atom |
| 05:20 | julianleviston | clgv: it’s not being stored in an atom |
| 05:21 | clgv | julianleviston: I didn't answer you ;) |
| 05:21 | julianleviston | clgv: oh haha soz :) |
| 05:22 | clgv | julianleviston: you need to provide some kind of example to explain what you want to do |
| 05:22 | julianleviston | clgv: ok. I’ll build one. |
| 05:22 | wagjo | clgv: dysfun: something like https://github.com/flatland/useful/blob/develop/src/flatland/useful/state.clj#L43 |
| 05:22 | TEttinger | a multimap? |
| 05:24 | clgv | wagjo: not really, but could serve as a blueprint how to achieve the desired result |
| 05:24 | dysfun | clgv: actually you need a second atom or a promise :) |
| 05:24 | clgv | wagjo: though it is actually cheating ;) |
| 05:24 | dysfun | clgv: as i said, ref is a better option in this case |
| 05:25 | clgv | dysfun: I guess you cant make a general function for it - it would need to be a macro to be able to select an arbitrary return value and not to do computations twice |
| 05:29 | julianleviston | clgv: here’s my pastie illustrating what I’m after… it feels a bit messy because I’m duplicating data. On the other hand, in the context I’m using it in, I don’t have to update the data, so perhaps that’s not important: https://www.refheap.com/97520 |
| 05:29 | julianleviston | clgv: also, will there be any problems if the value at :data is a core async channel, do you think? |
| 05:30 | julianleviston | TEttinger: oh, were you talking to me? |
| 05:30 | TEttinger | yes, sorry |
| 05:30 | dysfun | clgv: i don't think it would need to be. but since refs are a better option in this case, i have no real desire to see if it can be done :) |
| 05:31 | julianleviston | TEttinger: ah… A multimap is multiple values, isn’t it? I want multiple keys... |
| 05:31 | julianleviston | TEttinger: as in… two paths into the values… |
| 05:33 | julianleviston | TEttinger: I mean, my proof-of-concept code there would work, it just feels ugly. |
| 05:33 | wagjo | you can have multiple keys pointing into the same data in classic hash-map |
| 05:34 | julianleviston | wagjo: I don’t follow, sorry… what’s classic hash-map ? |
| 05:34 | ianhedoesit | ,{:a 5 :b 5} |
| 05:34 | clojurebot | {:b 5, :a 5} |
| 05:34 | julianleviston | ah so just how i’m doing it? |
| 05:34 | wagjo | ,(let [data :foo] {:a data :b data}) |
| 05:34 | clojurebot | {:a :foo, :b :foo} |
| 05:35 | julianleviston | wagjo: https://www.refheap.com/97520 <— just what I’ve done, then… but would that work with (chan)s, too? |
| 05:35 | TEttinger | yeah, objects are references anyway |
| 05:35 | julianleviston | TEttinger: ah ok… I wasn’t 100% sure about that,… now I know that, that completely answers my question… :) |
| 05:35 | julianleviston | (inc TEttinger) |
| 05:35 | lazybot | ⇒ 43 |
| 05:35 | julianleviston | (inc wagjo) |
| 05:35 | lazybot | ⇒ 2 |
| 05:35 | TEttinger | (inc wagjo) |
| 05:35 | lazybot | ⇒ 3 |
| 05:36 | wagjo | thanks, but I'm a bit lost what's the problem you are trying to solve |
| 05:36 | mnngfltg | dysfun, sounds great |
| 05:37 | mnngfltg | dysfun, anything public already? |
| 05:37 | dysfun | mnngfltg: nothing yet, sadly. i've been debating how to handle it. i want any number of interesting properties |
| 05:38 | dysfun | and then i got bogged down with the layer i'm going to sit on top |
| 05:38 | julianleviston | wagjo: In a go-loop, I’m accumulating a map of debounce chans that pass messages off to a worker chan, and they also have an expiration timestamp on them… so I’d like to be able to look them up via timestamp, or via “id” (internal representation)… in the accumulation/message passing part, it needs to look it up via ID, and in the expiry phase it needs to filter by timestamp and then dissoc them. :) |
| 05:38 | mnngfltg | dysfun, I've been having this conversation with myself as well |
| 05:38 | dysfun | mnngfltg: we should collaborate |
| 05:38 | mnngfltg | totally |
| 05:39 | dysfun | i'll query you in a few once i've done the next item on my todo list |
| 05:39 | mnngfltg | cool |
| 05:39 | julianleviston | wagjo: if I needed to update the value of these keys, this solution wouldn’t work very well, but luckily I don’t, so it should be ok. Messy as it is. |
| 05:40 | TEttinger | ,(let [atm (atom 100) colll {:a atm b :atm}] (do (swap! atm inc) (reset! (:a coll) 5) (:b coll))) |
| 05:40 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:40 | TEttinger | ,(let [atm (atom 100) colll {:a atm :b :atm}] (do (swap! atm inc) (reset! (:a coll) 5) @(:b coll))) |
| 05:40 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: coll in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:40 | TEttinger | ,(let [atm (atom 100) coll {:a atm :b :atm}] (do (swap! atm inc) (reset! (:a coll) 5) @(:b coll))) |
| 05:40 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.concurrent.Future> |
| 05:40 | TEttinger | wat |
| 05:40 | TEttinger | ,(let [atm (atom 100) coll {:a atm :b atm}] (do (swap! atm inc) (reset! (:a coll) 5) @(:b coll))) |
| 05:40 | clojurebot | 5 |
| 05:40 | julianleviston | :atm |
| 05:40 | julianleviston | yeah :) |
| 05:40 | TEttinger | there you go |
| 05:40 | TEttinger | I'm getting sleepy |
| 05:40 | TEttinger | you see it's the same atom, referenced by a and b |
| 05:41 | CookedGryphon | Hey, I'm trying to redef async/timeout to a mock timeout provider that I have control of in my tests |
| 05:41 | julianleviston | TEttinger: if you’re talking to me, yeah, I get it. I just think it’s a messy way to do it. |
| 05:41 | CookedGryphon | but my redeffed function isn't getting used |
| 05:41 | julianleviston | TEttinger: it’s fine for what I want to do tho... |
| 05:41 | TEttinger | oh sorry yes, julianleviston. I'm getting quite sleepy and I hope that helped |
| 05:42 | julianleviston | TEttinger: thanks! :) |
| 05:42 | TEttinger | time for another attempt to get more than 3 hours sleep |
| 05:43 | CookedGryphon | does with-redefs work with async/timeout, or not because of something with the go macro? |
| 05:46 | wagjo | julianleviston: how do you plan to lookup data by the timestamp anyway |
| 05:48 | wagjo | julianleviston: model your incoming messages as {:id "1d43e98a", :expiration 14563213, :payload {...}} |
| 05:48 | julianleviston | wagjo: yeah, that was my plan. |
| 05:48 | wagjo | julianleviston: that way you can easily filter by timestamp any message you've selected in the previous step... |
| 05:49 | julianleviston | wagjo: that’s what I’m doing. |
| 05:55 | julianleviston | wagjo: the main thing I was wondering was whether there was a data structure I wasn’t aware of in some library such as contrib because my googling turned up nothing other than multimaps… but it seems not… all good :) |
| 05:56 | sveri | Hi, I remember there was a caching / memoization library that emptied the cache after a given time. But I don't recall the name, anyone knows what I mean? |
| 05:56 | julianleviston | sveri: core.cached |
| 05:56 | CookedGryphon | Could someone take a look at my attempt to mock core async timeouts for testing and let me know what's going wrong: https://gist.github.com/AdamClements/33ef8d6ac9a65e9361ae |
| 05:57 | julianleviston | sveri: sorry cache… not cached. https://github.com/clojure/core.cache |
| 05:58 | CookedGryphon | core.cache is caching primitives, core.memoize uses core.cache to memoize functions |
| 05:58 | sveri | julianleviston: Hm, I think it was a different one |
| 05:59 | sveri | ah, it was core.memoize with the ttl function |
| 05:59 | sveri | CookedGryphon: julianleviston thank you both |
| 06:07 | mnngfltg | This puts the `:end` at the beginning rather than the end: (conj (take 5 (range 10)) :end) -- what's the idiomatic way to fix this? |
| 06:07 | mnngfltg | There doesn't seem to be a `takev`... |
| 06:08 | hyPiRion | mnngfltg: if you can afford to retain some semantic garbage, then (conj (subvec (vec (range 10)) 0 5) :end) |
| 06:08 | hyPiRion | which should be equal to this |
| 06:08 | hyPiRion | ,(-> (range 10) vec (subvec 0 5) (conj :end)) |
| 06:08 | clojurebot | [0 1 2 3 4 ...] |
| 06:09 | hyPiRion | ,(-> (range 10) vec (subvec 0 4) (conj :end)) |
| 06:09 | clojurebot | [0 1 2 3 :end] |
| 06:09 | mnngfltg | ah so a solution would be replacing take w/ subvec (and use mapv before instead of map I guess) |
| 06:11 | mnngfltg | hyPiRion, it is a significant amount of semantic garbage though |
| 06:15 | CookedGryphon | no core.async experts around today? |
| 06:17 | AeroNotix | give CookedGryphon ask |
| 06:17 | AeroNotix | ,ask |
| 06:17 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ask in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 06:17 | AeroNotix | ~ask |
| 06:17 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 06:17 | AeroNotix | CookedGryphon: ^^ |
| 06:17 | CookedGryphon | AeroNotix: I already asked, see a few lines back |
| 06:18 | CookedGryphon | Could someone take a look at my attempt to mock core async timeouts for testing and let me know what's going wrong: |
| 06:18 | CookedGryphon | https://gist.github.com/AdamClements/33ef8d6ac9a65e9361ae |
| 06:42 | CookedGryphon | ah, I think I know what's going wrong. With-redefs is putting the var back before it's even been called because the go loop returns immediately and we fall out of the end of the redef scope |
| 06:44 | CookedGryphon | lvh: Just reading your blog post on the fn type of timeout, I'm curious, did you finish your clock implementation? It sounds like you were trying to do exactly what I'm trying to do now |
| 06:45 | kaplan_ | Hi, can anyone explain Refs to me? |
| 06:54 | mnngfltg | What do you think of this general `constrain` function usable for, say, adding ellipses to a truncated seq? https://gist.github.com/pesterhazy/af12a5f85355f5c80358 |
| 07:00 | wagjo | mnngfltg: straightforward but not very efficient |
| 08:15 | sameerynho | what is the pattern in libraries for getting global values for example api key |
| 08:17 | mnngfltg | wagjo, consise but truthful |
| 08:27 | Glenjamin | sameerynho: generally they should be passed as the first argument to api calls |
| 08:28 | sameerynho | Glenjamin: thanks |
| 08:28 | Glenjamin | (let [config {:api-key "ASDASDASD"}] (api/call config and other arguments)) |
| 08:30 | ordnungswidrig | glenjamin: if you want to enable threading then you might want the config on second position. |
| 08:31 | ordnungswidrig | sameerynho: I think another typical case is to bind a dynamic variable and to provide a `with-foo` macro. |
| 08:31 | Glenjamin | i'd say if you want to do a dynamic var, have that as an api which wraps a first-arg internal version |
| 08:31 | sameerynho | thanks |
| 08:32 | Glenjamin | i know the clojurewerkz projects are going down the first-arg route: http://clojureelasticsearch.info/articles/getting_started.html#querying |
| 08:33 | ordnungswidrig | Glenjamin: it depend on whether you'll need to pass the argument around a lot. |
| 08:33 | ordnungswidrig | Glenjamin: but on the library-level I'd go with explicity args |
| 08:33 | Glenjamin | yeah, can always wrap that in other API styles |
| 09:02 | pandeiro | anyone using httpkit w/ websockets noticed that the on-close handler isn't called when a browser window refreshes (expected behavior would be to close socket connection and then re-establish)? |
| 09:05 | ordnungswidrig | every browser? |
| 09:08 | pandeiro | ordnungswidrig: no, just chrome yeah |
| 09:08 | pandeiro | found this: http://code.google.com/p/chromium/issues/detail?id=51687&q=websocket&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20OS%20Area%20Feature%20Status%20Owner%20Summary |
| 09:08 | ordnungswidrig | pandeiro: I wonder whether this could be a feature. Is the websocket kept alive? |
| 09:08 | pandeiro | so it's chromium |
| 09:09 | pandeiro | ordnungswidrig: yes it appears to be |
| 09:09 | pandeiro | from that bug report seems only firefox implements the expected behavior |
| 09:09 | ordnungswidrig | pandeiro: which is unfortunate in the case of browser shutdown. you will either lower some timeout or fight the idling sockets on the server. |
| 09:10 | pandeiro | ordnungswidrig: yeah it means i have to do more bookkeeping |
| 09:10 | pandeiro | ordnungswidrig: even browser refresh presents a problem, i have duplicate entries for the same client id |
| 09:11 | ordnungswidrig | pandeiro: can you drop the old one? Except when you want to support mutliple windows from one browser, then this will fail |
| 09:11 | pandeiro | ...and using core.async channels to broadcast events i get errors about exceeding the number of put!s b/c of these 'ghost' connections |
| 09:12 | pandeiro | ordnungswidrig: yeah it's just a question of looking for the client-id each time a connection is established |
| 09:12 | pandeiro | and probably implementing some sort of a timeout |
| 09:12 | pandeiro | which i don't want to do (maybe the browser is just idle) |
| 09:13 | ordnungswidrig | pandeiro: that opens a can of worms, you'd need to make the browser send keep alive requests etc. |
| 09:14 | justin_smith | this stuff will all change with http/2 right? |
| 09:15 | pandeiro | justin_smith: no idea, will it? |
| 09:16 | pandeiro | i wonder if sente has any logic to clear this up... |
| 09:16 | ordnungswidrig | not sure, http/2 changes are mostly on the "transbport" layer. instead of opening multiple tpc connections it will multiplex over a single connection. |
| 09:16 | ordnungswidrig | which allows the server to send out-out-band responses to prefetch resources. |
| 09:17 | ordnungswidrig | I guess websockets will be multiplexed over that connection too and should behave like now |
| 09:23 | julianleviston | Hooray! My debouncing core async chan is working really nicely! :) |
| 09:37 | AeroNotix | ordnungswidrig: problem with "just drop the old one" is multiple services |
| 09:38 | AeroNotix | we are solving a similar problem in Erlang, and erlang has built in tools for stuff like this. I wonder what Clojure has. |
| 09:39 | AeroNotix | The safest bet is to use Zookeeper or something to manage the connection registration |
| 09:42 | ordnungswidrig | areonotix: not sure but zookeeper might be to slow. |
| 09:42 | AeroNotix | I said "safest" not fastest |
| 09:42 | AeroNotix | It really depends what you're after |
| 09:43 | AeroNotix | with our erlang solution we use pg2 (built in Erlang distributed process registry, it's AP) |
| 09:43 | ordnungswidrig | AP? |
| 09:43 | AeroNotix | as in CAP |
| 09:44 | AeroNotix | favouring availability and partition tolerance |
| 09:44 | AeroNotix | instead of consistency |
| 09:44 | AeroNotix | with pg2 after a netsplit, for example, the registry on different nodes is different. |
| 09:44 | AeroNotix | but it works for us, we have 7k registrations some times and the 95th percentile is 800ms on EC2 with 4 nodes. |
| 09:45 | AeroNotix | a registration needs to do an erlang message to each node |
| 09:45 | AeroNotix | ordnungswidrig: I'd love to see what there is in the Clojure space for this. |
| 09:45 | AeroNotix | 7k in the space of 1s I mean |
| 09:46 | AeroNotix | Akka probably has something like this right? |
| 09:46 | AeroNotix | I didn't look into it much |
| 09:46 | julianleviston | AeroNotix: wow |
| 09:46 | AeroNotix | julianleviston: yeah we handle a lot of websocket connections |
| 09:46 | AeroNotix | we use Erlang though |
| 09:47 | AeroNotix | it's great for this |
| 09:47 | julianleviston | AeroNotix: yeah, that’s it’s perfect use case |
| 09:47 | AeroNotix | indeed |
| 09:47 | AeroNotix | I'd really love to use Clojure simply because I hate Erlang otherwise :) |
| 09:47 | julianleviston | AeroNotix: there’s not really a dist soln for clojure yet is there... |
| 09:47 | julianleviston | AeroNotix: yeah, it’s a bit GUHHHHHH to code in, isn’t it |
| 09:47 | AeroNotix | I don't know if there's something specifically for Clojure, but I'm sure you could use Akka |
| 09:48 | ordnungswidrig | AeroNotix: I think akka is what is used most likely. maybe hazelcast can be used |
| 09:48 | AeroNotix | ordnungswidrig: this could work |
| 09:48 | AeroNotix | what are the failure semantics? |
| 09:49 | julianleviston | AeroNotix: http://joxa.org ? |
| 09:49 | julianleviston | hehe ;-) |
| 09:49 | AeroNotix | it doesn't mention on the front page whether it's CP or AP |
| 09:49 | AeroNotix | julianleviston: it's fine, LFE is more popular. But none of them are anything like Clojure. |
| 09:49 | julianleviston | AeroNotix: yeah fair enough :) |
| 09:50 | mbac | zookeeper seems to have fared well in the call me maybe series |
| 09:50 | AeroNotix | mbac: indeed! |
| 09:50 | AeroNotix | but it's throughput might be quite bad |
| 09:50 | AeroNotix | I don't see you being able to add/remove keys to ZK in the way we want to for example |
| 09:51 | mbac | maybe if you could federate the zookeeper namespaces across sub-zookeepers? :) |
| 09:51 | AeroNotix | e.g. 7k add/removes a second |
| 09:51 | mbac | that's one scaling strategy... |
| 09:51 | AeroNotix | mbac: so you mean sharding an already distributed kv store :) |
| 09:51 | julianleviston | AeroNotix: Last I heard Rich was still saying distributed computing was “an area of interest” I wonder if he’s hammock’d up anything amazing yet? :) |
| 09:51 | AeroNotix | julianleviston: I would *love* to see what Rich comes up with |
| 09:51 | mbac | AeroNotix: i don't think i mean sharding |
| 09:52 | AeroNotix | mbac: you mean having different namespaces on different ZK clusters? |
| 09:52 | ordnungswidrig | Is zookeeper AP or CP? |
| 09:52 | julianleviston | AeroNotix: I really liked that pretty much the first thing you build in the book on erlang that joe armstrong wrote was a distributed bouncing ball… lol |
| 09:52 | ordnungswidrig | or can you configurE? |
| 09:52 | AeroNotix | ordnungswidrig: massively CP |
| 09:52 | mbac | i think i mean that you can decide some sections of the zookeeper namespace are delegated to other zookeepers |
| 09:52 | mbac | sort of like dns |
| 09:52 | mbac | that is, it would be nice if this existed |
| 09:52 | AeroNotix | julianleviston: ignore Joe Armstrong as much as possible |
| 09:52 | mbac | i have no idea if it does |
| 09:53 | AeroNotix | he's an out of touch fool that spouts cliches and memes over and over. |
| 09:53 | julianleviston | AeroNotix: really? haha what in preference? and why? :) |
| 09:53 | julianleviston | AeroNotix: ah… ok lol. |
| 09:53 | AeroNotix | I've spoken to him a few times, he really has no clue about modern Erlang development at all. |
| 09:53 | mbac | ordnungswidrig: according to this https://aphyr.com/posts/291-call-me-maybe-zookeeper it's CP |
| 09:53 | julianleviston | oh Akka has clojure bindings |
| 09:54 | AeroNotix | mbac: ordnungswidrig definitely CP. |
| 09:54 | ordnungswidrig | for websocket registration, could you use something like cassandra? would that make sense? |
| 09:54 | AeroNotix | ordnungswidrig: AP, massive row mutation, imagine the tombstones/compaction on that. |
| 09:55 | AeroNotix | worth a try but the operational overhead might be massive |
| 09:55 | ordnungswidrig | hmm, maybe in a memory only mode :-) |
| 09:55 | AeroNotix | as a SPOF? |
| 09:55 | julianleviston | oh not really actually. |
| 09:56 | AeroNotix | ordnungswidrig: check out pg2 in erlang |
| 09:56 | AeroNotix | this is a really good way of doing it |
| 09:56 | AeroNotix | it's in-memory, pretty scalable |
| 09:56 | AeroNotix | but it *is* AP. But it gives you tools to merge similar keys together. |
| 09:57 | cemerick | AeroNotix: cool story re: Joe Armstrong o.0 |
| 09:57 | ordnungswidrig | good to know. I actually do not have any needs for such tool right now. |
| 09:57 | AeroNotix | cemerick: Did you ever use Rebar? |
| 09:57 | AeroNotix | the Erlang build tool |
| 09:58 | cemerick | AeroNotix: I have. |
| 09:58 | julianleviston | have any of you used avout? |
| 09:58 | AeroNotix | cemerick: I spoke to him about repeatable builds and the like. He was aware of rebar and said it was fine and I quote "dependencies are easy" |
| 09:59 | julianleviston | I’m only curious. |
| 09:59 | AeroNotix | julianleviston: oh yeah I tried that |
| 09:59 | AeroNotix | so cool |
| 09:59 | AeroNotix | the idea is really neat |
| 10:00 | AeroNotix | it Just Werkz |
| 10:00 | julianleviston | AeroNotix: reminds me of some kind of precursor to datomic a lot… |
| 10:01 | cemerick | AeroNotix: Okay. Going to have a hard time bootstrapping that into "Joe Armstrong is a clueless fool". |
| 10:01 | AeroNotix | cemerick: clueless about modern Erlang development. There's a lot more to it than that though. |
| 10:02 | gfredericks | what? dependencies are easy? hasn't he heard that they're hard? |
| 10:02 | AeroNotix | gfredericks: go use rebar in prod for a while. You'll see what I mean. It's horrifi |
| 10:02 | AeroNotix | horrific |
| 10:03 | cemerick | so bizarre |
| 10:03 | AeroNotix | a lot of the people you see swooning over Erlang are just using it for trivial projects. |
| 10:04 | AeroNotix | I've met most of those people who go to all the Erlang/Erlang solution gigs |
| 10:04 | AeroNotix | literally all of them are just making shit up |
| 10:04 | AeroNotix | it's full of posers et al. |
| 10:04 | cemerick | Bjarne Stroustrup is an idiot for not saving us from semicolons |
| 10:04 | AeroNotix | Excuse me though, I'm a little burned out on it. |
| 10:04 | julianleviston | LOL |
| 10:04 | cemerick | Guy Steele is dumb for having helped make Java |
| 10:05 | julianleviston | cemerick: multiple inheritance! |
| 10:05 | cemerick | dunno, I'll stop now :-P |
| 10:05 | julianleviston | cemerick: you protest too much ;-) |
| 10:05 | mavbozo | AeroNotix: let's hear more about it in #clojure-offtopic |
| 10:05 | AeroNotix | cemerick: Joe claims to have invented Erlang but he invented JAM which is not BEAM and was vastly different. |
| 10:07 | cemerick | AeroNotix: I don't really have anything to add. The whole thread is absurd. |
| 10:07 | cemerick | Sorry for the noise, everyone :-) |
| 10:07 | AeroNotix | yeah^ sorry |
| 10:08 | mavbozo | we need a place to vent our frustation |
| 10:12 | ordnungswidrig | cemerick, AeroNotix: it's interestung noise |
| 10:16 | mavbozo | AeroNotix: thanks for sharing |
| 10:16 | mavbozo | (inc AeroNotix) |
| 10:16 | lazybot | ⇒ 8 |
| 10:59 | daniel__ | clojure.core seems to crash my browser: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj |
| 10:59 | daniel__ | or rather github |
| 11:01 | locks | I'm trying to do something like http://stackoverflow.com/questions/10634417/image-resize-to-fit-on-jpanel but I'm getting an empty pane, my code (I'm using seesaw): |
| 11:01 | locks | https://www.irccloud.com/pastebin/z5hVQvO8 |
| 11:02 | chrstphrhrt | anyone know which of the clojure repl options is most like bpython? don’t need fancy graphical notebook or editor integration, just a solid standalone repl |
| 11:03 | locks | the backtrace is so big LightTable isn't displaying all of it |
| 11:17 | mnngfltg | chrstphrhrt, bare `lein repl` should get you most of the way there; for colored output, https://github.com/venantius/ultra |
| 11:18 | mnngfltg | what exactly are you looking for? |
| 11:18 | chrstphrhrt | mnngfltg: ooh purdy, thanks! |
| 11:18 | chrstphrhrt | mnngfltg: looks like REPLy is nice too |
| 11:19 | chrstphrhrt | mnngfltg: would like completion to help learning.. but prefer in terminal rather than editor |
| 11:30 | mmitchell | justin_smith: hey sorry to bother again. Re. cider and nrepl... I just can't seem to get "lein ring server" + repl options to work with cider-nrepl. No matter what I do, I get the "wrong version" warning in Emacs. The only way I can get it to work is through "lein repl". This seems to indicate the problem is in the "lein-ring" plugin? |
| 11:30 | mmitchell | which is all handled here - https://github.com/weavejester/lein-ring/blob/e0bee845db33e18c020a27fb069bf16a07dcf11c/src/leiningen/ring/server.clj#L54 |
| 11:31 | justin_smith | mmitchell: that code makes me think that by adding cider-nrepl to the :nrepl-middleware key in your project you could fix that |
| 11:32 | mmitchell | oh snap, i didn't even see that |
| 11:40 | mnngfltg | chrstphrhrt, I agree, using the repl from the console is easier a lot of times than one integrated in the editor |
| 11:40 | mnngfltg | chrstphrhrt, REPL-y is actually the repl you see when you run `lein repl` |
| 11:41 | chrstphrhrt | mnngfltg: oh ha didn’t realise that |
| 11:44 | __tim_ | hi how do you detect a dependency issue with lein deps when using it with a CI server? The return code seems to be the same regardless or any dependency errors, or i'm using it wrong. I've enabled :pedantic true in my project. and running lein deps. |
| 11:47 | ordnungswidrig | __tim_: if the return code is the same then you might be able to grep for a keyword in the output |
| 12:04 | mmitchell | lein-ring :nrepl-middleware for cider support doesn't seem to help at all :( |
| 12:10 | mmitchell | oh wait, latest version of lein-ring doesn't support those options, they're only in master |
| 12:58 | clintm | Do any of you happen to know if we will eventually see support for read macros in clojure? |
| 12:59 | dnolen | clintm: it will not happen |
| 13:00 | clintm | Ok, thanks! |
| 13:34 | bja | having spent some time in a CL codebase recently, I'm glad I won't see full read macros in clojure anytime soon |
| 14:11 | moquist | dnolen: Wouldn't om/IRender be preferable for professor-view in https://github.com/omcljs/om/wiki/Basic-Tutorial, since professor-view has no state of its own? |
| 14:13 | moquist | dnolen: NM... somehow got the history of my own tutorial code confused. The tutorial doesn't use om/IRenderState like I firmly had in my head that it did. |
| 14:14 | moquist | dnolen: Figured it out. Same comment, but for registry-view. :) Isn't om/IRender more appropriate than om/IRenderState ? |
| 14:19 | daniel`` | looking for the clojure or java equivalent of random.SystemRandom().getrandbits(n) |
| 14:19 | daniel`` | in python |
| 14:19 | AeroNotix | daniel``: https://github.com/weavejester/crypto-random |
| 14:20 | AeroNotix | relevant java classes are java.security.SecureRandom |
| 14:21 | daniel`` | SecureRandom :) |
| 14:21 | daniel`` | i was looking at Random |
| 14:22 | daniel`` | is more or less the same, i need a way to convert a byte-array to a long |
| 14:22 | justin_smith | ,(let [rnd (java.util.SecureRandom.)] (.next rnd 8)) |
| 14:22 | AeroNotix | doesn't it have .getLong ? |
| 14:22 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: java.util.SecureRandom, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:23 | justin_smith | ,(let [rnd (java.security.SecureRandom.)] (.next rnd 8)) |
| 14:23 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: next for class java.security.SecureRandom> |
| 14:23 | justin_smith | hrmph |
| 14:23 | daniel`` | justin_smith: i think .next is protected and i can't call it |
| 14:23 | justin_smith | well that's dum |
| 14:24 | daniel`` | AeroNotix: don't think so, it has nextLong but then i can't specify the byte length |
| 14:24 | justin_smith | daniel``: nextBytes |
| 14:24 | justin_smith | tell it how many bytes you want, turn them into whatever you need |
| 14:25 | justin_smith | you probably wanted a multiple of 8 anyway |
| 14:25 | AeroNotix | daniel``: what do you need the random for/ |
| 14:25 | AeroNotix | ? |
| 14:25 | daniel`` | trying to implement an SRP login system |
| 14:26 | daniel`` | its for a salt |
| 14:26 | daniel`` | http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol im copying this python implementation |
| 14:26 | AeroNotix | I'm just using (random/bytes 20) |
| 14:26 | AeroNotix | from crypto.random |
| 14:27 | AeroNotix | the _first_ thing I linked you to |
| 14:27 | AeroNotix | 20 is the number of bytes, obv |
| 14:28 | justin_smith | AeroNotix: a whole lib seems a bit much for what could be two interop calls |
| 14:28 | AeroNotix | justin_smith: it's a whole lib which does the interop calls :) |
| 14:29 | justin_smith | AeroNotix: that fit in a clojurebot one-liner |
| 14:29 | AeroNotix | and I don't understand that argument either. We have great tooling for managing dependencies in Clojure, use them! |
| 14:29 | daniel`` | AeroNotix: yep, thats similar to my implementation |
| 14:29 | daniel`` | trouble is the python version returns a long not a byte array |
| 14:29 | AeroNotix | justin_smith: right, but there's no reason (especially with crypto code?) to do it over and over again |
| 14:29 | justin_smith | AeroNotix: using the class directly is not reinventing the wheel in any sensible definition of the term |
| 14:29 | AeroNotix | daniel``: byte-array => ByteBuffer => getLong? |
| 14:30 | daniel`` | and crypt-random is a good reference though |
| 14:30 | daniel`` | AeroNotix: thanks for the tip, ill try |
| 14:30 | amalloy | i think that either using this lib or doing interop directly are both perfectly reasonable approaches, i don't know why you guys are arguing about it |
| 14:30 | AeroNotix | amalloy: shrug |
| 14:30 | daniel`` | amalloy: :) |
| 14:30 | dnolen | moquist: perhaps, the wiki is user modifiable, I'm always happy to see enhancements |
| 14:31 | AeroNotix | no arguments just different approaches and asserting they are the preferred way. |
| 14:31 | daniel`` | its useful for me to see the interop because i have no java background |
| 14:31 | daniel`` | and like to know whats going on |
| 14:32 | moquist | dnolen: Cool. I'll do that. |
| 14:33 | AeroNotix | user> (.getLong (ByteBuffer/wrap (random/bytes 200))) |
| 14:33 | AeroNotix | ;; => 7805789527915639494 |
| 14:33 | AeroNotix | daniel``: ^^ |
| 14:34 | daniel`` | yep, thanks AeroNotix, just got to the same |
| 14:34 | AeroNotix | obv you only need 8 bytes |
| 14:34 | daniel`` | yeah |
| 14:35 | justin_smith | you can use bit-and to ensure you don't get more bits that wanted (if it wasn't a multiple of 8) |
| 14:37 | daniel`` | it uses 1 or 0 for the remaining bits? |
| 14:38 | justin_smith | daniel``: it would be for ensuring bits you don't want are zeroed out (but keeping the sign bit intact) |
| 14:38 | justin_smith | if you want a value with a specific non-multiple-of-8 bits |
| 14:39 | daniel`` | right |
| 14:39 | daniel`` | Error detected while processing function <SNR>64_printop..<SNR>64_opfunc: weird error i get trying to evaluate the long |
| 14:39 | daniel`` | its ok if i call it with (prn s) |
| 14:40 | daniel`` | think this is a fireplace thing |
| 14:40 | daniel`` | can't evaluate a value outside parens |
| 14:40 | AeroNotix | primitive ;) |
| 14:46 | daniel`` | this is where i got to https://gist.github.com/danielstockton/40dd5a9c3bdde35244ea |
| 14:47 | daniel`` | can't parse the string digest in the one way hash function to an integer either |
| 14:48 | daniel`` | python has hexdigest that MessageDigest doesnt |
| 14:51 | socksy | is datomic the only existing database[-style-project] that supports the clojure philsophy of immutability/persistent data structures, or are there some others out there? |
| 14:52 | lvh | Hm. I have a data structure, only passed at runtime, that looks like [{:a :a} {:b :b} {:c :c}]. I want to transform that into (l/run* [q] (conde [(l/featurec req {:a :a})] [(l/featurec req {:b :b})] [(l/featurec req {:c :c})]). The obvious choice for that kind of rewriting seems to be macros, but I can't do that, because runtime (unless I'm supposed to call macroexpand or something). |
| 14:53 | lvh | Just apply won't work; l/run is itself a macro. |
| 14:54 | amalloy | i think you can easily enough write a version of conde that takes a list of goals |
| 14:58 | amalloy | (defn conds [goals] (if (empty? goals) (fail nil) (conde [(first goals)] [(conds (rest goals))]))) or something like that |
| 14:59 | hiredman | isn't there already one? |
| 15:00 | amalloy | hiredman: probably |
| 15:00 | hiredman | everyo or something? |
| 15:00 | lvh | hiredman: Isn't everyo conjunction? |
| 15:00 | gfredericks | you can write a recursive function too I thinks |
| 15:00 | amalloy | gfredericks: that's what i did |
| 15:00 | gfredericks | that's what amalloy just did |
| 15:01 | lvh | conde is [[a AND b AND c] OR [d AND e AND f]] |
| 15:01 | amalloy | i mean, who knows if it works |
| 15:03 | AeroNotix | daniel``: do you have the python code you're emulating? |
| 15:03 | daniel`` | yeah http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol |
| 15:03 | daniel`` | made a tiny bit more progress on the gist |
| 15:07 | daniel`` | hmm it actually works, what i have in the gist |
| 15:07 | lvh | amalloy: Thanks! |
| 15:07 | daniel`` | im having trouble with reevaluating my file due to my primitive setup |
| 15:07 | amalloy | lvh: does it actually work? |
| 15:07 | lvh | amalloy: I removed the inner []s since I still want to be able to specify the conjunctions |
| 15:07 | lvh | amalloy: Yeah, looks like it :) |
| 15:08 | amalloy | great |
| 15:08 | daniel`` | hmm no, sometimes it gives a NumberFormatException Infinite or NaN |
| 15:08 | lvh | wait, maybe not |
| 15:09 | lvh | amalloy: What's (l/fail nil)? I thought you were just supposed to use l/fail to get a failing goal? |
| 15:09 | amalloy | lvh: yeah, it's a failing goal. if there are no goals left in the conds, you need to fail, right? |
| 15:10 | lvh | amalloy: OK, cool, as long as it's the same as l/fail I know what it means :) |
| 15:10 | amalloy | lvh: i don't really know; i just wanted a failure for my base case, and found l/fail. it probably does what i mean. haven't touched core.logic for at least a year |
| 15:10 | lvh | amalloy: Okay, cool :) Thanks! |
| 15:15 | lvh | amalloy: I can't get the version without []s to work, though: https://gist.github.com/lvh/353d5a5c057a758b7858 |
| 15:15 | lvh | not the bestest error message :( |
| 15:15 | amalloy | that is not how brackets or core.logic work |
| 15:16 | amalloy | in (conde [a b c]), the value [a b c] never exists at runtime: it's just a grouping mechanism for core.logic's macroexpander to use |
| 15:16 | amalloy | creating your own vector and passing it in will never work; you need to use like (l/all a b c) |
| 15:24 | AeroNotix | When I am trying to generate a class is it not possible to keep re-evaluating the gen-class ns and have the changes reflected? |
| 15:24 | AeroNotix | because it seems that this is the case. |
| 15:25 | AeroNotix | i.e. I add / change the :constructors key, and the changes aren't reflected. |
| 15:25 | amalloy | dnolen: a lot of stuff in core.logic is macros that doesn't seem to need to be. like, why is l/all a macro? it expands into bind*, which expands into bind, which is just a function with no funny business |
| 15:25 | AeroNotix | amalloy: I've had similar thoughts when looking at core.logic |
| 15:25 | dnolen | amalloy: dunno, some things are vestiges of history or things brought over from miniKanren |
| 15:25 | amalloy | so it seems to me like bind* could be a function, which would make l/all a function, and then you could just write (apply l/all goals) |
| 15:25 | AeroNotix | there's a few places that could seemingly be replaced by functions |
| 15:26 | amalloy | dnolen: would you take a pull request that changed bind* and all to functions? |
| 15:26 | ul | hi! anybody encountered such error in repl? |
| 15:26 | ul | clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: vfsm.core.Automaton cannot be cast to compile__stub.vfsm.core.Automaton |
| 15:26 | ul | what is compile__stub? |
| 15:26 | amalloy | oh, core.logic is a contrib, so i guess it'd be a jira ticket |
| 15:27 | dnolen | amalloy: I don't like changing old stuff |
| 15:27 | dnolen | amalloy: but I'm happy to see the desirable behavior provided by some other route |
| 15:27 | ul | it happens if i try to call function from vfsm.core namespace |
| 15:28 | amalloy | dnolen: you mean something like all* that's a function version of all? |
| 15:28 | AeroNotix | dnolen: would the observable behaviour change all that much? |
| 15:28 | dnolen | amalloy: yeah, that's preserved |
| 15:28 | amalloy | AeroNotix: well no, not at all, which is the point |
| 15:28 | dnolen | s/preserved/preferred |
| 15:28 | AeroNotix | amalloy: that's why I don't get the fuss about changing it. |
| 15:28 | dnolen | amalloy: I'm happy to assess the change if you do a bit more legwork wrt to verifying it doesn't actually change anything (perf etc.) |
| 15:30 | amalloy | AeroNotix: nobody wants to fiddle with the foundations of their work on a lark. even if it seems like it would obviously be an improvement, it's dangerous |
| 15:31 | AeroNotix | amalloy: isn't this why we have test suites and beta/rc releases? |
| 15:32 | AeroNotix | do I really need to restart the vm when I change gen-class definitions? |
| 15:32 | amalloy | AeroNotix: when you have a project as large and widely used as core.logic, you can make a policy of accepting any pull request that doesn't break the tests. but since core.logic is dnolen's, i'm happy to live with his policies |
| 15:32 | AeroNotix | amalloy: ok |
| 15:33 | dnolen | AeroNotix: core.logic is just really old now, I'm not quite so cautious with other projects that I maintain |
| 15:33 | AeroNotix | dnolen: rog |
| 15:33 | amalloy | dnolen: i don't really want to do a ton of legwork, since i don't even use core.logic; i just noticed this issue while answering someone's question in here. but i can put together and*, a function version of all, and or*, a function version of conde. or do you prefer some other name? |
| 15:34 | vas | So I want to chain transformations together in enlive using ( enlive/do-> ) ... but i'm not sure how it works. do I need to supply the nodes it operates on to each transform, or are all transforms applied to the same node set? |
| 15:35 | dnolen | amalloy: we do have a simple convention around goal functions, just tack a g onto it. but that's kind of ugly. maybe a new goals namespace? |
| 15:35 | amalloy | "condeg"? |
| 15:35 | dnolen | amalloy: but also happy to take a patch, think on it, and refactor it if I get a better idea |
| 15:35 | ul | is it legitimate to e.g. extend-type clojure.lang.PersistentArraMap with own protocol? |
| 15:35 | AeroNotix | condegg |
| 15:35 | amalloy | okay |
| 15:35 | AeroNotix | hehe |
| 15:35 | dnolen | er apply it, and refactor it |
| 15:35 | amalloy | right |
| 15:36 | ul | figured out that mentioned above compiler exception happens after i did such extension |
| 15:36 | amalloy | ul: yes, if it's your own protocol or your own type it's fine |
| 15:36 | amalloy | extending someone else's protocol to someone else's type is the dangerous thing |
| 15:36 | ul | it is my protocol, but clojure.lang... type |
| 15:37 | ul | and it leads to compiler error =( |
| 15:37 | AeroNotix | ul: can you show some code friend? |
| 15:37 | AeroNotix | what's triggering that? |
| 15:37 | ul | yes, wait a second |
| 15:37 | AeroNotix | just looks like you're passing something to some java joint that it doesn't like, though |
| 15:38 | AeroNotix | do I really need to restart the vm when I change gen-class definitions? |
| 15:38 | AeroNotix | justin_smith: ^? |
| 15:38 | ul | https://gist.github.com/ul/a8d61b4372a4e04484e4 |
| 15:38 | ul | this is vfsm.core |
| 15:38 | ul | if i paste its content directly to repl |
| 15:38 | ul | or require — it loads fine |
| 15:39 | amalloy | AeroNotix: probably yeah |
| 15:39 | AeroNotix | amalloy: sadness |
| 15:39 | amalloy | gen-class is heavy stuff |
| 15:39 | ul | but calling any function involving my protocols produces exception |
| 15:39 | AeroNotix | understandable though |
| 15:55 | amalloy | dnolen: https://www.refheap.com/0383ff71c2b0ad526bd7f9b66 is the outline. anything you want changed before i make a proper patch? |
| 15:56 | dnolen | amalloy: looks good, a few simple example tests would be nice |
| 15:59 | amalloy | dnolen: good idea. actually i'll just take a couple example tests from conde, and assert that or*/and* get identical results |
| 15:59 | dnolen | amalloy: nice |
| 16:00 | dnolen | amalloy: you might want to try some of the trickier ones |
| 16:00 | TimMc | something something generative tests for equivalence |
| 16:00 | TimMc | That would be a fun challenge. |
| 16:00 | amalloy | TimMc: well that's the joke, you can't actually do it |
| 16:00 | amalloy | because the existing features are macros |
| 16:00 | amalloy | you can't really generate calls to them without eval |
| 16:00 | TimMc | Nonsense, there's eval. |
| 16:00 | TimMc | yeah |
| 16:01 | amalloy | and tbh the last thing i want to use eval on is randomly generated code |
| 16:01 | dnolen | ugh |
| 16:01 | TimMc | What's the point of this fancy-ass language if we don't ever use eval? |
| 16:01 | dnolen | GitHub syntax highlighting is so bad now |
| 16:01 | dnolen | locks up in every browser |
| 16:02 | dnolen | amalloy: anyways, the divergence tests would be interesting |
| 16:02 | AeroNotix | would be cool if they just had a profile option to turn it off |
| 16:02 | dnolen | amalloy: search for "divergence" in tests.clj |
| 16:03 | amalloy | dnolen: (def f1 (fresh [] f1))? you're a maniac |
| 16:04 | dnolen | amalloy: ha, that's Will's tests actually |
| 16:05 | locks | dnolen: that's quite the big file dnolen :P |
| 16:05 | dnolen | locks: for some definition of "big" |
| 16:05 | dnolen | last time I checked the year it was 2015 |
| 16:07 | amalloy | dnolen: hrm, conde does interleaving? my version probably doesn't |
| 16:07 | crack_user | someone knows what is wrong with this tiny code: https://gist.github.com/fariasvp/fae3d6ae4bf5ab083e15 |
| 16:07 | amalloy | i wasn't sure if you'd made that the default |
| 16:07 | dnolen | amalloy: oh yeah, it is |
| 16:07 | dnolen | amalloy: sorry for sending you down this direction, didn't realize you were still going off TRS ;) |
| 16:09 | crack_user | hello guys |
| 16:10 | crack_user | some one can help with this error: https://gist.github.com/fariasvp/fae3d6ae4bf5ab083e15 |
| 16:10 | amalloy | you can't name a function new |
| 16:11 | crack_user | thx |
| 16:15 | AeroNotix | it's weird that it *allows* you to make a function called new but then completely ignores you |
| 16:15 | {blake} | Is there any code lying around to turn a nested JSON into a flat-file or CSV? |
| 16:16 | TEttinger | {blake}, sounds like a recipe for disaster |
| 16:16 | {blake} | TEttinger: Heh. Why? |
| 16:16 | {blake} | It could get very wide, I suppose. But... |
| 16:17 | TEttinger | I just think of CSV as having specific columns, and JSON could have any name for any field, so you would have many columns yeah |
| 16:18 | {blake} | Well, I guess no big deal to roll my own. |
| 16:18 | boblarrick | http://konklone.io/json/ |
| 16:19 | boblarrick | also http://csvkit.readthedocs.org/en/latest/index.html |
| 16:19 | boblarrick | {blake}: ^ |
| 16:22 | {blake} | boblarrick: Thanks. I guess I steal from here and convert to clojure. =P |
| 16:23 | boblarrick | if you really need to do in-process i guess, maybe just shell out? |
| 16:25 | {blake} | Honestly, I wouldn't want to deal with the bitching from devops. =P |
| 16:32 | nicferrier | how annoying that clojure is infected with java's private fallacy. |
| 16:33 | the-kenny | Only with interop. But it sucks, yeah :/ |
| 16:33 | nicferrier | I am trying to find where http-kit/client converts { :a 1 :b 2 } to "B=2&A=1" (caps??) but it would be easier if I could get at the internals. |
| 16:33 | nicferrier | as it is, I'm having to read the code and try and guess :-( |
| 16:36 | the-kenny | nicferrier: that sounds very strange. Why would http-client do that?! |
| 16:37 | nicferrier | the-kenny: I presume defn- means "private" of some sort? |
| 16:37 | the-kenny | nicferrier: yes, but still accessible via fully-referenced var like #'my.ns/some-private-fn |
| 16:38 | nicferrier | hmmm. ok. can;t seem to reach it from the repl. must be my fault. |
| 16:39 | the-kenny | Accessing it via foo.bar/foo won't work, throwing something like var: foo.bar/foo is not public - accessing it via the var should work |
| 16:39 | nicferrier | via the var? |
| 16:40 | the-kenny | Via #'foo.bar/foo |
| 16:40 | the-kenny | it's a side channel here |
| 16:40 | nicferrier | ok. fair enough. thanks. |
| 16:41 | nicferrier | still a *bit* frustrating though. why do we need privates? |
| 16:41 | lmohseni | howdy |
| 16:42 | AeroNotix | nicferrier: otherwise you'd have silly naming conventions indicating what's private and what's note. |
| 16:42 | AeroNotix | not* |
| 16:42 | AeroNotix | nicferrier: with the way it is now, you can at least show the user of the code "hey this is not public" |
| 16:42 | AeroNotix | but they can easily circumvent it |
| 16:43 | AeroNotix | https://gist.github.com/AeroNotix/83a91d08b05ea694abbb |
| 16:43 | the-kenny | nicferrier: Distinction between public/private api for example. You don't want to make all utility-fns accessible in case you will remove that later. All such stuff |
| 16:44 | AeroNotix | It's *a* distinction that causes pause for thought when using it |
| 16:44 | amalloy | okay dnolen, you bastard, i replicated your interleaving for or* and now it behaves exactly like conde in the divergence test. do you need "simple" tests for it too, or is passing the divergence tests good enough? |
| 16:44 | nicferrier | the-kenny: yeah. but here you go, it's still accessible... so people could break it if they wanted. |
| 16:44 | the-kenny | That's their fault though. You marked it as non-public. |
| 16:44 | dnolen | amalloy: divergence tests are good |
| 16:44 | amalloy | (ps i guess that kinda sounds like i'm really mad, but i am just playing. the internet is hard sometimes) |
| 16:44 | AeroNotix | nicferrier: except someone clearly knows they shouldn't be doing that |
| 16:44 | the-kenny | Else you would get internal comments or silly naming conventions like AeroNotix said |
| 16:45 | the-kenny | (like in elisp :D) |
| 16:45 | dnolen | amalloy: haha, I read it as "I got nerd-sniped by dnolen" |
| 16:45 | AeroNotix | e.g. in Python or Emacs Lisp you have silly naming convenctions |
| 16:45 | {blake} | amalloy: I was waiting for you to say "DNOLEN YOU MAGNIFICENT BASTARD I READ YOUR BOOK!" |
| 16:45 | AeroNotix | dnolen: you have a book? |
| 16:45 | amalloy | does he have a book? i read TRS |
| 16:45 | {blake} | lol |
| 16:45 | xemdetia | "dnolen's fishing guide" |
| 16:45 | AeroNotix | oh that one |
| 16:45 | AeroNotix | yeah that's a snoozefest |
| 16:46 | AeroNotix | "Dnolen's guide to having rad hair" is much better |
| 16:46 | nicferrier | the-kenny: I just think it's silly. there was some xkcd a while ago about it I seem to recall. I think he was right. |
| 16:46 | AeroNotix | nicferrier: what's your alternative? |
| 16:46 | AeroNotix | how do you convey "hey this is private, dragons" |
| 16:46 | TimMc | ^:dragons |
| 16:47 | AeroNotix | TimMc: perfect! |
| 16:47 | TimMc | Actually, I'm going to start using that, thanks. |
| 16:47 | the-kenny | I thought ^:private meant dragons |
| 16:47 | AeroNotix | except that's exactly what defn- does |
| 16:47 | AeroNotix | defn- is ^:private |
| 16:48 | TimMc | I've seen ^:internal |
| 16:48 | {blake} | ^:infernal |
| 16:48 | AeroNotix | TimMc: does tooling/the language do anything with it though? |
| 16:48 | AeroNotix | ^:private is clear, well understood, integrated into the language, and above-all -- Ignorable. |
| 16:48 | the-kenny | nicferrier: FWIW: I don't see the behavior in http-kit: @(org.httpkit.client/get "http://localhost:4035" {:query-params {:foo 233}}) works just like xpected |
| 16:49 | TimMc | AeroNotix: :private is annoying because it gets in the way of tests |
| 16:49 | AeroNotix | TimMc: explain |
| 16:49 | AeroNotix | why are you testing private functions |
| 16:49 | TimMc | Because unit tests? |
| 16:49 | the-kenny | AeroNotix: I think that's fine. For granularity. |
| 16:49 | nicferrier | the-kenny: yeah. I just found the problem and it was me being stupid. and i wasted 10 minutes not finding my stupidity by having to arse around to prove that it wasn't http-kit. |
| 16:49 | the-kenny | TimMc: can't you just use the #'foo.bar/fun workaround? |
| 16:49 | AeroNotix | TimMc: you test private functions? |
| 16:49 | TimMc | Absolutely. |
| 16:49 | AeroNotix | Lol |
| 16:50 | AeroNotix | test the interface |
| 16:50 | the-kenny | AeroNotix: I do that too from time to time. |
| 16:50 | xemdetia | if I am relying on it why wouldn't I test it |
| 16:50 | the-kenny | If there's hairy logic or some widely-used utility-fn why not test its behavior? |
| 16:50 | TimMc | Just because they're not part of the interface doesn't mean you can't or shouldn't pin down behavior. |
| 16:50 | amalloy | dnolen: http://dev.clojure.org/jira/browse/LOGIC-167 |
| 16:50 | dnolen | amalloy: thanks! |
| 16:50 | AeroNotix | you should be able to invoke this "hairy" code through regular testing of the interface |
| 16:51 | AeroNotix | also, if your interface makes it hard to get good coverage, you dun f'd up. |
| 16:51 | nicferrier | in fact, that's the definition of a unit test. unit tests are supposed to test "business value" and not integration. |
| 16:51 | TimMc | AeroNotix: Sometimes I test things that the interface does not *currently* expose but could later if the code is modified. |
| 16:51 | AeroNotix | TimMc: I just delete things the interface doesn't expose. |
| 16:51 | TimMc | That's your call. |
| 16:52 | TimMc | but sometimes that is not possible |
| 16:52 | AeroNotix | TimMc: vcs makes it possible to time travel |
| 16:52 | TimMc | The private fn may be highly general and the public one restrictive. You can't "delete" the generality. |
| 16:53 | TimMc | Anyway, you haven't demonstrated that there is harm in testing private fns. |
| 16:53 | xemdetia | I like bridges I built to be tested even if we only care about the cars that drive over it :( |
| 16:53 | AeroNotix | there's no harm, obviously. I'm just saying that it's code that should be easily invoked through normal interface testing and it's code that could be ephemeral in the face of changing requirements |
| 16:54 | TimMc | I do it because it can add robustness against future code changes that I haven't even imagined yet. |
| 16:55 | AeroNotix | my goal is to usually check the coverage report and see whether these helper/private functions have been invoked and ensure that I write tests to invoke those paths |
| 16:55 | AeroNotix | "branch testing" |
| 16:55 | TimMc | AeroNotix: OK, but many of my tests of non-interface fns are also there because I test as I write and it helps flush out bugs faster. You think I should delete them afterwards? |
| 16:55 | AeroNotix | TimMc: I use a repl for that |
| 16:56 | AeroNotix | but yeah, when I develop I have snippets of code that work with the internal stuff in the file, when I am doing messing with it, I'll paste it into a test file. If eventually I don't need it and I can invoke that code from just the interface, I'll delete it. |
| 16:57 | TimMc | Whatever floats your boat. |
| 16:57 | AeroNotix | This is why people end up with test suites which take hours to run |
| 16:57 | AeroNotix | because they're testing irrelevant things, or things multiple times. |
| 16:57 | TimMc | Never had that problem. |
| 16:57 | AeroNotix | perhaps not hours |
| 16:58 | TimMc | If and when I have that problem I'll consider changing things. |
| 16:58 | xemdetia | I mean this is why you make your test suite configurable so you only run what tests are required and still have them around for a full final build |
| 16:58 | AeroNotix | xemdetia: sure, but you still need to do the full final build for CI. |
| 16:59 | AeroNotix | in fact, I just run tests in the repl too by evaluating the test. |
| 16:59 | nicferrier | personally I do change based testing. |
| 17:00 | xemdetia | I don't mind CI builds taking a while, the point of CI is that nobody is having to watch the stove |
| 17:00 | AeroNotix | xemdetia: it's fine when you've got the infr or the cash to spunk on redundant CI servers |
| 17:00 | AeroNotix | it's actually _really_ fun when you've got N-million CI servers |
| 17:02 | TimMc | you mean customers? |
| 17:02 | xemdetia | well I don't know, when something is taking too long I do the sensible thing of take measurements, make changes, measure for improvements like everyone else, even if my CI server is just a vm on my laptop building linux iso's |
| 17:02 | AeroNotix | haha |
| 17:02 | xemdetia | if I have to make tests more efficient because it doesn't fit my needs that is just as well a documented problem as code optimization |
| 17:02 | xemdetia | that doesn't mean I should just purge it |
| 17:02 | xemdetia | at least to me |
| 17:06 | TEttinger | Open Build Service from OpenSUSE is pretty nice for linux builds |
| 17:07 | TEttinger | not CI I guess |
| 17:07 | AeroNotix | travis is sweet |
| 17:12 | justin_smith | TEttinger: does suse stop being super weird? because as a long time debian user I jumped into it recently and it was a major culture shock |
| 17:12 | TEttinger | justin_smith: I use windows, I stopped fiddling with linux a few years ago tbh |
| 17:12 | justin_smith | OK |
| 17:13 | TEttinger | I still have some VMs I occasionally use for FontForge |
| 17:13 | TEttinger | one is basically only used to build GNU Unifont |
| 17:15 | sveri | Hi, I have a string containing some html code. Using selmer I want to get the content from the string and just use that as plain html in the template. {{some.content|safe}} keeps the content from being escaped, but it still is inside a string. How can I do that? |
| 17:15 | TEttinger | http://www.unifoundry.com/unicode-utilities.html this stuff is highly linux-specific, but I used clojure to bit-twiddle each line of hex digits (after parsing) into different shapes to make 8x16 glyphs into 16x16 glyphs or 16x16 glyphs into garbage 8x16 ones |
| 19:11 | jodaro | hrm |
| 19:11 | jodaro | are there any flambo users in the house? |
| 19:13 | amalloy | ~anyone |
| 19:13 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 19:14 | jodaro | yeah, i know, but its pretty esoteric |
| 19:15 | amalloy | so? nobody is going to volunteer, sight unseen, to answer an unknown esoteric question about whatever flambo is. but if you ask a specific question, someone might know the answer |
| 19:16 | jodaro | trying to figure out the right way to mimic the streaming/scala equivalent of dstream.foreach(rdd=> { rdd.foreachPartition ... |
| 19:16 | jodaro | in a defsparkfn |
| 19:55 | justin_smith | jodaro: wouldn't that just be flambo.api/map ? |
| 19:55 | justin_smith | jodaro: https://github.com/yieldbot/flambo#basics |
| 19:58 | jodaro | i think i can do it with map, yeah, but the action i want to perform is something along the lines of what the streaming docs suggest using the foreach pattern |
| 19:58 | justin_smith | what is the difference between a mapping and a foreach? |
| 19:59 | jodaro | so i figured id attempt that first |
| 20:00 | jodaro | seems like the difference between map and doseq |
| 20:02 | justin_smith | jodaro: this mentions support for foreach https://github.com/yieldbot/flambo#rdd-actions |
| 20:03 | justin_smith | looks like it is just flambo.api/foreach |
| 20:04 | justin_smith | (based on the unit tests that call it) |
| 20:08 | jodaro | yup, that works fine, but I'm in streaming land so my top level is a dstream, not an rdd |
| 20:08 | jodaro | i think i figured it out 3 minutes before commute time |
| 20:08 | jodaro | which is typical |
| 20:12 | xapak | Hello. |
| 20:12 | jodaro | map might still make more sense though because i can collect the results of the action and do something with them |
| 20:13 | xapak | What do you suggest as the “best” (in your opinion) Clojure learning resource for someone without 1) Lisp background and 2) Java Virtual Machine background? |
| 20:13 | justin_smith | jodaro: sorenmacbeth is around here sometimes, but hasn't been around today I don't think. He'd likely be in a better position to answer your questions than anyone else. |
| 20:14 | justin_smith | $seen sorenmacbeth |
| 20:14 | lazybot | sorenmacbeth was last seen quittingPing timeout: 255 seconds 15 hours and 18 minutes ago. |
| 20:14 | justin_smith | xapak: other programming experience? |
| 20:15 | xapak | justin_smith, PHP, JavaScript, Ruby, and some Erlang lately. |
| 20:15 | jodaro | justin_smith: yeah, figured he would be the one to ask |
| 20:17 | justin_smith | xapak: you should check out "clojure for the brave and true", the tone isn't to everyone's liking, but it's pretty good |
| 20:17 | justin_smith | xapak: also, programming clojure (the book) |
| 20:18 | namra | i like the clojure for the brave and true |
| 20:18 | dijkstracula | xapak: aphyr's tutorial is nice imho (though I second justin_smith's suggestion too) |
| 20:18 | namra | funny and well enough expleined |
| 20:18 | xapak | justin_smith, nice, thank you. That first suggestion I’m checking. “Looks” like an interesting approach. :) |
| 20:19 | xapak | dijkstracula, I will check that out, thanks. |
| 20:19 | justin_smith | dijkstracula: aphyr's series is especially good for someone who is new to programming, but could be a little slow for someone with experience for the first few chapters at least |
| 20:20 | dijkstracula | justin_smith: hm, yeah, that's fair |
| 20:35 | TEttinger | dijkstracula: your nick reminds me of this, which it turns out is very easy to implement in clojure http://www.roguebasin.com/index.php?title=The_Incredible_Power_of_Dijkstra_Maps |
| 20:36 | TEttinger | my slower clojure impl is here, I also have one that's optimized but uses hiphip for convenient array handling http://ideone.com/pwiTf2 |
| 20:37 | TEttinger | (this is all less than a third the size of a comparable C implementation) |
| 20:44 | dijkstracula | TEttinger: oh no, putting a roguebasin link in front of me is liable to make my friday night evaporate :) |
| 20:45 | TEttinger | hehe |
| 20:45 | justin_smith | "garlic considered harmful" |
| 20:46 | TEttinger | 7 day roguelike challenge march 7, hasn't been a clojure entry yet |
| 20:46 | justin_smith | oooh, interesting |
| 20:46 | justin_smith | I bet you could do nifty things in a 7 day clojure roguelike |
| 20:46 | TEttinger | indeed |
| 20:46 | TEttinger | then you see what OTHER people have done in 7 days and it's just... how |
| 20:47 | justin_smith | TEttinger: speaking of roguelikes, I think it would be cool to make an algorithm that generates randomized and solvable sokoban levels |
| 20:47 | justin_smith | bonus points if you can parameterize difficulty |
| 20:47 | dijkstracula | that's v interesting |
| 20:48 | dijkstracula | (I once did a similar thing with Intelligent Qube puzzles that never turned out the way I wanted; always hoped smarter people than me could do a thing like that and have it work out well) |
| 20:48 | TEttinger | http://7drl.org/2014/03/16/cyberdekay-success/ |
| 21:00 | amalloy | TEttinger: dijkstra maps look pretty cool. thanks for the link |
| 21:03 | justin_smith | TEttinger: looking back at that dijkstra map thing, very cool - one obvious extrapolation would be a monster that knows how to dig, changing the cost function for diggable routes based on their stamina / digging speed |
| 21:03 | justin_smith | so it would know whether it is faster to go the long way or dig a shortcut |
| 21:12 | TEttinger | amalloy, no prob, they are used heavily in a game called Brogue, where they lead to some of the craftiest AI. |
| 21:12 | amalloy | TEttinger: i'm just pleased to learn how crawl's autoexplore works |
| 21:12 | TEttinger | like monkeys that steal an item and then run away, with knowledge of the dungeon layout (since they live there), and intelligently sidestep around you to get to doors and such |
| 21:13 | justin_smith | oh god monkeys are the worst |
| 21:35 | Blake1 | Well, shoot, I probably won't be in the 7DRL this year. :-/ |