#clojure log - Aug 11 2013

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

0:19 callen: Music for writing Clojure: http://www.youtube.com/watch?v=_aTFLnG3YcY

0:21 clj_newb_2345: suppose I tag something with "localhost/base"

0:21 how is it separated between vs "username localhost" with tag "base" ?

0:26 Bahman: Hi all!

0:27 wolfes: Hello!

0:27 callen: Bahman: hai

0:27 Bahman: Hey wolfes, callen!

0:28 wolfes: Does anyone know of a good way to get an aleph server to auto-restart/reload when code changes in development mode?

0:30 callen: wolfes: prolly hafta to hack it up yourself. That's pretty strange anyway.

0:30 wolfes: usually you're running and re-running a test harness with something like Aleph. You aren't using that for web dev are you?

0:30 a Guardfile is one option.

0:32 wolfes: callen: i'm looking to create a simple server that accepts http post requests and forwards messages to specific websocket connections — v1 works (https://github.com/wolfes/nspire), but it uses aleph(http server)+compojure(route), and it doesn't have the nice "lein ring server" possibility that hot-reloads server code on code change

0:32 callen: wolfes: you should probably consider using http-kit instead unless there's something specifically compelling about Aleph.

0:32 wolfes: i don't really know that much about aleph and don't have any super compelling reasons to use it over another option :)

0:33 callen: Aleph isn't (ztellman can correct me here) a general purpose web server.

0:33 http-kit is.

0:33 wolfes: callen: I'll take a look at http-kit though, would you recommend http-kit over ring+compojure?

0:33 callen: wolfes: er, you're still using ring and compojure.

0:33 wolfes: do you know what any of these words mean?

0:33 you need to take a breather and understand what's going on.

0:34 Ring is the middleware + http abstraction, it's not an HTTP server.

0:34 Compojure is routes/handlers abstraction.

0:34 wolfes: compojure handles routing

0:34 callen: http-kit is a web server. Jetty is a webserver.

0:34 when you use vanilla lein ring server, you're firing up a jetty instance.

0:34 wolfes: ah ok, i mistook ring for an http server :)

0:34 callen: it is decidedly not.

0:34 it wouldn't make any sense.

0:34 Ring is like Ruby's Rack and Python's WSGI and Perl's Plack and Common Lisp's Clack

0:35 it's designed to enable tooling that isn't specific to a particular web server.

0:35 wolfes: ring abstracts http into a request map and response map, and gives you middleware

0:35 callen: it would suck ass if every web library and framework had a homespun web server.

0:35 wolfes: you don't need to repeat it in here, I know what ring is.

0:35 I'm sure most others do too.

0:35 wolfes: use http-kit + ring + compojure.

0:35 wolfes: read the documentation this time.

0:36 wolfes: callen: thanks!

0:37 callen: wolfes: just one thing to be aware of with async libraries like http-kit and and Aleph

0:37 wolfes: no global state.

0:39 wolfes: callen: just to clarify, you mean these async libraries don't provide facilities for managing global state themselves right, or that I'll run into some terrible gotcha if I try to manage global state outside of the library?

0:39 callen: wolfes: well lets work through it.

0:39 wolfes: async means the code is going to be stopped and started at any given time

0:40 wolfes: in Jetty, (which is synchronous) you have a thread pool and each http request gets its own thread for processing from that pool.

0:40 wolfes: in something like http-kit, while a handler is blocking on something else, the thread might get retasked to processing a different request.

0:40 among other things

0:41 this is why most websocket compatible servers are async, so you can juggle more connections without choking off the machine.

0:41 wolfes: if you have global state in a thread, what do you suppose happens if that same thread gets retasked to different code?

0:41 as a result, you should avoid global state (thread local or not) in async code unless you know what you're doing.

0:41 and if you had any doubt, you don't. So don't do that.

0:45 wolfes: callen: hmm, the retasked thread would provide access to the thread's global state to the new code and/or the old code, when resumed, may be in a different thread without access to the its previous thread's global state?

0:45 callen: wolfes: you'd have a state conflict, race conditions, etc

0:45 Bad News Bears (TM)

0:45 wolfes: have you used a language with threads before?

0:45 wolfes: where's your book?

0:46 wolfes: callen: python is my main language now, but the threading i've done in it was for code that didn't have any shared state

0:46 callen: python doesn't have real threads anyway because of the GIL

0:47 roight so

0:47 wolfes: where's your book?

0:47 wolfes: callen: i have a pdf of "Clojure Programming"

0:48 callen: wolfes: you should read it and do the examples.

0:53 wolfes: callen: I read 1-10, but not the last sections yet, ch16+17 look relevant — i've been using an atom to hold a single point of global state for named message-channels (to avoid race conditions creating new named channels with listeners at the same time), since i don't need multiple identities to change in the same operation (for now)

0:54 callen: :|

0:54 wolfes: read and perform the exercises the whole book

0:54 of the*

0:57 wolfes: callen: thanks for the advice :)

1:03 kristof: Is letfn exactly the same thing as let* in Scheme?

1:03 As in, binding everything simultaneously so as to allow referencing between bindings?

1:04 I'm learning Clojure coming from Scheme, and I'm really happy to see that the majority of the stuff I know (the VAST majority) is almost exactly the same, and I get some new goodies, too.

1:04 callen: kristof: simultaneity wouldn't allow for cross-referenced bindings.

1:04 wolfes: kristof: letfn lets you create a named function closure within your let statement iirc (http://clojuredocs.org/clojure_core/clojure.core/letfn)

1:05 john2x: dammit am I having a hard time understanding the pedestal dataflow

1:06 kristof: wolfes, callen, ok!

1:06 callen: john2x: don't use Pedestal.

1:06 bts-: kristof: i haven't used let* in a while, but i think clojure's let is the same thing. it lets you successively use previous bindings

1:07 kristof: cool! =)

1:07 bts-: kristof: i haven't used scheme*

1:07 callen: it is successive and sequential though.

1:07 wolfes: bts-: let* lets you swap two variables without creating a third temp var, like python's x,y = y,x iir(scheme)c

1:08 bts-: wolfes: ah interesting

1:09 john2x: callen, yeah I probably shouldn't, just find it really interesting. :P what do you suggest for an alternative to building the client-side of an app with clojure?

