#clojure log - Sep 14 2015

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

0:00 Trioxin: strange, lein is working from command prompt now but not from in IDEA. it's in user path

0:01 could also add to system path

0:03 hah got it

0:04 Leiningen 2.5.2 on Java 1.8.0_60 Java HotSpot(TM) 64-Bit Server VM

0:04 * Trioxin back to tutorials

0:05 Trioxin: thx for help guys

0:43 I did this last night correctly. what am I doing wrong now? http://screencast.com/t/PLkgkgDlUA

0:45 I right clicked "Run REPL for project4" so it connected, then switched to project4.core and tools -> REPL -> Switch REPL NS to current file

0:46 but have no access to foo .. (defn foo [x] (println x "Hello, World!")) from the REPL window

0:47 justin_smith: Trioxin: do you need to tell it to load the namespace first?

0:47 before telling it to switch to it

0:48 in a normal repl, you would have the two steps separately

0:48 Trioxin: ill try

0:54 okay I got it. I switched to the file (There was a button for switch to) then I ran load current file in REPL and then finally switched NS to current file

0:55 so when I finally go and build my project the end result will be a jar?

0:55 justin_smith: yeah, so that sounds like the right sequence

0:55 yes, it will make a jar you can run via java

0:56 so your deploy environment doesn't need to have clojure or any of your other libs or lein

0:56 just java

0:56 or, with some plugins you can make a package that can be loaded in a container (eg. uberwar for running inside tomcat on beanstalk)

0:56 Trioxin: ok and then from there I can go about packaging, making executables, packaging the JRE if I want to or whatever

0:57 if it's some software I'm selling I mean

0:57 justin_smith: well "packaging" is mostly done by the uberjar process. I guess you can ship a jre if you want, but it will run on any reasonably modern jre so someone could just use their own

0:58 the key thing is that the uberjar puts everything needed to run your code into one file, except the jvm itself

0:59 Trioxin: is that part of the IDEA/cursive build process?

1:00 justin_smith: it's something lein does (though cursive should make lein do it if you go to build the project)

1:00 TEttinger: it's a lein command. I believe cursive doesn't produce an uberjar for every build?

1:00 cfleming: No, Cursive doesn't do anything like that

1:00 TEttinger: for me, uberjars take a while to make but cursive runs the program quickly

1:02 Trioxin: "We recommend against using uber-JARs. They introduce many problems for downstream consumers. "

1:02 oh that was on the fii site

1:03 justin_smith: who's

1:03 ?

1:03 Trioxin: http://fiji.sc/Uber-JAR

1:04 was just looking for how to do it

1:04 and that came up in the results

1:04 justin_smith: Trioxin: uberjars should be used for apps, not for libs

1:04 Trioxin: apps are what I'm trying to make

1:05 justin_smith: yeah, I would agree with the fiji folks that uberjars are annoying with libs, but when I am deploying apps uberjars have always worked for me

1:05 though I am deploying to my own servers, not to clients...

1:06 Trioxin: https://github.com/technomancy/leiningen/blob/master/src/leiningen/uberjar.clj

1:06 raspasov: same here, no problems with uberjars for apps, they work great

1:07 justin_smith: Trioxin: oh man I submitted a silly thing to that namespace

1:07 Trioxin: so lein can make my uberjar?

1:08 yeah: lein uberjar

1:09 "For this to work you'll need to specify a namespace as your :main in project.clj and ensure it's also AOT (Ahead Of Time) compiled by adding it to :aot."

1:09 justin_smith: eh, I break those rules all the time :P

1:10 java -cp my-uber.jar clojure.main -m my.ns

1:10 rem500: Hi I have a question. (seq? [1,2,3]) returns false because only lists are sequences. But rseq can only be used on vectors or sorted maps, things that AREN'T seqs. Can someone explain?

1:10 justin_smith: et. voila, no aot needed

1:10 rem500: rseq generates a seq from things that are not seqs

1:11 ,(seq? (range))

1:11 Trioxin: ic

1:11 clojurebot: true

1:11 justin_smith: rem500: note that (range) does not return a list, but it is a seq

1:11 ,(list? (range))

1:11 clojurebot: false

1:11 justin_smith: rem500: at risk of being totally unhelpful, seq? returns true for things that are seqs :P

1:12 rem500: Ok and rseq is the most efficient way to reverse anything?

1:12 justin_smith: rem500: most efficient way to reverse the things it can reverse

1:12 seqs are not structured in such a way that rseq can reverse them

1:13 this is because vectors and sorted maps provide fast access to their last element

1:13 seqs do not

1:13 rem500: why is it called rseq though

1:13 justin_smith: it gives you a reversed seq from your input

1:14 rem500: is it worth changing a list into a vector just to use rseq?

1:14 justin_smith: rem500: clojure does weird things with return types sometimes, but if you check the return types those should be predictable at least, and there's usually a very good reason (though its counterintuitive)

1:15 rem500: oh, I don't think so no

1:15 because creating a vector is O(1), and so is reversing a list

1:15 rem500: ok so just rseq on vectors and sorted maps and reverse on lists, sounds easy enough

1:15 Trioxin: what about GUIs? I enjoy creating webkit GUIs and if I could do that then I could use clojurescript in my GUI alongside my other javascript and html/css. I could just use node-webkit and call my .jar file from the command line or maybe load it into the webkit app as an applet?

1:16 justin_smith: rem500: yeah, though don't call reverse on things that are unbounded for obvious reasons

1:16 Trioxin: don' really want to use like GTK+

1:16 rem500: unbounded like (range)

1:16 justin_smith: Trioxin: with clojurescript you can ship the js output

1:16 rem500: exactly

1:17 Trioxin: the tooling can be a bit complex, but I have found clojure server, plus figwheel, plus clojurescript and react on the frontend, is a very slick way to develop a browser based app with a backend

1:17 I haven't tried standalone cljs though I imagine that would work pretty slick too

1:22 Trioxin: justin_smith, are you talking about for a web site or for a desktop app?

1:23 trying to make some sense of this at the moment https://github.com/bhauman/lein-figwheel/wiki/Quick-Start

1:23 justin_smith: Trioxin: reagent / figwheel / cljs should work for either, but what I'm doing is a web app

1:23 rem500: What is a sequence? I know lists are linked lists and vectors are contiguous arrays does that play into it or is it something else

1:24 justin_smith: vectors are not contiguous

1:24 vectors are actually a type of tree

1:24 rem500: http://hypirion.com/musings/understanding-persistent-vector-pt-1 awesome series of blog posts on how our vectors work

1:25 rem500: everything in clojure that is a seq is some kind of linked list (even if not strictly a list)

1:25 rem500: ok cool thanks i will read that

1:25 justin_smith: rem500: thinks seqs share is that it is easy to get the next item, but not easy to do random access, and there is no way to find out the total size without walking all the way to the end

1:26 *things

1:26 basically the constrants of a linked list, there

1:28 muhuk: rem500: sequence is an abstraction on top of lists, vectors, maps & sets

