#clojure log - Mar 31 2015

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

0:00 mavbozo: xphillyx: what do you mean 'generically'?

0:01 xphillyx: Were it a vector i could say [[x y z]] but if it's a list, I can't do that right?

0:01 mavbozo: ,(let [[a b c] '(1 2 3)] [a b c])

0:01 clojurebot: [1 2 3]

0:02 amalloy: sequential destructuring works on anything sequential

0:03 xphillyx: Hmmm.. maybe I'm misunderstanding if-let then. If I pass a 2 element sequence to an if-let expecting 3, it should jump into the else, correct?

0:03 amalloy: no

0:03 cfleming: dnolen: Ok, I'll see what I can do - I'm unlikely to be implementing custom REPLs before Clojure/West unfortunately.

0:03 amalloy: xphillyx: (if-let [x y] ...) is just (if y (let [x y] ...) ...)

0:04 it doesn't somehow test whether the destructuring is "going to work"

0:04 ie, it is not pattern matching

0:04 xphillyx: Oh! That explains it. Thank you.

0:34 cfleming: rhg135: You were right about loading clj into cljs REPLs being a bug - macros can't be loaded via load-file

0:35 rhg135: Will be fixed in the next drop

0:35 rhg135: well, cfleming, I guess I was wrong about being wrong lol

0:35 my subconcious is a better programmer than me it seems

0:36 cfleming: Hehe

0:37 There's also another annoying bug - send top form to REPL doesn't work in cljs over clojure.main

0:37 Also fixed for the next release

0:37 rhg135: haven't noticed that

0:38 but i haven't tried either

0:38 cfleming: If you try, you will notice it :)

0:39 rhg135: i've been using figwheel for loading code; I only use the repl to muck with the state

0:43 cfleming: Yeah, that seems pretty common - I don't think many people use a straight CLJS REPL like you would in Clojure

0:45 rhg135: well it didn't exist tillo a few months ago

0:45 ppl found alternatives i guess

0:46 although for nodejs it would be useful

1:08 Lutin`: @seen raynes

1:09 Raynes: @saw raynes

1:10 Lutin`: Raynes: you need to renew 4clojure.com!

1:10 Raynes: I do not. It isn't my website.

1:10 Lutin`: Oh I thought it was.

1:10 woops

1:10 ignore me

1:10 Raynes: amalloy_: ^

1:10 justin_smith: Lutin`: it's been renewed

1:11 Raynes: Oh.

1:11 elvis4526: How do you require clojure macro from clojurescript ?

1:11 (#cljs is empty at the moment)

1:12 Lutin`: justin_smith: ah I see

1:12 comcast dns was just behind

1:12 justin_smith: what else is new, heh

1:13 Raynes: Lutin`: Alan and I share a VPS where he runs 4clojure.com (a domain which another fellow, David Byrne, owns).

1:13 So it was a reasonable assumption to make.

1:13 justin_smith: Raynes: I wouldn't trust that David Byrne guy. He's a psycho killer and he burns down houses.

1:13 Lutin`: haha

1:14 Raynes: I've totally never heard that joke every time I say that dude's name

1:14 justin_smith: figures

1:14 Raynes: :P

1:15 Lutin`: Ah nice it has an expiration date of 2020 now

1:16 amalloy: Lutin`: 4clojure was renewed like 12 hours ago

1:16 Lutin`: yeah I see that

1:17 I just saw mihailp's message in #4clojure and no one had responded

1:17 Raynes: http://www.developers.meethue.com/tools-and-sdks holy shit

1:17 Lutin`: didn't want anything bad to happen

1:17 Raynes: I didn't know they added clhue to this page

1:17 Those assholes never gave me any swag or anything!

1:17 Wunderlist gave me swag!

1:17 I've been cheated!

1:17 Er

1:18 Wunderground

1:18 The weather site

1:18 Lutin`: Raynes: I'll bug my friend who works at Phillips lol

1:18 Raynes: Not the todo list.

1:18 Tell him I love his bulbs.

1:18 Lutin`: He only does QA, but maybe he has some connections

1:18 Raynes: He should send me a light strip :3

1:19 Lutin`: Apparently every bulb in his office is a hue

1:19 amalloy: Raynes: "i love your bulbs, baby". not weird at all

1:21 Lutin`: I've been wanting to get one to mess with some audio visualizations

1:26 Raynes: he noticed that since they aren't using HTTPS he could just grab someone's username in flight

1:26 and they use the same username throughout the office haha

1:33 arrdem: hehe

1:33 this is how real devs do security...


1:36 Lutin`: so I know this is a touchy subject but just a survey

1:37 who uses emacs and who uses vim?

1:37 * arrdem grabs beer, popcorn

1:37 justin_smith: Lutin`: we have civil discussions about editors here

1:37 believe it or not


1:37 justin_smith: I use evil mode in emacs because my fingers like it better

1:38 Lutin`: I've been using vim for years but elisp is enough to convince me to switch

1:38 justin_smith: I don't use cider because it changes and I'm too stupid to keep it working

1:38 arrdem: I used to use vim before fireplace.vim came out, switched to emacs for CIDER, don't regret it at all

1:39 Lutin`: I've noticed there are several starter packs for emacs. Any ones you can recommend?

1:40 justin_smith: starter packs are a bad idea, because you inevitably end up customizing things, and they just make it more complicated to do that. But technomancy's better-defaults is a great alternative to that.

1:40 arrdem: +1 starter packs are a bad idea

1:40 justin_smith: https://github.com/technomancy/better-defaults <- use this if you try emacs

1:40 Lutin`: Oh it's not like I would stick with the pack

1:41 just something to kind of get exposed to the different plugins

1:41 but I'll definitely check that out

1:41 justin_smith: Lutin`: the problem is you either a) loose everything nice about the pack or b) deal with a huge pointless pain in the ass trying to customize

1:41 Lutin`: and we don't have plugins, we have libraries

1:41 just use better-defaults

1:41 and then install libs and try them

1:41 Lutin`: ah alright, I was unsure about the terminology used

1:42 justin_smith: Lutin`: in emacs, ~95% of the editor is written in elisp

1:42 so elisp isn't just an extension language, it is the language that implements the editor

1:42 Lutin`: yep, I get that much

1:43 justin_smith: so yeah, it's not plugins, it's enhancements / replacements for the default implementation

1:43 Lutin`: so calling them libraries does make more sense

1:43 justin_smith: yup

1:43 or even "forks"

1:43 the emacs you install by default is just RMS' .emacs file writ large :)

1:44 anyway, you won't regret better-defaults

1:44 unless you hate emacs, which is fine and fair, it's not for everyone

1:44 Lutin`: I love the architecture

1:45 But it's hard to stop thinking in motions and text objects

1:45 amalloy: Lutin`: i'm an emacser, but from what i understand text objects are pretty cool and you can use evil-mode or something to get stuff that maybe feels a bit like that?

1:46 Lutin`: last time I tried Emacs was with Evil mode was a few years ago

1:46 amalloy: ie you shouldn't have to stop thinking in terms of stuff that is cool

1:46 but Raynes will know better than i do

1:46 Raynes: evil-mode is basically vim.

1:46 Just go get it

1:46 You likely won't notice you're in Emacs.

1:47 It supports everything in vim that matters.

1:47 amalloy: ^ most convincing liar in #clojure

1:47 justin_smith: haha

1:47 Raynes: And I said it so it's true.

1:49 Lutin`: hmm I need to rebind Ctrl-Z

1:49 amalloy: oh? why's that?

1:49 Lutin`: hard to `fg` from the gui client

1:50 unless there's a keybind I don't know about

1:50 justin_smith: Lutin`: (global-set-key (kbd "C-z") #'undo)

1:50 is what I do

1:50 Lutin`: minimize and then maximize again does the "fg"

1:50 Lutin`: with evil mode, C-z would switch from emacs mode to vim emulation mode

1:50 Lutin`: Ah okay that works

1:51 and I can't minimize in i3 lol

1:51 justin_smith: Lutin`: oh man I use i3 too and I forget how I did it but I have done it...

1:51 maybe float then pack again?

1:51 * Lutin` shrugs

1:52 Lutin`: evil mode just installed so will we ever know!?!?

1:52 justin_smith: in terms of waking emacs up after C-z that is

1:52 amalloy: yeah i guess i bound C-z to do-nothing in gui mode too

1:52 justin_smith: I guess not :)

1:52 Lutin`: oh awesome better-defaults enables flex matching

1:52 justin_smith: Lutin`: i3 is the only wm where I don't hate how it handles multiple monitors, and what to do when they are added/removed

1:53 including non-linux stuff

1:53 amalloy: (when (window-system) (global-unset-key "\C-z") (global-set-key (kbd "C-x C-c") (lambda () (interactive) (message "Why would you ever leave?"))))

1:53 best part of my .emacs

1:53 justin_smith: haha, I like that

1:54 Lutin`: justin_smith: A friend has been pushing me to try out awesomewm

1:54 amalloy: i can still quit with alt-f4, but in practice i accidentally quit more often than i intentionally quit

1:54 Lutin`: But I'm not sure if I like permonitor workspaces

1:56 justin_smith: Lutin`: with 3 monitors, having a keybinding to jump to each workspace, and being able to move each workspace to an arbitrary monitor is a huge win for me

1:59 arrdem: justin_smith: you should check out xmonad

1:59 justin_smith: arrdem: I did, after the 10th customization to make it more like i3, I switched back to i3

2:00 arrdem: laem

2:00 justin_smith: it didn't do anything I wanted that i3 doesn't do

2:02 Lutin`: I'm sure xmonad is awesome if you spend a lot of time customizing, or use someone elses

2:02 But I couldn't justify it when i3 had plenty sane defaults

2:02 arrdem: I've found the defaults to be sufficiently sane

2:03 Lutin`: also muscle memory with a wm is hard to break haha

2:03 arrdem: ^ yeha

2:04 Lutin`: I'm really liking awesome though

2:05 arrdem: I switched off of awesome because I had real issues with it freezing up

2:06 rhg135: it's written mostly in lua

2:06 iirc

2:06 arrdem: yep

2:06 Lutin`: yep

2:07 I love Haskell but the paradigm shift between it and shell scripting was more cognitive burden than I had time to deal with

2:07 rhg135: hope their test suite is comprehensive

2:08 Lutin`: uh oh..

2:08 oh nevermind wrong folder

2:09 Yeah they could use better test coverage

2:10 maybe I'll check xmonad out again when I have the time

2:11 arrdem: One of these days I'll mess with my xmonadrc to make it auto-pace the emacs and other instances I spawn on xinit.. but that's all more I'd really want

2:25 Lutin`: ugh I need to switch out conky for something else

2:25 I keep getting json parse errors from i3bar

2:25 and debugging them is nigh impossible

2:35 ane: i3 is indeed really nice

2:50 bbloom: joe124: ... huh?

3:01 Lutin`: Raynes: still around?

3:02 Have you changed the structure of your .emacs.d recently?

3:29 ggherdov: Hello. Can I call a var "atom" without clashing with... well, "atom" is already a thing in clojure.

3:29 can i ?

3:30 justin_smith: ggherdov: well you can specifically use clojure.core/atom by its full name

3:30 but it will likely still read weird to someone looking at your code

3:30 ggherdov: justin_smith: ok

3:31 Lutin`: and you can use (ns yournamespace (:refer-clojure :exclude [atom]))

3:31 but the question is more, should you?

3:31 ggherdov: Lutin`: yeah

3:32 Lutin`: I'm a clojure noob, but it seems like a bad idea

3:43 justin_smith: you use emacs, yeah?

3:43 Do you just use package.el for package management?

3:43 I see some people like el-get and use-package

3:43 justin_smith: yeah

3:43 I use package

3:44 Lutin`: use-package looks nice

4:01 oh man use-package is nice

4:02 justin_smith: oh look, a nice clean way to do the total hack I have set up :)

4:02 (it checks for availability, loads another el file with all my related stuff if it is there)

4:03 so I have one file with all my evil related things, and it only gets loaded if evil gets loaded

4:03 etc.

4:03 Lutin`: yeah

4:03 with this you could just do (use-package evil :ensure t :config (require 'init-evil))

4:03 justin_smith: oh nice, it even has a nice clean syntax for the conditional key bindings to add if that package is there

4:03 right

4:04 Lutin`: Yep :)

4:04 really clean

4:04 I like

4:05 and you can add your own keywords :D

4:07 elvis4526: Why this: http://pastie.org/10064247

4:07 is finishing with an NullPointer