1:09 wolfes: kristof: not entirely sure what your use case is, but you might find trampoline useful (example: http://pramode.net/clojure/2010/05/08/clojure-trampoline/)

1:09 callen: john2x: client-side meaning web app?

1:09 john2x: yes, simpler alternative to pedestal-app I guess

1:09 callen: john2x: if it's complicated JS + Angular or ClojureScript + Angular. If it's not complicated, and it's probably not, very little JS at all.

1:10 john2x: it's probably not complicated. So just render HTML.

1:10 statically.

1:10 john2x: for rendering that - https://github.com/yogthos/Selmer

1:10 kristof: wolfes: I didn't know that letfn wasn't mutually recursive but I didn't need that to begin with :P I was simply thinking of using previous bindings in later ones, and it turns out it was that.

1:10 wolfes: But trampolining looks like the shit and I am so going to use this sometime

1:10 callen: don't overcomplicate your code.

1:11 kristof: pffft screw that, that's what LISP is for

1:11 callen: it's really not.

1:11 kristof: Forgetting about abstraction barriers and making funcitonal spaghetti

1:11 *functional

1:11 callen: it's for making otherwise painful or complicated things doable.

1:11 wolfes: kristof: just a warning, clojure doesn't optimize non-self-calling tail recursion

1:12 kristof: wolfes: right, I had a feeling.

1:12 wolfes: I'd probably just restructure my logic and use a loop in that case

1:12 john2x: ah cool, so Angular works with ClojureScript. I'm primarily a server-side guy, and whenever I try writing javascript, I always find it terribly ugly.

1:12 kristof: wolfes: Although how would someone write something like the eval apply loop in that case? :P

1:13 callen: john2x: so don't write JavaScript.

1:13 kristof: I guess I can look in clojure's core and find out! Haha

1:13 callen: john2x: like I said, static HTML. Keep it simple.

1:16 john2x: shake-n-bake best practices: http://www.luminusweb.net/

1:18 akhudek: I wish luminus would swap korma for clojure.jdbc

1:18 callen: akhudek: part of the point of Luminus is the swappability.

1:18 akhudek: which fits in with the Clojure aesthetic.

1:18 akhudek: you can swap in whatever you want.

1:18 akhudek: if you want a luminus sub-template that defaults to JDBC, contribute one.

1:19 akhudek: callen: I realize that, but as a "best-practices" recommendation I would prefer clojure.jdbc

1:19 callen: I often find myself saying "see luminus as a great starting but, but swap korma…."

1:19 callen: akhudek: I'm the reason it's Korma atm, if you have arguments to make, I'm the person to make it to.

1:20 that having been said, since I introduced him to it, yogthos seems to have been satisfied with Korma so far. He's only needed raw sql for a couple of things.

1:20 akhudek: callen: the main reason is that korma still has a little too much magic in it. I've still managed to find queries were korma is generating things that don't map to the obvious sql.

1:20 plus there are some dangerous side effects that you might not expect having used sql elsewhere

1:21 callen: I haven't run into anything egregious or disconcerting yet

1:21 akhudek: like returning the entire record on deletion, a killer if you use large binary objects

1:21 callen: that's a simple patch.

1:21 :no-return

1:21 Come on man.

1:21 akhudek: this is open source, file issues / send PRs.

1:21 I'm sure Baranosky would love it if he wasn't the only person writing any code.

1:22 akhudek: you need to at least document these complaints on the github issues, if not fix them.

1:23 akhudek: callen: I have for at least two things, but both were essentially about changing defaults and thus ended up not changing.

1:23 which is fine

1:23 * callen sighs and rubs forehead

1:23 gcr: Hey! I'm trying to follow https://github.com/clojure-android/lein-droid/wiki/Tutorial but when I add [lein-droid "0.2.0-SNAPSHOT"] to my (nonexistent) ~/.lein/profiles.clj, running even just "lein2 --version" raises an exception, "java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.util.Map$Entry"

1:23 callen: okay, I haven't heard anything sufficiently compelling to switch away from Korma

1:23 akhudek: but if you run into anything else problematic, if you aren't going to file an issue, please *AT LEAST* tell me in here.

1:24 I'm always online on IRC and I will see my lastlog and queries.

1:24 akhudek: if the problems pile up, I'll seriously consider a switch, for now I'm invested in improving Korma when it needs it.

1:25 gcr: Here's the backtrace and transcript: http://pastebin.com/Atj4SghH

1:26 akhudek: callen: sure, didn't realize you were in charge of it now. We've already swapped a lot of code to c.jdbc so won't likely run into anything new. Overall I find the jdbc defaults to work a lot closer to how I'd expect (e.g. much closer to writing raw sql at the console). Now that it has a nice korma-like sql dsl, I don't see the downsides.

1:26 callen: akhudek: I am decidedly not in charge of it, but I'm very good at convincing/cajoling yogthos to change things. Luminus is his baby and there's another dude that contributed a lot.

1:26 akhudek: but as you say, it's not really a big deal

1:26 easy to swap

1:27 callen: incidentally, Selmer was also mostly yogthos (thus is being on his github) but I was pushing him along, writing tests, etc there as well.

1:27 akhudek: the other weird magic I encountered with korma was something to do with aggregates I think

1:27 callen: and explaining the performance and design of Django templates.

1:27 akhudek: Korma is a little weaker on aggregates, partition, etc.

1:27 That's a known dilly.

1:27 akhudek: remember spending hours trying to get it to write the correct sql and being annoyed that it was a query I could write instantly in raw sql. I think that's what first prompted me to switch.

1:28 callen: akhudek: that's been a common reaction to SQL abstraction layers of all kinds for years.

1:29 akhudek: the answer is to improve the layer. I like Korma explicitly because it translates pretty closely to the SQL I'd write, just cleaned up.

1:30 wolfes: would anyone recommend any libraries over clojurewerkz neocons for use with neo4j's http api (the free, non-embedded edition)?

1:30 akhudek: callen: hah, that's an understatement. It took me a long time to get those complaints. I started with clojureql, then moved to korma because of annoying magic, then to jdbc because of the same (though korma is much closer to sql as you say)

1:30 callen: akhudek: I've been using relatively complicated ORM layers for a little over a decade. Korma is a breath of fresh air and easy to hack for me.

1:31 akhudek: callen: Aside from these few pain points with korma, I suppose my argument is more: what does korma offer now, that jdbc doesn't, given the new jdbc dsl?

1:32 callen: akhudek: the new JDBC DSL is okay. I like it much better than the dumb raw string smashing of yore.

1:32 I don't hate the new JDBC DSL, but I started using Clojure long before it existed

1:32 so I was on the Korma train.

1:32 heh. K(a|o)rma train.

1:35 john2x: skimmed through all the chapters of the pedestal tutorial. holy shit.

1:35 callen: john2x: just use Luminus.

1:40 john2x: yeah.. already did a simple project with luminus, though it was all backend with just simple javascript for the client. i guess I could update it to clojurescript as a start.

1:41 callen: john2x: do you need to?

1:42 john2x: nope. but it'll be a learning experience and fun :)

1:43 hmm not too sure about the fun part yet.

1:43 gcr: nevermind, i found that profiles.clj should contain {:user {:plugins [[lein-droid "0.2.0-SNAPSHOT"]]}} and not just the bare plugin dependency. i edited the lein-droid wiki to say this.

1:51 clj_newb_2345: on ubuntu, do people use openjdk-7 or openjdk-7-zero ?

1:52 callen: clj_newb_2345: use Oracle JDK 7

1:52 clj_newb_2345: callen: as in install via a tgz ?

1:53 callen: wutevs.

1:54 heylo: Hello

1:54 callen: heylo: heylo

2:41 sinistersnare: ,(doc when)

2:41 clojurebot: "([test & body]); Evaluates test. If logical true, evaluates body in an implicit do."

3:51 clj_newb_2345: so no one else has the stale NFS handle problem with "docker rm" on certain containers?

3:58 callen: clj_newb_2345: this is #clojure

3:58 clj_newb_2345: ah, sorry

3:59 i promise to make up for this in the future

3:59 when peopel have trouble setting up clojure servers, I'll tell them to use docker :-)

3:59 qed: uhhhh

4:00 Maybe he meant: https://github.com/pallet/pallet-docker

4:05 callen: qed: nope.

4:06 people using docker is hilarious

4:06 they're using jails for their apps on jailed VPSes.

4:06 qed: callen: whether or not that's the case, he was looking for help

4:06 callen: most redundant bullshit I've ever seen.

4:06 devn: <-qed

4:06 callen: containers are for people managing their own instancing on a dedi.

4:06 devn: how'd you snag the nick qed?

4:07 I'd have assumed that was taken by now.

4:07 you know, like right after "root"

4:07 devn: he repeatedly forgets what channel he is. I was operating on the basis of "data".

4:07 devn: as soon as I remind him he's not in the docker channel, he buggers off.

4:07 he is in*

4:07 devn: idk, when i was 16 and without direction I went on a nick hunting spree on freenode, grabbed te and qed

4:08 Raynes: lol

4:08 callen: of course it's worth remembering that I don't need data to tell people to fuck off.

4:08 devn: callen: depends on what you mean by "need"

4:08 Raynes: $dict need

4:08 lazybot: Raynes: noun: A condition or situation in which something is required or wanted: crops in need of water; a need for affection.

4:08 Raynes: ^ I expect.

4:09 callen: people don't need affection, unless you are rolling into, "not going postal" into need.

4:09 personally, I think raising the black flag and slitting a few throats is healthy.

4:09 devn: Raynes: What I mean is that no one strictly requires data, it can sometimes be considered irresponsible to operate without it as a matter of course

4:10 callen: I'm a nihilist, for me data is just ammo for getting people to stop squawking.

4:10 I'm going to do what I want regardless.

4:10 devn: heh, ^-things you're likely only to ever hear on IRC

4:11 callen: devn: you haven't met me in person. Raynes has though.

4:11 I'm polite and nice in person, I think, but I still don't really care.

4:11 Raynes: devn: I can vouch that he is equally as nihilist in real life.

4:11 * devn shrugs

4:12 devn: so what's up with clojure and stuff?

4:12 What are you dudes & gals working on?

4:12 Raynes: I'm writing Elixir because life is meaningless.

4:12 callen: devn: I'm writing a server defense library for Clojure.

4:12 devn: haha

4:12 Apage43: my funsies project is at the point where I am about to write a parser for a mini language

4:12 callen: Raynes: nihilist != life is meaningless, it just means there's no inherent/universal meaning.

4:12 Apage43: CFG?

4:12 devn: Apage43: cool! have a repo?

4:12 Apage43: then again, i could make my users write in edn and not do that

4:13 devn: Raynes: are you seriously writing a lot of elixir?

4:13 callen: it's most of what I've seen from him or heard about lately.

4:13 so I'd vote, "yes"

4:13 that and that fucking youtube video.

4:13 Apage43: callen: nah.. kind of a really light weight math expression language

4:13 callen: Apage43: yeah but is the grammar context free?

4:13 Apage43: think R-lite-lite

4:13 Raynes: devn: I've written https://github.com/Raynes/reap, https://github.com/Raynes/rapture, and I'm working on a website now. If I don't throw my macbook against the wall trying to use simple_oauth2, I might end up writing a lot of Elixir.

4:13 callen: I'm asking for a Chomsky Hierarchy bro.

4:14 devn: it's super simple, but I needed it: https://github.com/bitemyapp/trajectile

4:14 devn: Colorless green ideas sleep furiously

4:14 callen: my server defense thingy will be out by the end of the weekend.

4:14 Apage43: probably?

4:14 callen: Apage43: o_O

4:15 I'm having a hard time coding right now because I'm tired though.

4:15 and hungry.

4:16 Apage43: anyway my thing is https://github.com/couchbaselabs/mortimer which is a tool for sifting through the numbers collected from the data-dumps our customer support guys get when Couchbase is acting weird or is on fire

4:17 callen: the : separated classpath formatting is not very friendly.

4:17 Apage43: want to add a way for folks to type expressions "(somestat + otherstat) / overstat" and plot that

4:17 callen: sensible for ${PATH} but jesus guys.

4:17 Apage43: instead of just the current offering which is the raw numbers or their rates

4:17 callen: aha, couchbase.

4:17 I had to shut that daemon down today because it was eating my machine alive.

4:18 Apage43: miiiight be my fault >.> probably not though

4:18 generally the erlang parts are what do that

4:18 callen: working on couchbase has to be annoying sometimes. I hear the weirdest reasons from people for why they still use CouchDB

4:18 TEttinger: Apage43, I think there's an infix math lib for clojure, loading "(somestat + otherstat) / overstat" as a string

4:18 Apage43: I work on the C parts

4:18 callen: Apage43: it was a long running instance, but yeah, it was taking more than it's fair share of my laptop.

4:18 like 10-15% of 4gb

4:18 TEttinger: http://data-sorcery.org/2010/05/14/infix-math/

4:19 callen: damn you, I was googling so I could be the hero.

4:19 Apage43: isn't Couchbase C++?

4:19 Apage43: TEttinger: interesting.

4:19 I'm already pulling in incater so

4:19 TEttinger: cool beans

4:20 callen: Apage43: what got you into Clojure if your day-to-day is C/C++?

4:20 Apage43: callen: Parts. It's memcached on the frontend + C++ in the caching layer + C in the storage layer (my part)

4:20 callen: lawd.

4:20 Apage43: Couchbase is CP right?

4:20 Apage43: callen: I've been using Clojure since before I was at Couchbase.

4:20 yes

4:21 callen: cool

4:21 Apage43: I probably mentioned before that I used to work on a big couchdb cluster.

4:21 Apage43: it's just what I use when I am doing something that I get to pick what I do it in =P

4:21 callen: and by work on, I mean by brutalized by.

4:21 Apage43: mostly for tools and stuff

4:21 callen: that's very cool.

4:22 for some reason a lot of the C programmers I know are fuddy-duddies and don't use anything newer than C89.

4:22 except for the one guy that switched to doing iOS mobile dev.

4:22 Apage43: I refuse to use a language that hasn't been updated since I've been born

4:22 (which is why my C project recently became C++, since we've decided it has to work on MSVC which won't support C99)

4:23 callen: Raynes: do you know if most people use rainbow parens in here?

4:23 sinistersnare: ,(doc if)

4:23 clojurebot: Cool story bro.

4:23 callen: I've been pondering why I don't seem to need paredit yet everyone else here does.

4:23 Raynes: I think most don't, but I have no scientific data to back that up, callen.

4:24 Most people seem to despise rainbow parens.

4:24 callen: sinistersnare: there is clojure documentation online. are you unable to use http due to a proxy?

4:24 Raynes: really? they're quite wonderful.

4:24 Raynes: I use them and I'm friggin' colorblind.

4:24 sinistersnare: no, ill look it up online

4:24 callen: devn: see? I was thoughtful about it and checked to make certain he didn't have some sort of extenuating circumstance.

4:25 * Apage43 uses rainbow parens and .. paredits depending on the day of the week. Since I manage to get the vim paredit out of sync a lot I sometimes just turn the thing off.

4:25 TEttinger: I love rainbow parens

4:25 use them in light table

4:26 Apage43: everyone who uses the crap out of paredit says they mostly use slurp and barf, which I pretty much never use

4:26 I tend to use splice and wrap a lot though

4:31 callen: if limit-break didn't work

4:32 I would probably cut my wrists.

4:32 technomancy: why isn't limit-break on clojars?

5:27 well I finally got nrepl ritz to work. sorta.

5:27 shit's kinda spooky but whatever.

5:27 I'm going to need it for a future project.

5:45 samrat: if I want to upload a large file with clj-http is there a way to do it without loading that file into memory?

5:59 Foxboron: Raynes: is famine a web framework'ish/server thingie written in elixir?

6:00 callen: yeah okay I take that back

6:00 nrepl-ritz is still batshit

6:01 meanwhile over in Common Lisp they have a real debugger in their Emacs :\

6:06 samrat: are there any examples using clojure.java.io/input-stream for sending multipart post requests with clj-http?

6:17 Raynes: Foxboron: Nope.

6:18 Foxboron: It's a web app.

6:18 It's literally impossible to make a guess at what it'll do yet since I've implemented exactly zero functionality (what's there is oauth experimentation at the moment).

