#clojure log - Nov 11 2014

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

0:03 technomancy: also relevant http://en.wikipedia.org/wiki/Chinese_room

0:06 rritoch: technomancy: That is very cool, I'll need to review that in more depth, it is the first I've seen it but it looks like it can help with my work

0:06 justin_smith: sm0ke: rritoch: evolutionary programming (creating random configurations of input, varying them by some scheme, scoring them, varying the highest scoring results) was the method that was used to make the first (only?) successful malbolge programs. It was a system writting in common lisp.

0:07 malbolge was designed to be impossible to program in, but a lisp program was able to solve "hello world" and "99 bottles of beer" where humans failed

0:08 rritoch: justin_smith: Nope, IBM just made one, lets see if I can find it

0:08 justin_smith: wat

0:08 how is that a response to what I said?

0:08 rritoch: http://www.ibm.com/smarterplanet/us/en/ibmwatson/what-is-watson.html

0:08 justin_smith: rritoch: that has nothing to do with what I was talking about

0:09 rritoch: justin_smith: IBM hasn't exactly open-sourced their technology, but as far as I can tell the watson system is doing exactly what your stating

0:09 justin_smith: rritoch: you do not understand what I said

0:09 malbolge is a pathological vm, designed as a joke

0:10 a lisp program, by a separate author, was able to "solve it" using evolutionary programming

0:10 where no human was able to solve it

0:10 I gave this as an example of a successful genetic algorithm

0:13 rritoch: justin_smith: Evolutionary programming has many practical applications, but rarely are companies willing to fund it. The most common use I've seen is schedule generation.

0:14 http://www.codeproject.com/Articles/23111/Making-a-Class-Schedule-Using-a-Genetic-Algorithm

0:15 justin_smith: But yes, you can achive calculations with genetic algorithms that are impossible for a human to perform

0:15 justin_smith: rritoch: yeah, stuff like simulated annealing is well suited to ridiculously large search spaces

0:17 godd2: I wrote a little evo-sim in ruby with little tanks that shoot at each other. It will be fun to learn enough Clojure to reimplement it. https://github.com/nicklink483/combat

0:23 rritoch: godd2: For projects like that Clojure should have an official "projects" page like Pike does... http://pike.lysator.liu.se/applications/

0:24 I've learned of a lot of clojure apps in this chatroom that I never would have found otherwise, many of which should probably be maintained in an official list to help those starting out

0:24 godd2: Clojars?

0:25 justin_smith: rritoch: clojure tends to be used more for server side stuff, rather than end-user applications

0:26 rritoch: justin_smith: I'm using it for an end-user application, for extremly high-profile customers

0:27 godd2: "tends to be"

0:27 justin_smith: for every person who has mentioned an end user app in here, I think there have been 10 people mentioning some back-end service (usually http)

0:28 and it seems like most of the end-user stuff is clojurescript

0:29 rritoch: justin_smith: That is normal for an emerging technology, very few languages where developed from the ground up with end-user applications in mind, C/C++ and Pascal are the only ones I can think of that fit that category

0:30 technomancy: tcl and elisp... maybe factor.

0:31 justin_smith: visual basic!

0:31 javascript

0:32 technomancy: technically java was designed for set top boxes originally, but that probably doesn't count.

0:32 justin_smith: yeah, I was just considering that

0:33 bourne shell would almost count

0:33 minikomi: maybe racket

0:33 justin_smith: where the end user is a beginner programmer, in that case

0:34 R, for end users who do statistics

0:35 similarly the various computer algebra systems for folks who do math

0:35 matlab / octave / mathematica

0:35 godd2: derive

0:35 justin_smith: coq

0:36 minikomi: kdb / q

0:36 rritoch: justin_smith, R, matlab, octave, and mathematica are all for research and development purposes, they're not often used by end users, the output from them are often delivered to end users though, but that doesn't really count.

0:37 justin_smith: I consider scientists/mathematicians to be end users - they certainly aren't good programmers for the most part

0:37 engblom: Coming from Haskell background, I miss very much the official lists of applications of libraries

0:37 justin_smith: engblom: you know about clojars, right?

0:37 engblom: justin_smith: No, I do not know more than that lein pulls down from there

0:38 justin_smith: https://clojars.org/projects

0:38 it's a veritable firehose

0:38 engblom: Clojars seems to be the equivalent of Hackage.

0:39 justin_smith: is there a "popularity" listing?

0:39 godd2: Seems like Clojars could benefit from showing off metrics like total downloads and recent library activity

0:39 rritoch: justin_smith: What I mean is there needs to be a "sane" list of completed end-user applications

0:39 justin_smith: engblom: http://crossclj.info/ cross-references lib usage, which is a useful metric

0:39 godd2: Oh it does the first, but only when you look at the library in detail

0:40 minikomi: there’s http://www.clojuresphere.com/ as well .. but hasn’t indexed since feb this year..

0:40 justin_smith: rritoch: there are very few end user applications written in clojure, as I said

0:40 engblom: What I am missing for Clojure is this: https://www.haskell.org/haskellwiki/Applications_and_libraries#Haskell_applications_and_libraries

0:40 TEttinger: $google clojure toolbox

0:40 lazybot: [The Clojure Toolbox] http://www.clojure-toolbox.com/

0:40 justin_smith: engblom: clojuresphere is close to this too http://www.clojuresphere.com/

0:40 engblom: There you click on "Web, Html, XML" and you get relevant libraries with some comment on what they do.

0:41 justin_smith: engblom: I think clojure toolbox, as TEttinger mentions, is close to that

0:41 godd2: hey technomancy where would I submit a feature request for the clojars site?

0:42 TEttinger: clojure toolbox doesn't have comments, but it does pretty much only have often-used libs

0:42 justin_smith: godd2: it has a github repo https://github.com/ato/clojars-web

0:42 engblom: Yep, clojure-toolbox is what I have been missing!

0:42 technomancy: godd2: is it something you would submit a patch for?

0:43 engblom: If only some comments on what each library do would be added, it would be pretty much perfect

0:43 godd2: technomancy Yeah I suppose I could. Can I just submit a pull request to the repo?

0:43 justin_smith: engblom: I think the cross-reference "who-uses-what" info on crossclj.info is a good supplement to that

0:43 gives a good idea of what likely is usable, well updated

0:43 technomancy: godd2: yeah, but if it's going to be significant work it might be best to get feedback on the clojars-maintainers mailing list; it's on google groups

0:43 godd2: okay awesome thanks

0:45 technomancy: trying to think of end-user clojure applications that aren't development tools

0:45 justin_smith: yeah, pretty much zilch unless you count cljs websites

0:45 minikomi: hmm.. how about quill or overtone? they’re still code based but in a different way..

0:46 justin_smith: that's true, I could see counting those

0:46 minikomi: Also, https://nightweb.net/

0:46 technomancy: minikomi: all three designed around writing code

0:46 oh, sorry

0:46 nightweb is not nightcode

0:46 justin_smith: in that sense, incanter - even if used from a repl, is in some cases an end-user tool rather than a lib

0:46 minikomi: yeah, same dev i believe

0:47 technomancy: ironic that the only non-dev clojure application is an android thing, which clojure is admittedly terrible at

0:47 minikomi: indeed..

0:47 engblom: Is Android Quill made with Clojure?

0:47 minikomi: is it a pain to distribute to end users perhaps?

0:47 engblom: Or is there any other Quill?

0:48 technomancy: maybe it's because if you're writing an application in clojure it seems like a shame not to let users write clojure too =)

0:48 justin_smith: minikomi: I think part of this is cultural - the folks who really go for clojure are less often the folks to be excited to make UI / end-user apps I think

0:48 technomancy: hehe, that too

0:48 minikomi: let’s say I want to make an app which someone can just download, double click, use.. what are my options for clojure?

0:48 justin_smith: perhaps end-users are too mutable for our delicate sensibilities

0:49 minikomi: let’s say restriction to a platform is ok

0:49 justin_smith: minikomi: seesaw for the UI is probably worth checking out

0:49 minikomi: not too hard to make a click+run jar

0:49 minikomi: will the end user get scary java popups and such?

0:49 justin_smith: java is so platform-independence focused, a non-portable app may be harder to make than a portable one

0:49 minikomi: no, that's only for web applets

0:50 don't make web applets

0:51 minikomi: OK. might be worth looking through https://github.com/search?q=%22seesaw.core%22&type=Code&utf8=%E2%9C%93

0:51 technomancy: justin_smith: you get a weird java popup on macosecks though the first time you run it

0:52 because you have to agree to the eula

0:52 justin_smith: technomancy: oh, I had no idea

0:52 but that's for java, not a specific app, right?

0:52 technomancy: yeah /usr/bin/jana on a fresh install is this weird wrapper that downloads a JRE on demand

0:52 yup

0:52 TEttinger: I'm working on making a lein plugin that integrates the jre bundler called Packr

0:52 justin_smith: maybe part of why clojure doesn't have end-user apps is because jvm sucks for end-user apps somewhat

0:52 TEttinger: yeah, I look forward to seeing and using that

0:52 (inc TEttinger)

0:52 lazybot: ⇒ 27

0:52 technomancy: Sun Microsystems made its money selling server hardware, go figure

0:53 TEttinger: it's available now, justin_smith but it doesn't work for weird reasons I can't understand

0:53 engblom: Out of curiosity, has anyone made a X window manager (similar to xmonad) in Clojure?

0:53 godd2: I know I don't have any, but how do I see my own current karma?

0:53 TEttinger: https://github.com/tommyettinger/lein-packr

0:53 $karma godd2

0:53 lazybot: godd2 has karma 0.

0:53 justin_smith: engblom: the kind of host interop that would require is a huge pain in the ass

0:53 godd2: coll thanks

0:53 justin_smith: engblom: I started looking into it

0:54 TEttinger: (identity TEttinger)

0:54 lazybot: TEttinger has karma 27.

0:55 justin_smith: engblom: I searched for wms written in java, as a starting point, and the dirth of results was my first bad sign

0:55 *dearth

0:55 technomancy: justin_smith: did you find an X lib written by a guy called frank?

0:55 justin_smith: technomancy: not that I recall, should I have/

0:56 technomancy: I dunno, that's what I found when I looked in 2009 or so

0:56 pretty much the only option on the jvm at the time

0:58 justin_smith: technomancy: oooh, this time I found an intriguing page full of broken links http://escher.sourceforge.net/

0:58 engblom: There seem to be some options nowadays. At least a quick googling for 'java xlib' makes it look like that.

0:58 justin_smith: engblom: right, but none are mature, from what I found

0:59 engblom: Might be :/

0:59 technomancy: X sounds crufty enough that it wouldn't be something you'd do just for kicks

0:59 rritoch: engblom: With a quick google search I found https://github.com/Zubnix/trinityshell which may be helpful, never tried it though.

0:59 technomancy: kind of hard to justify when xmonad exists

0:59 engblom: Well, I will have to continue with xmonad. Even though it would have been fun to have something similar in clojure at least while learning clojure.

1:00 technomancy: but maybe if that's your thing who am I to judge =)

1:00 justin_smith: technomancy: engblom: I did a quick search, and my reasoning was "I could see hacking on this if there were evidence that it had been done well before, but I don't have the energy / motivation to be the first one to do it successfully"

1:01 technomancy: it seems like maybe a good project for someone who has worked with X before but wants to learn the jvm or clojure

1:01 justin_smith: yeah

1:01 hmm - what about doing it via mono? mono obviously has extensive X11 bindings (via gtk or qt likely)

1:02 engblom: I think it is too much for someone wanting to learn Clojure... but modifying it would be perfect for someone learning.

1:02 justin_smith: clj-clr / mono of course

1:02 rritoch: justin_smith: Working directly with the X11 protocol is a nightmare, I've tried it before at a socket level and I quit the project soon after processing a few packets, it is just too big of a project to do without libraries, at least for a normal developer.

1:02 justin_smith: rritoch: yeah, low level X stuff sucks

1:03 I could see taking a wm done in mono, and then bolting on clojure for configuration / runtime behavior

1:03 a nice extensible wm with a repl

1:03 I still miss sawfish sometimes :)

1:04 with a better lisp sawfish could have been so much better

1:04 technomancy: stump isn't so bad

1:06 engblom: I think stump is terrible as it is not dynamical. If I open one app more, I have to manually arrange the windows. If I am closing one, again I need manually rearrange or I will have unused space.

1:06 justin_smith: rritoch: looks like trinity shell is pretty immature, it has no program launcher, and I can't find any screenshots

1:06 technomancy: hm; I don't remember having that problem.

1:07 engblom: My favorite WM are xmonad and dwm.

1:08 justin_smith: i3 is cool because it has a generalized tree of windows

1:08 screens / desktops / frames / panels

1:08 which is something I often wanted until I found i3

1:08 rritoch: justin_smith: Per the docs it's started via java -jar bootstrap-0.0.1-SNAPSHOT-jar-with-dependencies.jar

1:09 justin_smith: rritoch: I mean no launcher for programs inside the wm

1:09 rritoch: justin_smith: I suppose you could just drop that in your init-scripts somewhere

1:09 justin_smith: I mean you need to go to a shell somewhere and type in the name of programs to run them

1:10 it has no menus or launch tool

1:10 rritoch: justin_smith: X11 doesn't work that way, apps "discover" the window manager directly from the X server, but apps don't need to be started with a special app to be aware of the window manager.

1:10 justin_smith: You just launch your apps the same way you always would

1:10 justin_smith: rritoch: I know how x11 works. The documented fact that the wm has no menus or launcher is indicative of how immature the project is

1:11 the way I always would is win-d which brings up my launcher tool

1:11 every wm that is usable at least has a keybinding that spawns an xterm

1:11 at the very least

1:12 technomancy: justin_smith: meh, xbindkeys is what I use

1:12 I mean, I agree it's indicative of immaturity

1:12 justin_smith: technomancy: OK, but it's pretty low hanging fruit as a feature

1:12 technomancy: but I also like "do one thing well, and embed guile while you do it"

1:12 justin_smith: I could do it in like three lines of code if you already have keybinding support

1:13 rritoch: justin_smith: Per the specs it says it's a modular design, I suspect features like that are intended to be added as modules.

1:13 justin_smith: rritoch: and clearly none of those modules exist

1:13 clojurebot: Excuse me?

1:13 rritoch: justin_smith: Though with no one actually using that window manager, there are probably no modules for it.

1:13 justin_smith: right, I was just taking that as an indicator of maturity, not my must-have-feature

1:13 engblom: http://sourceforge.net/projects/jdx/

1:14 justin_smith: engblom: I think that is a fork of gnome

1:14 most of the code is c iirc

1:15 engblom: oh wait, maybe not

1:17 engblom: that looks like the most complete one I have seen so far

1:20 catern: better to write it as a wayland compositor (we're talking about WMs here?)

1:20 justin_smith: catern: yeah - the project that rritoch linked has a wayland target

1:21 catern: are people actually using full wayland systems yet?

1:21 catern: justin_smith: yes

1:22 GNOME's Wayland session and all the GNOMEy applications work

1:22 justin_smith: catern: cool (I tend to use debian, so maybe this will be my reality in a decade or two)

1:22 catern: justin_smith: GNOME Wayland works fine in jessie

1:22 (as long as you're using a free driver)

1:22 justin_smith: OK, I hope it's obvious I was exaggerating a little about the time frame

1:22 sadly I am not using a free graphics driver

1:22 catern: ya :)

1:23 justin_smith: and limiting myself to gnome apps would be - interesting

1:23 does emacs have a version for wayland?

1:24 catern: not yet :(

1:24 justin_smith: I can replace all the other apps I use

1:24 a native windowed emacs is a must have

1:24 catern: oh, you can use X applications on Wayland

1:24 engblom: I would not have much use of a wayland window manager. Quite often I need the remote X ability. For example, someone is calling me and asking me: Does site X work at the school with their browser and firewall? The only way to give a sure answer is to do X forwarding with SSH and test it.

1:24 justin_smith: oh, OK

1:26 catern: XWayland works fine

1:27 justin_smith: hearing that all the kids are using some new windowing system I have never tried definitely makes me feel old.

1:27 catern: nah

1:27 it's not really *too* ready for daily use

1:27 i'm sure some people (GNOME devs) are using it as such though

1:27 justin_smith: so it's only the arch / gentoo folks using it

1:28 ahh

1:28 catern: it's still got minor bugs

1:28 haha

1:28 justin_smith: ∀x -> hasBugs(x)

1:30 ∀𝓍 → 🐛(𝓍)

1:31 (where that unicode is "bug" if you cannot see it)

1:32 catern: ewww

1:32 that's creepy

1:38 rritoch: It's really too bad I've lost all of my CLISP codes, it was on a server that I threw out when I imigrated to Asia, but I had previously written a unix shell in CLISP which would probably be very useful for clojure developers

1:40 I found it very useful to be able to do loops to expand data directly from the command line using CLISP syntax

1:40 godd2: justin_smith well my code is a member of Y not X, so neener neener

1:40 justin_smith: heh

1:44 * engblom was almost going to learn CLISP. Luckily he decided to begin with Clojure despite it is running on JVM.

1:45 rritoch: engblom: Good choice, CLISP is a dinosaur

1:45 godd2: There are other hosts for Clojure out there

1:46 engblom: Java is/was normally like this: Write once, run nowhere. A minor bug-fix version often broke applications written in Java.

1:47 godd2: ClojureCLR uses .Net

1:47 rritoch: I stole the idea for the shell from CLASH, because I didn't like CLASH syntax since it put preference on LISP syntax vs shell syntax.

1:47 TEttinger: clojurescript, Pixie is some kind of PyPy VM thing

1:47 rritoch: If I recall correctly I just added some filters to convert "cmd `(...)" syntax into the syntax CLASH expects.

1:51 That reminds me, is it possible to define subclasses using gen-class? There are some java libraries which have interfaces that require subclasses. Other than writing java wrappers I really don't see how it's possible from clojure.

1:52 justin_smith: rritoch: proxy

1:52 http://clojuredocs.org/clojure.core/proxy

1:52 ddellacosta: yeah, gen-class should be avoided if possible just 'cause of how complicated it is

1:52 rritoch: justin_smith: Hmm, is there an example?

1:52 justin_smith: on that page I linked

1:53 rritoch: justin_smith: I can give an example of a problem... https://docs.oracle.com/javaee/6/api/javax/servlet/FilterRegistration.Dynamic.html

1:53 justin_smith: That's not a lass, it's an interface. There are a bunch of options for that.

1:53 *class

1:54 reify, proxy, defrecord, deftype, and yes, genclass

1:54 or even extend is suitable, sometimes

1:55 though the nested class may make that more complicated...

1:56 rritoch: justin_smith: I don't see a relevant example of the syntax needed to proxy a subclass on that page though, I know I could proxy the FilterRegistration but how would I define the methods for the Dynamic subinterface?

1:56 justin_smith: rritoch: you would include an invocation to proxy in the gen-class invoking namespace, I think

1:57 though with nested classes it may just be easier to use java and make a shim

1:57 rritoch: justin_smith: But proxy returns an object, it doesn't return a class

1:58 justin_smith: I can't just def -Dynamic (proxy ...)

1:58 justin_smith: why can't you invoke proxy in the constructor?

1:59 in order to fill that slot

2:00 and typehint the slot to have that class

2:01 I am not sure though, this is definitely more complex than it looked at first. Clojure deliberately avoids concrete inheritence, and doesn't provide much for it.

2:03 rritoch: justin_smith: As of now I've written this case off as impossible and if I need to implement filtering I'll need to write that code in Java because I simply can't figure out how to do it from clojure

2:03 justin_smith: I tried, without any luck, doing (:genclass (:name foo.bar/childbar)) but it doesn't work

2:04 justin_smith: rritoch: a shim class should not be too hard to do - make the bare skeleton in java, and call clojure code for all the methods

2:14 rritoch: wait, this is a nested interface in an interface right?

2:14 rritoch: justin_smith: Yes

2:14 justin_smith: FilterRegistration$Dynamic

2:14 that's the syntax to specify it

2:15 rritoch: :)

2:15 That sounds about right, I never tried it though

2:16 justin_smith: yeah, I was confused by the "nested class" thing (what, a class inside an interface?) then I realized it was a nested interface (I blame the beer, sorry)

2:16 rritoch: So how would I do that? Implement FilterRegistration$Dynamic, and extend the parent class, then somehow def the child into the parent?

2:16 justin_smith: so yeah, you should be able to extend FilterRegistration$Dynamic as an interface

2:17 rritoch: justin_smith: Well either way, this is a HUGE step forward

2:17 I wasn't able to refrence the subinterface at all so I didn't get anywhere so far

2:18 justin_smith: you can implement a subinterface separately from the interface iirc

2:18 rritoch: Once I'm done with this documentation I'll test it out on the clj-grid-core library where that interface is part of the dependencies.

2:22 justin_smith: so as I was saying before, reify, proxy, deftype, defrecord, and extend all allow making things that implement arbitrary interfaces

2:22 including subinterfaces via the syntax I just mentioned

2:23 in particular, deftype and defrecord define not just one-off instances, but also a class and a constructor

2:24 rritoch: Well, I'll try it, ALL of theServletContext implementations in grid are incomplete as I had no way of implementing these classes which are required return-types for the ServletContext interface.

2:24 It means the difference between having a semi-functional JSP implementation and having a fully functional one.

2:25 It also means back to systems level code I go, lol

2:25 I suspect I"ve entered a bottomless pit

2:26 justin_smith: I don't know about that. If you find a way to use defrecord / deftype / proxy / reify instead of gen-class, it makes things much simpler and easier to implement

2:27 gen-class is one of the hardest to use parts of clojure

2:27 rritoch: This isn't the first time though, when I made my first web platform I had the same thought, that I'd never get out of systems level code, than one day without noticing I was out and never needed to look back.

2:29 justin_smith: Well I really don't need to use any of those constructs at this time, that would be up to the web developer, I just need to produce the classes for them to utilize.

2:30 justin_smith: rritoch: the question is whether you need gen-class. gen-class is the hard to use thing you reach for if those simple options don't work.

2:30 and this matters if your code is going to be modified or extended

2:31 rritoch: justin_smith: Yes, the gen classes are required, in this case you need to gen-class to produce servlet filters

2:32 justin_smith: a record or deftype plus aot could not do it?

2:32 rritoch: The ServletContext doesn't accept filters as an object, it takes them as a class or class name.

2:32 justin_smith: defrecord and deftype define classes

2:33 ,(deftype FOO [x y])

2:33 clojurebot: sandbox.FOO

2:33 justin_smith: ,(class (FOO. 1 2))

2:33 clojurebot: sandbox.FOO

2:33 justin_smith: that's a class, with two slots

2:34 of course in practice you would implement some interfaces

2:35 ,(deftype FOO [x y] Object (toString [this] (str "☃" x " , " y "☃")))

2:35 clojurebot: sandbox.FOO

2:35 justin_smith: ,(Foo. 1 2)

2:35 rritoch: Doesn't defrecord require you to implement every method?

2:35 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Foo, compiling:(NO_SOURCE_PATH:0:0)>

2:35 justin_smith: ,(FOO. 1 2)

2:35 clojurebot: #<FOO ☃1 , 2☃>

2:35 justin_smith: as ooposed to inheriting them?

2:36 *opposed

2:36 rritoch: justin_smith: As much as possible I've only implemented the absolute necessities, and gen-classes handle that well by throwing an exception if a method that isn't defined gets called.

2:36 justin_smith: rritoch: gen-class is the hard way

2:36 it really is

2:37 rritoch: justin_smith: See how many methods you need to define with a defrecord? https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html

2:37 justin_smith: That would take forever, with gen-class I can just implement the ones I need

2:37 engblom: Is (do ... ) only needed in special cases, like for (if ...) if you need to do several things when a condition is true? Is it otherwise OK inside of functions to just add forms after forms without (do ...)?

2:37 rritoch: justin_smith: which is exactly what I've done to reduce development time

2:37 justin_smith: engblom: right, it is for usage inside if or when

2:38 engblom: I tested kibit and it said I had been using unnecessary (do ...). In haskel you always used "do" if you wanted a sequence of code.

2:38 justin_smith: rritoch: so instead you are currently inheriting all of these?

2:39 rritoch: justin_smith: Nope, just leaving them as the default provided by clojure, an exception that the method hasn't been defined

2:39 justin_smith: rritoch: deftype/ defrecord do the exact same thing

2:39 seancorfield: engblom: forget everything you know :)