4:08 (i know define-func is useless, i'm just trying to understand macros)

4:08 Lutin`: well for one there's a typo

4:08 elvis4526: yep its not present on my version

4:08 justin_smith: elvis4526: nam != name

4:08 elvis4526: http://pastie.org/10064250

4:08 updated

4:09 sorry

4:09 justin_smith: also, ~body should be ~@body, or else the body will be wrapped in extra parens

4:09 and the extra parens will make things like npes happen

4:09 elvis4526: oh thats why

4:09 justin_smith: ,`(~(range 10))

4:09 clojurebot: ((0 1 2 3 4 ...))

4:09 justin_smith: ,`(~@(range 10))

4:09 clojurebot: (0 1 2 3 4 ...)

4:09 justin_smith: see the diff

4:10 elvis4526: why there extra parenthese ?

4:10 are*

4:10 justin_smith: because it is a collection

4:10 so they really aren't "extra"

4:10 that's what & does - it takes all the remaining args, and puts them in a list

4:10 or list-like thing

4:10 elvis4526: okay this has nothing to do with the macro itself

4:10 okay okay

4:10 justin_smith: so you need ~@ to take them back out again

4:11 Lutin`: justin_smith: so what makes that cause npes?

4:11 ,((0))

4:11 clojurebot: #error{:cause "java.lang.Long cannot be cast to clojure.lang.IFn", :via [{:type java.lang.ClassCastException, :message "java.lang.Long cannot be cast to clojure.lang.IFn", :at [sandbox$eval73 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval73 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke...

4:12 justin_smith: Lutin`: it turns (fn [x] (print x)) into (fn [x] ((print x)))

4:12 print returns nil

4:12 Lutin`: ah alright yeah

4:12 justin_smith: many other things do too

4:12 Lutin`: that's what I was thinking

4:26 otfrom: morning

4:26 I know about iterator-seq, but is there a way of turning a seq into a java iterator? I'm sure I'm missing something simple and googling is only giving me iterator-seq.

4:30 amalloy: otfrom: clojure collectoins are all java.lang.Iterable

4:30 you just call .iterator on them

4:31 TEttinger: ,(.iterator (map + [1 2] [10 20]))

4:31 clojurebot: #object[clojure.lang.SeqIterator "clojure.lang.SeqIterator@77d90d5b"]

4:31 TEttinger: (inc amalloy)

4:31 lazybot: ⇒ 245

4:31 TEttinger: (identity justin_smith)

4:31 lazybot: justin_smith has karma 229.

4:31 TEttinger: it's a battle for the ages

4:43 hyPiRion: huh, the new notation is interesting

4:44 ,(.root (vec (range 1000)))

4:44 clojurebot: #object[clojure.lang.PersistentVector$Node "clojure.lang.PersistentVector$Node@19289b86"]

4:44 hyPiRion: Oh, it wasn't _that_ interesting

4:49 TEttinger: hyPiRion:

4:49 ,clojure-version

4:49 clojurebot: #object[clojure.core$clojure_version "clojure.core$clojure_version@3cb250e7"]

4:49 TEttinger: so useful

4:50 hyPiRion: wait what

4:50 ,(prn clojure-version)

4:50 clojurebot: #object[clojure.core$clojure_version "clojure.core$clojure_version@3cb250e7"]\n

4:51 hyPiRion: oh

4:51 TEttinger: (str ,clojure-version)

4:51 hyPiRion: ,*clojure-version*

4:51 clojurebot: {:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true}

4:51 TEttinger: ha

4:52 I knew something was weird there...

4:52 hyPiRion: That makes it really hard to distinguish functions and objects though

4:53 Or maybe not, when I think about it

4:53 TEttinger: ,#(+ %)

4:53 clojurebot: #object[sandbox$eval118$fn__119 "sandbox$eval118$fn__119@1eafcafa"]

4:53 otfrom: amalloy and TEttinger thx!

4:53 thought I was missing something simple(TM)

4:53 TEttinger: I didn't do anything, amalloy's the hero!

4:57 otfrom: TEttinger you gave me the example code, but I agree that amalloy is a hero :-D

4:57 TEttinger: hehee

5:00 otfrom: (inc amalloy)

5:00 lazybot: ⇒ 246

5:00 otfrom: (inc TEttinger)

5:00 lazybot: ⇒ 46

5:15 elvis4526: Is it possible to "apply" each things in a vector as arguments to a function?

5:18 mavbozo: ,(map + [0 1 2 3 4])

5:18 clojurebot: (0 1 2 3 4)

5:18 mavbozo: elvis4526: ^like that ?

5:18 elvis4526: but this still count as one argument if you pass this to a function

5:18 (i believe)

5:19 mavbozo: ,(map inc [0 1 2 3 4])

5:19 clojurebot: (1 2 3 4 5)

5:19 Niac: user=> (doto (Graphics.) (.create 10 10 10 10)) CompilerException java.lang.IllegalArgumentException: No matching ctor found for class java.awt.Graphics, compiling:(NO_SOURCE_PATH:45:7)

5:19 elvis4526: map will always return a sequence

5:20 mavbozo: ,(apply + [0 1 2 3])

5:20 clojurebot: 6

5:20 elvis4526: initially i tought apply was what im looking for

5:21 xulfer: you want to convert a vector into individual function arguments?

5:21 elvis4526: yeah

5:22 Niac: so how can i use java.awt.Graphics package?

5:26 martinklepsch: when I deploy an uberjar, what's the best way to provide some additional resources (static files) when I start the service? is this only possible by wrapping these resources in jars?

5:27 the files I want to provide to my clojure process are periodically updated by an external process

5:34 mavbozo: martinklepsch: if you use ring, you can use ring.middleware.file/wrap-file

5:34 martinklepsch: i'm assuming you're running a webapp

5:34 martinklepsch: mavbozo: I'm not intending to serve the file

5:35 An alternative to providing the file via resources is to just use (io/file "/usr/share/my.file") but that feels a bit as if it's unclean

5:35 maybe someone has an opinion to offer on that

5:41 mpenet: it's a config file of some sort?

5:42 martinklepsch: mpenet: not really. it's a ip->geolocation database

5:43 oddcully: and who updates it? ops? os-update?

5:44 martinklepsch: oddcully: ops via a separate updater process

5:44 elvis4526: So I wrote a macro to solve my problem, again lol. http://pastie.org/10064396

5:46 mavbozo: java -cp /var/geoip:/home/web-app/web-app.jar com.web.app

5:46 oddcully: then i'd put it in /var/db/<yourappname> or something and find a way to trigger reloading

5:46 mpenet: preferably not hardcoding the path in your app, ex via an env var and a default value

5:47 martinklepsch: mavbozo: so can I just supply random dirs as classpath and their contents will be reachable via io/resource ?

5:47 mavbozo: martinklepsch: yup!

5:47 oddcully: yes

5:48 martinklepsch: ok, great. that wasn't entirely clear to me tbh

5:50 oddcully: if your ops isn't aware either, it might be easier to have the location in a config and read it via file, as mpenet suggested

5:50 less java magic

5:53 martinklepsch: makes sense. I think the java-magic is the easier route for now

5:56 mavbozo: elvis4526: what's the usage example of your macro?

5:57 mpenet: I gave up on messing with classpath/resources, too much indirection

5:58 ARM9: how do I :use several libraries? something like (ns foo.bar (:use [seesaw.core seesaw.font]))

5:58 mpenet: ~use

5:58 clojurebot: use is don't use use.

5:58 ARM9: ~require

5:58 clojurebot: It's greek to me.

6:09 danlentz: ARM9: a ns form can have multiple use/require clauses

6:09 ARM9: what would be the equivalent :require to :use

6:11 martinklepsch: ARM9: (:require [lib.ns :refer :all])

6:11 ARM9: but don't do it!

6:11 ARM9: I tried that but it did not work in this case

6:11 martinklepsch: ARM9: do something like (:require [lib.ns :as n])

6:11 danlentz: Something like (:require [clj-uuid [constants :refer :all] [util :refer :all]])

6:13 But it is usually better to do the :require ... :as like martinklepsch suggests

6:18 ARM9: I see

6:18 thanks

6:37 kungi: What does "minting cost" mean in the following context? UUIDs are one of the URNs with the lowest minting cost? Minting is as I recall the process of creating coins.

6:39 danlentz: Minting is just creating

6:39 kungi: danlentz: Thank you

6:39 danlentz: Where did you read it?

6:40 kungi: rfc4122

6:40 Page 3

6:41 danlentz: Neat. I've spent some time reading RFC4122 myself :)

6:42 You've seen clj-uuid?

6:43 kungi: danlentz: yes. At the moment I just use java.util.UUID to create the ones I need

6:44 danlentz: There are various versions of UUID, each with specific use-cases and performance characteristics

6:45 So, java.util.UUID/randomUUID uses a cryptographic random number generator, which is unguessable, but very slow

6:45 kungi: danlentz: But sadly the one I need in my use case.

6:46 danlentz: I have to create UUIDs that are unguessable

7:01 tahmid: quit

7:01 oops! sorry

7:24 danlentz: kungi: do you have an interesting use-case you are using UUID's for? I understand if its proprietary and you can't discuss -- I am just collecting examples because sometimes people ask

7:24 kungi: danlentz: query

7:45 arossouw: just wondering, when you create a standalone jar with leiningen and deploy it to a webserver. Is there a way to do it without interrupting the website?

7:47 raspasov: arossouw: one approach would be using a load balancer, either manually setup or via AWS/Rackspace/et al...

7:47 arossouw: ok

7:47 raspasov: the process would be something like: 1. setup a load balancer with at least 2 JVM nodes serving requests

7:47 when you want to deploy...

7:47 oddcully: arossouw: search the web for blue-green-deployment

7:48 raspasov: 2. remove one server from circulation

7:48 3. update the uberjar on that server

7:48 4. put that server back in circulation

7:48 5. repeat on all servers

7:48 arossouw: thanks, i'll experiment with both approaches

7:49 raspasov: I think there's better approaches than that, prob blue-green is better

7:49 that gets into "immutable infrastructure" and these kinds of topics

7:49 arossouw: load balancer is a good idea for high availability

7:49 oddcully: 3.1 run your smoketests against that server

7:50 arossouw: ok

7:50 raspasov: oddcully: yea :)

7:53 arossouw: hehe, we dont have app servers, our servers are hosted on site

7:53 Glenjamin: you can still have a load balancer and more than one process on a single node

7:53 raspasov: arossouw: so physical servers, not AWS/Rackspace etc?

7:54 Glenjamin: good point

7:54 arossouw: raspasov: correct

7:54 i see, good idea

7:55 raspasov: arossouw: yea so in this case I think things like immutable infrastructure become more challenging, unless you have the whole API/virtualization layer ala-Amazon/Rackspace

7:55 arossouw: ok, might be time to persaude management to go with Amazon/Rackspace

7:56 bandwith is very pricy in south africa and we'd need plenty of bandwithd for database operations

7:57 raspasov: arossouw: well don't jump and that wagon just because I threw in some buzzwords :) carefully evaluate benefits/trade offs

7:57 arossouw: yes, just thinking of it now, haven't made decision yet

7:57 raspasov: arossouw: you mean if you go with Amazon/Rackspace?

7:57 about bandwidth?

7:58 is your database remote, i.e. not in the same data center?

7:58 or you're thinking of keeping your DB on premise and going with AWS for app servers? I wouldn't do that

7:58 arossouw: the applications are desktop apps, we also have web applications ,but the business core is from desktop apps, there's a major defect with performance on database queries from client to server. with the desktop environment

7:59 raspasov: no i thought of moving the database servers to a hosted environment on a lan at a server-farm/designated place

8:00 raspasov: virtualizing databases not a good idea i think

8:00 raspasov: yea one thing I would say is that AWS/Rackspace is like an all or nothing proposition, either all your servers, both DB and JVM app servers are there or not

8:00 arossouw: ok

8:00 raspasov: which do you prefer aws or rackspace?

8:01 raspasov: arossouw: hardware has gotten much better in the last few years; but you definitely dont want to be paying the latency cost of talking to a DB cross-data center

8:01 arossouw: yes, definately

8:01 borkdude: in clojure, is there a "failing" version of map lookup?

8:01 that throws an exception when they was not found

8:01 raspasov: arossouw: I have been using Rackspace for the longest time, but recently started using Amazon... they are comparable, I think Amazon has the advantage of bigger ecosystem around it because of more developers using it

8:02 arossouw: raspasov: they create a database connection for every query instead of grouping querries, looks like syn flood on database , hehe

8:02 raspasov: arossouw: wow, yea that's not good :) what Database is it?

8:02 arossouw: mysql

8:02 raspasov: arossouw: haha, is it EVERY. SINGLE. query?

8:03 arossouw: indeed. instead of select columns from table where id in (12,3), its select columns from table where id = 12, select columns from table where id =3, simple example but get the point

8:04 cemerick: dnolen: you can stop muttering about me under your breath ;-P

8:04 arossouw: even created code with c++ and qt to prove with graphs that, that is stupid

8:04 dnolen: cemerick: lol

8:04 arossouw: https://github.com/arossouw/study/tree/master/c%2B%2B/qt5-mysql-basic/testcases

8:04 raspasov: arossouw: oh ok, but at least does it REUSE a socket/connection pool or just straight up makes a new connection? :)

8:04 dnolen: cemerick: need to fix a bug cfleming found with load-file and will then likely cut a release

8:05 arossouw: doesn't reuse, creates a socket for each connection, waits for os to time out, also known as timeout_wait tcp

8:05 usually timeout_wait is 60 from what i've read

8:05 60/secs

8:05 raspasov: arossouw: yea that's nasty... a lot of load on the DB I'm sure

8:05 arossouw: aha, 24 cpu xeon , massive server. load on 400%

8:05 lots of context switching

8:06 raspasov: arossouw: look into http://jolbox.com/

8:06 cemerick: dnolen: works. Speaking of, it's possible that piggieback's load-file operation is slightly borked (it just uses load-stream), but I haven't seen any breakages so far in everyday use.

8:06 arossouw: had to optimize linux kernel to handle more connections, for their broken performance code

8:07 raspasov: i think qtsql is good, no?

8:07 dnolen: cemerick: yeah using load-stream is not the right way to do it, breaks source mapping

8:07 cemerick: well, there we go

8:07 raspasov: arossouw: never used it, have used BoneCP though

8:07 dnolen: cemerick: but it's also not a show stopper, people and load-file doesn't work atm the moment

8:08 arossouw: raspasov: will it work with visual studio 8?

8:08 hehe

8:08 * arossouw chuckles

8:08 raspasov: arossouw: lol what does that mean

8:08 arossouw: visual studio 2008

8:08 the desktop app is coded with ms visual c++

8:08 cemerick: dnolen: the only reason I'm not just using the load-file special fn is it assumes the file is on disk

8:08 raspasov: arossouw: hahah yea I know what Visual Studio is, but it's a library, how can a library WORK or NOT WORK with an IDE lol?

8:08 dnolen: cemerick: er "people" will be happy that so much stuff now works.

8:09 cemerick: yeah you need that for source mapping to work

8:09 oddcully: you are in clojure land. so this is either emacs (or vim *ducksandruns*)

8:09 arossouw: oh, ok . was stupid question

8:09 raspasov: arossouw: it's ok :)

8:09 dnolen: cemerick: in general REPLs have to be disk oriented for this reason - debuggability and how source mapping works across runtimes

8:09 cemerick: dnolen: I can provide the source file's path, if that's what's necessary

8:10 dnolen: cemerick: browser & Node.js specifically which are the two most popular options

8:10 arossouw: would it be difficult to create an offline leiningen installer?. bandwith in south africa very expensive

8:10 dnolen: cemerick: there's nothing you can do fix this without a ton of work

8:10 cemerick: use load-file when I fix it

8:11 arossouw: raspasov: i thought jdbc was stricly a java thing

8:11 see boneCP can connect to jdbc

8:11 raspasov: arossouw: yes it is, are using a Clojure CLR?

8:11 are you*

8:11 cemerick: dnolen: will do

8:12 dnolen: cemerick: in the browser you just have to use a script tag, in Node.js it has to be on disk - load-stream is just not the right solution for ClojureScript

8:12 arossouw: i download leiningen standalone and clojure 1.6. I'll tinker abit to see if i can just copy the .lein folder and make it work that way on windows

8:14 is the job market for clojure programmers improving?

8:16 raspasov: ok, boneCP will work for my clojure web apps, but they are using visual c++ for their desktop bloatware app

8:17 raspasov: arossouw: I've setup BoneCP before, you can take a look at this file (no guarantees provided :) ) https://github.com/raspasov/neversleep/blob/master/src/neversleep_db/mysql_lib.clj

8:17 arossouw: raspasov: whats wrong with the standard jdbc?

8:18 dnolen: borkdude: there is not

8:18 arossouw: ok, still have lots to learn on clojure, whats that doto do?

8:18 borkdude: dnolen ok

8:18 oddcully: ,(doc doto)

8:19 clojurebot: "([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"

8:19 raspasov: arossouw: http://clojure.org/java_interop

8:19 arossouw: aha

8:19 would it be worth time to dissect java calendar widget and rewrite it to clojurescript?

8:20 raspasov: "doto thisObject someStuff1, someStuff2, etc"

8:20 arossouw: s/java/javascript/

8:20 ok

8:21 so why not create a hash-map instead of doto?

8:22 Glenjamin: sometimes you have a java object

8:22 arossouw: o, i see its to transform java classes

8:22 Glenjamin: ,(doto (HashMap.) (.add "a" 1) (.add "b" 2))

8:23 clojurebot: #error{:cause "Unable to resolve classname: HashMap", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.IllegalArgumentException: Unable to resolve classname: HashMap, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.IllegalArgumentException, :message "Unable to resolve classname: HashMap", :at [clojure.lang.Comp...

8:23 Glenjamin: meh, my java is rubbish

8:24 arossouw: makes sense now, neat thing

8:24 oddcully: Glenjamin: clojurebot says put! ;P

8:25 arossouw: is it practical to build desktop apps with clojure?

8:25 Glenjamin: ,(doto (java.util.HashMap.) (.add "a" 1) (.add "b" 2))

8:25 clojurebot: #error{:cause "No matching method found: add for class java.util.HashMap", :via [{:type java.lang.IllegalArgumentException, :message "No matching method found: add for class java.util.HashMap", :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]}], :trace [[clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53] [clojure.lang.Reflector invokeInstanceMethod "Reflector.jav...

8:25 arossouw: like gui app (qt, wxwidgets, gtk)

8:25 tahmid_: (doc doto)

8:25 clojurebot: "([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"

8:25 Glenjamin: oh, i see .put

8:25 anyway, you get the idea

8:26 arossouw: so you have to escape strings every time?

8:26 oddcully: no

8:26 see Glenjamin code, but s/.add/.put/g

8:26 this is just because of the bot

8:26 arossouw: ok

8:26 oh, phew.

8:28 wanted, a calendar widget in clojure script :-)

8:29 alejandrozf: Hi all!

8:29 a

8:31 peterk87: arossouw: is this what you're looking for? https://github.com/reagent-project/reagent-cookbook/tree/master/recipes/bootstrap-datepicker

8:32 arossouw: peterk87: i've been googling like crazy, thanks. i'll try github next time

8:34 alejandrozf: still getting network errors installing leiningen, exist another way to download the dependencies?

8:35 peterk87: arossouw: you mentioned desktop apps, I remember seeing this https://github.com/breach/thrust - Haven't tried it though...

8:36 arossouw: peterk87: looks great, i'll experiment

8:37 and easier than c++ with qt5

8:38 waltermm: Hi, i'm a clojure(script) beginner and im having trouble to debug "cannot read call of undefined". I use lein-figwheel template and chrome console doesnt help anything ;(

8:38 Can anybody help?

8:38 dysfun: arossouw: i'm not sure how writing qt c++ helps you get a calendar widget in your browser :)

8:39 arossouw: lol, no thats another project. just learning gui development with qt

8:39 peterk87: waltermm: are you trying to call some JS code?

8:40 tahmid_: waltermm: share your project.clj

8:40 waltermm: no.. i'm using reagent

8:41 i dont think the problem is in the project.clj since it was working just a few line of code ago..

8:42 peterk87 and tahmid_: maybe its a typo or something, but im unable to find the origin ;/

8:42 dnolen: waltermm: ClojureScript supports source mapping which is enabled by default

8:42 peterk87: waltermm: are you using advanced compilation?

8:42 arossouw: peterk87: reagent looks impressive

8:43 dnolen: peterk87: doubtful if they are using piggieback

8:43 waltermm: figure out how source mapping support works in your dev browser, it will save you a lot of time

8:43 waltermm: dnolen: thank you very much.. i will do some research about source maps!

8:43 thanks for the help guys

8:44 dnolen: waltermm: in Chrome in the dev console there is a settings button (the gear), click it, find the source map option, enable it, refresh your browser, you should see a ClojureScript stack trace

8:44 waltermm: if you enable Catch Exceptions then it will drop you into the ClojureScript file at the line/column where the error occurred

8:45 waltermm: I strongly recommend spending the time to sort this out as it will save you countless hours in the future

8:46 waltermm: dnolen: nice! thanks for the advice and i will learn it

8:46 dnolen: waltermm: np

8:47 tahmid_: dnolen: when om-native is coming out ?

8:47 dnolen: tahmid_: no idea, there's various things that need looking into first

8:47 tahmid_: dnolen: are there plans for android ?

8:48 dnolen: tahmid_: only in so far as we let React Native sort it out

8:52 arossouw: is it possible to build apps for the android platform with clojure? (since android underhood is java)

8:54 oh, found this, http://clojure-android.info/, not production ready yet though

9:01 borkdude: Clojure and S3: https://github.com/weavejester/clj-aws-s3 or https://github.com/mcohen01/amazonica?

9:02 the first one seems more maintained

9:03 raspasov: borkdude: I actually used Amazonica a little bit, it's pretty neat how the API is designed to escape Java-lang nastiness

9:03 borkdude: raspasov thanks

9:03 raspasov I'll go for that one

9:03 raspasov: borkdude: the Amazon API actually helps, since all the Java classes are designed as pure data holders basically

9:04 borkdude: I think weavejester's stuff is also top notch

9:04 borkdude: raspasov yeah

9:04 raspasov: if you just need S3, I'd go with clj-aws-s3

9:04 if need entire AWS, I'd look into Amazonica

9:07 Guthur: is there any defacto stander HTTP server for clojure?

9:07 s/stader/standard

9:08 borkdude: Guthur jetty, immutant (jboss or undertow), httpkit are used a lot

9:08 raspasov: Guthur: https://github.com/ztellman/aleph based on Netty, with great performances, there's other options as well but Netty is a very solid project

9:08 performance*

9:09 borkdude: raspasov the clj-aws-s3 seems to be lagging a bit behind. it uses [com.amazonaws/aws-java-sdk "1.7.5"], amazonica uses [com.amazonaws/aws-java-sdk "1.9.13" :exclusions [joda-time]]

9:09 raspasov I'm kind of worried that if I go with clj-aws-s3 I have to migrate because this project is abandoned

9:09 raspasov: borkdude: yea I was just poking around with Amazonica 1-2 weeks ago, I believe it was up-to-date, which was nice to see

9:13 Guthur: borkdude, raspasov: cheers

9:13 arossouw: neat, https://github.com/SnootyMonkey/lein-sphinx

9:14 midje vs deftest, which one is preferred?

9:16 raspasov: arossouw: I go for simple, deftest

9:16 arossouw: ok

9:17 danlentz: Without taking anything away from the greatness of tools like Grimoire, I want to mention that Dash for Mac and iOS is pretty awesome.

9:17 https://kapeli.com/dash

9:17 arossouw: for the life of me, dont get how our software engineers get by without version control

9:18 danlentz: Clojure, java, emacs, clhs, Scala, ...

9:21 oddcully: arossouw: maybe the like to life dangerous?

9:22 arossouw: hehe, cowboy coding and monkey patching

9:22 living on the edge

9:23 mavbozo: the original extreme programming

9:24 oddcully: and since you used the plural: how do they sync their effords?

9:24 slipset: I'm working on this little rest-client a la post-man for chrome

9:24 arossouw: does anyone here rebase git repositories?

9:24 slipset: using http-kit

9:24 danlentz: Dash is paid software though I should mention, well... paid-ish.

9:25 slipset: our server sends us a cookie which is new on each request, so I need a way to store it for each request, and apply it for the subsequent request

9:25 any good patterns for doing this?

9:26 bja: oddcully, xtreme cowboys only use highly interactive environments like common lisp or GDB and thus don't need to coordinate. They just inspect what is running.

9:26 slipset: (do-cookie-stuff (http/post ".." ) doesn

9:26 t look to good.

9:27 bja: since cowboys are so expensive and prone to race conditions, you only need to hire 2-3 for each codebase, offset appropriately around the world so they don't overlap each other.

9:27 oddcully: bja: at least that would work. i'd rather fear some shared drive or insane copy actions

9:28 mavbozo: slipset: you want to find better pattern than this https://github.com/dakrone/clj-http#cookie-stores ?

9:28 slipset: mavbozo:problem is that I'm not using clj-http

9:28 bja: oddcully, you're mistaking Xtreme Cowboys(tm) for my auto industry employer ~2005

9:28 mavbozo: slipset: i thought they have same client apis

9:28 slipset: for some none-obvious reason, and http-kit doesn't seem to support cookie-store

9:34 arossouw: bja: maybe thats why it managers should at least have a bsc in computer science

9:34 so that they can appoint skilled software engineers

9:35 but, that also might be subjective, it would depend on the knowledge that the it manager has

9:39 sveri: Hi, I tried to use test-refresh within a leiningen plugin, but it fails because it cannot find the test files. When I comment this line: :eval-in-leiningen true in the project.clj file it works and runs the tests. Are there any known defects for this?

9:52 joe124: hi can someone explain why my duplicating function doesn't work http://pastebin.com/ZqsH4PtG

9:57 mavbozo: (duplicate-nums 1 2 3) returns (1 1 2 2 3 3) is what you expect right?

10:00 really_clojure: hello. I'm trying to run my compojure app. I'm attempting to have routes for various parts of the site in their own files.

10:00 joe124: mavbozo: yes

10:00 really_clojure: When the main route maker attempts to pull one of the sub routes, I get this error: No such var: clojure.core/home-management.routes.profile

10:00 justin_smith: joe124: a few things about that

10:00 really_clojure: The (ns) declaration looks good.What am I missing?

10:01 justin_smith: joe124: because clojure collections are immutable (seq args) is the same as args

10:01 joe124: also, copy-of-coll is the same as coll

10:01 joe124: so you can just write (defn duplicate-args [& coll] (interleave coll coll))

10:01 and the get the same exact result

10:02 joe124: what does seq do though?

10:02 oddcully: ,(let [col [1 2 3]] (interleave col col))

10:02 clojurebot: (1 1 2 2 3 ...)

10:02 justin_smith: joe124: it coerces the input to a seq

10:02 oddcully: justin_smith is just to quick

10:02 justin_smith: ,(seq "hello")

10:02 clojurebot: (\h \e \l \l \o)

10:02 justin_smith: oddcully: if I knew you were trying to answer I would have let you

10:03 oddcully: no worries

10:03 justin_smith: joe124: also, let bindings can see prior bindings, so you never actually need (let [...] (let [...] ...)) with nothing in between

10:04 ,(let [a 1 b (+ a a) c (* b b)] c)

10:04 clojurebot: 4

10:05 joe124: ok cool didn't know you could do multiple bindings in the same let declaration

10:05 thank you oddcully that solution is perfect

10:06 justin_smith: joe124: your version already worked

10:06 it was just awkward for the reasons I listed

10:07 oddcully: so what didn't work then?

10:07 justin_smith: oddcully: I copy/pasted his version, it worked

10:08 joe124: not for me, if my version took [1 2 3 4 5] it outputted [1 2 3 4 5][1 2 3 4 5]

10:08 or something like that

10:08 justin_smith: joe124: you must have been using a prior definition

10:08 joe124: I promise, that version worked

10:08 I put it in my repl, and got the correct output

10:09 patrkris: is it good practice to have a (satisfies? SomeProtocol x) in the precondition of functions at "the edge" of an API?

10:09 oddcully: no he called it like this: (duplicate-nums [1 2 3])

10:09 justin_smith: oddcully: that's just using it wrong

10:09 joe124: yah you're right it does work

10:09 justin_smith: oddcully: if you expect to use it like that, take the & out of the parameter declaration

10:10 ,(defn dup-nums [& coll] (interleave coll coll))

10:10 clojurebot: #'sandbox/dup-nums

10:10 justin_smith: ,(dup-nums :a :b :c)

10:10 clojurebot: (:a :a :b :b :c ...)

10:11 mavbozo: ,(apply dup-nums [:a :b :c])

10:11 clojurebot: (:a :a :b :b :c ...)

10:11 justin_smith: (inc mavbozo)

10:11 lazybot: ⇒ 4

10:11 justin_smith: good point

10:11 oddcully: ,(apply dup-nums [1 2 3])

10:11 clojurebot: (1 1 2 2 3 ...)

10:11 oddcully: darn! ;P

10:12 * justin_smith buys oddcully touch-typing lessons.

10:12 joe124: why does (fn duplicate-nums [& coll] (interleave coll coll)) fail http://www.4clojure.com/problem/32

10:13 justin_smith: joe124: because it doesn't get varargs, it just gets args

10:13 joe124: delete the &

10:13 mavbozo: justin_smith: in fairness, i think justin_smith uses his touch-screen keyboard again.

10:13 joe124: what's the difference?

10:14 mavbozo: justin_smith typing is slower than usual

10:14 joe124: i mean why woudl that change anything

10:14 sm0ke: cemerick: hello regaring piggieback issue #57, you there?

10:14 oddcully: haha

10:14 justin_smith: ,((juxt (fn [a] a) (fn [& a] a)) :a)

10:14 clojurebot: [:a (:a)]

10:14 justin_smith: joe124: ^ that's the difference

10:14 also, the first one only takes one arg

10:14 joe124: so the & collects everything into a list

10:14 justin_smith: exactly

10:15 joe124: even if it's only one thing, ok neat

10:15 justin_smith: joe124: notice how I got sneaky and taught you to use juxt too just for the hell of it

10:15 cemerick: sm0ke: for 2m, what's up?

10:15 joe124: and i understood what it did too lol amazing

10:15 sm0ke: cemerick: just wanted to ask that this would need a minor patch for fireplace right?

10:16 cemerick: just remove the :repl-env?

10:16 cemerick: sm0ke: If the piggieback stuff is encapsulated in a vim command, yeah. Not sure why it is, though?

10:17 sm0ke: cemerick: i guess fireplace takes the :repl-env as a !Piggieback param

10:17 will try it out, thanks for answering all question!! cemerick

10:18 cemerick: sm0ke: Not sure what that means. :-) In any case, it really shouldn't hide `cljs-repl`, as that's the only way you'll get REPL / compiler configuration flags set, etc.

10:19 joe_1246: sorry i dc

10:19 mavbozo: joe124: did you managed to create max function?

10:24 joe_1246: no i tried but it started getting really complicated http://pastebin.com/jeGuVySz.

10:24 i feel embarrassed to paste it but hey lol

10:25 justin_smith: joe_1246: it's not super bad. try adding a second line to the let: (let [cur-max (first coll) coll (rest coll)] ...)

10:25 that should get you closer to the answer

10:25 if not making the code work right away

10:26 err wait

10:26 that does not suffice because you are returning a function...

10:26 but I think it gets you within a step or three of fixing it

10:27 joe_1246: i kinda just want to start over on this function because its so big

10:27 justin_smith: joe_1246: to make it smaller you would need to learn some new functions

10:27 as is, it's a fairly succinct recursive loop

10:27 mavbozo: joe_1246, you can put the loop-function in let binding

10:28 [cur-max (first coll) loop-function (fn [cur-max coll] ....

10:28 justin_smith: or just replace "fn loop-function" with "loop" I think :)

10:29 joe_1246: idont like having the loop at all though, the only reason it exists is because i needed cur-max to equal the first coll

10:30 but i only wanted to do that once

10:30 not every recursion

10:32 * mavbozo didn't realize that it's a loop

10:32 justin_smith: joe_1246: you need the recursion, and the repeated binding to cur-max in order for that function to work

10:32 joe_1246: until you learn reduce, this is the right way to get a single result based on a collection

10:33 joe_1246: is that a correct functional style?

10:33 justin_smith: yes

10:34 joe_1246: ok i will learn reduce

10:34 justin_smith: joe_1246: the principle being applied here is that since our variables are not mutable, we need to call a function with different args to move forward

10:34 joe_1246: I think it's good to make the recur based version work

10:34 it will help in understanding how reduce works

10:34 oddcully: is this a builtup on that site or is reduced not allowed to solve it?

10:34 joe_1246: is it possible to make a recur based version without using an extra loop inside my function?

10:35 reduce is allowed on that problem

10:35 justin_smith: joe_1246: yes, using extra arities

10:35 joe_1246: but I don't think that would make it that much simpler

10:35 joe_1246: reduce will make it a lot simpler, but I think it's a good learning exercise to learn how to do it with loop or regular recursion first

10:36 joe_1246: i will try to do it wi th regular recursion

10:37 g2g be back later afternoon thx guys

10:37 justin_smith: joe_1246: one think that I think will help: reduce is a way to express a common kind of recursion where each step you make a sequence shorter, and update a "accumulator" or "result" var

10:58 danlentz: I've been playing with vinyasa. Convenient idea of "." as a default namespace to inject useful functions

11:18 noncom: danlentz: wow, vinyasa is cool

11:19 danlentz: There have definitely been some changes since 0.2.0 which was the last time I looked at it

11:20 noncom: i see it for the first time and it kinda contains lots of functional i have been dreaming of but had no time to implement

11:20 vinyasa not only implements it, but does that vey stylishly

11:21 Lutin`: I'm going to go insane..

11:21 danlentz: Although the setup as described on the website seems to omit the Apache commons http client dependency

11:21 Lutin`: Writing a distributed programming system in APL

11:21 clojurebot: Titim gan éirí ort.

11:21 Lutin`: someone shoot me

11:21 noncom: danlentz: hmm, i also see, the last commit was like 8 months ago?

11:22 Lutin`: what do you mean? you had a bad dream? :)

11:22 Lutin`: no this is my current job haha

11:22 noncom: 8O

11:22 danlentz: I really don't think that is a useful way to evaluate software

11:22 Lutin`: math professor at my uni is only comfortable with APL and wants to turn some of his APL programs into distributed ones

11:24 danlentz: If people are using it and it has been stable, why consider that a defect?

11:26 noncom: danlentz: you mean what? apl?

11:26 danlentz: Of course, I'm coming from common-lisp, where some of the packages are so old they actually use dust as part of the syntax

11:26 noncom: Lutin`: i will be surprised if apl can support any sane networking at all

11:27 Lutin`: It's basically a thin layer over the winsocket api

11:27 oh yeah I forgot to mention the APL distribution he uses is windows only

11:27 danlentz: noncom: no, I mean just because it hasn't been recently updated isn't necessarily a bad omen

11:28 Lutin`: noncom: he was talking about vinyasa

11:28 I believe

11:28 noncom: danlentz: ah, yeah, i agree. especially that sometimes there is just not that much to improve, if all is working good already

11:30 Lutin`: there is a project: https://github.com/shaunxcode/apl-to-clojure

11:30 but.. it never was finished...

11:30 Lutin`: hahahahahaahahaha

11:30 my sides!

11:31 ahhhh

11:31 that's exactly how I feel right now

11:32 noncom: :)