6:18 All the information currently to go on is the name, which certainly isn't helpful. :p

6:29 callen: I am scowling so hard right now. https://github.com/noir-clojure/noir/blob/master/src/noir/request.clj

6:30 my face might get stuck in this scowl.

6:30 my needs may call for a macro.

6:31 everybody hold onto something bolted down, dis gon b gud

6:36 Foxboron: Raynes: yeah, so much more specefic then :

6:36 :3*

8:36 dotemacs: Hi, I'm running this little snippet, but for some reason, the exception is not getting caught: https://gist.github.com/6204633

8:37 Any hints as to why ?

8:37 Thanks

8:41 IamDrowsy: dotemacs: only the first matching catch block will be executed. so the FileNotFoundException is already catched by the catch Exception block... if this is what you mean by not getting caught

8:42 dotemacs: IamDrowsy: no, I mean the following, regardless how many catch blocks I have none of them catch the exception. Even if I have just a single (catch Exception e (prn "error 0")) it gets ignored

8:43 and the exception still dumps

8:43 So lets say I just have this: https://gist.github.com/6204656 the exception gets ignored completely. How come ?

8:44 IamDrowsy: mh.. but you are sure the exception is thrown? i just created a mock run-main that just throws an exception and it works like it should

8:48 dotemacs: ok, i'll show you the real code, it's here: https://github.com/technomancy/leiningen/blob/master/src/leiningen/run.clj#L100

8:49 I've removed the 'apply' and I'm trying to run just the smallest part of that function

8:54 IamDrowsy: does it make sense to you ?

8:54 IamDrowsy: so first guess would be that the exceptions are already caught inside the run main (and are not rethrown as you can see)...

8:55 depends on the implementation of catch and throw

8:57 dotemacs: good point, thanks

9:52 zilti: Sometimes I don't really grok how binding works. Why does this example here fail? https://www.refheap.com/17503

9:54 ambrosebs: zilti: should be (assert *dynvar* "Error!")

9:56 zilti: ambrosebs: ...oh. Wow. Thanks! Sometimes I hate my brain...

9:56 ambrosebs: :)

9:57 IamDrowsy: zilti: or at least (assert (not (nil? *dynvar*)) "Error!") if you really want only nil (and not false) to fail (you missed the '?')

9:57 zilti: That's a typo that the ? is missing

9:58 ...hmm but wait. Then it still doesn't solve my problem.

9:59 IamDrowsy: nil means nil and is no fn.. nil? checks if something is nil

10:01 zilti: That's so weird. That small example I posted works, but in my code it doesn't...

10:04 ambrosebs: zilti: do you have a link?

10:05 zilti: ambrosebs: I just found out what doesn't work, I updated the snippet: https://www.refheap.com/17503

