#clojure log - Sep 07 2015

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

0:39 neoncontrails: ,(defn dedup [s] (map first (partition-by identity s)))

0:39 clojurebot: #'sandbox/dedup

0:39 neoncontrails: ,(apply str (dedup "Leeeeeerrroyyy"))

0:39 clojurebot: "Leroy"

0:40 neoncontrails: @amalloy: 4Clojure #30 doesn't like the partition-by strategy you taught me yesterday :(

0:40 sorry, uh

0:42 amalloy: quick question for you

0:53 TEttinger: (defn dedup-str [s] (apply str (map second (re-seq #"(.)\1*" s))))

0:53 ,(defn dedup-str [s] (apply str (map second (re-seq #"(.)\1*" s))))

0:53 clojurebot: #'sandbox/dedup-str

0:53 TEttinger: ,(dedup-str "Leeeeeerrroyyy")

0:53 clojurebot: "Leroy"

1:01 amalloy: neoncontrails: ?

1:03 neoncontrails: Is there a missing constraint on 4Clojure #30? (see my solution above)

1:05 amalloy: no

1:06 you're using defn instead of fn

1:06 Rurik_: When I do (source def) I get nothing, why is that?

1:06 neoncontrails: amalloy: Thanks!

1:07 amalloy: Rurik_: imagine if java had a "source" function. what would you expect to find if you wrote source("while")

1:07 Rurik_: ah

1:07 so the def form is implemented in Java?

1:14 ska-fan: Is there a convention how to put units in symbol names? i.e age-in-seconds maybe age:s?

1:38 kavkaz: ska-fan: I don't know the answer to that. Perhaps there is. But perhaps the best thing to do is whatever is most self explanatory

1:38 I don't think you'll be going against some sort of convention / idiom

1:38 but then again I'm not a Clojure veteran

1:43 bbatsov, who created CIDER, has a pretty handy guide for Clojure style that I just ran into

1:43 https://github.com/bbatsov/clojure-style-guide

1:43 amalloy: ska-fan: if you can bear to be a little long-winded, you can encode the units in the value itself, instead of conventionally via the variable name: (def whatever {:unit :seconds :magnitude 5})

3:01 felipedvorak: Given the following structure: loop>if>let>if>recur

3:01 if the recur argument was defined in let, can the first if see it?

3:08 http://pastebin.com/GYJ87Q5P

3:08 this is a clojure-bloody-beginner question but clojure beginner isn't active right now, I guess its night where you all live

3:08 opqdonut: I see your question

3:08 but I don't really understand it

3:09 everything inside a let sees all bindings made in the let

3:09 nothing outside the let can see it

3:10 felipedvorak: so where the "remaining-asym-parts" loses a part?

3:11 opqdonut: nowhere

3:11 ClashTheBunny: Hi, I was wondering if I could get some help remembering a project. It was based off of restructuring clojure’s core namespaces, but it was still syntactically the same. Can anybody remind me of it?

3:11 opqdonut: or more constructively, "remaining-asym-parts" becomes what "remaining" was on the call to recur

3:12 felipedvorak: opqdonut: so it does see remaining?

3:12 sorry, my head is producing smoke right now

3:13 I'm almost getting this after 10 hours trying to understand this function (not kidding)

3:13 but this single thing is still escaping me

3:13 opqdonut: felipedvorak: loop-recur is just recursion

3:13 felipedvorak: you could try writing out the recursive version of this code, without loop-recur, and see if it's simpler

3:16 felipedvorak: opqdonut: I don't even know what you're talking about hehe where can I understand recursion better?

3:16 would it be to just use "ifs" and anonymous functions to produce the same result?

3:17 TEttinger: felipedvorak: I don't know how much you currently know about how recursion works? Also, I can understand some romance languages, but not nearly well enough to be able to read technical portuguese...

3:17 opqdonut: felipedvorak: it's the difference between these two versions of factorial:

3:17 felipedvorak: TEttinger: hehe sorry for the portuguese but it isn't technical, its just me talking with myself trying to make sense of it

3:17 TEttinger: oh ok :)

3:18 felipedvorak: I have printed this code and glued it to my bedroom wall

3:18 opqdonut: felipedvorak: (defn factorial [param] (loop [acc 1 n param] (if (pos? n) (recur (* acc n) (dec n)))))

3:18 oops

3:18 TEttinger: ah, this is part of it. you use the same name, final-body-parts , as a local name in the let, and as a name for a loop variable

3:19 opqdonut: felipedvorak: (defn factorial [param] (loop [acc 1 n param] (if (pos? n) (recur (* acc n) (dec n)) acc))) -- correct version

3:19 TEttinger: hm, you know that, nevermind

3:20 opqdonut: felipedvorak: (defn factorial-helper [acc n] (if (pos? n) (factorial-helper (* acc n) (dec n)) acc)) (defn factorial [n] (factorial-helper 1 n)) -- recursive version

3:21 felipedvorak: anyway, it seems to me if you're struggling with understanding loop-recur, you need to work with simpler code

3:21 felipedvorak: I just don't get where they connect to each other

3:21 I mean, loop is almost a let, but it connects with something that changes it somehow

3:22 at least as far as I can understand it hehe

3:22 recur "updates" the value of the new loop with the values it had in the end of the first run

3:22 TEttinger: ,(def asym-hobbit-body-parts [{:name "head" :size 3} {:name "left-eye" :size 1} {:name "left-ear" :size 1} {:name "mouth" :size 1}])

3:22 clojurebot: #'sandbox/asym-hobbit-body-parts

3:23 felipedvorak: right?

3:23 TEttinger: I'll see what I can do...

3:26 opqdonut: felipedvorak: if you have a (loop [x ... y ... z ...] ...) and somewhere inside it a (recur a b c), execution "jumps" to the top of the loop and now x has value a, y has value b, etc.

3:26 felipedvorak: no other values from the previous iteration of the loop are visible any more

3:27 felipedvorak: opqdonut: hmmmm, wait, this was a very good explanation, let me look at the code a bit more, I guess its coming hehe

3:28 TEttinger: ,(mapcat (fn [{:keys [name size] :as arg}] (if (re-find #"^left-" name) [{:name (clojure.string/replace name #"left-" "right-") :size size} arg] [arg])) asym-hobbit-body-parts)

3:28 clojurebot: ({:name "head", :size 3} {:name "right-eye", :size 1} {:name "left-eye", :size 1} {:name "right-ear", :size 1} {:name "left-ear", :size 1} ...)

3:29 TEttinger: my advice is "don't use loop/recur until you are sure you need it"

3:30 felipedvorak: TEttinger: this is part of braveclojure.com tutorial.. I was getting everything but got seriously stuck by the end of the lesson

3:30 TEttinger: ahhh...

3:31 felipedvorak: got it

3:31 voila

3:31 TEttinger: woohoo!

3:31 felipedvorak: just like this

3:32 hauhauh

3:32 awesome

3:32 TEttinger: 10 hours in it just clicks, heh

3:33 felipedvorak: wow

3:33 4:33 am here

3:33 probably much more than 10 hours

3:33 My sunday was looking at this function

3:33 :)

3:33 I'm happy

3:33 thanks to both of you

3:36 its just like loop is receiving a new set of data from the outside to associate with its bindings :D looks so easy now but damn

3:39 ClashTheBunny: Dunaj! I found it!

3:41 felipedvorak: opqdonut: you nailed it with that explanation :) it should be in the documentation hehe

3:42 well, i'll take a shower and dream with symmetrical hobbits

3:42 thanks again

3:44 opqdonut: :)

4:04 Pupeno: When making Ruby on Rails applications I generally just throw active_admin into my projects to be able to edit records. My searches for something like this for Clojure turned up nothing (not unexpected). What tools do you use for CRUDing records?

4:06 tdammers: Pupeno: the psql command-line client...

4:07 Pupeno: tdammers: I find it much easier to edit records with an UI and my support person doesn't even know what a command line is.

4:07 stain: Pupeno: just do it in the REPL..?

4:07 in rails I would use rails console

4:08 wasamasa: ^

4:08 stain: I wouldn't give a support person full access to the whole of the database

4:08 Pupeno: stain: same thing I mentioned before. I'm not asking for a command line tool. I already have and know those. I'm asking for a UI tool, something at the active admin level or so.

4:09 stain: but where is your data now..?

4:09 Pupeno: stain: it's stored in PostgreSQL.

4:09 newcljuser: Hi! I can't figure out why am I getting this dependency error even though I have already imported core.async. http://pastebin.com/C3pwfhmt

4:10 wasamasa: given the way web development is done with clojure, I very much doubt there is such a standalone thing

4:10 maybe it does exist for the more framework-like approaches like luminus

4:10 Pupeno: wasamasa: yeah, I agree.

4:10 stain: Pupeno: any of these? https://wiki.postgresql.org/wiki/Community_Guide_to_PostgreSQL_GUI_Tools

4:10 Pupeno: wasamasa: luminus is not a framework, it's just a template for the usual libraries, compojure and so on.

4:11 tdammers: Pupeno: http://pgadmin.org/ <- this one isn't half bad

4:12 Pupeno: stain: I'm not sure if my support person could use one of those. I do it myself. My problem with Navicat is that it lists all the databases, finding the one you want among the 1000s in Heroku is a pain. I tried PgAdmin for a while, but found it a bit buggy.

4:13 I think I might just throw an empty rails app with active_admin in another server. But if I'm going to do that, I wonder whether there are better tools that would work like that.

4:14 wasamasa: you could just write your own admin route

4:14 newcljuser: Please, can someone help?

4:15 this is what my imports look like: http://pastebin.com/mPGu0b3u

4:15 I am using clojure 1.7

4:15 Pupeno: wasamasa: that is one of the options, and I'm really tempted because it looks line fun, but I already spent way too much time building things to make up for missing stuff in the Clojure world that is already built in RoR; if I keep doing that, my business decision should be to go back to RoR instead of using Clojure.

4:15 oddcully: newcljuser: i have my doubts that the version number there does any good

4:16 newcljuser: What should I do?

4:16 oddcully: newcljuser: use clojure.core.async :as async :refer [ ... ]

4:17 newcljuser: and since you have added it here, i just ask: have you added it in your projects deps?

4:19 newcljuser: @oddcully yes

4:19 I am using clojure 1.7 though

4:23 oddcully: now I am getting this java.lang.Character cannot be cast to clojure.lang.Named

4:26 roelof: hello, what is wrong with this code : http://lpaste.net/140432

4:27 luma: you destructure your point as a vector inside a vector

4:28 oddcully: ,(name \a)

4:28 clojurebot: #error {\n :cause "java.lang.Character cannot be cast to clojure.lang.Named"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Character cannot be cast to clojure.lang.Named"\n :at [clojure.core$name invokeStatic "core.clj" 1527]}]\n :trace\n [[clojure.core$name invokeStatic "core.clj" 1527]\n [clojure.core$name invoke "core.clj" -1]\n [sandbox$eval25 invokeStatic "NO_SOURC...

4:28 oddcully: newcljuser: if you relate this error with your code please

4:30 roelof: luma: oke , back to the drawing board and read manuals how to destruct this properly

4:32 oddcully: roelof: && looks out of place

4:32 roelof: If I change it to this : http://lpaste.net/140433 i cannot xp

4:33 oddcully: what I try to say it that the xp must be between x1 and x2 and yp must be between y1 and y2

4:34 oddcully: roelof: in the last one your let []-brackets are off

4:38 roelof: oddcully: thanks, again back to the manual

4:41 found it. The good answer is this : http://lpaste.net/140434

4:56 gargsms: I am authenticating my routes with friend. I used the friend/authenticate wrapper. When I access /login with the correct authentication params, I receive a response from /. But when I try to open the routes wrapped in friend/authenticate without any params, they function just fine.

4:57 dstockton: gargsms: think you have to wrap the routes in authorize

4:58 https://github.com/cemerick/friend#authorization

5:19 gargsms: dstockton, I don't have any roles defined as such. Can I still use authorization?

5:19 tdammers: q: can I somehow make it such that stack traces include full filenames instead of just the basename?

5:19 dstockton: gargsms: i don't think so

5:19 tdammers: "core.clj" isn't exactly helpful usually

5:20 dstockton: i don't know honestly, but you can just define one role

5:20 that everyone has

5:20 gargsms: The problem is that I am reading my users from a DB and there I haven't defined any roles

5:22 dstockton: gargsms: you probably have a get-user type function that returns a map

5:22 just assoc on a role for everyone

5:22 after fetching the rest from the db

5:23 gargsms: i will try that now

5:23 dstockton: probably what i'd do, then you can easily replace it with a real role from the db if you wanted them later

5:27 amalloy: tdammers: you can infer the filename from the name of the class in the stacktrace

5:27 it's not ideal i admit, but enough informatio is there

5:27 tdammers: amalloy: yeah, hmm, figured it out

5:28 amalloy: eg, the file is core.clj but the exception is being thrown from clojure.core$inc

5:28 tdammers: the actual stack trace, the part that I'm interested in, is three screens up

5:28 yeah, got it

5:28 just got thrown off by this helpfully colored stack trace

5:28 which turns out to be the part that I don't need; the interesting part is what gets dumped *before* that

5:29 amalloy: *shrug* sometimes. i usually find the most interesting part is the top line of the bottom-most exception. but it depends

5:30 tdammers: it seems that in this case, there is some sort of exception handler hooked into the app that is supposed to produce helpful debugging output in the browser, but that thing itself is throwing

5:32 Pupeno: I’m doing some performance testing of my Clojure app, and it seems the bare minimum will happily eat 350MB of RAM (Jetty with 6 threads, the minimum). As soon as I add Nashorn, it jumps to >512MB. Is this common or am I experience a problem here? Clojure/Java being memory hungry might have an effect on whether I use Heroku or not.

5:36 kwladyka: Pupeno, try load only Nashorn and check how many MB consume

5:38 Pupeno: kwladyka: how would you do that? what would be the goal?

5:39 kwladyka: Pupeno, i don't know. I don't use Nashorn :)

5:40 But maybe just Nashorn consume this memory. It sounds like that.

5:40 Pupeno: kwladyka: I don't mean how do I measure memory usage. What I have is coming from New Relic.

5:40 kwladyka: I'm pretty sure it's Nashorn consuming that memory.

5:42 kwladyka: mmmm so what is the question?

5:42 Pupeno: I already deployed my app with Nashorn disabled and my testing reported the numbers I already mention. I don't want to re-measure Nashorn, I want to know if this numbers are what to expect.

5:43 Is it common from a bare minimum compojure app to take on 350MB of ram. Is it common for a library or a few libraries to push it beyond 512MB?

5:43 kwladyka: ok, so i don't use Nashorn so i guess i can't tell anything more.

5:43 Pupeno: ok.... let's try again.

5:43 kwladyka: Pupeno, 350 MB in REPL or as jar?

5:44 Pupeno: kwladyka: RAM.

5:44 I’m doing some performance testing of my Clojure app, and it seems the bare minimum will happily eat 350MB of RAM (Jetty with 6 threads, the minimum). Is this common or am I experience a problem here? Clojure/Java being memory hungry might have an effect on whether I use Heroku or not.

5:44 kwladyka: Pupeno, yes but are you running your app in REPL or as jar file?

5:44 REPL consume more and it is slower

5:44 Pupeno: kwladyka: a jar file as far as I know... Heroku runs the uberjar.

5:44 kwladyka: if you want have real result test it as jar file

5:45 Pupeno: This is New Relic instrumentation of my app, as real as it gets. And when the app is actually doing something, it goes above 512MB, which I can see in the graphs and in Heroku throwing out-of-memory errors.

5:46 kwladyka: Pupeno, what i can say i have experience only with performance test on my local machine with one algorithm. And what i can say from that:

5:47 1) i had problem with memory, because of not optimal code. It is hard to do things optimal sometimes.

5:47 2) i had problem with time execution because of reflections

5:48 3) and a few more but it is not important in this topic i guess...

5:49 anyway after only changing the code i changed memory and time extremely, but i don't know what exactly you are doing

5:52 sorry i cant help more

5:52 wasamasa: let's write webapps in C to conserve RAM

5:58 ashwink005: does anyone has any info on writing deftests for a mysql db CRUD operations?

6:05 Pupeno: kwladyka: thank you for the comments.

6:05 ashwink005: I use a test database and talk to the real thing. I don't think it worth it to mock it up or anything. Is that what you are asking?

6:06 ashwink005: what I do is put every test inside a transaction so that after the test runs, the data goes back to normal.

6:06 ashwink005: you can look at luminus to achieve that as we implemented it there.

6:16 gargsms: I am doing ( ( juxt identity (assoc ? :a "1" ) { :b "2" } )

6:16 What do I replace ? with to make it work?

6:16 I need { :b "2" :a "1" } at the end

6:24 dstockton: ,(assoc {:a "1"} :b "2")

6:24 clojurebot: {:a "1", :b "2"}

6:27 gargsms: dstockton, I need to pass the result of identity at the place of ?

6:27 dstockton: i think you want something like (assoc identity :role ::user)

6:29 gargsms: Then I get the error clojure.core$identity cannot be cast to clojure.lang.Associative :(

6:33 oddcully: ,((juxt identity #(assoc % :a "1" )) {:b "2" })

6:33 clojurebot: [{:b "2"} {:b "2", :a "1"}]

6:40 gargsms: oddcully, thanks. what is the # for? I don't have much knowledge of Clojure. :/

6:40 dstockton: its a shorthand for an anonymous function, % is the single argument that it accepts

6:41 Bronsa: #(f %) -> (fn [x] (f x))

6:49 gargsms: Bronsa, how can two NaN be equal?

6:50 ,(= Double/NaN Double/NaN)

6:50 clojurebot: false

6:50 gargsms: I remember someone mentioning last day that you know of one hack

6:50 s/hack/trick

6:52 Bronsa: ,(let [[a] [Double/NaN]] (= a a))

6:52 clojurebot: true

6:52 Bronsa: boxed NaNs are equal in java

6:53 gargsms: Ah.

7:04 ashwink005: I'm getting a string as k1=v1;k2=v2 etc. How can I convert it to a HashMap?

7:09 oddcully: ashwink005: split on `;` and then split each item on `=` for the element

7:10 ashwink005: so split, join, split

7:11 oddcully: what do you want to join?

7:13 ashwink005: oddcully: I don't think I can split on the resultant vector can I?

7:13 without iteration

7:16 luma: ,(into {} (map #(clojure.string/split % #"=") (clojure.string/split "k1=v1;k2=v2;k3=v3" #";")))

7:16 clojurebot: {"k1" "v1", "k2" "v2", "k3" "v3"}

7:18 oddcully: ,(let [s "k1=v1;k2=v2"] (apply hash-map (clojure.string/split s #"[=;]")))

7:18 clojurebot: {"k1" "v1", "k2" "v2"}

7:19 Rurik: you can split on multiple chars in a regex?

7:19 opqdonut: oddcully's solution is a bit flaky though

7:19 oddcully: opqdonut: it's aggressive ;)

7:19 opqdonut: ,(let [s "k1=v1=k2=v2;"] (apply hash-map (clojure.string/split s #"[=;]")))

7:19 clojurebot: {"k1" "v1", "k2" "v2"}

7:19 opqdonut: yeah

7:31 ashwink005: luma: Thanks alot man!

7:31 worked!!

7:35 oddcully: ,(into {} (map #(clojure.string/split % #"=" 2) (clojure.string/split "k1=v1=k2=v2;k3=v3" #";")))

7:35 clojurebot: {"k1" "v1=k2=v2", "k3" "v3"}

8:28 Olajyd_: Hi All :)

8:33 Please how can i modify this function (partition-by identity "LeeerrroyyLLy") suche that i have something like [[\L\L\L][\e\e\e][\r\r\r][\o][\y\y\y]]?

8:36 ashwink005: Olajyd_: you could use java functions to sort it, then create a char array, then selectively create a vector

8:36 Bronsa: Olajyd_: does the order matter?

8:37 Olajyd_: Bronsa, Nope

8:37 Bronsa: ,(vals (group-by identity "LeeerrroyyLLy"))

8:37 clojurebot: ([\L \L \L] [\e \e \e] [\r \r \r] [\o] [\y \y \y])

8:38 luma: also, if you just want the count of each letter, you can use (frequencies "LeeerrroyyLLy")

8:38 Olajyd_: Bronsa, merci :)

8:38 lluma, really?

8:38 luma, really?

8:39 luma: ,(frequencies "LeeerrroyyLLy")

8:39 clojurebot: {\L 3, \e 3, \r 3, \o 1, \y 3}

8:44 Olajyd_: Aite thanks

8:47 Bronsa, say given (def rows [["coke" "5.6ml"] ["beer" "10.7ml"] ["coke" "500ml"] ["smirnoff" "5.6ml"] ["Red-wine" "33ml"] ["coke" ""] ["beer" “”]]), can I apply the solution you gave based on column 1?

8:47 Bronsa: just (map first rows)

8:49 Olajyd_: we’d want to group all rows based on column 1

8:51 so we’d have something like [["coke" "5.6ml"] ["coke" "500ml"] ["coke" ""] ["beer" "10.7ml"] ["beer" ""] ["smirnoff" "5.6ml"] ["Red-wine" "33ml”]]

8:51 oddcully: use first instead of identity

8:52 Olajyd_: Bronsa, ok

8:52 Thanks that worked

8:52 :)

8:59 Bronsa, say we want to remove duplicates based on the value of a given column, i.e given column 2 to have a value of “5.6ml”, after grouping ;)

9:05 sobel: how would ["coke" "5.6ml"] be selected over other elements where "coke" is the 1st element?

9:06 Hrorek: sobel, (first ["coke" "5.6ml"])

9:08 sobel: Hrorek: yes, i know how to achieve that result, i was asking Olajyd_ what logic should select that element

9:08 Hrorek: ahh, sorry

9:08 sobel: np ):

9:08 :)

9:22 Olajyd: sobel, hmm

9:24 sobel: Olajyd: point being, you don't have duplicate elements of the outer vector

9:24 Olajyd: after grouping, we’d want to apply a dedups function such that if the second column in the given row is not equal to “5.6ml” we want to remove the row, thus th result will look like: [[“coke" "5.6ml"] ["beer" "10.7ml"] ["beer" ""] ["smirnoff" "5.6ml"] ["Red-wine" "33ml”]]

9:25 sobel: sounds like a job for filter

9:26 i don't know your whole context but it sounds like you need to filter before dedupe

9:28 Olajyd: sobel, can I share the problem on refheap so we can walk through the solution, if its ok by you? You are obviously more experianced ;)

9:29 *experienced

9:29 sobel: i won't be here much longer but if you're clear on what your goal is you can get lots of good help here

9:29 Olajyd: aite

9:29 Thanks

9:30 sobel: sure. i'm around frequently but about to have to take off for now

9:30 Olajyd: great

9:30 sobel, are you in the US?

9:31 sobel: yes, CST

9:31 i lurk here a lot 5-8am CST

9:32 i've gotten lots of small and large help here. it helps to have your questions really clear, but also be prepared to have your questions reformulated by someone who probably already understands what you're doing

9:33 ordnungswidrig: Olajyd: you might want to do (remove (fn [[f s]] (= s "5.6ml")) mysequence)

9:33 where (fn [[f s]] (= s "5.6ml")) is the same as (fn [row] (= (second row) "5.6ml"))

9:34 Olajyd: ok nice, ordnungswidrig :)

9:59 triss: hey all. anyone like to point out the major differences between codeina and codox?

9:59 codeina looks a touch easier to configure?

11:18 ceruleancity: is there a good way to reduce the depth of nested empty seqs? for example turn (("123")) into ("123")

11:19 right now I'm basically using (first (("123"))) because I know the seq I'm dealing with will always be a seq containing one and only seq

11:20 expez: cursork: flatten

11:20 ,(flatten [[1 2] [3 4]])

11:20 clojurebot: (1 2 3 4)

11:21 expez: ,(flatten [[1 [2] [3 [4]])

11:21 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

11:21 expez: ,(flatten [[1 [2]] [3 [4]])

11:21 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

11:21 expez: impossibru without paredit

11:23 ceruleancity: @expez mein dude

11:23 tyvm

11:24 oddcully: ~flatten

11:24 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

11:43 kavkaz: If I have an infinite lazy sequence, can I let it go on for a while and then interrupt it and take the element it was currently at?

11:46 MasseR: kavkaz: I don't think so

11:46 But you can take the nth element of an infinite sequence if that is what you need

11:49 expez: kavkaz: the sequence is lazy. If you're not asking it for values it won't produce any. Since it's not doing any work when you're not asking it for values there's also nothing to interrupt.

11:50 ClashTheBunny: kavkaz, do you want to filter and then take the first value?

11:50 something like:

11:51 (take 1 (filter #(= 5 %) (range))) will give you the first time that the infinite sequence equals five.

11:52 Or do you want a time based selection?

11:52 kavkaz: ClashTheBunny: Ah I see.

11:52 ClashTheBunny: I would rather have a time based selection yes, something like that

11:53 ClashTheBunny: Something like generate permutations for 16ms then render the newest permutation?

11:54 I think you want something like https://clojuredocs.org/clojure.core.async/timeout

11:55 kavkaz: ClashTheBunny: I will look into that, thank you

11:56 ClashTheBunny: This is on the JVM, right?

11:56 roelof: hello, I have this project file (http://lpaste.net/140445) but still I see this error message : No :main namespace specified in project.clj.

11:57 kavkaz: Basically I have an infinite lazy prime sequence I implemented. It's very useful when wanting the nth prime, rather than the last prime under n limit. But I wanted to use it in a continuous way, where it just keeps going and going and prints every nth prime or something like that

11:57 ClashTheBunny: Yeah this is on the JVM

12:01 noncom: in clojure i am assembling a list of command line params to be passed to an application that i will run with conch. i have my initial params in a [], then i want to add some other params, depending on conditions

12:01 the problem is that when i conj params, what is returned is a list and it has it's order reversed

12:02 after a few sequential additions, i get a total mess

12:02 what is the idiomatic way to get around this?

12:02 roelof: no web developers here ??

12:02 noncom: i do some little web

12:02 with cljs

12:05 roelof: noncom : I do follow the web development with clojure and have some trouble with the first example

12:05 hello, I have this project file (http://lpaste.net/140445) but still I see this error message : No :main namespace specified in project.clj.

12:06 noncom: roelof: you specify a function but you must specify a namespace in which there is a function named "-main", the name is obligatory

12:07 it must be of signature (defn -main [& args] ...)

12:07 where "args" will contain all parameters passed to your app from the command line

12:07 as strings

12:07 oddcully: noncom: conj onto a vector gives you back a vector

12:07 rhg135: A static main method

12:08 roelof: noncom: this is the function : http://lpaste.net/140446 . I do it like the book says

12:08 noncom: roelof: nono. you *must* have a funtion named "-main"

12:08 roelof: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L177

12:09 roelof: not much freedom in this, it's just java

12:09 oddcully: how strange. why was i getting lists back then...

12:11 rhg135: And gen-class

12:11 oddcully: noncom: hard to tell without any further information. maybe you are doing at one point something else? map/filter/...

12:11 noncom: oddcully: maybe.. or maybe i used concat..

12:11 rhg135: yes, a gen-class is also important iirc

12:12 rhg135: Yup

12:14 noncom: oddcully: this thing is very nasty:

12:14 ,(conj (concat ["a"] ["b"]) "m")

12:14 clojurebot: ("m" "a" "b")

12:15 noncom: and i really wish it returned ["a" "b" "m"]... since why would i even wait it to behave the way it does?

12:16 rhg135: It always returns a seq

12:18 noncom: rhg135: yeah, but..

12:19 kavkaz: ,(conj (into [] (concat ["a"] ["b"])) "m")

12:19 clojurebot: ["a" "b" "m"]

12:19 rhg135: It's annoying for sure on vectors, but nice and simple

12:19 kavkaz: noncom: Would that be feasible for you to do?

12:20 oddcully: ,(conj ["git" "commit"] "-a" "-m" "lerl]")

12:20 clojurebot: ["git" "commit" "-a" "-m" "lerl]"]

12:21 rhg135: ,(let [x [1 2 3] y [4 5 6]] `[~@x ~@y])

12:21 clojurebot: [1 2 3 4 5 ...]

12:22 rhg135: Don't do that

12:23 apply conj should work fine

12:25 ,(into [1 3 5] [7 9])

12:25 clojurebot: [1 3 5 7 9]

12:28 roelof: noncom : thanks

12:35 tmtwd: how do we make http requests with om/reagent/cljs?

12:35 I can't find good resources

12:35 ClashTheBunny: cljs-ajax?

12:39 novak`: If I have this kind of expression in Emacs (fo|o1 (foo2 some)) and I want to get (| (fo|o1 (foo2 some))) how to do that? Does it supported by Smartparens or Paredit or something?

13:15 noncom: kavkaz: rhg135: oddcully: thank you guys!

13:15 avallark: hello all :)

13:16 noncom: avallark: hello!

13:17 avallark: noncom: great to get a response. someohow irc is so dead these days.. the only place poeple seem to talk is in #ubuntu and i think i am still banned there :D

13:17 noncom: i find #clojure, #emacs, #lisp, #lispcafe, #libgdx are pretty alive...

13:17 #lispgames also

13:18 avallark: lispgames? nice.. checking it out

14:44 TEttinger: so I can report now that an early build from source of OpenJDK 9 does work on Windows, it does start up small Java applications noticeably faster, it does start up maven a hair faster, and it does not appreciably speed up the load times for lein repl (even in an empty folder), because I think the majority of the time is spent loading jars from disk.

14:51 justin_smith: TEttinger: it would be interesting to see that profiled

14:52 TEttinger: the profiler would complain that my disk is too slow

14:55 amalloy: TEttinger: there is a lot of time spent running the foo.core$__init classes and so on, too

14:55 i'm pretty sure it's not just disk i/o - you can cat an uberjar a lot faster than you can start it up

15:14 lodin_: Why is (:require [foo :refer :all]) prefered over (:use foo)?

15:15 TEttinger: I don't think either is preferred over not referring

15:15 but for just the two of those, hm, not sure

15:15 Pupeno: What do you use to deploy clojure web apps?

15:17 Empperi: ansible

15:18 fijgr: In CIDER for Emacs, is it possible to eval every file in src/ and test/? It's pretty annoying to have to open every file in a buffer, and eval them all, to get all the vars I need instantiated

15:18 Or is it possible to eval everything in a ns with only clojure? Then cider doenst need to do it

15:19 justin_smith: fijgr: this is what require is for

15:19 it recursively loads an ns and everything it requires

15:19 typically a project will have a single ns that is the top of the dep tree, and loading that one will cause all other code to load

15:20 fijgr: justin_smith: so if everything is loaded from (or loaded from a child of) my core ns, its top-level forms will be eval-ed?

15:20 justin_smith: fijgr: right, that is what require is meant to do

15:21 fijgr: justin_smith: hmm, I see... I'll have to check that out again. Thank you for your answer :)

15:21 justin_smith: fijgr: one gotcha is if there is an error during the first load, you need to use the :reload or :reload-all argument to require to force reloading

15:21 Empperi: https://www.youtube.com/watch?v=EOjGsdDoicw

15:22 fijgr: justin_smith: I see. It was not functioning as you describe it, so maybe I have to do that. Will try. Thank you very much for answering my noob question!

15:35 noim: Any help will be appreciated: https://gist.github.com/anonymous/041dc81e168f176c7ab1

15:36 justin_smith: noim: maps are not ordered

15:37 noim: hrm any better ideas for a data structure then?

15:37 justin_smith: noim: you will need to either manually sort things, or use a sorted-map instead of a map

15:38 or maybe an ordered map (you can get that from a lib)

15:52 TEttinger: noim, justin_smith: maps are not sorted but keys and vals both return vecs that have the same order

15:53 ,((juxt keys vals) {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]})

15:53 clojurebot: [(:a :b :c :d :s) ([34 56 7] [21 87 999] [3] [2 4] [4])]

15:53 TEttinger: ,((juxt keys vals) {:s [34 56 7] :b [21 87 999] :c [3] :d [2 4] :a[4]})

15:53 clojurebot: [(:s :b :c :d :a) ([34 56 7] [21 87 999] [3] [2 4] [4])]

15:53 TEttinger: woah, I'm surprised it's holding up insertion order there

15:54 ,((juxt keys vals) (hash-map :s [34 56 7] :b [21 87 999] :c [3] :d [2 4] :a[4]))

15:54 clojurebot: [(:s :c :b :d :a) ([34 56 7] [3] [21 87 999] [2 4] [4])]

15:54 TEttinger: there we go, it was using an ArrayMap maybe before?

15:56 also, noim, your example doesn't make sense in that gist

15:56 clojurebot: Excuse me?

15:56 noim: the intenntion with transform is to setup the rows for an html table

15:57 TEttinger: ok

15:57 I mean the numbers don't coincide with the ones you gave earlier, and aren't in the same order as supplied in the vectors

15:59 noim: I failed at copying heres the function call (transform {:a [34 56 7] :b [21 87 999] :c [3] :d [4 5 ] :s [4]})

16:02 my function also explodes if I have some thing like this (transform {:a [34 56 7] :b [21 87 999] :c [3] :d [4 5 7] :s [1 3 4]})

16:03 wrong number of args 3 passed to core/vec

16:04 TEttinger: &(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]}] (map (fn [i] (map vector (keys data) (map #(nth % i) (vals data)))) (range)))

16:05 lazybot ded

16:05 ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]}] (map (fn [i] (map vector (keys data) (map #(nth % i) (vals data)))) (range)))

16:05 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

16:05 TEttinger: hm

16:05 ah!

16:06 ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]}] (map (fn [i] (map vector (keys data) (filter some? (map #(nth % i nil) (vals data))))) (range)))

16:06 clojurebot: (([:a 34] [:b 21] [:c 3] [:d 2] [:s 4]) ([:a 56] [:b 87] [:c 4]) ([:a 7] [:b 999]) () () ...)

16:06 TEttinger: it doesn't have the lone pairs separated

16:06 and there's worse problems hm

16:08 ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]}] (map (fn [i] (remove #(nil? (second %)) (map vector (keys data) (map #(nth % i nil) (vals data))))) (range)))

16:08 clojurebot: (([:a 34] [:b 21] [:c 3] [:d 2] [:s 4]) ([:a 56] [:b 87] [:d 4]) ([:a 7] [:b 999]) () () ...)

16:10 TEttinger: ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]}] (take-while seq (map (fn [i] (remove #(nil? (second %)) (map vector (keys data) (map #(nth % i nil) (vals data))))) (range))))

16:10 clojurebot: (([:a 34] [:b 21] [:c 3] [:d 2] [:s 4]) ([:a 56] [:b 87] [:d 4]) ([:a 7] [:b 999]))

16:10 TEttinger: that gets rid of an infinite lazyseq

16:11 noim: it would be fine if I could get to the next key and extract the first element from each vector val as every n-tupple is a complete row

16:11 nice

16:12 TEttinger: if the loners need to be separate, there happens to be a way...

16:15 ,(let [data (map (fn [[k v]] (if (= (count v) 1) [k v] [k (concat [nil] v)])) {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]})] (take-while seq (map (fn [i] (remove #(nil? (second %)) (map vector (keys data) (map #(nth % i nil) (vals data))))) [1 2 3 0])))

16:15 clojurebot: (([:a 34] [:b 21] [:d 2]) ([:a 56] [:b 87] [:d 4]) ([:a 7] [:b 999]) ([:c 3] [:s 4]))

16:16 TEttinger: (I'm extremely surprised that worked, I would have thought it would need into {})

16:16 noim: does that do the trick?

16:17 you would need to figure out the maximum count of the vals, which is just...

16:17 ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]})] (apply max (vals data))

16:17 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

16:17 TEttinger: ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]})] (apply max (vals data)))

16:17 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

16:17 TEttinger: ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]}] (apply max (vals data)))

16:17 clojurebot: #error {\n :cause "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers gt "Numbers.java" 229]}]\n :trace\n [[clojure.lang.Numbers gt "Numbers.java" 229]\n [clojure.lang.Numbers max "Numbers.java" 4027]\n [clojure.core$max invoke...

16:17 TEttinger: sorry

16:18 noim: no worries

16:18 TEttinger: ,(let [data {:a [34 56 7] :b [21 87 999] :c [3] :d [2 4] :s[4]}] (apply max (map count (vals data))))

16:18 clojurebot: 3

16:18 noim: in that first let form what does range do

16:19 TEttinger: noim, are you maybe scrolled up in the chat log?

16:19 noim: no I just wasnted to know what it did

16:20 TEttinger: oh ok

16:20 ,(range 4)

16:20 clojurebot: (0 1 2 3)

16:20 TEttinger: ,(range)

16:20 clojurebot: (0 1 2 3 4 ...)

16:20 TEttinger: range with no args is an infinite lazyseq from 0 onward

16:21 it needed the (take-while seq .......) because that stops the map once it gets to an empty return sequence

16:21 that is, you see ([:a 7] [:b 999]) () () ... in one of the returns without take-while in the code?

16:22 it would have kept doing () () () () forever without the take-while, but lazybot stops execution after 5 elements in any collection

16:25 noim: ah ok

16:27 nesting was confusing me

16:30 neoncontrails: TEttinger: just curious, how does (range) avoid overflowing once it hits the Java int limit?

16:30 Does it just convert at that point to bigint?

16:34 TEttinger: neoncontrails: hopefully it never gets that far

16:34 that's the lazy part

16:35 neoncontrails: Sure, right. But suppose that it does. I believe it still works, right?

16:35 I've used (range) for Project Euler problems and never had trouble.

16:36 TEttinger: ,(nth (range) 36rZZZZZZZZZ)

16:36 clojurebot: #error {\n :cause "Value out of range for int: 101559956668415"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Value out of range for int: 101559956668415"\n :at [clojure.lang.RT intCast "RT.java" 1198]}]\n :trace\n [[clojure.lang.RT intCast "RT.java" 1198]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compi...

16:36 TEttinger: there you go.

16:36 ,(nth (range) 36rZZZZZZ)

16:36 clojurebot: #error {\n :cause "Value out of range for int: 2176782335"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Value out of range for int: 2176782335"\n :at [clojure.lang.RT intCast "RT.java" 1198]}]\n :trace\n [[clojure.lang.RT intCast "RT.java" 1198]\n [sandbox$eval49 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval49 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "...

16:36 neoncontrails: !!! I'm glad you clarified this.

16:36 TEttinger: that might be nth doing that

16:36 I think nth can't access more past the 2^31th item

16:37 ,(nth (range) (bit-shift-left 1 31))

16:37 clojurebot: #error {\n :cause "Value out of range for int: 2147483648"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Value out of range for int: 2147483648"\n :at [clojure.lang.RT intCast "RT.java" 1198]}]\n :trace\n [[clojure.lang.RT intCast "RT.java" 1198]\n [sandbox$eval73 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval73 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "...

16:37 TEttinger: ,(nth (range) (bit-shift-left 1 30))

16:37 clojurebot: Execution Timed Out

16:37 TEttinger: and yeah lazyseqs need to calculate every element to do nth

16:38 since they're very similar to iterators

16:39 neoncontrails: That would make sense

16:40 noim: thanks again

16:41 nooga: hah

16:42 I'm trying to implement efficient immutable graph and it seems that I have no idea how to start

16:45 TEttinger: nooga: have you tried the Purely Functional Data Structures book?

16:45 nooga: I'd like to (let [g (graph) a (add-node g {:foo :bar}) b (add-node g {:baz :quux})] (add-edge g :label a b)) but since the graph is immutable, add-node and add-edge should return new graph

16:46 so this example is stupid

16:46 TEttinger: no, I havent

16:46 TEttinger: http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf

16:46 nooga: thx

16:50 TEttinger: no graphs in it though

16:52 nooga: yup

16:52 turbofail: easiest way is probably just a map from node-names to edges

16:53 nooga: yeah but that requires node names from the user

16:53 turbofail: not necessarily, you could just have add-node generate names automatically

16:54 obviously you'd still have to thread the graph objects through it, probably using ->

16:55 anyway there's also https://github.com/aysylu/loom to look at

16:59 nooga: hm

17:00 turbofail: add-node could generate ids internally but then how can I say connect this to that

17:04 it (let [g (add-node (graph) :x) x (last-node g) g2 (add-node g :y) y (last-node g)] (add-edge g2 :z x y))

17:04 it could be*

17:05 but this will be catastrophic if I want concurrent writes

17:11 Wild_Cat`: what's the best practice on functions that take [& args] vs functions that take one seq/vector argument?

17:11 (as in, when should I use one or the other?)

17:15 arry: hi! can somebody tell me how to create a new Compojure project? The docs say `lein new compojure-app foo` but it doesn't work, because `lein new` doesn't seem to use the template.

17:15 (when running `lein help new`, it says Arguments: ([project-name] [project-name project-dir]))

17:19 TEttinger: arry: hm, I wonder if lein can't connect to clojars on the internet

17:22 arry: i think i've found the problem: lein version is 1.7.1 (installed via apt-get), while the site says that current version is 2

17:22 i'm going to reinstall 'properly' and try again

17:26 neoncont_: I was gonna ask this in #clojure-beginners, but it's looking a little dead there. Maybe #Clojure can help.

17:26 I just configured figwheel. Trying to write my first webapp. Basic. Just a gui calculator. Figured I should start small.

17:28 oddcully: neoncont_: feel free to continue here. but so you know: there is also a #clojurescript channel

17:28 neoncont_: I have HTML buttons, and my core.cljs file is interfacing with the browser. I can send alerts to the buttons, but I'm not sure how to make them interactive. Can someone hold my hand?

17:29 arry: yep, the old version was the reason. Now it worked out of the box.

17:29 neoncont_: oddcully: Oh cool, thanks! Sorry if this is off-topic

17:30 ferz_: Hello, I am having some issues with running demo Seesaw app. I am getting java.awt.HeadlessException when running lein on Ubuntu. Am I missing something?

17:30 oddcully: neoncont_: you mean you are doing alert calls in your onclick of the button?

17:32 neoncont_: oddcully: heh, so I have figured out how to make the button do something on click. But I'm not sure how to approach the problem of composing a function of three separate button click events. Does that make sense?

17:32 oddcully: ferz_: is -Djava.awt.headless=true in JAVA_OPTS? or is it the other way around?

17:33 neoncont_: Or, I should say, at least 3

17:33 oddcully: neoncont_: so you want to have some action once three or more buttons are clicked by the useR?

17:34 neoncont_: oddcully: yeah. I want the app to behave exactly as a calculator behaves.

17:35 ferz_: oddcully: I did 'echo "$JAVA_OPTS"' and it didn't return anything, not sure how else to check it

17:36 oddcully: ferz_: are you running your code as root and your x11 is running as a regular user? has the user a DISPLAY var set and can it start x11 apps that show up?

17:36 TEttinger: ferz_: can you check in the package manager if you installed some kind of headless version of openjdk or oracle java?

17:36 but oddcully's suggestion is more important to check

17:37 justin_smith: oddcully: ferz_: you can check the value with ##(System/getProperty "java.awt.headless")

17:37 oddcully: yeah could be some "server env" setup for java in ubuntu - i have not used it for so long i don't know where to look

17:38 nooga: neoncont_: create some state holding your calculation

17:38 hlolli: ignore this message, first time using IRC in 20 years. So this is a test.

17:38 justin_smith: oddcully: iirc the default ubuntu java is a headless distro

17:38 TEttinger: hi hlolli.

17:38 justin_smith: TEttinger: he wanted you to ignore that message, you insensitive clod

17:39 hlolli: nice, well 1999 so almost 17 years. Ok, look forward to read interesting clojure discussion...

17:39 nooga: neoncont_: it could be a vector in an atom, that could behave as a stack for calculations, number buttons would conj numbers, operation buttons would take the numbers form the stack and conj result

17:40 TEttinger: haha

17:41 nooga: hlolli: please tell me that you're running some kind of IRC FS on Plan 9 like it's nineties again?

17:41 hlolli: No, I used Mirc on PC in the old days. Looking for a quake scrim. Now Im in emacs... That's old I guess :)

17:42 neoncont_: nooga: that makes sense. Just to make sure, this doesn't have to be anywhere represented as a DOM element, right? I can just define the vector somewhere in the core.cljs, and use it as a helper function in the code?

17:42 nooga: ahhh mIRC :D

17:43 neoncont_: I'd just stick (defonce state (atom [])) in there

17:44 (defn input-digit [d] ...) (defn input-operation [op] ...) and then use those two with swap! inside on-click handlers

17:44 this should keep things simple

17:44 neoncont_: defonce gets my vote for funniest, most bizarre-sounding language primitive I've learned yet

17:44 (inc defonce)

17:45 justin_smith: neoncont_: it rhymes with beyonce

17:45 neoncont_: Oh, god. Hahahaha

17:46 justin_smith: neoncont_: or at least it does if I convince enough people to pronounce it that way :)

17:46 nooga: yeah, wait until you make a typo when writing a controller :F

17:47 neoncont_: Défoncé is french for being drunk off one's arse, interestingly. Heh

17:47 oddcully: defonzie?

17:47 justin_smith: neoncont_: in all seriousness, the existence of defonce in core shows how important the idea of reloading and redefining things in runtime is in clojure

17:47 neoncont_: I had no idea

17:48 neoncont_: hlolli: Hey, welcome! I just saw your facebook post. :)

17:49 nooga: ,(defmacro défoncé [x y] `(defonce ~x ~y))

17:49 clojurebot: #'sandbox/défoncé

17:49 nooga: here

17:50 justin_smith: haha

17:50 luma: so, how does that represent being drunk off your arse?

17:50 ferz_: running this fixed it forwhatever reason 'sudo apt-get install default-jdk'

17:51 justin_smith: ferz_: yeah, I think you started out with the default jvm, which has no X support, but the default jdk does have X support

17:51 ferz_: anyway, what does everyone use to write GUI apps in Clojure?

17:51 oddcully: ferz_: has it actually installed something?

17:51 ferz_: yeah something was installed

17:51 oddcully: ferz_: maybe the jre is headless and the jdk changes the env

17:51 ferz_: 50mb of packages

17:51 nooga: ,(defmacro défoncé [x y] `(defonce ~x "burp"))

17:51 clojurebot: #'sandbox/défoncé

17:51 justin_smith: ferz_: in my opinion using an html renderer and clojurescript, with either reagent or om to manage the dom, is the best option right now

17:51 nooga: better

17:52 ferz_: Yeah I've played with Reagent recently, not much with Om. How about desktop apps?

17:52 justin_smith: ferz_: though seesaw uses a more traditional GUI and is OK too - I just don't think it has the same growth right now

17:53 ferz_: something like atom shell could do interesting things, and for more traditional jvm+X you can use seesaw (it's a swing wrapper)

17:53 ferz_: It looks like seesaw is dated a bit, their doc references Clojure 1.4, kinda behind

17:53 justin_smith: it's decent though

17:53 but yeah, not as active as the html oriented stuff

17:53 ferz_: I got my demo app to work so I will be messing with it today

17:53 thearthur: It's "mature"

17:54 justin_smith: people also use javaFX - I don't know if any good wrappers are out there? You can do it via regular interop.

17:54 ferz_: I think interop is pretty good enough, maybe that's why there is not a lot of wrapper or updates for seesaw

17:55 But I am fairly new to Clojure so I can't be the judge

17:55 nooga: ferz_: my Java colleagues wrote this "shell" JavaFX app and we just delivered clj logic

17:55 glue was thinner than I'd expect

17:55 justin_smith: nooga: yeah, glue between java and clojure tends to be pretty thin actually

17:56 I need a bigger desk.

17:57 tcrayford____: I need some glue for my desk

17:57 (it wobbles)

17:57 justin_smith: haha

17:57 I have some java on my desk, it's delicious

18:03 nooga: I once read that space probes used to be programmed in lisp and they had REPLs running on the spacecraft during its flight

18:04 that makes me want nREPL running inside my apps in production

18:04 which is probably dumbest idea ever

18:04 justin_smith: nooga: that's pretty easy to do with nrepl

18:04 nooga: I know :D

18:04 that's why it's so tempting

18:04 futuro: I've been curious about the efforts surrounding auth with nrepl

18:04 justin_smith: nooga: just be sure to only allow connecting to localhost

18:04 nooga: I could use ssh tunnels then

18:05 justin_smith: futuro: ssh is good enough for host based auth, per-user is another can of worms

18:05 as it stands, running nrepl means every process on your computer could escalate to your user's privs if it new how to exploit nrepl

18:05 futuro: justin_smith: yeah, a good first step at least

18:06 that's primarily why I'm curious about auth with nrepl

18:06 to help avoid exploits utilizing nrepl

18:06 justin_smith: futuro: if we ditch windows support it's doable with unix domain sockets

18:06 Wild_Cat`: (reposting but nobody answered) what's the rule of thumb on functions that take [& args] vs functions that take one seq/vector argument?

18:06 justin_smith: I don't think there's a portable secure option with the nrepl model

18:07 futuro: justin_smith: hmmm

18:07 justin_smith: has there been any work on securing nrepl on particular platforms?

18:07 with middleware, perhaps

18:08 justin_smith: Wild_Cat`: thanks to apply we can easily go from the former to the latter, I guess it depends on whether your functionality treats the args as equivalent items in a series or gives any of them special meaning

18:08 Wild_Cat`: that's precisely why I'm asking.

18:09 I mean, given the choice between arbitrary homogeneous arguments, and one argument that's a homogeneous sequence, when do I pick one or the other?

18:09 justin_smith: futuro: on unix you could do it with unix domain sockets, but I don't know of anything similar for windows. Maybe TEttinger knows of how to get user permissions for a local socket (or equivalent funcitonality) on Windows?

18:09 TEttinger: not... really

18:09 justin_smith: Wild_Cat`: I'd go with the latter almost always (but there are plenty of functions, like str that go the other way in core)

18:10 TEttinger: my method of security is mostly "don't do online banking"

18:10 justin_smith: Wild_Cat`: interesting question, I wonder if there are good arguments about when you would chose either one

18:11 nooga: Wild_Cat`: I'd go for the latter if you return another sequence or you expect long sequences, the former if you make scalar value from the arg sequence

18:44 Wild_Cat`: nooga: makes sense. Thank you!

20:02 neoncontrails: Is there an equivalent way of writing this code without Sablono? https://github.com/bhauman/lein-figwheel/wiki/Quick-Start

20:03 justin_smith: neoncontrails: well, you could use reagent, or om, or punch the dom in the face directly with your bare fists

20:03 each of these will look different

20:04 neoncontrails: Heh. I'd like to understand cljs basics first before I commit to a framework. Is that reasonable

20:05 justin_smith: using some version of react is much simpler than manual dom transformations

20:05 reagent, om, sablono are all react frontends

20:05 mungojelly: can anyone link me to a short program in clojure that makes a pretty picture?

20:05 neoncontrails: Not for ideological purity reasons, just because I find this code very mysterious for something so basic and simple

20:06 justin_smith: neoncontrails: the alternatives are not less mysterious

20:06 the DOM is weird

20:06 neoncontrails: Good to know.

20:07 justin_smith: mungojelly: I saw this guy talk recently about his project - it uses clojure to generate images, and then it mutates the code based on feedback on twitter https://github.com/rogerallen/tweegeemee

20:07 neoncontrails: I never did figure out how to implement that atomic swap nooga recommended earlier. Probably because I don't know the context in which my code is executing

20:08 justin_smith: mungojelly: that project uses Clisk, so you might just want to skip straight to Clisk and generate images that way https://github.com/mikera/clisk

20:09 mungojelly: here's the account for the twitter bot for tweegeemee that tweets the images it makes https://twitter.com/tweegeemee

20:09 mungojelly: each image links to source code that made it

20:09 mungojelly: justin_smith: wow that looks awesome thanks, evolving processes is just what i'm working on :)

20:09 justin_smith: awesome

20:11 mungojelly: also though does clojure have anything truly simple for beginners, you know like racket does, something where just a few words makes pictures appear?

20:11 justin_smith: mungojelly: that should be possible with clisk which I linked above

20:12 mungojelly: looks simple enough from here https://github.com/mikera/clisk#example-code-and-resulting-image

20:14 mungojelly: yay yeah that looks good! i've been mystified in the larger picture how there's so little given to real beginners, it seems so easy to throw people a bone and make something you can just play with.

20:15 justin_smith: mungojelly: there is also quil which is a wrapper for processing, oriented to beginners

20:15 mungojelly: is leinining.. leiningin.. leiningen, is this the package manager y'all use lately, i should learn that?

20:15 justin_smith: but fair warning, to an experienced clojure user some things about quil are just - a bit off

20:15 nooga: neoncontrails: I know the initial cljs ordeal can be mysterious and unclear

20:16 but really you just need to chill out, it's still the browser that's running your stuff, you don't need to know every bit of the stack you're running on

20:16 justin_smith: mungojelly: yes, it's how almost all of us manage dependencies - it's not quite a "package manager" in the traditional sense because there is no global install, just a local cache of available packages, and each run will decide which of those packages to make available to a program

20:16 so it's more selective, kind of like the nix package manager where you have full freedom of multiple package versions, which one version per program

20:17 *with

20:17 nooga: basically cljs functions are just JS functions in the end, runtime handles atoms and other async primitives so you don't have to worry

20:17 mungojelly: oh cool yeah nix is a distro right, i've been thinking of trying that out yeah, sounds good, makes sense

20:17 justin_smith: mungojelly: well, there is a nix distro and a nix package manager

20:17 nooga: reagent is just layer on top of react, which AFAIK decides what to do with DOM inside requestAnimFrame

20:18 justin_smith: mungojelly: but the real point was that unlike eg. gem or apt where you pick a version to install globally, you get to pick which versions of which lib you want on a per-run basis (and leiningen is built to manage that)

20:19 nooga: neoncontrails: try to write an inc/dec counter

20:19 mungojelly: ok yeah that's good, everything should work that way, we have enough disk space now, gotta keep up

20:19 justin_smith: :)

20:19 nooga: with two buttons

20:20 justin_smith: mungojelly: yeah, it simplifies things to have that kind of fine-grained per run control when needed (but it also does automatic recursive dep management and resolution, as you'd expect from a smart dep manager)

20:24 neoncontrails: nooga: did that already. And I get that it works, sure. I just don't see any reason why I shouldn't be able to now replace those calls to inc/dec with a cc like ((fn [val] (conj register val)), for instance

20:26 ferz_: I gotta ask this... Do I have to learn Emacs? I can't touchtype so should I bother with Emacs at all? I use Cursive at the moment. I haven't developed anything bing Clojure yet, am I better off with Emacs as an "investement" if I learn it?

20:27 justin_smith: ferz_: I don't think you are missing out using cursive instead of emacs

20:27 nooga: ferz_: I sterted using emacs with clojure and wouldn't come back but that's subjective imo

20:27 justin_smith: ferz_: emacs is what I use, and I love it, but for clojure development specifically cursive is probably better

20:28 nooga: neoncontrails: I'm not sure if I follow you, maybe you have a gist I can look at?

20:28 justin_smith: in terms of quality of feature integration and ease of use

20:28 neoncontrails: sure, let me rewind it to a previous state

20:28 mungojelly: ferz_: the fact that some people know a lot about emacs doesn't mean you need to know everything about emacs to use it, i'm by no means an expert in emacs but i certainly don't regret trying it out and learning some things-- it's free

20:29 nooga: and remember to get SYMBOLICS sticker for your keyboard...

20:30 ferz_: yeah thats what I am thinking. It seems like people are proficient in either vim or emacs can utilize it and it's nice to have editor that I can run from terminal. Maybe I should look into it.

20:30 touchtyping probably helps too?

20:30 justin_smith: yeah, I took the time to learn ed, vi, vim, and emacs, currently use emacs with evil mode (which emulates vim)

20:31 rhg135: It helps for a lot of things

20:31 mungojelly: ferz_: i use and recommend the dvorak keyboard, if you don't touchtype yet all the more reason not to learn wrong ;)

20:31 nooga: rebinding caps lock to ctrl helps

20:31 justin_smith: two great ways to learn touch typing while also ruining your life is to get into the game nethack or start playing muds. They are both addictive so you will get very good at typing fast.

20:31 ferz_: I've seen dvorak keyboards and it feels compelling, I just might do that

20:32 justin_smith: and also probably lose your job, and all your relationships, and flunk out of school if applicable, etc.

20:32 ferz_: oh then I am perfect for this game

20:32 I am already ahead...

20:32 justin_smith: heh

20:32 nooga: I was always afraid of non qwerty keyboards because they look like the best way to ruin your muscle memory

20:33 and make you unable to use any other machine besides your own

20:34 ferz_: how many of you code Clojure for a living?

20:34 justin_smith: ferz_: I've been a full time clojure dev for about 4 years now

20:34 ferz_: justin_smith: woah, nice

20:35 justin_smith: ferz_: I actually learned clojure because a job expected it (though I already did scheme / ocaml / common lisp for hobby projects)

20:35 ferz_: justin_smith: do you work in a clojure shop or it's one of the many languages you use?

20:35 I see

20:36 nooga: does running a startup powered by clojure count?

20:36 justin_smith: ferz_: funny thing, both of the long term jobs were ruby shops that started migrating to clojure for web dev for performance / stability reasons

20:36 with part of performance being how many servers you need to keep running (eg. a cost thing)

20:36 ferz_: nooga: actually yeah, big brownie points for a clojure startup, how is that working out? I want to see more clojure shops but alas it's rare

20:37 you think clojure will get more popular with start ups like ruby/rails?

20:38 nooga: ferz_: you're not the first person that tells me that :) It's my second company, we have an awesome team which comes from various backgrounds but we all like smart things so we got interested in clj, then started doing some side projects and then wrote our core stuff in clj

20:39 replacing node.js pieces one by one

20:39 justin_smith: ferz_: well, it has the bonus of facilitating more stable large scale design, and utilizing resources more effectively. But it has the disadvantage of not providing as many cookie cutter solutions to common tasks, and being a little harder for inexperienced devs to jump into sometimes (if even just because they are not used to so many parens)

20:39 ferz_: nooga: that's awesome, I hope it's working out for ya'll, I like clojure and I hope it gets more mainstream as a viable solution.

20:40 nooga: it's fun and we're learning a lot with every iteration

20:41 but we had mocroservices from the start so the transition wasn't very painful

20:41 microservices*

20:41 and some things even got smaller by factor of 10 code wise

20:42 justin_smith: gluten free macrobioticservices*

20:44 sorry, kidding

20:44 nooga: ferz_: from my experience, RoR shops have their methods polished and their CTOs aren't very keen to dump that for another tech

20:45 and they're still making good money

20:45 ferz_: I think my city has 1 Ruby shop and it's pretty new, some of their coders been playing with Elixir but thats about it.

20:45 Local clojure meetup has like 5 people...

20:46 and it's the 7th largest city in the US, lol

20:46 nooga: here we have a ruby shop that became international and huuge

20:47 but it's like a factory, they train students and write CRUDs

20:47 ferz_: thoughtbot? or something lol

20:47 nooga: I happen to know the CTO, he doesn't even like adapting new gems

20:48 JS community is pretty strong

20:48 ferz_: can't blame them, rails is solid

20:48 nooga: but I think there are only two clojure using companies in the town

20:48 justin_smith: nooga: aren't deps a huge source of instability in ruby land? that seems sensible from what I have heard

20:48 ferz_: I started to "get" ruby a bit more after clojure

20:48 nooga: one of which is mine, and there's this software house

20:49 mungojelly: i'm bikeyboardal, i only have to use qwerty occasionally to keep my qwertyism ok

20:49 nooga: justin_smith: it's a nightmare

20:50 IIRC ruby was excruciatingly slow

20:51 i used to like it but then it got sour after some time

20:51 ferz_: ruby is alright, still fun, but lisp blew my mind

20:52 nooga: l

20:52 lambda enlightment hehe

20:53 ferz_: to me it was like, why haven't I encountered this before, it makes so much sense..

20:53 neoncontrails: nooga: tried to modify this to insert a decrement side-by-side with increment, but my attempts at that just overwrote the previously created dom object. Oops

20:53 http://pastebin.com/1K6cFNw8

20:53 this is basically just the "getting started with figwheel" tutorial at https://github.com/bhauman/lein-figwheel/wiki/Quick-Start

20:56 nooga: [:a {:href "#" :onClick #(swap! data update-in [:likes] dec)} "Dec it"] ?

20:57 tried that?

20:59 neoncontrails: Yeah I just figured it out. I didn't realize you could nest two elements inside the same div

21:00 rhg135: HTML, it's fun to learn

21:00 nooga: neoncontrails:

21:00 http://pastebin.com/TtgfwTvN

21:01 neoncontrails: I'm familiar enough with HTML, but clojurescript that outputs *to* HTML is brand new to me

21:02 nooga: I'd guess that sablono is all about expressing html (DOM) as a data structure

21:03 neoncontrails: It does look that way, doesn't it

21:05 nooga: now try to bind text input to some bit of state, make some buttons that append digits to this string

21:07 #(swap! data update-in [:display] str digit)

21:08 add another field for current operation

21:08 etc

21:10 neoncontrails: "str digit" that's interesting, I'll try that

21:12 nooga: gotta go, but that actually solves a problem I was having trying to encapsulate the value.

21:12 Thanks!

21:12 (inc nooga)

21:12 ,(range 4)

21:12 clojurebot: (0 1 2 3)

21:13 neoncontrails: ,(inc nooga)

21:13 clojurebot: #error {\n :cause "Unable to resolve symbol: nooga in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: nooga 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: nooga in this...

21:13 neoncontrails: d'oh. I tried!

21:22 elvis4526: Hey, is there a way to display variables when debugging with CIDER in the repl ?

21:30 mungojelly: A+ to "lein repl" for telling me right off what to say to quit :o)

21:39 rhg135: ^D is nice

21:43 mungojelly: rhg135: ^D is what i would have tried, but it's nicer not to have to know things, i like for anyone else to be able to follow me. :/ speaking of, clisk doesn't have any cartoons or anything in it does it?

21:44 rhg135: Ah right screencasts exist

21:44 mungojelly: i want cartoons and toys and pretty things pls

21:48 rhg135: This seems out of context

21:48 mungojelly: you'd think writing games would entail writing little toy pieces people could play with but no, mostly big god objects :(

21:49 kavkaz: elvis4526: http://endlessparentheses.com/cider-debug-a-visual-interactive-debugger-for-clojure.html

21:57 elvis4526: It's pretty cool actually

22:13 rhg135: mungojelly: sad, ain't it

22:14 mungojelly: rhg135: i'm poking around the games i can find in clojure and tehy're all a flat list of functions like create-player-body-thingy :(

22:16 i'd just like some sort of play space, like you know morphic in squeak? or just things that know how to draw themselves in their bounding boxes so you can zoom around their world and ask the appropriate ones to draw themselves to you. any basic context to play with things.

22:17 dnolen: mungojelly: I'm not aware of anything that general in Clojure

22:17 TEttinger: mungojelly: have you seen play-clj ?

22:17 mungojelly: TEttinger: i haven't, i'm new, i'll look now :)

22:17 TEttinger: or brute for an ECS, there's at least three entity-component systems for clojure

22:18 https://github.com/muhuk/clecs https://github.com/markmandel/brute

22:18 and the resatori one doesn't have the blog working

22:18 http://web.archive.org/web/20150204201847/http://resatori.com/clojure-entity-component-system

22:19 play-clj has something called nightmod that is meant for beginners to clojure

22:19 https://sekao.net/nightmod/

22:22 mungojelly: ok yay that does look fun, thanks, i'm sure this will be enough to teach me, i just don't know why nowhere has anything really more basic and torn apart, where you can play by making really simple things

22:22 it seems like we're so abstracted that we literally cannot remember what normal simplicity even looks like, it becomes unimaginable

22:23 TEttinger: games are not something friendly to simplicity

22:23 mungojelly: but there's no reason we can't have a fun little world where the fun characters in the world are made with a few lines of code and you can try changing "green" to "blue"

22:24 TEttinger: you have the innate mutability of graphics. you have some rather intense performance needs for all but the simplest games. you, in particular, have a unique problem of visual behavior being especially inextricable from what should be pure logic (re: animations)

22:25 the one thing that seems like it could be an escape rope from that is functional reactive programming, but there haven't been any successful commercial games to use it IIRC

22:25 mungojelly: in general in the lisp world there's this statement in the abstract "we can make really simple DSLs" but then what's actually done is an integrated process of making and then applying a DSL, which involves simplicity but is itself complicated, as opposed to ever actually providing anyone ELSE any simple DSLs

22:26 TEttinger: clojure doesn't really emphasize DSLs as much as sensible APIs for regular code

22:26 not having reader macros means you can't make clojure look like something else very easily, and the consensus is that it's not a great idea usually anyway

22:27 mungojelly: well that's superficial, i mean you can create a set of primitives related to a problem, you can create a vocabulary for a situation

22:28 the only problem is that it gets as "simple" as "simple" a wrapper around a C graphics library but never as "simple" as actual ordinary every day red blue apple sunshine happy sad SIMPLE simple

22:28 racket goes a little way towards meeting reality and normal people, if somewhat condescendingly, you can say to it (jack-o-lantern 100) and that makes a little picture of a jack o'lantern

22:29 and squeak tried to go a little further, but also it's built all out of mutable objects so it predictably inevitably falls all over itself in the process, sigh

22:29 TEttinger: ...yeah, because we live in the real world and everything has to go down to OpenGL eventually. unless you want software rendering, which... believe me, I have written a lot of software rendered code, it is extremely hard to make it fast

22:31 it's unfortunate that currently the big C OpenGL API and wrappers around it are the only choices, but Vulkan is on the horizon and would enable quite a lot of fun stuff

22:31 mungojelly: of course i want a wrapper around opengl, and then i want another wrapper around that that makes it really actually easy within some basic assumptions, and then i want a wrapper around THAT that makes it easy to make cartoons, and then i want a wrapper around that that makes particular fun cartoons i get to play with

22:31 TEttinger: that sounds closer to play-clj with each sentence :)

22:32 play-clj is a wrapper around libgdx, which wraps lwjgl on desktop and different stuff on android and iOS, and each of those wraps something OpenGL or OpenGL ES like.

22:32 jeaye: It takes hundreds of lines of code to get a modern GL context setup enough to render a triangle, typically. Going higher level is a good idea, if you can spare the performance.

22:33 TEttinger: play-clj is about as far as you can get from writing OpenGL gets in clojure-land

22:33 jeaye: For cartoons, you almost certainly can.

22:34 TEttinger: when I say play-clj wraps libgdx, I mean the API is extremely clojure-like and not at all java-like. and libgdx adds a ton of java-level abstractions to the C-level OpenGL API.

22:34 seako did a good job there :)

22:34 but I think that's an away nick

22:40 seako: TEttinger: what did I do?

22:41 TEttinger: heh, sorry thought you were sekao

22:41 mungojelly: i do understand what y'all mean by play-clj being a soft gentle wrapper, i do, i'm with you, because i know what's under it, but also if you'd please try to imagine being a normal human being-- the least abstract thing in this toolkit seems to be a polygon

22:41 TEttinger: ah. yeah play-clj is much better at handling sprites

22:41 which I mean, most games are going to want graphics

22:48 dnolen: mungojelly: that's a very narrow definition of "normal" human being. Clojure programmers are also "normal" human beings. But I'll go out on a limb and say they are as a population generally less interested in system features with significant pedagogical benefits because they are building systems where the tradeoff assessment doesn't tip that way.

22:49 mungojelly: the only person I know doing serious work in this area is Robert Krahn, somewhat unsurprising since he works with Dan Ingalls. http://cloxp.github.io/cloxp-intro.html, he's been working on a Clojure version of Dan's Lively Kernel.

22:49 mungojelly: dnolen: it seems to me that generally the "tradeoff assessment" people are making is they should make everything fairly obscure and difficult to use to guarantee themselves power over it, but um that's fucked up!?

22:50 dnolen: mungojelly: that's just a lot of rhetoric, sorry not interested

22:52 mungojelly: making something so other people than yourself can use it isn't really so much paedogogy as just not pulling the ladder up after yourself. i don't really want a simple interface that's for me to learn a little before graduating to a complex one, i just want simple interfaces, forever.

22:59 rhg135: ~simple

22:59 clojurebot: Cool story bro.

Logging service provided by n01se.net