11:32 justin_smith: haha

11:33 Lutin`: the worst part is it pays pretty well

11:33 but it takes so much work just to convince myself to start working on it haha

11:33 I have to do version control by hand..

11:33 noncom: omg...

11:33 but, actually, APL is not that bad in itself..

11:33 justin_smith: wait, you aren't allowed to use a vcs? couldn't you be sneaky and use one in secret?

11:34 Lutin`: But how?

11:34 justin_smith: noncom: agreed, it has some nice higher level abstractions for arrays

11:34 oddcully: just use git on your own box and be done with it

11:34 Lutin`: The files are a proprietary binary format

11:34 oddcully: no one need to know. we won't tell

11:34 noncom: also, this is the modern flavor of it that i have most experience with: http://www.jsoftware.com/index.html

11:34 Lutin`: I literally cant even

11:34 justin_smith: Lutin`: you can put binary objects in source control (it's just not as helpful as text, of course)

11:34 oddcully: yet you can commit your stuff

11:35 would give you bisect etc

11:35 Lutin`: yeah

11:35 I mean that's basically what I'm doing, but it just means I don't really get diffs

11:35 danlentz: I looked at J but had a hard time memorizing all the mountains of syntax that had no mnemonic recognition to me

11:35 justin_smith: Lutin`: I had no idea about the proprietary format. Who thought this would be a good idea?

11:36 noncom: yeah. i think that J would be great if all of its operators be turned into pictures so you could play with them like a combinatorics game

11:36 Lutin`: The same people who charge $1,750 for a 2 year license