10:06 I somehow understand why, but not how to elegantly work around that

10:06 ambrosebs: make wrapper2 a macro

10:06 it should be a simple with-* macro

10:07 (defmacro with-wrapper2 [test & body] `(binding [*dynvar* ~test] ~@body))

10:08 zilti: Yes, that works. Thanks!

10:08 ambrosebs: cool

10:09 zilti: ,(inc ambrosebs)

10:09 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ambrosebs in this context, compiling:(NO_SOURCE_PATH:0:0)>

10:09 zilti: ...wrong channel I guess

10:09 ambrosebs: (inc ambrosebs)

10:09 lazybot: You can't adjust your own karma.

10:10 hyPiRion: (inc ambrosebs)

10:10 lazybot: ⇒ 1

10:10 ambrosebs: (inc ambrosebs) (inc ambrosebs)

10:10 lazybot: ⇒ 1

10:10 ambrosebs: :)

10:10 zilti: :)

10:10 hyPiRion: huh, no karma? that was unexpected.

10:10 (identity hyPiRion)

10:10 lazybot: hyPiRion has karma 20.

10:10 hyPiRion: hrm.

10:11 gavri: how do I use list comprehensions in clojure to generate all m-length lists possible from a sequence of length n, both with and without replacement?

10:12 I mean, both permutations and combinations

10:13 ambrosebs: have you looked at https://github.com/clojure/math.combinatorics

10:14 I don't particularly know if it solves your problem.

10:14 gavri: ambrosebs: thanks, I think it does

10:17 also, I guess I wanted permutations and selections

10:17 thanks again. that library is what I wanted

10:28 is there a shorter way to find the most frequent element in a sequence than calling frequencies on it and picking the map entry with the highest value?

10:29 hyPiRion: urgh, always forget this paredit command. Anyone remembers how to go from (foo [x y z] (bar |...)) to (bar (foo [x y z] ...)) ?

10:30 Foxboron: hyPiRion: http://www.emacswiki.org/emacs/PareditCheatsheet

10:31 hyPiRion: Foxboron: it's unfortunately one of those not on that sheet if I remember correctly

10:31 Foxboron: yeah, was looking. Didn't see it.

10:32 gavri: speaking of paredit, I use evil on emacs. does paredit make sense with evil?

10:32 ambrosebs: I don't use paredit, but is this paredit-convolute-sexpr?

10:32 Just recognise it from the recent posting on clojure ml

10:33 hyPiRion: ambrosebs: Yeah, that's it. Thanks :)

10:33 (inc ambrosebs) ; for real this time

10:33 lazybot: ⇒ 2

10:33 ambrosebs: haha

11:15 TimMc: hyPiRion: Bonus: You can use C-u to change the number of levels you're... convoluting.

11:16 hyPiRion: TimMc: If I need that I seriously need to reconsider my Clojure/lisp skills.

11:17 That's neat though, I'll keep it whenever I figure out I am horrible at Clojure.

11:17 TimMc: I've used it once or twice.

11:18 Both times I think for lifting a let outside several layers of doseq, for, or binding.

11:19 hyPiRion: TimMc: oh right, so it's not flipping the paren, it's just raising it up

11:19 I though (foo (bar (baz ...))) would become (baz (bar (foo ...)))

11:20 I realize in hindsight that it would make no sense to have that.

12:40 noncom: I have a question on optional args to a macro, here it is: https://www.refheap.com/17506

12:42 zilti: noncom you have to do & [{:as features}] instead

12:43 noncom: zilti: looks like it does not work this way... i'm getting IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:505)

12:44 like it is trying to treat :width as a []

12:44 i think so

12:44 zilti: That would be weird...

12:45 noncom: could copy-paste the reafheap with the changes, maybe i'm missing something..

12:48 zilti: Oh for me "[name- params & {:as features}]" works as expected.

12:50 noncom: ~features is enough, no need to unsplice with ~@

12:51 noncom: zilti: oh, you are right, looks like the @ was unnecessary

12:51 still learning macros

12:52 what is ~@ good for?

12:53 muhoo: noncom: splicing in a whole form

12:53 hyPiRion: ,`[~@[:unsplicing :lists :and :vectors, :etc]]

12:53 clojurebot: [:unsplicing :lists :and :vectors :etc]

12:54 noncom: i see, thanks! the official docs seem a little scarce on this

12:54 or maybe the problem is that english is not my native language. sometimes i have to ask people of very basic things that are already written somewhere...

13:00 TimMc: noncom: What you'll often see is [... & body] as arugments to a macro, and then ~@body in the macro's own body.

13:01 That allows the macro's caller to have a multi-expression body, useful for side effects.

13:17 hyPiRion: oh great

13:33 shafire: hi

13:33 does anyone know a fastcgi implementation?

13:35 wolfes: shafire: possibly this? http://pepijndevos.nl/the-perfect-server/index.html

13:35 https://github.com/pepijndevos/fastcgi-ring

13:37 shafire: yeah, thanks

13:40 juxovec: /join #ruby

14:13 shafire: wolfes: do you use ring?

14:29 wolfes: shafire: i've just recently started using ring

14:32 shafire: wolfes: which serve-protocol do you use?

14:52 wolfes: shafire: (websocket clients + http api) — http-kit server — ring — compojure is my server's current stack

14:53 glosoli: Hey, I am using nREPL with Clojure mode in Emacs, kinda curious, there is some interesting behaviour I get when I do function calls in nREPL buffer, it shows me at the bottom the parameter I am expected to write for that function call, any ideas how I can get the same behaviour while writing function calls in Clojure code buffer?

14:53 wolfes: shafire: project is here if you want to look at it: https://github.com/wolfes/cmdsync

14:55 zilti: glosoli: That is eldoc-mode.

14:56 wolfes: ^^ is there a plugin that does that for vim?

14:56 zilti: glosoli: add this to your config: (add-hook 'nrepl-interaction-mode-hook 'nrepl-turn-on-eldoc-mode)

14:57 glosoli: zilti: thanks !! :)

14:59 zilti: Argh, macros + dynamic binding seems to be pretty much impossible with clojurescript...

15:01 shafire: wolfes: which ide do you use?

15:12 zilti: Can't "case" handle symbols?

15:13 bbloom: ,(case 'y x 1 y 2 z 3)

15:13 clojurebot: 2

15:13 bbloom: seems to work :-)

15:14 zilti: ,(case (symbol "a") (symbol "a") :a (symbol "b") :b)

15:14 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate case test constant: symbol>

15:19 hyPiRion: ,(case (symbol "a") a :a b :b)

15:19 clojurebot: :a

15:19 hyPiRion: ,(case (symbol "b") (a b c) :foo d :bar)

15:19 clojurebot: :foo

15:38 toxmeister: howdy! quick Q about cljsbuild: does anyone know if the current version supports Closure compiler's property map export? Or more generally speaking, is there a way to pass any other currently unsupported args (by cljsbuild) to the closure compiler?

15:59 H4ns: is @ an operator? i'm looking at the http-kit client documentation and it seems as if @ is used to force a future? any pointer would be appreciated.

15:59 bbloom: H4ns: @x is shorthand for (clojure.core/deref x)

15:59 (doc deref)

15:59 clojurebot: "([ref] [ref timeout-ms timeout-val]); Also reader macro: @ref/@agent/@var/@atom/@delay/@future/@promise. Within a transaction, returns the in-transaction-value of ref, else returns the most-recently-committed value of ref. When applied to a var, agent or atom, returns its current state. When applied to a delay, forces it if not already forced. When applied to a future, will block if computation not complete. When app

15:59 H4ns: bbloom: thanks!

16:01 ivan: ,'@x

16:01 clojurebot: (clojure.core/deref x)

16:04 bbloom: H4ns: ah yes, ivan demonstrates how to solve this problem on your own

16:04 although it can *sometimes* trick you:

16:04 ,''x

16:04 clojurebot: (quote x)