2:39 justin_smith: you don't implement them, and then get an exception if they get called

2:39 rritoch: justin_smith: I only get that exception IF I try to call one of thoose methods

2:40 justin_smith: exactly

2:40 seancorfield: it feels the same way going from clojure to haskell btw

2:40 justin_smith: rritoch: this is exactly what defrecord and deftype do

2:40 engblom: seancorfield: I can imagine that :)

2:40 rritoch: justin_smith: Well, I wasn't aware of that, but I don't see gen-class as complicated, accept when it comes to handling these subinterfaces

2:41 justin_smith: rritoch: it is complicated because it does not run in code that is not from a file (unless you do complex workarounds)

2:41 it is complicated because deftype and defrecord do things automatically for you that gen-class does not

2:41 especially defrecord

2:42 rritoch: note how I defined a type extending toString above? how would you do that with clojurebot with gen-class?

2:44 anyway, I need to turn in for the night

4:01 Glenjamin: ~for

4:01 clojurebot: for is forget arrdem

4:02 Glenjamin: helpful

4:02 for?

4:02 clojurebot: for is complected

4:11 sm0ke: ,(let [c (atom 10) rfn (fn [] (when (not (zero? @c)) (swap! dec c) (rfn)))])

4:11 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: rfn in this context, compiling:(NO_SOURCE_PATH:0:0)>

4:11 sm0ke: is there any way to close over a closure itself?

4:13 clgv: sm0ke: you can close over any value

4:13 sm0ke: close to close over itself

4:13 ugh closure to close over itself i mean

4:13 clgv: your example will work with (rcur) instead of (rfn)

4:13 sm0ke: clgv: but rfn is not resolved within itself in this example

4:13 clgv: no stack consumption then, as well

4:14 *(recur)

4:14 sm0ke: no, the name of the let binding is not bound before the right hand side is evaluated

4:15 you can name the function if needed, as in (fn rfn [] ... (rfn))

4:15 sm0ke: ok recur could be a solution but what if instead of calling it directly i am using something like (partial rfn)

4:16 clgv: yeah, you can name the function as shown above

4:16 sm0ke: makes sense

4:16 i guess i am not doing it right

4:17 clgv: ,((fn count-down [n] (if (pos? n) (do (print n) (count-down (dec n))) (print "BOOM!"))) 3)

4:17 clojurebot: 321BOOM!

4:18 sm0ke: yes i know recursion! :D

4:19 thanks clgv

4:20 clgv: just an example for the naming of the lambda, I mentioned before ;)

4:20 sm0ke: got it

4:22 clgv: ,((fn count-down [n] (if (pos? n) (do (print n) (map count-down (range n))) (print "BOOM!"))) 3)

4:22 clojurebot: 3(BOOM!12nil (BOOM!nil) (BOOM!1nil (BOOM!nil)))

4:22 clgv: ah doseq would have been better ;)

4:43 m1dnight: hmm, is there an easy way around the arithmetic overflow in clojure?

4:44 clgv: m1dnight: what is the calculation where this occurs?

4:44 m1dnight: a function for the colatz conjecture

4:45 (defn colatz [n] (cond (== 1 n) 1 (odd? 1) (recur (+ 1 (* 3 n))) :else (recur (/ 2 n))))

4:45 clgv: m1dnight: (odd? n) right? ;)

4:45 m1dnight: oh snap

4:46 clgv: yeah there are integers with arbitrary precision

4:46 ,(type 1L)

4:46 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 1L>

4:46 clgv: ,(type 1M)

4:46 clojurebot: java.math.BigDecimal

4:46 clgv: wrong guess

4:47 ah yeah just use autopromoting ops, e.g. *' +'