11:36 danlentz: (J is I think the successor to APL?)

11:36 Lutin`: J is the spiritual successor

11:36 noncom: Lutin`: yeah, sort of

11:37 Lutin`: tbh I like APL's character set :X

11:37 noncom: there is also K, but it is highly commercial and mainly used in database things

11:37 Lutin`: Easier to read at a glance than J

11:37 noncom: coz them are pictures :)

11:37 not punctuation signs like in J

11:37 Lutin`: But this damn version of APL doesn't even have lambdas

11:38 noncom: whooa

11:38 Lutin`: And I think they added multithreading last year

11:38 but it's not even what you would think

11:39 noncom: does this APLs flavour have awebsite?

11:39 Lutin`: http://www.apl2000.com/index.php

11:39 "(Note: The Google Chrome browser is not supported.)"

11:39 oddcully: cool name ;P

11:39 Lutin`: That's actually on their site

11:39 danlentz: Apl2000 -- sounds... Um... Modern.

11:40 Lutin`: Yeah the company and APL2000 and the software is APL+Win

11:40 danlentz: Way better than APL1973 I guess

11:40 Lutin`: and their form of multithreading is called APLNextSupervisor

11:41 but what it really does is start up several versions of apl and then acts as a message bus

11:41 several 'workspaces'

11:42 noncom: there are still weird creatures left on the face of the earth since the age of giants.. and they walk under the sun, ever looking for a place to rest...

11:42 Lutin`: I wish they would just die already

11:42 the software, not the people!

11:42 noncom: :D

11:42 justin_smith: Lutin`: shared-nothing concurrency is a solid model

11:42 clojurebot: 'Sea, mhuise.

11:43 danlentz: Send them all to New Jersey

11:43 justin_smith: ~Lutin`: shared-nothing concurrency

11:43 clojurebot: Lutin`: shared-nothing concurrency is a solid model

11:43 justin_smith: haha

11:43 clojurebot: weirdo

11:43 clojurebot: Pardon?

11:43 Lutin`: justin_smith: well yeah that's what I'm doing for this distributed system

11:44 It's just that it's not like a library

11:44 danlentz: Do you have "green threads"?

11:44 Lutin`: It's a separate program with a separate install and license

11:44 danlentz: hahahahahaha

11:44 what is a thread

11:44 justin_smith: yeah, just saying, there's not too many steps from that to something much like core.async for example

11:44 Lutin`: justin_smith: it's not the underlying model I have a problem with, it's the execution

11:44 danlentz: Yes, like some form of cooperative multitasking

11:45 justin_smith: Lutin`: oh, if they implemented it badly haha yeah

11:45 "forget your mind and you'll be free"

11:45 Lutin`: I mean I'm basically writing what their thing probably does

11:45 but he doesn't want to upgrade to the most recent version

11:45 so we're on the one from 2009

11:46 anyways I shouldn't spend too much time complaining

11:46 I have a meeting in about an hour

11:47 justin_smith: Lutin`: clearly this is time to turn off brain and excrete APL code

11:47 noncom: Lutin`: well, I hope you will gain some secret abilities and some higher understanding on your way in that land..

11:49 Lutin`: well I've learned that people still use labels and gotos

11:49 clojurebot: Pardon?

11:49 Lutin`: I know right cljbot?

11:55 timvisher: anyone using alembic with private repositories? is that supposed to work?

11:56 justin_smith: timvisher: I know it takes optional args to specify the repo to use

12:00 timvisher: justin_smith: ok

12:01 justin_smith: `:repositories`: specify a map of leiningen style repository definitions to be used when resolving. Defaults to the repositories specified in the current lein project.

12:01 it uses the same syntax as lein for specifying repositories

12:02 so if you can use the private repo from lein, you can likely use it with alembic

12:02 (that was from the doc string from alembic.still/distill)

12:03 timvisher: this is the stack i'm getting https://gist.github.com/timvisher/ca838b094c9415d59323

12:03 yeah, i would think that if lein can resolve it, alembic should be able to resolve it

12:04 justin_smith: timvisher: odd. I haven't used private repos so I can't speak to this specific issue, but I would have expected it would work. Maybe cemerick is around and has more to say about the issue?

12:05 timvisher: cemerick: ooo! erc says he's online. :)

12:05 does hugo duncan ever hang around here?

12:06 justin_smith: timvisher: I remember seeing him in #clojure-emacs more often, when I was in there

12:06 timvisher: that's true.

12:06 i have seen him there a couple of times

12:06 justin_smith: $seen hugoduncan

12:06 lazybot: hugoduncan was last seen quittingPing timeout: 264 seconds 1 week and 2 days ago.

12:08 hugod: justin_smith, timvisher: I'm more often here as hugod

12:08 justin_smith: aha!

12:08 Lutin`: hehe

12:08 timvisher: whoa! :)

12:09 hugod: any knowledge on whether alembic should work with private repos?

12:09 or if the stack i posted a little while ago indicates a problem in that area?

12:11 hugod: timvisher: seems that the constructor pomegranate is expecting to use hasn't got the expected signature - not sure if that is just an aether version issue, or something wrong with the arg types alembic is passing, or some other issue with pomegranate itself

12:12 timvisher: hugod: neat :)

12:12 hugod: the easiest might be to check what alembic is passing to pomegranate, and compare it to what lein passes

12:13 assuming the repo works with lein

12:13 * hugod is in the middle of some rust coding atm

12:13 justin_smith: something like (alter-var-root #'f (fn [f] (fn [& args] (conj debug args) (apply f args)))

12:14 actually that conj should be a (swap! debug conj args)

12:14 of course

12:19 Bronsa: 1.7.0-alpha6 is out

12:19 justin_smith: I decided to try that locally - ended up altering a function called by apply

12:19 which was fun

12:20 Bronsa: awesome

12:20 Bronsa: comes with lots of new goodies and bug fixes :P

12:20 mavbozo: YESSSS!!!

12:20 (inc Bronsa)

12:20 lazybot: ⇒ 101

12:21 Bronsa: mavbozo: I didn't release it but thanks for the internet points I guess :P

12:22 justin_smith: Bronsa: it's the opposite of shooting the messenger

12:22 Bronsa: if you'd told us clojure was being discontinued, he would have dec'd you instead

12:23 * mavbozo #clojureftw

12:23 timvisher: justin_smith, hugod: good points all around. maybe i'll mess with it later. i hate closing my repl :)

12:25 * mavbozo downloading clojure-1.7.0-alpha6

12:29 justin_smith: timvisher: clearly, or you wouldn't be using alembic

12:36 vas: Hi. I'm trying to store the results of a function. When I try invoking (memoize) and then later trying to get a value using 'nth' it says operation not supported. any ideas?

12:39 timvisher: vas: post a paste :)

12:39 justin_smith: vas: that's not how memoize works

12:40 adu: vas: off-by-one? maybe?

12:40 justin_smith: vas: memoize returns a new function, it does not modify the function you supply. And it doesn't result in something you can call nth on.

12:41 vas: justin_smith: aha. thanks

12:41 well, perhaps i can just describe what i wish to achieve, i'm not attached to any particular implementation at the moment

12:41 fxn does a datomic query and has nine elements. how can i make sure i only query when the list is empty and not when it has stuff already?

12:42 justin_smith: vas: would it suffice to query when you first look for results, and reuse the result next time?

12:42 vas: if so (def query-results (delay (query ...)))

12:42 then access as @query-results

12:42 first time you access, it will do the query

12:43 vas: the query should be repeated every page refresh. but it should not happen multiple times during a page rendering, which is what's going on now

12:43 hmm. that could work. maybe i can unset a flag when all the things are rendered to query again and use @results again for the next time

12:44 noncom: do you know of any working MUDs created in clojure?

12:44 justin_smith: vas: inside your page rendering, use let over a delay

12:44 vas: thus, when the page is rendered again, you get a new result

12:45 vas: (delay ) is new to me. shall investigate ^_^

12:45 justin_smith: noncom: I've fantasized about making one, but as a recovering addict I cannot safely approach such a thing

12:45 vas: thank you brave parenthetical knight justin_smith et. al

12:45 noncom: :D

12:45 justin_smith: ,(def a (delay (do (println "realizing") 42)))

12:45 clojurebot: #'sandbox/a

12:45 justin_smith: ,@a

