2014-06-03
| 00:57 | rs0 | i just noticed something else about the Clojure 1.6.0 Java API |
| 00: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? |
| 00:57 | rs0 | the public API supposedly consists *solely* of IFn and clojure.java.api.Clojure |
| 00:57 | rs0 | however, IFn in turn depends on ISeq, which depends on IPersistentCollection... |
| 00:58 | tolstoy | rurumate: I got the impression that bindings are thread-local. |
| 00:58 | rs0 | so the transitive dependency closure of those two classes contains more than just those two classes |
| 00:58 | rs0 | 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 |
| 00:59 | rs0 | 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 |
| 00:59 | rs0 | rurumate: there's apparently an InheritableThreadLocal type since Java 1.2, but Clojure doesn't appear to use it |
| 01:00 | rurumate | what about pmap or fork/join things like reducers? |
| 01: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 |
| 01:02 | ambrosebs | rs0: every API has an implementation |
| 01:03 | rurumate | experimentation now |
| 01:03 | rs0 | ambrosebs: that's not really my point |
| 01:03 | rs0 | ambrosebs: the actual IFn interface makes mention of ISeq |
| 01: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) |
| 01: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" |
| 01:04 | rurumate | if bindings are not inherited, using them seems brittle because concurrency might be added to the program later on |
| 01:04 | ambrosebs | right? you still use the `seq` Var to get an ISeq |
| 01:04 | ambrosebs | you don't actually use ISeq |
| 01: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. |
| 01:05 | rurumate | yeah but atoms are not automatically reset to root binding after the work is done |
| 01:06 | tolstoy | Maybe a macro? |
| 01:06 | rhg135 | tolstoy, wouldn't it mess up any concurrent ops? |
| 01:07 | rurumate | also atoms are automatically shared between *all* threads which might be more than I wanted |
| 01:07 | tolstoy | (defmacro with-reset [some-atom] `(let [orig# @some-atom] ~@body (reset! some-atom orig#)).... blua blah. |
| 01:08 | tolstoy | rurumate: Ah, well. "Depends on the problem you're trying to solve." ;) |
| 01: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 |
| 01:10 | rhg135 | rs0, am indurstanding correctly that it's in java using the api to add functionality? |
| 01:10 | rhg135 | if so i'm in awe |
| 01:10 | rs0 | rhg135: ? |
| 01:10 | ambrosebs | rs0: can you write the boilerplate in a real clojure file? |
| 01:10 | rhg135 | rs0, a jav app basically using clojure as a tool? |
| 01:11 | ambrosebs | I guess I mean the calls to eval |
| 01:11 | rs0 | ambrosebs: i'll probably investigate that route next |
| 01:11 | mange | rurumate: Take a look at bound-fn for maintaining bindings in different threads |
| 01:11 | rs0 | ambrosebs: it's easy to invoke remove-method, which is an actual function |
| 01:11 | rs0 | ambrosebs: not sure how much it will help to write a function wrapper around a macro |
| 01:12 | ambrosebs | rs0: mm |
| 01: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 |
| 01:13 | ambrosebs | cool |
| 01:13 | rs0 | it's a bit like defrecord ported to java |
| 01:13 | ambrosebs | where's the eval calls? |
| 01:13 | rhg135 | uh, why can't it be in .clj and gen-class a java api? |
| 01:13 | rs0 | ambrosebs: i haven't pushed them yet =) |
| 01:14 | ambrosebs | or even better just write the interface in java and do everythign else in clojure |
| 01:14 | rurumate | mange: nice find, thanks |
| 01:14 | ambrosebs | is thatpossible? |
| 01:14 | rhg135 | yes |
| 01:15 | rhg135 | reify ftw! |
| 01:15 | ambrosebs | looks like you're using generics.. |
| 01:15 | rhg135 | generics are only hints for the compiler |
| 01:15 | rs0 | ambrosebs: okay, *now* it's pushed |
| 01:15 | rhg135 | they don't exist in bytecode |
| 01:16 | rs0 | i could look at reimplementing this in clojure, but i doubt i will... it's already working |
| 01:16 | rhg135 | ahh |
| 01: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 |
| 01:16 | ambrosebs | Don't the generics exist for the Java user? seems like we're throwing them out. |
| 01: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 |
| 01:16 | rs0 | besides, i'm relying on a lot of JDK8 features, like default methods |
| 01:17 | rs0 | 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 |
| 01:17 | Jaood | abandon ship, swift is here |
| 01:17 | rs0 | ambrosebs: within the library, it's complete downcasting anarchy and dynamic typing |
| 01:18 | rhg135 | just use Objects and reflection |
| 01:18 | rhg135 | performance may suffer but freedom goes up |
| 01:19 | dissipate | Jaood, yeah, i'm going to totally abandon ship for swift! |
| 01:19 | rs0 | rhg135: can you be more specific? |
| 01:21 | dissipate | BTW, what's with all these programming language names that it's impossible to do a proper search for, like 'go' |
| 01:21 | rs0 | dissipate: the convention is to use the term 'golang' instead of just 'go' |
| 01:21 | rs0 | dissipate: it's funny that people have to manually SEO the name of a programming language that came out of a web search company |
| 01:22 | dissipate | rs0, that is pretty ridiculous |
| 01:25 | rs0 | i remember that people made the same criticism of C# when it first came out |
| 01:25 | rs0 | because back in those days search engines would just drop all the weird symbols |
| 01:25 | rs0 | apparently |
| 01:26 | ambrosebs | rs0: is there much of a performance difference with generics? |
| 01:26 | dbasch | rs0: I worked at a search engine in the late 90s, and we had to create special tokens like AT&T |
| 01:27 | rurumate | "quoting may work when searching c#" |
| 01:27 | dbasch | we had a bunch of one-off special cases in the indexer parser |
| 01: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 |
| 01:28 | talios | rs0 - mmm, dynamic-object looks damn squishy! I like. |
| 01:28 | rs0 | talios: squishy? |
| 01:28 | rurumate | dbasch: I'm in the search business too, bro :3 |
| 01:28 | talios | so huggable :) nice a nice plush toy |
| 01:28 | ambrosebs | rs0: ah ok |
| 01:28 | ambrosebs | yea looks like fun |
| 01:29 | dbasch | rurumate: I’ve been out of the search business for a while myself :) |
| 01:29 | rurumate | sad to hear it |
| 01:29 | dbasch | rurumate: 14 years, it was time to try something else |
| 01:29 | talios | hey ambrosebs! |
| 01: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 |
| 01:29 | ambrosebs | talios: hi! |
| 01:30 | talios | ambrosebs - was thinking we should get you back on the show for a 3rd round state of typed-clojure ;) |
| 01:30 | rs0 | this is all explained in http://www.youtube.com/watch?v=2WLgzCkhN2g |
| 01:30 | ambrosebs | talios: oh yea sure :) |
| 01:30 | ambrosebs | talios: let's try July sometime |
| 01:31 | talios | sounds goodo |
| 01:32 | talios | ambrosebs - will schedule something and get back to you |
| 01:32 | ambrosebs | talios: thanks |
| 01:32 | dissipate | rs0, i doubt that is going to happen |
| 01:33 | ambrosebs | rs0: improved startup time should be phase zero :) |
| 01:33 | rs0 | ambrosebs: it's really easy, just use nailgun. nothing solves everything forever like nailgun |
| 01:33 | rs0 | (not actually) |
| 01:34 | rs0 | 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 |
| 01:35 | rs0 | 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 |
| 01:36 | rs0 | dissipate: however, widespread availability of the Clojure runtime couldn't hurt adoption |
| 01:39 | dissipate | rs0, well, you shouldn't be doing Java development at your day job... that's a problem right there |
| 01:43 | rs0 | dissipate: at least i'm not doing Scala development at my day job |
| 01:43 | rs0 | dissipate: or, like, C++ |
| 01:44 | dissipate | rs0, *shiver* yeah, that's pretty bad too |
| 01:47 | dbasch | rs0: you know, there are Clojure jobs |
| 01:50 | dissipate | dbasch, i think i could only do the remote ones |
| 01:50 | rs0 | dbasch: is the Clojure job market a buyer's market or a seller's market? |
| 01:51 | rs0 | dbasch: or is it too illiquid to say? |
| 01:54 | dissipate | rs0, probably a lot like any other job market for a niche language |
| 01:54 | rs0 | dissipate: i'm not really familiar with them, or with the general experience of hunting for jobs based on language |
| 01: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 |
| 01: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. |
| 01:58 | dissipate | rs0, the flip side of that, is that there can end up being a lot more tasks for dealing with legacy code. |
| 02:01 | dbasch | rs0: I think it’s too illiquid to say |
| 02:01 | dbasch | 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 |
| 02:02 | dbasch | Scala/Java interop is type hell |
| 02:18 | rs0 | dbasch: Scala is basically C++ for the JVM |
| 02:19 | bob2 | that's unfair |
| 02:19 | bob2 | it's even more complicated than c++ |
| 02: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 |
| 02:23 | rs0 | bob2: i think that Scala and C++ are both examples of very solid technical competence pursuing exactly the wrong principles |
| 02:23 | rs0 | bob2: those languages weren't just built by incompetent amateurs like PHP was |
| 03:41 | hellofunk | Does anyone know how to specify that a route in Compojure is an HTTPS (secure) route? |
| 03:57 | blur3d | hellofunk: you could try https://groups.google.com/d/msg/compojure/XWluMvf4CBs/OJVc_IVPsxUJ |
| 03:57 | hellofunk | blur3d thanks I found that as well. |
| 03:58 | blur3d | I dont think it handles it any other way… you just have to add handlers for it |
| 04: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 |
| 04: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. |
| 04:05 | ddellacosta | hellofunk: sure thing |
| 04: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 |
| 04:21 | ddellacosta | hellofunk: what is the google requirement, is that for openid or oauth2? |
| 04:21 | hellofunk | oauth2 |
| 04: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 |
| 04:24 | beamso | i've done oauth work where the URL i used was localhost :/ |
| 04: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 |
| 04:24 | hellofunk | ah ok, that would probably do it. |
| 04:42 | noncom | is it ok to have a package and ns with a same name, on the same level? |
| 04:42 | noncom | say i have "core.clj" and package "core" on one level |
| 04:42 | noncom | won't there be any problems with requiring or other ns-related management? |
| 04: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 |
| 04:45 | noncom | yeah, that seems like exactly my case :) |
| 04:45 | clgv | noncom: the folder name is only the last but one package in the fullqualified package name |
| 04:46 | noncom | oh, thanks for the correction |
| 04:46 | noncom | clgv: do you work with ccw? |
| 04:46 | clgv | in java that's different. there the fullqualified package consist of all the folders below the root source folder. |
| 04:46 | clgv | noncom: yes |
| 04:46 | clgv | all the time^^ |
| 04:47 | noncom | clgv: ummm.. could you give a little example on difference between java and clojure package concept? |
| 04: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 |
| 04:50 | noncom | aah, that's what |
| 04:50 | clgv | hence src/my/lib.clj => my.lib and src/my/lib/impl.clj => my.lib.impl |
| 04: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 ? |
| 04:52 | Glenjamin | does it help to think of clojure functions as java classes? |
| 04:52 | noncom | Glenjamin: i suppose it depends on the context of your thinking |
| 04:53 | Glenjamin | it's always package.package.package.Class |
| 04:53 | noncom | yeah |
| 04: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 |
| 04:54 | Glenjamin | i'm unsure if that helps, but i think i get what clgv is saying - and it had never ocurred to me before |
| 04: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 |
| 04: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 |
| 04:58 | clgv | noncom: though it depends which kind of clojure constructs you consider. since there is a difference between functions and deftype/defprotocol/defrecord |
| 04:59 | clgv | noncom: just AOT compile your whole project and investigate where the implementation ends up |
| 04: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 |
| 05: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 |
| 05:00 | noncom | clgv: but ok, back to ccw |
| 05:01 | clgv | noncom: conclusion: your namespace layout is just fine ;) |
| 05: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..] |
| 05:02 | clgv | noncom: also after refreshing the project? |
| 05:02 | noncom | clgv: here is my q on so: https://stackoverflow.com/questions/22784284/creating-a-source-package-folder-in-a-counterclockwise-project-programmatically |
| 05:03 | noncom | but the last statement about eclipse recognizing extensions is i am *not sure of* |
| 05:03 | noncom | yes, refresing does not elp |
| 05:03 | noncom | i though just maybe you've tried that |
| 05:04 | noncom | it does not really always recognize the created structure of folders and source files, be it .java or .clj |
| 05:04 | clgv | noncom: does "leiningen->reset project configuration" help? |
| 05:04 | noncom | and sometimes does |
| 05:05 | clgv | does that actually have consequences on a freshly started REPL? |
| 05: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.. |
| 05:08 | noncom | this will only be possible much later in today, so i will try and then, maybe tomorrow, write back.. |
| 05:08 | clgv | ok np. |
| 05:09 | clgv | "reset project configuration" should reset the classpath settings to what they need to be |
| 05: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. |
| 05:10 | ddellacosta | hellofunk: what do you mean? |
| 05: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 |
| 05:12 | beamso | are you sure you haven't noticed it redirect from the callback url to the default landing uri? |
| 05:12 | beamso | it could just be very quick |
| 05:12 | hellofunk | beamso well perhaps it is, but that's nifty that Friend manages to override that |
| 05: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? |
| 05:14 | beamso | i have to admit i did the oauth stuff with a phonegap app |
| 05: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. |
| 05:15 | ddellacosta | hellofunk: try turning off https://github.com/cemerick/friend/blob/master/src/cemerick/friend.clj#L152 |
| 05:17 | ddellacosta | 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 |
| 05: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. |
| 05:18 | ddellacosta | hellofunk: yes, it's a nice feature to have it redirect back to the page you intended to go to, agreed |
| 05:18 | hellofunk | ddellacosta which would work regardless of the workflow in action |
| 05:19 | ddellacosta | yep |
| 05:19 | hellofunk | unifies them |
| 05:55 | hellofunk | 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? |
| 05:56 | justin_smith | hellofunk: atoms are synchronized in state across threads |
| 05:56 | justin_smith | so changes made in one request should be visible to another |
| 05:56 | hellofunk | ok, thanks. |
| 06:17 | hellofunk | 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 |
| 06:18 | hellofunk | 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 |
| 06:20 | hellofunk | 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. |
| 06: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 |
| 06:22 | ddellacosta | 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 |
| 06:22 | ddellacosta | hellofunk: https://github.com/dakrone/clj-http, https://developers.google.com/accounts/docs/OAuth2?hl=en |
| 06:23 | hellofunk | ddellacosta ah ok, so Google is returning things in its oauth2 that are not actually oauth2-specific? |
| 06:23 | ddellacosta | hellofunk: yes, although I guess they may be part of the OpenID connect spec which I have not implemented as of yet |
| 06:24 | ddellacosta | 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 |
| 06: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 |
| 06: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 |
| 06: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? |
| 06:28 | hellofunk | apologize for how green I am with some of this stuff, general dev workflow, etc |
| 06:29 | ddellaco_ | hellofunk: sorry, got disconnected |
| 06:29 | hellofunk | no prob ddellaco_ did you see my question? |
| 06:29 | ddellacosta_ | hellofunk: the simplest way is just to include the workflow itself in your codebase |
| 06:29 | ddellacosta_ | hellofunk: and replace it at such a point that the openid connect flow is supported |
| 06:30 | ddellacosta_ | hellofunk: which will be Real Soon Now |
| 06: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 |
| 06:31 | ddellacosta_ | hellofunk: ...most of the time if you are building a production app this is not an issue, in terms of dependencies |
| 06:31 | ddellacosta_ | hellofunk: but it sounds like you need this ASAP so this is the best thing I can suggest |
| 06: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? |
| 06: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. |
| 06:36 | ddellacosta_ | 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. |
| 06: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 |
| 06:36 | ddellacosta_ | hellofunk: ah, gotcha. Don't feel bad about asking questions, and sorry if I'm not always giving you the best responses. |
| 06:37 | ddellacosta_ | hellofunk: just be patient and it'll become more clear |
| 06:38 | ddellacosta_ | 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. |
| 06:38 | hellofunk | ddellacosta_ thanks again! |
| 06:38 | ddellacosta_ | hellofunk: np, cheers. :-) |
| 06:59 | cfleming | Hi everyone - I'm wondering how :refer-clojure :exclude works in cljs. Does it exclude symbols from cljs.core, macros, or both? |
| 07:16 | ambrosebs | *checks the source* |
| 07:17 | cfleming | ambrosebs: I tried that, but still wasn't sure :-) |
| 07:18 | ambrosebs | looks like it excludes everything. |
| 07:19 | ambrosebs | try it: (ns my.ns (:refer-clojure :exclude [for])) (for [a [1]] a) |
| 07:19 | ambrosebs | :) |
| 07:19 | cfleming | So for a given name, it'll exclude it from both? That was what I suspected, but couldn't tell. |
| 07:19 | cfleming | Hehe |
| 07:19 | ambrosebs | yea I think the core-name? predicate in cljs.analyzer resolves core vars/macros |
| 07: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 :-) |
| 07:19 | ambrosebs | and that takes :excludes into account |
| 07:20 | cfleming | Ok, thanks - I'll assume that for the moment. |
| 07:20 | cfleming | There's not much doc about a lot of these cases in cljs |
| 07:20 | ambrosebs | I'm sure we'll get to 0.1 one day. |
| 07:21 | cfleming | I'm working on indexing cljs now, it's surprisingly tricky |
| 07:22 | ambrosebs | what does that mean? |
| 07:22 | cfleming | I'm working on indexing cljs for Cursive. |
| 07:23 | cfleming | It's tricky because the same name can and frequently does refer to two things. |
| 07:23 | ambrosebs | oh. hi colin :D |
| 07:23 | cfleming | :) |
| 07:23 | cfleming | Hi Ambrose |
| 07:23 | ambrosebs | (thought your name looked familiar) |
| 07: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. |
| 07:24 | ambrosebs | and you're getting lazy |
| 07:25 | cfleming | Fortunately Clojure smiles on laziness. |
| 07:25 | ambrosebs | agreed |
| 07:25 | cfleming | That's my excuse, anyway |
| 07:25 | ambrosebs | I always look up cljs.analyzer instead of running cljs code :P |
| 07:25 | cfleming | Yeah, the code is actually really nice, it's very easy to understand in general. |
| 07:26 | cfleming | It definitely looks like a v2 of the Clojure code :) |
| 07:29 | ambrosebs | yea. Looking forward to v3 with tools.analyzer.js |
| 07:31 | cfleming | Nice. |
| 07:31 | cfleming | 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. |
| 07:32 | cfleming | Exciting things happening with clj compilation though, the GSOC projects look great. |
| 07:38 | ambrosebs | yea loving the foundation our students are building. |
| 08:00 | noncom | hey what's up with core.async? |
| 08:00 | noncom | so many talks were here |
| 08:00 | noncom | suddenly all is gone |
| 08:01 | noncom | did everyone finally understand everything about it/ |
| 08:01 | noncom | ? |
| 08:02 | ambrosebs | all gone? |
| 08:03 | noncom | well, no more talks.. |
| 08:03 | noncom | i loved reading them since that let me learn many new things |
| 08:03 | noncom | now however i am here, there is not much of them... |
| 08:03 | noncom | or maybe i am here at wrong times... |
| 08:05 | ambrosebs | I think #clojurescript discusses it every so often |
| 08:06 | noncom | ah, that's what - they moved to a separate channel |
| 08: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) |
| 08:10 | centrapheta | Order of operation is variable. |
| 08:10 | centrapheta | Dynamic programming :) |
| 08:10 | centrapheta | Example output: http://pastebin.com/yDpS3Na4 |
| 08:17 | centrapheta | locks, :o how? |
| 08:17 | centrapheta | locks, Using dynamic programming? |
| 08:26 | clgv | centrapheta: is there a dp strategy, i.e. does the bellman principle apply? |
| 08:27 | centrapheta | clgv, dp[i][j][k] = Can I make the number k using the numbers a[i ... j]. |
| 08:28 | clgv | ah right. that trick. large table then, exponential in the result size (476) |
| 08:30 | centrapheta | Just curious to see some clojure dp solutions :) |
| 08:31 | clgv | centrapheta: well if they shall be really fast, it's only almost imperative with clojure syntax |
| 08:32 | clgv | dp is just nested loops anyway ;) |
| 08:33 | mdrogalis | Just Wiki'ed the Bellman principle. That was too much before coffee. |
| 08:33 | clgv | mdrogalis: will get much easier after the coffee ;) |
| 08:34 | mdrogalis | As do most things. :) |
| 08:35 | clgv | mdrogalis: hm well, the wikipedia page does not have an easy top level explanation it seems ;) |
| 08:36 | mdrogalis | clgv: I didn't want to call you a liar, but.. :P |
| 08: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. |
| 08:36 | centrapheta | That is how you compute A[i][j][X]. |
| 08:37 | centrapheta | 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. |
| 08:37 | centrapheta | _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 /. |
| 08:38 | mdrogalis | What is happening. D: |
| 08: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. |
| 08:38 | mdrogalis | Make it stop D: |
| 08:38 | clgv | mdrogalis: there are easier problems to learn DP ;) |
| 08:38 | mdrogalis | Ha. I'm just kidding, at any rate. Carry on :P |
| 08:39 | clgv | in fact a trivial on is the Fibonacci sequence. a more representative but still simple one is binomial coefficients |
| 08:40 | clgv | so back to linear algebra and matrices ^^ |
| 08:41 | mdrogalis | Hah |
| 08:59 | adsisco | any good library to connect to mysql besides sqlkorma? |
| 09:02 | beamso | adsisco: clojure.java.jdbc? |
| 09:05 | adsisco | beamso: which is better? |
| 09:07 | alexherbo2 | Hi |
| 09:08 | beamso | adsisco: i've only used clojure.java.jdbc |
| 09: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) |
| 09:10 | dabbelingClj | Hi there! I got a complex JSOn document/file, which clojure lib fits best to drill in and extract data from JSON? |
| 09:10 | ddellacosta | adsisco: korma is a bit more magical and higher level, and wraps up more functionality in its DSL |
| 09:12 | ddellacosta | dabbelingClj: take a look at https://github.com/clojure/data.json and https://github.com/dakrone/cheshire and see which one you like better |
| 09:13 | dabbelingClj | ddellacosta: thanks, i have alook! |
| 09:13 | alexherbo2 | How list all functions ? |
| 09:13 | cshell | Is there a way to build regex patterns by referencing other regex patterns in clojure? |
| 09:14 | alexherbo2 | I’m writing syntax highlighting for Kakoune; i need the list of function names. |
| 09:14 | cshell | alexherbo2: http://clojure.github.io/clojure/ |
| 09:15 | ddellacosta | cshell: you're talking about somehow composing regexes? Haven't heard of anything like that in Clojure |
| 09: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 |
| 09:16 | shep-home | cshell: sounds like you want a real parser :-) |
| 09:16 | Glenjamin | http://clojuredocs.org/clojure_core/clojure.core/re-pattern perhaps? |
| 09:16 | shep-home | https://github.com/Engelberg/instaparse |
| 09:17 | shep-home | "there may be times when it is useful to build parsers with parser combinators." |
| 09:17 | alexherbo2 | cshell: is there a function to get this list? |
| 09:17 | cshell | shep-home: haha, yeah |
| 09:18 | cshell | Glenjamin: thanks - that might work actually |
| 09:18 | alexherbo2 | or i have to wget the page and parse it |
| 09:18 | ddellacosta | alexherbo2: try (map first (ns-publics 'clojure.core)) for example |
| 09:18 | cshell | Glenjamin: I was using the #”…” syntax but that might not work for what I’m doing |
| 09:19 | alexherbo2 | ddellacosta: thanks |
| 09:19 | alexherbo2 | ^^ |
| 09:19 | ddellacosta | alexherbo2: np |
| 09:36 | broquaint | If cshell was still about I would've suggested seqex - https://github.com/jclaggett/seqex |
| 09:41 | ddellacosta | broquaint: cool stuff |
| 09:58 | eflynn | is there anything wrong with a collection of atoms? |
| 09: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 | eflynn | 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 | eflynn | 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 | ddellacosta | eflynn: swap!-ed it, to be clear |
| 10:09 | ddellacosta | 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 | 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 | dabbelingClj | 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 | dabbelingClj | 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 | sluukkonen | (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 | hyPiRion | And I don't mean core.typed here |
| 11:10 | dabbelingClj | no its fine its an "ovious" API mistake on my side |
| 11:11 | dabbelingClj | can I put that (parse-stream (clojure ...) in a def ? |
| 11:12 | dabbelingClj | ha ok I always forget that i have to evaluate "every *new" expression in LT |
| 11:13 | dabbelingClj | 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 | Glenjamin | or just shift+cmd+enter to re-eval the whole file |
| 11:14 | Glenjamin | 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 | Glenjamin | 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 | hhenkel | 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 | gfredericks | throan |
| 11:21 | gfredericks | 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 | PigDude | 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 | clgv | hhenkel: but you want to force immediate evaluation? |
| 11:31 | clgv | hhenkel: then use "doall" or "vec" |
| 11:31 | clgv | 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 | PigDude | llasram: this is honestly how i often see my relationship with code users when i work on a library |
| 11:40 | PigDude | llasram: you're probably right |
| 11:40 | PigDude | clgv: that is what i do now, the API is in core |
| 11:40 | PigDude | 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 | PigDude | 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 | PigDude | clgv: (thinking of package privacy and such) |
| 11:47 | PigDude | clgv: funny post bw |
| 11:47 | PigDude | *btw |
| 11:48 | PigDude | '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 | shriphani | done * |
| 12:28 | shriphani | 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 | shriphani | nbeloglazov: https://www.refheap.com/86236 |
| 12:31 | shriphani | see the draw routine and the call to image at the end |
| 12:33 | shriphani | nbeloglazov: and that does this: http://shriphani.com/pics/bug.png |
| 12:33 | shriphani | 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 | shriphani | wee ! |
| 12:41 | nbeloglazov | which renderer works? |
| 12:41 | nbeloglazov | 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 | justin_smith | ie. it handles them kind of indeterminately |
| 12:51 | shriphani | nbeloglazov, both java2d, p2d and p3d |
| 12:51 | shriphani | 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 | justin_smith | 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 | justin_smith | 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 | stompyj | 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 | gtrak | it's easy. |
| 12:58 | gtrak | 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 | stompyj | but ok |
| 12:58 | stompyj | enough people are using jetty that I shouldn’t necc. avoid it |
| 12:59 | stompyj | has anyone seen when uberjar works, but uberwar fails? |
| 12:59 | stompyj | 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 | stompyj | Exception in thread "main" java.lang.NullPointerException, compiling:(util.clj:90:1) |
| 13:00 | stompyj | oh geez |
| 13:00 | stompyj | I’m a moron |
| 13:01 | stompyj | 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 | bbloom | on the jvm side that is |
| 13:13 | bbloom | 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 | bbloom | oh well. i'll just need to use a deftype |
| 13:13 | bbloom | and extend |
| 13:14 | bbloom | 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 | bbloom | 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 | bbloom | 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 | bhauman | 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 | stompyj | 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 | gtrak | twitter acct |
| 14:01 | gtrak | it's hard to find good ones if I just go look for them, but sometimes that's what I want. |
| 14:01 | gtrak | 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 | arrdem | 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 | arrdem | so I should be alright. |
| 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: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 | hiredman | 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 | dbasch | 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 | dbasch | 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 | ToxicFrog | 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 | ToxicFrog | 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 | bbloom | 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 | amalloy | 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 | Raynes | 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 | dbasch | 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 | bbloom | 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 | TimMc | (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 | TimMc | 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 | hiredman | you just need to load the class, not call any methods |
| 15:10 | hiredman | similar to jdbc driver kind of things |
| 15:10 | hiredman | Class.forName("clojure.lang.RT"); |
| 15:11 | TimMc | Yeah, I suppose that would be more clear to the reader. |
| 15:11 | TimMc | The error I get if I don't preload it is really bizarre though. |
| 15:12 | TimMc | 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 | hiredman | 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 | l1x | 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 | justin_smith | 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 | cbp | er |
| 15:26 | cbp | ignore that |
| 15:28 | justin_smith | /ignore that |
| 15:46 | johnwalker | why doesn't (.start (Thread. #(println "print"))) print "print"? |
| 15:47 | johnwalker | o_o |
| 15:49 | cbp | johnwalker: it does |
| 15:50 | cbp | 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 | johnwalker | because using .run gave me some output |
| 15:51 | johnwalker | thanks cbp |
| 15:52 | dbasch | johnwalker: check your *nrepl-server* buffer |
| 15:54 | johnwalker | right on dbasch |
| 15:55 | johnwalker | 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 | bbloom | extensional means the collections list all the members |
| 16:11 | bbloom | 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 | bbloom | ystael: amalloy can tell you that my spelling sucks |
| 16:11 | bbloom | fifosine: anyway, the point is: you can just define a function for membership testing & pass that function around |
| 16:12 | bbloom | 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 | bbloom | 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 [¶ms] (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 | fifosine | 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 | bbloom | you have a total ordering of colors, so you can create an extent map |
| 16:17 | bbloom | an extent map is a sorted set of ranges of used colors |
| 16:18 | bbloom | there are many extent map data structures, such as bitmap trees and stuff like that |
| 16:18 | bbloom | but really, i think this is totally crazy... so please explain what you're actually trying to accomplish |
| 16:18 | bbloom | 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 | bbloom | ok |
| 16:19 | bbloom | 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 | fifosine | I wanted to do this in clojure |
| 16:22 | fifosine | So I'm curious to find a fast way to query a unique color |
| 16:22 | fifosine | 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 | ystael | 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 | bbloom | 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 | amalloy | (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 | amalloy | &(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 | ystael | 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 | ystael | 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 | ystael | 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 | ystael | 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 | ystael | (because (7^2)^6 = (7^3)^4 = (7^4)^3 = 7^12 = 1) |
| 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 | amalloy | ystael: there's guaranteed to be (at least) one p that works for any given n, right? |
| 16:50 | amalloy | 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 | ystael | For n = 13, they are 7^j, where j is relatively prime to 12 |
| 16:51 | ystael | (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 | edlothiol | 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? |
| 16:58 | pbostrom | |
| 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 | noncom|2 | ? |
| 17:04 | Glenjamin | merge-with |
| 17:04 | Glenjamin | (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 | noncom|2 | 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 | noncom|2 | oh i can just see if the arg is a {} then, repeat this again, else just return the arg |
| 17:09 | noncom|2 | i guess.. |
| 17:09 | noncom|2 | 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 | noncom|2 | nice, one more case to watch for :) |
| 17:10 | noncom|2 | 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 | noncom|2 | bbloom yeah.. |
| 17:11 | amalloy | noncom|2: i mean, one reasonable interpretation of "deep merge" is in flatland.useful.utils/adjoin |
| 17:12 | amalloy | 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 | Glenjamin | 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 | noncom|2 | 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 | Glenjamin | 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 | yeoj___ | 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 | Glenjamin | 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 | justin_smith | 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 | justin_smith | socket, not port |
| 18:12 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | dbasch | s |
| 18:17 | arohner | I remember seeing a blog post a few months ago /join #clojurescript |
| 18:17 | arohner | gah |
| 18:17 | arohner | ^^ 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 | justin_smith | 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 | awwaiid | and make your window small |
| 18:19 | awwaiid | 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 | justin_smith | that tries to describe the various distinctions of forwarding types |
| 18:24 | justin_smith | "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 | yeoj___ | 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 | yeoj___ | ssh -L 1000:remotehoste:1000 |
| 18:28 | yeoj___ | (i don't put 22 in there anywhere? ) |
| 18:28 | justin_smith | no |
| 18:28 | justin_smith | ssh uses 22 implicitly |
| 18:28 | justin_smith | 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 | justin_smith | (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 | justin_smith | instead of remotehost specify "localhost" or "127.0.0.1" |
| 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 | justin_smith | in case you are using it proxy style |
| 18:30 | justin_smith | 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 | justin_smith | using "localhost" or "127.0.0.1" as the remote? |
| 18:32 | justin_smith | 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 | justin_smith | yeoj___: and visualvm does show that app as being there? |
| 18:35 | justin_smith | *that process |
| 18:35 | yeoj___ | trying again with 127.0.0.1 |
| 18:35 | yeoj___ | 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 | yeoj___ | same two on the laptop |
| 18:41 | yeoj___ | 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 | yeoj___ | (the one i changed the java debug options/dt_transport/etc. stuff) |
| 18:43 | yeoj___ | the ssl -L one logs me into another terminal (through cygwin/bash) and then just sits there |
| 18:43 | yeoj___ | no idea |
| 18:44 | justin_smith | yeoj___: you mentioned windows, this looks relevant: https://netbeans.org/bugzilla/show_bug.cgi?id=48170 |
| 18:44 | justin_smith | 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 | amalloy | 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 | yeoj___ | i wish jvisualvm was an ncurses app |
| 18:47 | yeoj___ | 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 | justin_smith | (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 | arrdem | 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 | arrdem | 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 | PigDude | 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 | PigDude | 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 | PigDude | the regex "0" is less specific than "^0##.*$" so what gives? |
| 19:10 | amalloy | re-matches checks for a complete match |
| 19:10 | amalloy | &(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 | amalloy | (or re-seq) |
| 19:10 | PigDude | i just want a fast LEFT() test |
| 19:11 | PigDude | aka startswith |
| 19:11 | dbasch | PigDude: then use startsWith :) |
| 19:11 | PigDude | ah ok |
| 19:12 | PigDude | thanks dbasch |
| 19:35 | PigDude | do you use :refer [s] or :refer (s)? |
| 19:37 | technomancy | PigDude: use [s] |
| 19:39 | technomancy | 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 | amalloy | 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 | amalloy | 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 | amalloy | 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 | technomancy | 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 | amalloy | 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 | amalloy | 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 | gfredericks | 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 | gfredericks | 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 | gfredericks | er |
| 20:03 | gfredericks | ~/.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 | amalloy | sadly. i have no idea why |
| 20:04 | amalloy | but it can't be the same one |
| 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 | gfredericks | "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 | gfredericks | 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 | gfredericks | 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 | andyf_ | 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 | andyf_ | 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 | Bronsa | 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 | amalloy | you don't want reduce, though, you want every? |
| 20:46 | amalloy | (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 | yeoj___ | i know i can allow for remote repl connections by listening on 0.0.0.0 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 | justin_smith | 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 | justin_smith | that always works for me on a lan |
| 22:15 | justin_smith | (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 | yeoj___ | 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 | justin_smith | 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 | yeoj___ | i have no idea what is on what isn't and how it works |
| 22:19 | yeoj___ | 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 | amalloy | 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 | Shaun__ | Is there some hacky way to kill all go-blocks even? |
| 23:02 | amalloy | unplug your computer |
| 23:03 | amalloy | (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 | p_l | 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 | amalloy | 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 | right1 | 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 | blr | 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 :) |