4:47 ,(*' 2 Long/MAX_VALUE)

4:47 clojurebot: 18446744073709551614N

4:47 clgv: ah "N" is the correct suffix ^^

4:48 ,(type (*' 2 Long/MAX_VALUE))

4:48 clojurebot: clojure.lang.BigInt

4:48 Glenjamin: bah, i was just typing that but it took me 4 goes to find the name of MAX_VALUE

4:49 clgv: ,(odd? (*' 2 Long/MAX_VALUE))

4:49 clojurebot: false

4:49 m1dnight: I had a function previously for belphegor numbers and that coerced to big ints

4:49 but then my prime function no longer worked

4:49 :(

4:49 I believe it was with odd as well

4:50 clgv: m1dnight: so you have two choices (1) use auto-promoting operations or (2) start the calculation with BigInts e.g. 1N

4:50 m1dnight: auto-promoting is coercion (if thats the right term here) to bigint?

4:50 clgv: m1dnight: what does your prime function assume?

4:50 m1dnight: well, that it's an int, I guess :D

4:50 let me get the code, hold on

4:50 clgv: m1dnight: coercion to BigInt when needed

4:51 m1dnight: if that was a performance optimization you'll need to drop that to use BigInt

4:51 m1dnight: clgv: no just puzzles to keep my mind busy in the early mornings :)

4:52 i wanted to check Belgphegor numbers (10006660001 for example) for prime-ness

4:52 but 1066601, .. 1000066600001 quickly overflows

4:54 clgv: m1dnight: how is the check implemented?

4:54 m1dnight: https://www.refheap.com/93129

4:55 hmr, dit past me fix the issue?

4:55 :D

4:55 clgv: how exactly should that overflow as long as x is a long?

4:55 m1dnight: It seems to fine here now

4:57 clgv: the belphegor fn might overflow - maybe numeric-tower implements `expt` cleverly to auto promote

4:58 btw. (:use ...) in ns should be used instead of (use ...) in the implementation part

4:58 TEttinger: yep, it will autopromote

4:58 https://www.refheap.com/93131

4:58 Glenjamin: why is :use preferred over use ?

4:58 clgv: and yeah, use should usually be omitted in favor of :refer ... :as

4:58 Glenjamin: or :require vs require etc

4:58 TEttinger: that's numeric tower expt

4:59 clgv: Glenjamin: then all dependencies are contained within the ns declaration and not scattered all over the file

4:59 TEttinger: Glenjamin: it organizes includes into one place, so they aren't scattered through ...

4:59 (inc clgv)

4:59 lazybot: ⇒ 36

4:59 clgv: (inc TEttinger)

4:59 lazybot: ⇒ 28

4:59 clgv: ;)

4:59 TEttinger: :D

4:59 Glenjamin: clgv: oh right, i thought you meant don't do (ns myns (require a))

5:00 clgv: Glenjamin: it is idiomatic to use keywords there as well, since it is "specification data"

5:00 Glenjamin: right, ok

5:04 rritoch: Hi, does anyone know how to implement a subinterface? I tried the following ... (deftype Blah [] javax.servlet.FilterRegistration$Dynamic (setAsyncSupported [foo] nil)) But I'm getting an error saying it can't define a method not in an interface, but it is in the interface.

5:10 m1dnight: clgv: it is a relic of testing execution of that file without a leiningen project :D

5:10 but you are right

5:11 clgv: rritoch: did you include a param for the "this" reference in the implementation?

5:12 rritoch: cljgv: No, but changing [foo] to [this foo] gives me the same error

5:13 clljgv: Oops, your right, awesome !

5:15 cljgv: So if I add a (def Dynamic (deftype ParentClass$Dynamic [] javax.servlet.FilterRegistration$Dynamic ....)) to a parent (gen-class) will that mimic the full structure of the parent->child relationship?

5:17 foodoo: Is there something like a hash-map comprehension in clojure? Just like list comprehensions?

5:19 rritoch: ,(let [{foo :foo} {:foo :bar}] foo)

5:19 clojurebot: :bar

5:20 mavbozo: foodoo: what languages have hash-map comprehension construct?

5:20 foodoo: mavbozo: Python

5:20 rritoch: ,(let [{foo :foo} (hash-map {:foo :bar})] foo)

5:20 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: {:foo :bar}>

5:20 foodoo: mavbozo: Python3: { x: x+1 for x in range( 3 } }

5:21 rritoch: ,(let [{foo :foo} (hash-map :foo :bar)] foo)

5:21 clojurebot: :bar

5:21 foodoo: mavbozo: This creates a mapping from the numbers 0 to 2 to to each number plus 1

5:22 rritoch: foodoo: Is that what your looking for? You can expand it the same way you expand a map

5:23 foodoo: rritoch: No. What I would like to have is something that makes it possible to define each key and value in the body of a 'for' expression

5:23 Glenjamin: ,(into {} (for [x (range 3)] [x (inc x)]))

5:23 clojurebot: {0 1, 1 2, 2 3}

5:24 foodoo: Glenjamin: that looks good. Thanks

5:29 Glenjamin: if anyone has a couple of minutes to look over https://github.com/defshef/defshef12/blob/master/ClojureScript.md it would be much appreciated - it's a ClojureScript primer to get experienced programmers going at a practical functional programming meetup

5:31 mavbozo: Glenjamin: thank you

5:40 Barley: i'm having problems with cursive not picking up my user.clj in the repl even though it's in the classpath

5:41 anyone know if thre's some tricks to be made about it

5:41 cfleming: Barley: AFAIK it should just work

5:41 Barley: One sec, let me trawl the issues, there was one talking about user.clj

5:43 Barley: There are some comments there saying that someone had said it worked, but I can't find the person saying that - it must have been via email

5:44 Does it work if you invoke lein repl on the command line?

5:54 Glenjamin: Barley: are you using lein repl or your own nrepl server?

5:54 oh right, that's what colin just asked

5:55 i found that when using my own nrepl server, i had to add (require 'user) myself

5:59 Barley: nrepl

5:59 just doing what cursive does by default

6:00 actually there might be a problem with my user.clj after all...

6:00 cfleming: Barley: Does it work if you run lein repl on the command line?

6:00 Barley: That's usually the first thing to try to isolate whether it's a Cursive problem or not.

6:02 zot: t

6:05 godd2: Any reason that (map #(println %) [1 2 3]) works in the repl, but not when I do lein run?

6:07 Glenjamin: godd2: because the repl prints out the result of each expression, which causes it to realize the seq

6:08 godd2: do I just need to remember that clojure won't realize things on its own?

6:09 cause I had the same issue of understanding with lazy-seq haha

6:09 thank you Glenjamin

6:10 dysfun: is there clojurescript source mapping support yet?

6:11 Glenjamin: dysfun: yup, cljsbuild has some settings for it

6:11 dysfun: sweet!

6:18 martinklepsch: In a system similar setup to stuartsierra/component what would be a good way to setup a test system and were would be the right spot to stop it again?

6:18 when using fixtures the system is created for every namespace and the created connections block for some time

6:19 Glenjamin: martinklepsch: is this for end-to-end acceptance tests?

6:20 i'd generally try not to create a whole system, and just do the component your testing + mocks for most tests

6:20 martinklepsch: Glenjamin: if you mean that as in "running the complete set of tests" yes

6:20 Glenjamin: i meant as in "a test that tests the complete system"

6:21 martinklepsch: Glenjamin: yes

6:23 Glenjamin: i don't really have a good answer then i'm afraid

6:24 martinklepsch: ok, just had an idea, maybe that works

6:24 myguidingstar: Glenjamin, have a look at this, too https://github.com/swannodette/lt-cljs-tutorial

6:40 rritoch: Can someone take a look at my attempt to create a subclass relationship and advise what I'm doing wrong? For some reason I can't get the static subclass to show up.

6:40 https://github.com/rritoch/clj-grid-core/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/webapp/filter_registration.clj

6:42 In the repl I attempt to check the type of the Dynamic static class but I get an error that the static property is not found using (type FilterRegistration/Dynamic)

6:56 m1dnight: do you have to forward declare macros?

6:56 well, I know I have to, but does it work properly? I get argument errors, and they seem to be correct

6:59 arav93: Hi, is there anyone familiar with Typed Clojure?

7:00 martinklepsch: Glenjamin: I ended up using a dynamic var for the test-system, and if it's missing it's created otherwise the existing one is used

7:01 (checking that in a fixture)

7:03 Glenjamin: seems reasonable, are you not worried about sharing state between tests though?

7:04 martinklepsch: Glenjamin: I am :D

7:04 we'll see if we can find a clean way to reset the system

7:07 ddellacosta: arav93: what is your question?

7:33 clgv: ~anybody

7:33 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

7:35 clgv: rritoch: I don't think you can create inner classes with gen-class. why would you want to do that anyway?

7:37 rritoch: clgv: I just figured it would be easier if I could instantiate the class via (new parentClass/childClass)

7:37 clgv: This parentClass$childClass is a very odd syntax to be using

7:38 clgv: rritoch: huh?

7:38 rritoch: you'd need to change Clojure to modify constructor call syntax

7:39 rritoch: why don't you just generate two classes without the requirement that ones class name looks as if it was an inner class generated from Java?

7:42 rritoch: clgv: I could probably do that, it would certainly make this code more readable

7:42 clgv: Before your assistance I didn't even know how to instantiate these subinterfaces anyhow, so there's a learning curve involved here.

7:44 clgv: rritoch: let's step an additional step back: what exactly are you trying to achieve? maybe you don't even need gen-class

7:45 rritoch: clgv: I'm trying to add filter support to add JSP filter support to the web application framework I'm developing

7:46 clgv: rritoch: so in the code it seems you definitely have to extend a class and implement additional interfaces, right?

7:46 rritoch: clgv: Yes

7:47 clgv: rritoch: do you need to access those classes by name from java?

7:47 rritoch: or is it sufficient to be able to construct instance via a function?

7:49 rritoch: clgv: honestly I'm not sure. I've wrapped Tomcat's servlet context to provide the capability of serving JSP source files from OSGi bundles

7:50 clgv: Currently there's no support at all for filters, but I'm trying to add that support now

7:52 clgv: I believe, for things to function properly, I'll need to pull out all of the filters from the actual tomcat provided servlet context and wrap them all

7:54 clgv: Basically I just don't want the actual tomcat provided context to slip through because if it does than the filters won't be able to resolve OSGi resources

7:55 clgv: rritoch: I was aiming at the following - maybe using `proxy` suffices and you do not need "gen-class"

7:55 rurumate: is it possible to define a package in the repl?

7:55 ! package foo { }

7:56 clgv: rurumate: what is a package?

7:56 rurumate: you can define arbitrary namespace in the repl

7:56 rurumate: oops sorry I thought I in scala

7:56 * rurumate blushes

7:56 clgv: if a scala package is the same as a java package I doubt that this is possible ;)

7:57 rurumate: clgv: currently learning scala for my next job

7:57 no I think it's not the same

7:58 clgv: ok interesting. I have no clue about scala ;)

8:05 rurumate: My research so far: scala has anonymous functions. But an anonymous function has no way to refer to itself; recursive calls are only by function name. Hence you cannot do recursion in anonymous functions.

8:06 also no s-expressions; hence, no paredit. it's kinda sad

8:07 clgv: rurumate: http://stackoverflow.com/questions/6475001/how-do-i-write-recursive-anonymous-functions ?

8:08 rurumate: clgv: amazing, thanks

8:08 ingsoc: can't you assign the anon to a variable then pass the var reference as a param when you call it

8:09 rurumate: but is that tail-call optimized

8:09 I assume that awkward mess will also blow the stack

8:09 clgv: probably

8:10 so the idiomatic choice is probably to have names for recursive functions

8:10 rurumate: still a lot better than java where you're stuck with loops

8:11 *while and for loops, that is

8:11 oh, and the scala compiler will by default not complain when something can not be tail-call optimized

8:12 that's for you to find out. at runtime

8:12 clgv: nice :P

8:12 m1dnight: isn't there a flag to make it warn?

8:12 clgv: that's a feature it shares with java then ;)

8:13 m1dnight: doesnt java lack tco at all?

8:13 rurumate: there's a @tailrec annotation

8:13 m1dnight: yes that's why you're stuck with while and for

8:14 m1dnight: rurumate: I didn't know that

8:14 good to know

8:14 rurumate: of course you can write recursion in java, but it will blow up the stack

8:14 m1dnight: yeah, I realize that :D

8:14 A guys on SO yesterday gave an answer for replcing string using recursion

8:15 it's pretty, yes. but it sucks

8:15 SagiCZ1: could someone clarify what is meant by TCO, and does java/clojure has it always/sometimes?

8:15 ingsoc: rurumate: i spose it depends what you are doing. There will be cases where you have to be careful but it depends on what the function does.

8:15 rurumate: SagiCZ1: clojure does it whenever you do (recur)

8:15 m1dnight: SagiCZ1: TCO means that when you do a function like: (defn f([x] (dostuff) (f (inc x))))

8:15 you call yourself. Since the recursive call to f is in last position it is *tail position*

8:16 clgv: rurumate: the interesting thing is that you hardly notice missing TCO in Java if you never used a functional language because you are writing loops instead of recursions most of the time

8:16 m1dnight: (defn f[x] (f (inc c) (println "something"))), here the call to F is not in tail position

8:16 clgv: you usually notice the stack limitation as soon as you implement a backtracking algorithm for larger problems ... ;)

8:17 m1dnight: so basicly what you can do, is, when the last expression is call yourself (f), you can "forget" all the local variables in the scope of the caller and reuse the space on the stack. If you don't have this optimisation (like java) it will still remember all the variables on the stack

8:17 and you eventually run out of that

8:17 clgv: SagiCZ1: TCO = tail call optimization

8:17 m1dnight: => blown up stack => not a happy programmer

8:18 long story short (defn f[x] (recur x)) will run forever in clojure

8:18 rurumate: this is tail position too:

8:18 `(loop [x 10] (if (not (zero? x)) (recur (dec x)) 0))

8:18 m1dnight: public static int f(int x) { f(x);} will fail instantly

8:18 clgv: m1dnight: in contrast to (defn f [x] (f x))

8:18 m1dnight: yes, correct :)

8:19 clgv: ,((fn f [x] (recur x)))

8:19 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: sandbox/eval25/f--26>

8:19 rurumate: ,(loop [x 10] (if (not (zero? x)) (recur (dec x)) 0))

8:19 clojurebot: 0

8:19 clgv: ,((fn f [x] (recur x)) 1)

8:19 clojurebot: eval service is offline

8:19 m1dnight: RIP clojurebot

8:19 rurumate: notice that the (recur) form is not the last argument to if

8:19 clgv: damn. I though he had a timeout

8:19 ,((fn f [x] (f x)) 1)

8:19 clojurebot: #<StackOverflowError java.lang.StackOverflowError>

8:19 clgv: demonstartion finished ;)

8:20 m1dnight: I had to implement TCO in a compiler/evaluator for Lisp last year

8:20 I had hella fun with that :p

8:20 in C++ that is

8:20 clgv: in clojure you just get a for-loop on the jvm for simple cases...

8:20 m1dnight: Yeah, I figured that something like that would happen

8:21 only possible choice on the JVM, for what I nkow of it

8:21 ingsoc: so, if I want to do something concurrently in clojure, like say, read on a socket while i am doing other things like make http request what is the general approach in clojure ?, some kind of async library, or threads with STM, or some other green thread user level library ?

8:21 m1dnight: a future, i'd say

8:21 that's what they're for

8:21 ingsoc: or actor library

8:21 m1dnight: an actor is not really something built for that, but you could, I guess :p

8:21 just use a future

8:22 ingsoc: ok so futures just defer to some kind of thread pool ?

8:23 m1dnight: I'm not aware of the basics, no. But I do believe they do

8:23 They are not green threads (i mean native OS threads)

8:23 I always confuse red/green threads

8:23 and you can check if they have been resolved as well

8:23 ingsoc: yeah, when i was talking about the different options for concurrency threads meant OS scheduled threads

8:23 m1dnight: they are very well suited for what you are asking

8:24 you should use futures because they are more lightweight than an actual thread

8:24 unless it is something that will run through your entire program, then you might consider a thread

8:24 but I'd prefer futures for lightweight work

8:25 rurumate: ingsoc, core.async is also worth a look

8:29 ordnungswidrig: ingsoc: if you have multiple things that need to be computed in parallel and you need to wait for all to finish at some point I guess core.async might be easiest thing to use.

8:30 godd2: ingsoc: here's a clear and concise overview of clojure concurrency and parallelism: http://www.braveclojure.com/concurrency/

8:30 Glenjamin: futures are not lightweight in clojure afaik

8:30 they just spawn a thread in a threadpool

8:30 edw: They're threads.

8:30 Beat me.

8:31 Glenjamin: everything in the JVM runs off OS thread threadpools

8:31 m1dnight: but that means they are more lightweight than an actual thread?

8:31 rurumate: Glenjamin: source on that?

8:31 m1dnight: a threadpool can hold a lot of threads, you can't spawn 10k threas in java

8:31 well, you can try

8:32 Glenjamin: https://www.youtube.com/watch?v=yhguOt863nw

8:32 martinklepsch: is honeysql a popular choice as plain SQL abstraction? https://github.com/jkk/honeysql

8:32 edw: Back in the old days the JVM used green threads but by the Twenty-first C. they were using native OS threads.

8:32 ingsoc: the impression i get is future is just a way to send a task to a thread pool then check on it and resolve the result later

8:32 Glenjamin: as i understand it, most JVMs have their Thread class be 1-1 with OS threads

8:32 ingsoc: an OS thread pool

8:32 Glenjamin: ^^ that is my understanding also

8:33 ingsoc: async is node like progreamming

8:33 Glenjamin: even core.async is just a threadpool

8:33 ingsoc: where you use callbacks

8:33 edw: Node.js programming is backwards programming.

8:33 ingsoc: yeah i know

8:33 Glenjamin: right, co-operative multi-threading across a threadpool

8:34 clgv: Glenjamin: that's wrong. futures do not spawn threads. there is a configure threadpool for futures whose threads are used for futures

8:34 so you can definitely spawn as many futures as your heap settings allow

8:34 rurumate: ingsoc: uh, really?

8:34 ingsoc: godd2: interesting resource

8:34 Glenjamin: clgv: right, but the threads in that pool are OS threads, they just might already be there?

8:34 ingsoc: thanks

8:34 edw: And they queue up? Huh. This is interesting information.

8:35 ordnungswidrig: ingsoc: no callbacks necessary with core.async

8:35 clgv: Glenjamin: yeah the threads are reused. If I remember correctly futures use a fixed threadpool with n+2 threads where n is the number of processors determined from runtime class

8:36 ingsoc: I assume there is a way to specify/configure the thread pool size for these things depending on usage characteristics

8:36 clgv: nope

8:36 only for agents, sadly

8:36 m1dnight: so does that not imply that (.start (Thread. (fn..))) is heavier than a future..?

8:36 clgv: m1dnight: yes

8:36 Glenjamin: that sounds familiar, does that mean futures can be considered "more lightweight" ?

8:36 phillord: with lein release is there anyway to know what version number it will give to the release before you do it?

8:36 Glenjamin: right, because there's no thread creation cost

8:36 m1dnight: Glenjamin: of course.

8:36 clgv: you can call futures lightweight with respect to this

8:36 m1dnight: I *think* futures are like callables

8:37 ingsoc: it is only heavier in a sense that you have the overhead of thread creation before any work is done

8:37 clgv: m1dnight: they are java futures in fact

8:37 ingsoc: but it is still a thread that is doing the work

8:37 m1dnight: yeah, and program counters and memory as well, ingsoc

8:37 Glenjamin: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L49

8:37 there's the pools

8:37 and here's core.async's https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj#L17

8:37 clgv: yeah that's the one

8:37 alexanderte: I get an error (doesn’t seem to do any harm) when running lein. I installed lein with brew. anyone know how to get rid of it? output: /usr/local/bin/lein: line 9: [: too many arguments

8:37 ingsoc: ok so it is examining the number of cores

8:37 Glenjamin: num cpus * 2 + 42 :D

8:38 ingsoc: then using that as a base for making a decision on what to run

8:38 clgv: love those magic numbers

8:38 m1dnight: lol, why + 42? :D

8:38 the answer to life?

8:39 godd2: dogecoin mining uses all your extra super-hyper threads

8:47 ordnungswidrig: alexanderte: can pastebin /usr/local/lein somewhere?

8:47 alexanderte: can you pastebin...

8:47 rritoch: clgv: Well, thanks again with your help accessing SubInterfaces, that eliminates the need for me to use any java in these libraries. The code is all still extremly sub-optimial, but it's slowly coming together. I need a way to deliver static resources (like javascript) from the OSGi bundles which is why I'm starting to delve into the filters.

8:48 clgv: alexanderte: I'd recommend a manual leiningen installation - it's no big additional effort.

8:48 rritoch: clgv: I bypassed filter usage with a hack https://github.com/rritoch/clj-grid-core/blob/master/src/com/vnetpublishing/clj/grid/lib/grid/jsp/request_dispatcher.clj#L53-L69 since I didn't think I could instantiate filter subinterfaces.

8:50 clgv: rritoch: ok, let me cite clojurebot: "that's greek to me"

8:50 rritoch: ,(inc clgv)

8:50 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: clgv in this context, compiling:(NO_SOURCE_PATH:0:0)>

8:50 rritoch: hmm, not sure how that works

8:51 rurumate: ,(let [clgv 10] (inc clgv))

8:51 clojurebot: 11

8:51 rurumate: see

8:52 clgv: :P

8:52 rritoch: it works without the ","

8:52 rritoch: (inc clgv)

8:52 lazybot: ⇒ 37

8:53 alexanderte: ordnungswidrig: clgv: will attempt with a manual install. thanks!

8:53 rritoch: Cool, we'll your my first inc, but I've been searching for months for a solution to this problem, justin_smith helped me earlier when he let me know about the $ syntaxx but that still wassn't quite enough to get the code functional.

8:54 ordnungswidrig: ,clgv

8:54 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: clgv in this context, compiling:(NO_SOURCE_PATH:0:0)>

8:54 rurumate: ,(def clgv 10)

8:54 clojurebot: #'sandbox/clgv

8:54 rurumate: ,clgv

8:54 clojurebot: 10

8:54 clgv: $karma ordnungswidrig

8:54 lazybot: ordnungswidrig has karma 0.

8:54 ordnungswidrig: what?

8:54 rritoch: Even in javaland I rarely ever had to work with subinterfaces, after looking at tomcat's code for awhile I truly believe they intentionally made the code incomprehensible.

8:54 clojurebot: what is <amalloy> just use juxt, it'll be great

8:54 ordnungswidrig: how embarrasing

8:54 clgv: (inc ordnungswidrig)

8:54 lazybot: ⇒ 1

8:54 rurumate: ,(def clgv (atom 10))

8:54 clojurebot: #'sandbox/clgv

8:55 ordnungswidrig: (inc ordnungswidrig)

8:55 lazybot: You can't adjust your own karma.

8:55 ordnungswidrig: how lame

8:55 rurumate: ,(swap! clgv inc)

8:55 clojurebot: 11

8:55 * clgv can't be swapped!

8:56 vijaykiran: ordnungswidrig: you can tweak by re-nicking ;)

8:59 rurumate: Glenjamin: super vid thanks

8:59 clgv: ,(ns-unmap *ns* 'clgv)

8:59 clojurebot: nil

9:41 m1dnight: hrm, there is metadata for datastructures in Clojure

9:41 that's new

9:41 (to me, that is)

9:42 stuartsierra: m1dnight: It's rarely used except for compiler hints.

9:43 m1dnight: yeah, but once you start doing some esoteric academic stuff, it might come in handy

9:43 can't think of use right now, but it's good to know they're there

9:44 hyPiRion: m1dnight: annotations on an AST

9:44 m1dnight: right, for example! :)

9:44 for AVL trees it could be handy

9:46 clgv: metadata on variables defined by a DSL is pretty handy

9:47 hyPiRion: clgv: yeah like, hmmm.... project.clj or something? :)

9:47 clgv: hyPiRion: for example. I also have a DSL for my projects that I was refering to ;)

9:50 m1dnight: righ hickey really really does not like state

9:50 i'm watching his talk "concurrency in clojure" on ClojureTV

9:50 rweir: that's unfair

9:51 clgv: m1dnight: huh? isn't the take-a-way to have sane state management to decouple state from time?

9:52 m1dnight: you are probably refering to java's (& co) inplace mutation as "state", right?

9:52 m1dnight: clgv: yeah, sorry I meant that yes

9:52 well, the mutability part, that is

9:53 I'm sorry for wrong terms

9:53 clrnd: implicit state

9:53 clgv: m1dnight: well definitions depend on the context. that's why it is important to get the definitions straight before serious discussions ;)

9:54 m1dnight: you are right :D

9:57 I just don't understand well how it is really that bad to determine "how your program got to a state" when you use OO style

9:58 Isn't it equally hard in clojure?

9:58 I cna imagine in pure haskell where all functions are pure

9:58 but when your functions are no longer pure.. you have kind of the same issues, no?

9:58 rweir: no, because clojure requires you to explicitly state when you make global mutations, and provides tools to make them sane

9:59 m1dnight: but you can still do IO and other side effects in functions

9:59 which make your functions unpure

10:00 clgv: m1dnight: yeah Clojure has no machanisms to enforce pure functions

10:00 rweir: yes, it's not about function purity

10:02 clgv: m1dnight: but usually you should try to have as much "pure" functions as makes sense since those are a lot easier to test

10:03 m1dnight: Yeah, i certainly understand that :)

10:03 dnolen_: m1dnight: many of the design decisions in Clojure are less obvious if you haven't done a lot of multithreaded concurrent programming in languages with shared mutable state particularly in OO style. IMO Java Concurrency in Practice is a must read to really understand Rich's points.

10:03 m1dnight: "how you your multithreaded program got to state"

10:03 m1dnight: yeah, I've written the book down, he talks about it in his talk

10:04 dnolen_: m1dnight: so while yes you do have to minimize state and still think about it - you don't IME encounter the truly horrific scenarios when writing concurrent programs in Clojure.

10:09 m1dnight: even so all these principles work great in single threaded contexts too. Om and the various ClojureScript React bindings demonstrate this to good effect. So Clojure is less "State is Bad" and more "Unmanaged State is Bad"

10:46 llasram: Huh. Did the syntax for github-flavored Markdown Clojure syntax highlighting change recently?

10:48 clgv: llasram: a few months ago they changed their markdown backend

10:48 llasram: clgv: I must not have been paying enough attention...

10:49 Bronsa: llasram: it's been broken for a couple of weeks

10:49 llasram: Weird. In like half of my project's .md files Clojure code isn't getting highlighting, but it is in other

10:49 Bronsa: Ok, whew

10:49 Glad it isn't just me

10:49 clgv: oh that as well?

10:49 llasram: I've been writing in C for the past few weeks, which must be why I hadn't noticed :-)

10:51 Bronsa: llasram: https://twitter.com/ztellman/status/529880281621491712

10:51 clgv: llasram: https://github.com/blog/1867-github-pages-now-runs-jekyll-2-2-0

10:52 llasram: Bronsa: Iiiinteresting. Well, I'm sure they'll fix it soon

10:53 It's probably because Clojure is so difficult to parse

10:53 clgv: yeah all this weird syntax ;)

10:53 llasram: Exactly

10:54 ,`#(~@@% %&)

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

11:02 SagiCZ1: ,(let [{a :a :as m} 5] (println a m))

11:02 clojurebot: #<CompilerException java.lang.UnsupportedOperationException: Can't type hint a primitive local, compiling:(NO_SOURCE_PATH:0:0)>

11:02 SagiCZ1: can anyone help me here?

11:02 i thought that 'a' would be nil and 'm' would be 5

11:03 n0n3such: hey

11:03 nkoza: SagiCZ1: you are trying to map-destructure an integer, that's not possible

11:03 Bronsa: SagiCZ1: the fact that it might work for non-map values is an implementation detail

11:03 hyPiRion: ,(macroexpand-1 '(let [{a :a :as m} 5] (println a m)))

11:03 clojurebot: (let* [map__78 5 map__78 (if (clojure.core/seq? map__78) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__78)) map__78) m ...] (println a m))

11:03 SagiCZ1: ,(let [{a :a :as m} [5 3]] (println a m))

11:03 clojurebot: nil [5 3]\n

11:04 SagiCZ1: i can easily destructure vector as map though

11:04 justin_smith: SagiCZ1: (pprint (macroexpand '(let [{a :a :as m} 5] (println a m))))

11:05 Bronsa: SagiCZ1: "Map binding-forms allow you to bind names to parts of associative things (not just maps), like maps, vectors, string and arrays (the latter three have integer keys)."

11:05 justin_smith: SagiCZ1: that should make it a little more clear I hope

11:05 hyPiRion: ,(let [{a :a :as m} (list 1 2 3 4)] (println a m))

11:05 clojurebot: nil {1 2, 3 4}\n

11:06 SagiCZ1: ,(let [{a :a :as m} (list 1 2 3)] (println a m))

11:06 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: 3>

11:06 SagiCZ1: ok so i see that it can take a vector or list but only if it can make key value pairs from it

11:06 justin_smith: ,(let [{a :a :as m} (list 1 2 :a 4)] (println a m))

11:06 clojurebot: 4 {1 2, :a 4}\n

11:06 SagiCZ1: ,(let [{a :a :as m} '(1 2 :a 4)] (println a m))

11:06 clojurebot: 4 {1 2, :a 4}\n

11:07 SagiCZ1: this is equivalent right?

11:07 Bronsa: with lists it's a different case than with vectors

11:07 lists get transformed into maps

11:07 vectors don't

11:07 SagiCZ1: ,(let [{a :a :as m} [1 2 4]] (println a m))

11:07 clojurebot: nil [1 2 4]\n

11:07 SagiCZ1: i see

11:07 Bronsa: this is to support keyword args via destructuring

11:08 SagiCZ1: i will need to remember this

11:20 ordnungswidrig: SagiCZ1: ,(let [{:keys [a b c] :or {a 1 b 2 c 3}} {:a 10}] [a b c])

11:20 ,(let [{:keys [a b c] :or {a 1 b 2 c 3}} {:a 10}] [a b c])

11:20 clojurebot: [10 2 3]

11:21 Bronsa: ordnungswidrig: FYI lazybot can evaluate inline code ##(inc 1)

11:21 lazybot: ⇒ 2

11:21 ordnungswidrig: SagiCZ1: in case you're fine with having the values bound to locals named after the keys

11:21 Bronsa: Ah, nice!

11:21 inc bronsa

11:21 SagiCZ1: ordnungswidrig: thanks

11:21 ordnungswidrig: ,inc bronsa

11:21 clojurebot: #<core$inc clojure.core$inc@9defa>

11:21 SagiCZ1: its (inc Bronsa)

11:22 ordnungswidrig: (inc bronsa)

11:22 lazybot: ⇒ 69

11:22 ordnungswidrig: (dec ordnungswidrig)

11:22 lazybot: You can't adjust your own karma.

11:22 ordnungswidrig: ha

11:22 justin_smith: this also may work: $#(inc Bronsa)#$

11:22 maybe Raynes did not turn that plugin on, but it works now

11:23 maybe only for $commands though

11:24 ordnungswidrig: hmm, can we have access to all users in the bot expr please? $#(->> users filter #(> (count % 10)) (map dec)) for excessively long nicks

11:24 SagiCZ1: whats the opposite of slurp? i though it was barf?

11:24 or is it vomit?

11:24 ordnungswidrig: SagiCZ1: use pr-str

11:24 justin_smith: SagiCZ1: spit

11:24 SagiCZ1: spit"

11:24 afhammad: does folder structure in a project have any significance to compiler? do folders need to represent namespaces?

11:24 SagiCZ1: thanks

11:25 justin_smith: we should have all the bodily functions

11:25 fart would be for inserting something into mongodb

11:25 ordnungswidrig: afhammad: yes, this is necessary for the runtime to know where to look for the file

11:25 SagiCZ1: afhammad: afaik they need to correspond to namespaces like in ajva to packages

11:25 justin_smith: hah

11:25 afhammad: SagiCZ1: ordnungswidrig: is this documented anywhere?

11:26 justin_smith: afhammad: doc require (it's too big for this forum)

11:26 ordnungswidrig: afhammad: `load` will load the file from every location but the magic behind `requrie` depends on the ns coressponding with the path

11:26 justin_smith: $source require

11:26 lazybot: require is http://is.gd/SqKuAM

11:26 justin_smith: see doc string in the above link

11:27 afhammad: thanks

11:27 justin_smith: afhammad: it's one of the most extensively documented clojure functions actually

11:28 afhammad: any idea if lighttable does anything fancy with loading namespaces? require doc says "skipping any that are already loaded" but I often get "already required" errors when re-evaling a ns

11:29 justin_smith: "already required" is a weird error

11:29 ordnungswidrig: afhammad: in lighttable?

11:29 afhammad: not those words exactly

11:29 ordnungswidrig: yes

11:29 justin_smith: afhammad: unless you specify the :reload keyword, require will silently ignore args that are already loaded

11:29 ordnungswidrig: afhammad: or is it complaining a var is already refering to a different var?

11:30 justin_smith: afhammad: maybe "already refers to clojure.core/foo in namespace ..."

11:30 that's different, it's about conflicting aliases, usually caused by :use or :refer []

11:30 ,(def count 1)

11:31 clojurebot: #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>

11:31 justin_smith: hrmph

11:31 well if you do the above locally, you can see that error

11:31 *warning

11:31 not an error

11:32 afhammad: i think it might have been clojurescript file not clojure

11:32 justin_smith: it's never an error to call def again on something already defined though

11:36 csd_: Would someone mind giving me a code review on my first clojure project? https://github.com/prunes/amzn/tree/master/src/hackerati_interval_web_app

11:36 I'm especially looking for what I might be able to refactor

11:36 also, ban fluuflu

11:36 stuartsierra: justin_smith: It is an error if the symbol was `refer`ed from a namespace other than clojure.core.

11:37 justin_smith: stuartsierra: oh, I guess I would know that if I used :use, thanks

11:37 afhammad: so that could be your issue

11:38 Bronsa: there's also a bug with namespace reloading

11:39 http://dev.clojure.org/jira/browse/CLJ-1578

11:39 afhammad: justin_smith: #<Error: Namespace "bcr.routes" already declared.> this is clojurescript when evaluating in lighttable

11:39 Bronsa: technomancy: ban fluuflu please

11:39 justin_smith: afhammad: odd, I have never seen that

11:40 Bronsa: technomancy: it's the usual spammer

11:40 <3

11:40 afhammad: justin_smith: ah, looks like a google closure issue: at Object.goog.provide (http://localhost:3020/js/out/goog/base.js:248:40)

11:41 atyz: Does anyone know of a plugin of some kind that reads a .env file or something when you cd into a directory and sets those environment variables?

11:42 Kind of like rbenv does for ruby

11:42 justin_smith: atyz: clojure doesn't really have "cd"

11:43 massi: Hi all !

11:43 afhammad: justin_smith: i think he means in the terminal

11:43 atyz: justin_smith: I wans't talking clojure specific

11:43 afhammad: knows what I'm talking 'bout

11:43 justin_smith: atyz: things like that tend to fall out of usage because they make exploits too easy

11:43 ordnungswidrig: atyz that depends on your shell

11:44 justin_smith: if I create the right env file, and a root user cd's into that dir, I can get root

11:44 ordnungswidrig: you can use something like a precmd for that. but the security problems are a think

11:44 justin_smith: you never want to use rbenv or like that as root

11:44 justin_smith: also, this is very shell specific, any solution would only work for a particular shell

11:44 pepijndevos: Does Alex Miller hang out here?

11:44 atyz: justin_smith: I suppose thats true, but in the end its kind of similar to setting them in your ~/.zshrc

11:45 Bronsa: pepijndevos: yeah usually, his nick is puredanger

11:45 justin_smith: atyz: the difference is if I cd to /home/jackass/, I don't load jackass's .zshrc automatically

11:45 pepijndevos: ah

11:45 Bronsa: pepijndevos: he's not here constantly but frequently

11:45 atyz: justin_smith: thats totally true, I only want to use this on my machine though

11:46 justin_smith: atyz: yeah, this is all a throwback to when more then one person used the same computer

11:46 but that's what unix was designed for, so there we are

11:46 atyz: justin_smith: to me, thats kind of like using my toothbrush

11:46 technomancy: justin_smith: also for checking out random codebases

11:46 pepijndevos: Bronsa, my local meetup has a hackathon, and this seemed fun to hack on, but it's assigned to him, so I don't want to duplicate work: http://dev.clojure.org/jira/browse/ASYNC-104

11:47 I'll see if he turns up today...

11:47 justin_smith: technomancy: atyz: excellent point - someone could get root on your machine byt putting a dot file in a github repo

11:47 Bronsa: pepijndevos: FYI he's usually quite responsive to emails

11:48 pepijndevos: If I had his email... maybe google knows.

11:48 justin_smith: $mail pepijndevos you can also use this lazybot feature to leave a message on this channel

11:48 lazybot: Message saved.

11:48 atyz: justin_smith: that is true, I guess my want for teh convenience kind of outweighs that at this point :P

11:48 pepijndevos: eh, oh, I forgot about that.

11:48 Bronsa: pepijndevos: https://github.com/puredanger he has his email here

11:50 justin_smith: atyz: anyway, it's up to you, but these are the reasons it isn't a standard feature, though it's been implemented multiple times. Feel free to find one of those implementations or make another one I guess, if you really don't care.

11:50 afhammad: Do you see the compilation error here (http://programming-enchiladas.destructuring-bind.org/swannodette/6385166)? I keep getting this in my project, even though compiler finds it first time. my code is unrelated to the link, just came across that searching for the exception

11:50 specificly with require-macros

11:51 atyz: justin_smith: I understand why but I hadn't really considered cloning someone elses repository

11:52 Glenjamin: atyz: the other issue is if you move around a lot, you'll accumulate env vars

11:52 justin_smith: atyz: yeah it's funny, when you download an archive someone else made, that effectively makes your machine multi-user

11:52 Glenjamin: i generally find having 'env.sh' and using `source env.sh` to get the vars is a good balance

11:53 justin_smith: (inc Glenjamin)

11:53 lazybot: ⇒ 7

11:53 justin_smith: yeah, make it an explicit you opt-in on

11:53 atyz: Glenjamin: I assumed the plugin or whatever would have removed the variable when you cd out but that is a good comprimise

11:53 I think I'll do that

11:54 justin_smith: or call it e, and ". e" for those avoiding typing

11:54 mgaare: atyz: you could write a little bash script that checks if the target directory has an env file and executes it and alias `cd` to it or create something li ke a `cdenv` alias

11:54 justin_smith: mgaare: executing does not suffice, it would have to be sourced

11:55 mgaare: justin_smith: yes, you're right, misspoke

11:55 pepijndevos: Bronsa, thanks, email sent.

11:55 Bronsa: np

11:56 justin_smith: anyway, another, more subtle issue, with this kind of automation is that it's an implicit mutation of your execution environment, which makes it harder to understand what is going wrong as soon as anything breaks

11:57 atyz: justin_smith: that is also true. This would also be pretty easily addressed if I were to move all my development work into docker containers

11:57 justin_smith: like a program that breaks when run in directory /home/foo, but only if I have visited /home/bar earlier in the same shell

11:57 atyz: Then you only really have teh variables that you explicitly set

11:58 justin_smith: atyz: in that case, you would set your docker environment vars, not per-directory ones I would assume

11:58 atyz: Correct

11:58 mgaare: none of this really qualifies as a "good" idea, no

11:59 technomancy: I prefer to only use env vars in production/staging and keep the defaults in code

11:59 mgaare: I wonder if someone has a written a tool that lets you push/pop your environment on a stack

11:59 technomancy: that way you can change them without restarting the jvm

12:00 atyz: https://www.refheap.com/93153 <--- I've just started using those for one of my projects

12:00 But technomancy is right, restarting could get irritating, however I'm hoping its not something you do frequently (set env vars)

12:01 csd_: Would anyone be able to do a code review please? https://github.com/prunes/amzn/tree/master/src/hackerati_interval_web_app

12:03 justin_smith: csd_: I've been browsing it but not super closely, no issues to note yet

12:04 csd_: context is, I have a pair programming interview coming up where I need to suggest either a feature to add or a refactoring to do, and I have no clue what to suggest

12:04 whatever it is, it should take ~15-20 mins to do, according to them

12:05 SagiCZ1: csd_: there is always something you can refactor.. though i am not saying the result would be better than the original

12:05 justin_smith: csd_: a simple one might be using schemas for more function arguments

12:05 csd_: justin_smith: what do you mean?

12:06 justin_smith: csd_: sorry, reading comprehension fail

12:06 saw schema, thought prismatic/schema, but that's not what it was at all

12:06 csd_: oh, no

12:07 justin_smith: csd_: test coverage is an easy, if boring one

12:07 almost always applies

12:07 dbasch: csd_: you should not be using floating point for money

12:07 csd_: testing is definitely something i am lacking in

12:08 justin_smith: dbasch: if your account balance is so large that you get rounding errors, you deserve the rounding you get

12:08 (kidding)

12:08 csd_: dbasch: this isn't for transactions so i think it's fine in this case

12:09 justin_smith: csd_: it should be easy enough to use BigDecimal, or store things in integer cents though

12:09 csd_: oh you guys are talking about the clj datatype, not the sql datatype

12:10 justin_smith: csd_: even in sql you should be using a decimal or integral type and not a float

12:10 csd_: yeah it's decimal in sql

12:10 justin_smith: (some dbs have floats)

12:11 dbasch: ,(= 0.01 (- 0.36 0.37))

12:11 clojurebot: false

12:11 dbasch: ^ csd_

12:11 do you still want to use floating points for money? :)

12:11 justin_smith: ,(= 0.01 (- 0.37 0.36))

12:11 clojurebot: false

12:11 csd_: floats are weird

12:11 dbasch: ,(= 0.01 (- 0.37 0.36))

12:11 clojurebot: false

12:11 dbasch: (that’s what I meant)

12:11 justin_smith: I figured

12:12 csd_: how is using BigDecimal any better than float though?

12:12 dbasch: and those are doubles

12:12 justin_smith: dbasch: if you have a whole 37 cents, you can afford to lose a penny :P

12:12 dbasch: csd_: fixed point

12:12 justin_smith: ,(= 0.01M (- 0.37M 0.36M))

12:12 csd_: i have to admit i don't know much about the underworkings of floats

12:12 clojurebot: true

12:13 justin_smith: csd_: oh you have a world of wat to learn

12:13 dbasch: csd_: every developer must know how floating point works

12:13 justin_smith: ,(= (/ 0.0 0.0) (/ 0.0 0.0)) ; csd_

12:13 clojurebot: false

12:13 dbasch: you wouldn’t pass an interview at most companies I’ve worked at if you don't

12:13 justin_smith: ,(let [a (/ 0.0 0.0)] (= a a)) ; csd_

12:13 clojurebot: false

12:14 justin_smith: dunno why, I find NaN infinitely amusing

12:14 dbasch: ,(= Double/NaN Double/NaN)

12:14 clojurebot: false

12:15 dbasch: Float in fact has very restricted applications right now

12:15 the default for floating point should be Double

12:16 justin_smith: and in clj it is (when not rationals)

12:16 ,(/ 3 4)

12:16 clojurebot: 3/4

12:16 dbasch: If you need to use floating point values and save memory, Float is an option but not necessarily the best

12:16 yes, in Clojure Double is (sanely) the default

12:16 (dec Float)

12:16 lazybot: ⇒ -1

12:17 csd_: well i imagine i can replace parseFloat with parseDouble with little difficulty

12:17 Bronsa: how cool would it be if that returned -0.9999999997?

12:17 technomancy: haha

12:17 * justin_smith starts working on that PR

12:18 justin_smith: I'm thinking a set of "nicks" that should get sloppy float representation

12:18 two minute hack

12:19 technomancy: $timer 120 hack done

12:19 justin_smith: haha

12:19 technomancy: did I do that right?

12:19 justin_smith: $timers

12:20 technomancy: =(

12:20 justin_smith: I wonder if he disabled that one

12:20 I know it works

12:21 $timer 0:2:0 hack done

12:21 lazybot: Timer added.

12:21 justin_smith: $timers

12:21 lazybot: 1: hack done (1 minute and 56 seconds remaining)

12:22 technomancy: time's a-wastin'

12:23 I guess that's better though; no ambiguity about whether integers are milliseconds or whatever

12:23 lazybot: hack done

12:23 dbasch: csd_: keep in mind that the above example *is* doubles

12:23 some numbers simply cannot be represented in floating point

12:24 csd_: if you want an in-depth explanation, https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

12:25 csd_: apparently there's a lot to know

12:27 technomancy: ^ truth

12:27 dbasch: csd_: you can start here http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary

12:28 justin_smith: $timers

12:28 OK I am very close :)

12:29 (inc Float)

12:29 lazybot: ⇒ 0

12:29 anybot: ⇒ 0.9976645522002479

12:29 justin_smith: w00t

12:30 dbasch: justin_smith: rename it to pentiumbot :P

12:30 * dbasch is old

12:31 dbasch: cannot believe the Pentium FDIV bug is 20 years old

12:32 justin_smith: https://github.com/noisesmith/lazybot/commit/b783b8370ae75ba1293a5de4187c6fa2bb05337c

12:32 csd_: I think I know what I'll propose we work on. Right now if you submit the same link twice, it will get scraped twice. I'll suggest we address that.

12:32 justin_smith: dbasch: I remember it too, though I was a weirdo that did not use computers until I hit my 20s

12:32 dbasch: justin_smith: I started programming in 1983…

12:33 at this rate I think I’ll be competent at it by 2150

12:34 (barring singularities)

12:35 justin_smith: dbasch: better than the common case of reaching an early plateau of semi-competance and refusing to move forward after that early success

12:35 dbasch: justin_smith: they look like plateaus but really they have a downward slant

12:36 justin_smith: dbasch: or red-queen style mountain ranges get born all around you

12:37 dbasch: I was part of a team of C developers who refused to learn Java back in 2000

12:38 and more recently I worked with a Java team that refused to try any other jvm languages

12:38 justin_smith: technomancy: so I was about 6 minutes off in my 2 minute estimate - that's damn good for software

12:39 technomancy: indeed; I wish I could make estimates that good =)

12:40 Glenjamin: factor of 4?

12:48 ed-g: Hello everyone. I'm following an older core.logic tutorial and it uses 'defrel and 'facts what is the modern way to do this? is it pldb? if so how do I install pldb?

12:49 edw: I'm trying to locally install/deploy a lib I've forked locally and lein always seems to want to load it from clojars. How does one go about installing a lib in one's ~/.m2?

12:49 justin_smith: edw: lein install

12:50 it helps if you set a custom version-name that will be unique to your local version

12:50 edw: I was wondering if that would help.

12:50 justin_smith: ed-g: it seems there is no concrete db imple in pldb https://github.com/threatgrid/pldb/blob/master/src/pldb/logic.clj

12:50 CookedGryphon: How do I go about mapping over two sequences which might be different lengths, in such a way that the shorter of the two lists is padded out with nils

12:50 justin_smith: *impl

12:56 ed-g: justin_smith: hmm. Also, it does not work with newest core.logic, since it depends on nonexistent fn core.logic/contains-lval?

12:56 crack_user: hello gyus

12:57 some one knows if there are a form to put defn and let together?

12:58 dbasch: crack_user: you mean letfn?

12:58 oskarkv: crack_user not sure what you mean

12:59 crack_user: like: (defn func [value] (let [var1 var2] values()))

12:59 I will search about letfn

12:59 justin_smith: CookedGryphon: this is one way that works https://www.refheap.com/93155

12:59 {blake}: CookedGryphon, Extend the shorter one with "repeat" and a default value that works.

13:00 dbasch: crack_user: it looks like you want to destructure function arguments

13:00 justin_smith: {blake}: trick is which is shorter :)

13:00 dnolen_: ed-g: pldb is built in and replaces the old logic db stuff

13:00 crack_user: dbasch: yep, it is avaliable?

13:00 {blake}: justin_smith, Duh. The one with fewer elements. =P

13:00 justin_smith: {blake}: I am just saying there is some logic, and some pitfalls, to be found there

13:01 dbasch: crack_user: http://stackoverflow.com/questions/12575161/destructure-parameter-of-a-clojure-function-while-keeping-the-original-value

13:01 oskarkv: crack_user http://clojure.org/special_forms at the bottom

13:01 ed-g: dnolen_: fantastic, thank you!

13:01 {blake}: justin_smith, lol, yeah...just being a smartass.

13:03 crack_user: dbasch that is it, thx for yout time

13:04 {blake}: justin_smith, I wonder--you could extend both out infinitely but stop when you hit a state where both lists supply the default?

13:04 mi6x3m: hey clojure, any way to print a string wihtout the additional logic of pr / prn?

13:05 hiredman: print

13:06 dbasch: ,(.write *out* "foo")

13:06 clojurebot: foo

13:06 mi6x3m: dbasch: yes write now I use (.write) on a (io/writer .... ) manually

13:07 dbasch: mi6x3m: you can rebind *out* and use print

13:08 mi6x3m: ,(require 'clojure.repl)

13:08 clojurebot: nil

13:08 mi6x3m: (clojure.repl/source print)

13:08 ,(clojure.repl/source print)

13:08 clojurebot: Source not found\n

13:08 justin_smith: {blake}: both? map is varargs

13:09 mi6x3m: dbasch: print just delegates to pr

13:09 according to my repl :)

13:12 {blake}: justin_smith, I didn't know "both?" was a thing.

13:12 justin_smith: {blake}: you used the word both

13:13 I am saying it could have 10 args, 2 of which are infinite

13:14 mi6x3m: does writer support :encoding ?

13:15 {blake}: justin_smith, I thought the premise of the original question was two sequences.

13:19 CookedGryphon: justin_smith: {blake} thanks

13:19 justin_smith: {blake}: oh yeah, I "invented" the n input generalization, good catch

13:19 it can be much simpler if you know it's only two inputs

13:34 mi6x3m: what namespace you put utils in, Clojure?

13:34 your utils *

13:35 misc.util?

13:36 justin_smith: group.util, where group is the umbrella owner of various libs in one project

13:40 mi6x3m: justin_smith: i settled for misc.util :)

13:46 technomancy: sorta apropos of the evolutionary algorithm discussion last night http://reverseocr.tumblr.com/

13:47 justin_smith: technomancy: oh yeah, that's a fun one

13:48 technomancy: I wonder what's the average ballpark number of revisions it has to go through

13:48 I guess it's harder because there's no gradual fitness, just binary

13:48 Glenjamin: it could do per letter presumably

13:48 technomancy: oh true

13:48

13:49 justin_smith: but many of those scribbles don't even have a matching letter count

13:49 it could play mastermind style

13:49 aperiodic: technomancy: there's also the same concept applied to face-detection: http://iobound.com/pareidoloop/

13:50 mi6x3m: technomancy: OCRad recognizes those things?

13:50 aperiodic: which is a little more interesting because it does have a fine-grained fitness measurement

13:50 justin_smith: aperiodic: plus you get to watch it iterate

13:51 a version of the reverse ocr that showed fitness and iterations would be cool

14:01 technomancy: mi6x3m: supposedly. wild, huh?

14:01 mi6x3m: technomancy: this project is quite entertaining to be honest

14:07 justin_smith: technomancy: pareidoloop is good at rendering old men, as seen near the shady areas near a pier on a foggy night

14:28 sorenmacbeth: ahoy

14:28 can someone with a far larger brain than myself help me with a macro?

14:29 https://www.refheap.com/ab0413ca651f4fe2fa39915df

14:29 kungi: sorenmacbeth: I can try. But my brain is not "far larger"

14:30 Bronsa: sorenmacbeth: you're passing the symbol x to the genmethods macro

14:30 amalloy: sorenmacbeth: you can't do that without eval. you want your macro to generate code at compile time based on values that exist at runtime

14:30 sorenmacbeth: I understand that `fields` is being treated a symbol instead of a sequence, but I don't understand why or how to fix it

14:30 Bronsa: sorenmacbeth: the feature of macros is that the arguments are not evaluated

14:30 csd_: Is there any way to make `cond` return nothing at all, rather than nil?

14:30 hiredman: no

14:30 amalloy: csd_: nil (n): nothing at all

14:31 hiredman: an expression must return a value

14:31 sorenmacbeth: amalloy: ok, that makes sense. where do I need eval?

14:31 technomancy: csd_: you can throw an exception

14:31 kungi: sorenmacbeth: first why not use k# and v# to generate symbols for k and v

14:31 csd_: i just dont want my list getting cluttered up with nils

14:31 amalloy: technomancy: or enter an infinite loop!

14:31 csd_: guess i have to filter them out somehow

14:31 Bronsa: sorenmacbeth: you'd need to make genmethods a function rather than a macro and eval the result

14:31 amalloy: csd_: use mapcat instead of map or whatever

14:31 technomancy: amalloy: hehe

14:31 sorenmacbeth: ok

14:32 my good friend eval

14:32 thanks folks

14:32 Bronsa: sorenmacbeth: not that I would recommend using eval if it can be avoided

14:32 llasram: Calm advice about `eval`

14:33 sorenmacbeth: Bronsa: yes indeed. I am unfortunately and old hand at abusing eval

14:33 I was hoping to avoid it

14:33 but once more into the breach

14:33 amalloy: indeed. do you really need this stuff to be determined by the shape of runtime objects, or do you know ahead of time what fields you'll be setting in various places?

14:34 sorenmacbeth: amalloy: has to be at runtime I'm afraid

14:34 llasram: sorenmacbeth: why OOC?

14:34 Bronsa: sorenmacbeth: a way to avoid using eval would be to use clojure.lang.Reflector/invokeInstanceMethod rather than the . form

14:35 sorenmacbeth: Bronsa: I saw that in a few example around the web. could you give me a concrete example?

14:36 Bronsa: sorenmacbeth: `(. ~obj ~(symbol "method") ~@args) becomes `(clojure.lang.Reflector/invokeInstanceMethod ~obj "method" (into-array ~args))

14:37 sorenmacbeth: note that this will use reflection each time the method is invoked -- it's going to be slow

14:38 amalloy: Bronsa: IMO it's easier to just use eval anyway. it's not immensely slower, and it's in a place where you clearly don't care about performance anyway; and it's easier and more readable than doing reflection, because it looks like code you're used to seeing anyway

14:39 sorenmacbeth: fwiw I'm just going to use eval, but I appreciate the example Bronsa

14:41 Bronsa: it would be nice if `.` automatically compiled to a reflective runtime call if the method/class was not available at compile-time

14:42 but that would have issues with locals I guess -- (let [toString 'hashCode] (. "foo" toString))

14:42 mi6x3m: Given that I am writing a viewer for about 30 examples showing various GUI stuff. I added a function to export separate Leiningen projects for all the demos but the code is dynamically generated and thus includes many dependencies which won't be needed by every example.

14:43 is this approach better than generating >30 mini Leiningen projects?

14:43 manually writing them I mean vs. automatically generated from the viewer

14:50 m1dnight_: I'm going to make a chess engine in clojure I think

14:50 Just not sure how yet

14:50 I want to make it a pearl of functinoal programming

14:51 jjmojojjmojo: 8 x 8 cylinders

14:51 justin_smith: m1dnight_: how much have you used clojure and / or fp so far?

14:53 SegFaultAX: Board games are actually really good for FP languages.

14:54 amalloy: SegFaultAX: well. it's very easy to write a correct algorithm, but if you end up actually wanting performance at some point you are in rough shape. performance matters a lot for board game AIs

14:55 SegFaultAX: amalloy: What I meant was it's trivial to model board games as pure functions over immutable data.

14:55 amalloy: SegFaultAX: right. i think i was agreeing with that, while pointing out that there are some problems too

14:56 m1dnight_: justin_smith: had a course @ uni last year in haskell, doing my thesis in clojure

14:56 dbasch: amalloy: it’s not that easy, e.g. I wouldn’t say writing a program that wins at tic-tac-toe is trivial

14:56 m1dnight_: and had a course on algorithms an datastructures (whole year course) in lisp

14:56 so I dare say I know wha ti'm doing

14:56 I just have to iterate over code a few times until it's clean

14:57 SegFaultAX: dbasch: Why? There is a very simple perfect algorithm for TTT.

14:57 amalloy: dbasch: i can't tell if you're just messing with me because TTT is solved, and a draw

14:57 or if you actually think that writing a good TTT AI is hard

14:57 SegFaultAX: "AI"

14:58 dbasch: SegFaultAX: amalloy what I mean is, if you give someone a computer and tell them “write me a program that wins at tic-tac-toe” it will probably take them a while and they will make lots of mistakes even knowing that the algorithm itself is trivial

14:58 justin_smith: artificial intelligence is easy, but just try artificial common sense

14:58 m1dnight_: Right, i'll need an AI player too

14:59 dangit

14:59 I could do forkjoin though and use some simple metric of probability

14:59 amalloy: SegFaultAX: *shrug* the term clearly applies, even if you think it's trivial

14:59 m1dnight_: that is like...thirty more levels of complexity way before you need to think about that

14:59 dbasch: amalloy: btw, of course I know that TTT was solved in 2008 by Deep Blue

14:59 m1dnight_: I know

15:00 I'm just not sure how to do it yet

15:00 I know I'll have a board and functions that make moves

15:00 and return a modified board

15:00 (defn make-move [piece white/red board]..)

15:00 I think that should do it

15:01 In haskell I could pattern match on the piece though, and write logic for each piece

15:01 wait a minute no, a player tells the proram "move to that point" and I need to check if it's a valid move

15:01 * m1dnight_ is going to stop thinking out loud

15:01 justin_smith: m1dnight_: you can use multimethods / protocols that each piece implements for a similar logic

15:01 m1dnight_: you would use objects? or what do you mean by "that each piece implements"

15:01 amalloy: m1dnight_: i would suggest modeling the board and ways to make moves first, then write a basic minimax algorithm that works for any game (taking in a function for producing legal moves from a position and determining whether a position is won), then start refining that with alpha-beta pruning or other simple stuff

15:02 justin_smith: m1dnight_: sorry, extended for each piece

15:03 amalloy: like, (defn minimax [position legal-moves make-move find-winner] ...) is a super-general function that will be very useful to write

15:03 csd_: why is () truthy? this trips me up so often

15:03 amalloy: csd_: because it is neither false nor nil

15:04 csd_: idk, imo everything empty should be nil/false

15:04 justin_smith: csd_: seq fixes this ##(seq ())

15:04 lazybot: ⇒ nil

15:04 dbasch: csd_: that would be a bad idea

15:04 amalloy: csd_: that's a very expensive decision to make

15:04 csd_: how so?

15:05 amalloy: well it makes every call to if a lot more expensive

15:05 dbasch: csd_: you’d have to special-case the empty sequence everywhere

15:05 amalloy: right now, (if x then else) involves two pointer comparisons

15:06 you instead want it to involve several polymorphic dispatches, some instanceof checks, and at least one allocation

15:06 csd_: ill just take your word for it :)

15:07 amalloy: it's not semantically clearer either. you get nil punning back, which is kinda nice, but you lose the ability to distinguish between {} and nil without some mental gymnastics

15:08 man, i am looking back at the minimax implementation i wrote when i was new to clojure, and it is weird

15:08 https://github.com/amalloy/ddsolve/blob/master/src/ddsolve/ai.clj#L53-L82 if anyone would like to gawk

15:09 hyPiRion: oh mutation

15:09 jjmojojjmojo: amalloy, it's good you put that TODO note in there

15:09 m1dnight_: amalloy, yeah, I've done a minimax before for tictactoe I believe

15:09 I had fun doing that

15:09 amalloy: jjmojojjmojo: hey, there's still time. tomorrow hasn't arrived yet

15:10 jjmojojjmojo: :D

15:10 csd_: amalloy: is that bridge?

15:11 amalloy: csd_: it is. you can see some evidence of that in like... https://github.com/amalloy/ddsolve/blob/master/src/ddsolve/mechanics.clj#L31 and https://github.com/amalloy/ddsolve/blob/master/src/ddsolve/core.clj#L18

15:12 csd_: yeah core.clj is what made me wonder

15:12 amalloy: anyway, this ended up being a correct algorithm but many orders of magnitude too slow

15:13 like i could analyze a six-card ending i think, if i was patient, but seven would take hours, and anything beyond that was probably going to blow the heap or something stupid like that

15:14 whereas good computers can analyze full 13-card hands in under a second, or a few seconds for particularly complicated deals

15:20 dbasch: the real challenge is writing an algorithm that can win at chessboxing

15:20 llasram: dbasch: tell me more...

15:20 dbasch: llasram: http://en.wikipedia.org/wiki/Chess_boxing

15:20 llasram: Fascinating

15:21 m1dnight_: wu tang :D

15:21 amalloy: dbasch: ITYM http://www.youtube.com/watch?v=TJy2kIWtyvQ

15:22 actually that video has a bunch of fluff at the beginning. there are more action-packed ones to be found

15:22 dbasch: someone should make BattleChessBots

15:23 llasram: someone: you totally should

15:23 dbasch: (inc someone)

15:23 lazybot: ⇒ 2

15:23 amalloy: dbasch: anyway, the algorithm for chessboxing is easy. 1) get a factory robot to enter the match 2) have it stall through the chess phase; 3) punch your opponent hard enough to rip a car in half

15:24 dbasch: amalloy: what if your opponent is a concrete wall?

15:24 amalloy: pretty sure that's not a problem for numerous factory robots

15:24 or enter a wrecking ball, if you know who you'll be facing

15:24 llasram: How good are factory robots at precisely punching fast-moving human-sized objects these days?

15:25 turbofail: given a sufficiently fast fist i'm sure a robot will have no problem with that

15:25 dbasch: amalloy: if we’re going to make assumptions, let’s win it for the special case where your opponents are very smart raccoons

15:25 m1dnight_: Darpa probably can hook you up with a good machine

15:25 Have you seen those robots?!

15:26 justin_smith: m1dnight_: attach a chess-piece mover to bigdog

15:26 m1dnight_: chess-piece mover :D :D :D

15:26 justin_smith: maybe strap watson on for fun

15:27 SagiCZ1: wow i missed that evolutionary algo discussion, gotta check it out

15:27 ~lazy-logs

15:27 clojurebot: lazy-logs is http://logs.lazybot.org/

15:27 dbasch: BigDog vs Watson: The Movie

15:27 justin_smith: m1dnight_: maybe mash it up with this robot https://www.youtube.com/watch?v=4WX58CZwyiU

15:27 amalloy: man, speaking of darpa. i saw yesterday that they think "a computer that can write code itself" is an problem can be solved with just $11M, presumably because none of the companies who can afford $11M have ever thought of doing this themselves

15:27 justin_smith: dbasch: LOL - and they team up like in a jodorowsky movie in the end

15:27 annelies: hi sweeties

15:28 justin_smith: hello

15:28 * llasram braces for spam

15:28 m1dnight_: hahaha, that ketchup robot is the most funny robot ever

15:28 annelies: is core.typed used in any significant projects?

15:28 I like static typing but I have never seen core.typed used.

15:28 m1dnight_: https://www.youtube.com/watch?v=CzXMoo4nlUM

15:28 dbasch: amalloy: who wouldn’t want a Neural Turing Machine? I’d support that on kickstarter just for the name

15:28 m1dnight_: This one with, as said, watson strapped on it

15:28 justin_smith: (inc m1dnight_)

15:28 lazybot: ⇒ 1

15:29 m1dnight_: and a ketchup bottle too

15:29 because why not

15:29 justin_smith: right

15:29 throws a brick at you, beats in in chess, and then spurts ketchup on you while you are down

15:29 spinning its hulk arms

15:29 m1dnight_: extra humiliation :D

15:29 dbasch: justin_smith: or it could be a reboot of Star Wars, with Watson as C3P0 and BigDog as R2

15:30 amalloy: justin_smith: it later turns out that the whole fight was as real as pro wrestling, and the ketchup is there to hide the lack of blood

15:30 justin_smith: right

15:31 Bronsa: annelies: I believe circleci is using core.typed

15:32 technomancy: llasram: http://i.imgur.com/PSaJyLu.gif

15:32 Bronsa: annelies: you might want to ask that question to ambrosebs though, he surely can answer that better than anybody else

15:32 justin_smith: annelies: this search result may be useful http://crossclj.info/fun/clojure.core.typed/ann.html

15:32 grilix_: sorry guys, is there any way to tell leiningen where to install the dependencies?

15:33 justin_smith: I assume everyone using core.typed is calling ann at some point

15:33 annelies: justin_smith: ohh nice

15:33 danke

15:33 dat website

15:33 amalloy: grilix_: you mean you don't like ~/.m2, or something else?

15:33 justin_smith: crossclj has an odd UI, but amazing info

15:34 Bronsa: (inc crossclj)

15:34 lazybot: ⇒ 1

15:34 justin_smith: (inc crossclj)

15:34 lazybot: ⇒ 2

15:34 justin_smith: we should add a crossclj plugin to lazybot

15:35 Bronsa: and by we you mean you right? :P

15:35 justin_smith: Bronsa: exactly

15:35 grilix_: amalloy: yeah, my project would run on a vm with a volatile fs (docker), the code is on a shared folder

15:35 justin_smith: I was using the "royal we"

15:35 {blake}: We are not amused.

15:39 amalloy: huh, crossclj is interesting

15:41 grilix_: oh.. setting the ":local-repo" on project.clj seems to work, I'll go with that, thanks!

15:41 noncom|2: where do i get the version of clojure that runs on android ?

15:41 i just need the bare clojrue.jar i guess...

15:41 Bronsa: http://crossclj.info/ns/org.clojure/core.typed/0.2.72/project.clj.html#outdated uuuh nice

15:42 justin_smith: oh sweet

15:42 I am going to be playing with crossclj.info more

15:43 and maybe we can crowdfund a usability study and a UX expert...

15:43 TimMc: good stuff

15:43 Bronsa: heh

15:43 TimMc: Just needs more spacing.

15:44 joobus: noncom|2: have you looked at lein-droid? I've used it. Using the clojure.jar on android is something you shouldn't have to do, i don't think.

15:44 justin_smith: TimMc: spacing, clear differentiation of types of content, differentiation of actions vs. information vs. information with optional actions related to said info...

15:44 joobus: noncom|2: https://github.com/clojure-android/lein-droid

15:44 razum2um: anyone knows best practice to test if I need "at least one expectiation to be true" if I'd write (expect true (some? pred coll)) it will fail with a very unclear message "expected true. got false"

15:44 noncom|2: joobus: well, i used clojure like that before, in an AIDE project :) now i am trying to embed it as a java lib in a java app :)

15:45 {blake}: Arcadia is in alpha. But it targets the Unity (game) system which targets Droid (and iOS, OS X, Linux, etc.).

15:45 noncom|2: btw, is #clojure-android dead ?

15:46 or is there any new IRC chat for that ?

15:46 joobus: noncom|2: the lein-droid repo was updated 2 days ago.

15:47 oh, nm, you were talking about the irc channel...

15:48 noncom|2: yeah.. i know that lein-droid is fine, but i wanted the jar solelu :) maybe i gt hte jar from a lein-droid project then :)

