#clojure log - Apr 03 2016

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:00 tolstoy: I don't know what "vectors with a namespace :node" means. Maybe just show a couple?

0:00 backnforth: ah

0:00 ok

0:01 , [someVector [:node [1], :node [4], :node [9]]

0:01 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

0:01 backnforth: , [someVector [:node [1], :node [4], :node [9]]]

0: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...

0:01 backnforth: something like that

0:01 I wanted to the count of 3 for the count of :node

0:02 tolstoy: ,(count (filter #(= % :node) [:node [1], :node [4], :node [9]]))

0:02 clojurebot: 3

0:03 tolstoy: Something like that?

0:03 backnforth: gross

0:03 use filter?

0:03 tolstoy: Heh. ;)

0:03 backnforth: its so alient to me

0:03 alien

0:03 i will look into it

0:03 thanks

0:03 wow, im learning so much so fast

0:03 this is great

0:04 tolstoy: ,(:node (frequencies [:node [1], :node [4], :node [9]]))

0:04 clojurebot: 3

0: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?

0: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.

0:05 will_sm: Instaparse to design your own language.

0:05 Well, sort of, anyway.

0:24 sdegutis: Is there a way to combine dec and max-0?

0:25 I guess (comp (partial max 0) dec)

0:28 ,(def dec-pos (comp (partial max 0) dec))

0:28 clojurebot: #'sandbox/dec-pos

0:28 sdegutis: ,(map dec-pos [-2 -1 0 1 2 3])

0:28 clojurebot: (0 0 0 0 1 ...)

0:29 sdegutis: ,(map dec-pos [0 1 2 3])

0:29 clojurebot: (0 0 1 2)

0:29 sdegutis: Yay!

0:30 justin_smith: not to be confused with dec-comp-pos-e

0:43 backnforth: wow

0:43 filter wont include a map if its value is false

0:50 tolstoy: Huh. Clojure's pretty good at, uh, s-expressions. ;)

0:50 Read in some forms that reference forms you previously read in, and, boom: there's postwalk-replace all ready for you.

0:56 sdegutis: backnforth: filter with some? if needed then I guess

0:57 backnforth: i like it, its very simple and useful

0:58 reminds me of grep

1:41 Lewis: ,(some #{false} [false false false])

1:41 clojurebot: nil

1: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?

1:41 Lewis: why?

1:41 clojurebot: why is startup slow is busy compiling the `for` macroexpansion

1:41 makufiru: sorry wrong channel

2:09 ridcully: Lewis: because false is not logical true

2:09 ,(doc some)

2: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)"

2:09 ridcully: ,(some (partial = false) [false false])

2:09 clojurebot: true

2:10 Lewis: ridcully: what does logicaly true mean

2:12 ,(some #{nil} [nil nil nil])

2:12 clojurebot: nil

2:12 ridcully: neither nil nor false

2:12 Lewis: I see

2:13 ridcully: what book do you advise

2:13 ridcully: ,(some (partial contains? #{false nil}) [1 nil false])

2:13 clojurebot: true

2:16 Lewis: ,(some (partial #{false nil}) [1 nil false])

2:16 clojurebot: nil

2: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

2:16 Lewis: ,(doc contains?)

2: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'."

2:17 ridcully: others suggested the "brave" book and the one from Carin Meier (spl?!) for beginners

2:17 Lewis: so joy of clojure and clojure applied are for intermediate?

2:18 ridcully: i see.

2:19 ridcully: i'd say clojure applied is for you, if you have delivered software in other languages

2:19 ,(#{1 2 3} 1)

2:19 clojurebot: 1

2:20 ridcully: the problem with using the set as a function here is, that it returns the element found - which is "the" false

2:21 contains? on the other hand will tell you if the item is in the set

2:24 Lewis: ridcully: right i think i got it

2:31 ridcully: what language are you coming from?

2:48 ridcully: Lewis: groovy on the jvm and c++, python otherwise

2:49 Lewis: i see

2:49 ridcully: i dont know anything about the jvm

2:55 ,

2:55 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:55 Lewis: ,(doc conj)

2: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."

9:12 ARM9: is there any decent way to leverage the jvm jit compiler to build programs at runtime?

9:12 like say I've got some simpler functions that I'd want to combine into one function based on some input at runtime

9:13 call it dynamic recompilation if you will

9:14 justin_smith: ARM9: the clojure bytecode compiler is always present during runtime in clojure

9:15 you don't need jit just to get something compiled

9:16 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.

9: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

9: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...

9:21 ARM9: I know how the jit works

9:21 justin_smith: ARM9: OK, have fun then

9:21 you can compile byte code at runtime in clojure. The JIT decides what to compile and how. That's your answer.

9:22 ARM9: yes and what I'm looking for is how to compile byte code at runtime

9:22 justin_smith: ARM9: by defining something

9:22 ARM9: every time you evaluate a clojure expression, it is compiled

9:22 Empperi: oh god I'm going nuts with boot soon

9:22 I love the concept but man

9:23 right now I just can't get my cljs compilation to end up into the target path I want it to

9:23 yes, I know about the foo.cljs.edn thingy

9:23 but it just doesn't read it apparently

9: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.

9:23 Empperi: feels like only thing I can get to work properly is the stuff I define myself...

9: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.

9:37 ARM9: right, fortunately for me I don't need it to be idiomatic

9:37 like I said I just need some pointers on leveraging the jvm from clojure if at all possible, instead of writing my own jit

9:37 justin_smith: ,(defn compile-a-thing [] (eval '(fn [])))

9:37 clojurebot: #'sandbox/compile-a-thing

9:38 justin_smith: that compiles bytecode every time it is called

9:38 you'll essentially be writing a macro definition, wrapped in eval

9:38 ARM9: that's good, I'll keep playing with eval then

9:38 cheers

9:38 justin_smith: ,(= (compile-a-thing) (compile-a-thing))

9:38 clojurebot: false

9: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 ane: like what

13:20 ane: the G1 GC becomes the default

13:21 also Jigsaw, which lets you break the JRE into smaller components so you can drop the stuff you don't need

13:21 native JSON support... uh what else, units of measure (!)

13:40 sdegutis: ane: JSON sounds nice

13:41 ane: Jigsaw sounds useless with Clojure

13:41 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 but they can't specify any version constraints, and you can only have one unique instance of a module in play

14:21 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 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 *over not representing...

15:17 Lewis: hey

15:17 https://gist.github.com/6ewis/dcd71252a1277ed8d7b94e391a04d124

15:17 can someone explain to me why 2 is showed twice

15:18 justin_smith: Lewis: swap! retries if concurrent modification occurs

15:19 Lewis: this is why you should not put anything with important side-effects inside a swap! call

15:19 Lewis: so two threads overlapped when incrementing from 1 to 2, one of them retried

15:19 (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 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 Lewis: if the value has changed, it runs your function over, but with the new value as input

15:25 Lewis: this is repeated until the same value is read twice, in every call to swap!

15:26 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 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 "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 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 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 (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 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 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 :)

16:12 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 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 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 oh

16:15 of course :P

16:15 i get you

16:15 justin_smith: I did say ruby above, right?

16:15 noethics: yeah

16:16 i'm not sure i really understand what you mean actually

16:16 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 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 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 Go reminds much more of Python

16:19 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 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 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 ;)

16:24 cwgem|mac: If you use JRuby you could tap into the Java deployment method

16:24 * noethics doesn't sense enough disdain for ruby here

16:25 Lewis: huh

16:25 deploying a rails app seems pretty straight forward to me

16:25 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 puts away pitchfork

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 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 but it's still managed code

16:32 noethics: define managed

16:32 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 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 the JVM runs that compiler

16:35 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 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 you mean outside of core.async?

16:36 ane: Clojure supports CSP with core.async, an external library

16:36 noethics: okay

16:36 what other method of doing concurrency is there?

16:36 java threads

16:36 ?

16:37 ridcully: refs, agents, atoms

16:38 ane: yeah

16:38 CSP is orthogonal to those approaches in some way

16:39 noethics: csp is more than just message passing but

16:39 maybe i'm not understanding how you mean

16:39 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 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 just like you have to rely that they have a jvm installed for their target operating system

16:41 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 :P

16:43 "don't forget to set PATH"

16:44 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 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 noethics: for web apps

16:50 noethics: Lewis, i think it depends very much on the problem :P

16:50 i would almost always choose go because it's more enjoyable stack to work with

16:51 if i could write clojure for the go runtime i'd be insanely happy though

16:51 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 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 how do I check if a variable is bounded or not?

16:53 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 but if it means you have to learn a new language (or 2)

16:55 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 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 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 (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 but tht degrades perf

17:00 you wouldnt use it in prod or anything

17:00 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 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 well the basics

17:03 noethics: yeah P: but that's not where the trouble begins

17:04 another thing people stuggle with in go is lack of generics

17:04 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 but come to #go-nuts if you want to talk about it

17:06 :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 noethics: no offense but go seems ten times easier, i pick it up in a day

17:08 noethics: and actually did that exercise the same day

17:08 noethics: o im not offended at all :P

17:09 i think you will see what i mean

17:09 maybe not

17:09 Lewis, note the things i said were problems in go

17:09 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 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 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 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 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 troydm: there's no way to ask a function what argument count it takes and get a useful answer

18:07 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 justin_smith: thx

18:09 justin_smith: troydm: so you are going to require that the var be passed in?

18:10 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 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 it's an emulator, so state is unavoidable. I'm porting from a terribly imperative codebase too, which doesn't help

19:06 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 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 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 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 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 also collapse the =/!= opcodes

19:19 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 So, as you're processing each op-code, you'd do something like (loop [state init] (recur (process state next-opcode))) ....

19:25 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 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 yeah it does the Persistance tree trick I guess

19:29 *trick as in the best part of Clojure collections :o

19:29 tolstoy: Yeah.

19:30 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 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 and most emus/consoles are single threaded anyway

19:32 so no reason to descale it

19:32 *not to descale

19:32 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 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 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 dirty is not used by ops, so probably the vector/tuple return is the best option

19:45 sdegutis: back

19:46 what did i miss

19:48 tolstoy: sdfgsadg had a cool emulator.

19:50 sdegutis: oh cool

19:50 what did it emulate?

19:50 sdfgsadg: chip 8

19:51 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 so I started with the simplest one that had a decent reference

19:52 chip8, I'm like 60% done with the opcodes and will use play-clj for the UI, as libgdx is my jam

19:52 then move onto something with more meat, NES or GBC

20:09 sdegutis: WELCOME

20:13 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 It is not working at all

20:17 here is my code:

20:17 (def cli-options

20:17 [["-t" "--test"

20:17 :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 libertytrader: also, use gist

20:18 libertytrader: wtf is gist

20:18 and my code is small

20:18 TEttinger: http://gist.github.com

20:18 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 TEttinger: Rappaport, you've got a new suit!

20:20 libertytrader: anyway here is my gist

20:20 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 TEttinger: Rappaport, I don't remember you ever had glasses on?

20:21 (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 (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 bu-dum tssh!

20:24 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 sighs

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 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 using = true is generally not needed

20:31 libertytrader: how do i print out a map

20:31 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 ,(prn {:options "like this"})

20:31 clojurebot: {:options "like this"}\n

20:32 TEttinger: also clojure.pprint/pprint

20:32 ,(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 (prn (:options (parse-opts args cli-options))) ;;; that's probably what you want

20:34 prn is print readably with newline

20:35 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 {#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 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 ohhh!

20:38 ,(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 it should be :id :test

20:39 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 :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 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 how do u print fibbonaci help plz thnx

20:45 TEttinger: sdegutis: golf-off

20:46 ,(take 5(map +(range)(iterate inc 1)))

20:46 clojurebot: (1 3 5 7 9)

20:47 TEttinger: hm.

20:47 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 ,(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 ,(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 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 justin_smith: now you be the straight man, I'll stand over here

20:52 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 oh man

20:53 so good

20:54 libertytrader: did you see that?

20:54 haha!

20:57 libertytrader: what did i miss?

20:59 Lewis: libertytrader: vim

20:59 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 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 instead of (not (= ...))

21:07 Lewis: the type signature is weird

21:07 ,(not= 1 2)

21:07 clojurebot: true

21:07 Lewis: libertytrader: ^^

21:07 justin_smith: Lewis: type signature?

21:08 ,(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 it doesn't describe what it returns at all - it just describes more than one arity

21:10 all it gives you for args is names

21:11 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 ,(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 can you explain it

21:11 justin_smith: it describes two lists of args

21:11 it does not describe the return value

21:12 you can either do (nth coll index) or (nth coll index not-found)

21:12 ,(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 to allow the second arg of reduce fns

21:19 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 ,(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 ([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 & 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 ,((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 wait brb

22:34 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 heres java: http://pasteboard.co/2Lr08NhF.png

22:40 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 this makes lots of sense

22:44 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 (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 I'm just computing fiboancci recusively in this example

22:46 with some macro magic that turns the computation into a bunch of fork/join tasks

22:46 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 because boxing is allocation, and you can usually eliminate it (at least in the tight spots) with the right annotations

22:50 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 Not descriptive enough>?

23:46 TEttinger: user_: as in multiple maps in a vector, or a specific one?

23:47 ,(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 ,(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 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 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 ,(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 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 TEttinger, I was suggested that a few weeks ago on irc lol

23:57 .

23:58 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 i think it added a nil vector

23:59 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]]}]]

Logging service provided by n01se.net