1:28 ,(= (seq [1 2 3]) '())

1:28 clojurebot: false

1:29 justin_smith: muhuk: more than that actually - you can get a seq from a string, a List, an array...

1:29 an iterator even

1:31 Trioxin: I wonder if I could just run a clojure uberjar in node-webkit as an applet

1:32 i know I could execute it behind the scenes by just running the process

1:32 justin_smith: Trioxin: like I said, for cljs you export js

1:32 js does not run uberjars

1:32 if you are using node you shouldn't also be running java

1:33 Trioxin: it's a browser

1:33 justin_smith: and if you are using that you should be using clojurescript, what does it gain you if the backend is clojure?

1:34 Trioxin: because even with having node available it borks up sometimes when trying to do computationally intense things like I tried to monitor the filesystem (The windows dir) and it hung up

1:35 plus the advantage of just having the JVM along with my webkit app

1:35 i wouldn't have to rely on node

1:35 and I could use clojurescript and clojure

1:35 justin_smith: OK, I guess you could do that, it still seems like it would be simpler to ship js if you want node-webkit to run the app

1:35 but yeah, that's all doable

1:36 Trioxin: i just like that part of it for the ease of making the GUI

1:36 and I know applets can talk to JS and the other way around

1:36 justin_smith: applets too?

1:36 why applets?

1:37 Trioxin: because they can talk to JS and therefore clojure easily, not that I would have to take that route

1:37 i could use sqlite or something

1:38 justin_smith: I don't understand what applets would do for you, if you already are running a clojure process plus cljs in the browser talking to it

1:38 and I don't have any concept of how sqlite would be an alternative to an applet...

1:39 Trioxin: because then I could have nw just run the applet and communicate with nw/the gui through sqlite

1:39 not the applet I mean the jar

1:39 the clojure process

1:40 justin_smith: we have websockets

1:40 OK

1:40 Trioxin: there's that too

1:40 justin_smith: so when you said applet you meant the clojure jar

1:40 right, that makes sense

1:40 sente makes it very easy to use websockets between clojure and clojurescript

1:40 Trioxin: well no at first I meant embedding the jar as an applet because it and javascript can communicate easily

1:41 i don't think sockets are necessary when doing that

1:41 i think it's done in the browser

1:41 justin_smith: I think you'll find a regular clojure process (not in an applet) can communicate with clojurescript in a browser very fluently

1:42 Trioxin: ok. what I was mainly getting at is apart from nw, how do people using closure usually go about a desktop GUI? Just want to compare to what I would normally do with a webkit

1:43 justin_smith: if I were doing it I would compile a clojurescript app to js, and just run that js

1:43 but someone else might have more actual experience to share

1:43 Trioxin: run it in webkit you mean?

1:43 justin_smith: there's also seesaw, which is a frontend to swing

1:43 Trioxin: yes

1:44 also, there's javafx, for another native java option

1:46 Trioxin: ok I'll just stick with nw because it's portable and easy to use and I can obviously compile clojurescript to run in it. as for clojure doing heavy lifting on the backend there's the option to do that in a few different ways

1:46 justin_smith: yeah, that sounds smart to me

1:46 Trioxin: yeah I've seen some good looking javafx stuff too

1:47 but I'm guessing it would be much more tedious

1:47 justin_smith: Trioxin: using javafx looks pretty easy actually... https://coderwall.com/p/4yjy1a/getting-started-with-javafx-in-clojure

1:47 I have not tried it though

1:48 and you might want to spend more time getting good at the language before you get into weird tooling and optional libs and such

1:50 Trioxin: i paid someone a while ago to make this awesome app in java/javafx and loaded as an applet. it was for streaming torrents and was much better than popcorn time. One thing I want to do is rewrite that project

1:50 justin_smith: interesting, I have not heard anything good about applets myself...

1:50 Trioxin: usually no but in this case it was awesome

1:52 i mean I could have made it a desktop app but I wanted people to be able to just come to the site and run it and back then I didn't know about webkit desktop apps

1:54 i should bring it back online

1:54 and kickstart the rest

1:55 justin_smith: I bet it would be a nice exercise to take the app as is and port as much of the functionality as possible to clojure

1:55 Trioxin: yeah

1:55 the GUI is great. it's metro style in javafx

1:55 justin_smith: though clojure might run into RAM usage limits in an applet

1:56 Trioxin: popcorn time is cool but they've made some mistakes that I didn't

1:56 mungojelly: what can i say to poke at the ram usage of things

1:57 justin_smith: muhuk: you can connect visualvm to your clojure process and see a log of its usage of memory

1:57 err

1:57 mungojelly: ^

1:57 Trioxin: maybe there's a webkit I can run in clojure

1:57 webkit lib for java

1:58 i see this for nw seesaw

1:58 oops

1:58 https://github.com/wilkerlucio/lein-node-webkit-build

1:59 mungojelly: wow yay, leveraging generic jvm tooling

1:59 justin_smith: I hear yourkit works even better with clojure

2:07 Trioxin: https://github.com/solicode/clj-thrust

2:08 justin_smith: interesting, I had not heard of that one

2:14 Trioxin: ok so back to reality. (+ 2 3) evaluates to 5 but why can't i do like (+ 2 3 * 2)

2:14 justin_smith: Trioxin: because a paren treats the first thing after it as a thing to call

2:14 Trioxin: and without a paren, you are just referring to the function, not calling it

2:15 ,(+ 1 2 3)

2:15 clojurebot: 6

2:15 justin_smith: ,[1 2 + 3 4 * 5]

2:15 clojurebot: [1 2 #object[clojure.core$_PLUS_ 0x66b73e82 "clojure.core$_PLUS_@66b73e82"] 3 4 ...]

2:15 mungojelly: ,(+ 2 (* 3 2))

2:15 clojurebot: 8

2:16 justin_smith: yes, that's likely what Trioxin wants there

2:16 Trioxin: ah i see

2:16 justin_smith: it takes a little while before flipping math expressions like that makes intuitive sense

2:16 here's a cool one we can do in clojure:

2:16 ,(< 0 1 2 3)

2:16 clojurebot: true

2:17 Trioxin: heh

2:17 justin_smith: ,(< 0 1 2 3 -1)

2:17 clojurebot: false

2:17 mungojelly: it's a compromise, you have to learn an unusual order for some verbs, but in exchange the syntax is deadly regular and thus the computer can help more with writing the code

2:17 justin_smith: < effectively asks if all the args are sorted

2:17 Trioxin: oh

2:17 justin_smith: mungojelly: indeed, and we can do cool things by stacking up the args that wouldn't work with binary predicates

2:17 ,(+)

2:17 clojurebot: 0

2:18 justin_smith: ,(*)

2:18 clojurebot: 1

2:18 justin_smith: ,(/ 2)

2:18 clojurebot: 1/2

2:18 justin_smith: ,(/ 8.0)

2:18 clojurebot: 0.125

2:18 mungojelly: ,(/)

2:18 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: core//"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: core//"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 399]\n [sandbox$eval241 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval241...

2:18 justin_smith: mungojelly: no base case for /

2:18 mungojelly: ,(/ (/ 2) (/ 2))

2:18 clojurebot: 1N

2:18 Trioxin: ,(< 1 50000000000000000000000000000000000000000000000000000000000000000000000)

2:18 clojurebot: true

2:18 justin_smith: ,(/ 1 2 3)

2:18 clojurebot: 1/6

2:19 mungojelly: it should have an extra truth case TRUE!!! for when something is really super obviously true

2:19 Trioxin: it spits out fractions like that?

2:19 mungojelly: yeah it has real ratios

2:19 Trioxin: holy crap

2:19 justin_smith: Trioxin: it uses fractions when possible instead of truncating, yeah

2:19 mungojelly: ,(/ 22 7)

2:19 clojurebot: 22/7

2:19 justin_smith: Trioxin: old lisp tradition, that one

2:20 Trioxin: what about factoring?

2:20 justin_smith: Trioxin: this can be a performance issue, so when number crunching is a bottleneck you often want to explicitly force floating point or integral math

2:20 hmm, I think the vm has some stuff for factoring, but I may not know what you mean exactly

2:20 do you mean like primality testing?

2:21 Trioxin: was just thinking of performance since that can be computationally expensive

2:23 justin_smith: with clojure 1.7 and newer we have an option to have the compiler warn about math boxing, which is a superset of that perf issue (since rationals are always boxed)

2:25 Trioxin: ,(defin factoring [n] (filter #(zero? (rem n%)) (range 1 (inc n)))) (print (factoring 45))

2:25 clojurebot: #error {\n :cause "Unable to resolve symbol: defin in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: defin in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: defin in this...

2:25 Trioxin: ,(defn factoring [n] (filter #(zero? (rem n%)) (range 1 (inc n)))) (print (factoring 45))

2:25 clojurebot: #error {\n :cause "Wrong number of args (1) passed to: core/rem--inliner--4336"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "clojure.lang.ArityException: Wrong number of args (1) passed to: core/rem--inliner--4336, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type clojure.lang.ArityException\n :message "Wrong numb...

2:26 justin_smith: Trioxin: n% is treated as if it were one thing

2:26 Trioxin: ,(defn factoring [n] (filter #(zero? (rem n %)) (range 1 (inc n)))) (print (factoring 45))

2:26 clojurebot: #'sandbox/factoring

2:26 Trioxin: lol

2:26 justin_smith: Trioxin: also, that call to factoring won't be called, unless you wrap the whole thing in a do

2:26 mungojelly: what should i say when i want to remember something

2:26 justin_smith: now you can just do the call to factoring on its own of course

2:26 mungojelly: ?

2:27 like store a value for later?

2:27 mungojelly: well i don't want to hard code a database call obviously

2:27 justin_smith: ,(factoring 45)

2:27 clojurebot: (1 3 5 9 15 ...)

2:27 mungojelly: i could wrap in my own save-this thingy, but is there a better idiom for putting a database hook

2:27 Trioxin: how would I rename factoring to factor?

2:27 justin_smith: Trioxin: you don't need to call print at the top level - every expression returns a value to the repl, and that value is always preinted

2:27 Trioxin: can that be doe?

2:27 justin_smith: this is the P in rePl

2:28 ,(def factor factoring)

2:28 clojurebot: #'sandbox/factor

2:28 justin_smith: ,(factor 45)

2:28 clojurebot: (1 3 5 9 15 ...)

2:28 Trioxin: nice

2:28 ,(factor 3255)

2:28 clojurebot: (1 3 5 7 15 ...)

2:28 Trioxin: oh it won't keep going

2:28 justin_smith: mungojelly: for simple stuff I like to put a hash map inside an atom

2:28 mungojelly: is that a seq it's making?

2:29 ,(type (factor 3255))

2:29 clojurebot: clojure.lang.LazySeq

2:29 justin_smith: Trioxin: clojurebot has a limit on how long its printed output can be

2:29 mungojelly: ,(take 20 (factor 3255))

2:29 clojurebot: (1 3 5 7 15 ...)

2:29 mungojelly: still won't give me more :)

2:29 justin_smith: ,(def db (atom {}))

2:29 clojurebot: #'sandbox/db

2:29 justin_smith: ,(swap! db assoc :a 42)

2:29 clojurebot: {:a 42}

2:30 justin_smith: ,(swap! db update :a inc)

2:30 clojurebot: {:a 43}

2:30 Trioxin: looks like we're not cracking an encryption with clojurebot :P

2:30 justin_smith: ,(swap! db assoc :b "OK")

2:30 clojurebot: {:a 43, :b "OK"}

2:30 justin_smith: mungojelly: so that's the basic idea if yuo don't need persistence beyond runtime

2:30 also useful for debugging

2:30 sm0ke: how do i change the default ns in boot again?

2:31 justin_smith: sm0ke: changing :main will suffice in lein / nrepl

2:31 Trioxin: so def will rename it and I'm guessing anything else

2:31 mungojelly: justin_smith: that just taught me "swap!" so thanks but persisting to disk is what i'm thinking about

2:31 justin_smith: Trioxin: not rename, it gives the thing another name

2:32 Trioxin: oh right because we're immutable

2:32 sm0ke: hurmm

2:32 justin_smith: mungojelly: OK, yeah, you'll want a db for that

2:32 sm0ke: doesnt work

2:32 mungojelly: justin_smith: as well as multiple algorithms can {} be a hook for a database :) or what hook should i put

2:32 Trioxin: or at least we want to be

2:32 justin_smith: Trioxin: you can also destroy the original var with ns-unmap if you want

2:32 Trioxin: (ns-unmap factoring)

2:32 ,(ns-unmap factoring)

2:32 clojurebot: #error {\n :cause "Wrong number of args (1) passed to: core/ns-unmap"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/ns-unmap"\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" 32]\n [sandbox$eval332 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$...

2:32 sm0ke: i can use `boot repl -e '(in-ns...)', but looks overkill

2:33 Trioxin: ,(ns-unmap factor)

2:33 clojurebot: #error {\n :cause "Wrong number of args (1) passed to: core/ns-unmap"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/ns-unmap"\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" 32]\n [sandbox$eval356 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$...

2:33 justin_smith: Trioxin: look at the docs before trying again

2:33 Trioxin: k

2:33 justin_smith: (doc ns-unmap)

2:33 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

2:33 justin_smith: note that it has an ns arg, and a symbol arg

2:33 mungojelly: how can that error not say what number of args would be right :/

2:33 justin_smith: I think both need to be symbols, not the values

2:34 mungojelly: because clojure has very little work put into making errors sensible or friendly

2:34 mungojelly: (something 1) no! one is the wrong number of arguments! (something 1 2) no! two is also the wrong number! (something 1 2 3)? pls? y u make me guess, error

2:34 justin_smith: mungojelly: yeah, or you could look at the source or the doc string via the repl

2:34 Trioxin: yeah I've noticed that playing with repl

2:35 justin_smith: but yes, clojure has terrible UX around errors

2:35 mungojelly: that's what it seems like is an admonishment: you have used this incorrectly, you should look at the docs before even thinking of trying to use it again :)

2:35 ,(doc ns-unmap)

2:35 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

2:36 Trioxin: ,(ns-unmap sym factor)

2:36 clojurebot: #error {\n :cause "Unable to resolve symbol: sym in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: sym in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: sym in this conte...

2:36 mungojelly: ,(ns-unmap sandbox factor)

2:36 clojurebot: #error {\n :cause "Unable to resolve symbol: sandbox in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: sandbox in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: sandbox i...

2:36 justin_smith: mungojelly: both those values should be quoted

2:36 ,(ns-unmap 'sandbox 'factor)

2:36 clojurebot: nil

2:37 justin_smith: ,(ns-publics 'sandbox)

2:37 clojurebot: {}

2:37 justin_smith: no defs!

2:37 Trioxin: my fault I'm a bit off my tutorial doing this right now

2:37 mungojelly: "nil" is a funny way to say "i have happily completed that operation," does that "nil" have metadata saying what it means

2:37 justin_smith: no, it's just the thing usually returned if there is nothing interesting to return

2:37 Trioxin: nil == null?

2:38 justin_smith: you can't put metadata on nil

2:38 right

2:39 mungojelly: i just thought it makes sense with that metadata pattern, you're returning "nil" so things can test on whether the result, but also that doesn't necessarily mean you have nothing at all to say to your caller, you could also report to them on how the operation went if they wanted details

2:40 instead when i want details of executions i'm putting :verbose flags and such apparently so :)

2:41 Trioxin: ,(ns irc (:import (java.net Socket) (java.io PrintWriter InputStreamReader BufferedReader)))

2:41 clojurebot: nil

2:42 justin_smith: ,*ns*

2:42 clojurebot: #object[clojure.lang.Namespace 0x39b70af3 "sandbox"]

2:42 justin_smith: foiled!

2:43 Trioxin: what happened?

2:43 justin_smith: you tried to change the namespace, and it didn't stick

2:43 Trioxin: oh

2:43 (:import (java.net Socket) (java.io PrintWriter InputStreamReader BufferedReader))

2:43 justin_smith: every call to clojurebot starts a new repl

2:43 import doesn't work that way at the top level

2:44 ,(:import 'this-arg-ignored 'this-arg-returned) ; nothing was imported here

2:44 clojurebot: this-arg-returned

2:45 Trioxin: ,(:import (java.net Socket) (java.io PrintWriter InputStreamReader BufferedReader)) (def freenode {:name "irc.freenode.net" :port 6667}) (def user {:name "someguy" nick "someguy333")

2:45 clojurebot: #error {\n :cause "java.net"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: java.net, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.ClassNotFoundException\n :message "java.net"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLCl...

2:46 Trioxin: oops wrong part

2:46 justin_smith: Trioxin: :import only works inside ns, outside ns you need import

2:46 Trioxin: oh

2:46 justin_smith: anyway, I'm leaving my client logged in, but will be physically away from the computer for a while

2:47 mungojelly: bye justin_smith

2:47 Trioxin: later thx for the teaching

3:23 mungojelly: i'm still wondering how makes sense to hook to databases, like if i'm making a piece of code that by its nature wants to write out a stream of data, but it doesn't care how it's recorded-- wait ok i should just have it emit a stream of data, then, i guess, and handle it from the other side!?

3:32 if my thingy gives off streams with various sorts of information then in context you can persist those or forget them or w/e. ok how do i have my thingy give off various streams of stuff?

3:39 muhuk: mungojelly: you can start by defining "thingy" & "stuff"

3:39 mungojelly: muhuk: hello fellow "mu"! i'm thinking abstractly though

3:39 i just have any thing, it produces data, or does if you poke it, or w/e

3:40 i'm thinking the state should all be external, and also whether to persist that state or what parts of it, but maybe they should give hints what would be good to do with what output, hm

3:44 muhuk: mungojelly: you're almost describing an agent system.

3:46 mungojelly: how do you joint the connection between your programs and their databases

3:48 no joint at all: program writes to a particular database interface. ouch. minimal joint: program calls local "write to database" idea, which abstracts over a pluggable choice of databases. but i want to joint more than that?

3:49 muhuk: mungojelly: have you ever written code that writes to a db?

3:50 if you did, chances are you have had the maximum amount of joint.

3:51 mungojelly: um sure i've written to dbs various ways. a couple weeks ago i wrote code in python that manually stitched together bits of SQL :/

3:52 but i'd like to abstract above "write to db", more like "this data could be interesting to write to disk" as a hint to something that takes that hint

4:02 copycat: hi guys, i hope i can ask a rather frivolous question

4:02 what's the most fun thing you wrote in clojure?

4:04 mungojelly: copycat: i just started, so the most fun i've had so far is just playing around with parameters in ants.clj, probly not helpful to your survey sorry

4:05 i mean like, (run-with-logging (thingy :log-level :zillions) database-writing-function), so you can trap its log stream for testing or w/e-- no?

4:39 nedviles: Hi!

4:40 Guest87768: What's up?

4:41 sup?

4:41 hallo!

4:42 ping!

4:42 !staff

4:42 oddcully: Guest87768: herro! we can see you!

4:43 Guest87768: I just tried some commands, haha!

4:43 oddcully: in a public channel with a metric ton of users

4:43 Guest87768: On some other networks they have commands like "staff, ping, sup" etc.

4:52 oOzzy`: Hey there! I was just wondering on what the best practice is for runtime constants. I use `environ` to fetch environment variables for e.g. a database url that's different in dev, test and prod. It seems like when using `(def database-url (env :database-url))` the variables are fetched from the compilation environment though.

4:59 muhuk: oOzzy`: well, of course. You can convert database-url to a no-args function.

5:00 oOzzy`: or make if a delay and then deref each time you use it.

5:00 oOzzy`: or change the var root during execution (but I wouldn't go that way)

5:01 oOzzy`: The no-arg function is what I'm doing at the moment. Is any of the first two preferable?

5:03 muhuk: oOzzy`: matter of style I think. But delay version might be preferable to signify that the value doesn't change during runtime.

5:04 schmir: oOzzy`: are you sure that's the case? the (def database-url ...) is eval'ed when compiling, but I think it will also be eval'ed when running the compiled code

5:04 raspasov: schmir: I don't think it does

5:04 also, if you look inside environ.core, the env there is specified using defonce, so I'm not sure that get re-evaled either

5:05 I dealt with this in the past, and that's what I ended up using, and it works for me

5:05 https://gist.github.com/raspasov/6725d9aa2c6d0f628162

5:05 oOzzy`: I actually didn't try. I just noticed because I was getting an error at compilation time because that environment variable was null.

5:06 raspasov: I read my config from a config.clj file inside of -main and call (merge-with-env! ...) in -main

5:06 oOzzy`: cheers raspasov

5:06 muhuk: raspasov: you know that environ also reads a config file, don't you?

5:07 raspasov: yea but does it do it dynamically every time?

5:07 or only at compile time? I ran into problems when doing a uberjar

5:07 not 100% sure though

5:08 muhuk: raspasov: every time, at the start of execution

5:09 raspasov: was the file part of the uberjar?

5:10 raspasov: muhuk: Don't remember, but that's what ended up working for me https://gist.github.com/raspasov/6725d9aa2c6d0f628162 (just edited)

5:10 muhuk: raspasov: I think it's worth trying again. It seems you are duplicating work here.

5:11 raspasov: muhuk: it's possible

5:11 https://github.com/weavejester/environ/blob/master/environ/src/environ/core.clj

5:11 mavbozo: raspasov, so you put your production configuration file in production server in /etc/.../config-....clj ?

5:12 raspasov, or is that a location in your dev machine?

5:12 raspasov: mavbozo: it's there in production as well

5:13 muhuk: raspasov: AFAIU .lein-env shouldn't go inside the uberjar, but it should be placed in the same directory with it. Not 100% sure.

5:13 raspasov: muhuk: I'm looking at https://github.com/weavejester/environ/blob/master/environ/src/environ/core.clj

5:13 that defonce at the bottom - does it get executed everytime a uberjar runs, or only once when it's compiled?

5:14 that's the question I am not sure about : )

5:14 schmir: it gets evaled when the uberjar runs

5:15 muhuk: raspasov: yeah, as schmir says.

5:15 raspasov: ok : )

5:15 schmir: the (def database-url

5:15 (env :database-url)) also get's evaled when the uberjar runs

5:16 (and also when it's compiled)

5:16 muhuk: actually it doesn't really get evaled twice

5:16 it gest evaled when the code is compiled (JVM bytecode) and then run.

5:17 if you just compile, it wouldn't get evaled.

5:17 schmir: muhuk: if you compile a .clj file the top level forms with get evaled

5:18 muhuk: schmir: clojure.core/compile?

5:19 oOzzy`: schmir: the problem was it didn't compile because I did something like this: `(def some-port (Integer/parseInt (env :some-port)))` and `SOME_PORT` wasn't set.

5:21 schmir: muhuk: yes

5:23 if you couldn't change environment variables (or rather if it wouldn't have any effect on the program), the environ package wouldn't make much sense

5:24 muhuk: schmir: you are right. I just checked.

5:52 karls: https://www.duedil.com/b2b-lead-generation

5:52 sorry! wrong window.

5:55 visof: hi guys

5:56 what is the best solution for this, if i have 3 variable of boolean values, and want to check whether combination of three are either true true true, or false false true or other combinations and do action for each combination

5:56 ?

5:57 my approach is to convert combination to strings like "110" or "111" and apply case for it

5:57 is there a better ?

6:00 muhuk: visof: core.match

6:01 schmir: visof: a map mapping a the vector of values to some action comes to mind...i.e. there's no need to convert to a string representation first

6:01 but it probably doesn't matter much

6:01 ceruleancity: visof: maybe a multimethod would work?

6:02 schmir: clojure.core/match may also help (https://github.com/clojure/core.match)

6:02 ceruleancity: (defmulti parse-bin (fn [input] input))

6:03 (defmethod parse-bin “111” [input] true)

6:03 etc etc

6:04 muhuk: I wouldn't use a multimethod for this. There are only 8 possibilities.

6:06 oddcully: does this binary representation provide better readability? why not case with [true true false]?

6:07 muhuk: oddcully: I was also thinking that. Reads better IMO.

6:07 mavbozo: (cond (= [true false true] [x y z]) "true false true" (= [false false true] [x y z]) "false false true"

6:08 i'll use cond first

6:08 muhuk: mavbozo: why? It's repetitive.

6:09 mavbozo: muhuk, depends on combination i want to check

6:10 muhuk: mavbozo: do you mean you'd use it in another situation and not the particular situation we're discussing here?

6:11 mavbozo: muhuk, i use cond for this 3 variable of boolean values situation

6:12 muhuk: mavbozo: then you'd repeat (= ... [x y z]) 8 times for no good reason.

6:14 mavbozo: muhuk, i can wrap the cond in (let [v [x y z])... then (cond (= ... v)

6:14 mungojelly: ,(let [x true y false z true] (if (= [x y z] [true false true]) "yes" "no"))

6:14 clojurebot: "yes"

6:15 muhuk: mavbozo: then you'd repeat (= ... v) 8 times for no good reason.

6:15 mungojelly: do we have optional keyword arguments

6:15 muhuk: mungojelly: sort of

6:15 Trioxin: ,(defn foo [x y] (print x y) (if (< x9) (recur (inc x) (dec y)))) (foo 5 2)

6:15 clojurebot: #error {\n :cause "Unable to resolve symbol: x9 in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: x9 in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: x9 in this context"...

6:16 Trioxin: ,(defn foo [x y] (print x y) (if (< x 9) (recur (inc x) (dec y)))) (foo 5 2)

6:16 clojurebot: #'sandbox/foo

6:16 mungojelly: can i give a keyword to an argument but also have it filled by a nameless first argument, like (fun :something :val) is the same as (fun :val)

6:16 muhuk: mungojelly: someone will post a link about how they should be attempted in 3 .. 2 .. 1

6:16 oddcully: but cond would allow to combine common cases (e.g. always blerp if z==true)

6:16 muhuk: r/should/should not/

6:16 oddcully: good point.

6:16 Trioxin: why did the bot just say that?

6:17 mungojelly: you defined a function so it returned it to you

6:17 mavbozo: but the v is not the important thing here, the [true false true], [false false true] pattern that i want to match is, at the expense of writing v many times

6:17 Trioxin: i called the function too

6:17 ,(foo 5 2)

6:17 clojurebot: 5 26 17 08 -19 -2

6:18 mavbozo: muhuk, i'm open to better alternatives for this particular problem

6:18 muhuk: mavbozo: write cond & case versions side by side to see what I mean.

6:18 mavbozo: oddcully raised a good point, but let's assume we want to check for all 8 cases and do something different.

6:19 Trioxin: ,(def foo)

6:19 clojurebot: #'sandbox/foo

6:20 mavbozo: muhuk, agree, case leads to shorter codes, I change my mind

6:20 Trioxin: (def foo foo2)

6:20 oddcully: Trioxin: the bot only deals with ,(...) and not with ,() () ()

6:20 Trioxin: ,(def foo foo2)

6:20 clojurebot: #error {\n :cause "Unable to resolve symbol: foo2 in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: foo2 in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: foo2 in this co...

6:20 Trioxin: o

6:20 what's the way to make an alias of a function again?

6:21 oddcully: ,(def blerp inc)

6:21 clojurebot: #'sandbox/blerp

6:21 oddcully: ,(blerp 1)

6:21 clojurebot: 2

6:21 ceruleancity: ,(= blerp true)

6:21 clojurebot: false

6:21 ceruleancity: just wanted to join the blerp party

6:22 oddcully: you are only supposed to blerp if z is true

6:22 Trioxin: ,(def blerp uppy)

6:22 clojurebot: #error {\n :cause "Unable to resolve symbol: uppy in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: uppy in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: uppy in this co...

6:22 Trioxin: ,(def uppy blerp)

6:22 clojurebot: #'sandbox/uppy

6:23 Trioxin: (uppy 1)

6:23 ,(uppy 1)

6:23 clojurebot: 2

6:23 Trioxin: ,(uppy 9999)

6:23 clojurebot: 10000

6:23 Trioxin: ,(uppy -1)

6:23 clojurebot: 0

6:23 mungojelly: ,(= uppy blerp)

6:23 clojurebot: true

6:23 oddcully: ,(= uppy blerp inc)

6:23 clojurebot: true

6:24 Trioxin: and then to remove let's say uppy?

6:25 ,(uppy 1/5)

6:25 clojurebot: #error {\n :cause "Unable to resolve symbol: uppy in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: uppy in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: uppy in this co...

6:26 Trioxin: that made no sense what I just did anyway

6:26 oddcully: ,(ns-unmap (find-ns 'user) 'uppy)

6:26 clojurebot: nil

6:26 oddcully: ,(uppy)

6:26 clojurebot: #error {\n :cause "Unable to resolve symbol: uppy in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: uppy in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: uppy in this co...

6:27 mungojelly: is that better/different than (def uppy nil)

6:27 Trioxin: you have to actually search for it?

6:27 ,(def blerp nil)

6:27 clojurebot: #'sandbox/blerp

6:27 Trioxin: (blerp)

6:27 ,(blerp)

6:27 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [sandbox$eval117 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval117 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval117 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6943]\n [clojure.lang.Compiler eval "Compiler.java" 6906]\n [clojure.core$eval invokeStatic "c...

6:27 Trioxin: ,(blerp 1)

6:27 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [sandbox$eval141 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval141 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval141 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6943]\n [clojure.lang.Compiler eval "Compiler.java" 6906]\n [clojure.core$eval invokeStatic "c...

6:28 Trioxin: nil seems better?

6:28 mungojelly: you killed blerp :(

6:28 ,(def blerp inc)

6:28 clojurebot: #'sandbox/blerp

6:28 mungojelly: now i feel better

6:28 Trioxin: lol

6:28 ceruleancity: so is z false forever now?

6:28 mungojelly: ,(blerp (blerp (blerp 1)))

6:28 clojurebot: 4

6:29 oddcully: Trioxin: yes i looked it up. i never had the urge to undef something before. if all is lost i restart the repl for my humble usecases

6:30 mungojelly: ,(map blerp (take 10 (iterate blerp 0)))

6:30 clojurebot: (1 2 3 4 5 ...)

6:30 ceruleancity: ,(doc blerb)

6:30 clojurebot: excusez-moi

6:30 mungojelly: yeah, don't remove things, leave them, they are nice useful things

6:31 see what you did to poor blerb!? no need

6:31 * Trioxin tears up

6:31 Trioxin: BHWYYYYYYYYYYYYYYYYYYY? bluuuuuuuuuuurp

6:32 blerp

6:32 ceruleancity: ,(doc blerp)

6:32 clojurebot: "; "

6:32 ceruleancity: nice

6:33 mungojelly: ,(defn blerp "good for incrementing stuff, deserves to live" [n] (inc n))

6:33 clojurebot: #'sandbox/blerp

6:33 mungojelly: ,(doc blerp)

6:33 clojurebot: "([n]); good for incrementing stuff, deserves to live"

6:33 Trioxin: I can create a language with clojure right?

6:33 mungojelly: that's sorta how you program lisps, it's a metalanguage

6:33 ,(blerp (blerp (inc (blerp 2))))

6:33 clojurebot: 6

6:34 Trioxin: what if I recreate PHP.. the right way

6:34 mungojelly: php has no comprehensible standard :(

6:34 Trioxin: yet

6:35 mungojelly: nor does java really, which is why clojure is such an amazing accomplishment, it actually engages all that crap

6:35 Trioxin: I'm still not even closed to used to coding like this

6:36 ceruleancity: you’re not alone Trioxin

6:36 wink: mungojelly: that's not true anymore, the spec is coming along quite well

6:36 mungojelly: when i get close to thinking lispily i honestly have a strange drifting hazy feeling like the world is dissolving, it's too much

6:36 Trioxin: yeah php isn't so bad. I've made good use of it over the years

6:37 wink: mungojelly: i.e. I think with PHP7 and HHVM it should be a lot better of a standard than many other languages

6:37 Trioxin: sure some things aren't in the order you'd expect. some arguments

6:38 mungojelly: i don't understand why any arguments are positional anywhere

6:38 Trioxin: probably because you use lisp lol

6:38 wink: since when is stuff in lisp not positional?

6:39 Trioxin: idk it was guess. i'm a noob

6:39 mungojelly: it's terse is the only good thing i can think of for using positions, everything else says use names, much more comprehensible

6:39 wink: well if the language has no named arguments..

6:39 Trioxin: php documentation is awesome though

6:40 wink: I mean, python has both. that's probably the best tradeoff

6:40 Trioxin: so is error output and an IDE will tell you positions

6:40 mungojelly: roughly equivalent to keywords is to pass in one compound value describing your input

6:40 wink: that's still a bad hack

6:40 the IDE one

6:41 Trioxin: yea

6:41 i rarely forget an order though

6:41 wink: mungojelly: I find that to be verbose and a lot of boilerplate, even if it's just a litt {:foo 3}

6:41 ceruleancity: yea you can basically achieve what python does by providing your regular positional parameters, followed by an optional map at the end for named parameters

6:41 mungojelly: that's backwards, the clear version should be the text, and then the ide can help by hiding or emphasizing things, if things exist only in the ide then the text is empty

6:43 Trioxin: PHP has done some annoying things to me though like I run a CLI script and it seemed to run on just 1 core

6:44 wink: that's expected behaviour

6:44 unless you use pcntl it's singlethreaded. by design

6:45 Trioxin: meh

6:46 mungojelly: i don't feel like i mostly want to be wonking around with the "parameters" to some little function and tuning it to do something, anyway, why is that my job, i'd like to just connect it to something that gives it the right values in the shape it wants

6:46 i'm always working for the functions, shouldn't they be working for me, do stuff for me functions

6:48 Trioxin: would using more cores be pcntl_setpriority()?

6:48 i don't see anything to set the affinity

6:48 mungojelly: so more concretely with my tile toybox thing i had thought of making something to let you put various stuff in some shape into a grid, but i think instead what i'm going to do is let you build up grids and combine grids, so then you can make a grid with the stuff you want to add and add the whole thing together

6:52 Trioxin: I'm not seeing how to work with curl in clojure

6:55 mavbozo: Trioxin, you want to use linux curl from clojure?

6:55 Trioxin, or you want some kind of http client?

6:55 Trioxin: well, I used it a lot in PHP because it had built in curl functions that were nice

6:56 made it easy to do like curl_mulithread

6:56 get and post and set proxies and user agents

6:56 mavbozo: Trioxin, well, you can use clj-http library

6:56 Trioxin: o

6:56 tdammers: in my experience, using system libraries from clojure doesn't tend to be the most pleasant approach

6:57 you're better off using something written in clojure, or, failing that, some JVM lib

6:58 nooga: I have several functions exposed as methods on a static class for Java users to call them. Now I'd like Java users to be able to pass me a callback function which I could call at any moment.

6:58 and I'm stuck

7:00 Trioxin: clj-http looks pretty good.

7:01 the mutlithread thing would have to be coded manually

7:01 noncom: Trioxin: also, if you want to use cli tools from clojure comfortably, like curl, look at the conch library

7:02 Trioxin: as per your last phrase - sort of. thanks clojure is oriented toward very easy multithreading

7:03 ceruleancity: does anyone have any resources on deploying clojure projects? I guess I would just use lein to build an uberjar and then distribute that, is that more or less standard or is there some literature on the topic that’s worth reading?

7:05 noncom: ceruleancity: that's standard... also you can use all these java-exe-packers and other stuff

7:05 ceruleancity: also, if you care about code obscurity, i guess you have to aot everything and remove sources from the distribution

7:06 ceruleancity: the class files you get after aot can too be obfuscated by specialized tools

7:06 ceruleancity: noncom: I’ve just got a little ring/cljs app that I want to deploy internally so at least for now I’m not too concerned with obfuscation etc. I guess I’ll go with uberjar for now. Thanks for the input

7:08 noncom: ceruleancity: sounds appropriate! but if it is *that* local, you can also simply have it in the form of an uncompiled project to have the ability to easily modify it

7:08 ceruleancity: just "lein run" inside the project and it'll start working

7:09 mavbozo: Trioxin, there's also connection-pool option for clj-http https://github.com/dakrone/clj-http#persistent-connections

7:10 noncom: nooga: let the java users extend the AFn class

7:11 nooga: and pass if to you. this will be just an ordinary clojure function. also they can extend IFn but that may seem tantalic, and AFn does some boring stuff for you

7:12 nooga: sounds good

7:16 sm0ke: any suggestion for a programmable template language in clojure?

7:16 agarman: hiccup?

7:16 clojurebot: hiccup is both https://github.com/weavejester/hiccup and http://tinyurl.com/426og7n

7:17 sm0ke: hiccup is limited to html

7:17 something generic

7:17 agarman: clj-template?

7:17 sm0ke: again html

7:18 agarman: http://www.clojure-toolbox.com

7:18 dig through the template languages there

7:18 nooga: I'd roll my own :D

7:19 sm0ke: thanks agarman

7:20 comb is exactly what i want

7:21 nooga: ... implemented in 62 lines

7:23 noncom: git status

7:23 ooops

7:26 kramar: On branch master

7:26 Your branch is up-to-date with 'origin/master'.

7:26 nothing to commit, working directory clean

7:27 sm0ke: clostache is good too

7:27 some nice extra things

7:28 noncom: kramar: :D

7:29 sm0ke: used it, liked it. also, selmer and stencil.

7:31 sm0ke: I think i will go with comb, only two kind of syntax, and can be used to do anything other projects are doing

7:31 noncom: yep

7:33 though i found {{this}} much easier on the eyes in big template

7:37 sm0ke: i think you should be able to overwrite it

7:37 let me just try to overwrite the delimiters in comb's ns

7:39 ugh doesnt work

7:41 wth noncom , you got me obsessed with the delimiters now

7:41 noncom: :)

7:42 nooga_: maybe because comb is evaling clojure

7:42 and {{}} is like a map with map key and without value for that key

7:43 noncom: sm0ke: try intern, it allows redefining stuff in other ns, not a very popular practice, but if you really need it...

7:43 nooga_: true, i think that's the reason.

7:43 sm0ke: actually redefining is just fine, problem is with the regex he is building with it

7:44 the (def parse-regex ...)

7:44 noncom: but OTOH, getting {{}} in the code is very unlikely... if this is in your code, the code is already broken, sooo... :)

7:44 sm0ke: it is throwing error with deleimiters ["{{" "}}"]

7:44 noncom: it won't hurt much if we break it some more

7:44 sm0ke: probably because { and } are special for regex?

7:45 sm0ke: try \{\{ and \}\}

7:45 sm0ke: they are?

7:45 noncom: yes

7:45 http://www.fon.hum.uva.nl/praat/manual/Regular_expressions_1__Special_characters.html

7:46 sm0ke: worked

7:46 (def delimiters ["\\{\\{" "\\}\\}"])

7:46 heh pretty ugly huh

7:46 noncom: yeah, escaped them once more for the string

7:46 but you will not see this, it will just lay inside

7:47 TEttinger: ,(re-find #"[{]{2}[}]{2}" "{{}}")

7:47 clojurebot: "{{}}"

7:47 noncom: TEttinger: so, a more radical approach! :)

7:47 sm0ke: yeah i tested it

7:47 TEttinger: the curliest of braces

7:47 noncom: haha

7:48 sm0ke: not sure if the author would like it

7:48 i guess i will keep it <% %> way

7:48 as nooga_ also metioned {} could be a map

7:48 noncom: well, it's opensource.. :) but yeah, that makes sense and what nooga_ said too

7:49 but you just had a little nice adventure

7:49 sm0ke: :D

7:51 oddcully: also good luck generating lua code with {{...}} ;)

7:52 sm0ke: hurmm

7:53 oddcully: spy much?

7:53 ah {{ }} is something in lua too?

7:55 well <% %> is something in jsp i guess

7:55 oddcully: yes, {{1,2,3}} is [[1 2 3]]. and pseudo objects etc

7:55 sm0ke: so yeah everything you pick will be something in some lang

7:55 except if you picj #$%^%&#&^#%^#

7:55 xtrntr: hi, wondering if a newb can get some help

7:55 sm0ke: i guess that would be something too in APL

7:55 noncom: xtrntr: sure, just ask

7:56 xtrntr: i've done some tutorials in modern-cljs, would like to try running this code

7:56 https://gist.github.com/rm-hull/6857333

7:56 noncom: sm0ke: rofl

7:56 xtrntr: in my new project

7:56 but i can't find the directory structure in github

7:56 i'm also new to open source

7:57 aside from these 4 scripts, what else do i need to do? find and add the required dependencies in project.clj?

7:57 noncom: xtrntr: oh, i see

7:57 xtrntr: technically, yes, you could do all this manually and more experienced folks here do

7:58 xtrntr: but why don't you check out http://www.luminusweb.net/

7:59 xtrntr: ok, i'll try that

7:59 noncom: xtrntr: this will get you going quickly, jut be sure to add the +cljs flag to the template. and later you can dive in for more details

7:59 xtrntr: yes, that's exactly the learning approach i feel like taking :)

7:59 noncom: you can try this and learn, and later ask more specific questions on particular things

7:59 cool! :)

8:01 oddcully: xtrntr: the files would go in your src/maze dir

8:01 xtrntr: this code is used from there: http://programming-enchiladas.destructuring-bind.org/rm-hull/6857333

8:03 xtrntr: from the includes i'd say you should try to get rid of the enchiladas and read that stuff just from your html; jayq and monet are libraries you have to add

8:10 xtrntr: get rid of the enchiladas and read that stuff from html

8:10 hmmmm

8:11 oddcully: xtrntr: i have not used that. but my impression is, that enchiladas is the framework for that site i linked. so it would provide the canvas, canvas-size etc you see in the :require

8:13 xtrntr: ahh.. it's the person

8:13 it's the person's custom created framework?

8:19 oddcully: xtrntr: yes. your goal is to use these three files in your own project and render the mace on a html page, right?

8:20 s/mace/maze/

8:20 xtrntr: yeap

8:20 i'm looking up the guy's github page right now

8:20 some aggressive copying going on

8:20 HEHE

8:22 oddcully: xtrntr: then my rough approach would be: lein new figwheel maze; add jayq and monet to the deps there. add a canvas element in the index.html; put all three files in your src/maze/ dir; remove/comment the :require for enchilada and provide your own def(n)s for them

8:23 xtrntr: ok, i'll try that

8:29 lodin_: oddcully: Regarding re-frame that we talked about, I figured that the replayability you enable when using pure data (i.e. not event (constantly ...) as argument) is probably really really useful for testing.

8:31 noncom: after i upgraged to lein 2.5.2 from 2.5.1 i am getting class not found exception for all my namespaces when I uberjar... how do i fix it, without adding gen-class to each of them?

8:31 lodin_: oddcully: s/event/even/

8:47 visof: hi

8:49 noncom: visof: hi

8:50 xtrntr: oddcully: this might be a silly question.. but where do i put my main

8:50 visof: i have a method which return record say it the method called mo and record V, and another map which apply function to this record called xmap, and another func which xmap take to apply on record called fo, i do this (xmap fo (mo v. :hello :world)), how can i use the result of xmap to another xmap and fo ?

8:50 xmap return another V record

8:51 i can use iterate

8:51 ?

8:52 muhuk: visof: have you tried?

8:52 visof: (iterate #(xmap fo (mo %)) (V. :hello :world)) should be something like this?

8:53 muhuk: xtrntr: if you're using Leiningen, you should put -main in your :main ns defined in project.clj

8:54 visof: yes, if you want to apply mo each time

8:55 visof: this would return a lazyseq, so (nth i (iterate ...)) or something like that to get the result.

10:16 TimMc: Is there anything in the clojure standard libraries that handles scheduling repeated events, or should I use Executors directly?

10:20 schmir: TimMc: I don't think there's anything in the standard libraries. I like and use https://github.com/jarohen/chime

10:26 TimMc: Thanks, I'll take a look.

10:34 mdeboard: Where is it configured which function will be called when `java -jar /path/to/uberjar` is invoked?

10:34 (on a jarfile created with `lein uberjar`)

10:38 TimMc: mdeboard: The -main function of your :main ns.

10:39 Or rather, you can change which ns by changing the :main in your project, and you can change which fn by changing the gen-class statement.

10:39 katratxo: mdeboard: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L189-L196

10:41 mdeboard: thanks

11:00 noncom: TimMc: there's also the at-at library (very simple) and quartz (very advanced)

11:00 mdeboard: Is there someplace I should start looking if `java -jar whatever.jar` doesn't work like executing `(-main)` in the console?

11:01 because `(-main)` does get invoked

11:01 noncom: and what is it saying ?

11:01 mdeboard: Well -main invokes this function https://gist.github.com/mattdeboard/ecd0d033d1977bf6da78 which I expect to write data to output.txt

11:01 and it does, when invoked via the repl

11:02 it doesn't say anything noncom

11:02 noncom: how do you know that main gets called? you get the file?

11:02 i mean output.txt

11:03 mdeboard: No, I put a println in there

11:03 noncom: noncom: okay, and you don't get the file or the console does not exit indefinitely?

11:03 mdeboard: I don't get output.txt at all

11:03 wat

11:03 noncom: you've already answered

11:04 mdeboard: Also the actual operation (moving data from one SQS queue to another) does not happen

11:05 noncom: mdeboard: actually it looks like you have much async code in yout function

11:05 from your description it looks like it does not work

11:05 you could put println after every like in your function

11:05 mdeboard: It works

11:06 In the repl, it works fine, so I know the logic is good

11:06 noncom: yes, but it does not work standalone..

11:06 why not put a println on every line and see where it actually stops...

11:07 with core.async too much guessing can go into nowhere.. i got in so many strange situations with it..

11:08 in a let you can put println after each assignment too, like [_ (println something)]

11:08 mdeboard: Ok that's helpful

11:11 TimMc: noncom: I'm just going to go with j.u.Timer. :-P

11:12 noncom: TimMc: ahaha :)

11:21 TimMc: I only need one task at a fixed interval.

11:22 sdegutis: TimMc: what's the question?

11:23 justin_smith: mdeboard: regarding which function is run, there is also "java -cp my.uber.jar clojure.main -m any.ns"

11:23 mdeboard: as long as any.ns has a -main, it will run that

11:23 the cool thing, is that does not even require gen-class or aot compilation, which eliminates about a dozen headaches

11:25 noncom: sdegutis: a scheduling lib

11:25 justin_smith: TimMc: at-at is a pretty thin wrapper on j.u.Timer

11:25 mdeboard: justin_smith, I just wanna know under what circumstances running the uberjar would behave differently than executing the -main function from the repl

11:26 justin_smith: TimMc: (which depending on your criteria can mean a yes or no of course)

11:27 noncom: sdegutis: i too, long in a search for a clear, thin and versatile scheduling lib.... chime uses core.asyc, quartzine is too monstrous (it's a wrapper over monstrous quartz), and at-at has proved the most clojuric and thin, although it has some lack of something, i don't remember exactly...

11:29 sdegutis: Sorry, what's a scheduling lib's purpose?

11:29 I don't quite know what this terminology is about.

11:30 noncom: sdegutis: to like make certain things run on certain time/date or for a certain period and stuff

11:30 sdegutis: like calendar for tasks

11:30 justin_smith: noncom: someone should make the scheduling version of gfredericks 's seventy-two lib. It would be a scheduler and you hand it a function and it will call your function at 4:20 pm every day

11:30 sdegutis: So like cron but specific to Clojure?

11:30 gfredericks: justin_smith: it's called seventy-one dammit

11:30 justin_smith: totally non-configurable, that would be the only thing it would do

11:30 gfredericks: oops

11:30 sdegutis: We just use cron so I'm a bit confused why one might not want cron.

11:31 justin_smith: sdegutis: ever try running a task two minutes after the hour every hour with cron?

11:31 I mean I know it is possible but it's weird

11:31 also we are talking scheduled tasks inside a long running vm here

11:31 noncom: wow! a genius lib!

11:32 sdegutis: justin_smith: iirc that's one of the easier timings to express with cron?

11:32 noncom: i also found this: https://github.com/AdamClements/schejulure

11:32 sdegutis: Oh, inside a VM.

11:32 justin_smith: sdegutis: I didn't think it was, but OK, once every 38 minutes and 17 seconds then

11:32 noncom: sdegutis: well, yes, the point is to run the schedule inside your app for various things

11:33 sdegutis: justin_smith: hmm yeah we use Thread/sleep for that

11:33 justin_smith: 38.17 is even easier iirc

11:34 justin_smith: sdegutis: the idea with a scheduling lib is you get the ability to look at your timed tasks, cancel them, change the timings if you need to, etc. - a lot more control than you get with a looping thread doing sleep calls

11:36 sdegutis: Oh neat.

11:36 Sounds like it could be useful in some cases.

11:36 I wonder how many cases I have where it would be useful but I haven't thought if it that way yet so I haven't connected the dots...

11:37 Ober: if I want to pretty print a stacktrace, what should I convert to line returns?

11:37 justin_smith: also, " the sleep period can be terminated by interrupts, as we'll see in a later section. In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified" - a proper scheduling lib should have stronger guarantees than this

11:38 Ober: you could check out aviso/pretty for an existing project that attempts to do this

11:38 mdeboard: I figured out the problem. It's that the jvm process terminates thus killing the threads I had going lol

11:38 computing is hard when you're dumb

11:40 noncom: chronno: o_O

11:40 ooops

11:40 that was for mdeboard :)

11:40 mdeboard: yeah I switched to >!!, alts!! etc. and it works fine.

11:43 mungojelly: so writer-m is a writer monad implementation, but we don't use it mostly? does that implementation suck, or is that an intentional style choice, or ar we too scared of the m-word?

11:44 Ober: justin_smith: stuck doing this outside the jvm

11:44 justin_smith: mungojelly: I think the general perception (right or wrong), is that monads are a lot less useful without strong typing

11:45 Ober: oh, and you are just getting raw unformatted stack traces?

11:45 mungojelly: justin_smith: how does typing help? i mean especially, it seems to me like it just helps you not get your connecitons miswired like anywhere else

11:45 justin_smith: mungojelly: it's that monads help with keeping things typed

11:46 haskell wants strong typing, monads help them achieve that

11:46 mungojelly: yes haskell forces you to. is it that nobody uses monads unless they're forced to? :D

11:47 justin_smith: mungojelly: there's that, and the clojure compiler is not a clever compiler like haskell's is, monads in clojure are slow

11:47 mungojelly: i just want to make things that log and write data and stuff but i don't want to just say "write data!" with no way to constrain the flow, what a mess.

11:48 justin_smith: mungojelly: I think a more idiomatic solution to that would be a core.async go block getting things to write from a channel, or a looping thread that gets things to write from a queue

11:48 mungojelly: is there a different way i should inject that dependency, like have my things ask to have a writer injected into them

11:49 justin_smith: but maybe monads are the right way to do this, I just know they aren't very popular, I gave up on them pretty quickly when I was trying them

11:49 lodin_: justin_smith: With strong typing, do you mean purity?

11:49 justin_smith: lodin_: well, purity is part of strong typing, but a lot of haskells usage of monads has nothing to do with side effects

11:49 mungojelly: whatever, everything's monads whether anyone says that or not, it's just an explicit monad-monad has maybe more general algorithms you can use on it, but not really because no one writes monad algorithms because no one uses them so w/e

11:50 lodin_: justin_smith: I'm trying to understand what you meant with monads help with keeping things typed.

11:50 justin_smith: monads are a convenient way to "lift" code to different datatypes without having to do a lot of boilerplate, but we can ignore that aspect in clojure because we are looser about types

11:51 lodin_: justin_smith: Not really. We run into problems when we want to write abstractions that make use of return/pure, because we don't know the type.

11:52 Like sequence with haskell type [m a] -> m [a]. If the list is empty, how do you construct the return value? You must pass in info explicitly.

11:53 mungojelly: i vaguely feel like metadata could let you do monady things to data while letting naive functions participate without knowing what's happening

11:54 justin_smith: mungojelly: if functions were disciplined about returning values that preserved the metadata of their input, maybe

11:54 good luck finding functions that do that

11:54 mungojelly: channels feels nice though, yeah that's looser in a clojurey way, wait um what's the jointing with channels, do they have names or you need specifically handles to them?

11:54 mdeboard: I think justin_smith 's point is that there are other idioms for transforming/processing data in Clojure, and that monads are a mismatch without strong typing.

11:54 justin_smith: mungojelly: they are values

11:54 mungojelly: justin_smith: oh i thought if they didn't pay attention they'd just pass it through :(

11:56 justin_smith: ,(meta (with-meta (range 10){:a 0}))

11:56 clojurebot: {:a 0}

11:57 justin_smith: ,(meta (map inc (with-meta (range 10){:a 0})))

11:57 clojurebot: nil

11:57 justin_smith: mungojelly: sad but true

11:58 lodin_: Monoids suffer from the same issue, btw, due to the identity element.

12:02 mungojelly: with a monad i get an abstraction over the side effects, with channels i get spatially removed from them, whatever, i'm happy as long as i don't have to actually like make concrete decisions about things i don't care about :)

12:16 luxbock: https://groups.google.com/forum/#!topic/clojure/wccacRJIXvg

12:17 there's some discussion on why monads are not so much used in Clojure

12:21 visof: hi guys

12:21 mdeboard: luxbock, nice link

12:26 noncom: visof: hi!

12:29 visof: 'm trying to draw white and black boxes based on returned result, returned result is list of lists, each inner list has true or false values, what i do is simulate this using quil, each list represent new line, https://gist.github.com/aibrahim/1286ce58b1e7d085ff9e

12:30 that's my code, i need to change this line (q/rect 0 0 20 20) which contain 0 0 for x y positions, so i need updated values

12:30 to not overwrite to this position

12:30 how can i achieve this

12:30 res has lists of lists

12:30 list* of lists

12:31 noncom: i'd iterate over ranges

12:32 visof: noncom: ah step by 20 for y as example and iterate over it

12:32 noncom: wait, i'll write an example

12:32 visof: ok

12:33 noncom: (let [lst (get-list)]

12:33 (doseq [y (-> lst count range)]

12:33 (doseq [x (-> (nth lst y) count range)]

12:33 (let [value (get lst x y)]

12:33 ; bool-fill logic here

12:33 (q/rect (* x cell-size) (* y cell-size) cell-size cell-size)

12:33 ))))

12:33 something like this

12:33 you have to stick to indexes to get coordinates

12:35 sorry, the [value (get lst x y)] should be [value (get-in lst [x y])]

12:37 ooops. get-in does not work for lists that wy!

12:37 but that's a minor thing, use (nth) or produce the sequences as []s, not ()

12:38 visof: ^

12:38 ,(get-in '(1 (1 2) 3) [1 1])

12:38 clojurebot: nil

12:38 noncom: hmmm, now i wonder, why does it not work with lists? does anyone have an explanation?

12:38 mungojelly: i'm so sick of (* x cell-size) (* y cell-size) cell-size cell-size, that's just the boilerplate i want to write away with my tile toolbox, so i can play with tiled things without ever writing x*size y*size ever again phew

12:39 noncom: mungojelly: right! i remember you were after saving us from this

12:39 i program quil and other tiling things too, i am so sick of this too

12:40 mungojelly: i don't understand why every one of those things doesn't come with a tile abstraction already, it's what everyone writes first when you start using them

12:40 noncom: a good excersize, maybe :D

12:40 but i am sure there are grid libraries for processing

12:40 or maybe not :/

12:40 mungojelly: there are things but they're so heavy

12:41 like i found something i thought might be useful in clojure but it was a whole thing intended for dealing with geospatial data, seeing whether basic little squares intersected was in there somewhere i think

12:42 noncom: hahah :) well, you well have the chance to create *the* tiling library

12:43 mungojelly: here's something i don't understand yet, my format goes like {:grid {[0 0] :name-of-tile} :tiles {:name-of-tile {:attribute "stuff about tile"}}} and i realized that i was assuming the [0 0] would always be integers

12:44 (a) what do i say to ensure it's always integers there, is it that defrecord thing, or some guards or something? (b) do i have to? if i incrementally enforce that later will that be just as good

12:45 noncom: mungojelly: imho (a) you can use the prismatic schema library for that (b) i would not restrict it to ints

12:46 fractional indexes could be interesting since in this implementation as i see, position of a tile is bound to its index, but what if i want to manipulate with tiles and place them on fractional positions?

12:47 mungojelly: yeah i'd also considered that, sure yeah why not leave it so you can do that if you want

12:47 noncom: like, i want to begin my game with a whirld wind of tiles, which them settle to form my field

12:47 yeah

12:48 the tile-data extracting functions, however, will take integer indexes and use (nth) to get the positions

12:48 mungojelly: but i guess what i'm thinking is i'd like to make more than one client implementing viewing the tiles, and i was just imagining implementing the simple case of non-overlapping even square tiles there

12:49 noncom: still i don't see why restrict, or why a viewer could not handle it by itself...

12:49 but, sure it's up to you :)

12:50 mungojelly: i'll think about it, that's very helpful advice thanks :)

12:50 noncom: like, modern monitors (viewers) take care of lighting up proper pixels, and the programmer does not think of this when he writes graphics - even if the resolution does not fit at all, for example

12:50 :)

12:53 mungojelly: hmm i think that's maybe another different problem we solve repeatedly because it's too simple to simplify: x y positioned sprites with bounding boxes or some other basic collision detection, for making bouncy rooms (:

12:54 so there's an obvious abstraction above both of them of generic "x y positioned thingies" i guess i should make just that

13:10 a very nice algorithm just popped into my head but i'm not sure i could even pseudocode it, um, i imagined things that paint themselves and then making a collision box out of that and then ask which cells it would intersect in a square grid so you mark those as used by that shape, like if it's a tetris L block it blocks off those four squares, hmm and then you could take some shapes and ask what size g

13:11 rid would be most harmonious with them

13:11 justin_smith: mungojelly: something like this is done with quad-trees if I understand you correctly

13:11 the more uniform your shapes (or the more rough your outline determining rules) the simpler this is

13:12 mungojelly: cool quad-trees are new to me, yeah looks sorta like what i was thinking, yeah i was vaguely imagining some algorithm that'd shrink wrap the boundaries of something and that'd do :)

13:15 wink: mungojelly: http://www.gamasutra.com/blogs/AAdonaac/20150903/252889/Procedural_Dungeon_Generation_Algorithm.php interesting read maybe?

13:15 mungojelly: sounded a bit like what you just described

13:16 there's also http://journal.stuffwithstuff.com/2014/12/21/rooms-and-mazes/ but that's a little different

13:17 mungojelly: wink: ok yay thanks looks fun :)

13:17 * wink goes back to being useless besides digging up obscure links :P

13:23 mungojelly: ugh i hate how x and y are ambiguous, is there any possible way i can give an interface to horizontal and vertical position that's not confusing

13:24 how about if it's n-dimensional and you can name your dimensions yourself, bring your own dimension

13:24 justin_smith: mungojelly: that reminds me, I was going to write a js lib, one.js, which would specialize in rendering a line

13:25 followed up by zero.js, which would display a pixel

13:25 mungojelly: ok good sounds useful

13:25 justin_smith: 3.js and two.js worked out pretty well, so why not

13:27 mungojelly: i'm going to look at how they do x and y ing and zing and see if it helps me think about it

13:28 i just always feel like-- i don't care where. i want an orange circle. i want it located-- somewhere i can see it!? that is all. purple circle pls. shouldn't giving exact coordinates of things be optional. why are we always on the star trek bridge.

13:49 ambrosebs: Bronsa: taj thinks this is reflective (fn [^Number x] (pos? x))

13:49 any idea what's happening?

13:52 Bronsa: afaict validate isn't doing a subclassing test

13:52 pos? expects an Object, but we're giving it a Number

13:53 clojure.lang.Numbers/isPos rather

13:57 Bronsa: ambrosebs: I'm taking a look now

13:58 I just had cider consume 12gb of ram starting up the clojure process btw :|

14:01 ambrosebs: I don't get any reflection

14:01 expez: Bronsa: I've never heard of such obscene resource usage. I'd appreciate it if you opened an issue if you see this again :/

14:02 Bronsa: expez: no idea what happened, I managed to kill the process & restarted it and it's fine now

14:06 abox0: Hi how do I make a function that takes in a variable number of arguments and then prints them? I tried this but it didn't work:

14:06 muhuk: Are there any good reasons to add infix ops to lisp, other than unfamiliarity of newcomers? (I can't think of any.)

14:06 abox0: (defn printargs [& args] (apply print '(args)))

14:07 muhuk: abox0: try replacing '(args) with just args

14:07 abox0: neat thank you lol

14:08 Bronsa: ambrosebs: clojure.tools.analyzer.jvm> (-> (analyze '(fn [^Number x] (pos? x))) :methods first :body :validated?) ;=> true


14:12 abox0: clojure is so cool

14:14 sotojuan: ^ true

14:14 I wanna make something with clojure but i cant think of anything :'( so just doing project euler and sicp

14:16 mungojelly: we should do some fun group project

14:17 sobel: learn how to interface to java so you can use it at work

14:17 not just interop syntax but know it from the angle java-not-clojure devs will see it

14:19 mungojelly: i'm apparently like the only person in all of programming who likes to have any fun, i'd like to just make something fun and silly

14:19 i think it's confused how beginners always say they don't know how to make anything, they do know how to make things but no one's respecting and working with what they know how to make

14:19 sobel: my sense is, do something moderately ambitious

14:21 i wish i had clojure when i was learning 20 years ago. :)

14:22 mungojelly: no one ever makes anything without a particular purpose in mind, can't we ever just make anything for fun? then it's easy. one person makes some random interesting sequences, the next person turns those into colors, the next person throws the colors up on the screen, now interesting beautiful things are happening, not everything needs to be planned

14:23 blake_: mungojelly: I've been too busy but I'd like to flesh out/revamp "The Caves of Clojure".

14:23 sobel: eh, it's programming, but there's still such a thing as planning

14:24 i mean, start something and accept a lot of pull requests?

14:24 mungojelly: i don't deny that in general planning is useful to accomplishing tasks. why is everything so absolute!? i just mean, ever, we could set that down and have fun, ever, for a moment.

14:24 sobel: i think the add-on concept you're getting at can be facilitated if you build the right foundation.

14:28 mungojelly: is there a standard for what to use for colors? oh do we just use some standard java colors?

14:29 sobel: ...

14:29 java didn't invent color

14:30 i recognize a lot of your questions from my own topic-bucket i call, "this project needs more domain expertise"

14:30 mungojelly: well as i understand it we just reuse java abstractions here unless they're too crappy to work with so as to maintain compatibility with the java layer

14:30 sobel: i like programming but there's also other topics

14:31 ok, it depends on the value of reusing a java class

14:31 there are pros and cons

14:31 sooooo...ahunno. you gonna build something for programmers?

14:31 mungojelly: a "color" is just three bytes with an optional alpha byte basically, but there's a zillion interfaces to that

14:32 sobel: please don't build a better Color class

14:33 mungojelly: ,(partition 3 (take 30 (iterate inc-mod-256 73)))

14:33 clojurebot: #error {\n :cause "Unable to resolve symbol: inc-mod-256 in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: inc-mod-256 in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: i...

14:34 mungojelly: oh right i defined that sorry

14:34 ,(partition 3 (take 30 (iterate #(mod (inc %) 256) 73)))

14:34 clojurebot: ((73 74 75) (76 77 78) (79 80 81) (82 83 84) (85 86 87) ...)

14:35 mungojelly: hmm looks grey

14:37 it's not that that doesn't exist or that beginners can't make it it's just that a program that gets partway to making a stream of greys doesn't count to us somehow as a program at all and we make no space for it

14:41 i think rather than saying "good for you, maybe someday you'll make a real program" a better response would be to write the line that turns it into Color objects and go along from there playing with fun things

14:45 how about functions from epoch time to rgb colors, you could easily mod the ticks to make stuff throb, or also you could program things for particular absolute times/patterns

14:45 sobel: ok, but i'm not that interested in finishing someone else's code

14:45 i want to see a whole idea. that appeals to me.

14:46 mungojelly: "finishing" implies a goal, what if we just made something by adding part by part and seeing what emerges

14:54 wow cool https://github.com/jolby/colors has some really awesome palette generators! usually you just get smudging from place to place, this is way better :)

15:10 it's always the same interface to colors and it's always a brighter and darker that brighten and darken a random hardcoded amount. it's both too concrete and too abstract. what would it hurt to have something that makes things a little darker and a little bluer, or a little brighter and a little pinker, you never get anything fun, but "brighter" is boring enough it gets in even though it's hella vague.

15:10 xeno_: what's the shortest way I can generate a list of readable symbols, like '(:a :b :c ... ?

15:10 or stream or whatever

15:11 snowell: xeno_: From what?

15:11 xeno_: from nothing

15:11 start at :a :b and then continue, and when reaching :z then maybe :aa :ab ...

15:11 snowell: You'd probably write a function that generates strings in the format you want

15:12 And then apply keyword to its results

15:12 noncom: xeno_: you can cast a int into char and then (keyword "string") to get :string

15:12 xeno_: also there's clojure.core.generators

15:12 snowell: Oh yeah, that works too

15:12 noncom: clojure.data.generators, sry

15:12 J_Arcane: ClojuTRE 2015 talks are all online on Youtube now! https://www.youtube.com/playlist?list=PLetHPRQvX4a_tA9hGP935-OyLOYaRKpnj

15:12 snowell: ,(apply (comp keyword str) (range 5))

15:12 clojurebot: :01234

15:12 snowell: Er

15:13 noncom: ,(apply (comp keyword char) (range 5))

15:13 clojurebot: #error {\n :cause "Wrong number of args (5) passed to: core/char"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (5) passed to: core/char"\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" 48]\n [clojure.lang.AFn applyToHelper "AFn.java" 171]\n [clojure.lang.AFn a...

15:13 snowell: ,(map (comp keyword str) (range 5))

15:13 clojurebot: (:0 :1 :2 :3 :4)

15:13 noncom: ,(map (comp keyword str) (map char (range 5)))

15:13 clojurebot: (:

15:13 noncom: wow!

15:13 dbasch: ,(map (comp keyword str char) (range 97 102))

15:13 clojurebot: (:a :b :c :d :e)

15:14 snowell: dbasch getting all fancy on us :)

15:14 noncom: :D

15:14 but i can make clojurebot smile now!

15:14 ,(map (comp keyword str) (map char (range 5)))

15:14 clojurebot: (:

15:14 noncom: it wokrs!

15:14 mungojelly: aw you found what makes it happy (:

15:15 luma: null chars, apparently

15:15 mungojelly: null characters make me happy too clojurebot (:

15:15 noncom: ,(print "i'm so happy :)")

15:15 clojurebot: i'm so happy :)

15:16 noncom: ,k

15:16 clojurebot: 1

15:16 noncom: ,*out*

15:16 clojurebot: #object[java.io.StringWriter 0x556a7dc1 ""]

15:17 noncom: ,(def sw *out*)

15:17 clojurebot: #'sandbox/sw

15:20 TimMc_: Apropos of a conversation the other day, here's some code I just wrote that *does* make use of a mutable inside an atom.

15:20 https://gist.github.com/timmc/6df394983a24817ca3e3

15:25 sobel: nice

15:26 justin_smith: TimMc: interesting

15:26 TimMc: what happens when two start-timer calls are concurrent?

15:28 eg a -> start timer (1) b -> start timer (2) a -> retry, because there was a conucurrent call, cancelling (2) and starting (3)

15:29 end result, timers 1 and 3 are both running, right?

15:29 amalloy: justin_smith: also possible: a timer is cancelled twice

15:29 justin_smith: depending on the timer b might stop (1), but we can't count on it

15:30 amalloy: oh, yeah

15:30 *depending on the timing

15:30 amalloy: you really have to swap a delay of the value, rather than the value itself, if you must avoid duplicate work and/or concurrent realization

15:30 but then you're really just reimplementing a mutex, so...you can just use locking

15:32 justin_smith: amalloy: from the doc for TimerTask "This method may be called repeatedly; the second and subsequent calls have no effect." so the double cancel shouldn't be so bad (though it's sloppy)

15:32 err, doc for the cancel method on TimerTask

15:35 amalloy: justin_smith: well, it happens to correlate 100% with the cases where two competing timers are started

15:35 or...i guess if there were a race the very first time you start a timer, there could be two starts without a double-stop. you win

15:36 justin_smith: amalloy: concurrency is weird and I am often wrong about it, it's not about winning, just figuring out how these things work

15:37 amalloy: well, of course. but adding a few more winners rarely disrupts a situation

15:37 justin_smith: heh

15:46 TimMc: Oh yeah, could end up with a double start, hmm.

15:47 justin_smith: another option is an agent, agents don't do that restart thing, they lock instead

15:48 snowell: ,(for [i (range 10) :while (not= i 5)] i)

15:48 clojurebot: (0 1 2 3 4)

15:48 snowell: Is there a variant that would give me those results, but WITH the 5 included?

15:49 So less of a :while, and more like… :until or something

15:49 :including-when :)

15:50 oddcully: inc 5?

15:50 justin_smith: that doesn't generalize though

15:50 dbasch: ,(for [i (range 10) :while (<= i 5)] i)

15:50 clojurebot: (0 1 2 3 4 ...)

15:51 snowell: Well I'm using simple sets and functions for sake of ease

15:51 In practice, I'm generating a sequence of Java objects :)

15:51 justin_smith: dbasch: my interpretation (right or wrong) was the general question of "get items until a condition is met, including the item matching the condition"

15:51 snowell: justin_smith: Exactly

15:51 I'm porting over a Java for loop with a break in it

15:52 justin_smith: snowell: my translation of a for with a break would always be a reduce / reduced

15:52 snowell: A for loop that (as a side effect) generates an object

15:53 dbasch: snowell: just use a loop and an accumulator

15:53 justin_smith: ,(reduce (fn [acc el] (if (= el 5) (reduced (conj acc el)) (conj acc el)) [] (range))

15:53 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:53 justin_smith: ,(reduce (fn [acc el] (if (= el 5) (reduced (conj acc el)) (conj acc el))) [] (range))

15:53 clojurebot: [0 1 2 3 4 ...]

15:53 justin_smith: clojurebot, there was only one more item in that stupid vector :P

15:53 clojurebot: Cool story bro.

15:54 snowell: Hahaha maybe the most appropriate clojurebot response I've seen yet

15:55 justin_smith: snowell: anyway, try it yourself, it stops at 5 and includes 5, generalizes to imperative cases where unexpected chunking would cause bugs if you were counting on laziness for side effects

15:56 snowell: I'll try that indeed. Did not know reduced

15:58 amalloy: justin_smith: where chunking of the *output* would be an issue, this helps. if the seq you are reducing is already chunked you are too late

15:58 justin_smith: amalloy: oh, I was talking about side effects inside the reducing function - of course if your lazy source has side effects you count on then chunking is still an issue, yeah

15:59 but in general lazy-seqs are like polka dots and plaid anyway

15:59 err, lazy seqs and side effects

16:03 Tagore_: err- maybe coming in late here, but... how are lazy seqs like polka dots and plaid?

16:03 I mean, not as pretty as it is in Haskell, where that's just the normal thing and you do't have to think about it, but...

16:04 Empperi: wtf, polka dots?

16:04 Tagore_: Surely not eye-searingly ugly either, right?

16:04 Empperi: like this lol? http://i671.photobucket.com/albums/vv76/nicoledanielleadams/2012/christmas/meow026_zpsc3e1e05d.jpg

16:04 mungojelly: the way they don't match with side effects, he was saying

16:04 snowell: Works like a champ, justin_smith

16:05 (inc justin_smith)

16:05 Or lazybot is dead again. You're inc'd in my heart

16:07 Tagore_: He'll be inc'd when necessary.

16:08 snowell: Sounds like he's getting a tattoo

16:09 arrdem: damn lazy bots always sleeping on the job

16:14 snowell: I feel like I still haven't had the AHA moment I need to with reduce

16:14 My head still refuses to wrap itself around what it's doing

16:14 I feel like it'll be the same as when map/apply clicked

16:15 mungojelly: reduce is kinda infix

16:15 idk it feels to me like putting the operation inbetween what you feed it

16:16 justin_smith: snowell: reduce is like a factory assembly line - the kind where sometimes you break something up into smaller pieces, and sometimes you combine pieces into a unit, but either way you are not limited to one output unit per input unit

16:17 mungojelly: it's like a little bot you set down at the first value and say, go along and do this over and over until you get to the end, and it tottles along bloop bloop until they're all done

16:17 justin_smith: mungojelly: that's general enough to describe map or iterate too

16:17 mungojelly: how when do you break something up into pieces in a reduce

16:18 justin_smith: ,(reduce into [] [[1 2 3] [4 5 6]]) ; mungojelly: trivial example

16:18 clojurebot: [1 2 3 4 5 ...]

16:19 justin_smith: it's still only returning exactly one thing, like everything in clojure always

16:19 but the inner structure is broken up

16:19 mungojelly: oh so that's what "into" does. and a transducer may be supplied, i'm going to watch that transducers talk again and maybe that'll seem useful.

16:20 justin_smith: transducers are a really cool generalization of reduce (or at least that's one way to approach them)

16:23 mungojelly: also I didn't need the initial coll with that one

16:23 ,(reduce into [[1 2 3] [4 5 6]])

16:24 clojurebot: [1 2 3 4 5 ...]

16:30 mungojelly: ,(reduce into [[1 2] [3 4 [5 6]]])

16:31 clojurebot: [1 2 3 4 [5 6]]

16:31 mungojelly: how to squish it recursively then?

16:31 justin_smith: reduce might not be the best thing for that, once you want recursive operation

16:31 mungojelly: yes i see what you're saying, i don't have the vocab to make much go through it, but you can build things up, work with that, break it down, partition it differently, work with that for a while, etc

16:32 justin_smith: yeah - mainly this is in contrast to eg. map which is exactly one-for-one, or iterate, which is strictly result following result from a single initial value

16:32 sobel: i still mean to do more than hello-world with transducers. i have an application in mind but no time to refactor it.

16:32 justin_smith: unlike those, reduce has more power over the shape of its output

16:34 mdeboard: justin_smith, You inadvertently gave the only explanation for what a monad is I've ever understood

16:34 justin_smith: haha, when?

16:34 mdeboard: 'monads are a convenient way to "lift" code to different datatypes without having to do a lot of boilerplate'

16:34 Or rather,

16:34 justin_smith: oh, yeah

16:34 mdeboard: you gave a good explanation for when you'd use them

16:34 Which is just as good.

16:34 Maybe better

16:34 justin_smith: mdeboard: I'll make a point of mentioning mexican food next time

16:35 mdeboard: Some kind of astronaut eating a burrito or something?

16:35 Monadsplanations are frustrating because it's like the Clojure doc for `alts!`: It only makes sense after you've blundered your way through to understanding what `alts!` is used for

16:36 Surely there's a term for "an explanation of a thing that requires an understanding of the thing sufficient to not need the explanation"

16:36 justin_smith: mdeboard: right, I'm a fan of Heinz Von Foerster (pioneer of cybernetics) who said that the meaning of a word is actually an action plan - it's the orientation to the thing you do with the named object

16:37 mdeboard: that insight leads me to making better definitions :)

16:37 mdeboard: yes!

16:37 Exactly, wow that hits on something I have tried to articulate so many times

16:37 justin_smith: he's a brilliant guy, invented a lot of things we use all the time

16:37 or at the very least, helped us understand them much better

16:38 mdeboard: Also maybe at the heart of why I need to actually do a thing to understand it. Experiential versus didactic learning

16:39 justin_smith, Is that quote on this page? https://en.wikiquote.org/wiki/Heinz_von_Foerster

16:39 justin_smith: mdeboard: I'll check, I forget the source and the exact words..

16:40 mdeboard: Yeah I C-f'd for a few different words and came up dry, figured you've probably synthesized the actual quote into something else over the years :)

16:40 justin_smith: well, the original was in German, and might have been from a subtitled video I watched or something...

16:40 mdeboard: gotcha

16:40 I'll just pass it off as your quote

16:41 justin_smith: haha

16:41 sobel: possession is 99% of the law

16:41 mdeboard: "'The meaning of a word is actually an action plan -- it's the orientation to the thing you do with the named object.' - Werner Herzog" - justin_smith

16:42 justin_smith: mdeboard: I think the Louis H. Kauffman one comes close- and now I am recalling a paper name "Objects as EigenBehaviors"

16:42 I actually met Kauffman, very smart man

16:43 mdeboard: http://www.univie.ac.at/constructivism/journal/special/second-order/material/kauffman-2003-eigenforms.pdf

16:44 "This essay is a discussion of Heinz von Foerster's concept of an eigenform, wherein an object is seen

16:44 to be a token for those behaviors that lend it (the object) its apparent stability in a changing world."

16:45 sobel: i was wondering how long it would take to hear a little Buddhism here

16:45 ;)

16:46 justin_smith: To anyone who thinks this is off topic - clearly this is espousing functional programming: "Forms are created from the concatenation of operations upon themselves and objects are not objects at all, but rather indications of processes."

16:46 sobel: i think it's absolutely on topic

16:49 mavbozo: justin_smith could make a clojure conj talk about functional programming and monads using Heinz von Foerster as the hero of the talk

16:49 mdeboard: There's something to be said about documentation that explains "when would I use this" along with "what is this"

16:51 justin_smith: mavbozo: if only I had the initiative, I bet I could...

16:52 mdeboard: There are wonderful drugs that will give you initiative

16:52 temporarily, anyway.

16:52 justin_smith: heh

16:53 sobel: And still others that will make you want to dance

16:53 oh wait, wrong channel

16:53 mdeboard: I think I have to anchor an explanation of a thing in a use case

17:12 sritchie: oh man, just have to say it - Ambly and react native is a badass combo

17:13 anyone here played with this stuff yet on a phone, vs just the simulator?

17:13 was curious about the white screen on startup, and if it matters, really, once you use advanced compilation

17:22 dnolen: sritchie: isn't that something you fix by adding a loading screen?

17:22 sritchie: mfikes could probably answer your questions. There's seems to be a growing number of people using Ambly + React Native.

17:22 sritchie: after the splash screen? yeah, I guess you add a view controller that transitions when the JS is done loading.

17:23 I’m building up an app prototype, would love to use Clojurescript, but also thinking of just going straight react native for the first version to get a little variation in my diet

17:24 dnolen: sritchie: wasn't aware that loading the JS took any significant amount of time, but that's probably a question for someone else to answer

17:25 sritchie: there’s a short, intermediate white screen before ambly takes over from react: https://github.com/omcljs/ambly/wiki/ClojureScript-React-Native-Quick-Start#try-it-out

17:31 dnolen: sritchie: yeah dunno, you're more likely to get answers in #clojurescript I suspect

17:44 dumbintel: How can I make a vector of LazySeqs into a Vector of Maps? i.e. [({})({})] into [{}{}{}]?

17:58 oddcully: ,(reduce (partial apply conj) [] [[{:A 1}{:B 2}][{:C 3}]])

17:59 clojurebot: [{:A 1} {:B 2} {:C 3}]

17:59 dumbintel: Neat!

17:59 Thanks.

18:00 oddcully: ,(mapcat identity [[{:A 1}{:B 2}][{:C 3}]])

18:00 clojurebot: ({:A 1} {:B 2} {:C 3})

18:00 oddcully: don't use it until one of the pros approve ;)

18:03 dumbintel: ,(reduce (partial apply conj) [] [({:a 1}{:b 2})({:c 1})])

18:03 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: PersistentArrayMap"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: PersistentArrayMap"\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 [sandbox$eval73 invokeStatic "NO_SOURCE_FILE" 0]\n ...

18:03 justin_smith: dumbintel: you probably want to quote those lists (or maybe use vectors instead)

18:04 amalloy: dnolen: (partial apply conj) is just a less-optimized into

18:04 oh, not dnolen

18:05 wow, i can't read at all. oddcully

18:05 justin_smith: amalloy: except apply conj can take one arg

18:05 amalloy: errr, i don't think i understand

18:05 dbasch: apply concat seems to be what dumbintel wants

18:06 amalloy: dbasch: maybe. reduce into [] is good pretty often too

18:06 justin_smith: ,(apply conj [[:a :b :c] :d :e :f]) ; amalloy

18:06 clojurebot: [:a :b :c :d :e ...]

18:06 dbasch: sure

18:06 justin_smith: amalloy: I guess that can be into, if you wrangle it a bit

18:07 dumbintel: justin_smith: The problem is when I'm creating the vector I'm basically taking an xml file, reading each portion and trying to construct a map of the form [{:name {:item1 thing1 :item2 3} :name2 {:item1 cookie :item2 snack}}] for some reason i get nil's which I filter out and I end up with Lazy Seq's so they look like [ ({{}{}})({{}{}})]

18:08 justin_smith: dumbintel: right, but you can't just type in lazy-seqs like that, that's all I was saying

18:08 the parens become function calls

18:08 dumbintel: ahhhh

18:09 amalloy: dumbintel: generally you can't take the output that a repl prints, and paste it back into the repl

18:09 you need to add a quote to it, to prevent evaluation

18:10 dumbintel: gotcha, didn't think that through when I tried using the bot.

18:11 either way I have new ammo to try out. Thank you

18:35 oddcully: amalloy: ah so true

21:22 noncom|2: in korma if i have an existing SQL table with fields, say "name", "address", "code", then do i have to specify them like (defentity users (entity-fields :name :address :code)) ?

21:40 diminishedprime: Any tips/resources for good testing of macros?

21:47 noncom|2: diminishedprime: there are macroexpand and macroexpand-1 functions... some articles in the internet here and there... but only practice will give understanding

21:48 diminishedprime: I'm decently familiar with macros in general, but I'm new to Clojure. I'm having problems in particular with testing a macro that throws an exception if not passed a symbol.

21:49 We're wanting to enforce it there, because the macro is a definition of part of a dsl we're putting together for some business folk.

21:51 noncom|2: diminishedprime: so, you want to check exactly for what?

21:52 one of the arguments is a symbol?

21:53 diminishedprime: noncom|2: I got the macro working, but the tests fail. I put macroexpand-1 and the macro inside of a try catch block, but it seems like the exception is being thrown during compile time.

21:53 noncom|2: diminishedprime: quite probably

21:53 can you show the code and tell me what you're expecting?

21:53 diminishedprime: I sorta worked around it using read-string to put that off, but that seems like a hack.

21:54 noncom|2: btw, just today was reading on teh music theory tl;dr guide about the diminished chords :D i know that it is a joke about the prime, but what a coincidence!

21:55 diminishedprime: I don't have the exact code with me (It's on the work computer), but I also don't have erc access at work. Nice catch-22 there. Let me see if I can get the general idea scratched out.

21:55 noncom|2: yes, try to make up an example

21:55 diminishedprime: noncom|2: ahh exciting. I do love me some music theory. ALso you win an award for being the first to comment on the music joke.

21:55 noncom|2: cool :)

22:07 diminishedprime: how's it going?

22:10 diminishedprime: having some issues, but getting there. I got the macro re-written out, but I'm still a newbie at getting things required in correctly so I haven't been able to pull in thrown? from clojure.test

22:12 noncom|2: oh, you're using clojure.test?...

22:12 did not think that was necessary, but ok

22:12 diminishedprime: Yes. Is there a better framework to use?

22:13 noncom|2: well, there are "better" test frameworks, although many folks claim that they need only (assert) so what could be better...

22:13 i simply don't use any, so don't listen to me on this one :)

22:13 diminishedprime: Well here's the macro. It works like expected, but issues arise when I'm trying to test it.

22:13 (defmacro macro-with-symbol [symbol & forms] (if (not (instance? clojure.lang.Symbol symbol)) (throw (java.lang.Exception. "bad")) `forms))

22:14 noncom|2: so, and you want it to throw up on runtime instead of compile time?

22:14 diminishedprime: Well, I want it to throw up when the macro is expanded.

22:15 noncom|2: (btw, for frameworks/libs: http://www.clojure-toolbox.com/ )

22:15 diminishedprime: so, that means you want to throw it on macro compile time

22:15 diminishedprime: Because that way the business folk can get a "nice" message from us on what they probably did wrong instead of a confusing message they wouldn't understand.

22:15 noncom|2: look: macro generates code. do you want it to throw up on the phase of code generation or on the phase of code execution?

22:15 diminishedprime: Yes, I think that's when I want it to happen.

22:16 On the phase of code generation.

22:18 noncom|2: well, you've written it correctly. almost

22:18 here:

22:18 (defmacro macro-with-symbol [symbol & forms] (when-not (symbol? symbol) (throw (java.lang.Exception. "bad")) `(do ~@forms)))

22:18 diminishedprime: Thanks, let me try that out.

22:18 noncom|2: what is befor the backticked form will be executed on compule time

22:20 diminishedprime: noncom|2: That did the trick. I'll switch it over to that tomorrow at work. The when makes more sense since for sure.

22:20 noncom|2: diminishedprime: sure. don't hesitate to ask here if you'll encounter more questions

22:21 diminishedprime: also, if you have lots of type checks, be sure to check out the prismatic schema library

22:21 diminishedprime: Thanks. I've really been enjoying Clojure. I come from a Java background, but I've been playing with some Lisps for the last few months and have really been loving it. Thanks for the library recommendation, I'll look into it.

22:21 noncom|2: :) cheers!

22:22 arrubin: Is anyone here an admin for the Clojurians Slack?

22:23 noncom|2: arrubin: i know that seancorfield may know something

22:24 :)

22:24 however, it looks like that most people on this channel are afk, probably asleep

22:24 or at work..

22:28 Trioxin: alright, fire up clojurebot, Trioxin is back!

Logging service provided by n01se.net