15:50 joobus: noncom|2: https://clojars.org/org.clojure-android/clojure

15:50 noncom|2: i think that is what lein-droid is using

15:50 noncom|2: joobus: oh, right! thanks! :)

15:59 joobus: anyone going to clojure-conj in DC on Nov 20-22?

15:59 http://clojure-conj.org/

16:03 {blake}: Anyone know if lein-fruit works for iOS? Or the level at which it works, rather?

16:10 m1dnight_: ~lazylog

16:10 clojurebot: I don't understand.

16:10 m1dnight_: ~lazylogs

16:10 clojurebot: Pardon?

16:10 m1dnight_: huh

16:10 give me the logs! :p

16:10 ~lazy-log

16:10 clojurebot: Pardon?

16:10 justin_smith: $lazy-logs

16:10 hrm

16:11 m1dnight_: ~lazy-logs

16:11 clojurebot: lazy-logs is http://logs.lazybot.org/

16:11 m1dnight_: aha!

16:15 afhammad: is there a way to run all project tests from the repl?

16:18 justin_smith: afhammad: load all namespaces that define tests, then run clojure.test/run-all-tests

16:18 afhammad: just remember to force reloading of the test namespaces if you edit the tests before you run the next time

16:21 afhammad: justin_smith: hmm ok. So theres no script that does this yet? i'm thinking loop through test folder, load namespaces and run them and i guess handle reloading after theyr run

