#clojure log - Jun 03 2014

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

0:57 rs0: i just noticed something else about the Clojure 1.6.0 Java API

0:57 rurumate: oi clojure, when doing (binding [*snowflake* "special"] (do-things)), and do-things does concurrent things like starting threads, will the binding of *snowflake* to "special" be visible in these threads?

0:57 rs0: the public API supposedly consists *solely* of IFn and clojure.java.api.Clojure

0:57 however, IFn in turn depends on ISeq, which depends on IPersistentCollection...

0:58 tolstoy: rurumate: I got the impression that bindings are thread-local.

0:58 rs0: so the transitive dependency closure of those two classes contains more than just those two classes

0:58 rurumate: that binding will not be visible in separate threads. however, there are cases where tasks will run in the *same* thread, and therefore will see the bound value. for instance, new Thread().run() will not create a new thread; it will directly invoke the Runnable in the current thread

0:59 rurumate: another example is a ThreadPoolExecutor with a CallerRuns saturation policy. that can cause tasks to run in the submitter's thread, with the submitter's bindings

0:59 rurumate: there's apparently an InheritableThreadLocal type since Java 1.2, but Clojure doesn't appear to use it

1:00 rurumate: what about pmap or fork/join things like reducers?

1:01 rs0: unless the API makes a specific guarantee, you'd have to read the source code to find out. generally you should assume that dynamic bindings will not propagate across thread boundaries

1:02 ambrosebs: rs0: every API has an implementation

1:03 rurumate: experimentation now

1:03 rs0: ambrosebs: that's not really my point

1:03 ambrosebs: the actual IFn interface makes mention of ISeq

1:03 rpaulo: trying to use seesaw and getting: Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: No matching ctor found for class com.jgoodies.forms.layout.FormLayout. This is on (forms-panel)

1:03 rs0: ambrosebs: which makes ISeq part of the public java API, unless the contract is "you can expect ISeq to exist, but you can't expect any particular methods on it to exist"

1:04 rurumate: if bindings are not inherited, using them seems brittle because concurrency might be added to the program later on

1:04 ambrosebs: right? you still use the `seq` Var to get an ISeq

1:04 you don't actually use ISeq

1:05 tolstoy: rurumate: I think the pattern is that you rebind for a single thread so that you can "customize" that value JUST for a thread. Atoms make better "shared state" for threads.

1:05 rurumate: yeah but atoms are not automatically reset to root binding after the work is done

1:06 tolstoy: Maybe a macro?

1:06 rhg135: tolstoy, wouldn't it mess up any concurrent ops?

1:07 rurumate: also atoms are automatically shared between *all* threads which might be more than I wanted