12:45 clojurebot: realizing\n42

12:45 vas: what's a mud?

12:45 justin_smith: ,@a

12:45 clojurebot: 42

12:45 justin_smith: vas: like WoW but no graphics

12:45 textual interface

12:46 vas: oh like nethack?

12:46 noncom: https://en.wikipedia.org/wiki/MUD

12:46 vas: but multiplayer o.O?

12:46 justin_smith: no, that's ascii pictorial

12:46 this is just textual

12:46 and multi-player

12:46 like multi player zork

12:46 vas: i need some ... textual heaaalin

12:46 noncom: nethack is more like a top-down, while mud is more book-text like

12:46 justin_smith: haha

12:46 noncom: also, there is something like tradewars2002...

12:46 which is a different sort..

12:47 vas: cool!

12:47 justin_smith: mud's are very addicting, much like any of those multiplayer online rpgs

12:47 my intro to programming was largely automating mud clients

12:47 noncom: vas: just in case if you're not afraid to get lost http://www.mudconnect.com/

12:48 justin_smith: it's straightforward, because input and output are all text, right...

12:48 vas: *falls into rabbit hole*

12:48 justin_smith: my first experience with race conditions was trigger actions that could trigger again before the previous was done responding :)

12:48 I "invented" debouncing

12:48 lol

12:49 vas: ,@a

12:49 clojurebot: 42

12:50 noncom: justin_smith: cool!

12:51 vas: delay is super cool! :D

12:55 thanks for your help fellow clojurians/pros/homies/neophytes/dungeon masters

12:55 grow the love

12:55 noncom: welcome! :)

12:56 justin_smith: noncom: eventually I was around long enough, and trusted enough, that I became one of the immortals that built the mud. There were "mprogs" that allowed scripted actions within the game engine, but they had no math operators.

12:57 noncom: I implemented a virtual machine to do math, using rooms as registers, and objects as bits (one object represented 1, another represented 2, another 4, etc.)

12:57 when they saw what I did (and that it worked) they promoted me to developer and gave me access to the code base

12:57 noncom: ha :) very clever

12:57 justin_smith: lol

12:57 noncom: wow!

12:57 that wac c/c++ i suppose?

12:57 justin_smith: c

12:58 this was ages ago

12:58 noncom: hey, but you were like neo!

12:58 justin_smith: haha

12:58 noncom: you saw the reality as code and started programming with it

12:58 justin_smith: yup, yup

12:59 noncom: a very good story, i like this kind

12:59 they bear something transcendental within

13:00 danlentz: so in order of efficiency: unboxed objects, boxed objects, rooms with boxes of objects.

13:01 TimMc: (inc danlentz)

13:01 lazybot: ⇒ 3

13:02 talvdav-lt-irc: hi

13:02 /j #lighttable

13:02 sry

13:07 noncom: justin_smith: i think about creating something mud-like, using neo4j, how do you think, is this meaningful?

13:08 danlentz: noncom: you should look at a book called "Land of Lisp"

13:09 it is in common-lisp, but it will walk you through a series of exercises to build your own MUD

13:09 it is also a really funny, weird, inspired piece of art

13:10 but it doesn't necessarily give you the best introduction to common-lisp best practice

13:10 noncom: oh, i saw this title, yeah, the website look intriguing :)

13:10 need to look into it

13:11 danlentz: The guy who wrote the book is not only a talented artist and developer, but also a very highly regarded kidney surgeon

13:12 is it really necessary for people to be genius at THREE different things? I mean, come on. After two isn't it just showing off?

13:12 justin_smith: noncom: where neo4j would be the persistence layer for all the game object state?

13:13 (inc danlentz)

13:13 lazybot: ⇒ 4

13:13 justin_smith: for the "rooms of boxes of objects"

13:14 danlentz: yes, it was very inefficient, luckily all I was doing was multiplying a number by two

13:15 danlentz: noncom: basically everything from chapter 5 on is about "building a text adventure game"

13:16 Grand Theft Wumpus

13:16 bja: the author of land of lisp has an interesting renaming of defmacro as defspel

13:16 danlentz: that works based on a structural representation of a graph using cons cells and symbols

13:16 justin_smith: danlentz: they figured out that I was less dangerous if they gave me access to a real programming language, rather than the odd mprog hacks I used to force it to be turing complete. At least they could understand C code

13:17 noncom: about being genius in many things: i remember someone, probaly tim leary, said "intelligence of a person can be expressed as the number of worlds this person can live in simultaneously"

13:17 bja: I don't know if it'd be better or worse for me at work if I talked about writing spells vs writing macros

13:17 timvisher: justin_smith: sometimes i miss my medievia days :)

13:17 but i'm too obsessed with nethack to play much else these days

13:17 justin_smith: heh, I have to avoid that too

13:17 I get sucked in

13:17 timvisher: justin_smith: badly :)

13:17 weren't we talking about time managament the other day? ;)

13:18 bja: talking about time management in IRC?

13:18 timvisher: bja: that's somewhere in the definition of meta right?

13:18 justin_smith: everyone knows time is the hardest thing in computer science

13:19 bja: I saw that the spacemacs distribution of emacs that I use has irc client bindings now. That is the absolute last thing I need if I want to stay employed. At least now I can alt+tab away from xchat into a full-screen emacs and forget about everything but code.

13:21 noncom: justin_smith: yeah, well, objects relations. the world of a mud is literally built of relations..

13:21 justin_smith: noncom: indeed

13:21 and the map is a graph, where rooms are nodes and exits are edges

13:22 noncom: and objects too

13:22 they are "in" something

13:22 justin_smith: and objects / players / mobs are three other kinds of edges

13:22 right

13:22 noncom: or room has some "objects" like exits and so on

13:22 justin_smith: noncom: the mud I played had a NULL room, so bugs would make people end up there

13:22 timvisher: bja: i have an emacs instance running on a server that i mosh to for irc, and i have a dedicated virtual desktop with nothing but that on it

13:22 justin_smith: it was the room with id=0

13:22 timvisher: makes it easy to avoid if i need to/easy to get to if i want to :)

13:23 justin_smith: noncom: our version of NPE were often a player letting us know they were stuck in "the void"

13:23 timvisher: i'm working on getting a notification system together that will remote notify me if i'm inactive for some period of time but erc's server status hooks are a little buggy/hard to discover :)

13:24 sobel: is there a first-nth? i want something like nthrest for the first n

13:24 justin_smith: sobel: take

13:24 ,(take 3 [:a :b :c :d :e :f :g])

13:24 clojurebot: (:a :b :c)

13:25 sobel: ty

13:29 noncom: justin_smith: haha, that's nice :)

13:29 having a null room

13:30 justin_smith: noncom: I think you could likely avoid the need in a clojure based mud

13:30 noncom: why?

13:30 justin_smith: noncom: because the only way for a player to end up in null was a race condition (an exit still exists, the target does not)

13:30 clojurebot: noncom: because you can't handle the truth!

13:30 justin_smith: haha

13:30 noncom: :D

13:31 justin_smith: or for the room to get deleted while the player was still in it

13:31 clojure can ensure these sorts of inconsistent states are not possible

13:32 noncom: but you said about avoiding the need in clojure based mud - what that means?

13:33 justin_smith: noncom: by using the clojure mutable containers

13:33 atom, ref, agent etc.

13:34 they can ensure that you don't get inconsistent states like players in rooms that don't exist, or exits existing but the destination room does not, etc.

13:34 noncom: ah, i thought you said "avoid the need in mud"

13:34 yeah! i think clojure can give many benifits

13:34 esp when used with a graph db

13:35 justin_smith: yeah

13:35 I'm sure it would open up a lot of interesting possibilities

13:35 I could see using atoms for things relevant to all players, and refs for other things, and per-room transactions

13:36 (for things like exchanging items)

13:36 another classic pair of bugs: the object duplication and object destruction bugs. Either can ruin your game (players getting free items, players losing valuable items, players scamming nice items by claiming they had one and it was destroyed...)

13:36 BinaryResult: Quick reminder that we are hiring clojure devs https://docs.google.com/document/d/1GvnrSCUbYgbY9XdFs_DUx-0QZG2bIYT8Mbr0zdpTeew/edit?usp=sharing

13:36 justin_smith: a transaction can ensure that you don't get duplicate objects, and you don't lose them

13:39 malthe: newbie question: can I use httpkit to power a server that I start with $ lein ring server-headless

13:40 justin_smith: malthe: no, lein-ring uses the embedded jetty server

13:40 malthe: oh okay

13:40 noncom: justin_smith: yeah, concurrency would be handled just fine!

13:40 malthe: how do I start httpkit's server through lein then?

13:40 or is that not a recommended way.

13:40 justin_smith: malthe: but you can make a -main method in your primary ns, and launch the http-kit server there

13:40 it's not super complicated

13:40 malthe: no, I see that they do that in the examples.

13:40 I just wondered if the more "declarative" approach was better.

13:40 like we call you, don't call us :-)

13:41 noncom: also i think that gtraph representation will give many possibilities in manipulating the world

13:41 justin_smith: malthe: the advantage of lein-ring is if you are deploying to a container

13:41 malthe: with http-kit, you are not deploying to a container

13:41 malthe: right

13:41 awesome, thx a bunch

13:41 justin_smith: malthe: with a container, you wouldn't want your code to embed a server, because in soviet aws, container embeds you

13:41 I should stop trying to make jokes

13:42 noncom: haha :)

13:44 korpse_: Is there something like partition-by but omitting the partitioning element?

13:44 timvisher: is it possible to disable {:pre [] :post []} conditions at run time?

13:44 justin_smith: timvisher: yes https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L259

13:45 timvisher: ah! there it is :)

13:45 justin_smith: or you can similarly initialize those variables from your -main for uberjar

13:45 timvisher: thanks :)

13:45 justin_smith: np

13:45 timvisher: can i mess with that var at the repl?

13:45 justin_smith: timvisher: sure, but because of how dynamic vars behave, some code can escape the dynamic scope

13:46 timvisher: ah

13:46 justin_smith: so it's more reliable to set it from the very root

13:46 malthe: justin_smith, hehe yeah ... trying to get my feet wet with clojure, coming from slow Python for 10+ years.

13:46 justin_smith: (which lein can do, or in an uberjar, -main can do)

13:46 malthe: there's a bit to learn.

13:47 justin_smith: malthe: yeah, that's true - there's a mix of our unique fp stuff to learn, and our lispy heritage, and the jvm stuff, and the wonderful inventions/ tasteful borrowings of rich hickey from other langs and research...

13:47 so there is a lot that will be unfamiliar

13:48 a veritable gumbo of learning

13:49 timvisher: tasty…

13:50 malthe: right

13:50 justin_smith, but its pretty fast.

13:50 which is a good motivation :-)

13:51 justin_smith: also, despite all the new things to learn, it is more self-consistent than most

13:54 sobel: are there take and nthrest that don't return lazy-seqs?

13:55 gfredericks: what else would they return?

13:55 justin_smith: sobel: subvec, kind of, if the input is a vector

13:55 sobel: justin_smith: that's probably what i'm looking for

13:56 justin_smith: sobel: subvec is a little weird though, but it's fast if you can fit its constraints

13:57 malthe: what's this mean: No such var: response/url-response

13:57 gfredericks: malthe: do you have "response/url-response" in your code somewhere?

13:57 malthe: nope

13:57 googled around and it suggests bad dependencies

13:57 justin_smith: malthe: could be a bug in some lib you are using

13:58 gfredericks: malthe: could be, check the output at the top of `lein deps :tree`

13:58 which will tell you about conflicts

13:58 justin_smith: malthe: basically it's saying that someone is trying to use a var in another lib, and the lib did not define that var

13:58 malthe: oh ok

13:59 justin_smith: and yeah, gfredericks has the best idea - it could be a newer / older version is there than expected, which doesn't have the var

13:59 and lein deps :tree will show where that is happening

14:00 malthe: hmm I'll try and play with it

14:12 borkdude: what's a good irc channel to ask a question about s3 file uploads?

14:20 justin_smith: borkdude: dunno, but I've done it extensively from clojure

14:21 using clj-aws-s3

14:24 borkdude: justin_smith I was wondering if it's possible to delete a bunch of files with the same prefx

14:25 *prefix

14:25 justin_smith like /foo/bar/...

14:25 justin_smith: hmm... I haven't tried, but I'll check the api

14:26 borkdude: justin_smith do you also use direct upload with s3?

14:26 justin_smith: borkdude: yeah, and I forked clj-aws-s3 to allow uploading from an outputstream even if I don't have a file

14:27 borkdude: justin_smith from a browser I mean?

14:27 justin_smith: no, I did a stream from browser -> jvm clj -> s3

14:27 because otherwise I would need to give the client my credentials

14:27 unless there is some other clever option...

14:28 borkdude: justin_smith you can use pre-authorized upload links to a form

14:28 justin_smith so the user can upload a file to a certain key

14:28 justin_smith: borkdude: this is news to me, and seems like a nice enough way to do it

14:29 borkdude: justin_smith but this introduces a new problem: I want to keep track of the filename, because else next time I don't know what image to show to the user

14:29 justin_smith: though my case was a cms, where it was still simpler to have the user send the media to the server (and do some things on the server side before uploading)

14:29 borkdude: justin_smith yes, probably I'll do that too. did you use direct downloads though, or also via the server?

14:30 justin_smith: borkdude: I embeded s3 links in my html

14:30 the uploads were for creating page content

14:31 (so the client uses the cms UI to create content, uploading the images to put on a certain templated page etc., then their visitor gets s3 links to that media in the rendered page)

14:31 which speeds page load because it parallelizes better

14:32 borkdude: would the thing you wanted with deleting a directory be covered by delete-bucket?

14:33 or do you want a more granular subdirectory within a bucket...

14:33 borkdude: justin_smith subdirectory

14:34 justin_smith: yeah, at least clj-aws-s3 lacks that functionality

14:34 borkdude: justin_smith I've now solved my problem by keeping track of who uploaded which file, for example a profile picture

14:34 justin_smith next time the same user uploads a profile picture I have to know which previous file to delete

14:34 justin_smith I'm saving the filename in a database

14:34 justin_smith: that makes sense, in our cms we had a db reification of the asset, with the file name, what cms model it is attached to, and the location on s3

14:34 which is basically the same thing, yeah

14:35 borkdude: right

14:36 justin_smith also one thing I wanted to check: deleting file costs time, so I'm doing that in a future, does it make sense?

14:36 justin_smith: sure, I think so

14:37 since your further actions don't depend on that completing, clearly