16:22 justin_smith: afhammad: better to ensure they are reloaded before running

16:22 afhammad: true

16:23 justin_smith: afhammad: you could look at what lein test does

16:23 afhammad: justin_smith: yes good call

16:23 justin_smith: bonus - if you did it that way you could use test-selectors too

16:24 afhammad: in a repl I usually have a specific test namespace I care about

16:24 then I would use lein test to make sure all of the others still pass, once that ns is figured out

16:24 afhammad: in fact, I often just repeatedly run one test

16:25 with its fixtures, of course

16:25 afhammad: justin_smith: yeh thats probably more common

16:26 justin_smith: being a lisp, of course we all have our own special-snowflake unique workflow we prefer :)

16:31 csd_: note to self.. when translating from common lisp, do not try to keep the alists

16:34 mdrogalis: Is there an idiom, other than reduce/reduced, that invokes a function repeatedly until the last element out of that collection matches a predicate and returns a seq?

16:35 llasram: mdrogalis: maybe `iterate` (with `take-while` or such)?

16:35 justin_smith: mdrogalis: take-while?

16:35 mdrogalis: justin_smith: take-while doesnt allow function invocation.

16:36 llasram: That miiight work.

16:36 Yeah, I think that does it. :D Thanks.

16:36 justin_smith: mdrogalis: right, you would use iterate or repeatedly or whatever

16:36 hiredman: it is called unfold, and doesn't exist in clojure.core but I am pretty sure there are implemenations around

16:36 mdrogalis: No no, justin_smith. llasram got the points this time. :(

16:37 justin_smith: mdrogalis: hah

16:37 mdrogalis: Makes sense hiredman. Pretty sure I ask this question every 5-6 months.

16:37 hiredman: http://www.enrico-franchi.org/2011/08/clojure-unfold-and-anamorphisms.html

16:38 gfredericks: ~rest is uncons

16:38 clojurebot: A nod, you know, is as good as a wink to a blind horse.

16:39 hiredman: ~botsnack

16:39 clojurebot: thanks; that was delicious. (nom nom nom)

16:39 mdrogalis: Heh

16:45 amalloy: $whatis logs

16:45 lazybot: logs is is http://logs.lazybot.org/irc.freenode.net/%23clojure

16:46 amalloy: also works. i just told clojurebot about ~lazy-logs because SagiCZ1 said he couldn't possibly remember a two-part command or something like that

16:50 {blake}: O

16:52 Whoops. I'm trying to figure out how my app is linking in Bootstrap. I thought I understood but I'm confused again. It's pointing to /bootstrap/css/bootstrap.css, e.g., which is a directory that doesn't exist.

16:52 I had been using the bootstrap clojure library which wraps some middleware around the routing function, which I believe is what captures references to bootstrap and points them to the right place.

16:53 But it was out of date, so I took it out and uses the latest Bootstrap manually.

16:53 And it works locally, but when I WAR it up and deploy, it can't find /bootstrap/css/bootstrap.css anymore.

16:53 hiredman: https://gist.github.com/hiredman/4d8bf007ba7897f11594 it has been forever since I've done anything in my scratch.clj

16:54 kind of a neat circle there, unfold is a recipe for creating a thing to be folded or something

16:55 {blake}: hiredman, That's cool.

17:04 aaelony: can anyone recommend a clojure encryption library that can decrypt AES-256-CBC ?

17:12 {blake}: Hmmm. So, for some reason, "public/resources/bootstrap" in my clojure directory becomes "/WEB-INF/classes/public/bootstrap" in the uberwar.

17:13 technomancy: I've never used war files, but typically resources/ is the top-level directory of the project, not public/

17:16 sdegutis: Does anyone in here use paredit.vim? I'm having some weird issues with it changing keybindings that don't seem to be documented, and I'm wondering if it's a known/unwritten issue.

17:16 {blake}: technomancy, Well, at the top level (looking through a decompressor) there's META-INF and WEB-INF. Then classes and lib underneath with a web.xml file describing the servlet. lib seems to contain direct includes (clojure, clout, compojure, hiccup, etc.) as well as my code and a "public" directory.

17:17 Then "public" contains bootstrap. This is from my original structure which has resources/public/bootstrap.

17:17 aperiodic: sdegutis: I do. I haven't noticed that, but that could just be the keybindings I happen to use. What are you seeing?

17:18 technomancy: {blake}: that's beyond me; sorry

17:19 {blake}: technomancy, No problem.

17:19 sdegutis: aperiodic: Oh, I see. It's actually because I swapped ; and : that's causing it. Never mind, thanks anyway :)

17:20 m1dnight_: Hmm guys, I'm in a bit of a lock. I have modeled basic actors in clojure but now I'm stuck on how to build a list of actors such that I can address them with (send-message :actor_name :message)

17:20 I should need something like a global variable that contains a hashmap of :actor_name mapped to an object reference (a blockingqueue in java)

17:21 what do you guys recommend?

17:21 so that when a user types (send-message :actor_name :message) it expands to a lookup in that variable by means of a macro

17:22 noonian: you could do that with a function, don't need a macro