1:07 tolstoy: (defmacro with-reset [some-atom] `(let [orig# @some-atom] ~@body (reset! some-atom orig#)).... blua blah.

1:08 rurumate: Ah, well. "Depends on the problem you're trying to solve." ;)

1:08 rs0: i've got my library virtually 100% compliant with the public java API, although i'm fudging a bit by including AFn in a few places because I didn't feel like reimplementing all that invoke() boilerplate. however i'm also evoking clojure.core/eval in order to define multimethods, and i'd really really prefer to do that through a Java API

1:10 rhg135: rs0, am indurstanding correctly that it's in java using the api to add functionality?

1:10 if so i'm in awe

1:10 rs0: rhg135: ?

1:10 ambrosebs: rs0: can you write the boilerplate in a real clojure file?

1:10 rhg135: rs0, a jav app basically using clojure as a tool?

1:11 ambrosebs: I guess I mean the calls to eval

1:11 rs0: ambrosebs: i'll probably investigate that route next

1:11 mange: rurumate: Take a look at bound-fn for maintaining bindings in different threads

1:11 rs0: ambrosebs: it's easy to invoke remove-method, which is an actual function

1:11 ambrosebs: not sure how much it will help to write a function wrapper around a macro

1:12 ambrosebs: rs0: mm

1:12 rs0: rhg135: i'm writing a java library that makes it possible to use clojure maps from java code without ruining them https://github.com/rschmitt/dynamic-object

1:13 ambrosebs: cool

1:13 rs0: it's a bit like defrecord ported to java

1:13 ambrosebs: where's the eval calls?

1:13 rhg135: uh, why can't it be in .clj and gen-class a java api?

1:13 rs0: ambrosebs: i haven't pushed them yet =)

1:14 ambrosebs: or even better just write the interface in java and do everythign else in clojure

1:14 rurumate: mange: nice find, thanks

1:14 ambrosebs: is thatpossible?

1:14 rhg135: yes

1:15 reify ftw!

1:15 ambrosebs: looks like you're using generics..

1:15 rhg135: generics are only hints for the compiler

1:15 rs0: ambrosebs: okay, *now* it's pushed

1:15 rhg135: they don't exist in bytecode

1:16 rs0: i could look at reimplementing this in clojure, but i doubt i will... it's already working

1:16 rhg135: ahh

1:16 rs0: i'd rather add new features than rewrite old ones. it's the same reason the Clojure compiler is still written in Java

1:16 ambrosebs: Don't the generics exist for the Java user? seems like we're throwing them out.

1:16 amalloy: ambrosebs: yeah, writing an interface in java and reifying it from clojure is a great interop plan. it's what i do when i need to put a java-friendly face on some clojure code

1:16 rs0: besides, i'm relying on a lot of JDK8 features, like default methods

1:17 ambrosebs: the generics are basically so that the static methods in DynamicObject return the correct types without requiring the user to downcast, which wouldn't be idiomatic

1:17 Jaood: abandon ship, swift is here

1:17 rs0: ambrosebs: within the library, it's complete downcasting anarchy and dynamic typing

1:18 rhg135: just use Objects and reflection

1:18 performance may suffer but freedom goes up

1:19 dissipate: Jaood, yeah, i'm going to totally abandon ship for swift!

1:19 rs0: rhg135: can you be more specific?

1:21 dissipate: BTW, what's with all these programming language names that it's impossible to do a proper search for, like 'go'

1:21 rs0: dissipate: the convention is to use the term 'golang' instead of just 'go'

1:21 dissipate: it's funny that people have to manually SEO the name of a programming language that came out of a web search company

1:22 dissipate: rs0, that is pretty ridiculous

1:25 rs0: i remember that people made the same criticism of C# when it first came out

1:25 because back in those days search engines would just drop all the weird symbols

1:25 apparently

1:26 ambrosebs: rs0: is there much of a performance difference with generics?

1:26 dbasch: rs0: I worked at a search engine in the late 90s, and we had to create special tokens like AT&T

1:27 rurumate: "quoting may work when searching c#"

1:27 dbasch: we had a bunch of one-off special cases in the indexer parser

1:28 rs0: ambrosebs: the generics are purely a programmer convenience thing for users of the library, who are going to be accustomed to static typing and OO

1:28 talios: rs0 - mmm, dynamic-object looks damn squishy! I like.

1:28 rs0: talios: squishy?

1:28 rurumate: dbasch: I'm in the search business too, bro :3

1:28 talios: so huggable :) nice a nice plush toy

1:28 ambrosebs: rs0: ah ok

1:28 yea looks like fun

1:29 dbasch: rurumate: I’ve been out of the search business for a while myself :)

1:29 rurumate: sad to hear it

1:29 dbasch: rurumate: 14 years, it was time to try something else

1:29 talios: hey ambrosebs!

1:29 rs0: ambrosebs: the strategy here is to bring Clojure's strengths to Java development in the most inconspicuous way possible. we lie low for a while, as the user base of dynamic-object grows steadily. eventually, clojure.jar is part of every Java deployment. then we begin Phase Two

1:29 ambrosebs: talios: hi!

1:30 talios: ambrosebs - was thinking we should get you back on the show for a 3rd round state of typed-clojure ;)

1:30 rs0: this is all explained in http://www.youtube.com/watch?v=2WLgzCkhN2g

1:30 ambrosebs: talios: oh yea sure :)

1:30 talios: let's try July sometime

1:31 talios: sounds goodo

1:32 ambrosebs - will schedule something and get back to you

1:32 ambrosebs: talios: thanks

1:32 dissipate: rs0, i doubt that is going to happen

1:33 ambrosebs: rs0: improved startup time should be phase zero :)

1:33 rs0: ambrosebs: it's really easy, just use nailgun. nothing solves everything forever like nailgun

1:33 (not actually)

1:34 i guess improved startup time could also be realized through the use of clojure-scheme, which compiles to native code by way of Gambit Scheme

1:35 dissipate: i'm not being completely serious; i mainly just wanted something that would make java development easier at my dayjob. in particular, i really wanted to get away from object serialization libraries. object serialization is a complete scam

1:36 dissipate: however, widespread availability of the Clojure runtime couldn't hurt adoption

1:39 dissipate: rs0, well, you shouldn't be doing Java development at your day job... that's a problem right there

1:43 rs0: dissipate: at least i'm not doing Scala development at my day job

1:43 dissipate: or, like, C++

1:44 dissipate: rs0, *shiver* yeah, that's pretty bad too

1:47 dbasch: rs0: you know, there are Clojure jobs

1:50 dissipate: dbasch, i think i could only do the remote ones

1:50 rs0: dbasch: is the Clojure job market a buyer's market or a seller's market?

1:51 dbasch: or is it too illiquid to say?

1:54 dissipate: rs0, probably a lot like any other job market for a niche language

1:54 rs0: dissipate: i'm not really familiar with them, or with the general experience of hunting for jobs based on language

1:57 beamso: i've seen clojure job ads locally, but clojure is typically listed as one of several languages you're required to be familiar with

1:57 dissipate: rs0, for a niche language, there are fewer jobs, but the employment tends to be a bit longer term with more loyalty on both sides. not always, but more so than 'big tent' languages.

1:58 rs0, the flip side of that, is that there can end up being a lot more tasks for dealing with legacy code.

2:01 dbasch: rs0: I think it’s too illiquid to say

2:01 for my last contract gig I wanted to use Clojure in a Java shop. The compromise was Scala, and it didn’t work out too well

2:02 Scala/Java interop is type hell

2:18 rs0: dbasch: Scala is basically C++ for the JVM

2:19 bob2: that's unfair

2:19 it's even more complicated than c++

2:19 rs0: dbasch: different versions of Scala aren't bytecode-compatible forwards or backwards, which means that Scala and Java interoperate better than Scala and Scala

2:23 bob2: i think that Scala and C++ are both examples of very solid technical competence pursuing exactly the wrong principles

2:23 bob2: those languages weren't just built by incompetent amateurs like PHP was

3:41 hellofunk: Does anyone know how to specify that a route in Compojure is an HTTPS (secure) route?

3:57 blur3d: hellofunk: you could try https://groups.google.com/d/msg/compojure/XWluMvf4CBs/OJVc_IVPsxUJ

3:57 hellofunk: blur3d thanks I found that as well.

3:58 blur3d: I dont think it handles it any other way… you just have to add handlers for it

4:01 ddellacosta: hellofunk: this is basically what you want to do: https://github.com/noir-clojure/lib-noir/blob/master/src/noir/util/middleware.clj#L59-L68. You could probably just use that with a subset of your routes too

4:04 hellofunk: Thanks ddellacosta. I may have another question for you in a while once I exhaust my current attempts to get a user's email address from the Google access token.

4:05 ddellacosta: hellofunk: sure thing

4:20 hellofunk: ddellacosta you used drawbridge much? I'm starting to the feel the pain of remote development. every little change I must push to heroku. I can't do it on localhost since there are URI that requests must come from to google

4:21 ddellacosta: hellofunk: what is the google requirement, is that for openid or oauth2?

4:21 hellofunk: oauth2

4:23 ddellacosta: hellofunk: assuming you are using mac os x or linux to develop, just change the url to be localhost in your /etc/hosts

4:24 beamso: i've done oauth work where the URL i used was localhost :/

4:24 ddellacosta: hellofunk: ^ that's the other alternative, just create an alternate app in the google settings using localhost. That's how I test oauth2 anyways

4:24 hellofunk: ah ok, that would probably do it.

4:42 noncom: is it ok to have a package and ns with a same name, on the same level?

4:42 say i have "core.clj" and package "core" on one level

4:42 won't there be any problems with requiring or other ns-related management?

4:44 clgv: noncom: that's fine, I have seen an idiom several time where the implementation details were in such a namespace, e.g. my.lib as API namespace and my.lib.* with implementation namespaces

4:45 noncom: yeah, that seems like exactly my case :)

4:45 clgv: noncom: the folder name is only the last but one package in the fullqualified package name

4:46 noncom: oh, thanks for the correction

4:46 clgv: do you work with ccw?

4:46 clgv: in java that's different. there the fullqualified package consist of all the folders below the root source folder.

4:46 noncom: yes

4:46 all the time^^

4:47 noncom: clgv: ummm.. could you give a little example on difference between java and clojure package concept?

4:49 clgv: java: src/my/lib/MyClass.java => package "my.lib", clojure: src/my/lib/myns.clj => package "my.lib.myns" where function in the ns are classes with that package

4:50 noncom: aah, that's what

4:50 clgv: hence src/my/lib.clj => my.lib and src/my/lib/impl.clj => my.lib.impl

4:52 noncom: so that in the case that i first mentioned, with "core" and "core.clj", the compiled contents of the core.clj get laid together with the "core" folder contents ?

4:52 Glenjamin: does it help to think of clojure functions as java classes?

4:52 noncom: Glenjamin: i suppose it depends on the context of your thinking

4:53 Glenjamin: it's always package.package.package.Class

4:53 noncom: yeah

4:53 Glenjamin: but in java only the Class has a file, but in clojure the namespace (which is the last 2 bits) has a file

4:54 i'm unsure if that helps, but i think i get what clgv is saying - and it had never ocurred to me before

4:57 clgv: noncom: no in your case ...core.clj and ...core/some.clj have different namespaces, in that concrete examples the difference is an additional "some" package at the end

4:57 hellofunk: ddellacosta just to confirm, while most Friend credential functions take a map, the cred fn to your oauth2 workflow just takes the actual access token, not a map

4:58 clgv: noncom: though it depends which kind of clojure constructs you consider. since there is a difference between functions and deftype/defprotocol/defrecord

4:59 noncom: just AOT compile your whole project and investigate where the implementation ends up

4:59 ddellacosta: hellofunk: yes, you can see a simple example here: https://github.com/ddellacosta/friend-oauth2/blob/master/test/friend_oauth2/test_helpers.clj#L65-L67

5:00 noncom: okay, i will experiment more into this field. really, i saw all thsese things, but did not pay much attention, but now you got me interested

5:00 clgv: but ok, back to ccw

5:01 clgv: noncom: conclusion: your namespace layout is just fine ;)

5:01 noncom: have you ever tried to generate namespaces from templates? like have a command in your repl that creates a namespace in your project, filling it with a template? the problem i get is that eclipse does not recognize the created stuff..]

5:02 clgv: noncom: also after refreshing the project?

5:02 noncom: clgv: here is my q on so: https://stackoverflow.com/questions/22784284/creating-a-source-package-folder-in-a-counterclockwise-project-programmatically

5:03 but the last statement about eclipse recognizing extensions is i am *not sure of*

5:03 yes, refresing does not elp

5:03 i though just maybe you've tried that

5:04 it does not really always recognize the created structure of folders and source files, be it .java or .clj

5:04 clgv: noncom: does "leiningen->reset project configuration" help?

5:04 noncom: and sometimes does

5:05 clgv: does that actually have consequences on a freshly started REPL?

5:08 noncom: clgv: i do not remember.. it was some time ago, and now i'm coming back to the issue. i can't find that test project. i think i have to re-create the situation and test what you suggested..

5:08 this will only be possible much later in today, so i will try and then, maybe tomorrow, write back..

5:08 clgv: ok np.

5:09 "reset project configuration" should reset the classpath settings to what they need to be

5:09 hellofunk: ddellacosta it is rather interesting that the oauth2 callback URL is taken out of the equation when integrating with Friend which instead specifies the landing-uri. someday I should pour through the source to figure out how that works.

5:10 ddellacosta: hellofunk: what do you mean?

5:11 hellofunk: ddellacosta i mean once you get through the google login form, you are taken back to the site landing page specified in the :default-landing-uri part of the friend/authenticate rather than the callback url specified with Google

5:12 beamso: are you sure you haven't noticed it redirect from the callback url to the default landing uri?

5:12 it could just be very quick

5:12 hellofunk: beamso well perhaps it is, but that's nifty that Friend manages to override that

5:13 beamso: isn't it more that google redirects to your specified uri, your app takes the tokens out and links them to a user's session then redirects to the default landing uri?

5:14 i have to admit i did the oauth stuff with a phonegap app

5:14 hellofunk: beamso well that depends on the library you are using. i tried another oauth2 library and it just honored the google callback url, you do what you want on that page.

5:15 ddellacosta: hellofunk: try turning off https://github.com/cemerick/friend/blob/master/src/cemerick/friend.clj#L152

5:17 hellofunk: but you do certainly land on the callback before being redirected: google certainly doesn't know anything about your site other than what you tell it

5:18 hellofunk: ddellacosta ok, it's just really fast and I find rather interesting that Friend takes over there. I don't mind it, just shows the extent of operation that chas did.

5:18 ddellacosta: hellofunk: yes, it's a nice feature to have it redirect back to the page you intended to go to, agreed

5:18 hellofunk: ddellacosta which would work regardless of the workflow in action

5:19 ddellacosta: yep

5:19 hellofunk: unifies them

5:55 when you have a mutable atom in a ring server page, does each separate visitor to the server get only the initial state for the atom, or are changes to that atom visible to all visitors?

5:56 justin_smith: hellofunk: atoms are synchronized in state across threads

5:56 so changes made in one request should be visible to another

5:56 hellofunk: ok, thanks.

6:17 so ddellacosta, i'm using this guy's little fn to pull the email from google from access token: https://coderwall.com/p/y9w4-g

6:18 ddellacosta that fn uses a different oauth library. i tried to use his function with the access token returned from your oauth2 but that google user email fn seems to depend on the additional parts of the access token that your oauth2 strips out

6:20 ddellacosta for example your returns a nice and clean map with just :access-token. google returns a larger map that also includes expiration time, and :id_token and more. so whatever reason, those seem necessary when using the google email fn mentioned above.

6:21 ddellacosta: hellofunk: as I said previously, friend-oauth2 does not collect or use this information as it is not part of the oauth2 spec. If you want to use *all* the data google returns you'll need to patch friend-oauth2 yourself

6:22 hellofunk: otherwise, you'll have to use clj-http w/ the default way of accessing Google APIs via oauth2, what I linked you to yesterday

6:22 hellofunk: https://github.com/dakrone/clj-http, https://developers.google.com/accounts/docs/OAuth2?hl=en

6:23 hellofunk: ddellacosta ah ok, so Google is returning things in its oauth2 that are not actually oauth2-specific?

6:23 ddellacosta: hellofunk: yes, although I guess they may be part of the OpenID connect spec which I have not implemented as of yet

6:24 hellofunk: in any case, to save yourself some pain you may want to just patch friend-oauth2 for the time being to intercept what Google is sending you back, that will be simpler than doing a separate api call

6:24 hellofunk: ddellacosta ok; it is a bit confusing that OpenID Connect seems to be a part of the OAuth2 process, as if they are synonymous

6:25 ddellacosta: hellofunk: it is an extension to oauth2, and I was not aware of it (and may not have been around) when I started working on this

6:26 hellofunk: ddellacosta when patching a library such as yours, I suppose that instead of linking to clojars i'd just download the source and place it along with mine?

6:28 apologize for how green I am with some of this stuff, general dev workflow, etc

6:29 ddellaco_: hellofunk: sorry, got disconnected

6:29 hellofunk: no prob ddellaco_ did you see my question?

6:29 ddellacosta_: hellofunk: the simplest way is just to include the workflow itself in your codebase

6:29 hellofunk: and replace it at such a point that the openid connect flow is supported

6:30 hellofunk: which will be Real Soon Now

6:30 hellofunk: ddellacosta i've often wondered how github users collaborate; if multiple people are manipulating the same code base, I guess none of them would be using project.clj to specify dependencies, they'd just have the code in the src/ folder

6:31 ddellacosta_: hellofunk: ...most of the time if you are building a production app this is not an issue, in terms of dependencies

6:31 hellofunk: but it sounds like you need this ASAP so this is the best thing I can suggest

6:32 hellofunk: ddellacosta when i look at a repo and see many contributors to it, i assume this means that most of them would have the entire source mirrored in their project rather than using a lein dependency, is that sorta right?

6:34 ddellacosta_: hellofunk: I'm not sure I follow; if there are many contributors to a clojure project, it just means folks have patched it and submitted a pull request/committed at some point. It doesn't indicate anything about how the contributors have used it. Perhaps they used checkouts to test it in the context of another project, or just ran lein install...if that's what you mean.

6:36 hellofunk: you don't necessarily even need to be running that project in the context of another one to test and make changes, if that's what you were getting at--but I'm not entirely sure where you were coming from with that question, sorry.

6:36 hellofunk: ddellacosta, thanks -- having nor formal or institutional training or education in modern development workflows, and working mostly by myself, i'm often frustrated by how little i know about the general process that everyone takes for granted

6:36 ddellacosta_: hellofunk: ah, gotcha. Don't feel bad about asking questions, and sorry if I'm not always giving you the best responses.

6:37 hellofunk: just be patient and it'll become more clear

6:38 hellofunk: on that note, unfortunately I have to get going, but ping me again if you have questions. Hopefully some of the info I gave you will get you on your way.

6:38 hellofunk: ddellacosta_ thanks again!

6:38 ddellacosta_: hellofunk: np, cheers. :-)

6:59 cfleming: Hi everyone - I'm wondering how :refer-clojure :exclude works in cljs. Does it exclude symbols from cljs.core, macros, or both?

7:16 ambrosebs: *checks the source*

7:17 cfleming: ambrosebs: I tried that, but still wasn't sure :-)

7:18 ambrosebs: looks like it excludes everything.

7:19 try it: (ns my.ns (:refer-clojure :exclude [for])) (for [a [1]] a)

7:19 :)

7:19 cfleming: So for a given name, it'll exclude it from both? That was what I suspected, but couldn't tell.

7:19 Hehe

7:19 ambrosebs: yea I think the core-name? predicate in cljs.analyzer resolves core vars/macros

7:19 cfleming: The problem is I need a symbol defined as both a macro and a sym - I could set up a test case but I'm lazy :-)

7:19 ambrosebs: and that takes :excludes into account

7:20 cfleming: Ok, thanks - I'll assume that for the moment.

7:20 There's not much doc about a lot of these cases in cljs

7:20 ambrosebs: I'm sure we'll get to 0.1 one day.

7:21 cfleming: I'm working on indexing cljs now, it's surprisingly tricky

7:22 ambrosebs: what does that mean?

7:22 cfleming: I'm working on indexing cljs for Cursive.

7:23 It's tricky because the same name can and frequently does refer to two things.

7:23 ambrosebs: oh. hi colin :D

7:23 cfleming: :)

7:23 Hi Ambrose

7:23 ambrosebs: (thought your name looked familiar)

7:24 cfleming: Of course, it's additionally tricky because there's no doc about how this stuff actually works, and I'm not familiar enough with the code yet.

7:24 ambrosebs: and you're getting lazy

7:25 cfleming: Fortunately Clojure smiles on laziness.

7:25 ambrosebs: agreed

7:25 cfleming: That's my excuse, anyway

7:25 ambrosebs: I always look up cljs.analyzer instead of running cljs code :P

7:25 cfleming: Yeah, the code is actually really nice, it's very easy to understand in general.

7:26 It definitely looks like a v2 of the Clojure code :)

7:29 ambrosebs: yea. Looking forward to v3 with tools.analyzer.js

7:31 cfleming: Nice.

7:31 I must admit I'm a little lost with all the analyzers - I'm going to investigate them soon to get it all straight in my head.

7:32 Exciting things happening with clj compilation though, the GSOC projects look great.

7:38 ambrosebs: yea loving the foundation our students are building.

8:00 noncom: hey what's up with core.async?

8:00 so many talks were here

8:00 suddenly all is gone

8:01 did everyone finally understand everything about it/

8:01 ?

8:02 ambrosebs: all gone?

8:03 noncom: well, no more talks..

8:03 i loved reading them since that let me learn many new things

8:03 now however i am here, there is not much of them...

8:03 or maybe i am here at wrong times...

8:05 ambrosebs: I think #clojurescript discusses it every so often

8:06 noncom: ah, that's what - they moved to a separate channel

8:10 centrapheta: Hey all, so I thought of a programming challenge: Given 7 9 8 7 6 5 4 3 2 5 6 7 3 4 2 4 5 8 7 = 476 Goal: find out what mathematical operators (minus, multiply, divide, add) satisfy that solution (476)

8:10 Order of operation is variable.

8:10 Dynamic programming :)

8:10 Example output: http://pastebin.com/yDpS3Na4

8:15 * locks uses prolog and solves it in 3 lines

8:17 centrapheta: locks, :o how?

8:17 locks, Using dynamic programming?

8:26 clgv: centrapheta: is there a dp strategy, i.e. does the bellman principle apply?

8:27 centrapheta: clgv, dp[i][j][k] = Can I make the number k using the numbers a[i ... j].

8:28 clgv: ah right. that trick. large table then, exponential in the result size (476)

8:30 centrapheta: Just curious to see some clojure dp solutions :)

8:31 clgv: centrapheta: well if they shall be really fast, it's only almost imperative with clojure syntax

8:32 dp is just nested loops anyway ;)

8:33 mdrogalis: Just Wiki'ed the Bellman principle. That was too much before coffee.

8:33 clgv: mdrogalis: will get much easier after the coffee ;)

8:34 mdrogalis: As do most things. :)

8:35 clgv: mdrogalis: hm well, the wikipedia page does not have an easy top level explanation it seems ;)

8:36 mdrogalis: clgv: I didn't want to call you a liar, but.. :P

8:36 centrapheta: If I want to make X with the numbers A[i ... j], then I find a position v such that A[i ... v - 1] can make Y, A[v ... j] can make Y', and either Y + Y', Y * Y', Y - Y', or Y / Y' is equal to X.

8:36 That is how you compute A[i][j][X].

8:37 If you want to find some sequence that does, then in A[i][j][X] you store the position at which you split (v) and the operator you chose.

8:37 _Every_ expression that you can form using the numbers in A[i ... j] is of the form (Y) op (Y'), where Y is an expression obtained from A[i ... v - 1], Y' is an expression obtained from A[v ... j], and op is either +, -, *, or /.

8:38 mdrogalis: What is happening. D:

8:38 centrapheta: If I'm trying to find several, I'll store the several v, but that (since the number of answers is already exponential) will be exponential in space and time.

8:38 mdrogalis: Make it stop D:

8:38 clgv: mdrogalis: there are easier problems to learn DP ;)

8:38 mdrogalis: Ha. I'm just kidding, at any rate. Carry on :P

8:39 clgv: in fact a trivial on is the Fibonacci sequence. a more representative but still simple one is binomial coefficients

8:40 so back to linear algebra and matrices ^^

8:41 mdrogalis: Hah

8:59 adsisco: any good library to connect to mysql besides sqlkorma?

9:02 beamso: adsisco: clojure.java.jdbc?

9:05 adsisco: beamso: which is better?

9:07 alexherbo2: Hi

9:08 beamso: adsisco: i've only used clojure.java.jdbc

9:10 ddellacosta: adsisco: clojure.java.jdbc is lower level. You can use DSLs on top of it like HoneySQL or the more basic one available with clojure.java.jdbc (java-jdbc/dsl)

9:10 dabbelingClj: Hi there! I got a complex JSOn document/file, which clojure lib fits best to drill in and extract data from JSON?

9:10 ddellacosta: adsisco: korma is a bit more magical and higher level, and wraps up more functionality in its DSL

9:12 dabbelingClj: take a look at https://github.com/clojure/data.json and https://github.com/dakrone/cheshire and see which one you like better

9:13 dabbelingClj: ddellacosta: thanks, i have alook!

9:13 alexherbo2: How list all functions ?

9:13 cshell: Is there a way to build regex patterns by referencing other regex patterns in clojure?

9:14 alexherbo2: I’m writing syntax highlighting for Kakoune; i need the list of function names.

9:14 cshell: alexherbo2: http://clojure.github.io/clojure/

9:15 ddellacosta: cshell: you're talking about somehow composing regexes? Haven't heard of anything like that in Clojure

9:16 cshell: ddellacosta: Yeah, I’m writing a GC log parser and there are a lot of repeating patterns that happen so I was hoping to leverage some reuse

9:16 shep-home: cshell: sounds like you want a real parser :-)

9:16 Glenjamin: http://clojuredocs.org/clojure_core/clojure.core/re-pattern perhaps?

9:16 shep-home: https://github.com/Engelberg/instaparse

9:17 "there may be times when it is useful to build parsers with parser combinators."

9:17 alexherbo2: cshell: is there a function to get this list?

9:17 cshell: shep-home: haha, yeah

9:18 Glenjamin: thanks - that might work actually

9:18 alexherbo2: or i have to wget the page and parse it

9:18 ddellacosta: alexherbo2: try (map first (ns-publics 'clojure.core)) for example

9:18 cshell: Glenjamin: I was using the #”…” syntax but that might not work for what I’m doing

9:19 alexherbo2: ddellacosta: thanks

9:19 ^^

9:19 ddellacosta: alexherbo2: np

9:36 broquaint: If cshell was still about I would've suggested seqex - https://github.com/jclaggett/seqex

9:41 ddellacosta: broquaint: cool stuff

9:58 eflynn: is there anything wrong with a collection of atoms?

9:59 ddellacosta: eflynn: needs more context, but if you have a collection of atoms it begs the question of why you don't have an atom of a collection instead

10:00 eflynn: ddellacosta: because the atoms would be shared in other collections, but yeah the same thought occurred to me too

10:01 ddellacosta: writing a scheme interpreter in clojure

10:02 ddellacosta: eflynn: what part of the interpreter is this?

10:02 Glenjamin: the purpose of the atom-collections is some sort of reference lookup?

10:02 clgv: eflynn: well if you never need to coordinate between the atoms to have some consistent operation on that collection that might be fine

10:04 eflynn: ddellacosta: the environment part. you can see something like what i have here: https://github.com/gregsexton/SICP-Clojure/blob/master/src/sicp/ch4.clj this is not my code

10:05 ddellacosta: if you make scheme without set! or define it’s pretty easy

10:08 ddellacosta: eflynn: I'm not totally following what that code is doing, but if you needed an analogue to set!, could you just have something that looked up a value in a table inside (a collection in) an atom?

10:08 eflynn: swap!-ed it, to be clear

10:09 eflynn: sorry, that may not be too helpful...but good luck. Very cool project. :-)

10:12 eflynn: ddellacosta: yeah it’s hella confusing. an environment is represented as a collection of ‘frames’ and if a frame is changed, other environments that share that frame need to see it.

10:13 ddellacosta: eflynn: I see, so that code actually does what you're talking about, huh--I see it makes a frame via creation of a new atom. Hrm

10:14 * ddellacosta makes note to self to actually finish SICP some day

10:14 eflynn: ddellacosta: it was converted from a scheme version so maybe it’s not very clojure-y

10:26 dabbelingClj: How do I get the "type" of a clojure expression?

10:26 cbp: (type expr)

10:26 dabbelingClj: !

10:26 thanks i tried :type

10:28 cbp: dabbelingClj: that would work like this: (:type (meta expr)), but only for clojure values with that metadata added

10:29 dabbelingClj: cbp no its fine it works liek expected

10:54 I'm trying to acces data from a clojure Map, usually i use: (keys {:a 1, :b 2}), which gives: (:a :b), which is fine but Cheshire returns also keys which are not :keywords? how do i access those?

10:55 llasram`: ,(let [m {"a" 1}] [(m "a") (get m "a")])

10:55 clojurebot: [1 1]

11:02 dabbelingClj: llasram`: why i need the let?

11:03 sluukkonen: you don't, it's just for demonstration purposes

11:03 (m "a") and (get m "a") where m is the map are the important bits

11:04 dabbelingClj: So this is my code: (keys (parse-stream (clojure.java.io/reader "data.json"))) which gives : ("entities" "in_reply_to_status_id_str" "place" "user")

11:05 mpenet: dabbelingClj: cheshire can keywordise the keys btw

11:06 dabbelingClj: (get "user" (parse-stream (clojure.java.io/reader "C:\\Temp\\tweedlsclj2\\resources\\tweedls_data.json"))) <- nil

11:06 mpenet: ,(doc get)

11:06 clojurebot: "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."

11:06 dabbelingClj: I dont get it should be dead simple...

11:06 mpenet: you're inverting the parameters

11:06 dabbelingClj: ah!

11:06 mpenet: ,(get {"a" 1} "a")

11:06 clojurebot: 1

11:06 llasram`: And Clojure takes a pretty extreme "garbage in, garbage out" stance

11:07 dabbelingClj: makes sense!

11:09 hyPiRion: There should be a clojure variant with support wheels for such mistakes.

11:09 And I don't mean core.typed here

11:10 dabbelingClj: no its fine its an "ovious" API mistake on my side

11:11 can I put that (parse-stream (clojure ...) in a def ?

11:12 ha ok I always forget that i have to evaluate "every *new" expression in LT

11:13 nested gets I see a use case for -> and ->> :D

11:13 Glenjamin: if i have some related things i sometimes wrap in a (do)

11:13 or just shift+cmd+enter to re-eval the whole file

11:14 and i've got a keybinding for "save all + (tools.repl.namespace/refresh)"

11:16 clgv: damn, I thought I could use "balagan". but it seems it extracts all possible paths from the given data and then filters those that match the query. that is not really usable with a data structure of 2GB and lots of arrays in it

11:16 hhenkel: Hi all, I'm trying to cummulate the result of a for loop into a let binding. That works so far, only issue is, that I only get the last return value of the for loop: https://www.refheap.com/86232

11:17 Glenjamin: hhenkel: it's generally best to not think of for as a loop

11:17 it's a list comprehension

11:17 hhenkel: I used trace to see that the for loop is executed two times and give me a result two times.

11:18 Glenjamin: yes, good point, thanks for the clarification.

11:18 Glenjamin: although this looks sort-of right

11:18 clgv: hhenkel: does config/substitute-all-the-vars return different keys?

11:18 Glenjamin: the ->> is actually making it trickier to read though imo

11:18 gfredericks: (defmacro throw-data [s m] `(throw (ex-info ~s ~m)))

11:20 mpenet: gfredericks: should be in core, dunno how many times I wrote this

11:20 hhenkel: clgv: yes, I would say so. Every execution gives me a map.

11:20 mpenet: gfredericks: throw-ex-info, or throw+ or whatever

11:20 gfredericks: throwx

11:21 throan

11:21 throat

11:21 Glenjamin: hhenkel: if every execution gives a map, you probably want (reduce merge) instead of into

11:21 gfredericks: throne*

11:21 mpenet: feel free to add this to catch-data, wouldn't hurt

11:21 Glenjamin: then you basically have slingshot though, no?

11:21 clgv: hhenkel: huh? a map? well then "into" will use "merge" since you use "into" with a map as target. I thought it returns key-value-pairs

11:21 mpenet: a slim, slingshot

11:21 gfredericks: Glenjamin: without unnecessary features

11:22 hhenkel: clgv: Glenjamin: It gives me a datastructure descibing attributes of a server.

11:23 Glenjamin: ,(into {} [{:a 1} {:b 2}])

11:23 clojurebot: {:a 1, :b 2}

11:23 Glenjamin: ,(into {} [{:a 1} {:a 2}])

11:23 clojurebot: {:a 2}

11:23 clgv: Glenjamin: that's what I meant ^^

11:23 Glenjamin: hhenkel: can you give an example of what you want the input and output to be?

11:23 clgv: ,(into {} [[:a 1] [:b 2]])

11:23 clojurebot: {:a 1, :b 2}

11:24 clgv: hhenkel: and that's what I thought your code does ^^

11:25 hhenkel: ,(into {} ({:a 1 b:2} {:a 3 :b 4}))

11:25 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

11:25 clgv: hhenkel: why do you use "into" if your "for" does not contain key-value pairs?

11:27 PigDude: clojure has no notion of package privacy which means i need to make a huge namespace to share private functions between my code?

11:27 hhenkel: Glenjamin: I updated https://www.refheap.com/86232

11:27 clgv: PigDude: I would make them public.

11:27 PigDude: if my code can require foo.util, so can anybody else, it seems like a clean API is more difficult to achieve in clojure unless you write very large namespaces

11:27 that's what i do now clgv

11:28 cbp: ,(apply merge '({:a 1 :b 2} {:c 3 :d 4}))

11:28 clojurebot: {:d 4, :c 3, :a 1, :b 2}

11:28 llasram`: PigDude: You can annotate namespaces as :private. It's just a hint to the library user, but is an explicit one

11:28 clgv: usually it is a bad idea to make functions private anyway. there are some examples for that in clojure.core as well

11:28 hhenkel: clgv: I simply tried to adopt some code I was using at a different point and did not think about the datatype in the first place.

11:28 PigDude: llasram`: when would a code user see the :private metadata?

11:29 llasram`: PigDude: When the generated/manully-written documentation?

11:29 clgv: PigDude: how about an "api" namespace that contains only the functions a regular user is supposed to use?

11:30 llasram`: PigDude: It sounds like you expect people to just randomly depend on random namespaces, then burn down your house if you change anything they can access :-)

11:30 clgv: hhenkel: you want a vector or sequence of all the configs?

11:31 hhenkel: but you want to force immediate evaluation?

11:31 hhenkel: then use "doall" or "vec"

11:31 hhenkel: (into {}...) merges all your distinct maps together to one

11:32 hhenkel: clgv: okay, so I do "vec" instead of "into {}" then, right?

11:32 clgv: yes

11:33 llasram: ~tias

11:33 clojurebot: Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance.

11:33 llasram: Mmmmmm.... fuzzy....

11:34 gtrak: I like my peaches a bit cold.

11:34 devn: mushy peas, please

11:35 hhenkel: clgv: Thanks, that works like a charm.

11:36 clgv: hhenkel: better build up from scratch next time ;)

11:37 hhenkel: clgv: Yes, definitely.

11:39 PigDude: llasram: yes? :)

11:40 llasram: this is honestly how i often see my relationship with code users when i work on a library

11:40 llasram: you're probably right

11:40 clgv: that is what i do now, the API is in core

11:40 clgv: llasram thanks for the advice!

11:45 clgv: PigDude: http://steve-yegge.blogspot.de/2010/07/wikileaks-to-leak-5000-open-source-java.html

11:45 PigDude: :P

11:46 clgv: *I* have yet to see the case where java's security is useful, but i understand that in practice it's very important, and allows you to run untrusted code

11:47 clgv: (thinking of package privacy and such)

11:47 clgv: funny post bw

11:47 *btw

11:48 'The Agile Java community has denounced the Wikileaks move as a form of terrorism. "It was probably instigated by those Aspect-Oriented Programming extremists," speculates Agile Java designer Claudia Hewitt, age 29. "I always knew they wanted to use my code in ways I couldn't predict in advance," she added.'

11:49 gtrak: PigDude: steveyegge?

11:49 clgv: gtrak: yes ^^

11:49 PigDude: yea clgv sent me the link

11:49 gtrak: :-)

11:49 gfredericks: Veyeg Geste

11:50 gtrak: that was a much better age of his rants.

12:27 shriphani: hi. anyone here used quil? I have a question about images.

12:28 dbasch: ~anyone

12:28 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 ..."

12:28 shriphani: I am performing some animation using the standard routines and at the end I want the image to be displayed on top the animation one

12:28 done *

12:28 the image call seems to put the loaded image in the background

12:30 nbeloglazov: shriphani: can you show your code?

12:30 shriphani: sure one sec.

12:30 nbeloglazov: https://www.refheap.com/86236

12:31 see the draw routine and the call to image at the end

12:33 nbeloglazov: and that does this: http://shriphani.com/pics/bug.png

12:33 I want the image to lie on top of the animation. Is that not possible ?

12:36 nbeloglazov: out of curiosity, what happens if you switch renderer to :java2d or :p2d/:p3d?

12:37 shriphani: yup that works !

12:37 wee !

12:41 nbeloglazov: which renderer works?

12:41 java2d and p2d/p3d or only java2d?

12:43 justin_smith: shriphani: I think this has to do with how opengl handles identical z indexes

12:43 ie. it handles them kind of indeterminately

12:51 shriphani: nbeloglazov, both java2d, p2d and p3d

12:51 s/both/all/

12:54 nbeloglazov: shriphani: cool. Actually opengl renderer is not recommended to use in processing/quil anyway :)

12:55 stompyj: Just a poll, do people use jetty, tomcat, other app servers?

12:56 justin_smith: on aws I have used tomcat (via beanstalk)

12:56 because the was the mandated platform

12:56 gtrak: all the lein-ring stuff uses jetty, which means a lot of people use jetty

12:57 justin_smith: really, http-kit (maybe a few instances) behind nginx/varnish is simpler to set up, and performs much better

12:57 cbp: I just use http-kit behind nginx

12:57 justin_smith: gtrak: at dev time, sure

12:57 lein-ring in production is not a good idea

12:57 stompyj: my lein ring uberjar works find, but lein ring uberWAR is failing, with a very ambigious error

12:57 I figured most people are using jetty (that what I’m currently trying to do)

12:57 gtrak: stompyj: we opted for dropping lein-ring and building a custom servlet.

12:58 it's easy.

12:58 still using jetty though.

12:58 stompyj: well, I’m just trying to checkout from git, lein ring uberwar, copy to jetty and bounce server. That should be super easy too

12:58 but ok

12:58 enough people are using jetty that I shouldn’t necc. avoid it

12:59 has anyone seen when uberjar works, but uberwar fails?

12:59 I’m just getting a NullPointerException, but nothing else relating to my project

12:59 hiredman: stompyj: when are you getting the error?

13:00 stompyj: hiredman: immediately after running “lein ring uberwar"

13:00 Exception in thread "main" java.lang.NullPointerException, compiling:(util.clj:90:1)

13:00 oh geez

13:00 I’m a moron

13:01 ignore me. :)

13:01 cbp: lein profile.clj errors are ze worst

13:13 bbloom: dnolen_: i just discovered another use case for specify

13:13 on the jvm side that is

13:13 i have two different protocols in two different namespaces, but they have a common method name.... i can't use reify b/c then the names conflict as methods on the generated type

13:13 oh well. i'll just need to use a deftype

13:13 and extend

13:14 or rename

13:15 dnolen_: bbloom: I thought that shouldn't matter, two different protocols in two different namespaces

13:15 bbloom: dnolen_: reify only creates class methods, not protocol methods

13:16 dnolen_: oh huh, did not know that - that seems like the real issue

13:17 bbloom: i guess so, but i don't know how you'd address it without changing the interop characteristics of reify and/or making it inconsistent with deftype

13:17 deftype has the same issue, of course

13:19 Bronsa: bbloom: maybe making the method names for protocol interfaces include the namespace segment could fix it?

13:19 dnolen_: cool stuff http://rigsomelight.com/2014/06/03/devcards-taking-interactivity-to-the-next-level.html

13:19 bbloom: Bronsa: would be a seriously breaking change for interop

13:21 Bronsa: bbloom: yeah, that sucks

13:23 bbloom: dnolen_: video is a bit long so i just clicked through it. seems neat

13:40 bhauman: bbloom: I suck at videos, it took me forever to get that stupid thing dome

13:41 bbloom: bhauman: for introductory videos, the 60 second rule applies :-)

13:42 bhauman: bhauman: I hear you, but way beyond my skill level

13:42 bbloom: when i saw "14:10" i immediately said "not gonna watch this" and only bothered to press play b/c david mentioned the thing

13:42 bhauman: designing videos is just like designing code: it's done not when there is nothing left to add, but when there is nothing left to take away

13:44 bhauman: bbloom: yeah it’s a hard sell but, its something that IMHO was hard to express.

13:45 bbloom: Although apple did it in like 3 minutes

13:45 bbloom: bhauman: you mean the playground demo? heh

13:51 arrdem: Bronsa: t.a.jvm can't express the class method reach set of an expression in the general case, right? I'm pondering if there's static analysis I can do to prove out clojure.lang.Var/alter* or warn if present.

13:53 seangrove: bhauman: I feel you, you always want to spend time emphasis/explaining parts that you feel are important. Hard to resist that

13:59 stompyj: videos are particularly tricky, we can scan text, so it’s easy to skim and find the good parts/parts we’re interested in, or scan quickly and figure out if the writing is worth reading

13:59 videos are a blind investment.

14:00 Bronsa: arrdem: well, if you require that all the dependencies must be analyzed by t.a.j, you might be able to write a pass that does that I

14:01 gtrak: there needs to be like a clojure video feed.

14:01 twitter acct

14:01 it's hard to find good ones if I just go look for them, but sometimes that's what I want.

14:01 for working out or something.

14:02 cbp: how do you get the doc for a namespace?

14:02 bhauman: seangrove: yeah its like when you try to talk a client down from adding music to there website.

14:03 arrdem: Bronsa: okay, I'll play with it some. I think the answer is that you generally can't, but the hinting requirements on methdo invocations may enable the cases that I care about.

14:03 that or you can if you're willing to implement and eat an expensive pointer analysis.

14:04 Bronsa: arrdem: uhm derp. I assumed you were talking about static methods, not instance methods.

14:04 arrdem: Bronsa: oh static methods are what I care about, instance methods are hard to impossible.

14:05 so I should be alright.

14:08 * seangrove holds his breath, goes into #meteor

14:08 seangrove: Time to meet the community

14:09 bhauman: seangrove: good luck man

14:09 TimMc: Foley: Sounds of pots and pans hitting the wall, pottery breaking.

14:12 aperiodic: dakrone: is it a conscious choice that there is no way to set a default key-fn in cheshire?

14:12 Jaood: seangrove: you gave up on cljs? :)

14:13 seangrove: Jaood: Oh, of course not :) But we have some reasons for dealing with meteor

14:14 * seangrove rages at https://news.ycombinator.com/item?id=7841556

14:26 dbasch: why the rage seangrove?

14:27 seangrove: dbasch: Bad decisions winning again and again

14:27 bbloom: dbasch: dnolen_ myself and seangrove have all trashed shadow dom a bunch in this room, check the logs :-)

14:28 dbasch: bbloom: but why? I don’t know shadowdom but I’m sure it’s web scale :P

14:29 seangrove: dbasch: It's definitely web-scale, where web-scale means as horrible as everything else on the web :P

14:29 bbloom: dbasch: it's a very complex non-solution to the modularity problem of web pages

14:30 dbasch: why can’t we go back to the 80s, when screens were represented as grids instead of trees?

14:31 justin_smith: why not upgrade from trees to graphs? then we get fully fractal page rendering for free

14:31 hiredman: emacs still does that

14:32 I was looking at the source for the mac gui for emacs and all the rendering code still treats the screen as a matrix of characters

14:32 dbasch: justin_smith: then we can have turing-complete web pages

14:33 TimMc: Do everything in LaTeX.

14:33 bbloom: LaTeX, it's a lisp with fexprs! :-P

14:37 dbasch: I don’t even. http://stackoverflow.com/questions/24015415/clojure-defining-a-macro-that-uses-the-carret-metadata-syntax

14:39 justin_smith: the dude seems to have a fundamental misunderstanding of what metadata is for (based on that and his other SO questions)

14:40 amalloy: i saw that one this morning, dbasch. didn't you comment on it? did it get removed, or am i inventing memories?

14:40 dbasch: amalloy: I removed my comment after reading the other question

14:40 amalloy: I have no idea what that person is trying to do

14:41 Raynes: what is this i dont even

14:42 dbasch: I also don’t understand why people are so fascinated with macros, or think they are the solution to random problems

14:42 it’s like regular expressions

14:43 amalloy: *shrug* the new, novel thing you don't understand always seems like it must be the easy solution to all your hard problems

14:43 ToxicFrog: dbasch: because after using a language that has them for a while, you really miss them when you go to a language that doesn't.

14:43 Much like regular expressions.

14:44 Raynes: I actually don't really ever miss macros in other languages.

14:44 ToxicFrog: Oh. I do.

14:44 Raynes: Most of what I've used macros for that actually required macros has been relatively superficial syntactical things.

14:44 dbasch: ToxicFrog: you reminded me of that famous question about parsing html with regular expressions

14:44 ToxicFrog: (no, cpp does not count)

14:45 Raynes: well, yes, macros are syntax transforms, their most obvious application is making new syntax for things that are inconvient to do "plainly".

14:45 hyPiRion: Raynes: You have never tried to perform a variadic loop unroll through #define in C, it looks like

14:45 amalloy: dbasch: it's really more of a famous *answer*. the guy didn't even ask to parse html with regular expressions, he was just looking for a particular tag

14:45 bbloom: i much prefer eval over macros

14:45 i'm guilty of (doseq [...] (eval `(...)))

14:45 amalloy: wat

14:45 bbloom: works great, much easier to reason about & write than macros

14:46 dbasch: amalloy: yes, this one http://stackoverflow.com/a/1732454/586880

14:46 amalloy: bbloom: that's madness. you can just use a local macro

14:46 bbloom: amalloy: but then i have to NAME the macro :-P

14:46 amalloy: bbloom: pull in macrolet, man

14:46 or any utils library with a cousin of it

14:46 sbi_: lol :D

14:47 Raynes: ToxicFrog: Sure, but I just don't often find places where a macro makes things objectively better.

14:47 dbasch: I assume that the maintainer of my code will be an idiot, and that’s true even if I’m the only person to ever see my code

14:47 justin_smith: most of the time if I need to use a macro it is because I am using a macro and need a macro to compose functionality with it

14:47 bbloom: how is it any different to do (defmacro m [args] `(...args...)) (m a b c) rather than (doseq [x [a b c]] (eval `....

14:47 dbasch: especially if I’m the only person to see my code, as I get dumber with age

14:47 Raynes: It's certainly an important and amazing feature of lisps.

14:47 But I can live without it in other languages.

14:47 justin_smith: "if I need to write a macro" that is

14:48 bbloom: i may be a crazy person, but i no longer feel that eval is evil :-P

14:49 Jaood: you are evil ;)

14:49 Raynes: You're pretty screwed up, man.

14:50 Jaood: we should be talking about swift

14:50 bbloom: i find that i need a lot less syntax-quote and unquote to do simple top-level eval usage

14:51 dbasch: Jaood: swift is so yesterday, nobody cares anymore :P

14:51 I looked at it and my first impression was that it looked like a proprietary version of go. Not interesting unless you need to do iOS development.

14:54 Jaood: dbasch: and OS X

14:55 dbasch: Jaood: well, you have more choices if you’re sticking to OSX

14:59 amalloy: haha, excellent. google's first autocomplete suggestion for "printstacktrace s": "should be removed"

15:00 bbloom: haha

15:01 TimMc: amalloy: "clojure is |nil"

15:01 amalloy: it turns out to be not quite as funny: apparently that's the warning message netbeans gives you if you have "e.printStackTrace();" as the body of an exception handler

15:02 bbloom: some IDE decided that was as good enough as any codegen default

15:02 and people leave it there

15:02 dbasch: just like FIXME in clojure projects :P

15:06 TimMc: I had to add this to a java project to be able to use some of the Clojure persistent data structures and I don't know why. :-( https://github.com/timmc/johnny/commit/340a217e4554ca296351affbc20911aeb805d85a#diff-c6d534713fa591414088043313740566R18

15:07 (If this sounds familiar, I'm revisiting a project from a while back: http://clojure-log.n01se.net/date/2013-10-25.html#17:15)

15:07 Apparently there's something weird with the order in which Clojure classes have to load.

15:09 hiredman: yeah, RT really wants to be loaded first

15:09 TimMc: RT.init() yells at you if you call it.

15:09 hiredman: sure

15:10 you just need to load the class, not call any methods

15:10 similar to jdbc driver kind of things

15:10 Class.forName("clojure.lang.RT");

15:11 TimMc: Yeah, I suppose that would be more clear to the reader.

15:11 The error I get if I don't preload it is really bizarre though.

15:12 Something about contains? not supporting PersistentList -- but this occurs during PersistentTreeSet's class init.

15:14 hiredman: TimMc: is the java app multithreaded at all?

15:14 it could be some kind of concurrent classloading issue

15:15 TimMc: Nah, I'm just running the JUnit tests.

15:18 l1x: guys, what is your take on dealing with files in Clojure? Should I use java.io.File to pass in to functions dealing with files or just string and convert it locally to a File type? both cases how would you deal with the different path element separators (windows

15:18 and macos)

15:18 amalloy: $google raynes fs

15:19 lazybot: [Raynes/fs · GitHub] https://github.com/Raynes/fs

15:19 justin_smith: l1x: also, the existing java libs already abstract over that stuff, and it is not hard to interop with them

15:21 l1x: a project I contributed to once tried to account for the separator used by each OS, but it turned out that broke things and the right way is to use '/' everywhere and let java.io.File decide when that needs translating

15:21 l1x: justin_smith: i was thinking having a function that reads files, but i am not sure if i should pass in a [] with the path so it can construct the platform specific File of it or should i pass in a File from each function i have

15:21 cbp: lix File can take multiple strings and will automatically add the separator no?

15:22 l1x: cbp: exactly

15:22 justin_smith: cbp: sure, but if you use '/' it turns that into the right separator for the platform

15:26 cbp: you see my sick pr sdegutis, i got you 2 stars

15:26 er

15:26 ignore that

15:28 justin_smith: /ignore that

15:46 johnwalker: why doesn't (.start (Thread. #(println "print"))) print "print"?

15:47 o_o

15:49 cbp: johnwalker: it does

15:50 johnwalker: if you're using cider it's not consistent with where it shows you your prints

15:50 johnwalker: oh what the fuck

15:51 cbp: when you use multiple threads

15:51 johnwalker: that explains a lot actually

15:51 because using .run gave me some output

15:51 thanks cbp

15:52 dbasch: johnwalker: check your *nrepl-server* buffer

15:54 johnwalker: right on dbasch

15:55 thanks :)

16:09 fifosine: Is there a way I can define a set but not generate its contents (because it is very large) and ask for a random member of that set?

16:10 bbloom: fifosine: clojure's collections are extensional

16:10 fifosine: bbloom: What does that mean?

16:10 bbloom: fifosine: mathematical term for the opposite of another mathematical term: intentional

16:10 extensional means the collections list all the members

16:11 intentional means it lists the criteria to be a member

16:11 ystael: bbloom: inten_s_ional

16:11 bbloom: ystael: dur, you're right

16:11 ystael: amalloy can tell you that my spelling sucks

16:11 fifosine: anyway, the point is: you can just define a function for membership testing & pass that function around

16:12 fifosine: you don't need it to be a clojure set

16:12 fifosine: bbloom: In the end, what I'd like to do is be able to query a random color (from the 256^3 space of colors) that is not in the given set of colors. What I don't want to do is have to make that entire color space.

16:12 bbloom: just use a predicate directly

16:12 l1x: is there an easy way to pass in a list of a function that calls an another function and puts the list elements as parameters?

16:12 bbloom: fifosine: what's wrong with simply creating a random-color function?

16:13 l1x: your explaination is not clear, please give an example

16:13 fifosine: bbloom: So, inside this random-color function I generate a random color, then check that it doesn't exist in the given set. If it does, then what, call random-color again? I don't want the stack to explode as the given set grows

16:14 l1x: (defn test [&params] (test2 param0 param1 param2....paramN))

16:14 PigDude: i noticed lein taking longer and longer, with all plugins removed it take 10s to start, without them it was taking 30+s. what do you do about this?

16:14 fifosine: bbloom: I want a random and unique color

16:14 Bronsa: l1x: I think you're talking about apply

16:14 l1x: Bronsa: hmm maybe

16:14 PigDude: oh sorry wrong channel

16:14 Bronsa: ,(apply + [1 2 3])

16:14 clojurebot: 6

16:14 ystael: fifosine: the algorithm you give is tail recursive, so if you use `recur` you need not worry about the stack

16:14 fifosine: ystael: You're right, didn't realize

16:14 ystael: this is a common way to generate random elements when the excluded set is small

16:15 bbloom: fifosine: how many colors are you generating?

16:16 fifosine: bbloom: At some point, up to half of all colors

16:16 bbloom: Would a set difference make more sense in this case?

16:16 bbloom: fifosine: setting aside that i feel like you've got a serious design problem that i don't understand yet... you'd need a custom data structure to do this efficiently

16:17 you have a total ordering of colors, so you can create an extent map

16:17 an extent map is a sorted set of ranges of used colors

16:18 there are many extent map data structures, such as bitmap trees and stuff like that

16:18 but really, i think this is totally crazy... so please explain what you're actually trying to accomplish

16:18 i'm sure there is a much simpler solution

16:18 fifosine: bbloom: I'm trying to paint a canvas with 1 pixel per unique color

16:19 bbloom: fifosine: as like an art project? or what?

16:19 fifosine: bbloom: For fun

16:19 bbloom: yeah, that's what i meant

16:19 ok

16:19 well, if it's for fun, go crazy :-P

16:19 fifosine: I still want it to be fast

16:20 amalloy: fifosine: so just loop over all colors, in order, right? do you need it to be random?

16:20 fifosine: amalloy: I want it to be random

16:20 ystael: fifosine: so essentially your problem is: generate an initial segment of length canvas-pixel-count, of a permutation of the vector of all 2^24 colors, where that permutation is chosen uniformly at random over all permutations of the color space?

16:21 bbloom: ystael: that's an interesting way to reason about it

16:21 fifosine: ystael: See the top answer here: https://codegolf.stackexchange.com/questions/22144/images-with-all-colors

16:22 I wanted to do this in clojure

16:22 So I'm curious to find a fast way to query a unique color

16:22 Yes, the colors are a permutation, but a specific permutation

16:23 ystael: oh. if you don't want a _random_ permutation, it's much easier, you just have to prove that your generator does not visit the same tuple twice

16:24 which is easier to do by static analysis than by choosing a clever data structure to make that fact manifest in the code

16:24 fifosine: ystael: What static analysis is available?

16:25 bbloom: he means simply reasoning about your code

16:27 fifosine: ystael: The solutions I see are: generate the color space, select a random color, and remove it one-by-one; perform a set difference between all colors and all used colors and select a random one; or recursively select a random color until we find one that has not been chosen.

16:27 amalloy: fifosine: for example, you can use the chinese remainder theorem to generate an ordering that appears random and is guaranteed to not repeat

16:27 fifosine: None of these seem like the best approach

16:28 ystael: fifosine: You're going back and forth on whether you want the colors to appear in a random or deterministic order

16:28 bbloom: fifosine: do you have something slow working yet?

16:28 start there!

16:28 amalloy: think of each color as a number from 1 to N (where N is a prime number somewhere near 2^24). pick another prime P, and a "seed" color X. compute X*P, X*P*P, X*P*P*P, all mod N

16:29 fifosine: bbloom: I do, but it's written in python, so I'm trying to convert it

16:29 amalloy: those are guaranteed to not repeat until you've exhausted all choices

16:29 bbloom: amalloy: that's neat!

16:29 fifosine: amalloy: This is the chinese remainder theorem?

16:29 amalloy: as i remember it, anyway. number theory was ten years ago; the details may be a smidge off

16:30 fifosine: Should N be larger than 2^24?

16:30 amalloy: if you want all possible colors available, then yeah, pick the smallest prime larger than taht

16:30 (and ignore any results which are too large to be rendered as a color)

16:32 ystael: amalloy: I don't think that's good enough; you need P to be a primitive root modulo N (generator of the multiplicative group of Z/NZ).

16:32 amalloy: ,(let [n 13, x 5, p 7] (for [i (range n)] (mod (apply * x (repeat i p)) n)))

16:32 clojurebot: (5 9 11 12 6 ...)

16:32 amalloy: ystael: i don't know what that means, but i think i'm right as long as P and N are both prime (as i stipulated)

16:32 &(let [n 13, x 5, p 7] (for [i (range n)] (mod (apply * x (repeat i p)) n)))

16:32 lazybot: ⇒ (5 9 11 12 6 3 8 4 2 1 7 10 5)

16:33 fifosine: ystael: amalloy's conditions are more strict than yours, I think

16:34 ystael: &(let [n 13, x 7, p 5] (for [i (range n)] (mod (apply * x (repeat i p)) n)))

16:34 lazybot: ⇒ (7 9 6 4 7 9 6 4 7 9 6 4 7)

16:34 ystael: amalloy: Nope.

16:35 fifosine: nice example

16:36 amalloy: huh. well, i don't see what's wrong, ystael, and your objection was beyond my vocabulary. can you explain in baby-talk for me?

16:37 ystael: You're asking for (1, p, p^2, ...) to visit all the nonzero (multiplicatively invertible) entries of Z/nZ.

16:38 This does happen for some p, but not all p, and it's not directly identifiable with whether or not p is prime.

16:39 If p does generate all of the nonzero entries of Z/nZ in this way, it's called a primitive root modulo p. The number of primitive roots modulo p is Phi(p - 1) (Euler Phi function) which can be proved with a little bit of group theory.

16:40 GFREDERICKSdotCO: cemerick: ping

16:40 ystael: Sorry, some wrong letters there; every 'p' after "it's called a primitive root modulo" in that last line should be an 'n'.

16:42 If you know about cyclic groups, this is rooted in the fact that the multiplicative group of Z/nZ (n prime) is a cyclic group of order (n - 1). For n = 13, this means a cyclic group of order 12.

16:44 But that has a bunch of proper subgroups -- 7 happens to be a primitive root, but neither 7^2 = 10, 7^3 = 5, or 7^4 = 9 is one.

16:44 (because (7^2)^6 = (7^3)^4 = (7^4)^3 = 7^12 = 1)

16:44 * arrdem isn't convinced that ystael is speaking english

16:45 gfredericks: ystael: because 2 and 3 and 4 divide 12 amirite?

16:45 ystael: gfredericks: precisely

16:45 amalloy: yeah, i'm afraid introductory number theory was the furthest i got in that direction. i'm now just wondering what it is i misremembered, and particularly puzzled that i gave an answer that was *close* to being right

16:47 gfredericks: I've thought a lot about how to visualize groups as anything other than a multiplication table and never came up with anything promising

16:47 ystael: amalloy: It's a beautiful idea and I'm going to steal it if that's OK, but for it to work you need to check that p is a primitive root

16:49 amalloy: yes, feel free to steal it. it's not like a groundbreaking number-theory result i invented myself

16:49 ystael: there's guaranteed to be (at least) one p that works for any given n, right?

16:50 but you can't just pick any prime p like i suggested

16:50 gfredericks: clojurebot: this thing with N and P and some colors is a groundbreaking number-theory result that amalloy invented himself

16:50 clojurebot: Ok.

16:50 ystael: amalloy: Yes, in fact there are Phi(n - 1) of them (and most of them may not even be prime when reduced modulo n)

16:50 For n = 13, they are 7^j, where j is relatively prime to 12

16:51 (and that's true in general -- if you find one root p, the rest are p^j, where j is relatively prime to n)

16:51 amalloy: relatively prime to n-1

16:51 ystael: yes, right, sorry

16:52 amalloy: that sounds familiar now. at least i'm glad i didn't completely misremember

16:55 gfredericks: clojurebot: what is your favorite number

16:55 clojurebot: Alles klar

16:56 edlothiol: btw, this is basically a (special case of a) linear congruential generator

16:58 or, according to wikipedia, a Lehmer RNG

16:58 pbostrom: I have a ~50MB text file that I read into a byte-array, I want to do a search and replace on the file now, would you just shell out to sed, or stay in the JVM and try to do some stream processing?


17:02 Glenjamin: generally i believe the advice is once you're in the jvm - stay there

17:03 noncom|2: jvm for sure

17:03 amalloy: why byte array? text isn't bytes, it's characters

17:03 pbostrom: I read it from a zip file

17:04 noncom|2: is there a way to merge two {} but where matching keys values won't be replaced, but merged too

17:04 ?

17:04 Glenjamin: merge-with

17:04 (doc merge-with)

17:04 clojurebot: "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."

17:04 noncom|2: cool! is it deep?

17:05 bbloom: noncom|2: no, but you can make it deep

17:05 noncom|2: ,(merge-with {:a 1 :b {:c 2 :e 3}} {:b {:k 2}})

17:05 clojurebot: {:b {:k 2}}

17:06 noncom|2: ummm, it killed :a ... ?

17:06 bbloom: noncom|2: you didn't pass it a function

17:06 noncom|2: and lost the original :b

17:06 ah

17:06 amalloy: noncom|2: you just merged {:b {:k 2}} with itself

17:06 bbloom: ,(merge-with merge {:a 1 :b {:c 2 :e 3}} {:b {:k 2}})

17:06 clojurebot: {:b {:k 2, :e 3, :c 2}, :a 1}

17:06 noncom|2: wow!

17:07 bbloom: but "deep" is ambiguous, so you have to give it the merge function you want, which can be recursive in however you need it to be

17:08 noncom|2: yeah, gotta figure it out.. words are easy: i want to combine two maps so that nothing is lost. but the code...

17:09 oh i can just see if the arg is a {} then, repeat this again, else just return the arg

17:09 i guess..

17:09 gotta try

17:09 bbloom: consider: what happens if you combine a {:x 1} with {:x {:y 2}}

17:09 noncom|2: hmmm... well, according to the current task, the second should be taken..

17:09 nice, one more case to watch for :)

17:10 oh no, wait, i am wrong

17:11 bbloom: like i said, deep merge is ambiguous, you may be better off just writing a recursive function by hand to cover your particular needs

17:11 noncom|2: according to the task, :x must either both be maps which are to be combined, or a value (int/double/[]) which is to be replaced

17:11 bbloom yeah..

17:11 amalloy: noncom|2: i mean, one reasonable interpretation of "deep merge" is in flatland.useful.utils/adjoin

17:12 the implementation of which is a bit hairier than you might like, if you wanted to use it as a base to write your own; but its behavior is pretty nice

17:12 Glenjamin: my general on opinion on deep-merges is try not to have a general deep merge if you can

17:12 let them be specific to whatever it is you're merging, including appropriate semantics

17:13 bbloom: yeah, i find that general-purpose recursive combiners don't exist that much in practice

17:13 amalloy: sure. adjoin only behaves as it does because that's what protobufs do when you concat them together; other reasonable options exist

17:14 noncom|2: cool, looked at flatlands adjoin.. it's giving thoughts

17:14 yeah, i will tailor things for the particular task. this is not an abstract supermerger haha, i got a very exact case

17:59 yeoj___: I have a long-running clojure data migration app, moves about 50 million rows. For the first 10 million performance is great, and then it just slowly drops off from there.... what should i be looking for? I see no telling reflection, and have blindly been messing with my jvm options... any tips?

18:00 Glenjamin: yeoj___: you probably want to profile it

18:00 check out jvisualvm

18:00 yeoj___: ok, but i would like to run it on the sever... so i'll need to proflie from my laptop to this server i think

18:00 if i run on my laptop through lein it's not the same i don't think

18:01 Glenjamin: that is doable

18:01 although a smaller reproducible test case will make it easier to measure and test hypotheses

18:01 yeoj___: Glenjamin: ok thanks i'll read up on it

18:09 justin_smith: yeoj___: you can use an ssh tunnel (ssh -L ...) to access the dt_port of the server jvm process from your local machine

18:09 so the job is done on the server, and the profiling can happen locally

18:10 yeoj___: justin_smith: ok... i'm reading up jstatd now and it has me setting up a security policy and port/etc. with ssh would jstatd run locally on laptop? What is the dt_port?

18:12 justin_smith: yeoj___: actually I meant the transport=dt_socket option to the jvm

18:12 socket, not port

18:12 http://blog.javachap.com/index.php/debugging-in-java/

18:12 amalloy: <3 ssh -L

18:13 justin_smith: that link above describes how to tell it what port to expose etc.

18:13 then ssh -L will expose that remote protected port on your local machine (without exposing it to the rest of the world)

18:14 yeoj___: ok i'll give it a shot

18:14 justin_smith: amalloy: yeah, one of those little things that has pretty much totally changed my computer using life

18:14 yeoj___: so i'm thinking i probably need to stop the running job and plug in some debug options

18:14 justin_smith: yeoj___: once you have the port forwarded from remote, and the remote process is running, jvisualvm will give you the remote process as a clickable thing to interact with

18:15 yeoj___: yeah, unless you had it open a socket, probably

18:15 yeoj___: i'm hoping UseLargePages and AggressiveOpts doesn't confuse the debugger or anythnig

18:15 dbasch: yeoj___: running jvisualvm over ssh requires patience though, I’d exhaust other options first

18:15 justin_smith: yeoj___: anyway, you get better info if you profile from the beginning of the process (when the performance is OK)

18:15 yeoj___: ok sounds good

18:16 amalloy: dbasch: really? i've never had any trouble running yourkit over ssh; is jvisualvm worse, or is yourkit bad too and i'm just not picky?

18:16 justin_smith: I am sure it is linear with the amount of data you are trying to crunch in either case

18:17 dbasch: amalloy: I didn’t have any trouble with jvisualvm, it’s just that I usually ran it on aws servers and it was a bit slow for interactive sesions

18:17 justin_smith: so in depth profiling is one thing, quick snapshots are another, etc.

18:17 dbasch: session

18:17 s

18:17 * dbasch needs a new keyboard

18:17 arohner: I remember seeing a blog post a few months ago /join #clojurescript

18:17 gah

18:17 ^^ that's ADD, folks

18:17 justin_smith: dbasch: so was jvisualvm being run remotely with X forwarding, or jvisualvm locally with forwarded dt_socket port?

18:18 amalloy: oh god, surely not x forwarding

18:18 dbasch: justin_smith: X forwarding

18:18 justin_smith: yeah that is not what I was suggesting at all, X forwarding is a pain

18:18 unless you have a very fast connection

18:18 amalloy: i've learned my lesson about x forwarding: never do it to anyplace outside of the building you're in

18:18 justin_smith: exactly

18:18 amalloy: it's so, so much worse than vnc. x11 assumes a fast connection to the display

18:19 justin_smith: dbasch: next time try using ssh to forward the dt_socket, it will be worlds better

18:19 awwaiid: eh. just do it over ssh -CX

18:19 and make your window small

18:19 very small

18:19 dbasch: justin_smith: you’re right. We were doing other things that required X forwarding so just went with the usual

18:19 llasram: Huh. I've never had any big problems with X forwarding, at least within the same city

18:20 dbasch: I’ve run firefox over X forwarding from a different continent because I had no choice

18:20 llasram: justin_smith: Oh man, if you think `ssh -L` is awesome, check out `ssh -D`

18:21 justin_smith: llasram: oh, very nice

18:21 amalloy: i don't understand what -D does

18:22 llasram: amalloy: Creates a SOCKS proxy tunneling from your local system out the remote SSH endpoint

18:22 justin_smith: https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding

18:23 that tries to describe the various distinctions of forwarding types

18:24 "For example, dynamic port forwarding lets you bypass a company firewall that blocks web access altogether."

18:26 yeoj___: so with ssh -L , i have the app running (waiting for debugger) remotely with 1100 as the "address" with dt_socket

18:26 so can i still ssh over port 21 with a different user?

18:27 dbasch: yeoj___: if you mean port 22 yes, sure

18:27 sbi_: sure you can

18:27 yeoj___: ah, right 22

18:27 justin_smith: well -L can link up any two arbitrary ports

18:27 yeoj___: i'm confussed over the manpage then, where do i reference port 1100 (the dt_transport socket) ?

18:28 ssh -L 1000:remotehoste:1000

18:28 (i don't put 22 in there anywhere? )

18:28 justin_smith: no

18:28 ssh uses 22 implicitly

18:28 also the port numbers are arbitrary as long as they are accessible - visualvm just does a linear search for sockets that are serving dt_sockets

18:29 (I checked the source because I was working on something related)

18:29 yeoj___: ah ok

18:29 llasram: That's uh, weird (the localhost port scan)

18:29 justin_smith: also don't specify remotehost

18:29 amalloy: yeoj___: the idea with -L is, for example, `ssh -L xyz:localhost:abc someserver` - this says "ssh to someserver, and additionally start a server on my current machine's port xyz. if i try to connect to that port, then forward me through the ssh session to localhost:abc instead"

18:29 justin_smith: llasram: well the jvm has no "registry"

18:30 instead of remotehost specify "localhost" or ""

18:30 yeoj___: ohhh i see ok i thought the "host" bit in the man page was remote

18:30 clojurebot: Pardon?

18:30 justin_smith: you are telling remote who to connect to

18:30 in case you are using it proxy style

18:30 it really should have a "localhost" default mode I think

18:31 yeoj___: ok so to jvisualvm it thinks it's localhost, and doesn't care on the port,

18:31 justin_smith: right

18:31 yeoj___: i see in the console "Debugger failed to attach: recv failed during handshake: Resource temporarily unavailable"

18:31 justin_smith: hmm

18:32 using "localhost" or "" as the remote?

18:32 because dt_socket is opened for local access only for obvious security related reasons

18:32 visof: ,(map (fn [k v] (format "%s -- %s" v k)) {"Hello" "World"})

18:32 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval25/fn--26>

18:32 yeoj___: i did this at bash: ssh -L 1100:localhost:1100 remote_user@remote_server

18:33 visof: ,(map (fn [k v] (format "%s -- %s" v k)) ["Hello" "World"])

18:33 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval51/fn--52>

18:33 visof: why this don't work?

18:34 justin_smith: yeoj___: ok, the should work if there is a dt_socket on that thread remotely

18:35 yeoj___: and visualvm does show that app as being there?

18:35 *that process

18:35 yeoj___: trying again with

18:35 i hope this is not a windows/cygwin thing. ugh.

18:35 justin_smith: visof: try an extra pair of [] - fn is only getting one arg right now - the thing mapped over should be pairs of things for that code to work

18:36 amalloy: he'll need more than one extra pair of []s to make that weird code work, justin_smith. he perhaps means apply, not map

18:37 justin_smith: ,(map (fn [k v] (format "%s -- %s" v k)) [["Hello" "World"] ["gimme" "beer"]])

18:37 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval77/fn--78>

18:37 amalloy: for the vector version, anyway. i guess for the {} version, extra []s in the arglist would do it

18:37 justin_smith: ,(map (fn [[k v]] (format "%s -- %s" v k)) [["Hello" "World"] ["gimme" "beer"]])

18:37 clojurebot: ("World -- Hello" "beer -- gimme")

18:37 justin_smith: that is what I had in mind

18:38 amalloy: i'm imagining an alien has just landed his spacecraft and is trying to communicate using a phrasebook, and the best he can come up with is "world, hello. beer, gimme"

18:38 yeoj___: yeah, its still giving me this: Debugger failed to attach: recv failed during handshake: Resource temporarily unavailable and i see two local apps in jvisualvm but i don't think they are my remote app... it also says "not supported for this jvm" in the details.

18:39 justin_smith: yeoj___: do you see the list of processes to connect to change if you start / stop the server on the other end?

18:41 yeoj___: justin_smith: no

18:41 same two on the laptop

18:41 it's not getting hooked up; i'm googling this Debugger failed to attach: recv failed during handshake: Resource temporarily unavailable

18:42 justin_smith: yeoj___: is jvisualvm giving this message, or ssh?

18:42 yeoj___: ssh

18:43 justin_smith: hmm

18:43 yeoj___: it's a console application (the clojure one) and it's actually stdout from that console app. the one that moves 50 million rows.

18:43 (the one i changed the java debug options/dt_transport/etc. stuff)

18:43 the ssl -L one logs me into another terminal (through cygwin/bash) and then just sits there

18:43 no idea

18:44 justin_smith: yeoj___: you mentioned windows, this looks relevant: https://netbeans.org/bugzilla/show_bug.cgi?id=48170

18:44 yeoj___: it could be permissions on your local side for creating that port?

18:45 yeoj___: ah, maybe.

18:45 justin_smith: yeoj___: maybe relevant "if I add "server=y" to the runjdwp option, everything works"

18:46 amalloy: yeoj___: ssh -L will open an ssh terminal, just as if you didn't include -L

18:46 but it also opens a local socket, which persists until you close that ssh session

18:46 yeoj___: justin_smith: i tried the server=y bit as well. :/

18:46 i wish jvisualvm was an ncurses app

18:47 i wish everything was an ncurses app.

18:47 amalloy: or an emacs major mode

18:47 sbi_: unicorns!

18:49 arrdem: Bronsa: ping

18:54 justin_smith: yeoj___: this is a command line app http://jrat.sourceforge.net/

18:54 (with a separate viewer that can run locally after importing the dump, it seems)

18:55 Bronsa: arrdem: pong

18:55 arrdem: Bronsa: sorry it's late, what would you like in terms of a patch for making t.e.jvm check *compile-files* to write .classfiles?

18:56 I'm looking at emit.clj:1336 (emit-class) as the obvious candidate, but I need to read this more carefully I suspect.

18:56 yeoj___: justin_smith: found this: Oracle/Sun changed the JVM debug connection handshake in the 1.7 JVM series; somewhere after update 2.

19:01 Bronsa: arrdem: I don't think dumping the bytecode to a classfile is all it's going to take to add AOT compilation to t.e.j, it should probably compile a loader class too

19:01 justin_smith: yeoj___: oh, so you may need matching jvms

19:02 Bronsa: arrdem: see https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7235

19:04 arrdem: Bronsa: yep okay so this is going to have to be a separate emitter that tracks & registers all emitted classes for load class generation. I'll fool with this tomorrow then.

19:04 thanks as always

19:05 dbasch: yeoj___: it might be easier to just do it with X forwarding at this point. It would be slow though

19:05 yeoj___: dbasch: yeah. i wonder if profiling locally on this laptop through lein would yeild anything interesting at this point too.

19:06 dbasch: but if it’s a one-off, it’s not *that* horrible

19:06 yeoj___: i don't even have x install on t he server

19:06 Bronsa: arrdem: np. I haven't really looked into what's going on with the __load/__init methods there but feel free to ask for help if you need any

19:07 PigDude: do [patterns to re-matches have to be anchored?

19:07 i'm finding that unanchored patterns only match .. in the repl, !

19:07 dbasch: yeoj___: you don’t need it on the server, you do need it on the client side

19:07 PigDude: this is really strange

19:09 this is nil: (prn (re-matches #"0" (first (get-keys *store*)))), but is a match: (prn (re-matches #"^0##.*$" (first (get-keys *store*))))

19:09 the regex "0" is less specific than "^0##.*$" so what gives?

19:10 amalloy: re-matches checks for a complete match

19:10 &(doc re-matches)

19:10 lazybot: ⇒ "([re s]); Returns the match, if any, of string to pattern, using java.util.regex.Matcher.matches(). Uses re-groups to return the groups."

19:10 amalloy: if you want to find substring matches, that's re-find

19:10 (or re-seq)

19:10 PigDude: i just want a fast LEFT() test

19:11 aka startswith

19:11 dbasch: PigDude: then use startsWith :)

19:11 PigDude: ah ok

19:12 thanks dbasch

19:35 do you use :refer [s] or :refer (s)?

19:37 technomancy: PigDude: use [s]

19:39 clojurebot: import indent is brackets imply all entries are peers, while parens imply that the first entry is different from the rest: http://p.hagelb.org/import-indent.html

19:39 clojurebot: Alles klar

19:39 technomancy: clojurebot: who's a good little bot?

19:39 clojurebot: Huh?

19:40 PigDude: () just looked weird to me

19:44 gfredericks: technomancy: I'm not sure normal usage is entirely consistent with that

19:45 technomancy: gfredericks: if all your friends jumped off a cliff...

19:45 TEttinger: you'd be lonely

19:45 jonh: hehe

19:46 TEttinger: alternatively, you'd be a cliff diving competitor

19:48 amalloy: technomancy: i'd worry he learned the wrong |is|

19:48 clojurebot: import indent

19:48 clojurebot: import indent is brackets imply all entries are peers, while parens imply that the first entry is different from the rest: http://p.hagelb.org/import-indent.html

19:48 amalloy: okay, fine

19:49 gfredericks: technomancy: alright, I'm gonna go check the leiningen source

19:49 TEttinger: clojurebot: technomancy is the lord of lein

19:49 clojurebot: You don't have to tell me twice.

19:49 gfredericks: technomancy: how would you apply this standard to (:require [leiningen.core.user :as user])?

19:49 technomancy: amalloy: whew; that's like impossible to correct if you get it wrong iirc

19:49 TEttinger: clojurebot: technomancy

19:49 clojurebot: technomancy is the lord of lein

19:50 gfredericks: clojurebot: leiningen?

19:50 clojurebot: leiningen is better at starting clojure than amalloy is

19:50 technomancy: gfredericks: arguably irrelevant since you know it's not going to wrap?

19:50 gfredericks: technomancy: huh? wrap?

19:50 amalloy: gfredericks: it should be (:require (leiningen.core.user :as user)) according to that rule, except that ns doesn't let you do that

19:50 technomancy: gfredericks: since it's a question of indentation

19:51 amalloy: technomancy: i've had it wrap, like (:require [leiningen.core :as user :refer [a b c d e f g]])

19:51 gfredericks: oh I thought we were discussing [] vs ()

19:51 amalloy: oh, but that wrapping happens inside the refer

19:51 gfredericks: we are

19:51 technomancy: amalloy: right

19:51 gfredericks: I GIVE UP TALKING

19:51 amalloy: technomancy's point is that the ()/[] distinction only matters because it changes how emacs indents in the case of line-wrapping

19:51 technomancy: not just emacs

19:51 amalloy: s/point/claim

19:51 technomancy: but yeah

19:52 bhauman: Is there a way to check what version of cljs is running in the leinigen environment?

19:52 technomancy: it's relevant when considering collections of arbitrary length

19:52 gfredericks: okay I think I understand all of the various viewpoints involved in this discussion now

19:53 amalloy: i'll start writing (:require [leiningen.core.user :refer [a b c d e f g] \n :as user]) just to spite technomancy

19:53 nullptr: bhauman: lein deps :tree | grep clojurescript

19:54 amalloy: it'll indent terrible and i'll hate him for it

19:54 bhauman: nullptr: thanks, I phrased the question wrong I meant from a plugin.

19:54 technomancy: amalloy: I forget where you stand on the when/if issue

19:55 amalloy: technomancy: my viewpoint is that you are a lone madman

19:55 but one whose opinion is reasonable

19:55 gfredericks: amalloy: let's start a social media grassroots organic campaign using the power of our brand to get other people to do this too

19:55 technomancy: amalloy: then I'm likely to be too annoyed by your whens to notice the ns indentation crimes you commit

19:55 gfredericks: technomancy: not once we make up for it in volume

19:55 amalloy: really, technomancy, i think your when/if opinion is better than the mainstream one, but it's more important to conform than to be right, for minor issues like that

19:56 technomancy: amalloy: well I appreciate the thought

19:56 I'm just over here shifting the overton window

19:57 gfredericks: let's start a library called when-with-side-effects

19:57 technomancy: it's a tough job, but someone's gotta do it

19:57 metellus: what's the when/if issue?

19:57 gfredericks: metellus: when to use when

19:57 amalloy: by the way, everyone, here's your yearly reminder to run the commands at https://www.refheap.com/0bccc08fbe2924fd38fa38b88

19:57 pretty up your git-diff hunk headers

19:57 technomancy: metellus: some people think it's a mistake that clojure.core/if allows you to omit the "else" branch

19:58 gfredericks: amalloy: what what?

19:58 amalloy: gfredericks: last march i pasted that and suggested everyone run it. i just remembered to do it again

19:58 technomancy: metellus: they mistakenly argue that you should always use clojure.core/when if you don't have an else branch

19:58 gfredericks: amalloy: I'm wondering exactly what "pretty up your git-diff hunk headers" means

19:58 metellus: technomancy: is there a more important difference between when and the elseless if?

19:59 technomancy: metellus: rather than using c.c/when to indicate side-effects, given that it has an implicit do

19:59 amalloy: [15:43:13] amalloy: if anyone is interested, https://www.refheap.com/paste/0bccc08fbe2924fd38fa38b88 sets up git to provide custom hunk headers for clojure files in diffs. so the diff header tells you what function the diff is in the middle of

19:59 gfredericks: ooooooooohhh

19:59 Bronsa: omg that's awesome

19:59 gfredericks: for a minute I was hoping this had something to do with diffing sexps

19:59 technomancy: metellus: this is an ancient tradition we inherited from elisp and CL

19:59 gfredericks: seemed too short for that :)

19:59 technomancy: metellus: and my argument is that if you're less concerned about side-effects than a common lisper, it's time to re-evaluate your life choices.

20:00 amalloy: yeah, i think the best you can do is git-diff -b, gfredericks

20:00 hide the irrelevant whitespace changes, at least

20:00 gfredericks: good tip

20:01 amalloy: gfredericks: ready for a better tip? you can do that on github too! add ?w=1 to the url for a diff view, and the whitespace changes are hidden

20:01 gfredericks: this has to go in the .config/git directory?

20:01 amalloy: if I keep sitting here will the tips get indefinitely better?

20:02 amalloy: gfredericks: you're talking about the -b flag to diff? i dunno, i don't usually pass it; there's no amazing way to pass it by default, i think

20:02 gfredericks: s/indefinitely/arbitrarily/

20:02 technomancy: only logarithmically better

20:02 gfredericks: amalloy: no the hunk headers

20:02 amalloy: gfredericks: just paste the refheap's contents into your shell

20:02 gfredericks: logarithm is such a funny word

20:02 amalloy: it puts stuff in the right place

20:02 gfredericks: amalloy: yes but I want this in my dotfiles repo

20:02 so now I have to worry about how my symlinks all orchestrate themselves

20:03 amalloy: so isn't .config/git in your dotfiles repo?

20:03 gfredericks: not yet; I've never put anything in there before

20:03 amalloy: anyway, i don't think it has to go there. you can set your gitattributes file to be any file you want

20:03 gfredericks: but that's different from .git/config?

20:03 er

20:03 ~/.gitconfig I mean

20:03 clojurebot: I don't understand.

20:04 technomancy: I saw a trailer for the movie Gravity (without sound) and my only thought was that the movie looked like most of the tense scenes would consist of astronauts doing math in order to calculate force trajectories in order to not drift forever through space.

20:04 amalloy: yes, it's a separate file

20:04 sadly. i have no idea why

20:04 but it can't be the same one

20:04 * cowinfantry joins the horde ooing at amalloy's git config

20:04 technomancy: amalloy: I guess because you can't check anything in .git/ into the repo?

20:04 amalloy: technomancy: no, this is ~/.gitconfig

20:04 technomancy: huh

20:05 amalloy: you can set it repository-local, by putting it somewhere in .git, but i've never wanted to

20:06 gfredericks: "Attributes that should affect all repositories for a single user should be placed in a file specified by the core.attributesfile configuration option"

20:06 "Its default value is $XDG_CONFIG_HOME/git/attributes. "

20:07 arrdem: Bronsa: thanks for the comment, there's a huge bug in that code I just noticed because of it :P

20:08 gfredericks: oh I see amalloy's script was already dealing with this nonsense

20:09 arrdem: Bronsa: the reason load isn't in that list is theoretically check-vars looks at the reach set of the declared vars, not at the declared vars. so if you use c.c/load, c.c/load -> c.c/eval which is banned ∴ c.c/load is banned.

20:10 gfredericks: I'm not sure this is working

20:10 I would expect to see the function name on the line that looks like "@@ -73,10 +73,10 @@"?

20:10 amalloy: yeah

20:10 Bronsa: arrdem: uh? c.c/load calls Compiler/load IIRC

20:11 amalloy: gfredericks: do you have a particular repo+commit that this fails on, or is it all of them? so far this has worked for everyone who's tried it

20:11 arrdem: Bronsa: well either way I have that bug, and yeah load should be on the list.

20:11 gfredericks: amalloy: repo+commit for the sake of having you try it?

20:11 amalloy: yeah

20:11 arrdem: Bronsa: yeah calls clojure.lang.RT/load.

20:12 gfredericks: amalloy: definitely more than one repo

20:12 Bronsa: amalloy: FWIW it worked fine for me

20:13 gfredericks: amalloy: oh nevermind

20:13 your side effecting script thwarted my efforts

20:13 amalloy: gfredericks: you were hoping for a pure function that doesn't modify your filesystem?

20:13 gfredericks: amalloy: it works now

20:13 amalloy: cool

20:13 gfredericks: thxman

20:15 andyf_: technomancy: Thanks for metaverse advice a few days ago. I went with creating namespace-renamed local copies of Clojure contrib libs in Eastwood, and works like a charm^H^H^H^H^Hblunt hammer. Effective

20:16 I even get to fix things in the libs that I don't like without waiting on anyone :-)

20:17 technomancy: nice =)

20:22 andyf_: Bronsa: core.typed uses (alias 't 'clojure.core.typed) followed later by ::t/fn in the same file. I guess tools.reader can only handle this if I eval the first before continuing to read?

20:23 Bronsa: andyf_: correct

20:24 andyf_: One learns about the dynamicity of a language by trying to do "static" analysis on it. At least I do

20:24 Bronsa: andyf_: does eastwood read the whole file at once & then analyze form by form? I don't remember

20:25 andyf_: Double checking...

20:27 It does read, analyze, emit-form, eval for each top level form in turn. I guess the eval is not done in a way that affects tools.reader properly

20:27 Bronsa: oh.

20:29 hm, weird, that should work

20:30 andyf_: Not a big deal, since core.typed source is the only project out of about 50 that I have seen this. I may dig into it some time

20:30 Bronsa: andyf_: I'm going to bed now, I'll look into it tomorrow if I remember :P

20:31 andyf_: Forget .... :-)

20:36 jballanc_: let's say I have a map "foo" whose keys are a subset of the keys in map "bar", and I want to know if the values in "foo" and "bar" are equal but only for the common subset of keys in both...any quick way to do that?

20:38 andyf_: (= m1 (select-keys m2 (keys m1)))

20:39 jballanc_: hmm...is that quicker than (reduce (fn [match [k v]] (and match (= v (k bar)))) true foo) ?

20:41 andyf_: You mean faster execution time? I'd recommend some experiments using criterium to benchmark

20:41 ivan: this clojure fastload branch sure does start faster

20:41 jballanc_: andyf_: yeah, that's what I was thinking

20:42 justin_smith: jballanc_: probably, also that screams for reduced (reduce (fn [_ [k v]] (if (not= v (k bar)) (reduced false) true)) true foo)

20:42 jballanc_: yeah, there's definitely an advantage to being able to use reduced

20:43 justin_smith: but the equality check for maps probably uses short circuiting too

20:43 jballanc_: that's what I was wondering

20:44 justin_smith: if the two are actually the same object, the (= foo bar) call should return immediately (it should check object identity before anything else more expensive I would think)

20:44 amalloy: justin_smith: it does

20:45 andyf_: The select-keys method creates a new map, so seems unlikely to be faster than a solution that allocates no mem

20:45 amalloy: but you can't really short-circuit on equality because select-keys builds a big old map anyway

20:45 you don't want reduce, though, you want every?

20:46 (every? (fn [[k v]] (= (get m2 k) v)) m1)

20:46 jballanc_: amalloy: ah, true...I tend to run toward reduce

20:46 amalloy: jballanc_: reduce is lovely, but for anything where you want laziness or short circuiting it's not so hot

22:09 yeoj___: hi, how do i run my development ring server, so that remote connections can be made from co-workers?

22:10 i know i can allow for remote repl connections by listening on but not sure about ring on say port 3000

22:12 justin_smith: yeoj___: allowing remote repl connections is a bad idea, you should have something secure in between

22:12 yeoj___: it's all on my lan, i just wanted to let someone see my internal/intranet ring app... entirely dev stuff.

22:12 justin_smith: yeoj___: also, the right way to expose ring to the public is to put it behind something like nginx (which will put it on port 80), or in a container like tomcat or jetty

22:13 blr: justin_smith: probably overkill for just making your dev server lan accessible for a co-worker

22:13 justin_smith: they should be able to access http://yourhostname.local:3000

22:13 blr: I typed that before he mentioned it was local only

22:14 yeoj___: yeah ok

22:14 blr: right

22:14 justin_smith: as long as everyone's box understands bonjour / avahi

22:14 yeoj___: i think i'm having goofy crap firewall problems. second problem today that has to do with connections to this thing. my work might have some firewall thing i don't know about on here.

22:14 justin_smith: otherwise http://your.local.ip.quad:3000

22:14 that always works for me on a lan

22:15 (modulo getting the specific port right of course)

22:15 yeoj___: yeah, i thought that would work too. there is something up with this windows laptop.

22:16 thanks, sorry to bug with another stupid windows port on my laptop issue (just like ssh -L)

22:16 justin_smith: could be you have an agressive firewall installed, which would be compatible with your previous errors as well

22:17 now I wonder how much security theater is going on in windows land

22:18 yeoj___: it's not serucity thats the issue... its the lack of transparency

22:19 i have no idea what is on what isn't and how it works

22:19 causing me to mess with it... and probably making it less secure (as a workstation)

22:19 justin_smith: well oustensibly the reason for these kinds of issues is preventing takover of your machine by some remote control botnet process I think

22:19 yeoj___: yeah i won't have it long i'm going to wipe it as soon as i get the ok from my boss

22:39 amalloy: it occurs to me that, for work, i've never had a clojure process running on a machine that's reachable from the outside web. so it's always been viable for me to just throw in a super-insecure swank/nrepl server

22:40 and yet i always listen on localhost anyway, and connect via ssh tunnels

22:54 Jaood: amalloy: you are paranoid!

22:54 amalloy: it's just good hygeine, Jaood

22:57 right1: what are people doing for relational persistence nowadays in here? i've only used korma but that seems pretty dead to me

22:57 Shaun__: How do I kill a go-block in core async in cljs?

22:57 Is there some hacky way to kill all go-blocks even?

23:02 amalloy: unplug your computer

23:03 (the joke doesn't work as well now that everyone uses laptops, but i worry that "submerge your computer in vinegar" might get tried one day)

23:07 Shaun__: hahah, I like that solution

23:10 p_l: meh

23:10 thermite!

23:13 Shaun__: looks like this is the way do it: http://golang-examples.tumblr.com/post/64474189870/stop-goroutine-by-closing-a-quit-channel

23:15 amalloy: i was really hoping that was a youtube video of using thermite on a laptop

23:16 for anyone who shares my hopes and dreams: https://www.youtube.com/watch?v=S7CnVH6cobU is the top youtube hit

23:22 blr: right1: some people seem to be enjoying https://github.com/jkk/honeysql

23:23 amalloy: right1: just write sql

23:23 right1: i've been thinking of just using JDBI with java and then just use that from clojure code

23:24 yeah, basically just writing sql

23:24 amalloy: JDBI? just use jdbc

23:24 blr: yeah you can just use raw clojure.java.jdbc

23:24 works fine

23:25 amalloy: jdbi looks like another wierdo meta-language you'd have to learn for no reason

23:25 right1: jdbi is pretty ridiculously simple

23:26 amalloy: c'mon, `.map(StringMapper.FIRST)`

23:26 right1: you just map resultsets and you get your result

23:26 amalloy: why would you want that

23:26 right1: i'll read into clojure jdbc though

23:26 alandipert: i wonder about a stored procedure lisp interpreter to solve the SQL problem definitively

23:27 blr: and here I was hoping stored procedures were dead

23:28 amalloy: blr: they still are. lisp is dead, and transitivity...

23:34 Shaun__: amalloy: nice thermite video, I'll use that to stop the go-blocks :)

Logging service provided by n01se.net