14:37 maybe one concern would be finding out if it failed? you could check that future before function exit I guess

14:38 failing to delete seems like something you could log and come back and deal with later

14:38 unless you expect masive user profile churn :)

14:38 borkdude: justin_smith good one

14:38 pandeiro: is it possible to have comments in yesql query files that yesql will ignore?

14:38 borkdude: pandeiro good question, I also want to know

14:39 justin_smith: pandeiro: I'd expect it to ignore sql comments, but I haven't had a chance to really play with yesql in anger yet

14:39 pandeiro: it explicitly allows comments https://github.com/krisajenkins/yesql#one-file-one-query

14:39 cemerick: justin_smith, timvisher: I'm not *actually* here :-P What's the issue?

14:40 justin_smith: cemerick: timvisher had an issue with using a private repo via alembic (that was using pomegranate)

14:40 borkdude: justin_smith that comments will be in the docstring

14:41 justin_smith do you also use pregenerated urls, or is everything public on your s3?

14:42 justin_smith: borkdude: we used default-public, you can set access when uploading

14:42 but in practice we specified public every time

14:43 pandeiro: justin_smith: yeah so my question is how to create comments in SQL files used by yesql that are *not* query fn names or docstrings... some digging makes me think this use case is not supported

14:43 cemerick: justin_smith: not sure I'd have any insights. Pomegranate is stable (i.e. I haven't looked at its code in > a year)

14:44 borkdude: pandeiro my question too, it seems a forgotten feature

14:44 I'm tending more and more towards jdbc only though..., especially for updates/inserts

14:44 justin_smith: cemerick: and private repos are known to work?

14:45 pandeiro: borkdude: yeah i often go that route too

14:45 sqlingvo as well

14:45 cemerick: justin_smith: yup, I have a number of them, and work with a few others that do as well

14:45 justin_smith: cool, so if anything this is an alembic bug

14:45 (until we can prove otherwise)

14:46 cemerick: justin_smith: everyone uses https://github.com/technomancy/s3-wagon-private AFAIK

14:47 mavbozo: (inc technomancy)

14:47 lazybot: ⇒ 163

14:48 cemerick: the authentication mechanism is very flexible, but it's pretty hard to beat s3

14:50 justin_smith: oh yeah, and deploying to nexus-style repos (which might just use basic auth?) is as easy as having a :username :password map in ~/.lein/credentials.clj, etc

15:08 danielam: any idea what cider's tab completion isn't working? cider-repl-tab-command is set to cider-repl-indent-and-complete-symbol but I keep getting "No match" in the repl.

15:16 alpheus: Having trouble compiling a Clojure/Clojurescript app on just one machine. Works everywhere else. I've removed .m2/repository, installed the same Java version and am out of ideas.

15:17 I realize this is not a very good question, but I can furnish complete details if needed.

15:17 arohner: alpheus: define "trouble"

15:17 alpheus: OK to paste the exception?

15:17 arohner: alpheus: gist is better

15:17 gist.github.com

15:19 alpheus: sure, one moment

15:20 https://gist.github.com/craig-ludington/2d8bf9804cbbc93731a9

15:21 FWIW, the exception always refers to something in piggieback, but it's been a different source in the past. (Just upgraded JDK)

15:21 arohner: alpheus: 'Unable to resolve var: cemerick.piggieback/wrap-cljs-repl'

15:22 I bet you either don't have piggieback installed locally, or it's the wrong version

15:22 alpheus: is there something in your ~/.lein/profiles?

15:22 alpheus: Ah, good question!

15:22 arohner: also, pointing out that line is far more helpful than "it doesn't work"

15:23 alpheus: Sure, thanks.

15:37 piggieback was indeed out-of-date. Thanks for your help, and sorry for my vaguely-worded request for help.

15:40 patrkris: hi everyone. would someone here spend 30 seconds looking over a function I've written in Clojure that handles a Ring request. I am looking for pointers in improving the code to become more idiomatic. I'm used to working in languages where it's possible to do "early returns" and so on. here it is: https://www.refheap.com/99108

15:41 justin_smith: patrkris: some more destructuring might help, eg min-days and max-days

15:42 patrkris: justin_smith: oh yeah, thanks

15:42 justin_smith: patrkris: also, I would put the orders/update! call inside a when, separate from the calculation of the return value

15:43 even if that when has the same condition as the response generation

15:43 patrkris: justin_smith: great

15:43 justin_smith: patrkris: also, I think some-> might help some of your code be clearer

15:44 oh, never mind, that wouldn't help

15:44 I thought there was deeper chainging

15:44 patrkris: justin_smith: is the use of `when` right in your book to skip evaluation of code instead of having "early returns"? do you understand what I mean?

15:44 justin_smith: *chaining

15:44 patrkris: okay :)

15:44 justin_smith: patrkris: that is exactly what when is for - conditional side effects

15:45 some-> can chain multiple when, stopping at the first nil

15:45 effectively that is

15:45 patrkris: justin_smith: oh, clever

15:46 so that is the primary difference between a when and a one-clause if? (they have the same effect, but when is typically used for skipping potential side effects)

15:46 justin_smith: right

15:46 otherwise you could use and (to indicate the value is interesting - same semantics effectively)

15:47 where when is about the action, and would be about the value

15:47 so you may want to switch when to and on line 10 for example

15:47 and line 8

15:47 patrkris: cool, thanks

15:47 amalloy: that is kinda a political topic. i would leave it as a when, personally

15:48 justin_smith: yeah, it's not unanimous

15:48 amalloy: sometimes i wonder if justin_smith is really technomancy in disguise

15:48 justin_smith: patrkris: also, I think line 18 could cause problems

15:48 patrkris: you should add :otherwise nil to the end of the cond I think

15:49 patrkris: how about assigning `error` multiple times in the let form? is that kosher?

15:49 justin_smith: okay, i'll check

15:49 justin_smith: patrkris: never mind

15:49 amalloy: justin_smith: :else nil is the default for cond

15:49 justin_smith: I always have a default

15:49 yeah, I just checked it, :else nil is implicit

15:49 amalloy: i do too, but you don't actually *have* to

15:49 justin_smith: I guess I am so conservative I forgot what actually works :)

15:49 amalloy: justin_smith: i remember this causing some surprising issues with unboxed math

15:49 justin_smith: interesting

15:50 amalloy: stuff like (+ 1 2 (cond (even? x) 3 :else 4))

15:50 results in all the math being boxed, because the cond "might" fall off the end and return nil

15:50 justin_smith: because of an invisible fallover to nil

15:50 right

15:50 tricky tricky

15:50 amalloy: i don't remember if that was resolved or what

15:50 patrkris: hmmm... I thought it was nice not having to specify the default case in cond

15:51 Bronsa: amalloy: I have a patch in jira that fixes this

15:51 justin_smith: patrkris: yet another thing that is basically style, I initially brought it up because I honestly forgot if lacking a default could lead to an error

15:51 patrkris: also since it is specified behavior as far as the docstring goes

15:51 justin_smith: yes

15:51 patrkris: yes

