2016-04-03
| 00:00 | tolstoy | I don't know what "vectors with a namespace :node" means. Maybe just show a couple? |
| 00:00 | backnforth | ah |
| 00:00 | backnforth | ok |
| 00:01 | backnforth | , [someVector [:node [1], :node [4], :node [9]] |
| 00:01 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 00:01 | backnforth | , [someVector [:node [1], :node [4], :node [9]]] |
| 00:01 | clojurebot | #error {\n :cause "Unable to resolve symbol: someVector in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: someVector in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: som... |
| 00:01 | backnforth | something like that |
| 00:01 | backnforth | I wanted to the count of 3 for the count of :node |
| 00:02 | tolstoy | ,(count (filter #(= % :node) [:node [1], :node [4], :node [9]])) |
| 00:02 | clojurebot | 3 |
| 00:03 | tolstoy | Something like that? |
| 00:03 | backnforth | gross |
| 00:03 | backnforth | use filter? |
| 00:03 | tolstoy | Heh. ;) |
| 00:03 | backnforth | its so alient to me |
| 00:03 | backnforth | alien |
| 00:03 | backnforth | i will look into it |
| 00:03 | backnforth | thanks |
| 00:03 | backnforth | wow, im learning so much so fast |
| 00:03 | backnforth | this is great |
| 00:04 | tolstoy | ,(:node (frequencies [:node [1], :node [4], :node [9]])) |
| 00:04 | clojurebot | 3 |
| 00:04 | will_sm | I've been doing some clojurescript with figwheel and reagent for fun. What are some other cool Clojure tools/libraries I could look into? |
| 00:05 | tolstoy | Seems like you'd have to do some sort of filtering, but perhaps the worthies on this channel will figure out something more clever. |
| 00:05 | tolstoy | will_sm: Instaparse to design your own language. |
| 00:05 | tolstoy | Well, sort of, anyway. |
| 00:24 | sdegutis | Is there a way to combine dec and max-0? |
| 00:25 | sdegutis | I guess (comp (partial max 0) dec) |
| 00:28 | sdegutis | ,(def dec-pos (comp (partial max 0) dec)) |
| 00:28 | clojurebot | #'sandbox/dec-pos |
| 00:28 | sdegutis | ,(map dec-pos [-2 -1 0 1 2 3]) |
| 00:28 | clojurebot | (0 0 0 0 1 ...) |
| 00:29 | sdegutis | ,(map dec-pos [0 1 2 3]) |
| 00:29 | clojurebot | (0 0 1 2) |
| 00:29 | sdegutis | Yay! |
| 00:30 | justin_smith | not to be confused with dec-comp-pos-e |
| 00:43 | backnforth | wow |
| 00:43 | backnforth | filter wont include a map if its value is false |
| 00:50 | tolstoy | Huh. Clojure's pretty good at, uh, s-expressions. ;) |
| 00:50 | tolstoy | Read in some forms that reference forms you previously read in, and, boom: there's postwalk-replace all ready for you. |
| 00:56 | sdegutis | backnforth: filter with some? if needed then I guess |
| 00:57 | backnforth | i like it, its very simple and useful |
| 00:58 | backnforth | reminds me of grep |
| 01:41 | Lewis | ,(some #{false} [false false false]) |
| 01:41 | clojurebot | nil |
| 01:41 | makufiru | Hey all, I'm using the Blaze templating system, and I'm wondering if there's a good way to sort a #each? |
| 01:41 | Lewis | why? |
| 01:41 | clojurebot | why is startup slow is busy compiling the `for` macroexpansion |
| 01:41 | makufiru | sorry wrong channel |
| 02:09 | ridcully | Lewis: because false is not logical true |
| 02:09 | ridcully | ,(doc some) |
| 02:09 | clojurebot | "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)" |
| 02:09 | ridcully | ,(some (partial = false) [false false]) |
| 02:09 | clojurebot | true |
| 02:10 | Lewis | ridcully: what does logicaly true mean |
| 02:12 | Lewis | ,(some #{nil} [nil nil nil]) |
| 02:12 | clojurebot | nil |
| 02:12 | ridcully | neither nil nor false |
| 02:12 | Lewis | I see |
| 02:13 | Lewis | ridcully: what book do you advise |
| 02:13 | ridcully | ,(some (partial contains? #{false nil}) [1 nil false]) |
| 02:13 | clojurebot | true |
| 02:16 | Lewis | ,(some (partial #{false nil}) [1 nil false]) |
| 02:16 | clojurebot | nil |
| 02:16 | ridcully | i read two: the joy of clojure and clojure applied. the first one is a little tougher to chew and the second one is more practical |
| 02:16 | Lewis | ,(doc contains?) |
| 02:16 | clojurebot | "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'." |
| 02:17 | ridcully | others suggested the "brave" book and the one from Carin Meier (spl?!) for beginners |
| 02:17 | Lewis | so joy of clojure and clojure applied are for intermediate? |
| 02:18 | Lewis | ridcully: i see. |
| 02:19 | ridcully | i'd say clojure applied is for you, if you have delivered software in other languages |
| 02:19 | ridcully | ,(#{1 2 3} 1) |
| 02:19 | clojurebot | 1 |
| 02:20 | ridcully | the problem with using the set as a function here is, that it returns the element found - which is "the" false |
| 02:21 | ridcully | contains? on the other hand will tell you if the item is in the set |
| 02:24 | Lewis | ridcully: right i think i got it |
| 02:31 | Lewis | ridcully: what language are you coming from? |
| 02:48 | ridcully | Lewis: groovy on the jvm and c++, python otherwise |
| 02:49 | Lewis | i see |
| 02:49 | Lewis | ridcully: i dont know anything about the jvm |
| 02:55 | Lewis | , |
| 02:55 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 02:55 | Lewis | ,(doc conj) |
| 02:55 | clojurebot | "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type." |
| 09:12 | ARM9 | is there any decent way to leverage the jvm jit compiler to build programs at runtime? |
| 09:12 | ARM9 | like say I've got some simpler functions that I'd want to combine into one function based on some input at runtime |
| 09:13 | ARM9 | call it dynamic recompilation if you will |
| 09:14 | justin_smith | ARM9: the clojure bytecode compiler is always present during runtime in clojure |
| 09:15 | justin_smith | you don't need jit just to get something compiled |
| 09:16 | justin_smith | the jit is not predictable like that - it decides which bytecode it thinks should be inlined into machine code, and it has its own criteria. If you know exactly what should happen, do it yourself, and don't try to coerce the jit to do it. |
| 09:18 | ARM9 | yes, and what I wanted to do is build a program at runtime that runs and (very likely) gets compiled by the jit to native code |
| 09:20 | justin_smith | ARM9: if you want the JIT to happen predictably there's a LOT to learn - there is no "compile this with jit" command. It looks at how frequently the code is called, the size of the method, the specific optimizations it knows how to do, the most common code path... |
| 09:21 | ARM9 | I know how the jit works |
| 09:21 | justin_smith | ARM9: OK, have fun then |
| 09:21 | justin_smith | you can compile byte code at runtime in clojure. The JIT decides what to compile and how. That's your answer. |
| 09:22 | ARM9 | yes and what I'm looking for is how to compile byte code at runtime |
| 09:22 | justin_smith | ARM9: by defining something |
| 09:22 | justin_smith | ARM9: every time you evaluate a clojure expression, it is compiled |
| 09:22 | Empperi | oh god I'm going nuts with boot soon |
| 09:22 | Empperi | I love the concept but man |
| 09:23 | Empperi | right now I just can't get my cljs compilation to end up into the target path I want it to |
| 09:23 | Empperi | yes, I know about the foo.cljs.edn thingy |
| 09:23 | Empperi | but it just doesn't read it apparently |
| 09:23 | justin_smith | ARM9: so if you can get fn or defn to run at runtime (likely using eval), then you're done, that's how it works. |
| 09:23 | Empperi | feels like only thing I can get to work properly is the stuff I define myself... |
| 09:24 | justin_smith | ARM9: the hard part is doing it in such a way that the JIT will be able to help you at all. Especially with idiomatic clojure code. |
| 09:37 | ARM9 | right, fortunately for me I don't need it to be idiomatic |
| 09:37 | ARM9 | like I said I just need some pointers on leveraging the jvm from clojure if at all possible, instead of writing my own jit |
| 09:37 | justin_smith | ,(defn compile-a-thing [] (eval '(fn []))) |
| 09:37 | clojurebot | #'sandbox/compile-a-thing |
| 09:38 | justin_smith | that compiles bytecode every time it is called |
| 09:38 | justin_smith | you'll essentially be writing a macro definition, wrapped in eval |
| 09:38 | ARM9 | that's good, I'll keep playing with eval then |
| 09:38 | ARM9 | cheers |
| 09:38 | justin_smith | ,(= (compile-a-thing) (compile-a-thing)) |
| 09:38 | clojurebot | false |
| 09:38 | justin_smith | new one each time |
| 11:12 | sdegutis | bbl |
| 11:13 | liceoprova | ciao |
| 12:42 | justin_smith | java 9 will have a repl (!) http://www.pixelstech.net/article/index.php?id=1459558345 |
| 13:06 | awwaiid | fancy |
| 13:12 | sdegutis | back |
| 13:16 | ane | java 9 will have nice things |
| 13:17 | sdegutis | justin_smith: seems weird |
| 13:17 | sdegutis | ane: like what |
| 13:20 | ane | the G1 GC becomes the default |
| 13:21 | ane | also Jigsaw, which lets you break the JRE into smaller components so you can drop the stuff you don't need |
| 13:21 | ane | native JSON support... uh what else, units of measure (!) |
| 13:40 | sdegutis | ane: JSON sounds nice |
| 13:41 | sdegutis | ane: Jigsaw sounds useless with Clojure |
| 13:41 | sdegutis | ane: units of measure? |
| 13:41 | ane | actually I was confused, not units of measure (like in F#), but currency support |
| 13:59 | Glenjamin | Java 9 has the module system merged, but punted on version numbers :( |
| 14:18 | sdegutis | wha |
| 14:20 | Glenjamin | jars can now specify the packages they contain, and the ones they depend on |
| 14:21 | Glenjamin | but they can't specify any version constraints, and you can only have one unique instance of a module in play |
| 14:21 | Glenjamin | or at least, that's what I can infer from reading up on the topic |
| 14:42 | ane | that's stupid |
| 14:42 | backnforth | yes |
| 14:43 | backnforth | exactly what i was going to say about my understanding of map functions |
| 14:44 | shafire | :-( |
| 14:46 | justin_smith | it's an improvement of not representing dependencies in the language |
| 14:46 | justin_smith | *over not representing... |
| 15:17 | Lewis | hey |
| 15:17 | Lewis | https://gist.github.com/6ewis/dcd71252a1277ed8d7b94e391a04d124 |
| 15:17 | Lewis | can someone explain to me why 2 is showed twice |
| 15:18 | justin_smith | Lewis: swap! retries if concurrent modification occurs |
| 15:19 | justin_smith | Lewis: this is why you should not put anything with important side-effects inside a swap! call |
| 15:19 | justin_smith | Lewis: so two threads overlapped when incrementing from 1 to 2, one of them retried |
| 15:19 | justin_smith | (or is it 2 to 3?) |
| 15:22 | Lewis | justin_smith: thanks. I don't get it though... |
| 15:22 | justin_smith | Lewis: what do you think swap! does if two threads touch the same value? |
| 15:22 | Lewis | whats the difference between with the side effect and without |
| 15:22 | justin_smith | Lewis: the side effect will happen more than once when retries occur |
| 15:23 | justin_smith | Lewis: so if you put a file write, or a network connect, or a financial transaction, inside a swap!, it can be repeated |
| 15:24 | Lewis | justin_smith: can we start by the very basic..i use swap, what happen |
| 15:25 | justin_smith | Lewis: it reads the value stored, it executes your function, then it reads the value stored again |
| 15:25 | justin_smith | Lewis: if the value has changed, it runs your function over, but with the new value as input |
| 15:25 | justin_smith | Lewis: this is repeated until the same value is read twice, in every call to swap! |
| 15:26 | justin_smith | Lewis: it is much easier to see this in practice if you use a function that calls (Thread/sleep) before returning |
| 15:29 | Lewis | justin_smith: ok I think i undestand the basics but i still dont get whe i use swap multiple times why its different with sideeffects. let me think about it |
| 15:37 | Lewis | justin_smith: what's your favorite clojure editor? |
| 15:44 | cwgem|mac | Lewis: I'd recommend looking over http://dev.clojure.org/display/doc/Clojure+Tools and picking one out. It's going to depend on what sort of needs you have and what you expect out of your editor (also what OS you're on) |
| 15:45 | sdegutis | bbl |
| 15:45 | Lewis | cwgem|mac: im using lighttable and i can't get it to evaluate results |
| 15:45 | Lewis | "failed to open path |
| 15:47 | cwgem|mac | Lewis: might want to ask around in #lighttable as that's where I'd expect more help from |
| 15:47 | Lewis | cwgem|mac: its ok ill try something else |
| 15:49 | justin_smith | Lewis: if there's no side effects, nobody but the CPU cares that your function ran twice. With some kinds of side effects, (like running a monetary transaction or launching a weapon), doing the thing twice can be a problem |
| 15:49 | justin_smith | even doing the same file write twice can break things |
| 15:51 | cwgem|mac | Lewis: yeah as I mentioned you should take a look at the wiki page and see what's easiest to setup and work with that. I like Light Table but it's a bit different in how it handles the overall process than something like eclipse or netbeans |
| 15:52 | justin_smith | also, light table has bugs that will lose all your work when it crashes - for some people that's a deal breaker in an editor |
| 15:54 | Lewis | justin_smith: cwgem|mac ill look at vim |
| 15:55 | justin_smith | if you don't mind paying for an editor, cursive has an excellent featureset |
| 15:55 | justin_smith | I use vim currently myself (I like that I can easily ssh to my work box and work on the exact set of files I had last been looking at, with the help of tmux) |
| 15:56 | cwgem|mac | justin_smith: any bug reports etc on the Light Table crashing issue? Trying to find something like that in their issue tracker |
| 15:57 | justin_smith | cwgem|mac: sorry, it was anectdotal but I considered the source reliable (person I know from a local meetup) |
| 15:57 | cwgem|mac | justin_smith: I personally think I might put it on hold for a bit as it's a bit weird getting koans to work with it |
| 15:58 | justin_smith | cwgem|mac: I guess you could see what happens if you do a bunch of work without saving, then run kill -9 to force it to close - emacs or vim would have a file containing most or all of your work up to the point of that crash |
| 15:58 | justin_smith | (as would most other sensible editors I think, but those are the ones I have experience with) |
| 16:04 | Lewis | justin_smith: i use tmux/vim(yadr) im attempting to set up vim fireplace but it has a bunch of crazy dependencies |
| 16:04 | cwgem|mac | Hmm Cursive looks interesting |
| 16:06 | rhg135 | The good thing with it too is that it encourages doing the right thing |
| 16:06 | Lewis | https://github.com/guns/vim-clojure-static , how do you install it with vundle justin_smith |
| 16:06 | Lewis | rhg135: i also heard it makes easy to debug |
| 16:06 | justin_smith | Lewis: interesting - I use the vim-sensible package |
| 16:07 | rhg135 | Debugging async code, pfft |
| 16:07 | Lewis | rhg135: talking about cursive* |
| 16:07 | justin_smith | Lewis: I added pathogen as an autoload, then I checked out vim-clojure-static in my bundle directory |
| 16:07 | justin_smith | Lewis: that doesn't get your fireplace though, that's just a pre-req |
| 16:07 | Lewis | justin_smith: right that's a dep |
| 16:08 | justin_smith | so you can get pathogen.vim as a single file, put that in the autoloads dir, then clone vim-clojure-static in the bundle dir, and it just worked for me |
| 16:09 | rhg135 | The only reason I'm using it is because java |
| 16:09 | justin_smith | well, plus the pathogen.infect or whatever that is in the vimrc |
| 16:10 | rhg135 | I'm writing public domain code anyway. Licensing is not an issue |
| 16:11 | justin_smith | rhg135: wow, not just open source, but full public domain? |
| 16:11 | rhg135 | Yeah |
| 16:11 | Lewis | justin_smith: I'll try |
| 16:11 | rhg135 | Feel the freedom |
| 16:12 | Lewis | justin_smith: so pretty much installing pathogen |
| 16:12 | Lewis | :) |
| 16:12 | Lewis | lol |
| 16:12 | cwgem|mac | Well, it's still Java that has to run it, so there's only some freedom |
| 16:12 | rhg135 | Using copyleft to keep people honest seems complicated |
| 16:12 | noethics | why was the jvm chosen for clojure |
| 16:12 | justin_smith | we can avoid having to think about javac at least (most of the time) |
| 16:12 | noethics | easy? |
| 16:13 | justin_smith | noethics: widely available, large standard library |
| 16:13 | noethics | ok |
| 16:13 | noethics | stdlib makes sense i guess |
| 16:13 | justin_smith | there's some nice advantages - as anyone that has deployed both ruby and clojure to a server could probably tell you |
| 16:14 | cwgem|mac | Not only that but dealing with the annoying stuff like threading that the JVM does all over again isn't exactly fun |
| 16:14 | noethics | like what |
| 16:14 | justin_smith | noethics: repeatable builds - not needing a clean slate wipe of an entire system to reproduce a build environment |
| 16:14 | justin_smith | the fact that a deploy can be a single file uploaded, and that can just run |
| 16:14 | noethics | justin_smith, what are you comparing this to |
| 16:15 | justin_smith | noethics: ruby |
| 16:15 | noethics | most things fall into what you're talking about |
| 16:15 | noethics | oh |
| 16:15 | noethics | of course :P |
| 16:15 | noethics | i get you |
| 16:15 | justin_smith | I did say ruby above, right? |
| 16:15 | noethics | yeah |
| 16:16 | noethics | i'm not sure i really understand what you mean actually |
| 16:16 | noethics | given that both ruby and clojure need vms |
| 16:16 | justin_smith | but the existence of jars containing your deps (uberjars, fat jars, whatever you want to call them), is simpler to deploy than other things I've seen or tried. Also having version management that never requires global installs (and therefore doesn't require vms or sandboxing for basic day to day dev) |
| 16:17 | justin_smith | noethics: with ruby, you end up needing to worry about library versions, ruby version, and these typically are global installs |
| 16:17 | noethics | ok |
| 16:17 | backnforth | justin_smith, what if they're java dependencies? |
| 16:17 | justin_smith | not to mention native code dependencies (which are fairly common) |
| 16:17 | noethics | if this is interesting to you you might consider go :P |
| 16:17 | justin_smith | backnforth: you can pack them into the same jar with your code, and there is no need for a global install |
| 16:18 | backnforth | justin_smith, interesting |
| 16:18 | noethics | you compile a single binary and deploy that |
| 16:18 | noethics | no vm required |
| 16:18 | justin_smith | noethics: this is not the only reason I like clojure, but yes I hear go does these things somewhat sensibly too, haskell and ocaml as well (depending on tooling) |
| 16:18 | backnforth | noethics, Go is beautiful language and i have compared it to Clojure |
| 16:18 | rhg135 | You act like a VM is a bad thing |
| 16:18 | noethics | backnforth, not sure about beautiful :) |
| 16:18 | justin_smith | noethics: the vm is a single file, and that can be part of the machine build and doesn't need to change |
| 16:18 | noethics | it is great though |
| 16:19 | rhg135 | Well with jit |
| 16:19 | justin_smith | it's really not the pain point in any case I have seen |
| 16:19 | backnforth | noethics, harder to program with considering it's forced structures |
| 16:19 | backnforth | Go reminds much more of Python |
| 16:19 | backnforth | It is not a Lisp dialect |
| 16:19 | cwgem|mac | You can toss a .war up to a tomcat server, versus getting your rails code up, running bundler, etc. |
| 16:19 | noethics | ~_- |
| 16:19 | clojurebot | Excuse me? |
| 16:20 | noethics | is tomcat still used in new projects these days |
| 16:20 | noethics | in the clojure community? |
| 16:20 | justin_smith | noethics: elasticbeanstalk makes it easy to use tomcat as a target |
| 16:20 | noethics | $$$ though |
| 16:21 | justin_smith | noethics: I would never install it on my own machine, but it is easy to deploy to |
| 16:21 | justin_smith | typically I do a self hosting jar with aleph or http-kit though (for a web server) |
| 16:21 | noethics | ic |
| 16:21 | cwgem|mac | Just a random example of something that can take a packaged file and deploy it |
| 16:22 | justin_smith | yeah, there are multiple containers you can trivially deploy to, when you can make a compatible jar |
| 16:23 | Lewis | I didn't get the talk about deployment, it's hardly difficult in rubyh |
| 16:24 | noethics | you have to program in ruby though |
| 16:24 | noethics | ;) |
| 16:24 | cwgem|mac | If you use JRuby you could tap into the Java deployment method |
| 16:25 | Lewis | huh |
| 16:25 | Lewis | deploying a rails app seems pretty straight forward to me |
| 16:25 | Lewis | justin_smith: could you get fire place to work> 'no live repl' on my end |
| 16:26 | cwgem|mac | I'll say I don't hate ruby ( I work for a company that does a substantial amount of ruby deploys) and leave it at that since this is a Clojure channel ;) |
| 16:27 | ridcully | Lewis: have you started vim in the project root (where the .nrepl-port file is) or have you used `:Connect nrepl:///whattherepltoldyou` ? |
| 16:27 | noethics | fine |
| 16:29 | cwgem|mac | Regarding why the JVM it's about what, 20 or so years behind it as a VM so a lot of issues have been solved (to some decent extent). Compare that to rolling your own VM and hoping to get it right. |
| 16:30 | noethics | i personally use a lot of go |
| 16:30 | noethics | there isn't any need for a vm |
| 16:31 | ane | eh, it has a runtime too |
| 16:31 | noethics | a far different thing than a vm :P |
| 16:32 | ane | maybe not a JIT compiler and all that jazz |
| 16:32 | ane | but it's still managed code |
| 16:32 | noethics | define managed |
| 16:32 | noethics | the distinction is that you're running machine code |
| 16:32 | ane | garbage-controlled, thread management? |
| 16:32 | noethics | the runtime just handles gc/scheduling |
| 16:32 | ane | "just" |
| 16:32 | noethics | ? |
| 16:33 | ane | you shouldn't dismiss them like that |
| 16:33 | noethics | the runtime is also inlined into your binary |
| 16:34 | ane | sure is, that's what Clojure does as well |
| 16:34 | ane | but handling gc and scheduling isn't a minor thing |
| 16:34 | noethics | it inlines a full virtual machine :) |
| 16:34 | ane | no, it inlines the compiler |
| 16:34 | ane | the JVM runs that compiler |
| 16:35 | ane | if you want to compare Clojure to a completely VM-less language try Rust or C |
| 16:35 | noethics | i'm com[paring it to go because it's actually useable for the same problem space as clojure |
| 16:35 | noethics | they even have the same concurrency model! |
| 16:35 | ane | they don't |
| 16:35 | noethics | csp? |
| 16:35 | ane | clojure's innate concurrency model isn't CSP |
| 16:36 | noethics | because it runs on the jvm? |
| 16:36 | ane | no, that doesn't have anything to do with it |
| 16:36 | noethics | hmm |
| 16:36 | noethics | you mean outside of core.async? |
| 16:36 | ane | Clojure supports CSP with core.async, an external library |
| 16:36 | noethics | okay |
| 16:36 | noethics | what other method of doing concurrency is there? |
| 16:36 | noethics | java threads |
| 16:36 | noethics | ? |
| 16:37 | ridcully | refs, agents, atoms |
| 16:38 | ane | yeah |
| 16:38 | ane | CSP is orthogonal to those approaches in some way |
| 16:39 | noethics | csp is more than just message passing but |
| 16:39 | noethics | maybe i'm not understanding how you mean |
| 16:39 | noethics | how would you define a concurrency model |
| 16:40 | cwgem|mac | You don't have to have a VM persay, but with the JVM you have an abstraction around the different operating systems it supports, so (unless you use native OS code) you can hand someone a jar and mostly expect it to work |
| 16:40 | cwgem|mac | Now compare that to a go binary built on linux handed over to a windows user |
| 16:41 | noethics | yes you need multiple binaries |
| 16:41 | noethics | just like you have to rely that they have a jvm installed for their target operating system |
| 16:41 | noethics | go has some nifty cross compiling functionality out of the box though |
| 16:43 | cwgem|mac | yeah but I can tell someone "go install java" faster than explaining how to setup cross compiling. What it comes down to is each solution has some kind of sacrifice. Which sacrifice are you okay with decides what you use. |
| 16:43 | noethics | "go install java" or "here let me cross compile it for you" |
| 16:43 | noethics | :P |
| 16:43 | noethics | "don't forget to set PATH" |
| 16:44 | noethics | i dream of a day that clojure moves away from the jvm |
| 16:44 | tolstoy | I wouldn't mind seeing it built on top of Swift. |
| 16:44 | cwgem|mac | That would kill the ability for it to easily integrate into Java environments of which there are plenty |
| 16:45 | tolstoy | Maybe not "clojure moves away" but "clojure also available on LLVM, JS, and Java". |
| 16:46 | noethics | "clojure now comes with a legacy bytecode to llvm compiler and native llvm frontend" |
| 16:49 | Lewis | justin_smith: it seems to work now, i expected more though..I wish it was like javascript plugins that gives your line errors and all those goodies |
| 16:49 | Lewis | noethics: what do you prefer - go or clojure |
| 16:49 | noethics | as a language, clojure |
| 16:50 | Lewis | cwgem|mac: ane, cwgem|mac, noethics: what's a good ressource to learn more about what you guys just talked about: Vms, etc..I'm very ignorant on the topic |
| 16:50 | Lewis | noethics: for web apps |
| 16:50 | noethics | Lewis, i think it depends very much on the problem :P |
| 16:50 | noethics | i would almost always choose go because it's more enjoyable stack to work with |
| 16:51 | noethics | if i could write clojure for the go runtime i'd be insanely happy though |
| 16:51 | noethics | or anything really. i just don't really like having to lug around the jvm |
| 16:52 | tolstoy | I've used the JVM for so long, I don't recognize the tax anymore. |
| 16:52 | tolstoy | Install JVM, "java -jar myapp.jar", done. |
| 16:53 | backnforth | tolstoy, not all of us have used it for long |
| 16:53 | troydm | I've declared unbounded variable using declare |
| 16:53 | troydm | how do I check if a variable is bounded or not? |
| 16:53 | troydm | I've tried (bound? abc) but it doesn't works on unbounded variable |
| 16:54 | Lewis | noethics: I was debating between clojure and go for my next web project (a tough choice) |
| 16:54 | tolstoy | backnforth: Right! That's what I meant. |
| 16:54 | backnforth | (exist? abc) |
| 16:54 | noethics | Lewis, do you know both |
| 16:54 | backnforth | maybe, im not sure |
| 16:54 | Lewis | noethics: no |
| 16:54 | noethics | Lewis, do you know either |
| 16:54 | tolstoy | Lewis: Maybe Go on the server side, and Clojurescript for the client? |
| 16:54 | Lewis | noethics: i know go syntax |
| 16:54 | backnforth | ,(exist? abc) |
| 16:54 | clojurebot | #error {\n :cause "Unable to resolve symbol: exist? in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: exist? in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: exist? in t... |
| 16:54 | troydm | backnforth: no such function |
| 16:55 | noethics | what tolstoy said there is a super good decision |
| 16:55 | noethics | but if it means you have to learn a new language (or 2) |
| 16:55 | noethics | then weigh what is more important :P |
| 16:55 | tolstoy | noethics: I've wanted to do that on a project, but had no time to learn Go. |
| 16:55 | Lewis | tolstoy: I chose clojure because of reagent but I'm not looking forward to all those bad complain I hear about the JVM |
| 16:55 | noethics | completing the project, or learning said languuages |
| 16:55 | troydm | when I try bound? it gives me CompilerException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to clojure.lang.Var |
| 16:55 | backnforth | guys, sorry to cut off the conversation, but can someone answer my question in #clojure-beginners please |
| 16:55 | backnforth | thanks |
| 16:56 | cwgem|mac | https://docs.oracle.com/javase/specs/jvms/se7/html/index.html Here's a link on the JVM in detail |
| 16:56 | noethics | Lewis, to be clear the jvm is GREAT |
| 16:56 | Lewis | backnforth: I didn't know there was a clojure for beginners |
| 16:56 | noethics | itt's just big and noisy |
| 16:56 | cwgem|mac | Can search around for youtube for "JVM Architecture" or "JVM" in general as well |
| 16:56 | Lewis | cwgem|mac: holy cow, i was asing for a small summary to bring me up to speed with all the JVM gbc vs golang way of doing things talk |
| 16:57 | cwgem|mac | I'm not sure if anyone has really done that kind of talk before |
| 16:57 | Lewis | cwgem|mac: the argument you guys just had? |
| 16:58 | noethics | i think go wins on the backend (personally) because deployment is like the easiest thing NA |
| 16:58 | Lewis | noethics: How hard is it in clojure? |
| 16:58 | noethics | whereas with clojure you're probably dealing with some jetty stack |
| 16:59 | noethics | or maybe not, ut then who knows what you're dealing with :D |
| 16:59 | tolstoy | One thing the JVM has going for it in a lot of deployments is that most people know how to monitor it. |
| 16:59 | Bronsa | troydm: you need to check on the var object, on on the var value |
| 16:59 | Bronsa | (bound? #'your-var) |
| 16:59 | tolstoy | Tools to monitor the JVM can be independent of the app the JVM is running. (Basic ops, not business level, of course.) |
| 16:59 | noethics | like JVMTI and stuff |
| 17:00 | noethics | but tht degrades perf |
| 17:00 | noethics | you wouldnt use it in prod or anything |
| 17:00 | noethics | or maybe you would |
| 17:00 | Lewis | noethics: you're making me reconsider my choice (I hate that we have ten millions choices ) |
| 17:00 | noethics | Lewis, why not both :P |
| 17:00 | Lewis | i only have one lifetime |
| 17:01 | cwgem|mac | Lewis: here's a somewhat simplified explanation [PDF] http://www.cs.cornell.edu/courses/cs2112/2012sp/lectures/lec27-12sp.pdf [PDF] |
| 17:02 | noethics | Lewis, i think clojure is going to be easier to learn fwiw |
| 17:02 | noethics | go's syntax is simple but there are a lot of gotchas |
| 17:02 | tolstoy | Not too bad: https://en.wikipedia.org/wiki/Java_virtual_machine |
| 17:02 | noethics | specially with scoping and concurrency |
| 17:02 | Lewis | noethics: i learned goland pretty quickly |
| 17:03 | Lewis | well the basics |
| 17:03 | noethics | yeah P: but that's not where the trouble begins |
| 17:04 | noethics | another thing people stuggle with in go is lack of generics |
| 17:04 | noethics | everything you do is extremely adhoc and i think you need to understand that mindset to have a good time with go |
| 17:04 | ridcully | troydm: that should be (bound? #'abc) ? |
| 17:04 | noethics | in clojure you're free to do a lot of things |
| 17:05 | troydm | ridcully: hmm, let me think |
| 17:05 | Lewis | noethics: https://gist.github.com/6ewis/8bc789a14a46b921c16e |
| 17:06 | noethics | Lewis, decodeResponse should be a map[string]interface{} |
| 17:06 | noethics | but come to #go-nuts if you want to talk about it |
| 17:06 | noethics | :P |
| 17:06 | ridcully | hmm that's what Bronsa said already... didn't see |
| 17:08 | Lewis | cwgem|mac: thanks, tolstoy: thanks ill check it out |
| 17:08 | Lewis | noethics: no offense but go seems ten times easier, i pick it up in a day |
| 17:08 | Lewis | noethics: and actually did that exercise the same day |
| 17:08 | noethics | o im not offended at all :P |
| 17:09 | noethics | i think you will see what i mean |
| 17:09 | noethics | maybe not |
| 17:09 | noethics | Lewis, note the things i said were problems in go |
| 17:09 | noethics | you have 0 concurrency and very ltitle scoping here :) |
| 17:09 | Lewis | cwgem|mac: are you from cornell? |
| 17:10 | cwgem|mac | Lewis: No I just happened to come across it and found it somewhat reasonable in content :P |
| 17:10 | Lewis | noethics: how complicated scoping can be if you're coming from ruby or javascript? |
| 17:10 | noethics | Lewis, about the same |
| 17:11 | Lewis | noethics: easier actually |
| 17:11 | noethics | ?? |
| 17:11 | Lewis | noethics: from what I read* |
| 17:11 | clojurebot | ? is ! |
| 17:11 | noethics | you have the obvious late binding problem in js but there are way more gotchas than in js |
| 17:11 | noethics | YouWillSee(TM) |
| 17:11 | Lewis | noethics: I haven't touched concurrency though. I have never had to deal with it yet but I'll have to on my next project |
| 17:12 | Lewis | noethics: shame on you, you really have noethics you put goland back on my mind. Now I'll have to think about what's the best path to take again |
| 17:13 | noethics | :) |
| 17:14 | cwgem|mac | The answer is both paths at once :P |
| 17:15 | sdegutis | back |
| 18:00 | troydm | how do I make second argument to a function optional? |
| 18:00 | troydm | or rather I want to check if function that I get takes 2 or 1 arguments and act differently depending on that |
| 18:03 | justin_smith | troydm: you can define multiple arities to a function |
| 18:03 | justin_smith | but you can't check the arity a function accepts (now var for a defn, you can check that, and it will usually be useful - but more oriented to human readers) |
| 18:03 | troydm | justin_smith: I know but I get a function from calee as argument and I want to determine how many arguments that function can take |
| 18:04 | justin_smith | troydm: there's no way to do that |
| 18:04 | troydm | justin_smith: during runtime |
| 18:04 | justin_smith | troydm: you should be stricter about what functions someone can pass in, or expect them to pass args as a sequence and use apply |
| 18:04 | troydm | justin_smith: there is always a way (c) someone smart |
| 18:04 | justin_smith | troydm: trial and error, try/catch and when you get an arity error try something else? but that's bullshit, don't do it that way |
| 18:05 | justin_smith | troydm: there's no way to ask a function what argument count it takes and get a useful answer |
| 18:07 | justin_smith | troydm: you could look at what map does - it takes any number of colls and each becomes a source of one argument; or at swap! - it takes any number of args and passes them all to your swapping function after the value in the atom |
| 18:07 | troydm | justin_smith: found my answer http://stackoverflow.com/questions/17198044/how-can-i-determine-number-of-arguments-to-a-function-in-clojure |
| 18:07 | troydm | justin_smith: thx |
| 18:09 | justin_smith | troydm: so you are going to require that the var be passed in? |
| 18:10 | justin_smith | troydm: that means only supporting functions that are namespace level definitions |
| 18:10 | troydm | justin_smith: not sure what you mean, I just want my function to work with both (fn [a b] ) and (fn [a] ) arguments |
| 18:11 | justin_smith | troydm: the answer on that SO thread does not allow that |
| 18:11 | justin_smith | it only works for vars holding functions, not for functions - I mentioned the "require users to pass a var not a function" options above |
| 18:12 | troydm | justin_smith: I need it to work for vars holding functions only |
| 18:13 | justin_smith | troydm: OK |
| 18:56 | sdfgsadg | hello, could anyone give me a code review to see whether I'm writing idiomatic clojure, and what to fix/how to better model my data? I've tried #clojure-beginners but nobody has answered in several minutes |
| 19:01 | tolstoy | sdfgsadg Best to post a link and see if there are any takers. |
| 19:05 | sdfgsadg | Could I get a code review on this? https://bitbucket.org/pakoito/super8-clj/src/master/src/super8/ I want to know mostly whether the types I'm using to deal with mutable state in emu.clj are the correct ones, and whether the actual implementations are idiomatic cc @tolstoy |
| 19:06 | sdfgsadg | it's an emulator, so state is unavoidable. I'm porting from a terribly imperative codebase too, which doesn't help |
| 19:06 | sdfgsadg | thanks |
| 19:08 | sdegutis | brb |
| 19:10 | tolstoy | sdfgsadg: Looks fine to me. I guess some might say that you could hold all your state in an atom rather than refs. {:stack-point blah :program-counter blue} and so on. |
| 19:10 | sdfgsadg | train of thought was that given that only parts of it were updating at a time it need not block the whole map |
| 19:11 | tolstoy | sdfgsadg: Then on line 104, say, you can just (swap! state assoc :sp dec :pc (whatever)). But it's a bit unfair of me to say that given I don't know the code. |
| 19:12 | sdfgsadg | no, it's a fair point, I see what you mean |
| 19:12 | tolstoy | sdfgsadg: Well, that's a reasonable justification. |
| 19:12 | tolstoy | swap! doesn't lock for reads, I don't think. |
| 19:13 | sdfgsadg | are long let statements like the one in line 311 well regarded? |
| 19:13 | sdfgsadg | sometimes it feels like I could express all the logic save one return in it |
| 19:14 | tolstoy | For me, anyway, clarity is king. ;) |
| 19:15 | tolstoy | But you could do something like (let [{:keys [prog-c registers keys]} state] ....) destructure some of those things. But your way is easier to read. |
| 19:18 | tolstoy | Other than that, maybe you could put those dosync things behind functions, like (inc-program-counter state jump). Keep all the mutation in one place. |
| 19:19 | sdfgsadg | yup, I have to abstract that one |
| 19:19 | sdfgsadg | also collapse the =/!= opcodes |
| 19:19 | sdfgsadg | no need for duped code if it's just the operation that's different |
| 19:20 | tolstoy | Personally, I'm in favor of keeping things messy until one is nearly done, then seeing where the abstraction is appropriate. So I think the code looks great, in fact. |
| 19:22 | sdfgsadg | cool, many thanks :D |
| 19:24 | tolstoy | The only other thing I can think of is that a general pattern is that you pass in a state and get a new state back. |
| 19:24 | tolstoy | So, as you're processing each op-code, you'd do something like (loop [state init] (recur (process state next-opcode))) .... |
| 19:25 | tolstoy | If your emulator is just one code at a time, then maybe there's no need for mutation-in-place? |
| 19:28 | sdfgsadg | @tolstoy the actual op is a reduce, but I'm mutating the original map because performance, I guess |
| 19:28 | sdfgsadg | if I was to create a new state thousands of times per second it'd be too much |
| 19:28 | tolstoy | Ah. Well, there you go. Deviating from some common patterns for good reason. ;) |
| 19:28 | sdfgsadg | right now the emu is unbound |
| 19:29 | tolstoy | sdfgsadg: Well, but it's Clojure, so if you swap something onto a map, you're not creating a whole new state. It's fast. |
| 19:29 | sdfgsadg | you can see it in core, I'm actually passing back the same map |
| 19:29 | sdfgsadg | yeah it does the Persistance tree trick I guess |
| 19:29 | sdfgsadg | *trick as in the best part of Clojure collections :o |
| 19:29 | tolstoy | Yeah. |
| 19:30 | tolstoy | And then there's all that transient stuff I never use. But I don't see how dosync and so on are faster than just returning state with one key changed. |
| 19:30 | tolstoy | Sorry, that's sounds assertive: I just mean I really don't know. ;) |
| 19:31 | sdfgsadg | no, I'm learning, my assumption for going with that was multi-threading, which I won't implement because this is a learning project |
| 19:32 | sdfgsadg | and most emus/consoles are single threaded anyway |
| 19:32 | sdfgsadg | so no reason to descale it |
| 19:32 | sdfgsadg | *not to descale |
| 19:32 | sdfgsadg | I default to multi-threaded code because that's what I do day to day :P |
| 19:33 | tolstoy | Not that I know anything about how processors work, but you'd have to block anyway to switch context, etc, no? |
| 19:33 | sdfgsadg | you mean on the host or the emulated? |
| 19:33 | tolstoy | Well, hm. |
| 19:34 | tolstoy | I guess if you have multiple processes, each one seems single-threaded in and of itself (no shared memory). |
| 19:34 | sdfgsadg | the emulated isn't multi-threaded, it's ancient and just a step above a 7 segment display |
| 19:34 | tolstoy | So, each gets a "state". Can still do the loop technique. |
| 19:34 | tolstoy | Yeah. |
| 19:35 | sdfgsadg | yup, reducing on state makes sense to me, will change |
| 19:35 | tolstoy | Given the clarity of your code already, I'm hoping it be even simpler. |
| 19:35 | sdfgsadg | I have to return a vec or state/dirty, or reroll dirty inside the state again |
| 19:36 | sdfgsadg | dirty is not used by ops, so probably the vector/tuple return is the best option |
| 19:45 | sdegutis | back |
| 19:46 | sdegutis | what did i miss |
| 19:48 | tolstoy | sdfgsadg had a cool emulator. |
| 19:50 | sdegutis | oh cool |
| 19:50 | sdegutis | what did it emulate? |
| 19:50 | sdfgsadg | chip 8 |
| 19:51 | sdfgsadg | I'm learning emulators and clojure at the same time, I'm almost done with CFTB&T and did the koans a while ago |
| 19:51 | sdfgsadg | so I started with the simplest one that had a decent reference |
| 19:52 | sdfgsadg | chip8, I'm like 60% done with the opcodes and will use play-clj for the UI, as libgdx is my jam |
| 19:52 | sdfgsadg | then move onto something with more meat, NES or GBC |
| 20:09 | sdegutis | WELCOME |
| 20:13 | sdegutis | justin_smith: Rappaport! I haven't seen you in ages! How have you been? |
| 20:17 | libertytrader | Hi I am trying to parse a single command line argument in clojure using cli tools |
| 20:17 | libertytrader | It is not working at all |
| 20:17 | libertytrader | here is my code: |
| 20:17 | libertytrader | (def cli-options |
| 20:17 | libertytrader | [["-t" "--test" |
| 20:17 | libertytrader | :id test]]) |
| 20:17 | sdegutis | libertytrader: use gist |
| 20:18 | libertytrader | (if (= (:test (:options (parse-opts args cli-options))) true ) (println "true")(println "false")) |
| 20:18 | sdegutis | libertytrader: anyway i dont know what cli-tools is or how to use it |
| 20:18 | sdegutis | libertytrader: also, use gist |
| 20:18 | libertytrader | wtf is gist |
| 20:18 | libertytrader | and my code is small |
| 20:18 | TEttinger | http://gist.github.com |
| 20:18 | TEttinger | it's one of the many pastebins but most work allows viewing gist even if it blocks other pastebins |
| 20:19 | libertytrader | this is what I am trying use: https://github.com/clojure/tools.cli#example-usage |
| 20:19 | sdegutis | TEttinger: Rappaport! I haven't seen you in ages! How have you been? |
| 20:19 | libertytrader | Normally I would just try to use a repl... but how can i use a repl once i have launched app |
| 20:19 | TEttinger | eh? |
| 20:20 | sdegutis | TEttinger: You look taller than you used to be, did you grow? |
| 20:20 | sdegutis | TEttinger: Rappaport, you've got a new suit! |
| 20:20 | libertytrader | anyway here is my gist |
| 20:20 | libertytrader | https://gist.github.com/anonymous/699b95cd77d3c6503d44a1b67b0945cc |
| 20:20 | TEttinger | what's this? |
| 20:20 | sdegutis | TEttinger: now you say "I'm not Rappaport" |
| 20:21 | sdegutis | TEttinger: Rappaport, I don't remember you ever had glasses on? |
| 20:21 | sdegutis | (TEttinger: you're the straight man, you just say "I'm not Rappaport" whatever I say, ok?) |
| 20:21 | TEttinger | I've always had glasses on! Rattata, you remember this! |
| 20:22 | sdegutis | (Okay just say "I'm not rappaport" once) |
| 20:22 | sdegutis | (I set it up all wrong. It can still work though, just need this one line.) |
| 20:23 | TEttinger | I'm not rappaport |
| 20:23 | sdegutis | TEttinger: Rappaport, so you've gone and changed your name, too! |
| 20:23 | sdegutis | bu-dum tssh! |
| 20:24 | sdegutis | TEttinger: related: https://www.youtube.com/watch?v=F8yT24fnGJo |
| 20:24 | TEttinger | so confused |
| 20:24 | sdegutis | TEttinger: watch the video its 2 minutes |
| 20:25 | TEttinger | libertytrader: taking a look, is this code the ... in the block: (defn -main [& args] ... ) |
| 20:26 | sdegutis | Well this has been a spectacular failure. |
| 20:27 | libertytrader | Tettinger: yes |
| 20:28 | TEttinger | what's wrong with it, libertytrader? are you getting an exception or bad behavior or what? |
| 20:29 | libertytrader | It always evaluates to false |
| 20:29 | libertytrader | even with --test passed in |
| 20:30 | TEttinger | have you tried just printing (:options (parse-opts args cli-options)) so you know what you're working with? |
| 20:31 | TEttinger | using = true is generally not needed |
| 20:31 | libertytrader | how do i print out a map |
| 20:31 | libertytrader | ive tried to no success |
| 20:31 | TEttinger | ,(print {:options "like this"}) |
| 20:31 | clojurebot | {:options like this} |
| 20:31 | TEttinger | or better |
| 20:31 | TEttinger | ,(prn {:options "like this"}) |
| 20:31 | clojurebot | {:options "like this"}\n |
| 20:32 | TEttinger | also clojure.pprint/pprint |
| 20:32 | TEttinger | ,(clojure.pprint/pprint {:options "like this"}) |
| 20:32 | clojurebot | #error {\n :cause "clojure.pprint"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.pprint"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.n... |
| 20:32 | TEttinger | ,(use 'clojure.pprint) |
| 20:32 | clojurebot | nil |
| 20:32 | TEttinger | ,(pprint {:options "like this"}) |
| 20:32 | clojurebot | {:options "like this"}\n |
| 20:32 | TEttinger | same as prn here |
| 20:34 | TEttinger | (prn (:options (parse-opts args cli-options))) ;;; that's probably what you want |
| 20:34 | TEttinger | prn is print readably with newline |
| 20:35 | TEttinger | it prints vectors, maps, whatever you give it in a way that can usually be read back in as clojure code |
| 20:35 | libertytrader | I get unintelligible nonsense |
| 20:35 | libertytrader | {#object[clojure.core$test 0x61ff6a49 "clojure.core$test@61ff6a49"] true} |
| 20:35 | TEttinger | it's a map of some weird object to true |
| 20:36 | TEttinger | but that's not what I expected at all |
| 20:36 | libertytrader | I think the documenation for this api may be wrong |
| 20:38 | TEttinger | the code doesn't mention that class at all |
| 20:38 | TEttinger | ohhh! |
| 20:38 | TEttinger | ,(doc test) |
| 20:38 | clojurebot | "([v]); test [v] finds fn at key :test in var metadata and calls it, presuming failure will throw exception" |
| 20:38 | TEttinger | you have :id test |
| 20:39 | TEttinger | it should be :id :test |
| 20:39 | TEttinger | test is a valid ID, it's just an existing fn in clojure.core so unlike most names it happens to have a valid value |
| 20:39 | TEttinger | :test is what that should be |
| 20:40 | libertytrader | thank you so much |
| 20:40 | TEttinger | libertytrader: that's an odd one, it only happened because test is already defined and the name was actually valid. for almost any other name it would have given an error! |
| 20:41 | TEttinger | glad to help! |
| 20:42 | libertytrader | it made a big difference in my daily sanity |
| 20:42 | TEttinger | heh |
| 20:44 | sdegutis | hi |
| 20:44 | sdegutis | how do u print fibbonaci help plz thnx |
| 20:45 | TEttinger | sdegutis: golf-off |
| 20:46 | TEttinger | ,(take 5(map +(range)(iterate inc 1))) |
| 20:46 | clojurebot | (1 3 5 7 9) |
| 20:47 | TEttinger | hm. |
| 20:47 | TEttinger | there was a pattern for this |
| 20:48 | Lewis | what the heck is that |
| 20:48 | justin_smith | ,(iterate #(juxt second (partial apply +)) 1) |
| 20:48 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval49/fn--50> |
| 20:48 | justin_smith | ergh |
| 20:48 | justin_smith | ,(iterate #(juxt second (partial apply +)) [1 1]) |
| 20:48 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval75/fn--76> |
| 20:48 | justin_smith | ,(iterate (juxt second (partial apply +)) [1 1]) |
| 20:48 | clojurebot | ([1 1] [1 2] [2 3] [3 5] [5 8] ...) |
| 20:49 | Lewis | ,(iterate inc 1) |
| 20:49 | justin_smith | sorry that took so many tries, I blame the hornitos |
| 20:49 | clojurebot | (1 2 3 4 5 ...) |
| 20:49 | Lewis | justin_smith: thank you for earlier by the way |
| 20:49 | Lewis | ,(doc iterate) |
| 20:49 | clojurebot | "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects" |
| 20:49 | justin_smith | np, glad I could help |
| 20:50 | sdegutis | TEttinger: WHOA you won |
| 20:50 | justin_smith | sdegutis: he didn't print fibbonaci, he printed odd numbers |
| 20:50 | sdegutis | justin_smith: now whatever I say, you just say "I'm not Rappaport" |
| 20:50 | sdegutis | justin_smith: Rappaport, how've you been? I haven't seen you in ages? |
| 20:52 | justin_smith | I am not the eponymous character behind a play originally staged at the seattle reertory theater in 1984 |
| 20:52 | sdegutis | ,(->> (iterate inc 1) (map + (range)) (take 5)) |
| 20:52 | clojurebot | (1 3 5 7 9) |
| 20:52 | libertytrader | does anyone here use lighttable with vim bindings? Does anyone know how to make "/" for search and ":" for line number work |
| 20:52 | sdegutis | justin_smith: no no it was an old Willie Howard bit |
| 20:52 | sdegutis | justin_smith: now you be the straight man, I'll stand over here |
| 20:52 | sdegutis | justin_smith: Rappaport, what happened to you, you used to be a tall black guy now you're a short white guy? |
| 20:53 | justin_smith | I'm not rappaport |
| 20:53 | sdegutis | justin_smith: and you changed your name, too! |
| 20:53 | sdegutis | oh man |
| 20:53 | sdegutis | so good |
| 20:54 | sdegutis | libertytrader: did you see that? |
| 20:54 | sdegutis | haha! |
| 20:57 | libertytrader | what did i miss? |
| 20:59 | Lewis | libertytrader: vim |
| 20:59 | Lewis | I use vim and fireplace |
| 21:03 | TEttinger | ,(map first(reductions(fn[[a b]_][b(+ a b)])[1 1](range 5))) |
| 21:03 | clojurebot | (1 1 2 3 5 ...) |
| 21:04 | TEttinger | love reductions |
| 21:04 | TEttinger | I can get it shorter... |
| 21:06 | Lewis | (doc nth) |
| 21:06 | clojurebot | "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences." |
| 21:06 | libertytrader | is there a idiomatic way to say not equal in clojure? |
| 21:06 | libertytrader | instead of (not (= ...)) |
| 21:07 | Lewis | the type signature is weird |
| 21:07 | Lewis | ,(not= 1 2) |
| 21:07 | clojurebot | true |
| 21:07 | Lewis | libertytrader: ^^ |
| 21:07 | justin_smith | Lewis: type signature? |
| 21:08 | justin_smith | ,(nth [] 3 :something-else) ; you mean the arg list? |
| 21:08 | clojurebot | :something-else |
| 21:08 | sdegutis | i dont underst-- oh |
| 21:09 | Lewis | justin_smith: i mean the clojure type signature in the doc, what the args take and what it returns |
| 21:09 | justin_smith | Lewis: that's an args list |
| 21:10 | justin_smith | it doesn't describe what it returns at all - it just describes more than one arity |
| 21:10 | justin_smith | all it gives you for args is names |
| 21:11 | justin_smith | Lewis: it's saying that there are two argument counts for nth, I used the second one above |
| 21:11 | Lewis | justin_smith: for example check it out |
| 21:11 | Lewis | ,(doc nth) |
| 21:11 | clojurebot | "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences." |
| 21:11 | justin_smith | Lewis: yes I saw that the first time |
| 21:11 | Lewis | ([coll index] [coll index not-found]) |
| 21:11 | Lewis | can you explain it |
| 21:11 | justin_smith | it describes two lists of args |
| 21:11 | justin_smith | it does not describe the return value |
| 21:12 | justin_smith | you can either do (nth coll index) or (nth coll index not-found) |
| 21:12 | justin_smith | ,(nth [1 2 3] 1) |
| 21:12 | clojurebot | 2 |
| 21:12 | Lewis | i see |
| 21:12 | justin_smith | ,(nth [1 2 3] 42 :not-there) |
| 21:12 | clojurebot | :not-there |
| 21:12 | Lewis | i see thanks |
| 21:14 | justin_smith | ,(defn foo "many ways of getting nil" ([]) ([a]) ([a b]) ([a b c]) ([a b c d])) |
| 21:14 | clojurebot | #'sandbox/foo |
| 21:14 | justin_smith | ,(doc foo) |
| 21:15 | clojurebot | "([] [a] [a b] [a b c] [a b c d]); many ways of getting nil" |
| 21:17 | Lewis | ,(iterate (fn [[a b]] [b (+ a b)]) [0 1]) |
| 21:17 | clojurebot | ([0 1] [1 1] [1 2] [2 3] [3 5] ...) |
| 21:18 | Lewis | ,(first (iterate (fn [[a b]] [b (+ a b)]) [0 1])) |
| 21:18 | clojurebot | [0 1] |
| 21:18 | justin_smith | Lewis: yes, (fn [[a b]] [b (+ a b)]) is another way to write (juxt second (partial apply +)) |
| 21:18 | TEttinger | ,(map #(int(+(/(Math/pow 1.618 %)2.236)0.5))(range)) |
| 21:18 | clojurebot | (0 1 1 2 3 ...) |
| 21:19 | TEttinger | justin_smith: not quite |
| 21:19 | justin_smith | TEttinger: wow, sneaky! |
| 21:19 | TEttinger | mine had a _ |
| 21:19 | TEttinger | to allow the second arg of reduce fns |
| 21:19 | TEttinger | binet's formula, justin_smith |
| 21:19 | justin_smith | TEttinger: I was comparting to Lewis' function - which is identical to mine but written differently, not to your reduce |
| 21:19 | Lewis | ,(take 10 (def fib (map (first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))))) |
| 21:19 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Var> |
| 21:20 | TEttinger | oh ok |
| 21:20 | justin_smith | Lewis: def returns a var, and that function never got called |
| 21:20 | justin_smith | ,(take 10 @(def fib (map (first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))))) |
| 21:21 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$map$fn__4781> |
| 21:21 | Lewis | ,(take 10 ((def fib (map (first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))))) |
| 21:21 | clojurebot | #error {\n :cause "Wrong number of args (0) passed to: core/map/fn--4781"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: core/map/fn--4781"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 28]\n [clojure.lang.Var invoke "Var.java" 375]\n [sandbox$e... |
| 21:21 | Lewis | ,(def fib (map (first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))) |
| 21:21 | clojurebot | #'sandbox/fib |
| 21:21 | Lewis | ,(take 10 fib) |
| 21:21 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$map$fn__4781> |
| 21:21 | justin_smith | Lewis: why is first preceded by a paren? |
| 21:22 | Lewis | ,(def fib (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))) |
| 21:22 | clojurebot | #'sandbox/fib |
| 21:22 | Lewis | ,(take 10 fib) |
| 21:22 | clojurebot | (0 1 1 2 3 ...) |
| 21:22 | Lewis | justin_smith: thanks |
| 21:22 | justin_smith | ,(map first (iterate (juxt second (partial apply +)) [1 1])) |
| 21:22 | clojurebot | (1 1 2 3 5 ...) |
| 21:26 | Lewis | ,(doc juxt) |
| 21:26 | clojurebot | "([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]" |
| 21:27 | Lewis | what does it mean in english? |
| 21:27 | justin_smith | ,((juxt dec identity inc) 0) |
| 21:27 | clojurebot | [-1 0 1] |
| 21:27 | justin_smith | ,((juxt name symbol keyword) "hi") |
| 21:27 | clojurebot | ["hi" hi :hi] |
| 21:28 | Lewis | justin_smith: can you give me an example with each set of arguments given in the doc please? |
| 21:28 | Lewis | ([f] [f g] [f g h] [f g h & fs]) |
| 21:29 | justin_smith | ,((juxt inc) 0) |
| 21:29 | clojurebot | [1] |
| 21:29 | justin_smith | ,((juxt inc identity) 0) |
| 21:29 | clojurebot | [1 0] |
| 21:29 | justin_smith | do I need to do more? |
| 21:30 | Lewis | justin_smith: [f g h & fs]) |
| 21:31 | justin_smith | ,((juxt :a :b :c :d :e :f :g) {:a 0 :b 42 :c 33 :d 666 :e 420 :g 2 :f false}) |
| 21:31 | clojurebot | [0 42 33 666 420 ...] |
| 21:33 | Lewis | justin_smith: what does fs mean |
| 21:34 | Lewis | & fs |
| 21:36 | sdegutis | ,((fnil nil? 0) nil) |
| 21:36 | clojurebot | false |
| 21:36 | sdegutis | HAHAHA |
| 21:37 | Lewis | (doc fnil) |
| 21:37 | clojurebot | "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched." |
| 21:40 | justin_smith | Lewis: it describes a rest-param http://clojure.org/reference/special_forms#fn |
| 21:41 | justin_smith | ,((fn [a b & cs] cs) 1 2 3 4 5 6) |
| 21:41 | clojurebot | (3 4 5 6) |
| 21:42 | Lewis | i see |
| 22:34 | sdegutis | hi |
| 22:34 | sdegutis | wait brb |
| 22:34 | sdegutis | in like lots of hours |
| 22:39 | dpzmick | hi everyone, I'm running some benchmarks of some code on google's cloud. I expect some variablilty in my timings, but I'm getting some strange results. I have java code and clojure code. The java code tends to have much more consistent performance than the clojure code though. Both of them are being run through lein with the same profile. Both are doing similar things. Can anyone think of a reason I get much, much larger variance o |
| 22:39 | dpzmick | heres java: http://pasteboard.co/2Lr08NhF.png |
| 22:40 | dpzmick | heres clojure: http://pasteboard.co/2Lr2Adki.png |
| 22:41 | justin_smith | dpzmick: one guess (not seeing code) is that clojure puts more pressure on the short term gc |
| 22:43 | dpzmick | justin_smith: I know my code is putting lots of pressure on the gc |
| 22:43 | justin_smith | and the effects of gc are unpredictable (which leads to larger variance) |
| 22:43 | dpzmick | justin_smith: The java code has about the same logic, but it's not implementing that logic with first class functions and clojure structures |
| 22:43 | dpzmick | this makes lots of sense |
| 22:44 | dpzmick | so I may be able to tune gc flags to get some tighter values |
| 22:44 | justin_smith | maybe - or use more things like transients and transducers that can reduce gc usage |
| 22:45 | justin_smith | (if used apropriately, may or may not be helpful on your code, of course) |
| 22:45 | dpzmick | Won't help in this case unfortunately. |
| 22:45 | dpzmick | I'm just computing fiboancci recusively in this example |
| 22:46 | dpzmick | with some macro magic that turns the computation into a bunch of fork/join tasks |
| 22:46 | dpzmick | which is pretty rough on the gc |
| 22:48 | justin_smith | you could also look at numeric reflection - there's a flag to warn for that |
| 22:49 | justin_smith | because boxing is allocation, and you can usually eliminate it (at least in the tight spots) with the right annotations |
| 22:50 | justin_smith | dpzmick: http://insideclojure.org/2014/12/15/warn-on-boxed/ |
| 22:52 | dpzmick | justin_smith: I've added type annotations already but perhaps I'm missing something, will try the flag as well |
| 23:29 | user_ | maybe someone here can enlightenment me. I'm sorry for asking the same question a few times, but how do I count the amount of values a map in a vector holds? |
| 23:34 | user_ | Not descriptive enough>? |
| 23:46 | TEttinger | user_: as in multiple maps in a vector, or a specific one? |
| 23:47 | TEttinger | ,(count (apply concat [{:a 1 :b 2}])) |
| 23:47 | clojurebot | 2 |
| 23:47 | TEttinger | ,(count (apply concat [{:a 1 :b 2} {:c 3 :d 4}])) |
| 23:47 | clojurebot | 4 |
| 23:47 | TEttinger | also |
| 23:48 | TEttinger | ,(apply count [{:a 1 :b 2}]) |
| 23:48 | clojurebot | 2 |
| 23:48 | TEttinger | ,(apply count [{:a 1 :b 2} {:c 3 :d 4}]) ;; I believe this fails |
| 23:48 | clojurebot | #error {\n :cause "Wrong number of args (2) passed to: core/count"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/count"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [clojure.lang.AFn applyToHelper "AFn.java" 156]\n [clojure.lang.AFn... |
| 23:52 | TEttinger | dpzmick: just curious, but I wonder if your actual task is similar to fibonacci in terms of a sequence generator. if it is, it might be worth it to calculate a closed-form solution OH GOD THIS IS TURNING INTO #haskell |
| 23:53 | TEttinger | but really closed form solutions are interesting stuff |
| 23:54 | dpzmick | TEttinger: yeah that would be the right way to do fib. I'm doing a benchmark to see how much of a speedup I can get for a low intensity, embarassingly parallel problem though |
| 23:54 | TEttinger | mmm. |
| 23:54 | TEttinger | pmap is probably not the best example of parallelism in Clojure |
| 23:54 | dpzmick | akin to the fork/join fib examples, but I have clojure macros taking (defn fib ...) and spitting out fork join code |
| 23:54 | TEttinger | ah ok |
| 23:54 | dpzmick | pmap is interesting, but it's not "control flow parallel" |
| 23:55 | TEttinger | yeah pmap is mostly useless in practice it seems, since it doesn't allow much manipulation of the number of threads etc |
| 23:55 | dpzmick | I'm trying to find easy ways to parallelize control flow (eg pure recursive functions) as a proof of concept |
| 23:55 | user_ | (let [listInput [] listInput (conj listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}])] (print (count (:paths(nth listInput 1))))) |
| 23:55 | dpzmick | who knows if its actually useful. I found some paper saying that people generally use data parallel things much more often than task parallel |
| 23:55 | user_ | TEttinger, I'd want count to return 2 |
| 23:56 | TEttinger | well let's run it with the comma prefix |
| 23:56 | TEttinger | ,(let [listInput [] listInput (conj listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}])] (print (count (:paths(nth listInput 1))))) |
| 23:56 | clojurebot | #error {\n :cause nil\n :via\n [{:type java.lang.IndexOutOfBoundsException\n :message nil\n :at [clojure.lang.PersistentVector arrayFor "PersistentVector.java" 158]}]\n :trace\n [[clojure.lang.PersistentVector arrayFor "PersistentVector.java" 158]\n [clojure.lang.PersistentVector nth "PersistentVector.java" 162]\n [clojure.lang.RT nth "RT.java" 853]\n [sandbox$eval121 invokeStatic "NO_SOURC... |
| 23:56 | user_ | TEttinger, I tried so many techniques, very frustrating |
| 23:56 | TEttinger | oh of course |
| 23:57 | TEttinger | conj doesn't modify listInput |
| 23:57 | dpzmick | TEttinger: paper: http://dig.cs.illinois.edu/papers/StudyParallelLibraries.pdf |
| 23:57 | TEttinger | oh you redefine it nvm |
| 23:57 | user_ | TEttinger, maybe a straight binding would have looked better |
| 23:57 | user_ | TEttinger, I was suggested that a few weeks ago on irc lol |
| 23:57 | user_ | . |
| 23:58 | user_ | i tried so many variations |
| 23:59 | TEttinger | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (count (:paths(nth listInput 1))))) |
| 23:59 | clojurebot | 2 |
| 23:59 | TEttinger | I think the conj was producing a different vector than you thought |
| 23:59 | user_ | no way. |
| 23:59 | user_ | i think it added a nil vector |
| 23:59 | user_ | to the main vector |
| 23:59 | TEttinger | ,(let [listInput [] listInput (conj listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}])] listInput) |
| 23:59 | clojurebot | [[{:paths [[:node 1 :cost 1] [:node 2 :cost 2]]} {:paths [[:node 2 :cost 1] [:node 3 :cost 2]]} {:paths [[:node 0 :cost 1] [:node 1 :cost 2]]}]] |