17:22 m1dnight_: e.g., expand to (let [queue (lookup-actor :actor_name)] (send-message queue :message)

17:22 but the user should not have to declare the global address list of actors and stuff

17:24 I want to hide all the bookkeeping and dirty work for using the actors from the user

17:24 amalloy: why are you building an actor system from scratch? it is not an easy thing to do well, and it's hard to see what advantage you get. if you are really sold on actors, i'd suggest picking a language/ecosystem that loves actors (ie, erlang)

17:24 m1dnight_: amalloy: for my thesis

17:25 so no, picking a language is not the solution :p

17:25 i just mimic the erlang actor model in my implementation

17:25 amalloy: that's not really an answer. is your thesis "building an actor system in clojure"? if it's anything else, the i don't think building an actor system in clojure is a good way to do it

17:25 m1dnight_: amalloy: yes, it is.

17:26 SagiCZ1: i have a directory structure with lots of zip files, how could i extract them all while keeping the directory structure? any ideas? i wrote some clojure script for this, but it corrupted about 30% of the files for some reason

17:26 justin_smith: SagiCZ1: clearly the solution is a new clojure program without any bugs in it

17:27 amalloy: SagiCZ1: are you trying to do this in clojure for some reason? i'd just do it with `find`

17:27 SagiCZ1: amalloy: i am just trying to do it somehow

17:27 could you elaborate the find method?

17:28 m1dnight_: find -type f -name "*.zip" -EXEC unzip {} \; something like that

17:28 hyPiRion: ,(find {:a :b} :a)

17:28 clojurebot: [:a :b]

17:28 m1dnight_: oh, I was thinking about linux commands :p nvm

17:29 {blake}: Curiouser and curiouser: If I create a JAR file and run it on my server, the Bootstrap works out just fine. If I generate a WAR and put it in my jboss-as, it can't find the Bootstrap.

17:29 SagiCZ1: im on windows

17:29 m1dnight_: nvm me :p

17:29 amalloy: SagiCZ1: oh man. windows. you are on your own, mate

17:29 m1dnight_: You could do it with an iso file though

17:30 the link is on ubuntu.com somewhere :p

17:30 * m1dnight_ shuts up

17:30 SagiCZ1: ok, and maybe the clojure way? what would be a way to unzip a file? i am using java.util.ZipFile but i suspect it for bugs

17:30 m1dnight_: but SagiCZ1 I don't understand how you could alter your dir structure when unzipping?

17:30 {blake}: SagiCZ1, Bugs in Java's ZipFile seem unlikely to me.

17:31 SagiCZ1: m1dnight_: imagine a file directory tree several levels deep and at the leaves, there are single files, each packed in its own zip archive.. i need the exact same thing, except all the files unpacked

17:31 *leafs

17:31 or leaves? idk

17:31 amalloy: leaves

17:31 m1dnight_: leaves

17:31 FIRST

17:31 amalloy: STRIFE

17:31 m1dnight_: euhm, I'm thinking

17:32 SagiCZ1: m1dnight_: please do

17:32 m1dnight_: So you would want the files in the directories and remove the zip files?

17:32 or have copy of the dir tree with a different root path?

17:32 dvath: I'm trying to call a Java method Values(java.lang.Object... vals) in Clojure as (Values. [{:foo 5}]) and it tells me that I cannot convert a vector to a java.lang.Object. Where can I find information for converting between the two?

17:32 SagiCZ1: m1dnight_: thats not important, both approaches are fine by me

17:32 m1dnight_: create a function that unzips a file at a certain path

17:32 amalloy: dvath: you want (object-array [{:foo 5}])

17:32 m1dnight_: test it to see if it works fine, if so, your unzipping is safe

17:32 amalloy: varargs are arrays

17:32 SagiCZ1: {blake}: btw, thanks for that information, i will focus on my code in that case

17:33 m1dnight_: and then?

17:33 dvath: amallow: I will give that a shot. Thanks!

17:33 m1dnight_: next, I would (dont shoot me guys) create function that returns a lazy list of all the zip files found (including their path, that is) and extract them to their location

17:33 amalloy: dvath: also, your client will tab-complete usernames. you need never misspell a name again!

17:33 m1dnight_: shouldnt be too hard, I guess

17:33 dvath: amalloy: Haha thanks!

17:33 SagiCZ1: m1dnight_: yeah i was traversing the structure recursively using DFS and joining the path from the parent nodes as i went, but as i think about it, your approach would be whole lot easier

17:34 m1dnight_: yeah, how you traverse your tree doesn't really matter

17:34 amalloy: SagiCZ1: see also file-seq

17:34 m1dnight_: just make sure you build up a list of proper paths

17:35 SagiCZ1: amalloy: wow, i was reinventing the wheel last 5 hours and came up with a square anyways.. thanks

17:35 m1dnight_: Yeah, disclaimer: I'm telling you base don what I know from clojure. I'm not a pro.

17:36 based*

17:36 SagiCZ1: m1dnight_: thanks for your thoughts, very helpful

17:38 lazylambda: fellas, I have a problem with this https://www.refheap.com/93175. I get an exception when I call the fibs macro. Any ideas?

17:39 amalloy: why in the world is fibs a macro?

17:40 lazylambda: amalloy, I want to generate the numbers at compile time

17:40 I am just playing around with macros

17:40 still learning them

17:41 amalloy: lazylambda: okay, so take as background the advice that this is a bad thing to actually do

17:42 pdk: can't the clojure compiler fold constant expressions at compile time

17:42 amalloy: but the issue is that you are indeed correctly computing some fibonacci numbers, and your macro is expanding to (0 1 1 2 3)

17:42 lazylambda: amalloy, I understand. I know that macros shouldn't be used when functions would do, I am just experimenting.

17:42 amalloy: and then it's like...what happens next is the same as if you typed (0 1 1 2 3) into the repl. it blows up because 0 is not a function

17:42 noonian: take returns a lazy sequence also, try (into [] (take ...

17:43 amalloy: noonian: that would fix the immediate problem but not really help with understanding it

17:43 noonian: you need to return something that wont throw an exception when its compiled as code

17:43 mj_langford: I have a 3.2 MB file full of code generated from PDF->HTML->hiccup. Any idea how to make this into something prettier and easier to excerpt out of?

17:44 noonian: amalloy: well, you already pointed out why it throws an exception

17:44 mj_langford: Not even confronting the semantic parts, I'll get to those, just is there a formatting library that helps with these sorts of "code as data" problems?

17:44 pdk: almost makes you yearn for xslt

17:44 amalloy: fair enough, noonian

17:45 lazylambda: what I understand so far is that (fibs 5) is expanded at compile time to (0 1 1 2 3), I tested that with (macroexpand-1 '(fibs 5)). But I still don't understand why it's throwing an exception when I call (fibs n) in the code?

17:45 joobus: mj_langford: what language is the code in?

17:45 Bronsa: ,(1 2 3)

17:45 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

17:45 mj_langford: Hiccup is a formatting library that generates html. It's a clojure library.

17:45 Bronsa: lazylambda: invoking a number as a function doesn't work

17:46 amalloy: lazylambda: because when you macroexpand something, it next gets evaluated

17:46 joobus: mj_langford: so it's 3.2mb of hiccup?

17:46 mj_langford: You got it :D

17:46 amalloy: and evaluating (0 1 1 2 3) is not good news

17:46 lazylambda: amalloy, ah I see..so it's not actually returning a quoted list?

17:46 mj_langford: I want to manually go in and extract some parts, but man, this is going to be rough if completely unformatted.

17:46 m1dnight_: ,`'(1 2 3)

17:46 clojurebot: (quote (1 2 3))

17:46 amalloy: lazylambda: you macroexpanded it: you tell me. do you see a quote in the value that's returned by macroexpand?

17:47 noonian: lazylambda: the evaluation semantics of unquoted lists in clojure is to treat the first item as a function, and try to apply it to the rest of the list

17:47 joobus: mj_langford: yeah, i got nuthin...

17:47 Bronsa: lazylambda: wrap the take call with a (list 'quote ..), see how macroexpansion changes and what happens invoking the macro

17:47 m1dnight_: ,(eval `'(1 2 3))

17:47 clojurebot: (1 2 3)

17:47 m1dnight_: there we go

17:48 Bronsa: (do we /invoke/ a macro?)

17:48 m1dnight_: eval is what happens after your macro expansion, so you hae to make sure it evaluates to a list, instead of to an application

17:48 annelies: (Thread/sleep (* 7 60 60 1000))

17:49 amalloy: that is an adorable way to part the channel

17:53 mdrogalis: Anyone else ever feel like Clojure could be served better with something less defy than defmethod? More like add-method?

17:53 TimMc: amalloy: I missed it.

17:53 amalloy: TimMc: (Thread/sleep (* 7 60 60 1000)), followed by /quit zzzzzzzzzzzzzzzzzzzzzzzz

17:54 TimMc: hah

17:54 At some point I thought I had an irssi plugin that would show part/quit/nick messages for people who were recently active. I guess I don't have that enabled.

17:56 lazylambda: Thanks folks, I got it now. I missed the part that what is returned from a macro is evaluated. I was treating macros like functions.

17:56 amalloy: TimMc: i don't mind people making fun of me for using pidgin, but its join/part hiding is smarter than what y'all usually have

17:56 (ie, it shows those things for recently-active folks)

17:58 Bronsa: looks like I'm the only one who doesn't mind not hiding join/part/nick changes

17:59 TimMc: Bronsa: How do you see anything? o.o

17:59 amalloy: Bronsa: if i ever turn that feature off, all the actual discussion gets hidden in a swamp of join/parts

18:00 TimMc: amalloy: Pidgin's fine, it just doesn't work well headless on a raspberry pi.

18:00 Bronsa: TimMc: I really don't find it distracting, my eyes skip them automatically

18:00 amalloy: TimMc: i find your requirements absurd

18:00 SagiCZ1: whats the correct construct when i want to process an increasing number of elements in a sequence?

18:00 [:a :b :c :d] -> [[:a] [:a :b] [:a :b :c] [:a :b :c :d]]

18:00 TimMc: haha

18:00 andyf: amalloy: Bronsa: 2 folks that might know this off the top of their heads! When CLJ-865 ignore-metadata-on-macro-invocations behavior happens, does that only happen for macros defined with defmacro? For example, it seems like type hints are preserved on forms like (.read args), macroexpanded to (. arg1 (read other-args))

18:00 amalloy: &(reductions conj [] '(a b c d))

18:00 lazybot: ⇒ ([] [a] [a b] [a b c] [a b c d])

18:00 SagiCZ1: i just need to process them with sideeeffects, no need to return it like this

18:01 Bronsa: ,(meta (macroexpand-1 '^:foo (.foo bar)))

18:01 clojurebot: nil

18:01 Bronsa: ,(meta (macroexpand-1 '^foo (.foo bar)))

18:01 clojurebot: {:tag foo}

18:02 Bronsa: andyf: *only* type hints are preserved in that case

18:02 amalloy: andyf: Compiler/macroexpand1 specifically attempts to preserve the tag in the case of (.foo bar)

18:02 andyf: Bronsa: Special case in compiler for :tag key of metadata I guess?

18:02 Bronsa: yep

18:02 andyf: Also for (ClassName. args) ?

18:02 Bronsa: preserveTag or some similarly named method

18:03 amalloy: you can search for "sym.name.charAt(0) == '.'" to see the relevant code

18:03 Bronsa: andyf: I don't think so

18:03 amalloy: andyf: there's no need to preserve a tag there

18:03 the value is known to be of type ClassName

18:03 ag0rex: SagiCZ1: something like this? (doseq [x (reductions conj [] '(a b c d))] (println x))

18:03 andyf: OK. Will look it up. Thanks. I'm working on an Eastwood linter for warning about probably-lost metadata on macro invocations, and trying to make it precise.

18:04 amalloy: andyf: it also works for ^String (Foo/bar x)

18:04 Bronsa: amalloy: uhmm, say I have foo(SomeInterface) and foo(SomeClass) where SomeClass < SomeInterface. could type hinting ^SomeInterface (SomeClass.) make any difference when invoking foo?

18:05 * Bronsa tries it out

18:05 amalloy: Bronsa: yes, probably so

18:05 Bronsa: amalloy: in that case the type hint would be valuable

18:06 amalloy: although i don't think the compiler actually supports that right now

18:06 in the code for expanding Foo., it doesn't preserve your tag

18:06 Bronsa: yeah right

18:09 andyf: So seems like brief description might be: Java interop forms except those beginning with . discard all metadata except :tag. Other macros discard all metadata unless explicitly preserved by the macro definition.

18:10 amalloy: andyf: Foo/bar does not discard it

18:10 it's the same as starting with .

18:11 andyf: ,(meta (macroexpand-1 '^{:foo 7} (Math/abs 5)))

18:11 clojurebot: nil

18:11 andyf: Looks like it throws that metadata away. Keeps :tag, I know.

18:12 amalloy: right. i'm quibbling with "except those beginning with .", not with "all metadata except :tag"

18:13 andyf: Sorry, my intended meaning is probably better expressed as: Java interop forms discard all metadata except :tag. Exception to that rule: If the first symbol in the Java interop form is ., then all metadata is preserved, because no macro-expansion occurs.

18:13 Bronsa: I just tested the Class vs Interface thing, yeah not preserving tag in ctor forms is an issue

18:14 amalloy: i see. yes, that sounds right, andyf. except that as Bronsa showed, the other exception is that (Foo. x) throws away all metadata

18:14 Bronsa: if you have to, you can write ^Interface (new Class), right?

18:15 andyf: I'll make a table with examples :)

18:15 Bronsa: http://sprunge.us/LBZP?clj

18:15 amalloy: and of course let-binding it to a hinted name works too

18:15 Bronsa: amalloy: I think so, let me test

18:15 amalloy: no, looks like a let binding is the only way to make it work

18:15 wait I'm dumb.

18:16 well it doesn't work anyway.

18:16 amalloy: Bronsa: i don't understand your paste

18:16 it doesn't seem to actually try ^Interface (Class. x)

18:16 Bronsa: http://sprunge.us/ALQK?clj

18:16 amalloy: this does ^

18:16 http://sprunge.us/CGOB?java this is the java file btw

18:17 wll tex input-mode

18:17 http://sprunge.us/MSdV?clj there.

18:36 andyf: OK, not a table, but I think a reasonable summary of behavior, except it doesn't give an example of how to write a macro that explicitly chooses to preserve metadata: https://gist.github.com/jafingerhut/5c9344fd4c20445eb64b

18:37 amalloy: andyf: looks accurate and thorough

18:38 andyf: Cool. That will probably end up in Eastwood docs on the linter, then, or something close to it.

18:39 Bronsa: andyf: there are also issues w/ primInvoke & inline btw

18:39 andyf: Bronsa: Issues where they eliminate metadata?

18:39 Bronsa: yes

18:40 one sec trying to find the ticket

18:41 hiredman: clojurebot: Bronsa is <repl>there are issues

18:41 clojurebot: A nod, you know, is as good as a wink to a blind horse.

18:41 Bronsa: andyf: this is going to take a while, JIRA and stuff.

18:41 gfredericks: ,(defn integers [] (interleave (range) (map - (rest (range)))))

18:41 clojurebot: #'sandbox/integers

18:42 TEttinger: hey, it's hiredman

18:42 hiredman: ~hiredman

18:42 andyf: Bronsa: No rush. It'll take me time to get the warnings precise for as much as I've got so far.

18:42 clojurebot: hiredman is an evil genius.

18:42 hiredman: for the record I never said that

18:42 TEttinger: hiredman, I'm almost as curious as ddellacosta and arrdem about why clojurebot ignores them

18:44 * TimMc adds TEttinger to the ignore list

18:44 TimMc: 3!

18:44 TEttinger: https://github.com/hiredman/clojurebot/blob/fd3d1a7c036118ba4a3984fa789227c138133630/clojurebot-facts/src/clojurebot/facts.clj#L58-L61 TimMc, it would be 5

18:44 TimMc: Oh yeah

18:44 I forgot about callen.

18:45 hiredman: TEttinger: more or less, at some point they did something, at this point I don't recall what, that made me feel the need to have clojurebot ignore them

18:45 Bronsa: andyf: http://dev.clojure.org/jira/browse/CLJ-1533 oh you reported this, lol

18:45 TimMc: TEttinger: I guess you could cross-reference the commit date with the IRC log.

18:45 TEttinger: it's a good bot.

18:45 yep

18:45 andyf: Bronsa: But good you mentioned it, since your memory for the corners is often better than mine :)

18:45 hiredman: TEttinger: and the whole re-evaluating people for not doing things is too much work, so I am not going to do it

18:46 Bronsa: andyf: note that even "(Math/abs ^long (f2 -3))" will emit a reflection warning

18:46 technomancy: isn't that what commit messages are for

18:46 hiredman: clojurebot's ignore list is like 5 people, mine is like 344

18:47 amalloy: Bronsa: isn't this a pretty different issue? the problem is not how you call abs or hint f2, it's the definition of f2 which is incorrect

18:47 hiredman: technomancy: in theory you could use commit messages for that

18:47 technomancy: hiredman: you don't store your irssi config in git?

18:47 I'm scandalized

18:47 TEttinger: unfortunately, http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-03-24.txt is by lazybot which ignores clojurebot

18:48 hiredman: technomancy: you are assume that I don't store it in git, is entirely possible I do but the commit messages are all "blarg"

18:48 amalloy: clojurebot: commit messages |are| for remembering why you dislike people - technomancy, 2014-11-11

18:48 clojurebot: c'est bon!

18:48 Bronsa: amalloy: no, one second

18:49 amalloy: http://sprunge.us/OYSP?clj maybe this is clearer

18:49 hiredman: (same terrible commit messages hold for clojurebot's source)

18:49 https://github.com/hiredman/clojurebot/commit/fdc537e03092b357aa8853757f891a831538b922 very informative commit message there

18:50 Bronsa: amalloy: the issue is that the compiler will transform (f2 1) in (.invokePrim f2 1) w/ preserving meta

18:50 amalloy: Bronsa: i'd say that f2's definition is still wrong: it should clearly be (defn f2 ^long [^long x] (inc x)). that it works for f1 is more like a coincidence

18:50 i don't want the compiler to compile that call f2 without issuing a reflection warning, because i'm boxing up stuff in a Long when i apparently intend not to

18:50 Bronsa: amalloy: well take (defn f2 [^long x] "foo") then

18:51 amalloy: hinting ^String (f2 1) will still not work

18:51 amalloy: Bronsa: okay. that i will buy as an issue

18:51 Bronsa: amalloy: it's the example that's debatable, not the issue

18:51 andyf: Bronsa: But the CLJ-1533 cases don't involve metadata being lost due to macroexpansion, right?

18:52 Bronsa: andyf: well, not by macroexpansion, no

18:52 andyf: it's lost at analysis time

18:52 SagiCZ1: is (filter #(and p1 p2)) faster than (->> coll (filter p1) (filter p2)) ??

18:52 lazybot: SagiCZ1: Uh, no. Why would you even ask?

18:52 SagiCZ1: sorry, didnt wanna trigger the bot!!!

18:53 Bronsa: SagiCZ1: why would you do that ???

18:53 lazybot: Bronsa: Oh, absolutely.

18:53 andyf: Bronsa: I'll keep a reminder about that behavior, but will probably focus a linter specifically on macroexpansions that lose metadata.

18:53 godd2: I think he always answers that after a double ??

18:53 lazybot: godd2: Definitely not.

18:53 Bronsa: andyf: sure, I just mentioned it in case it was relevant to the linter

18:54 TEttinger: ??

18:54 lazybot: TEttinger: Uh, no. Why would you even ask?

18:54 clojurebot: CLABANGO!

18:54 TEttinger: ???

18:54 lazybot: TEttinger: Yes, 100% for sure.

18:55 TEttinger: SagiCZ1, you might want comp instead of and there

18:56 SagiCZ1: TEttinger: good idea

18:56 TEttinger: ,(let coll [1 2 3 4 5] (filter (comp odd? #(< % 4)) coll))

18:56 Bronsa: uh, looks like the new :warn-on-boxed thing doesn't warn for f1

18:56 clojurebot: #<CompilerException java.lang.IllegalArgumentException: let requires a vector for its binding in sandbox:, compiling:(NO_SOURCE_FILE:0:0)>

18:56 SagiCZ1: TEttinger: wait, what? thats not the same though.. if p1 and p2 both return boolean

18:56 TEttinger: ,(let [coll [1 2 3 4 5]] (filter (comp odd? #(< % 4)) coll))

18:56 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Argument must be an integer: true>

18:56 andyf: technomancy: merci beaucoup for that reverse ocr link. I don't know why I find that so funny, but I do. http://reverseocr.tumblr.com

18:57 technomancy: pretty nuts

18:57 Bronsa: andyf: lol. stupid computers

18:57 TEttinger: I have no idea what went wrong there

18:57 SagiCZ1: TEttinger: well odd returns boolean

18:57 which u then feed into the comparison

18:58 TEttinger: ah

18:58 amalloy: TEttinger: you want every-pred, not comp

18:58 TEttinger: rather, < returns boolean

18:58 dbasch: both return boolean

18:58 TEttinger: the < gets executed first

18:58 SagiCZ1: yeah true. sorry

18:58 TEttinger: (inc amalloy)

18:58 lazybot: ⇒ 189

18:58 TEttinger: also

18:58 (inc SagiCZ1)

18:58 lazybot: ⇒ 1

18:58 SagiCZ1: OH YEAH BABY I WAS WAITING FOR THIS SO LONG

18:58 sry :x

18:59 now i can finally feel like a useful part of this community!

18:59 andyf: SagiCZ1: I was almost expecting a "Sorry, wrong window" follow-up :)

18:59 godd2: That's a big change SagiCZ1, an infinite% change, by the looks of it

19:00 SagiCZ1: totally meant for this window.. :)

19:05 i have a little off topic, just asking for opinion.. let's say i have some extremely large computation, maybe in clojure, basically a pure function which eats input and returns some number.. lets say it takes 14 days to compute on my computer.

19:05 Is there an online service which would let me rent some processing time to compute this faster? would Amazon Web Services make sense for this?

19:05 technomancy: it would make sense if you could parallelize it

19:05 justin_smith: SagiCZ1: yeah, amazon has very granular time periods for renting instances

19:05 noonian: aws would work if you just want to free up your computer also

19:05 andyf: SagiCZ1: There are many services to rent processing time. Whether they are faster depends.

19:06 technomancy: I don't know if you'd get that much of a speed boost

19:07 SagiCZ1: technomancy: maybe there are some options which let you rent extremely powerful cpu for couple hours? instead of multiple slow cpu for something like a website?

19:08 Guest1: Should look into cascalog. Get the data into s3 and run it on EMR

19:08 technomancy: SagiCZ1: yeah. IO performance is not great, but if it's CPU bound you could do well

19:08 I guess they do have SSD-backed intstances now too if you do need IO

19:08 aperiodic: if it's embarassingly parallel it would probably be fruitful to try to run it on a GPU.

19:09 SagiCZ1: technomancy: and do i need to paralelize it for multiple cores (which i would probably be able to after some tinkering) or do i need to be able to harness multiple computers (which sounds way too complicated)?

19:09 technomancy: SagiCZ1: depending on the problem it might not be that much more complicated to fan out to multiple machines

19:10 for map/reducey stuff

19:10 SagiCZ1: sounds good

19:10 Guest1: thanks for the tip

19:11 justin_smith: SagiCZ1: program in terms of threads and queues, and when you go multi-machine turn the queues into tcp-connections transporting the queued data

19:12 SagiCZ1: justin_smith: okay, didnt know the transition was doable

19:12 justin_smith: I mean that's a super high level description that leaves out a bunch of frustrations that you find your first time doing it, but it's the basic idea

19:12 :)

19:12 technomancy: https://github.com/technomancy/die-roboter <- proof-of-concept rabbitmq-based distribution

19:12 justin_smith: SagiCZ1: well, if it's good clojure code you already are not relying on shared state outside the messages on the queues

19:12 SagiCZ1: so the only overhead is setting up the connections and dealing with what to do when they go down

19:13 which things like rabbitmq are designed to do for you of course :)

19:13 SagiCZ1: justin_smith: thanks..

19:13 i really didnt know what to google, thats why i asked here

19:13 aperiodic: SagiCZ1: also if you haven't tried profiling and optimizing it at all yet I'd bet you could get it down to ~2 days without much effort.

19:14 SagiCZ1: aperiodic: it is a hypothetical problem, the code doesnt exist yet but since it will be crunching tens of gigabytes of data and computing something from them it will be inherently slow

19:14 TEttinger: SagiCZ1: no one's mentioned NVidia Teslas or Xeon Phis yet?

19:15 justin_smith: SagiCZ1: I guess I am being a little vague, but if you put some effort into it you can program with threads that share no more data than two machines communicating on a network would, so the the transition to using something like rabbitmq or hornetq or whatever is as seamless as possible

19:15 SagiCZ1: TEttinger: read about it.. but they are only for very specific problems.. like matrix multiplication.. you have to really design around it

19:15 TEttinger: tesla can handle any GPGPU type tasks

19:15 which is any embarassingly parallel tasks

19:16 SagiCZ1: justin_smith: i guess there is a lot of benefit to using a whole farm of pcs instead of just one powerful cpu, right?

19:16 TEttinger: not for electrical cost

19:16 technomancy: SagiCZ1: it depends what the data is being used for and whether the computation is likely to be run again

19:16 justin_smith: SagiCZ1: there's some flexibility to it

19:16 SagiCZ1: i see

19:17 i wish they taught me this in school

19:17 technomancy: well, freenode is like school but you actually learn practical things

19:17 TEttinger: it's a little beyond school level, I'd say...

19:18 I know some universities in China have access to phenomenal supercomputers, since they are on their campus

19:18 justin_smith: yeah, depends on the school - ncsa is at UIUC for example

19:18 TEttinger: but the average student probably doesn't get neat them

19:18 *near

19:18 SagiCZ1: TEttinger: yeah i also thought about using my student status to get some free computation time

19:19 TEttinger: but its only for open source and the like

19:19 aperiodic: SagiCZ1: ah, okay. this does sound like it should be fairly amenable to a map & reduce paradigm. partition the input to single-machine-sized, map over the partitions to produce a preliminary result in each partition, and then reduce the map outputs to get the final number.

19:19 TEttinger: what are you calculating, I wonder?

19:19 justin_smith: cljcoins

19:20 SagiCZ1: it would be an evolutionary algorithm optimizing some trading strategies for stock/bonds i am designing.. the basic concepts are pre-designed and i the optimizing would tune parameters

19:20 godd2: I call dibs on the genesis block

19:20 SagiCZ1: so the parallelism can be done for each generation of the evolution

19:20 aperiodic: holy data dependencies, batman

19:21 previous advice retracted

19:21 SagiCZ1: sorry if i was being too vague, i was trying to keep it short

19:21 TEttinger: yeah, since stocks (but not bonds, I would say), change so quickly, computation time matters here huh

19:22 dbasch: some people code HFT strategies in assembly

19:22 TEttinger: yeah, high frequency trading is a strange land

19:23 SagiCZ1: TEttinger: no, i think you misunderstood, it wont be real-time trading computation.. just tune the strategy once and then use it for months unchanged

19:23 TEttinger: oh ok

19:23 SagiCZ1: so the time is not critical but it must be reasonable

19:23 dbasch: SagiCZ1: and you’ll tune it based on past data, I imagine

19:23 SagiCZ1: dbasch: exactly

19:23 thats where the tens of gigabytes of input come from

19:24 dbasch: well, not like you could tune it with future data

19:24 * dbasch is captain obvious

19:24 SagiCZ1: :>

19:24 godd2: "Here's a picture of me when I was younger"

19:24 dbasch: I have a picture of my son from when he was -6 months old

19:25 SagiCZ1: so in light of these specifics, is there any other tip you could give me?

19:25 dbasch: SagiCZ1: don’t trade real money?

19:26 SagiCZ1: i meant for the computation

19:26 dbasch: SagiCZ1: have you used hadoop?

19:26 if not it may be a good excuse to learn it, and it’s a useful thing to know

19:27 TEttinger: also, tens of gigabytes of data might be faster if you can fit in in RAM

19:27 technomancy: hadoop is super clunky

19:27 dbasch: technomancy: agree, it’s not something you normally use unless you absolutely need to

19:27 SagiCZ1: i was thinking maybe how to get to the hardware.. and then deal with the software part.. but maybe hadoop would be a good start

19:28 hiredman: I have found parkour and emr to work surprisingly well for little one off things

19:28 technomancy: cascalog supposedly exposes the good parts of the hadoop infrastructure without the horrible APIs

19:28 dbasch: hiredman: yes, I use parkour too (although it was a bit painful to get it to work)

19:28 mkw5053: Cascalog is fun to learn and super easy to run on EMR

19:28 justin_smith: SagiCZ1: I read http://reverseocr.tumblr.com/ (which was brought up earlier) as a cautionary tale for those using algorithms to generate models - after all, according to the metrics that algorithm has, it succeeded in generating the target words

19:28 SagiCZ1: i feel like AWS is meant for... well web services.. can't find similar renting service focusing on single tasks run one-time

19:28 hiredman: technomancy: my understanding is cascalog pays a pretty high price for the abstractions it provides

19:28 technomancy: hiredman: yeah, maybe

19:29 but the hadoop infrastructure is only useful if you need to colocate data and computation (hdfs cluster) and can't afford to ship it around

19:29 (imo)

19:29 SagiCZ1: justin_smith: where is the tale? i just see the pictures

19:29 TEttinger: well it depends how parallel your task is, but if you just want to have 100+ GB RAM to store the data in and can afford to have 36 slow cores, http://www.ebay.com/itm/DELL-C6100-C6105-CLOUD-SERVER-6x-1-8GHz-AMD-6-CORE-HEX-CORE-144GB-RAM-3x-250GB-/181306790824?pt=COMP_EN_Servers&hash=item2a36ba13a8

19:29 justin_smith: SagiCZ1: the tale is "I used an evolutionary algo to make images that would be readable by OCR, these are the outputs"

19:30 mkw5053: EC2 m3.2xlarge has 30 GB of RAM, 160 GB SSD

19:30 justin_smith: that is, the resulting algo is only as good as the tester of the success condition

19:30 dbasch: you can spin an instance with 244GB of RAM

19:30 r3.8xlarge

19:30 TEttinger: how much would that run you, dbasch?

19:31 mkw5053: dbasch: that is awesome

19:31 SagiCZ1: justin_smith: that is true.. but the algo accomplished its task.. if the fitness function was to be readable by the ocr, then it succeeded.. but if the ocr scored at HOW readable it is, then you could evolve more and get better results

19:31 dbasch: TEttinger: $2.80/hr

19:31 TEttinger: nice

19:31 dbasch: not bad if you need it for a few hours once every few months

19:31 hiredman: technomancy: I've found it to do ok running in ec2 and reading from s3

19:32 SagiCZ1: hiredman: what are these: ec2 and s3 please?

19:32 mkw5053: Amazon Web Services

19:32 dbasch: I don’t know if they have those available as spot instances

19:32 TEttinger: elastic compute cloud, something storage something

19:32 justin_smith: simple "secure" storage

19:32 dbasch: simple storage service

19:32 SagiCZ1: thanks.. so we are still talking about aws, great

19:33 technomancy: S3: the only product with "simple" in its name that isn't a lie

19:33 justin_smith: oh, that's it, yeah

19:33 dbasch: secure it’s not

19:33 kenrestivo: lol https://github.com/hiredman/clojurebot/commit/b7cbf7edc499ae67999d0c64d7643bb4fdf3a2f4

19:33 dbasch: technomancy: simpledb was simple in the same way mongodb is web scale

19:33 amalloy: kenrestivo: it's been a while since we saw Lajla, hasn't it

19:33 kenrestivo: sssh, don't summon it

19:34 technomancy: amalloy: oh man you said his name now we're in for it

19:34 SagiCZ1: dbasch: and when you used it, was the performance any higher than my 5 years old computer?

19:34 kenrestivo: s3 is simple? ever tried to set up permissions in s3?

19:35 TEttinger: ,"Divine shadow?"

19:35 clojurebot: "Divine shadow?"

19:35 technomancy: kenrestivo: it inherits some brain damage from just being part of aws, but the s3-specific parts seem to be simple

19:35 kenrestivo: true.

19:35 dbasch: SagiCZ1: I never used the r3.8xlarge but in theory “32 vCPUs” should be better than most desktops

19:35 technomancy: if ec2 were as easy to use as s3 I probably wouldn't have a job

19:36 well

19:36 I would have a different job

19:36 TEttinger: ,"Divine Shadow"

19:36 clojurebot: "Divine Shadow"

19:36 justin_smith: heh

19:36 clojurebot: It's greek to me.

19:36 dbasch: technomancy: at least the e in ec2 doesn’t stand for easy

19:36 technomancy: lol

19:36 kenrestivo: i thought it stood for "enterprise" which stands for "excessively complex"

19:36 SagiCZ1: dbasch: thanks, and could you describe the workflow, to get the computation there? how do i access the instance? .. i know there is a tutorial, but maybe u could just sumarize it?

19:37 turbofail: stands for "elastic," to remind you that if you slip up it'll snap back and slap you silly

19:37 justin_smith: SagiCZ1: with ec2 you just ssh in

19:37 dbasch: SagiCZ1: you pick an AMI (typically a Linux distro), perhaps there is one that’s already set up for scientific computing

19:37 if not you need to do a bunch of package installation, and then save your AMI for the future

19:37 justin_smith: I mean you can choose to create a windows system if you want...

19:38 dbasch: once you have it ready, it’s like ssh’ing into any old linux box

19:38 SagiCZ1: justin_smith: no, you would all laugh at me

19:38 justin_smith: haha

19:38 just saying ec2 allows that option

19:38 SagiCZ1: that sounds really simple, thanks dbasch

19:39 dbasch: SagiCZ1: of course there are a lot of minor gotchas and tutorials, but for the most part it’s no different than setting up a linux box anywhere

19:39 SagiCZ1: i've done some ssh'ing into some remote computers, so i know it works great

19:39 justin_smith: SagiCZ1: remarkably, without any audio or video to worry about, setting up linux for your task is not bad at all

19:39 SagiCZ1: cool

19:39 andyf: Bronsa: Is tools.analyzer(.jvm) preserving metadata on forms like (StringWriter.) ? At least in the value of the :form key of the AST it seems to be.

19:39 SagiCZ1: justin_smith: thats what im thinking... i guess it could just show the progress in the console and then create some results file..

19:39 Bronsa: andyf: it should be, yes

19:40 justin_smith: SagiCZ1: for a remote box, better to use nohup or directly write to a log file

19:40 andyf: Bronsa: Does it get stripped out during emit-form?

19:40 Bronsa: I'm being lazy asking instead of just trying it, I know.

19:40 justin_smith: SagiCZ1: or you could be ghetto and run everything inside tmux or screen

19:40 Bronsa: andyf: it shouldn't :P

19:41 andyf: Bronsa: So, intentional difference from Clojure?

19:41 Bronsa: andyf: yes. it's all in the macroexpander impl

19:42 SagiCZ1: justin_smith: yeah, i just wanted to know which way to start the journey... this sounds promising. sorry for being quite offtopic here, i am afraid of people on other channels after some bad experience hah

19:42 dbasch: SagiCZ1: whenever I do something like that I typically build an uberjar and then run it with nohup in the background

19:42 justin_smith: SagiCZ1: well, it's all pretty relevant to clojure, since most deployments of clojure are to places like that

19:42 Bronsa: andyf: t.a.jvm's macroexpander preserves metadata for everything, macros too

19:43 andyf: that's a saner behaviour IMHO but if it's a problem for anybody, no big deal it's just a matter of providing a custom macroexpander that behaves like clojure's

19:43 SagiCZ1: cool, didn't know that either.. i actually know nothing about deployment in clojure, i was using strictly REPL so far, will have to learn that too

19:43 dbasch: SagiCZ1: I make sure that my program writes (and flushes) output often enough so that I know what’s going on

19:44 andyf: Bronsa: OK, thanks for the confirmation of behavior I'm seeing.

19:44 Bronsa: github's new clojure highlighting colors are destroying my eyes

19:44 SagiCZ1: dbasch: yeah i dont know whats uberjar, but i will remember your advice

19:44 dbasch: SagiCZ1: lein uberjar

19:45 SagiCZ1: dbasch: oh ok

19:45 dbasch: you typically don’t want to build (or have code) on aws, so you build locally and deploy everything in one jar ready to run

19:45 SagiCZ1: makes sense

19:45 Bronsa: andyf: now that I think of it, I can probably make that configurable in t.a.jvm

19:46 andyf: :clj-865-compatible true :)

19:48 Bronsa: andyf: the big issue with trying to be 100% clojure compatible is that some of the behaviour of Compiler.java is insane. supporting identical behaviour would mean willingly introducing bugs/edge cases in t.a.jvm and I'm not really into that

19:48 jack_rabbit: ((clj-compatible-p) true)

19:48 true

19:49 andyf: Bronsa: Understood. I'm happy if I get the behavior I need from it.

19:49 justin_smith: jack_rabbit: looks suspiciously like common lisp

19:49 jack_rabbit: Well I never!

19:49 andyf: Bronsa: And I am pretty sure I don't need :clj-865-compatible true behavior

19:49 * Bronsa *phew*

19:50 turbofail: nah, in common lisp it'd be (funcall (clj-compatible-p) t)

19:50 justin_smith: (defn common-lisp? [sym] (or (.endsWith (name sym) "-p") ...))

19:50 jack_rabbit: justin_smith, I like. :)

19:50 turbofail: or possibly (setf (clj-compatible-p) t) for maximum yuck

19:50 justin_smith: haha

19:50 jack_rabbit: justin_smith, I do like defun better than defn. defun has 'fun' in it!

19:51 amalloy: who let de fun out?

19:51 jack_rabbit: XD

19:51 justin_smith: jack_rabbit: I keep calling letfn flet

19:51 andyf: turbofail: Be careful when making fun on of the giants on whose shoulders you stand, for they may choose to wiggle

19:51 SagiCZ1: i started to learn lisps with Common Lisp quickly becoming familiar with setf only to be very dissapointed when later discovering clojure, that its not the clojure way to setf anything :)

19:52 jack_rabbit: justin_smith, a macro will take care of that mistake. Unfortunately, your fellow programmers will hate you forever.

19:52 justin_smith: jack_rabbit: how many times has that exact statement been made I wonder?

19:52 jack_rabbit: Me too. :)

19:52 s/Me/I wonder/

19:53 Probably disproportionately said about lisp code.

19:54 justin_smith: C/C++ would count there too I think

19:54 jack_rabbit: I was going to say that, but the 'take care of that mistake' part seemed out of place.

19:54 macros are rarely the solution to a mistake.

19:55 :)

19:55 (In C/C++)

19:55 justin_smith: macros: the cause of, and the solution to, many of programmings hardest problems

19:56 jack_rabbit: Just like alcohol

19:56 Glenjamin: do people use letfn often?

19:56 jack_rabbit: Every once in a while.

19:56 Glenjamin: i tend to find when i want to extract a local function, i already have a let at the right scope

19:56 so i just let [f (fn [])]

19:57 jack_rabbit: I see that more often than letfn, sure.

19:57 Bronsa: Glenjamin: I usually just use let, letfn only for mutually recursive functions

19:57 which happens rarely

19:57 justin_smith: Glenjamin: I like it for something that needs a lot of decomposition, but does not need to be its own namespace

19:58 Bronsa: letfn doesn't really give you much over let if you don't need the parallel binding stuff

19:58 jack_rabbit: I'm not even aware of parallel binding stuff. :)

19:58 justin_smith: Bronsa: right, but it's easier on my eyes if I am defining more than 3 functions in a block

19:58 Bronsa: it might save you a couple of keystrokes if you need to define a bunch of functions, but that prevents you from binding non fn locals in the same block

19:59 justin_smith: Bronsa: more about the eyeball movements than keystrokes, but sure

19:59 brain-cycles

19:59 Bronsa: ,(letfn [(a [] 1) (b [] (a)) (a [] 2)] (b))

19:59 clojurebot: 2

19:59 Bronsa: jack_rabbit: ^

20:00 jack_rabbit: wow.

20:00 Bronsa: justin_smith: I actually find letfn harder to parse than let+fn

20:00 TEttinger: ,(letfn [(b [] (a)) (a [] 2)] (b))

20:00 clojurebot: 2

20:00 TEttinger: nice

20:00 jack_rabbit: is (let* ... clojure or CL?

20:00 Bronsa: both

20:00 jack_rabbit: I can't remember.

20:00 ahh.

20:00 Bronsa: but they are different things

20:00 TEttinger: let* is a special form

20:00 Bronsa: clojure's let is cl's let*

20:00 Glenjamin: ,(macroexpand '(let [a 1]))

20:00 clojurebot: (let* [a 1])

20:00 Bronsa: clojure's let* is the underlying special form on top of which let is implemented

20:01 jack_rabbit: hmm.

20:01 turbofail: i.e. without destructuring and such

20:01 jack_rabbit: so what does let* mean? Looks the same given that macroexpand.

20:01 ahh.

20:01 Glenjamin: ,(macroexpand '(let [[a] [1]]))

20:01 clojurebot: (let* [vec__109 [1] a (clojure.core/nth vec__109 0 nil)])

20:01 jack_rabbit: ...

20:01 hmm.

20:02 Bronsa: let is basically just let* + destructure

20:02 Glenjamin: does that mean destructuring function definitions expand to let*?

20:02 jack_rabbit: gross. So I should probably never need to use let*

20:02 Glenjamin: ,(macroexpand '(fn [[a] [1]]))

20:02 clojurebot: (fn* ([p__134 p__135] (clojure.core/let [[a] p__134 [1] p__135])))

20:02 jack_rabbit: (directly)

20:02 Glenjamin: oh right, fn expands to let

20:02 Bronsa: jack_rabbit: right

20:02 Glenjamin: makes sense

20:03 jack_rabbit: I noticed clojure's let was equivalent to CL's let*. I just wasn't aware clojure had a let*.

20:04 Although I'm going to stay far away from clojure's let*.

20:04 justin_smith: jack_rabbit: see also fn*

20:05 bbloom: jack_rabbit: clojure's let* isn't like CL's anything

20:05 it's an implementation detailo

20:05 amalloy: bbloom: only core.logic has implementation-detailo

20:05 jack_rabbit: bbloom, right, I've gathered that.

20:05 bbloom, not implementation detail, but impractical.

20:06 bbloom: jack_rabbit: there's letfn, which is similar to parallel CL let, but only for recursive functions, not recursive values

20:06 amalloy: jack_rabbit: yes, implementation detail

20:06 bbloom: amalloy: (defn typo [in out] ...)

20:06 amalloy: let* in clojure is something that you should pretend doesn't exist

20:06 jack_rabbit: justin_smith, unfortunately, google makes anything with symbols in it impossible to search.

20:06 amalloy: it only exists to enable you to bootstrap let

20:06 bbloom: ~symbols

20:06 clojurebot: symbols are kind of fun

20:06 amalloy: unlike in scheme where let* and let are two useful things with different tradeoffs

20:07 bbloom: ~characters

20:07 clojurebot: excusez-moi

20:07 Glenjamin: anything with an * on the end is probably intended for internal use

20:07 amalloy: ~symbolhound

20:07 clojurebot: Titim gan éirí ort.

20:07 bbloom: clojurebot: characters |is| http://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/

20:07 clojurebot: Ok.

20:07 jack_rabbit: amalloy, cool. I don't know the standard, so I can't say whether it's an implementation detail or not.

20:07 Glenjamin: maybe the fact you can't google is intentional

20:07 bbloom: ~characters ; check out this link jack_rabbit

20:07 clojurebot: Gabh mo leithscéal?

20:07 amalloy: $google symbolhound

20:07 lazybot: [SymbolHound: Search Better. Code Better.] http://symbolhound.com/

20:07 bbloom: ~characters

20:07 clojurebot: characters is symbols

20:07 bbloom: clojurebot: forget characters |is| symbols

20:08 i suck at clojurebot

20:08 amalloy: you do it

20:08 :-P

20:08 amalloy: http://symbolhound.com/?q=let*+clojure

20:08 kenrestivo: we've got symbols... cause we've got a band. and we've got symbols in the band.

20:08 amalloy: bbloom: it can't really be done, because clojurebot is adversarial

20:08 bbloom: argh.

20:08 Bronsa: jack_rabbit: clojure doesn't have a standard

20:08 SagiCZ1: can i specify encoding for slurping?

20:08 jack_rabbit: Bronsa, still?

20:08 justin_smith: SagiCZ1: yes, its an optional arg

20:09 SagiCZ1: justin_smith: thanks

20:09 amalloy: jack_rabbit: clojure is a fiat language, not a standards language

20:09 justin_smith: ,(slurp "http://www.google.com" "x-Big5-Solaris")

20:09 clojurebot: WARNING: (slurp f enc) is deprecated, use (slurp f :encoding enc).\n#<SecurityException java.lang.SecurityException: denied>

20:09 jack_rabbit: amalloy, what does that mean?

20:09 Glenjamin: small italian car

20:09 amalloy: like ruby and python, the "standard" is whatever the most popular implementation does

20:10 kenrestivo: means there's a BDL, not a commtttee

20:10 jack_rabbit: Glenjamin, that's what I got from search. XD

20:10 justin_smith: &(slurp "http://www.google.com" :encoding "x-Big5-Solaris")

20:10 lazybot: java.security.AccessControlException: access denied ("java.net.SocketPermission" "www.google.com:80" "connect,resolve")

20:10 Bronsa: which sucks when the most popular implementation has bugs

20:10 jack_rabbit: amalloy, kenrestivo gotcha.

20:10 Why is that? should it not be moving towards a standard?

20:11 bbloom: jack_rabbit: why should it?

20:11 Bronsa: .. or are they intended behaviour? who knows

20:11 SagiCZ1: is 'UCS-2 Little Endian' encoding i could specify?

20:11 amalloy: jack_rabbit: probably (although not certainly) that would be better than having no spec, but that's a time-consuming project that nobody wants to do

20:11 bbloom: jack_rabbit: clojure's design philosophy is one in which you must prove value to justify doing something, not just do something b/c it's the thing you do

20:11 justin_smith: jack_rabbit: it's originally the product of a single motivated programmer, he never designated a standard

20:11 jack_rabbit: bbloom, then more people can produce compliant compilers/runtimes, and it'll be more resiliant.

20:11 The language will develop faster with more implementations, I would think.

20:12 bbloom: jack_rabbit: what does it mean to be "compliant"?

20:12 Bronsa: bbloom: my happiness isn't valuable then? :P

20:12 jack_rabbit: bbloom, compliant with the standard.

20:12 Glenjamin: speaking of which, what's the state of CinC these days?

20:12 amalloy: jack_rabbit: that doesn't convince me. languages with a standard and multiple implementationd don't change very fast

20:12 bbloom: jack_rabbit: the standard is Rich's Clojure implementation

20:12 if that runs it, that's clojure

20:12 jack_rabbit: fair enough.

20:13 Bronsa: Glenjamin: lots of work on the going on on the frontend, the backend is lagging behind a bit

20:13 amalloy: look at the time difference between C++99 and C++0x (which eventually became C++11): twelve years between standard versions!

20:13 bbloom: jack_rabbit: hell, two implementations done by rich don't even match up. clojurescript has intentionally different semantics

20:13 people code to an implementation anyway

20:13 the standards aren't that useful

20:13 jack_rabbit: amalloy, and even before C++0x, lots of compilers didn't even fully support C++99.

20:14 bbloom: jack_rabbit: evidence in favor of ignoring standards :-P

20:14 jack_rabbit: bbloom, fair enough. Makes lots of sense.

20:14 bbloom, right.

20:14 amalloy: i think a standard *is* useful, but not because it makes the language develop faster

20:14 i think it makes the language develop more slowly, which is good once you're basically "done" and want stuff to stabilize

20:14 bbloom: Gnu C++ and MSVC++ are pretty different

20:14 Glenjamin: just knowing whether all the clojure core functions exist in cljs would be neat

20:14 amalloy: Glenjamin: spoilers: no

20:14 {blake}: Heh. Didn't the K&R C bible say something like "types should be reasonably converted"?

20:15 Bronsa: bbloom: so you wouldn't like to have a definitive document setting in stone how in hell metadata should be handled, for example?

20:15 bbloom: Glenjamin: that would be nice :-P

20:15 jack_rabbit: Is there even more than one clojure implementation?

20:15 Glenjamin: i knew that, but i can never remember which ones

20:15 jack_rabbit: As of now?

20:15 amalloy: jack_rabbit: well, cljs

20:15 bbloom: Bronsa: i just don't rely on metadata :-P

20:15 clojurebot: I don't understand.

20:15 justin_smith: clojure, cljs, clojure-clr

20:15 jack_rabbit: amalloy, what?

20:15 bbloom: Bronsa: as far as i'm concerned, it's for exceptionally limited & obvious use cases, where it is immediatley converted in to ACTUAL data as fast as possible... or it's compiler specific hinting hackery

20:16 Bronsa: in the former case, i don't care about the corner cases. in the later case, it's impl specific anyway

20:16 {blake}: clojure-py, arcadia...

20:16 bbloom: the only reason i cared was b/c i was doing a clojure implementation (mostly for fun) and was surprised that some stuff broke

20:16 would have taken me as long to read the spec as to debug the issue directly, so *shrug* :-P

20:16 SagiCZ1: justin_smith: how do i know which encodings are supported? i tried to supply some nonsense string and it didnt complain

20:17 justin_smith: SagiCZ1: https://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html

20:17 SagiCZ1: thanks, i couldnt find it

20:17 justin_smith: of course look for the version of that page for your jvm

20:18 Bronsa: {blake}: I believe clojure-py is abandoned

20:19 {blake}: Bronsa: So, it's the most stable of all, you're saying.

20:19 Bronsa: in a sense :)

20:20 kenrestivo: i haven't yet found a really good use for metadata. friend makes extensive use of metadata and it just made my head hurt... i kept thinking why not put all this data in-band and make the data structure deal with it.

20:20 bbloom: kenrestivo: after much waffling back and forth, i agree

20:20 Glenjamin: i quite like https://github.com/circleci/bond/blob/master/src/bond/james.clj#L3 for metadata

20:21 Bronsa: kenrestivo: 90% of the times that I use it, it's to mimic multiple value return

20:21 {blake}: kenrestivo: We got tons of metadata here. Mostly because we're describing equations and code, and having metadata allows us to separate that from, well, metadata.

20:21 justin_smith: Glenjamin: I am severely disappointed that bond.james/bond is not defined

20:21 Glenjamin: you :require [bond.james :as bond]

20:21 justin_smith: oh, of course

20:22 gfredericks: metadata on references is still pretty useful

20:22 justin_smith: :require [bond.james :as bond :refer [007]]

20:22 Glenjamin: now that i look at this code

20:22 i could be done with a deftype that implements IFn

20:22 justin_smith: not a valid symbol of course

20:23 Glenjamin: but still, i quite liked the metadata approach to recording function calls

20:23 kenrestivo: hmm, i could see that. tests and instrumentation. also i think add-watch/remove-watch uses metadata internally.

20:24 Bronsa: kenrestivo: no they don't

20:24 gfredericks: Glenjamin: also implementing IFn is no fun (HA)

20:24 so the metadata approach is definitely easier in terms of impl & clarity

20:24 Glenjamin: oh right, you need to unroll all the aritiies

20:24 Bronsa: kenrestivo: watches come with IRef, has no relation with IMeta

20:24 kenrestivo: Bronsa: thanks

20:25 gfredericks: ,(def a (atom []))

20:25 clojurebot: #'sandbox/a

20:25 Bronsa: kenrestivo: IRefs should have a __watches field like IMetas have __meta

20:25 gfredericks: ,(add-watch a ::history (fn [r _ old _] (alter-meta! r update-in [:history] (fnil conj []) old)))

20:25 clojurebot: #<Atom@103b248: []>

20:26 gfredericks: ,(swap! a conj 12)

20:26 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IReference>

20:26 gfredericks: ,(add-watch a ::history (fn [_ r old _] (alter-meta! r update-in [:history] (fnil conj []) old)))

20:26 clojurebot: #<Atom@103b248: [12]>

20:26 gfredericks: ,(swap! a conj 12)

20:26 clojurebot: [12 12]

20:26 gfredericks: ,(meta a)

20:26 clojurebot: {:history [[12]]}

20:26 kenrestivo: cool

20:26 andyf: Bronsa: I don't understand you latest comment on CLJ-1325. Which one of those example compilation results do you find unexpected?

20:27 Bronsa: andyf: the second one

20:27 andyf: Is it the 2nd example, because the ret value will be boxed?

20:27 Bronsa: andyf: right

20:29 andyf: in this case boxing happens on the return value rather than on one of the args

20:30 bbloom: can we discuss metadata some more? i feel like Bronsa and i discussed it a bit once and i remember that i was still not sure why it didn't feel right... has anybody a good sense of the benefits, costs, and possible better designs of it?

20:31 i wonder, would it be nicer if it just always went away if you did any sort of "change" to a value?

20:32 (-> [] (with-meta {:foo 1}) (conj :x) meta)

20:32 ,(-> [] (with-meta {:foo 1}) (conj :x) meta)

20:32 clojurebot: {:foo 1}

20:32 bbloom: would it be better if that (and basically everything) lost the meta?

20:32 Bronsa: bbloom: that might be more consistent IMHO, yes

20:33 bbloom: Bronsa: but would it be desirable?

20:34 Bronsa: bbloom: it might be problematic in cases where you don't have control over what happens to some value you hand a function/macro

20:34 e.g. metadata gets lost in a value consumed by a macro and there's no way for you to add it back because that value doesn't exist anymore

20:34 but I feel like those cases are rare?

20:35 bbloom: Bronsa: wouldn't that be up to the macro then? basically "this macro preserves metadata on X and Y arguments" as a promise

20:35 gfredericks: bbloom: your criticisms are just about metadata on data, right, not metadata on references?

20:35 Bronsa: right now if I care about metadata I just wrap it in a with-meta, I can't trust any of the c.c functions to preserve metadata because some do and some don't and I can't remember which ones do

20:36 (and it's not always documented either)

20:36 bbloom: gfredericks: well metadata on references 1) works different and 2) is mutable, right?

20:36 gfredericks: bbloom: does 1 mean 2?

20:36 otherwise I'm not sure what "works different" means

20:36 but yeah it's mutable

20:37 bbloom: gfredericks: lol yeah, sorry

20:37 gfredericks: you could say it's fundamentally a different feature

20:37 bbloom: i've never actually used metadata on ref types other than vars, i guess

20:37 gfredericks: I think robert.hooke is a decent example

20:38 I believe it stores a reference to the original function as metadata on the var

20:38 Bronsa: I'd be ok with metadata only on refs + a way to attach type hints

20:38 metadata on values is untrustable

20:39 gfredericks: Bronsa: seems strange to call out type hints as the only thing you might possibly ever want to say about a piece of code

20:40 Bronsa: how would the current metadata-on-vars be implemented if you didn't first attach metadata to a symbol?

20:40 I know defn has an alternate proper-map form

20:41 Bronsa: gfredericks: just how defn does it (def meta sym val)

20:41 gfredericks: ,(defn foo [] {1 2} nil))

20:41 clojurebot: #'sandbox/foo

20:41 gfredericks: ,(meta #'foo)

20:41 clojurebot: {:ns #<Namespace sandbox>, :name foo, :file "NO_SOURCE_PATH", :column 0, :line 0, ...}

20:41 gfredericks: ,(get (meta #'foo) 1)

20:41 clojurebot: nil

20:41 gfredericks: or something

20:41 Bronsa: gfredericks: it goes before the argvec

20:42 andyf: does eastwood have a linter for this?

20:42 verma: hey anyone use vim-fireplace here?

20:42 gfredericks: ,(defn foo {:before-the "argvec"} [] nil))

20:42 clojurebot: #'sandbox/foo

20:42 Bronsa: I guess :unused-ret-vals would catch that

20:42 gfredericks: ,(-> foo var meta :before-the)

20:42 clojurebot: "argvec"

20:43 Bronsa: or even

20:43 ,(defn foo ([]) {:wut 1})

20:43 clojurebot: #'sandbox/foo

20:43 Bronsa: ,(:wut (meta #'foo))

20:43 andyf: Sorry, reading back now. Looks like :unused-ret-vals should cover it?

20:43 clojurebot: 1

20:43 gfredericks: oh dear

20:44 Bronsa: andyf: yeah it should

20:49 andyf: Bronsa: amalloy: Do you happen to recall how a defmacro can be specially implemented to use metadata on one of its invocations? Would it need to examine the &form arg?

20:51 amalloy: andyf: yes

20:51 gfredericks: andyf: yeah that'll give you metadata on the whole form, or the macro name itself; for the args, you have it right there of course

20:52 amalloy: you have to write something like (defmacro foo [& args] (-> `(sdlkl ~args) (with-meta (meta &form))))

20:52 of course i wrote a copy-meta function that makes that a little shorter: (defmacro foo [& args] (-> `(sdlkl ~args) (copy-meta &form)))

20:52 gfredericks: ,(defmacro andyf [] {:form (meta &form), :sym (meta (first &form))})

20:52 clojurebot: #'sandbox/andyf

20:53 gfredericks: ,^:foo ^:bar (^:baz :boom andyf)

20:53 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

20:53 gfredericks: ,^:foo ^:bar (^:baz ^:boom andyf)

20:53 clojurebot: {:sym {:baz true, :boom true}, :form {:bar true, :foo true}}

20:53 andyf: Ah, clojure.core/fn does, too: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L42-L47

20:55 verma: its a hard life being a vim user with clojure at least

21:05 tuft: is there a ring server people like for testing?

21:05 fast startup/teardown, single threaded, etc.

21:06 amalloy: tuft: i uh...well, ring. just call your handler function, instead of attaching it to jetty

21:06 zero startup, zero teardown, exactly as many threads as you create in your test

21:07 tuft: tuft: ah hrm. my use case is i'm trying to mock a remote service out. client library is out of my control as well. i'm guessing this approach doesn't listen on a port =)

21:07 er amalloy, haha

21:07 hmm, maybe i can get tricky using with-redefs though

21:08 amalloy: so what you're actually asking for is not how to test a ring program, but how to write a ring program that will let you test some http client

21:08 tuft: amalloy: yes that's correct

21:09 gfredericks: tuft: also maybe useful: https://github.com/gfredericks/vcr-clj

21:10 tuft: gfredericks: wow cool

21:11 gfredericks: so if i understand correctly, with this approach i'll just run my test against the live server once and against the recorded responses thereafter

21:12 gfredericks: tuft: right

21:12 amalloy: that sounds like it would test rather more strictly than you want: if the client changes any detail of how it talks to the remote server, the canned responses won't work anymore?

21:14 but maybe it's better than nothing

21:15 tuft: amalloy: i think i see what you mean. i lose some "fuzz factor" this way, as i can't ignore the specifics of the request when returning the response as easily?

21:15 seems like :arg-key-fn might apply, although not sure that works with the clj-http integration(?)

21:16 otherwise i think this has identical results to what i was going to do. it's an xmlrpc service i'm trying to mock out, so i was going to stand up a mock one to return captured responses from

21:17 brehaut: step one: back away from the xmlrpc

21:17 amalloy: brehaut: sometimes it's a necessary evil

21:17 brehaut: sadly true

21:17 hiredman: https://github.com/sonian/cartridge

21:17 justin_smith: https://github.com/brehaut/necessary-evil ; LOL

21:17 amalloy: tuft: sure, if that's your plan, then letting gfredericks do it automatically is better than doing it by hand

21:17 justin_smith: you're welcome

21:17 tuft: brehaut: yeah, sadly no choice there =\

21:18 amalloy: unless there's a plan you prefer i should consider =)

21:18 amalloy: not really. i just like nitpicking

21:19 tuft: brehaut: thank you for this library!

21:19 working great for me

21:19 brehaut: no problem.

21:20 tuft: (inc brehaut)

21:20 lazybot: ⇒ 24

21:42 akurilin: hey guys, question: jaba.jdbc currently wraps postgres driver version 8.4 . Current version of the postgres jdbc driver is 9.3 . What should one do to get that bumped up?

21:42 Is a PR good enough or is there a more complex process?

21:43 Just to make sure nobody's broken too hard in the upgrade

21:43 seancorfield: ping.

21:50 seancorfield: per the readme on the repo, there's a link to JIRA to create an issue

21:50 here http://dev.clojure.org/jira/browse/JDBC

21:51 akurilin: ok appreciate yet

21:51 Hmm looks like the url param I'm looking for might not be in until postgres jdbc 9.4 :( Might have to fork.

21:52 seancorfield: to be clear, java.jdbc has no dependency on postgres at all

21:52 it has been tested by some people to work on 8.4

21:53 i don't use postgres and i don't have any way to test it against postgres (since I don't want postgres on my work machine!)

21:53 akurilin: seancorfield: I'm looking at project.clj in current java.jdbc master and I'm seeing [postgresql "8.4-702.jdbc4"] under :dependencies

21:53 am I looking at the wrong thing?

21:54 seancorfield: that's an artifact of testing from a long time ago - there's no actual dependency on postgres

21:55 clojure contrib projects are built with maven, not leiningen

21:55 so pom.xml is the relevant thing here

21:55 project.clj is only used for local testing

21:55 akurilin: ah ok

21:56 seancorfield: you'll notice in the pom they have scope = test

21:56 so they are purely test dependencies

21:56 akurilin: That's true

21:56 so Korma's basically using its own postgres dependency here

21:56 seancorfield: you should be able to pull in whatever version of postgres you want and use it successfully

21:57 ah... korma... that does some slightly naughty stuff with java.jdbc i believe that may preclude you passing options the way you want?

21:57 akurilin: heh yeah you have to pass a few things through to c3p0 in the way it expects you to

21:58 in my case I need to pass assumeMinServerVersion to the postgres URL, but that's only available in the unreleased jdbc driver 9.4

21:58 seancorfield: I didn't even think Korma was still being maintained but I see someone has taken it over from Chris...

21:59 akurilin: It's "maintained"

21:59 seancorfield: and I see you've been sending PRs there... good stuff...

21:59 akurilin: yeah it's a bit of an uphill battle, I ended up forking it for our org

21:59 I'm not sure I want to commit to maintaining it at this point so a fork is a cheap short-term shortcut

21:59 but it won't solve the problem long term

22:01 gfredericks: haha I have a korma fork too; I can't even remember why

22:02 apparently it is PR numbers #102 and #115

22:02 * gfredericks pats his past self on the back for leaving comments

22:03 akurilin: Hmm this is somewhat worrisome, we either come up with a way to maintain it or we tell people to migrate off of it

22:03 I'm not against using straight clojure.jdbc, the dsl is pretty neat sometimes

22:03 and free c3p0, but it's not really hard to set up by hand anyway

22:04 seancorfield: and the java.jdbc docs even show how to set up c3p0 :)

22:04 akurilin: :P

22:04 gfredericks: my forking was probably almost two years ago; I have no idea how/if korma has changed since then

22:04 seancorfield: http://clojure-doc.org/articles/ecosystem/java_jdbc/connection_pooling.html

22:05 I know quite a few people ran into problems with Korma because of the way it "encapsulated" how it manages connections etc.

22:05 akurilin: I was actually thinking of moving off of korma anyway because I need multi-database support and right now you have to define separate entities for that instead of picking a conneciton

22:05 We're moving to write db and read db and it's a bit awkward to do with korma from what I can tell

22:06 seancorfield: sounds related to what you mentioned

22:06 seancorfield: Yup, that's the sort of stuff that folks run into problems with.

22:06 We just use raw java.jdbc and c3p0 at World Singles

22:07 akurilin: yeah I have both side-by-side right now and I always have to look down in shame when I explain how I ended up with that

22:10 seancorfield: how do you guys deal with permutations of the same query from leading to combinatorial explosion of data access layer functions wrapping slightly different SQL statements?

22:13 * tuft really just wants a good stand-alone DSL for SQL construction.

22:13 justin_smith: sql!

22:13 it's the best sql dsl

22:15 akurilin: haha

22:16 justin_smith: in all seriousness, I like the way yesql lets you just write sql, and then abstract that as something you can invoke in your code

22:17 seancorfield: tuft: looked at HoneySQL?

22:18 or SQLingvo

22:18 those are both linked from the java.jdbc home page

22:19 akurilin: seancorfield: do you use any DSL?

22:20 seancorfield: We use HoneySQL for our more complex reporting queries

22:20 akurilin: btw I just looked up something in the maven for the first time ever, talk about being shielded from java :)

22:20 *maven repo

22:20 ok neat

22:20 that's good to know

22:25 seancorfield: the developer that works on our reporting and analytics stuff loves HoneySQL - she's created some crazy complex data-driven visualization stuff

23:14 sx: I'm having some trouble understanding lein and dependencies. If I specify one dependency in my project.clj which in turn loads several more libraries, what is the correct way to override one of the sub-dependencies with a different version?

23:15 TEttinger: sx, that would potentially break the library that expects the original version

23:15 this is in general a can of worms

23:15 sx: TEttinger: yes true.. so I'm going down a dangerous and probably wrong path?

23:15 ok

23:15 TEttinger: there may be a way people fix this

23:15 I in the past have forked libraries to update dependencies, and installed mine locally with `lein install`

23:16 sx: that is helpful to know. i'll try another approach. thansk

23:16 TEttinger: there's also metaverse if a lib absolutely needs one version and your code absolutely needs another

23:17 $google github clojure metaverse

23:17 lazybot: [metaverse/verse.clj at master · technomancy/metaverse · GitHub] https://github.com/technomancy/metaverse/blob/master/src/meta/verse.clj

23:18 TEttinger: a bit more docs here https://github.com/Seajure/metaverse

23:18 technomancy: eeeeh it's more of a proof of concept

23:19 sx: top-level declarations override transitive deps

Logging service provided by n01se.net