15:52 Lutin`: I survived the meeting ;D

15:52 justin_smith: patrkris: what's up with binding error twice?

15:52 patrkris: justin_smith: yeah, that is also one of my questions

15:52 justin_smith: patrkris: that first binding of error will never survive to the end of the binding vector

15:52 because it is shadowed, so it will get thrown away as inaccessable

15:53 patrkris: justin_smith: you're right... stupid mistake :S

15:53 Bronsa: amalloy http://dev.clojure.org/jira/browse/CLJ-1598

15:53 justin_smith: patrkris: I would make it data-error and order-status-error

15:53 patrkris: noted

15:53 justin_smith: and then check both in the if, or create error by or

15:54 patrkris: good idea

15:54 gfredericks: Bronsa: before I looked at the ticket I thought "there's no good way to fix that problem" and then I looked and "oh of course that makes sense"

15:55 justin_smith: patrkris: luckily it looks like this is nice and idempotent / functional, so you don't have to block side effects conditionally mid controller

15:55 gfredericks: the cond macro itself could fix it too I suppose, but the if fix is more general

15:55 justin_smith: err... handler, or whatever, I keep screwing up that terminology, I should know better

15:56 patrkris: justin_smith: I know what you mean :)

15:56 I guess what trips me up the most is, again, not being able to return early, like you would do in Go or other imperative languages

15:58 justin_smith: you can get similar semantics via delay

15:58 and then simply not having a code path that accesses the delay as your "early return"

15:58 though it is odder to read, especially at first

15:58 but it ends up being similar to haskell's lazy evaluation in a way - things that don't get accessed don't get calculated

16:02 patrkris: justin_smith: thanks again. I would like to see some "enterprise software" written by The Masters sometime. one thing is watching Rich Hickeys codeq, which has a fairly technical problem domain - another is to see Clojure used to write enterprisey, boring software.

16:03 tbaldridge: patrkris: you might be interested in this Clojure/West talk then : http://clojurewest.org/speakers#amarcar

16:04 patrkris: thanks, will check it out

16:04 tbaldridge: do you know when/if it will be online?

16:05 tbaldridge: patrkris: not sure, but the past few conferences puredanger has put on have hand same or next day video releases

16:05 clojurebot: Excuse me?

16:05 tbaldridge: *have had

16:05 patrkris: nice

16:06 rhg135: ooh I forgot clojure/west was coming up

16:06 tbaldridge: when I gave my talk at ClojureWest last year I think the video was online 3 hours after I gave the talk.

16:07 amalloy: yeah alex has been amazing with the videos

16:10 gfredericks: (inc puredanger)

16:10 lazybot: ⇒ 40

16:34 sobel: i've gotten lots out of Conj videos. i just wish PostgreSQL confs had the video support y'all did.

16:35 but i definitely soak up a lot from the clojure channel on youtube

16:45 verma: anyone here used nightcode on a osx system, can't figure out how to get the paredit shortcuts to work :(

17:28 mavbozo: i get some weird exception from destructuring using 1.7.0-alpha6

17:28 https://www.refheap.com/99113

17:28 gfredericks: I don't think you're supposed to expect that to work in general

17:28 mavbozo: am i doing destructuring wrong?

17:29 gfredericks: yeah I wouldn't use other keys in the :or expressions

17:30 mavbozo: ,(let [{:keys [b a] :or {b (or a :b)}} {:a "A" :b "B"}] [a b])

17:30 clojurebot: #error{:cause "Unable to resolve symbol: a in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: a in this context", :at [clojure.lang.Ut...

17:30 justin_smith: ,*clojure-version*

17:30 clojurebot: {:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true}

17:32 mavbozo: that works in 1.6.0. what happened?

17:32 amalloy: mavbozo: just random chance

17:32 ,(macroexpand-1 '(let [{:keys [b a] :or {b a)}} m])

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

17:32 amalloy: ,(macroexpand-1 '(let [{:keys [b a] :or {b a}} m]))

17:32 clojurebot: (let* [map__95 m map__95 (if (clojure.core/seq? map__95) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__95)) map__95) b ...])

17:32 amalloy: &(macroexpand-1 '(let [{:keys [b a] :or {b a}} m]))

17:32 lazybot: ⇒ (let* [map__46082 m map__46082 (if (clojure.core/seq? map__46082) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__46082)) map__46082) a (clojure.core/get map__46082 :a) b (clojure.core/get map__46082 :b a)])

17:35 mavbozo: it become somewhat close to certainty in 1.7.0-alpha6

17:36 Bronsa: mavbozo: try the one that's working in 1.7.0-alpha6, in 1.6.0. I bet it won't work

17:36 amalloy: mavbozo: maps aren't ordered, so the order in which :or destructuring happens is undefined

17:37 if you refer to bindings which may or may not exist, you get code that may or may not compile

17:38 mavbozo: not working in 1.6.0

17:39 thx guys

17:39 pmonks: (inc Bronsa)

17:39 lazybot: ⇒ 102

17:39 dxlr8r: is there a library for sending signals to running application in clojure? I use the great clojure.tools.cli library to send arguments on the command line, but would like to send the application more data from my commandline at runtime

17:39 mavbozo: (inc amalloy)

17:39 lazybot: ⇒ 247

17:39 mavbozo: (inc Bronsa)

17:39 lazybot: ⇒ 103

17:42 mavbozo: that's why carmine breaks https://github.com/ptaoussanis/carmine/blob/v2.9.1/src/taoensso/carmine/connections.clj#L55-L59

17:43 gfredericks: mavbozo: I can sense a pull request in carmine's future

17:44 bbloom_: guys. i'm writing some go for work... i miss you

17:44 pmonks: (dec bbloom_)

17:44 lazybot: ⇒ 0

17:44 bbloom_: ,(class (max 5 10))

17:44 clojurebot: java.lang.Long

17:44 * bbloom_ exhales

17:45 gfredericks: bbloom_: what is an "int max"?

17:46 bbloom_: gfredericks: the signature of go's max function is Max(float64, float64) float64

17:46 gfredericks: oh god

17:46 bbloom_: there's no Max(int, int) int

17:46 amalloy: bbloom_: sounds like java's

17:46 bbloom_: amalloy: java has double, float, int, and long overloads

17:46 gfredericks: ,(class (Math/max 5 10))

17:46 clojurebot: java.lang.Long

17:46 pmonks: (dec go)

17:46 amalloy: oh i'm wrong

17:46 lazybot: ⇒ -1

17:47 dxlr8r: any way to send signals to a running jvm running clojure without having some sort of socket server etc?

17:47 like sending signals with "kill"

17:47 amalloy: dxlr8r: my advice would be to use a socket server

17:47 Bronsa: amalloy: you can still save it by claiming you meant javascript

17:47 gfredericks: dxlr8r: there's a thing with a SignalHandler somewhere

17:47 amalloy: bbloom_: i guess i was thinking of Math/exp

17:48 gfredericks: dxlr8r: this worked for me for casual usage, no idea what the drawbacks/pitfalls are https://github.com/clojure/test.check/blob/gfredericks/prng-comparison/src/dev/clojure/clojure/test/check/prng_comparison.clj#L8-11

17:48 hyPiRion: bbloom_: Have you seen http://golang.org/pkg/bytes/#Map ? :p

17:48 bensu: bbloom_: I'm curious about go routines composition

17:49 bbloom_: hyPiRion: weeeee

17:49 bensu: after a fair amount of core.async experience... i'm not a huge fan of CSP. a little dab will do ya

17:49 bensu: bbloom_: in Go the compiler can make a state machine out of the go routines of arbitrary depth

17:50 bbloom_: bensu: no that's what core.async does

17:50 to be fair, go is much better than core.async in this regard

17:50 it can park full stacks

17:50 rather than finite state machines

17:50 bensu: bbloom_: ok, that is exactly the sort of thing I'm interested in

17:51 bbloom_: what else are you going to miss when you use core.async

17:51 even if it's not your favorite

17:53 clueless: Hey all. I'm stuck with this. http://pastebin.com/uGH57jb9. 'draw-world' doesn't work when being run from 'setup'. Even if I put prints inside there they aren't shown. Seems like the loop isn't even being run. I really can't figure out why. The function executes flawlessly when being run individually in the REPL.

17:54 So, help is very appreciated!

17:54 gfredericks: This paste has been removed!

17:54 no it hasn't

17:54 that was my fault for including the '.'

17:54 (inc computers)

17:54 lazybot: ⇒ 1

17:55 clueless: Hmm?

17:55 justin_smith: clueless: draw-world is lazy

17:55 clueless: draw-world will do nothing unless you consume its values

17:56 clueless: Oh, right...

17:56 justin_smith: clueless: perhaps you should s/for/doseq/

17:56 TEttinger: (doc doseq)

17:56 clojurebot: "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

17:56 justin_smith: clueless: also for and doseq both support a :let key in the binding vector, that can be nicer than a let block inside the body

17:57 TEttinger: if you do want a sequence of results, you can use doall

17:57 justin_smith: nested doall, for the nested for

17:57 clueless: Thanks a lot, really appreciated.

17:58 Will try to wrap my head around this now!

18:05 dxlr8r: gfredericks: thanks, that actually worked :)

18:08 wei: I’m building a native java package using “mvn install” and confirmed it’s in ~/.m2/repositories/… However, I can’t seem to depend on the library using leiningen. Is there anything else I have to do?

18:08 gfredericks: dxlr8r: w00t

18:09 wei: how does it fail?

18:09 wei: lein deps -> “Could not find artifact XXX in clojars"

18:10 justin_smith: wei: do the coords in your project.clj match the pom.xml that lein created and put under .m2/ ?

18:13 wei: justin_smith: I’m looking at maven-metadata-local.xml inside .m2, and the groupId, artifactId, and version all seem to match

18:13 dxlr8r: gfredericks: only problem is that it won't compile with uberjar

18:13 gfredericks: dxlr8r: uhmwhat?

18:14 dxlr8r: java.lang.IllegalArgumentException: Signal already used by VM or OS: SIGUSR1, compiling

18:15 gfredericks: dxlr8r: are you running it at the top level like in my code?

18:15 justin_smith: wei: can you share the pom.xml and the relevant line from your project.clj in a paste?

18:16 sorry, not pom.xml, but foo.pom

18:16 it will be in the dir with the jar

18:16 wei: justin_smith: thanks, give me a sec

18:17 dxlr8r: gfredericks: yeah

18:17 just after ns

18:17 gfredericks: dxlr8r: maybe throw it in a function and call it from your main then

18:20 wei: justin_smith: https://gist.github.com/yayitswei/134ac7d9f5d74b1cf74b

18:22 justin_smith: OK yeah, that looks just fine

18:22 and how are you accessing the lib?

18:22 wei: I’m just running lein deps

18:22 justin_smith: oh, .. .right

18:23 dxlr8r: gfredericks: same error :/

18:23 calling from main

18:23 justin_smith: and it's an error on the lib, and not one of its transitive deps? if so, that's super weird

18:24 gfredericks: dxlr8r: no ideas, I can't make sense out of that

18:24 wei: justin_smith: the error is Could not find artifact org.bitcoinj:bitcoinj-core:jar:0.13-SNAPSHOT in clojars (https://clojars.org/repo/)

18:24 dxlr8r: http://stackoverflow.com/questions/1050370/java-error-java-lang-illegalargumentexception-signal-already-used-by-vm-int found something there gfredericks

18:25 but I don't know how to input "-XX:-AllowUserSignalHandlers" to lein

18:25 lein -> jvm

18:25 wei: justin_smith: the installed repo is in ~/.m2/repository/org/bitcoinj/bitcoinj-core/0.13-SNAPSHOT is that correct? why do some packages get installed in ~/.m2 and some in ~/.m2/repository

18:25 justin_smith: wei: that is so weird - maybe it has to do with the SNAPSHOT thing? maybe try lein install without the SNAPSHOT version suffix?

18:26 because there are behaviors associated with SNAPSHOT, like checking upstream once a day for a new version, even if you already have a version

18:26 so maybe change SNAPSHOT to pre-release (or something that differentiates from the true 0.13 stable, but isn't going to trigger a check)

18:27 wei: i’ll try that, thanks

18:28 gfredericks: dxlr8r: lein has a :jvm-opts option, and after making an uberjar you'd specify it to `java` directly

18:33 still weirds me out that the compiler can tell what kind of signal you're trying to handle

18:34 justin_smith: gfredericks: well, for proper behavior the signal handling would have to get promoted out of the VM directly into OS Syscalls...

18:34 and I guess it might as well whitelist those

18:38 dxlr8r: well, got it to compile now with that flag to jvm-opts

18:59 TimMc: gfredericks: I'd be really curious what the bytecode difference is!

18:59 seangrove: Whenever I use ring.middleware.resource/wrap-resource in an uberjar and give it a uri of "/", it seems to think there's a file there

18:59 That sound familiar to anyone?

19:06 gfredericks: TimMc: it's a compile-time error is the thing

19:07 justin_smith: seangrove: so you are using (wrap-resource handler "/") ?

19:10 dxlr8r: I don't get it to run thought. not through "lein run" nor the uberjar

19:11 same error. have tried "java -XX:-AllowUserSignalHandlers file.jar" gfredericks

19:12 gfredericks: eliphino

19:16 Lewix: im looking for an alternative book to

19:16 clojure programming

19:16 justin_smith: Lewix: what are you looking for specifically?

19:16 Lewix: (i feel like it's moving too fast at times)

19:17 justin_smith: learn clojure from beginner to mastery ^^

19:18 justin_smith: have you looked at clojure for the brave and true or clojure from the ground up online? I think they are both a little slower in pace / less dense

19:18 dxlr8r: http://www.4clojure.com/problems that to

19:19 justin_smith: oh, yeah, 4clojure and the clojure koans are good

19:21 Lewix: justin_smith: i started with clojure for the brave then felt like it didn't dive deep enough - eventually bought the book as per your advise (i think)

19:21 dxlr8r: I do the clojure koans sometimes

19:23 seangrove: justin_smith: Nah, (my-wrap-resource "public")

19:23 justin_smith: Lewix: yeah, probably my advice

19:23 seangrove: odd, I have not seen wrap-resources try to serve /

19:23 seangrove: Ok, maybe I'm misunderstanding it

19:23 gfredericks: does anybody know of any differences between clojure string syntax and json string syntax?

19:24 Lewix: justin_smith did you read the book cover to cover

19:24 justin_smith: gfredericks: I think json supports \ in places clojure does not

19:24 Lewix: no, not yet

19:25 Lewix: to be honest, I had gotten a job doing Clojure, had never done it before, and I just crammed 3/4 of the book to get my bearings as fast as I could.

19:26 Lewix: justin_smith: what books where they?

19:26 justin_smith: Clojure Programming, and Joy of Clojure

19:26 that plus a lot of dumb mistakes and eventually I figured it out

19:27 Lewix: justin_smith: ok. I'll force through it -

19:29 justin_smith: I think trying stuff is under-rated. Just doing something (with the best advice you can find for not developing bad habits of course). You may have noticed, whenever someone shares some source code here they get helpful tips.

19:29 make some things, ask questions, we can help you avoid the bigger mistakes

19:29 and make more things

19:32 Lewix: justin_smith: good point

19:34 dxlr8r: gfredericks: for future referance: https://gist.github.com/nicoulaj/3758045

19:34 don't use SIGUSR1, I couldn't get it to work no matter what

19:36 Lewix: justin_smith: i wanna make a web app = maybe i should read a web app clojure book instead and use programming clojure as reference along the way

19:40 dxlr8r: Lewix: try sente

19:40 good web lib

19:41 TimMc: gfredericks: ...the hell.

19:42 dxlr8r: Do you get the same compile error if you use "INTX".substring(0,3) or whatever?

19:43 or rather, what does happen?

19:46 Lewix: dxlr8r: How about liminus - i might start reading web programming with liminus

19:48 justin_smith: Web Development with Clojure comes from a source I would trust

19:49 Lewix: in fact, it was written by yogthos

19:50 Lewix: justin_smith: I know, I attend the clojure meetup sometimes - he's our prof

19:51 justin_smith: oh, cool

19:51 dyba: I'm trying to write a macro where I'm using a case statement

19:51 Lewix: justin_smith: yea im gonna jump straight to the book and use programming clojure as ref

19:51 dyba: I'm thinking the better way to do it would be to use an if rather than a case statement

19:52 justin_smith: dyba: using a case statement to create the macro, or generating a case statement via a macro?

19:52 dyba: Oh, generating a case statement via a macro

19:53 justin_smith: depends how many conditions you plan on having I guess?

19:54 dyba: justin_smith: https://gist.github.com/dyba/1d9a3551e2bb9f75111c

19:56 justin_smith: dyba: would it be one defmacro generated per symbol / number pair?

19:57 oh, no, one macro (eg unit-of-time)

19:57 dyba: justin_smith: I just updated the gist to provide more info

19:57 I'm thinking maybe I need to ( apply case... )?

19:57 justin_smith: you can't apply a macro

19:57 dyba: But case is a macro

19:58 and I wasn't sure if you can treat macros like functions

19:58 i.e. (map a-macro-here ...) fails

19:58 justin_smith: I think you'll want something like (case un# ~@units)

19:59 ,`(case ~'x ~@[:a 0 :b 1])

19:59 clojurebot: (clojure.core/case x :a 0 :b ...)

19:59 justin_smith: that's the right structure, yeah?

19:59 you don't need the ~'x, that was for simplicity and you already have un#

20:00 dyba: right, ok. I'm going to try that out

20:23 johnmendonca: what does it mean when a name ends with #, like foo#

20:24 gfredericks: it's a macro thing; it makes sure the name is unique

20:24 in case there are other foos around when the macro expands

20:24 johnmendonca: gfredericks: gotcha thanks

20:25 gfredericks: ,`foo ;; more accurately it's a ` thing

20:25 clojurebot: sandbox/foo

20:25 gfredericks: ,`foo#

20:25 clojurebot: foo__49__auto__

20:25 gfredericks: ,'foo

20:25 clojurebot: foo

20:25 johnmendonca: seems like that would be common for symbol inside a macro?

20:27 gfredericks: macros use that almost all the time, yes

20:27 it's difficult to not use it

20:27 johnmendonca: cool, macros are one area i have not dived into yet, slowing wrapping my head around quoting, splicing, etc

20:31 gfredericks: ~macros

20:31 clojurebot: I added a ~' and it worked.

20:31 gfredericks: ~macros

20:31 clojurebot: macros are like dessert

20:31 gfredericks: ~macros

20:32 clojurebot: I added a ~' and it worked.

20:32 amalloy: gfredericks: i remember the first time i saw '~' in a macro

20:32 and i was like, the guy who wrote this is off his rocker

20:36 gfredericks: I refuse to read any macro with nested `

20:36 amalloy: gfredericks: you can need '~' without using nested `

20:36 `(require ['~'foo.core ...]]

20:37 and i dunno, in theory maybe `(require '[foo.core ...])) is fine because require just calls 'name on the namespace name, but i don't know if that's the case or what

20:37 hyPiRion: gfredericks: nested as in `(~@(foo `...)) or ``(..)?

20:42 gfredericks: hyPiRion: the latter

20:42 hyPiRion: they don't make much sense I think

20:43 gfredericks: maybe for macro macros

20:43 I know it's happened and that I'm ethically opposed to it

20:44 hyPiRion: Is it like triple pointers in C? Because I've not seen it yet

20:44 gfredericks: I bet if you looked through some ztellman code carefully enough...

20:46 hyPiRion: heh

20:54 Seylerius: Here's my solution to 4clojure #50. Any ideas on how to make it non-ugly? http://sprunge.us/SdgJ

20:55 amalloy: Seylerius: first thing that jumps out at me is to remove the repetition of (first remainder) and (rest remainder) all over the place

20:55 also your paste is cut off at the end

20:56 Seylerius: http://sprunge.us/OUYJ

20:58 amalloy: Seylerius: on a larger scale, it is pretty sad to have exactly four special cases here? what if someone added, say, a map? or a list? you'd have to add another loop variable, another cond clause...

20:59 Seylerius: amalloy: Yeah, that's why I don't like this solution.

20:59 amalloy: Seylerius: have you looked at anyone else's solutions?

20:59 Seylerius: No.

20:59 I try not to.

20:59 At least until after I've solved it at least once.

20:59 amalloy: well, consider the function (type)

20:59 Seylerius: Hrm.

20:59 amalloy: which is hinted at by the problem title/description

21:00 Seylerius: Ooh. Just had a thought.

21:17 justin_smith: thanks for the warning

21:33 * justin_smith is sorry.

22:08 justin_smith: vas: on the opening day of Clojure / West I am going to see Acid Mothers Temple - this reminds me I need to see if there are any visiting clojurists who would be into going to that show.

22:09 vas: justin_smith: dude sweet. what's one of your favorite songs by them?

22:10 justin_smith: I dunno about favorites, but this one is good https://www.youtube.com/watch?v=c7888r_vKX4

22:10 vas: would "scope" be an appropriate term for the access a fxn has to its goodies?

22:11 justin_smith: Sure. Also you can describe each of those goodies as being "closed over"

22:11 and call the whole thing a closure

22:11 vas: justin_smith: yo thanks for the link! video is also suitably trippy and to my liking.

22:12 like an umbrella !

22:15 are there alternatives to (shuffle) ?

22:16 justin_smith: alternative in what way?

22:17 cfleming: Is it true that for a splicing reader conditional, the list that gets spliced in must be a constant list, i.e. it's unevaluated?

22:17 timg: Hi all, I got a noob question...

22:18 amalloy: cfleming: i haven't been following jira or -dev or whatever, but: probably. the reader reads, not evaluates

22:18 and compare it to, eg, the record literal syntax, which is unevaluated

22:18 cfleming: amalloy: That's what I figured, thanks - I'll see if someone can confirm

22:18 timg: If I have a vector like (def x [+ 1 2 3]), is there a more idiomatic way to apply it than (apply (first x) (rest x)) ?

22:19 amalloy: timg: no. that's a weird vector to have, but if you do have it that's what you want to do

22:19 timg: Ok, thanks cfleming.

22:19 cfleming: ping puredanger

22:20 timg: You're welcome, but all thanks should go to amalloy there

22:20 timg: Oh, sorry! Thanks amalloy.

22:21 vas: ho snap vectors are FAST

22:21 justin_smith: vas: so what kind of alternative to shuffle did you have in mind?

22:22 vas: justin_smith: well i only have 9 elements and I want to mix them up. shuffle works but adds quite a bit of overhead time (from 14ms to 189ms)

22:22 justin_smith: based on the source, it looks like it's a pretty low level implementation

22:23 vas: Alright. I'll brainstorm it a bit. maybe I can achieve what I want later on in the process of rendering

22:23 justin_smith: you could maybe look and see if someone has a fast alternative for java.util.Collections/shuffle

22:23 which is what it uses

22:24 vas: is there a way to have (nth-rand [collection]) never return a duplicate for a given coll?

22:24 ah good thinking

22:24 amalloy: i have a lazy-shuffle somewhere

22:24 justin_smith: also, if the input was already an ArrayList or array, that would skip a step I guess...

22:26 vas: "After a little bit of Googling, I discovered that the Collections.shuffle() method uses the "Fisher-Yates" algorithm. This approach loops backwards over the array and swaps the current element with another randomly-selected element in the array. "

22:27 well it's not mission critical, thanks for your mind awareness anyway :)

22:27 also: acid mothers temple = amaze

22:29 justin_smith: I posted on facebook a while back, asking if anyone wanted to go to their concert. I guess Mitsuru Tabata had an alert or something, because he sent me a friend request. Now I get to see what he eats for lunch every day, because that's what he uses facebook for.

22:40 vas: justin_smith: that's all-star

22:40 justin_smith: he pretty much has curry or ramen every day

22:41 cfleming: Can anyone point me to the source in Clojure that handles the new #error and #object forms? I'd expected them to be in default-data-readers but they're not, and searching for "error" or "object" brings back a lot of results.

22:43 justin_smith: cfleming: here's the commit https://github.com/clojure/clojure/commit/692645c73c86d12c93a97c858dc6e8b0f4280a0b

22:44 oh, that only adds the printing part, huh...

22:44 cfleming: justin_smith: Thanks, I missed that scanning the log

22:44 justin_smith: Yeah, you're right

22:45 justin_smith: Maybe that's not in master yet, if it's part of the socket REPL stuff

22:46 amalloy: feature request: rename socket repl to rocket repl

22:46 justin_smith: ,(Exception. "except")

22:46 clojurebot: #error{:cause "except", :via [{:type java.lang.Exception, :message "except", :at [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke "core.clj" 3078] [clojure.core$eval3$fn__4$fn__14 invoke "NO_SOURCE_FILE" 0] ...]}

22:47 justin_smith: ,(read-string (pr-str (Exception. "except")))

22:47 clojurebot: #error{:cause "No reader function for tag error", :via [{:type java.lang.RuntimeException, :message "No reader function for tag error", :at [clojure.lang.LispReader$CtorReader readTagged "LispReader.java" 1180]}], :trace [[clojure.lang.LispReader$CtorReader readTagged "LispReader.java" 1180] [clojure.lang.LispReader$CtorReader invoke "LispReader.java" 1164] [clojure.lang.LispReader$DispatchReader ...

22:47 justin_smith: cfleming: I think that is your answer ^

22:48 cfleming: justin_smith: Looks like it, yeah

22:49 It seems like the lack of reading would make the printing fairly useless, doesn't it? Or am I missing something?

22:49 justin_smith: cfleming: it adds the option of defining a reader?

22:50 if you chose to

22:50 cfleming: justin_smith: I guess so

22:50 justin_smith: or maybe 1.7 will have a reader, and it's just not in yet

22:50 cfleming: Actually, I don't think you can do that for non-namespaced reader tags

22:51 Seylerius: ,(defn type-splitter [coll] (loop [remainder coll result {}] (cond (empty? remainder) result (contains? (type (first remainder)) result) (recur (rest remainder) result) :else (recur (rest remainder) (conj result [(type (first remainder)) (filter (partial = (type (first remainder))) remainder)])))))

22:51 clojurebot: #'sandbox/type-splitter

22:51 cfleming: Or maybe you can, and you're just not supposed to, I forget

22:51 Seylerius: ,(type-splitter [1 :a 2 :b 3 :c])

22:51 clojurebot: #error{:cause "contains? not supported on type: java.lang.Class", :via [{:type java.lang.IllegalArgumentException, :message "contains? not supported on type: java.lang.Class", :at [clojure.lang.RT contains "RT.java" 772]}], :trace [[clojure.lang.RT contains "RT.java" 772] [clojure.core$contains_QMARK_ invoke "core.clj" 1419] [sandbox$type_splitter invoke "NO_SOURCE_FILE" 0] [sandbox$eval96 invoke ...

22:51 justin_smith: cfleming: I'd guess it is just bad form

22:51 Seylerius: contains? doesn't work that way

22:52 ,(doc contains?)

22:52 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

22:52 Seylerius: Got the key and coll reversed.

22:52 justin_smith: Seylerius: if the input is a vector, the only thing that will return true is a digit arg

22:52 ,(contains? [:a :b :c] 1)

22:52 clojurebot: true

22:52 justin_smith: ,(contains? [:a :b :c] :a)

22:52 clojurebot: false

22:52 Seylerius: ,(defn type-splitter [coll] (loop [remainder coll result {}] (cond (empty? remainder) result (contains? result (type (first remainder))) (recur (rest remainder) result) :else (recur (rest remainder) (conj result [(type (first remainder)) (filter (partial = (type (first remainder))) remainder)])))))

22:52 clojurebot: #'sandbox/type-splitter

22:52 Seylerius: justin_smith: the input is a map.

22:53 justin_smith: OH, OK

22:53 Seylerius: ,(type-splitter [1 :a 2 :b 3 :c])

22:53 clojurebot: {java.lang.Long (), clojure.lang.Keyword ()}

22:53 Seylerius: ...

22:53 justin_smith: Seylerius: it's filtering for things that are equal to the type

22:53 isn't it?

22:54 Seylerius: Yeah. But I've got my type-filter wrong.

22:54 justin_smith: Seylerius: I think the issue there is nothing in the input is the type of anything else in the input

22:54 though they share types

22:54 Seylerius: Yeah. I see what I mixed up.

22:55 I need to put in an anonymous function that takes two things and returns true if they share types.

22:56 justin_smith: yeah, that sounds right

22:56 Seylerius: Also, I need to make an emacs function that squashes an arbitrary bit of clojure onto a single line.

22:56 Because that would make pasting in here simpler.

22:56 justin_smith: Seylerius: heh M-x one-line-defun

22:56 Seylerius: Oh R'lyeh?

22:56 justin_smith: no, that would be a thing to name it

22:56 it doesn't exist yet

22:57 Seylerius: Ah, well it will in a few minutes.

22:57 Mostly it just requires whitespace squashing.

22:57 justin_smith: Seylerius: join-line

22:57 it does the whitespace squashing for you

22:58 with truthy arg joins with next line, otherwise joins with previous

22:59 Seylerius: Neat

23:00 justin_smith: I have it bound to C-c j

23:00 Seylerius: Good idea.

23:00 justin_smith: because I find it useful (even with my evil-mode J binding that acts in reverse)

23:00 Seylerius: Hrm. What's the #() function syntax for multiple args?

23:00 %1 and %2?

23:01 justin_smith: yup, and %& does what you might expect

23:01 Seylerius: That being all?

23:01 justin_smith: ,(#(do % %2 %&) 1 2 3 4 5 6)

23:01 clojurebot: (3 4 5 6)

23:01 justin_smith: remaining ^

23:02 Seylerius: Nice!

23:03 ,(defn type-splitter [coll] (loop [remainder coll result {}] (cond (empty? remainder) result (contains? result (type (first remainder))) (recur (rest remainder) result) :else (recur (rest remainder) (conj result [(type (first remainder)) (filter #((= (type %1) (type %2))) remainder)])))))

23:03 clojurebot: #'sandbox/type-splitter

23:03 Seylerius: ,(type-splitter [1 :a 2 :b 3 :c])

23:03 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/type-splitter/fn--56>

23:04 justin_smith: Seylerius: I think you have extra parens on that lambda

23:04 also, why are you passing a two arg predicate to filter?

23:04 Seylerius: Just spotted that.

23:05 ,(defn type-splitter [coll] (loop [remainder coll result {}] (cond (empty? remainder) result (contains? result (type (first remainder))) (recur (rest remainder) result) :else (recur (rest remainder) (conj result [(type (first remainder)) (filter #(= (type (first remainder)) (type %)) remainder)])))))

23:05 clojurebot: #'sandbox/type-splitter

23:06 Seylerius: ,(type-splitter [1 :a 2 :b 3 :c])

23:06 clojurebot: {java.lang.Long (1 2 3), clojure.lang.Keyword (:a :b :c)}

23:06 justin_smith: Seylerius: ##(group-by type [1 :a 2 :b 3 :c])

23:06 lazybot: ⇒ {java.lang.Long [1 2 3], clojure.lang.Keyword [:a :b :c]}

23:06 Seylerius: Okay. Mostly there. Now I just returns the values of each key, rather than the map itself.

23:06 ...

23:06 R'lyeh? Srsly?

23:06 justin_smith: Seylerius: the former was still a good learning exercise

23:06 Seylerius: I did not know that existed.

23:06 justin_smith: Seylerius: http://conj.io

23:07 Seylerius: I just reimplemented group-by...

23:08 justin_smith: congratulations

23:09 Seylerius: ,(defn type-splitter [coll] (keys (group-by type coll)))

23:09 clojurebot: #'sandbox/type-splitter

23:09 Seylerius: ,(type-splitter [1 :a 2 :b 3 :c])

23:09 clojurebot: (java.lang.Long clojure.lang.Keyword)

23:09 Seylerius: ,(defn type-splitter [coll] (vals (group-by type coll)))

23:09 clojurebot: #'sandbox/type-splitter

23:09 Seylerius: ,(type-splitter [1 :a 2 :b 3 :c])

23:09 clojurebot: ([1 2 3] [:a :b :c])

23:09 Seylerius: And win.

23:31 TimMc: Seylerius: Another "wait, that exists?" is frequencies.

23:31 TEttinger: I love frequencies

23:32 arrdem: (inc Seylerius)

23:32 lazybot: ⇒ 2

23:32 TEttinger: ,(frequencies (repeatedly 10000 #(rand-int 5)))

23:32 clojurebot: {0 2026, 2 1928, 3 2037, 4 1973, 1 2036}

23:32 elvis4526: I have trouble understanding futures and promises.

23:33 What happen if you try to access one of them before the computation is over ?

23:33 TEttinger: elvis4526, in my experience, they're awesome and handy

23:33 I think futures block if they haven't completed yet

23:33 justin_smith: elvis4526: it will wait until it finishes

23:33 elvis4526: alright that's pretty simple lol

23:33 TEttinger: they're guaranteed to have some value

23:35 in a clojure dungeon crawler I worked on, I used futures for level gen. if you descended a floor, it would start generating the next level of the dungeon, which wasn't something that you needed immediately and was something that I didn't want to calculate immediately when it was requested

23:36 but you also couldn't descend to a non-existent level, which is nice :)

23:36 if you somehow speed-demoned your way through a level to get to the next one, it would block until it had the next level finished and ready, which probably wouldn't be long

23:37 elvis4526: that's nice thanks for the example

23:37 TEttinger: plus, it was an amazingly elegant solution with clojure futures

23:37 I was thinking how hard it would be to do all that in another thread with java, not pretty

23:37 justin_smith: TEttinger: did you ever finish that crawler?

23:38 I guess the followup is "is a crawler ever finished?"

23:38 TEttinger: tbh? I'm starting up a new one tonight. not graphical. going to use my quixotic 200 class project for data.

23:39 I decided I need a better handle on state to do what I want to be doing, and I can't do the kind of state shenanigans I want in C#

23:39 well, not concisely

23:41 (and I think, despite not being very good with macros yet, I know how to write good Clojure better than I know how to write good C#)

23:46 bbloom: shit, i'm falling behind :-P

23:47 justin_smith: bbloom: time lag again?

23:47 bbloom: who wants to submit a patch to fipp for #object and #error? :-)

23:48 justin_smith: apparently.

23:49 it must be my machine or client, b/c i'm on a different ISP 2500 miles away from the last time i experienced time travel...

23:52 TEttinger: fipp?

23:52 justin_smith: bbloom: looks like you're OK actually

23:52 $ping bbloom

23:52 bbloom: i just closed & reopened my client

23:52 justin_smith: ahh

23:52 TEttinger: $ping bbloom

23:52 $help ping

23:52 lazybot: TEttinger: Pings an IP address or host name. If it doesn't complete within 10 seconds, it will give up.

23:53 justin_smith: oops, wrong command

23:53 haha

23:53 bbloom: TEttinger: fipp is a pretty printer i wrote. should get the new clojure 1.7 #error and #object things

23:53 but i don't wanna write it right now :-)

23:55 justin_smith: ahh, it's /ping user, and it will tell you the round trip time between you (and thus show any lag)

23:55 ~0.7 seconds

23:55 clojurebot: It's greek to me.

23:55 bbloom: depends on your client

23:55 justin_smith: of course, yeah

23:55 but there is an underlying CCTP ping op

23:56 which I guess some clients might not even respond to

23:56 *CTCP

23:56 TEttinger: what's the general convention on multiple-word project names? lein rejects DungeonRising, if I have a hyphen in there will I need to do shenanigans with replacing - with _ ?

23:56 justin_smith: TEttinger: not really, lein will generate the folder / files with the right deal

23:57 bbloom: TEttinger: come up with a better project name ;-)

23:57 or just mash the words together

23:57 or deal w/ the -/_ of doom

23:57 justin_smith: TEttinger: also, I recommend "lein new biz.TEttinger/dungeon-rising" (if you own TEttinger.biz)

23:57 I don't actually think you own a .biz

23:57 TEttinger: I believe I don't own any domain names

23:58 I get by with subdomain redirects to github pages if I desparately need a better URL

23:58 justin_smith: dungeon-rising: in clojure land, dungeon crawls you

23:58 TEttinger: http://doge.csproject.org

23:58 justin_smith: dogeon-crawl

23:59 codesine: I'm trying to do a radix sort in clojure and was setting up the buckets like

23:59 (take 10 (repeat []))

Logging service provided by n01se.net