16:04 bbloom: ,'''x

16:04 clojurebot: (quote (quote x))

16:09 zilti: Is there a tool to get from the line in a js-file back to the line in the cljs-file?

16:21 sandbags: anyone here know of a better introduction to Pedestal than the tutorial from pedestal.io wiki?

16:22 kmicu: sandbags: you can try https://github.com/taylorSando/pedestal-todo/blob/master/beginners.md but pedestal-app-tutorial is the best IMHO

16:22 sandbags: kmicu: thanks... that's a shame

16:22 kmicu: no, no shame

16:23 pedestal is like a monad

16:23 sandbags: i'm too tired to tell if that was humour zinging over my head

16:23 kmicu: if you break a barrier, it is very simple (not easy, but simple)

16:25 sandbags: well to each their own

16:25 kmicu: Comparative Literate Programming?! soo sweet

16:26 sandbags: was that a question? a statement? a philosophy?

16:27 zilti: It seems like pedestal is just pretty much a collection of some clojure/clojurescript libraries out there - so what's the point of using it instead of the libraries and losing flexibility?

16:27 kmicu: Excitement for a next blog post by dnolen

16:28 sandbags: zilti: in general there may be value in assembling a set of libraries into an overarching framework, if you select the components well and provide a useful context/glue for them

16:28 flexibility is a two edged sword

16:29 i'm not offering that as a justification for pedestal btw... i've no idea if it's any good or not

16:29 zilti: I looked at their webpage, and there isn't even an API documentation or a proper overview of what's included, so I closed the tab again :D

16:29 Awesome. "Error: Invalid arity: 1". Thanks, ClojureScript, how meaningful...

16:30 kmicu: You can always use elm instead.

16:31 sandbags: zilti: i thought i'd at least try the tutorial ... i think they used the wrong word though

16:31 i believe confusamajig would have been a more appropriate term

16:32 zilti: sandbags: I just don't really have a need for it currently, I'm happy with my plugged-together libraries

16:32 sandbags: i've not settled on a way of building web apps with clojure and thought it looked worth a look

16:37 man what a lot of gobbledegook

16:37 kmicu: it's a monad

16:37 srlsy

16:42 zilti: *sigh* debugging clojurescript is such a pain in the ass...

16:43 especially when macros are involved

16:43 kmicu: and we can improve that with complaining! yey!

16:44 sandbags: kmicu: my guess is that zilti is just looking for a little fraternal acknowledgement that some things are just a pain in the ass

16:44 as someone who has attempted a little ClojureScript I can empathise with him

16:45 either that or we could turn that lense on your own response?

16:59 siscia: I have a weird question: it is possible (if yes how) to get as string the value of a print-dup ?

17:01 (something like this: clj-time.print-dup-test> (def u (print-dup {:a :b} *out*))

17:01 {:a :b}

17:01 #'clj-time.print-dup-test/u

17:01 clj-time.print-dup-test> u

17:01 #=(clojure.lang.PersistentArrayMap/create {:a :m})... )

17:02 bbloom: siscia: bind *print-dup*, then use with-out-string

17:05 siscia: wonderful, thank you so much

17:15 bosie: whats the proper way of handling access control for users in clojure?

17:15 i could hardcode with if-elses and hardcode getting the data to evaluate the if-elses... but...

17:17 siscia: ?

17:18 bosie: siscia: for example, in a routine i do things differently depending on the state of the user

17:19 siscia: multimethods ?

17:19 bosie: siscia: if the user logged in in the last 4 weeks and has 5 documents up, i do ABC. if its the first time, i do BCD. in another method its about payments

17:20 siscia: hm. thought more about core logic to be honest

17:20 siscia: bosie, humm... let me think...

17:22 bosie, you have some "state" (like logged in in the last 3 days and n documents is the sate A, or first time is the state X, or no document is the state C)

17:22 you have to define in what state is the user somehow

17:22 bosie: siscia: technically i can (and will) have a lot more states

17:22 siscia: and then i combine those states

17:23 siscia: bosie, ok, but my point is another...

17:24 bosie, you first define the state of your user and then you apply the right function

17:24 bosie: siscia: correct

17:24 siscia: now the question is how ;)

17:24 siscia: bosie, how you define the state is your real problem

17:25 bosie, (how you apply the function I will just use multimethods, IMHO

17:25 bosie, (how to apply the right function I will just use multimethods, IMHO

17:25 zilti: I have this one-line macro that fails me... https://www.refheap.com/17507 Can anyone tell me what's wrong with it?

17:25 bosie: siscia: i dont see how

17:26 siscia: even if i define nested states, i have say 100 states. in one particular function i chose 6. one of the 6 is valid on a particular user.

17:29 siscia: bosie, (defn get-state [user] (vodoo-magic-here)) (defmulti function get-state) (defmethod :state-a [user] (f user)) (defmethod :state-b [user] (g user))

17:29 bosie: siscia: well. get-state should be what though?

17:29 siscia: if get-state has another if-else ... it kinda defeats the purpose

17:30 siscia: bosie, well, this depends on your data...

17:30 bosie, one way could be to use logic.core

17:31 bosie: siscia: e.g. if profit > 10000 and currently 12 items in the store ELSE IF no sold item ELSE IF no item in store ELSE...

17:31 siscia: bosie, another could be match.core

17:31 bosie: with your method (and correct me if i am wrong) you are basically pushing the if statement into the get-state, no?

17:32 siscia: bosie, https://github.com/clojure/core.match

17:32 bosie: yup

17:32 siscia: bosie, yeah, you can see it like that...

17:34 bosie: siscia: prolog-like sounds interesting

17:34 siscia: bosie, you mean the core.match ?

17:34 callen: bosie: didn't you do golang before?

17:34 bosie: callen: no, have never looked at golang. why?

17:35 siscia: no, the other one you mentioned: https://github.com/clojure/core.logic

17:35 siscia: just realized that logic.core isn't core.logic most likely ;)

17:35 callen: why?

17:35 callen: R, ruby, java for me

17:35 callen: bosie: your nick is the same as somebody who was briefly prominent in that community.

17:35 wrote web stff for golang.

17:35 stuff*

17:36 bosie: callen: i wish i was prominent in ANY language really. but no :/

17:36 bbloom: bosie: just start making stuff :-)

17:36 bosie: bbloom: indeed. so easy ;)

17:37 callen: bosie: no really, that's what Raynes did for the most part.

17:37 bbloom: bosie: it is! you surely make stuff all the time. half your hacker news and reddit intake, then refocus that extra time on a little thinggie to make. and if it's neat, polish it up and ship it

17:37 callen: bosie: I'm making a defense library for Clojure right now.

17:37 bosie: bbloom: ouch

17:37 bbloom: do that 5 to 10 times & you'll be "prominent" :-)

17:37 callen: bbloom: and what time you do spend on HN and Reddit, spend it posting your libraries and explaining them.

17:38 bosie: callen: defense?

17:38 callen: i actually block HN and reddit now

17:38 callen: bosie: you're a rubyist so you should understand the analogy - "Rack::attack"

17:38 bbloom: bosie: i just assume everyone who isn't prominent somewhere spends too much time on some site. b/c that was m problem :-)

17:38 s/m/my

17:38 bosie: callen: ok

17:38 callen: bbloom: or vidya games.

17:38 bbloom: yeah, that too

17:38 zilti: I have this one-line macro that fails... https://www.refheap.com/17507 Can anyone tell me what's wrong with it?

17:38 bosie: bbloom: and now you are prominent?

17:39 bbloom: *shrug* i'm at least not anonymous

17:39 bosie: bbloom: well done ;) what you prominent for?

17:39 gfredericks: he concatenates

17:39 bbloom: gfredericks: heh :-)

17:39 callen: bosie: he's really into trees.

17:39 er, branches.

17:40 * bbloom is saddened to discover a github user with handle bbloom… mine is brandonbloom

17:40 siscia: zilti, replacer is suppose to be a macro ?

17:40 zilti: siscia why, should it? It's just a helper function called from the macro

17:41 siscia: zilti, I have never seen before ~@ inside a function...

17:42 replacer form itself works ?

17:42 zilti: Yes

17:42 It does exactly what it is intended to do

17:42 siscia: (defn replacer [table f]

17:42 (if (list? f)

17:42 (case (first f)

17:42 form `(apply ~sform ~table [~@(rest f)])

17:42 field `(apply ~sfield ~table [~@(rest f)])

17:42 f)

17:42 f))

17:42 opss, sorry

17:42 anyway, nope

17:43 that function does not even compile

17:43 bosie: bbloom: Brandon Bloom Consulting. how is that treating you if i may ask

17:43 bbloom: msg me if you're interested in hiring me :-P

17:43 bosie: bbloom: hah yea no

17:43 zilti: here it does compile

17:43 callen: siscia: please use Refheap next time you need a paste.

17:43 bosie: bbloom: mostly because i have no work. otherwise you would be my topchoice ;)

17:44 siscia: callen, sorry it was a mistake

17:44 zilti, honestly, where in the scope of such function is defined ~sform ?

17:45 callen: siscia: s'okay. jus' sayin'

17:45 bhauman: zilti: I don't see how replacer can work as defined

17:45 zilti: siscia sform is a variable in the same namespace that contains a (fn ) form, but that is not even relevant here

17:46 siscia: zilti, that makes sense... anyway, the use of form such as ~ ` and ~@ inside a function is beyond my knowledge...

17:46 zilti: siscia Try to "(replacer "test" '(form "asdf" "qwertz"))"

17:47 ~ ` and ~@ work exactly the same inside a function as they do inside a macro

17:47 clojurebot: is there a function that is somewhat similar to partition, except that it creates a max number of groups based on a number

17:48 gfredericks: clojurebot: no

17:48 clojurebot: no is tufflax: there was a question somewhere in there, the answer

17:49 siscia: zilti, sorry but I don't get it, what is the point of ~@ inside a function ?

17:50 zilti: siscia what's the point of ~@ inside a macro?

17:50 hyPiRion: both ~ and ~@ are just syntactic sugar, which isn't strictly speaking needed in Clojure

17:51 Same applies to [], {}, #{}, @, etc.

17:51 (Granted, it would be a bit harder to work with)

17:51 bbloom: hyPiRion: actually, the collection syntax is subtly different than the ~ and ~@ syntax

17:51 zilti: Anyway, I just found out how it works: (defmacro with-table [table & body] (prewalk (partial replacer table) `(quote ~body))) Though that looks like a very ugly hack

17:52 bbloom: hyPiRion: ~ and friends are really just sugar, but the data structure literals are self-evaluating and encapsulated, such that you can pass them through to macros, for example

17:52 kmicu: one big hacky nonidiomatic hack

17:52 bosie: siscia: thanks

17:53 zilti: Though that's the only solution I could find for that

17:53 siscia: bosie, :)

17:54 hyPiRion: bbloom: Well, yeah. Perhaps I should be a bit more careful saying "just" syntactic sugar.

17:54 siscia: well, this is the first time that I see such sugar inside a function...

17:57 kmicu: We must go deeper inside a function, Mr. Cobs. - Are you talking about syntactic sugar?

17:59 siscia: kmicu, I am ? Yes...

18:00 kmicu: It is not real. It is a one big hack. We must wake up!

18:02 siscia: still I am curious how it can work...

18:03 zilti: ,((fn [x] `(1 ~x 3)) 2)

18:03 clojurebot: (1 2 3)

18:04 callen: hrm. multi-arity macros. hrm.

18:05 zilti: hmm what could cause a "java.lang.IllegalArgumentException: No method in multimethod 'emit-constant' for dispatch value: class clojure.lang.LazySeq"?

18:06 callen: so probably not.

18:08 siscia: zilti, you are probably using too many macros...

18:08 zilti: I'm using exactly one

18:09 siscia: I guess it happen something like: (emit-constant clojure.lang.LazySeq)

18:09 zilti, where clojure.lang.LazySeq is the class itself... not sure about though...

18:11 zilti: ...hmm now the error just disappeared

18:11 lgs32a: are there good reasons to learn haskell when you are a happy with clojure? asking those who came to clojure from haskell.

18:12 callen: lgs32a: I technically learned some Haskell before Clojure

18:12 lgs32a: I say technically, because I'm not convinced any one person truly "knows" Haskell except for SPJ

18:12 lgs32a: haha

18:12 callen: lgs32a: Haskell will force you to learn things that Clojure merely makes "available"

18:12 siscia: lgs32a, good question...

18:12 callen: it also has a way of reifying types and making you think in terms of types that can be very education

18:13 I would never ever use Haskell to actually *make* anything, but it's excellent for learning.

18:13 Clojure makes most of the same FP niceties available (modulo core.typed), but I can actually enjoy making useful things.

18:14 siscia: haskel : clojure = C : python ???

18:14 lgs32a: what i am interested in to go more deep in terms of function composition

18:14 lazybot: siscia: Oh, absolutely.

18:14 callen: lgs32a: Haskell does a lot more than function composition, haha

18:14 you'll be writing monad transformers in like a week

18:14 bbloom: monad transformers *cring*

18:14 callen: I see bbloom knows my pain

18:15 bbloom: callen: http://lambda-the-ultimate.org/node/4786

18:15 lgs32a: hm. what is the clojure equivalent to a monad transformer?

18:15 bbloom: lgs32a: side effects.

18:15 lgs32a: mhm

18:15 callen: lgs32a: I'll tell you what man, I think Clojure is a practical choice and that Haskell's a good way to learn. If you want to learn, go forth and learn, If you're happy with Clojure, that's cool too. I could even give you some ideas for things to explore in Clojure that cover some of the territory Haskell covers.

18:16 speaking of side effects, I just got done making my CMS in Clojure side-effect free.

18:16 it's an improvement, but I have more macros to write to cleanup Compojure stuff.

18:18 lgs32a: ok

18:18 callen: well more accurately, thread-local state free

18:18 lgs32a: my motivation would basically be to learn about monads, functors and arrows

18:18 callen: but it's all immutable data getting passed around

18:18 lgs32a: you can do those in Clojure, but Haskell will teach them far better.

18:18 because it won't allow you to fuck up.

18:18 The compiler will fwack you in the head with a wiffle bat until you "get" it.

18:19 lgs32a: yeah i have played around with haskell a bit before i came to clojure

18:19 callen: I don't think there's much more to be said here. Learn it or don't.

18:19 Nobody's going to push you out of the nest. Do as thou wilt (shall the whole of the law...)

18:19 lgs32a: hehe

18:19 thank you for sharing experiences

18:20 callen: apropos: http://www.willamette.edu/~fruehr/haskell/evolution.html

18:20 lgs32a: :)

18:21 callen: bbloom: I want to like this, but so many EDSLs in Haskell have turned out to be the puzzle box from Hellraiser.

18:22 lgs32a: haha that link is quite entertaining

18:22 bbloom: callen: IMO, haskell requires at least a dozen compiler extensions to reasonably incorporate the last 20+ years of research. w/ SPJ stepping down, it's time for some new attempts. effect systems are gonna be the next frontier

18:23 10+ languages will show up wit ever more powerful effect systems & then some committee will make the next haskell-ish language

18:23 callen: bbloom: the amount of effort it takes just to catch Haskell up with the last 50 years of (not types) compile-time metaprogramming is absurd

18:23 and the result is vomit inducing.

18:24 I'd rather take a circular saw to my taint than figure out broken Template Haskell again.

18:24 bbloom: once again oleg & friends got you covered: http://okmij.org/ftp/meta-programming/index.html

18:24 callen: the Haskell community is collectively a useful idiot to steal nifty things from.

18:24 bbloom: see MetaOCaml & MetaHaskell

18:24 yeah, that's basically how i view haskell

18:24 the fact that anyone runs it in production is entertaining to me :-P

18:25 callen: Haskell is all about "coulda" not about "shoulda"

18:25 secondarily, it proves my ongoing point that just because you technically can do something, if it's painful, nobody will bother.

18:26 lgs32a: i must say when i came from c++ to play around in lisp the typelessness was a relief

18:26 callen: when I was actually a CL user, I would've killed for const correctness

18:27 now that just comes basically for free with Clojure without any real effort.

18:27 lgs32a: also true

18:27 i never thought about it

18:27 but its gone

18:28 callen: learning to constructively think with types, especially in something like Haskell, can be transformative to how you model software

18:28 especially since it's not a shitty dumb nominative type system, it can be used to represent generic "structure"

18:28 lgs32a: yeah i will certainly check out more haskell in my free time

18:28 just to keep the head spinning

18:29 callen: I would kill for an earthquake that didn't crash.

19:26 coventry`: *ns* and (all-ns) aren't working for me in the pedestal cljs repl. Is that the right way to interrogate namespaces in clojurescript?

19:27 callen: (dec coventry`)

19:27 lazybot: ⇒ -1

19:27 callen: for using pedestal.

19:28 coventry`: Well, I am just learning it, not actually using it at this stage. I am very interested in hearing any objections to it.

19:29 callen: over-complicated, bunch of breaky magic that doesn't make very much sense, contributes little to no value to typical web apps, splits client-side and server-side in a *really* annoying way.

19:29 bunch of complexity for net-negative return on investment.

19:32 coventry`: Thanks. I'm going to keep working through the tutorial because I'm actually learning a lot from it, but I can see a plausible case for some of what you say. (The rest I'm too ignorant to assess.)

19:33 I'm still interested in the way to interrogate namespaces in clojurescript, too.

19:33 dnolen: coventry`: I would ignore callen and come to your own conclusions about pedestal. as to namespaces, many REPL niceties are missing in CLJS - mostly because no ones really worked on it.

19:34 callen: coventry`: I don't use Luminus directly, but it's a good representation of good Clojure web practices. Compare and decide for yourself.

19:34 dnolen: I didn't say not to come to your own conclusions, just that using it is a bad idea if you want to ship.

19:35 coventry`: Gotta run, will be back in 20 min or so.

19:39 chord: why should I use clojure over haskell which is statically typed

19:40 callen: chord: you shouldn't. Haskell all the way bro.

19:40 chord: so you use haskell over lisps

19:40 callen: yes I use the Haskells all the times.

19:40 chord: you making fun of me?

19:40 callen: I use the haskells in beds, in the showers, and in the offices.

19:40 chord: no, Haskells is serious businesses.

19:40 wolfes: (inc callen) ; thanks for the advice last night, I replaced aleph with http-kit server and things make much more sense after getting farther into the docs :)

19:40 lazybot: ⇒ 1

19:40 callen: wolfes: <3

19:41 chord: so why are you in this channel i nstead of haskell

19:41 callen: chord: to save people from the sins of dynamic typing.

19:41 wolfes: I actually just got done fixing up my CMS to not use thread-local state so that it could be http-kit compatible.

19:42 I ended up writing a nifty macro that captures enclosing fn data into the rendering function so that I don't have to manually chain the request data.

19:42 wolfes: callen: awesome! is it somewhere visible that i can look at?

19:43 callen: wolfes: have a ball: https://github.com/bitemyapp/neubite/

19:43 I put it up so that people could see a practical Luminus-esque web app.

19:43 wolfes: callen: thanks :) what's the macro called?

19:43 callen: with auth, database access, and a basic CMS

19:43 wolfes: render-template

19:44 chord: so you think haskell is the best statically typed functional language?

19:45 callen: chord: I think the haskells is the best programming languages evers mades.

19:45 chord: all true hackers write Haskells.


19:45 callen: I'm not making funs, the Haskells are the way and the light

19:46 in fact, if I were making funs, I'd be writing Erlang!

19:46 http://www.erlang.org/doc/programming_examples/funs.html

19:46 see ^^ funs! Being made!

19:46 dnolen: chord: callen an be trollish, best to ignore him until your more familiar w/ his communiation style.

19:46 callen: dnolen: chord's actually been trolling this channel for over a week

19:46 dnolen: and constantly asking about Haskell

19:47 chord: callen making up shit now

19:47 callen: dnolen: he also privchat'd me ~8 days ago to ask me perverted questions about my sexuality and insult me.

19:47 chord: I have logs d00d.

19:47 chord: I can fabricate logs too

19:47 callen: dnolen: I'm just back-trolling. I was initially polite.

19:47 chord: there are public logs that don't belong to me.

19:47 chord: so you admit the private msgs were all madeup?

19:48 callen: no, they happened, but I can prove part of what I said.

19:48 that you're even trying to debate it in this manner proves my point.

19:48 you're a troll.

19:49 Bronsa: callen: just /ignore him

19:50 callen: Bronsa: I'd rather prevent him from wasting anybody else's time

19:50 Bronsa: by cherry-picking him, I rescue other people from taking him seriously

19:50 chord: you can't stop me from using haskell

19:50 callen: because I'd rather play linebacker than see other peoples' time wasted.

19:50 chord: I wouldn't dare - you should use the Haskells.

19:51 Bronsa: this I must do in the absence of any real moderation.

19:51 Bronsa: keep up the good fight then.

19:51 bbloom: callen: you're fighting ICBMs with antiballistic missiles. Have you considered diplomacy? It's much cheaper in the long run.

19:52 callen: bbloom: sociopaths can't be reasoned with.

19:52 bbloom: chord's not the only one, there's a sex offender that frequents this channel and wastes peoples' time with idle speculation all the time.

19:52 I hijack him when he starts misbehaving too.

19:53 chord: omg how can you compare me to a sex offender

19:53 bbloom: not everybody is fond of your policing tactics

19:54 callen: bbloom: my parents had a rule where if I let my room get too messy, they got to make it clean with the indiscriminate use of garbage bags.

19:54 I wouldn't have to lift a finger otherwise.

19:54 bbloom: nobody is interested in your family's parenting tactics either

19:55 believe me, the folks in this room can handle a troll without counter-trolling. especially without your particular brand of it

19:55 callen: I can leave chord alone, but the sex offender I'm not going to stop driving off.

19:55 also aforementioned just privchat'd me about my parents abusing me. lol.

19:56 wolfes: callen: nice render-template macro :)

19:56 callen: wolfes: thanks, it's not really hygienic but works fine in the presence of a contract that the request must always be available.

19:57 wolfes: nod

19:57 callen: wolfes: I'm writing a macro to clean up the repetitious Compojure routes right now.

19:57 which will also serve to make the contract moreautomatic.

19:58 bbloom: http://i.imgur.com/KFR6caY.png

19:58 (my server is UTC)

19:59 wolfes: what do you see as repetitious about compojure routes? (I've only needed 2 routes so far and haven't gotten to the point where i could experience this)

19:59 callen: wolfes: ...did you look at the routes in admin?

20:00 wolfes: looking

20:00 callen: maybe I have a high standard for brevity and clarity but: https://github.com/bitemyapp/neubite/blob/master/src/neubite/routes/admin.clj#L100-L111

20:00 wolfes: no need, I highlighted for you ^^

20:00 wolfes: only about 30% of that is unique, useful information

20:00 the information density of the code sucks, it's not DRY

20:00 wolfes: callen: ahhh wow

20:01 zilti: callen isn't that what routing/context was made for?

20:01 callen: zilti: context isn't nearly powerful enough.

20:01 I want to bake it down to :preprocess [superuser-only] and (GET "route/blah" handler)

20:01 zilti: I have used context in the latest version of the CMS to clean up *some* of it, but it's not good enough.

20:01 chord: callen: all those remarks I made were true

20:02 callen: chord: so you admit you're an abusive troll.

20:02 dnolen: bbloom ^^ see?

20:02 chord: YES

20:04 coventry`: dnolen: Thanks for the cljs ns tip.

20:12 chord: lets talk about clojure vs python/ruby

20:15 dnolen: callen: ok, you were right

20:17 chord: are you we going to compare clojure to python?

20:25 coventry`: Just going on the example application in the Luminus documentation, I get the impression that pedestal designed for different kinds of apps with more complexity in the client behavior.

20:25 callen: Luminus is agnostic about client-side.

20:25 works fine for everything from a heavy CLJS frontend app to a purely static website.

20:25 the point is explicitly not to do a heavy framework

20:25 No magic.

20:26 which, I sorta thought the community collectively figured out how after we ditched Noir but nobody told Relevance apparently.

20:26 at least you can extract liberator out of it.

20:27 coventry`: The heavy-framework aspect of pedestal does worry me.

20:28 callen: it's not just that, that is why I'm so negative about it

20:28 I understand when a heavy framework or the added magic/complexity is necessary

20:28 but you NEED a big win to justify it.

20:28 Pedestal has very little to show for itself.

20:28 I'm pragmatic, I can be convinced that composing libraries might not make sense in some case.

20:28 but Pedestal just isn't worth it.

20:30 Raynes: MongoDB and Erlang were never going to end happily.

20:30 Raynes: This is pretty pathetic.

20:30 Admittedly.

20:31 callen: my twitter reply sums up the matter handily I think.

20:31 * Raynes rolls his eyes so hard he sees brain.

20:31 callen: Raynes: to be fair, I use MongoDB too.

20:32 I too, have data I do not care about losing.

20:38 BufferUnderpants: Hello

20:38 callen: BufferUnderpants: soup.

20:38 BufferUnderpants: I'm having trouble doing lein cljsbuild

20:39 It complains about my namespace definition

20:40 java.lang.AssertionError: Assert failed: Only :refer-clojure, :require, :require-macros, :use and :use-macros libspecs supported

20:40 (#{:import :use-macros :require-macros :require :use} k)

20:41 dnolen: BufferUnderpants: paste your offending ns expression somewhere

20:41 BufferUnderpants: It doesn't tell =/

20:41 I have a bunch of requires of the form (:require [clojure.string :as string])

20:42 That's allowed, right?

20:43 Ah, hold on

20:44 Didn't read the fine print, I can't use a naked :use

20:44 Also, can I reference the classes that would normally be generated by defrecord?

20:45 e.g. (defmethod frobnicate my.namespace.FancyRecord […] …) ?

20:46 dnolen: BufferUnderpants: yes you can, but my.ns/FancyRecord is more idiomatic

20:46 BufferUnderpants: Alright, thanks

20:52 TimMc: BufferUnderpants: my.namespace.FancyRecord uses the JVM package and class names; my.ns/FancyRecord uses the Clojure namespace names.

20:52 The big difference is that - turns into _ for packages and classes.

20:53 callen: dnolen: why not make the worrydream style thing you want? I could build an interactive post creator into my CMS.

20:53 dnolen: callen: maybe eventually get there - it's not a small amount of work

20:55 callen: dnolen: I don't know the full extent of the thing you're talking about, but I could do in an evening with my CMS.

20:55 BufferUnderpants: @TimMc: oh, thanks, I had actually encountered the discrepancy in names, I hadn't thought that it was because of that

20:56 callen: dnolen: you mean being able to interact, test, and execute referenced code in the blog post and see output in another column dynamically right?

20:57 dnolen: callen: that plus, the tangle functionality - also present in LightTable

20:58 to some degree

20:58 callen: 'fraid I don't know the tangle bit, but blog post REPLs can be a thing in short order.

21:24 TakeV: Silly question, but is there actually a function to remove an element from a vector? I can't seem to find the appropriate one in any of the docs...

21:27 dnolen: TakeV: no such function exists - in the future probably possible with RRB-Trees

21:42 TimMc: TakeV: You can remove an element from the end, though.

21:51 TakeV: Hmm. Not exactly what I need at the moment. I guess I'll just concat two subvectors.

21:55 Actually, is there any downsides to just concating two subvectors of the same vector so it's the original minus the element I want?

21:57 bbloom: (doc subvec)

21:57 clojurebot: "([v start] [v start end]); Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done."

21:58 bbloom: notice: "no trimming is done"

21:58 TakeV: I'm not sure what that means.

21:58 bbloom: it means that a subvector is a "view" of a full vector, such that holding on to the sub vector holds on to the full vector

21:58 no garbage collection of items outside the view of the sub vector can occur

21:58 TakeV: Ah...

21:59 bbloom: if you call concat & get back a lazy seq, then you have linearly copied

21:59 but you have a seq, so you need to vec on that to get back to a vector

21:59 luckily! there are rrb-vectors: https://github.com/clojure/core.rrb-vector/

21:59 TakeV: Hmm, perhaps using for to copy it except for the element...

21:59 Or that. >_>

22:00 bbloom: which provide efficient slice and concat with trimming & preserve the vector's asymptotic guarentes

22:00 fuck yeah data structures.

22:00 or

22:00 if you know for a fact that your vector is small

22:01 where "small" depends on how often you need to remove an item from it

22:01 callen: I usually just filter out the element I don't want if it's small/infrequent.

22:01 bbloom: 10 items? 100 items? depends

22:01 yeah, (vec (…. some filtering here …)) gets the job done

22:01 and in fact that's what happens anyway if your vector is < 32 items or something like that

22:02 TakeV: Hmm, is there a function to get the index of the element, then?

22:02 callen: if you do that, you're going to be iterating over it anyway.

22:02 bbloom: clojure tries pretty hard to only give you functions that "make sense" for your data structures

22:02 unlike traditional lisps which just give you lists for everything, whether you like it or not

22:03 you should think more deeply about your requirements & you may find that map or a sorted-set or something works even better for the particular needs you have

22:03 TakeV: This rrb-vector isn't in the core yet, it seems.

22:03 callen: {0 elem 1 lol 2 :dont-do-this}

22:03 doseq (range) ^^ lol

22:04 TakeV: rethink what you're doing.

22:04 TakeV: bbloom: Well, I'm experimenting with making a matrix library, so I'm having a hard time thinking of a better data structure than a vector.

22:04 dnolen: TakeV: it's unlikely it will appear in the standard lib any time soon, but that's not really a problem.

22:04 callen: there are a ton of clojure numerics, array, and matrix libraries.

22:04 TakeV: you should probably use one of those.

22:05 TakeV: callen: It's a learning exercise.

22:05 callen: Incanter has nice wrappers for stuff like this too.

22:05 bbloom: TakeV: how large of vectors? 3x3 and 4x4 and friends? or arbitrary size?

22:05 callen: TakeV: you're going to end up doing some deeply unidiomatic if you don't learn more about how Clojure data structures work and the `why` of it.

22:05 TakeV: bbloom: Arbitrary.

22:05 bbloom: TakeV: do you need sparse matrices?

22:05 TakeV: bbloom: Sparse?

22:06 bbloom: it's probably best to avoid learning about matrix operations & clojure at the same time :-)

22:06 * callen bangs the amateur hour gong

22:06 bbloom: sparse == large stretches of zeros or nils or whatever

22:06 callen: the amateur hour has begun. Dance away people.

22:06 bbloom: callen: stop being a fucking dick.

22:06 i'm trying to help this guy and you're belittling him

22:06 callen: bbloom: http://www.apollotheater.org/amateur-night-history-legacy

22:06 bbloom: I like dancing.

22:07 TakeV: you should pick one thing and learn the one thing at a time.

22:07 TakeV: bbloom: I'm quite capable of ignoring him. I appreciate your help.

22:07 callen: TakeV: if you knew a lot about matrix processing and libraries, then implementing something in Clojure would make more sense.

22:08 bbloom: TakeV: i've finally just /ignore-ed him now

22:08 callen: babies.

22:08 TakeV: bbloom: Anyway, I'm making little assumptions about the matrices, except that they are well formed. Have a precondition set up to check for that.

22:09 bbloom: TakeV: so clojure's data structures are optimized for particular uses & matrix usage is NOT ONE OF THOSE USES

22:09 callen: ^^ don't do what this guy is doing. Implementing a library for something you know nothing about in a language you know nothing about is just going to produce another Rasmus Lerdorf.

22:09 TimMc: callen: No, seriously. Stop insulting people, especially newcomers. It's rude, it reflects badly on the community, and it's rude. Did I mention it's rude.

22:09 callen: TimMc: I'll listen to you because you're nice to me. So okay. I'll act on that.

22:10 bbloom: TimMc: thank you.

22:10 TakeV: bbloom: Yeah, that's actually why I'm doing it. It's a playground project, sharping the ax and all that. I do realize that if I was using python or java or something I could do it in about a couple of hours, but there is a fun challenge here. :P

22:11 bbloom: TakeV: well i guess my point is that you can use deftype (which is a bit advanced in clojure) to create your own data structures

22:11 callen: bbloom: don't thank him or I'll just stop listening on account of you agreeing with him.

22:11 bbloom: it's probably not a great learning experience to bypass clojure's data types

22:12 TakeV: bbloom: Probably not, honestly. The rest of the code is quite idiomatic. Just implementing a "get-minor" function is quite... ugly.

22:12 bbloom: TakeV: *shrug* yeah. Clojure is kinda geared for typical server tasks

22:14 callen: "I'm going to take my bits here and move my bits there"

22:15 TakeV: bbloom: Thank you for your help, and pointing out deftype. This looks perfect for what I need.

22:15 callen: TimMc: also did you miss the mess earlier or what?

22:16 bbloom: good luck!

22:20 TimMc: callen: What mess?

22:23 BufferUnderpants: Uh, another Clojurescript question: are macros supposed to go in separate Clojure files, or am I missing something?

22:29 bbloom: BufferUnderpants: yes

22:29 BufferUnderpants: macros are written in clojure, not clojurescript

22:58 coventry`: In the pedestal cljs-repl, how do I gain access to the functions configuring the app? For instance, if I try ((ns tutorial-client.rendering), I do not seem to end up with a render-config function (I get a backtrace saying "Cannot call method 'call' of undefined."

23:29 I am tampering with the pedestal tutorial app to try and understand it. I'm at tag v2.0.14. I would think that changing the (constantly {}) map in rendering.cljs/render-config to {:my-counter "0" :other-counters {"abc" "0" "xyz" "0"}} would result in the other-counters div of the template being displayed. Why is this not the case?

23:45 blr: given friend has no equivalent of sandbar's stateful-session, does anyone have any suggestions for managing state across api requests? I could drop my data into H2 perhaps?

Logging service provided by n01se.net