2014-08-29
| 00:00 | justin_smith | akj: a better definition (I think): (defn split-seq [pred coll] (lazy-seq (when (seq coll) (let [coll (drop-while pred coll) [leading remaining] (split-with (complement pred) coll)] (cons leading (split-seq pred remaining)))))) |
| 00:29 | akj | just_smith: thanks! that works perfect |
| 01:30 | echo-area | Is it true that updating existing values by adding cannot be used with prepared statement in jdbc? |
| 01:30 | echo-area | E.g. UPDATE table1 SET value = value + 1 ... |
| 01:33 | justin_smith | echo-area: http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html |
| 01:35 | justin_smith | echo-area: http://clojure.github.io/java.jdbc/#clojure.java.jdbc/db-do-prepared |
| 01:36 | echo-area | justin_smith: I tried this: ["update testtable set value = ? ..." "value + 1"] but it obviously won't work |
| 01:37 | justin_smith | clojure.java.jdbc also has prepare-statement to create a preparedstatement object |
| 01:37 | kqr | echo-area, why not just "UPDATE table SET value = value + 1"? |
| 01:38 | justin_smith | you can use a preparedstatement instead of a string |
| 01:38 | kqr | echo-area, you don't need any question marks to do that |
| 01:38 | echo-area | kqr: Yes a non-prepared statement will work. I wonder if it's possible to make it prepared |
| 01:39 | justin_smith | echo-area: yes - use prepare-statement to create it out of the string, then provide that to the db function instead of the string |
| 01:39 | kqr | what does it mean for you to "make it prepared"? |
| 01:39 | kqr | you don't *have* to have question marks in your prepared statements |
| 01:39 | echo-area | justin_smith: I tried to provide "value + 1" but it won't work |
| 01:40 | justin_smith | echo-area: don't provide anything |
| 01:40 | justin_smith | just use the prepared-statement function |
| 01:40 | kqr | and then executeUpdate |
| 01:40 | echo-area | justin_smith: How would I provide a value meaning "the current value in the database, plus 1" later? |
| 01:41 | justin_smith | echo-area: with the standard sql syntax |
| 01:41 | kqr | echo-area, by constructing the query statement later |
| 01:41 | kqr | echo-area, when you know that you want the current value + 1 |
| 01:41 | justin_smith | kqr: no, you can construct the prepared statement, and run it later |
| 01:41 | kqr | that's even better |
| 01:42 | kqr | I haven't had my morning coffee |
| 01:42 | echo-area | Hmm, so is it not possible to map statements without a query statement directly into prepared statement? |
| 01:43 | kqr | I think it might help to explain what you are trying to do |
| 01:43 | kqr | rather than how you are trying to do it |
| 01:43 | justin_smith | echo-area: a prepared statement is just a statement you compile once and re-use, if it doesn't need parameters, all the better |
| 01:44 | echo-area | I am trying to translate thread 1 and thread 2 codes in this link http://ronaldbradford.com/blog/understanding-innodb-mvcc-2009-07-15/ |
| 01:45 | justin_smith | echo-area: OK, that's showing stored procedures, which are similar to prepared statements in their advantages, but are not the same thing at all |
| 01:47 | echo-area | justin_smith: But code of e.g. thread 1 is not stored procedure |
| 01:47 | justin_smith | sure, and you can make a prepared statement with exactly those contents |
| 01:47 | justin_smith | you don't need to parameterize it or provide arguments |
| 01:49 | echo-area | Do I need to replace "f2 + 200" with a query statement? |
| 01:49 | justin_smith | just construct the whole thing, you don't need to parameterize it at all |
| 01:49 | justin_smith | think of it as a function that takes no arguments |
| 01:50 | kqr | stm = preparedStatement("update table set f2 = f2 + 200"); |
| 01:50 | kqr | executeUpdate(stm); |
| 01:50 | kqr | something like that |
| 01:50 | justin_smith | kqr: if you turn camelCase into snake-case and prefix(calls) into (nested calls) that may even work as is |
| 01:51 | justin_smith | or very close to it, modulo some connection arguments and such :) |
| 01:51 | kqr | yeah I think it operates on a database object of some sort |
| 01:51 | justin_smith | (execute! connection (prepare-statement "sql goes here")) |
| 01:52 | justin_smith | kqr: it's a config describing how one gets a connection |
| 01:52 | kqr | ah |
| 01:52 | justin_smith | it can contain a map of authentication data and a URL, or have a keyword with a connection pool, or a few other options iirc |
| 01:53 | kqr | was a while since I did database stuff in java |
| 01:53 | justin_smith | clojure.java.jdbc is a bit more lispy than regular jdbc too |
| 01:53 | kqr | that's nice |
| 01:54 | justin_smith | kqr: iirc the java api has setters for a connection object, while the clojure version takes an immutible config (which may have a mutable java thing like a pool hiding inside) |
| 01:54 | kqr | depends on what you mean by setters, but you inject arguments to a prepared statement with setters |
| 01:55 | kqr | don't remember any particular setters for the connection, but that might just be me not using the more advanced features |
| 01:55 | echo-area | Yes that was what I did and it succeeded. What if I want to e.g. parameterize f2 here? |
| 01:56 | justin_smith | than you would create a paramaterized statement and provide the apropriate arguments? |
| 01:56 | kqr | echo-area, parametrize f2 or the value of f2? |
| 01:56 | echo-area | f2 |
| 01:58 | echo-area | justin_smith: But the supplied value can only be constants |
| 01:58 | kqr | that's an unusual use case |
| 01:58 | kqr | so I don't know if it's possible with a preparedstatement at all |
| 01:59 | justin_smith | echo-area: the point of a prepared statement is that it be pre-compiled / pre-optimized. If the row you operate on is a variable, how much do you think it can really pre-optimize that? |
| 01:59 | justin_smith | s/row/column, sorry |
| 02:00 | echo-area | Okay, got it. Thank you both |
| 02:00 | justin_smith | OK, I'm staying logged in, but turning in for the night |
| 02:01 | echo-area | :) Good night then |
| 02:01 | kqr | echo-area, what you could do if you need to parametrise on f2 is make "field" a column in the database |
| 02:01 | kqr | echo-area, and set e.g. field=f2 |
| 02:02 | kqr | not exactly that because that wouldn't work as expected, but I think the idea is that you might have the wrong DB structure if you need to do that |
| 02:09 | echo-area | kqr: I see |
| 02:15 | mi6x3m | can someone explain why this happens: |
| 02:15 | mi6x3m | (def f #()) |
| 02:15 | mi6x3m | (= (with-meta f {:a 0}) (with-meta f {:a 1])) gives false |
| 02:20 | TEttinger | ,(def f #()) |
| 02:20 | clojurebot | #'sandbox/f |
| 02:20 | TEttinger | (= (with-meta f {:a 0}) (with-meta f {:a 1})) |
| 02:20 | TEttinger | ,(= (with-meta f {:a 0}) (with-meta f {:a 1})) |
| 02:20 | clojurebot | false |
| 02:20 | TEttinger | hm |
| 02:20 | TEttinger | ,(= f (with-meta f {:a 0}))) |
| 02:20 | clojurebot | false |
| 02:20 | TEttinger | ,(= f f)) |
| 02:20 | clojurebot | true |
| 02:21 | TEttinger | (doc with-meta) |
| 02:21 | clojurebot | "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata." |
| 02:21 | TEttinger | ,(let [f {:blah :foo}] (= (with-meta f {:a 0}) (with-meta f {:a 1})) |
| 02:21 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 02:21 | TEttinger | ,(let [f {:blah :foo}] (= (with-meta f {:a 0}) (with-meta f {:a 1}))) |
| 02:21 | clojurebot | true |
| 02:21 | TEttinger | woah |
| 02:21 | TEttinger | fn metadata is different from object |
| 02:22 | brehaut | ,(with-meta 1 {:a 1}) |
| 02:22 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IObj> |
| 02:22 | brehaut | ,(with-meta (Object.) {:a 1}) |
| 02:22 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Object cannot be cast to clojure.lang.IObj> |
| 02:25 | brehaut | (let [a #()] (= a a)) |
| 02:25 | brehaut | ,(let [a #()] (= a a)) |
| 02:25 | clojurebot | true |
| 02:25 | brehaut | oh but that will be identity based |
| 02:26 | brehaut | ,(let [a #() b #()] (= a b)) ;; obviously |
| 02:26 | clojurebot | false |
| 02:26 | brehaut | two identical functions created at seperate times are not equivalent because turing completeness |
| 02:26 | brehaut | and attaching meta data is a pure operation |
| 02:28 | brehaut | ,(let [a #()] (= a (with-meta a {:a 1}))) |
| 02:28 | clojurebot | false |
| 02:33 | TEttinger | dammit alan how much of clojure did you break with your turing completeness! |
| 04:50 | noncom|3 | if i am to create clojure datastructs from within java code, do i prefer using classes which are named "Persistent*" like "PersistentVector" and such ? |
| 04:51 | lgrapent` | noncom|3: You should use the Java API http://clojure.github.io/clojure/javadoc/clojure/java/api/package-summary.html |
| 04:52 | noncom|3 | lgrapent`: oh, how nice! i forgot about it being around |
| 04:54 | noncom|3 | lgrapent`: however, there is still a question - if i have a java method that shoudl return a clojure [], then what do i say for the return type? |
| 04:54 | noncom|3 | is it clojure.lang.PersistentVector ? |
| 04:54 | amalloy | noncom|3: c.l.IPersistentVector |
| 04:54 | amalloy | or something weaker than that, if you don't need all those guarantees |
| 04:54 | amalloy | like a Collection, or a List, or an Iterable. depends what you "need" |
| 04:56 | noncom|3 | amalloy: alright, got it. and how do i create such a [] inside the method? doing something like Clojure.read("[1 2 3]") as suggested in the link above does not really seem to be very fast.. |
| 04:58 | lgrapent` | noncom|3: You can spawn the vector or vec IFn |
| 05:00 | noncom|3 | lgrapent`: still seems to be slower than PersistentVector.create(...) ... |
| 05:00 | noncom|3 | but bot that much slower i guess.. if i take care to cache the things... |
| 05:00 | noncom|3 | what do yo think ? |
| 05:02 | noncom|3 | see, i am falling back to java because i need speed with operations on ints, which is damn hard with clojure.. therefore i would like to make it all as fast as possible.. |
| 05:03 | noncom|3 | and still the "IFn.invoke" thing returns an Object which requires another cast... |
| 06:16 | lvh | Can you turn a bigint into a byte[], or do I need BigInteger for that? |
| 06:16 | lvh | (I'm trying to turn numeric nonces into byte[24] nonces) |
| 07:04 | christian_stamm | Hi. I'm trying to deploy an uberjar to a local nexus using leiningen. lein deploy does not seem to support that. google suggests leiningen-plugins that appear to be unmaintained. Any ideas? |
| 07:05 | christian_stamm | the software will be used as a selfcontained microservice. Thats why I really want to deploy an uberjar. |
| 07:19 | mpenet | lein deploy can take a jar as parameter (and pom.xml etc etc), so you can do it |
| 07:20 | mpenet | christian_stamm: "lein deploy help" will tell you more about this |
| 07:20 | mpenet | christian_stamm: "lein help deploy" actuallaly |
| 07:20 | mpenet | meh, can't type today |
| 07:21 | christian_stamm | mpenet i was hoping for sonmething like "lein deploy uberjar", which creates the uberjar just like "lein deploy" creates the jar |
| 07:22 | christian_stamm | so i do not have to find out the current version in the shell. lein already knows it |
| 07:28 | mpenet | I dont think that's possible, maybe something worth doing a PR for! |
| 07:38 | hyPiRion | put an issue up first |
| 07:39 | hyPiRion | ah. see technomancy/leiningen#652 |
| 07:39 | lazybot | added support for deploy-uberjar plugin -- https://github.com/technomancy/leiningen/pull/652 is closed |
| 07:59 | zuzkins | Hey guys, anyone has some experience with putting a js (google closure style annotated) lib on classpath (packaged in a jar), so it will be picked up by the cljsbuild task and could be used in cljs? |
| 08:24 | SagiCZ1 | hi.. i would like to get interactive development with swing working.. can anyone check why is this not working? i would like to keep re-evaluating the setContentPane function thus changing content of the existing frame.. code -> https://www.refheap.com/89575 .. it actually does switch the content but the Rect is not being drawn |
| 08:24 | SagiCZ1 | it works fine when i setContentPane in the "doto" block |
| 08:25 | borkdude | is there a function that does a transformation on a map key by function? |
| 08:25 | borkdude | like (assoc m :foo (inc (:foo m)) |
| 08:27 | borkdude | update-in probable |
| 08:27 | borkdude | *y |
| 08:28 | andyf | borkdude: update-in is what I would recommend: http://grimoire.arrdem.com/1.6.0/clojure.core/update-in/ |
| 08:28 | borkdude | andyf thanks |
| 08:30 | andyf | the cheatsheet might be helpful for looking for functions related to particular data structures, or functionality similar to each other: http://clojure.org/cheatsheet but also these versions with tooltips: http://jafingerhut.github.io/ |
| 08:36 | SagiCZ1 | ok i needed to call revalidate and repaint |
| 08:36 | SagiCZ1 | wonder if there is a nicer way with plain swing |
| 08:39 | broquaint | SagiCZ1: seesaw? |
| 08:40 | SagiCZ1 | broquaint: i dont understand how to run the tutorial.. first google result throws me at github source code |
| 08:41 | broquaint | SagiCZ1: You eval the code as you go. |
| 08:41 | SagiCZ1 | so i just check the repo and work with the source? |
| 08:42 | broquaint | No, just depend on it and then boot up a repl. |
| 08:43 | broquaint | Is this where you ended up? http://blog.darevay.com/2011/12/a-seesaw-tutorial/ |
| 08:45 | SagiCZ1 | ehre https://gist.github.com/daveray/1441520 |
| 08:45 | SagiCZ1 | here |
| 08:46 | SagiCZ1 | so i added seesaw dependency.. downloaded it.. still dont know what to do |
| 08:47 | benzap` | SagiCZ1: you should probably follow a leinegen tutorial |
| 08:47 | benzap` | I had issues understanding the build system at first too |
| 08:47 | SagiCZ1 | so you do understand what am i supposed to do with the code in the link above? |
| 08:48 | benzap` | from the article? |
| 08:48 | SagiCZ1 | from what i linked |
| 08:48 | benzap` | yeah, you need to create a new project with leiningen |
| 08:49 | benzap` | lein new seesaw-tutorial |
| 08:49 | benzap` | go into project.clj, and add the seesaw dependency (this is the hardest part) |
| 08:49 | benzap` | then boot up your lein repl |
| 08:49 | benzap` | or run lein deps first, in the target folder, in my example, it would be ./seesaw-tutorial |
| 08:50 | benzap` | this is all basic leiningen build functionality, so i'd suggest running through the tutorial, and get a good understanding https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md |
| 08:50 | SagiCZ1 | i did all that |
| 08:50 | SagiCZ1 | and now what< |
| 08:50 | SagiCZ1 | ? |
| 08:51 | SagiCZ1 | just retype the code from the source and see what it does>? |
| 08:51 | benzap` | ah ok, so the next step is to get a repl environment setup |
| 08:52 | SagiCZ1 | i have the repl up and running |
| 08:52 | SagiCZ1 | and it works |
| 08:52 | benzap` | where are you running the repl? |
| 08:52 | SagiCZ1 | Cursive terminal |
| 08:53 | SagiCZ1 | am i supposed to read the source code on the link and retype the commands in my repl? |
| 08:53 | benzap` | ah I see, so that's a basic repl, you can actually link into a 'repl server' using an editor with an plugin |
| 08:53 | benzap` | most people around here use emacs, but it works with vim, eclipse, etc |
| 08:53 | SagiCZ1 | like remote repl< |
| 08:53 | SagiCZ1 | ? |
| 08:54 | benzap` | ya |
| 08:54 | SagiCZ1 | so whats the host and port? |
| 08:55 | benzap` | i'm not sure what the default is... i've just always left it up to my editor to set up the remote repl for me |
| 08:55 | cfleming | SagiCZ1: you don't need a remote REPL |
| 08:55 | SagiCZ1 | i am so confused |
| 08:55 | benzap` | when I connect to the clojure repl on my android device, it's usually 9000, but I don't know if that's stanard |
| 08:55 | cfleming | You're trying to run the Seesaw tutorial, right? |
| 08:55 | SagiCZ1 | can anyone explain what "REPL-tutorial" means and how do i use it? |
| 08:55 | SagiCZ1 | yes |
| 08:56 | cfleming | Ok |
| 08:56 | cfleming | And you have a Leiningen project set up, with Seesaw added as a dependency? |
| 08:56 | SagiCZ1 | yup |
| 08:56 | cfleming | Ok |
| 08:57 | cfleming | So your project has a namespace in it, seesaw-tutorial.core or something similar, right? |
| 08:57 | SagiCZ1 | no |
| 08:57 | SagiCZ1 | just core.clj |
| 08:57 | SagiCZ1 | i edited the project.clj file to add the dependency and then i run lein deps |
| 08:57 | cfleming | Ok, that one is fine - when you open it, it has the ns declaration and the function that lein creates for you, right? |
| 08:57 | SagiCZ1 | the dependencies are in my External Libraries |
| 08:58 | cfleming | Ok, good. |
| 08:58 | SagiCZ1 | yeah.. defn foo |
| 08:58 | cfleming | Right. |
| 08:58 | cfleming | Delete the defn foo, and replace the text of the file with the text of the REPL tutorial. You probably want to leave the namespace there at the top of the file, but replace the rest. |
| 08:59 | SagiCZ1 | got it |
| 08:59 | SagiCZ1 | and now i can evaluate |
| 08:59 | SagiCZ1 | whatever i want |
| 09:00 | cfleming | Ok. |
| 09:00 | SagiCZ1 | send it to repl right? |
| 09:00 | SagiCZ1 | works fine |
| 09:00 | cfleming | Exactly - the REPL tutorial is really just a series of commands to send to the REPL. |
| 09:00 | cfleming | But don't send the whole file at once, follow it down sending one command at a time. |
| 09:00 | cfleming | The comments explain what it's doing. |
| 09:00 | cfleming | Make sense? |
| 09:00 | SagiCZ1 | yeah i have a keyshortcut for the "run top form" |
| 09:00 | cfleming | Perfect. |
| 09:01 | SagiCZ1 | thank you very much.. i am sorry to summon you with the "Cursive" magic word with such a stupid question.. |
| 09:01 | cfleming | Haha, no problem, I've run that tutorial myself - it's nice. |
| 09:01 | cfleming | Seesaw is really great. |
| 09:01 | cfleming | Good luck. |
| 09:01 | SagiCZ1 | i like swing personally |
| 09:02 | SagiCZ1 | so i hope seesaw is just a good clojure way to access swing |
| 09:02 | cfleming | Oh, it's lovely. |
| 09:02 | SagiCZ1 | great! |
| 09:02 | SagiCZ1 | cfleming: have a great day.. i gotta run |
| 09:02 | cfleming | Check out Dave's presentation from Clojure/West a couple of years back, that explains the basics too. |
| 09:02 | cfleming | Ok, seeya |
| 09:02 | SagiCZ1 | k |
| 09:12 | lxsameer | hey folks, I need a lib to create a proxy server , what do you suggest ? |
| 09:26 | ephemeron | Are there interesting examples of using transducers to transform associative collections rather than sequences? |
| 09:37 | stompyj | Are clojure “alpha” builds stable outside of the new features? |
| 09:40 | hyPiRion | stompyj: I wouldn't count on it. There were some pretty serious "memleaks" in an alpha afaik. |
| 09:40 | stompyj | hyPiRion: thanks! |
| 09:40 | stompyj | thats what I was curious about |
| 09:41 | hyPiRion | usually it's okay for devel, but I would never use it in prod before there are release candidates |
| 09:45 | Bronsa | hyPiRion: the leak was on 1.5.0 |
| 09:45 | Bronsa | that's why 1.5.1 was released |
| 09:47 | Bronsa | stompyj: 1.7.0-alpha1 has only changes for transducers and a patch for faster symbol/keyword creation |
| 09:47 | Bronsa | stompyj: so, no more bugs than 1.6.0 aldready had, except for transducers |
| 09:48 | stompyj | Bronsa: thanks, I’ll experiment with it. I’ll be honest, I don’t fully understand transducers, but based on the usage patterns I’m seeing, I think I could use them in this project i’m using rightn ow |
| 09:48 | stompyj | heh |
| 09:48 | dnolen_ | ephemeron: what are you looking for it's pretty straightforward |
| 09:49 | Bronsa | stompyj: FYI 1.7.0-alpha1 has a pretty serious equality bugs w/ transducers producing lazy sequences, the fix has already been committed and will be in the next release |
| 09:50 | stompyj | Bronsa: Thanks, I’ll move with caution. Although, again, to be honest, I don’t even understand how that would affect me |
| 09:50 | stompyj | heh |
| 09:52 | borkdude | Why doesn't this return 1? (go (let [[v c] (alts! [(go 1)] :default 100 :priority true)] (println v))) |
| 09:52 | borkdude | *print 1 |
| 09:53 | mpenet | is that even possible to nest go blocks? |
| 09:53 | borkdude | mpenet I hope so? |
| 09:54 | mpenet | but why doing so? |
| 09:54 | stompyj | mrb_bk: you there? |
| 09:54 | borkdude | I just wanted to have a channel that has 1 in it, and this seemed to do it? |
| 09:55 | borkdude | like this: (go (let [v (<! (go 1))] (println v))) ;; prints 1 |
| 09:56 | mpenet | well, if you macroexpand (go 1), I believe this get hairy for just a 1 |
| 09:56 | martinklepsch | hi again. I have a situation where I want to use core.async to make a small ajax request and then initiate a longer running one based on the result of that first smaller ajax request. I'm confused how many channels I should be using/where to store the information from the first request (or should I just put it right into the next channel to make the second request?) does anyone have any guidance for me? :) |
| 09:57 | borkdude | martinklepsch you can do that in one go block |
| 09:57 | borkdude | (go (let [body1 (<! (http/get ...) body2 (<! (http/get ... body 1....)))))))) |
| 09:57 | borkdude | don't mind the closing parens, they are just an estimation ;) |
| 09:59 | supreme__ | Hi, Im using a parllax solution that Smashing magazine published some time ago, http://richardshepherd.com/smashing/parallax/ . It uses background-positon to achieve it's effects trough different speeds. How can I make this work with <p> tags? Do I need to make the same stuff but to set the margin-top maybe? |
| 10:00 | borkdude | do I have to use :priority true when I use just one channel in alts! with a default value provided? |
| 10:01 | borkdude | my guess is that it doesn't non-deterministically choose the default value |
| 10:09 | andyf | CLJ tickets moving to approved! I get excited about such things. |
| 10:12 | mdrogalis | andyf: I'll bet! |
| 10:16 | mpenet | I hope the work from ztellman on collections makes it in 1.7 |
| 10:17 | mpenet | but it's probably for 1.8. But maybe... since other "large" patch are supposed to be part of 1.7 still (lean runtime, feature expr. etc) |
| 10:19 | borkdude | mpenet what work on collections is this? |
| 10:20 | mpenet | https://groups.google.com/forum/#!topic/clojure-dev/pDhYoELjrcs |
| 10:25 | tbaldridge | andyf: https://github.com/clojure/clojure/commits/master :-) |
| 10:26 | andyf | yeeha! |
| 10:26 | andyf | Almost time to go find out which other patches have gone stale. |
| 10:27 | hyPiRion | Oh, I know one. http://dev.clojure.org/jira/browse/CLJ-1134 |
| 10:29 | andyf | by stale there, I simply meant any patches that no longer apply cleanly to the latest Clojure master after the most recent commits |
| 10:29 | andyf | not any reference to their age :) |
| 10:31 | adereth | (setq display-time-string-forms |
| 10:31 | adereth | '((propertize (concat " " 12-hours ":" minutes " ")))) |
| 10:31 | adereth | doh |
| 10:33 | justin_smith | elisp? in my clojure channel? |
| 10:34 | adereth | My worst fear about using emacs as my irc client just came true. |
| 10:34 | justin_smith | heh, I have done much worse |
| 10:35 | justin_smith | for example, accidentally cutting and pasting a significant chunk of the irc buffer back in at the prompt - the strings remain propertized, so nothing looks wrong at first glance... |
| 10:36 | mrb_bk | stompyj: hello |
| 10:38 | Bronsa | justin_smith: ahah I've done that |
| 10:48 | ephemeron | dnolen_: Mostly curiosity. I was wondering if the new abstractions allowed for a better way to e.g. map/filter over hashmap values. |
| 10:52 | dnolen_ | ephemeron: they do, you can do it w/o lazy seqs |
| 11:02 | csd_ | Can someone critique this code to help me improve my technique? http://pastebin.com/8daApynG |
| 11:03 | justin_smith | csd_ the vec call on line 4 does nothing |
| 11:04 | llasram | csd_: You should keep your wrist firm, swing with the whole arm, avoid locking your elbow at the end, and keep your eye on the lambda the entire time |
| 11:04 | csd_ | ha |
| 11:05 | llasram | csd_: I haven't fully read the code, but you very rarely actually need `loop`/`recur`. You can usually get away with one of the higher-order function capturing one of the standard recursion patterns |
| 11:05 | justin_smith | instead of calling map twice in a row, it's better to use comp (map (comp #(Integer/parseInt %) str) ...) |
| 11:05 | justin_smith | also #(str %) is just str |
| 11:05 | llasram | csd_: What's this function ultimately intended to do? |
| 11:06 | csd_ | It's solves http://www.4clojure.com/problem/86 |
| 11:08 | justin_smith | csd_: looking at my own solution to that problem - yours should be very close to being correct if it isn't already |
| 11:09 | justin_smith | once you've solved it I can show you my version if you like |
| 11:09 | justin_smith | we are doing basically the same thing, just expressing it differently |
| 11:11 | csd_ | Mine solves it.. just want to make sure i'm doing things as well as i can |
| 11:11 | justin_smith | here's mine https://www.refheap.com/89577 |
| 11:12 | justin_smith | the same algorithm (except I use repeated rem / quot instead of parsing each char of the string) |
| 11:13 | csd_ | when would you want to use `while` instead of loop/recur or a HoF |
| 11:13 | justin_smith | I wrote it a while ago - that call to get should be contains? instead |
| 11:14 | justin_smith | while makes sense when you are checking state |
| 11:14 | llasram | csd_: https://www.refheap.com/89578 |
| 11:15 | justin_smith | llasram: very nice |
| 11:18 | llasram | csd_: `while` is pretty much only good for side-effects. The only place I can think of off the top of my head where I've used it is in a polling loop |
| 11:18 | justin_smith | yeah - if your condition is a message coming from a channel or maybe a status reply from another process... |
| 11:18 | justin_smith | or maybe even an atom getting set by another thread |
| 11:20 | llasram | Maybe... Watches are good for that. And in-process you can usually use some sort of push messaging from the producer |
| 11:22 | justin_smith | llasram: but if the task to interrupt when you get the message is a loop with one clear stopping point, while can wrap that nicely. Then again, I've never even used watches in anger. |
| 11:39 | fifosine | How do I require all functions in a namespace in the repl? |
| 11:40 | fifosine | I tried (require 'name.space :all) but the syntax is obviously wrong |
| 11:41 | fifosine | nvm, figured it out |
| 11:44 | virmundi | which is more idiomatic clojure (somefn {:config1 :setting1 :config2 :setting2 :other :settings}) or (somefn :config1 :setting1 :config2 :setting2)? Specifically I’ve got a map that has general connection information in it. Then I’ve specific setting based upon when the user is trying to do. I just learned the & args {:keys [name1 named2]} trick. |
| 11:45 | justin_smith | virmundi: use a map as an argument |
| 11:45 | justin_smith | it composes better |
| 11:45 | virmundi | ok |
| 11:45 | virmundi | thanks |
| 11:45 | puredanger | re http://dev.clojure.org/jira/browse/CLJ-1516 does anyone know of Clojure code that uses vars with "." in the *name* ? |
| 11:46 | Bronsa | puredanger: I just replied |
| 11:46 | justin_smith | puredanger: none that I have ever read |
| 11:47 | Bronsa | puredanger: ah wait, that might break clojure.core/.. now that I think about it |
| 11:47 | puredanger | heh |
| 11:48 | Bronsa | puredanger: ... and core.incubator/.?. |
| 11:49 | puredanger | those are both *leading* dots - maybe a special case? |
| 11:49 | TimMc | ,(def a.b 4) |
| 11:49 | clojurebot | #'sandbox/a.b |
| 11:49 | TimMc | ,sandbox/a.b |
| 11:49 | clojurebot | 4 |
| 11:49 | TimMc | Plausible. |
| 11:49 | Bronsa | puredanger: no, they work because they are macros |
| 11:50 | Bronsa | ,(defmacro a.b []) |
| 11:50 | clojurebot | #'sandbox/a.b |
| 11:50 | Bronsa | ,(a.b) |
| 11:50 | clojurebot | nil |
| 11:50 | puredanger | Bronsa: right, makes sense |
| 11:50 | Bronsa | puredanger: should I update the patch to check whether the var is marked ^:macro then? |
| 11:51 | puredanger | leading is also different in that it can't be confused with a class name |
| 11:51 | justin_smith | ,(->> (all-ns) (mapcat ns-publics) keys (map name) (filter #(re-matches #".*\..*" %))) |
| 11:51 | clojurebot | (".." "a.b") |
| 11:51 | Bronsa | eh well, leading is special cased in the macroexpander though puredanger |
| 11:51 | Bronsa | (.foo x) -> (. x foo) |
| 11:52 | Bronsa | so a .foo Var might work as a value, but not in a call position |
| 11:54 | stompyj | Is the cursive clojure author in here right now? |
| 11:54 | stompyj | (sorry, I can’t recall their name) |
| 11:54 | puredanger | Bronsa: unless it's a macro (like .?.) |
| 11:54 | justin_smith | stompyj: cfleming |
| 11:54 | stompyj | justin_smith: thanks |
| 12:04 | Bronsa | puredanger: I updated the patch, now it only throws on non macro defs |
| 12:04 | puredanger | ok, thx |
| 12:04 | Bronsa | had to tweak the definition of defmacro to include {:macro true} |
| 12:04 | puredanger | ha |
| 12:05 | Bronsa | (defn .. [&env &form & rest] ...) (.setMacro #'..) didn't really help |
| 12:06 | Bronsa | puredanger: btw what's the reason for vswap! to be a macro? |
| 12:08 | puredanger | that was Rich's request and I didn't ask him why. but I suspect it's because you're doing something that isn't thread safe so he didn't want that on the Volatile itself as a method |
| 12:10 | puredanger | the deref / reset in vswap! is racy - that's fine if you constrain how and when it's called and understand the implications |
| 12:10 | puredanger | if I get a chance, I'll ask Rich about it |
| 12:13 | puredanger | I suspect 1.7.0-alpha2 approacheth btw if anyone is interested... |
| 12:13 | justin_smith | ,*clojure-version* |
| 12:13 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 12:14 | Bronsa | puredanger: TBH i'm still not convinced it needs to be a macro, there might be a good reason but I don't see it. thanks anyway :P |
| 12:14 | puredanger | Bronsa: I don't think it *needs* to be a macro either, could easily be implemented as a method on Volatile |
| 12:16 | Bronsa | puredanger: now you've lost me, why can't it just be (defn vswap! [v f & args] (vreset! v (apply f @v args)))? |
| 12:17 | puredanger | it could also be that, but it would incur multiple var invocations at runtime |
| 12:17 | Bronsa | puredanger: right, but core has unrolls & :inlines all over the codebase |
| 12:18 | puredanger | I don't think we're trying to increase the usage of :inline at all |
| 12:19 | Bronsa | we don't have anything better yet though, forcing a valid fn to be a macro just for the sake of not using :inline seems moot |
| 12:20 | Bronsa | I'm not trying to give you a hard time, just playing devil's advocate |
| 12:29 | Bronsa | oooooh https://github.com/clojure/clojure/commit/7977b49567ecb8023abfd51e90dcbd2581c41358 finally |
| 12:30 | lvh | I wonder why that isn't spelled (update-in m [k] ...) |
| 12:30 | lvh | performance? |
| 12:30 | clojurebot | performance is http://meshy.org/2009/12/13/widefinder-2-with-clojure.html |
| 12:32 | mi6x3m | can someone explain to me why this happens |
| 12:32 | mi6x3m | (def f #()) |
| 12:32 | TimMc | ,(macroexpand-1 `#()) |
| 12:33 | clojurebot | (fn* [] ()) |
| 12:33 | mi6x3m | (= (with-meta f {:a 1}) (with-meta f {:a 2})) returns false |
| 12:33 | TimMc | A swing and a miss! |
| 12:34 | TimMc | mi6x3m: While metadata does not change equality semantics, functions don't really support = in the first place. |
| 12:34 | TimMc | Adding metadata requires creating a new object, so the two are no longer identical? to each other. |
| 12:34 | Bronsa | mi6x3m: hiredman might have something to tell you about that :) |
| 12:36 | Bronsa | (if he's around) |
| 12:37 | mi6x3m | TimMc: well yes but in this case f is the same object |
| 12:38 | Bronsa | mi6x3m: after the with-meta, it isn't |
| 12:38 | TimMc | mi6x3m: Metadata isn't magical, it's an instance field. |
| 12:39 | TimMc | &(let [a [1 2 3]] (identical? a (with-meta a {:b 1}))) |
| 12:39 | lazybot | ⇒ false |
| 12:40 | TimMc | (= f f) is only true in a vacuous sort of way |
| 12:50 | fifosine | Does anyone have experience creating simple sampled sounds? Like a simple sine wave sound? |
| 12:50 | justin_smith | fifosine: yup |
| 12:51 | fifosine | justin_smith: Do you have a gist, by any chance? Or do you use a library? |
| 12:52 | justin_smith | fifosine: here is a lib that does that and a lot more https://github.com/kunstmusik/pink |
| 12:52 | justin_smith | it does software based audio synthesis in pure clojure |
| 12:53 | justin_smith | here's where he creates the source for the sine wave https://github.com/kunstmusik/pink/blob/master/src/pink/gen.clj#L12 |
| 12:53 | fifosine | justin_smith: do you prefer it over dynne? |
| 12:53 | justin_smith | I was not familiar with dynne |
| 12:53 | justin_smith | pink is from one of the lead devs of csound |
| 12:54 | justin_smith | he also wrote blue, a pure java ide / daw hybrid for doing algorithmic composition |
| 12:55 | stompyj | csound! awesome, haven’t used that in a good 10-15 years |
| 12:55 | fifosine | justin_smith: Just a quick, off-topic question, in that source-file you linked, he defines a macro get-sine-value. Why was it better in this case to define it as a macro and not a function? (I still don't know how to use macros) |
| 12:55 | justin_smith | stompyj: it's much more real time friendly now - you can define instruments in real time |
| 12:56 | justin_smith | fifosine: I am not sure - probably because he doesn't want to pay for var lookup at runtime? basically intent to inline is my guess |
| 12:56 | stompyj | awesome, I loved it even back then. |
| 12:56 | stompyj | I should check it out |
| 12:56 | justin_smith | stompyj: it also compiles to pnacl now - which means it can run inside a chrome browser |
| 12:57 | justin_smith | stompyj: http://vlazzarini.github.io/ check out "Stria" - its a classic composition, rendering in real time in the browser |
| 12:58 | justin_smith | stompyj: the interactive demos are cool too |
| 12:58 | mi6x3m | TimMc: I'd follow that argumentation _if_ there wasn't a strict contract for the semantics of with-meta and meta in general :) |
| 12:58 | mi6x3m | i understand functions are somewhat of an exception |
| 12:58 | stompyj | justin_smith: whoa, this is crazy |
| 12:58 | mi6x3m | but the same object is the same object |
| 12:58 | stompyj | between this and max/msp live integration, this is the rig I wish I had back then |
| 12:58 | stompyj | LOL |
| 12:59 | justin_smith | stompyj: yeah, pnacl means clean enough c code can be compiled to run in the browser portably - and csound just happens to be clean enough for that |
| 12:59 | justin_smith | stompyj: also, there is a program called cabbage, that runs as a vst and lets you graphically define csound instruments |
| 12:59 | TimMc | mi6x3m: What do you mean by "the same object is the same object"? |
| 12:59 | fifosine | justin_smith: do you know of a tutorial for using pink? the docs seem sparse |
| 12:59 | mi6x3m | well it's effectively the same function |
| 12:59 | mi6x3m | in every possible aspect |
| 12:59 | mi6x3m | except the meta |
| 12:59 | justin_smith | fifosine: there is an examples folder |
| 12:59 | justin_smith | fifosine: but also it's a fairly young project |
| 13:00 | fifosine | oh wow, just a few weeks |
| 13:00 | justin_smith | it's derived from some stuff he was doing with clojure in blue |
| 13:01 | justin_smith | http://blue.kunstmusik.com/ blue supports embedding clojure code into compositions (or python, or js, or java) |
| 13:04 | gfredericks | hooray clojure.core/update is commited |
| 13:08 | TimMc | Now to get (update-in _ [] _) fixed... :-) |
| 13:09 | TimMc | mi6x3m: "effectively the same function" doesn't really mean anything -- functions are considered uncomparable... |
| 13:18 | mi6x3m | TimMc: well this is interesting given you have enough info to determine they are completely identifcal :) |
| 13:18 | mi6x3m | -f |
| 13:18 | TimMc | That's a JVM thing and doesn't really count. |
| 13:18 | TimMc | (= f f) only accidentally returns true |
| 13:19 | mi6x3m | accidentally, I see |
| 13:26 | gfredericks | ,(= (partial + 1) (partial + 1)) |
| 13:26 | clojurebot | false |
| 13:58 | amalloy | oh man, https://github.com/clojure/clojure/commit/7d77fa43902dfaa820e4f24a7d54e7ca9fff2733#diff-b6b5d2fff4501df40d740b659c3b5dccR179 is the worst sort of test. it's not *that* hard to convert a deadlocking test into a failing test |
| 14:02 | dbasch | amalloy: the language is supposed to be lazy, not the developers :P |
| 14:02 | arrdem | :D |
| 14:02 | AimHere | Perl programmers are supposed to be lazy |
| 14:03 | AimHere | laziness, impatience and hubris |
| 14:03 | dbasch | AimHere: the three horsemen of the perlpocalypse? |
| 14:04 | AimHere | Or the three programmer virtues, depending on how you view Perl |
| 14:08 | TimMc | amalloy: How would you do it? Wait n milliseconds and kill it? |
| 14:12 | amalloy | TimMc: create a promise, a future to deliver to it, and then a deref with timeout |
| 14:13 | amalloy | is how i've done that in the past. i think one of the patches i tried to get into clojure used that approach |
| 14:13 | justin_smith | amalloy: why not just deref the future with a timeout? |
| 14:14 | amalloy | that does sound simpler, justin_smith. i don't see any reason why not |
| 14:14 | amalloy | i just forgot you can do that |
| 14:14 | bja | is there any package that lets me declare config variables in a central with defaults and validation, perhaps using environ and schema? I realize I can write this myself, just casting a line first |
| 14:23 | justin_smith | bja: environ and schema would be good bets, they are both widely used, and I can't see why you couldn't use schema to validate the config that environ accesses |
| 14:39 | andyf | amalloy: Guilty as charged |
| 14:39 | andyf | amalloy: I would suggest this is an even worse test: https://github.com/clojure/clojure/commit/5123c956477b48bb995d2c2b4621ef2291315498 |
| 14:40 | andyf | Disabled because it fails only on IBM JDK 1.6 but no others |
| 14:40 | amalloy | i wonder why it doesn't work on that jdk |
| 14:41 | andyf | Because IBM's implementation of UTF-16 is different than Oracle's |
| 14:43 | amalloy | is it actually possible for two implementations of UTF-16 to be different but both correct? i wouldn't think so |
| 14:43 | andyf | When the buffer you give it has 1char left but next Unicode code point needs 2 chars, it behaves differently |
| 14:46 | andyf | It is possible to work around the difference in JVM behaviors, but Clojure core didn't want to go that way |
| 14:48 | upwardindex | Anyone has had this type of problem with http-kit? https://github.com/http-kit/http-kit/issues/163 |
| 14:49 | andyf | I guess I haven't tried IBM JDK 1.7 with that - the test probably fails there, too. |
| 15:05 | ephemeron | dnolen_: (Sorry for the late reply.) When I asked about transducers and mapping/filtering over values of a hashmap, you mentioned that they could be used to avoid intermediate seqs, but would that be an advantage over reduce-kv? |
| 15:06 | miber | if I define foo like this http://pastebin.com/sKQrb7M7 why can't I call it without args like (foo)? is there a way to have foo accept zero and more args? |
| 15:09 | adereth | miber: I think you want (defn foo [& {:keys [a b] :or {a 1 b 2}}] [a b]) |
| 15:09 | adereth | Then you can call (foo :a 3) instead of (foo {:a 3}), and (foo) instead of (foo {}) |
| 15:10 | miber | aye, that's it |
| 15:10 | miber | thank you |
| 15:11 | jlongster | I'm publishing a post on CSP in JavaScript next week, and I was wondering if I could get some feedback on a demo. Go here and run the code: http://jlongster.com/Test-CSP?preview=true for those who use core.async, is the visualization intuitive/make sense? |
| 15:14 | justin_smith | miber: adereth: best of both worlds: (defn foo [& [{:keys [a b] :or {a 1 b 2}}]] [a b]) |
| 15:14 | justin_smith | map args end up working out much better than & :keys |
| 15:15 | dnolen_ | ephemeron: don't follow reduce-kv can take a transducer |
| 15:16 | hiredman | dnolen_: I don't know that it can |
| 15:16 | puredanger | yeah, I think actually it doesn't right now |
| 15:16 | puredanger | that was a consequence of one of the design decisions internally vs what was done in reducers |
| 15:16 | hiredman | transducers being transforms of reducing functions, the reducing function for reduce-kv is of a different type |
| 15:17 | dnolen_ | hiredman: oh right the signature is different |
| 15:17 | hiredman | reduce-kv is actually kind of annoying |
| 15:17 | miber | justin_smith: isn't adereth's version more idiomatic in terms of having a function that takes optional arguments? |
| 15:17 | dnolen_ | ephemeron: anyways, reduce-kv is orthogonal to transducers |
| 15:17 | justin_smith | miber: options maps are preferred in practice |
| 15:17 | dnolen_ | ephemeron: reduce-kv to accomplish what transducers do would need to take a transducer like thing |
| 15:18 | justin_smith | miber: maybe that's a more dev culture thing than language design, but it's easier to compose things, and you have more flexibility, when the optional args are all in a map |
| 15:19 | miber | ok |
| 15:24 | kqr | how would one construct a regex in clojure with the COMMENTS flag set in the underlying Pattern object? |
| 15:24 | bbloom | kqr: you can just call the constructor normally |
| 15:24 | bbloom | kqr: you don't need to use the literal syntax |
| 15:25 | bbloom | kqr: but you can also use the (?x) flag |
| 15:25 | kqr | yeah, I was just curious if there was a way to set it with the literal syntax |
| 15:25 | bbloom | http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#COMMENTS |
| 15:25 | kqr | how would one use the ?x flag? I'm not well versed in the Java world |
| 15:26 | justin_smith | kqr: C-f for "flag" here http://clojuredocs.org/clojure_core/clojure.core/re-pattern |
| 15:26 | bbloom | ,(.flags #"(?x)") |
| 15:26 | clojurebot | 4 |
| 15:26 | justin_smith | line 38 of the example |
| 15:27 | kqr | justin_smith, ah brilliant |
| 15:27 | bbloom | ,(bit-and (.flags #"(?x)") java.util.regex.Pattern/COMMENT) |
| 15:27 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to find static field: COMMENT in class java.util.regex.Pattern, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:27 | bbloom | ,(bit-and (.flags #"(?x)") java.util.regex.Pattern/COMMENTS) |
| 15:27 | clojurebot | 4 |
| 15:27 | kqr | justin_smith, very nice. thank you! |
| 15:28 | justin_smith | actually starts on 27 I guess, but I think that's exactly what you were looking for |
| 15:28 | kqr | yup |
| 15:28 | kqr | that regex mode is a godsend for writing more complicated regexes |
| 15:29 | justin_smith | it really seems like it would be |
| 15:29 | kqr | you can have indentation and just a few characters per line |
| 15:29 | kqr | really showing the structure of things |
| 15:29 | kqr | it probably makes it dangerously easy to read/write regexes... |
| 15:29 | justin_smith | I have seen scheme versions of an alternate regex syntax (sexp rather than string based) so that regexes become properly composible, transformible, etc. |
| 15:29 | kqr | yeah |
| 15:29 | justin_smith | this was for scsh iirc |
| 15:30 | kqr | i've been experimenting with writing a DSL for constructing regexes |
| 15:30 | justin_smith | I think the way scsh did it would be -- if not ideal, at least an excellent start |
| 15:30 | kqr | some combinators are really useful, such as "this regex represents a thing, now find a bunch of things separated by this regex" |
| 15:30 | kqr | for example |
| 15:31 | kqr | but in the end, I think a combination of raw regexes and combinators are the way forward |
| 15:31 | justin_smith | http://scsh.net/docu/post/sre.html some examples and a spec here |
| 15:32 | kqr | yeah the verbosity of that is what makes me think a combination is best |
| 15:32 | justin_smith | it uses operator overloading - which is not ideal for clojure |
| 15:33 | justin_smith | kqr: conciseness - the cause of, and the solution to, all regex problems |
| 15:33 | kqr | hahaha |
| 15:33 | kqr | you're not entirely wrong |
| 15:33 | kqr | but there's still a little part of me that thinks sometimes smaller things are easier to read because we can absorb more of it at once |
| 15:33 | justin_smith | can I quote you on that, in my resume? |
| 15:33 | kqr | or something |
| 15:34 | justin_smith | kqr: I information theory can lead us to a mathematical proof of the ideal conciseness / verbosity balance |
| 15:34 | kqr | I look forward to any results on that |
| 15:35 | justin_smith | the more inherently concise a syntax, the more likely an error is valid syntax, but not what you wanted |
| 15:36 | justin_smith | as a programmer, the potential a typo that still runs, but doesn't do what I wanted, is a very frightening thing |
| 15:39 | turbofail | something something shannon limit |
| 15:39 | justin_smith | exactly |
| 15:43 | justin_smith | turbofail: you can get the full Shannon article from bell labs http://cm.bell-labs.com/cm/ms/what/shannonday/shannon1948.pdf |
| 15:43 | justin_smith | it's brilliant |
| 15:47 | avi__ | justin_smith: the cross-entropy of source code is far far far less than than english |
| 15:47 | amalloy | justin_smith: "the potential a typo that still runs, but doesn't do what I wanted" makes me think of keywords |
| 15:47 | avi__ | justin_smith: software is very simple, repetitve and rigid (at least how people write it) |
| 15:48 | justin_smith | amalloy: yeah, I think of them that way too |
| 15:48 | turbofail | avi__: clearly you haven't read enough perl |
| 15:49 | avi__ | turbofail: real perlers write perl in a simple clear and repetitive manner |
| 15:49 | justin_smith | avi__: this is a bonus, it makes it easier to see accidental or corrupt content |
| 15:49 | avi__ | justin_smith: http://macbeth.cs.ucdavis.edu/natural.pdf |
| 15:49 | justin_smith | avi__: that article looks really cool, thanks |
| 15:50 | avi__ | justin_smith: by studying large corporae of software we found that software wasnt super exciting and people write boring stuff |
| 15:50 | justin_smith | avi__: are you quoting the article, or is this something you actually worked on? |
| 15:50 | avi__ | I am the first the author |
| 15:50 | justin_smith | oh, awesome, thanks for sharing |
| 15:50 | avi__ | On that topic, I'm a software engineering researcher studying the topics of issue/bug reports. Like those issues on the docker repo ;) I'm looking to pick the brains of devs to help validate if these NLP topics make any sense. I've got a short 10 minute survey consisting of "one of these things are not like other" questions. If you're interested in the survey please PM /msg avi__ me. |
| 15:50 | justin_smith | (inc avi__) |
| 15:50 | lazybot | ⇒ 1 |
| 15:51 | avi__ | (probably going to decr me for that one) |
| 15:51 | justin_smith | heh |
| 15:51 | avi__ | justin_smith: so using the n-gram model of code we can find the locations of syntax errors too |
| 15:52 | avi__ | justin_smith: my PhD student did a demo for java and a working one for python |
| 15:52 | justin_smith | avi__: I would love a probabalistic linter for clojure - something that would scan your code and tells you which parts are "weird" |
| 15:53 | mdeboard | lol |
| 15:53 | avi__ | justin_smith: yeah totally doable if you can lex it (of course you can) https://github.com/orezpraw/unnaturalcode http://webdocs.cs.ualberta.ca/~joshua2/syntax.pdf |
| 15:56 | avi__ | justin_smith: yeah the information content of code is really neat |
| 15:56 | avi__ | justin_smith: it is related to readability as well |
| 15:57 | avi__ | justin_smith: if you look at english complexity metrics, they are basically entropy or entropy * size. |
| 15:57 | avi__ | justin_smith: halstead's V is a vocabulary based -- entropy like -- metric for code that is similar |
| 15:57 | avi__ | justin_smith: and it correlates with human rankings of code readability |
| 15:58 | avi__ | justin_smith: the takeaway: code with a lot of uniq tokens is complicated to read. Code with lots of repetition and fewer unique tokens is easier to read. And of course the less code to read the more readable. |
| 15:58 | tac | Why does Hickey seem to have case/match statements? |
| 15:58 | tac | I've seen two talks now where he mentions it |
| 16:00 | turbofail | hate or have? |
| 16:01 | justin_smith | tac: is he, by any chance, contrasting them to a mechanism like multimethod dispatch? |
| 16:01 | tac | hate* |
| 16:01 | tac | sry |
| 16:01 | tac | justin_smith: I'm not sure. It's always been in passing |
| 16:01 | tac | But it's stuck out both times, because case-splitting is the morally correct way to do if statements :X |
| 16:02 | turbofail | i feel like racket is the lisp that does pattern matching best at the moment |
| 16:02 | tac | but I'm guessing he is judging them in a type-less context |
| 16:02 | avi__ | tac: is that because you believe most if statements don't need precedence? |
| 16:02 | avi__ | tac: or that if-chains usually are precedence free? |
| 16:03 | tac | It's not really about precedence |
| 16:03 | tac | It breaks up a value, then dispatches based on what form it has |
| 16:10 | tac | also, he's mentioned queues a lot. |
| 16:11 | tac | Which is strange, since I don't think I've ever used a queue |
| 16:11 | tac | But that probably says more about the kind of software I typically write |
| 16:12 | bbloom | tac: or you're just doing everything wrong. queues are awesome |
| 16:12 | justin_smith | tac: just speculating, but if you ever start doing serious concurrency, you will probably learn to admire queues |
| 16:13 | tbaldridge | tac, there's two problems with pattern matching, IMO. |
| 16:13 | tac | bbloom: justin_smith: If either of you wants to convince me, my mind is open today :) |
| 16:13 | tac | What makes queues magical :) |
| 16:14 | tbaldridge | tac: firstly pattern matching is often tied to types. That is to say, if I pattern match off of a vector of strings, does it always have to be a vector? |
| 16:14 | bbloom | tac: well, what type of software do you typically write? i ask so that a good answer can be tailored to you |
| 16:15 | virmundi | justin_smith: why is there no (not-nil?) |
| 16:15 | bbloom | virmundi: b/c there is seq |
| 16:15 | tbaldridge | tac: secondly, most pattern matching is closed, if I want to extend a pattern match, I have to go off and modify the original code. Something like multimethods are much more open |
| 16:16 | bbloom | tbaldridge: i'm not sure i understand your first point |
| 16:16 | tac | bbloom: single-threaded web stuff ;( |
| 16:16 | bbloom | tac: do you log anything? that's a queue :-P |
| 16:16 | justin_smith | also, if you want to check non-sequential things, there is (complement nil?) ##(map (complement nil?) [nil true [0 1 2] :ok]) |
| 16:16 | lazybot | ⇒ (false true true true) |
| 16:16 | mdrogalis | tbaldridge: Wasn't order-complecting one of his complaints? |
| 16:17 | bbloom | tac: you've never needed to run a background task? |
| 16:17 | bbloom | mdrogalis: yeah, rich's primary complaint is that typical pattern matching implies ordered choice |
| 16:17 | tac | hmm |
| 16:17 | tbaldridge | right as well as types: http://www.reddit.com/r/programming/comments/lirke/simple_made_easy_by_rich_hickey_video/c2t7a9f |
| 16:18 | justin_smith | bbloom: wouldn't the request -> handler dispatch be based on a queue? |
| 16:18 | tbaldridge | at least that was the argument from simple made easy |
| 16:18 | tac | gotcha |
| 16:18 | tac | with the background tasks, logging |
| 16:18 | bbloom | justin_smith: not at the application level |
| 16:18 | justin_smith | ahh, right |
| 16:18 | tac | it's whenever you need to delegate work, then, right? |
| 16:18 | amalloy | ,(doc some?) |
| 16:18 | clojurebot | "([x]); Returns true if x is not nil, false otherwise." |
| 16:18 | tac | and it's not so important who handles it |
| 16:18 | amalloy | ;; virmundi, justin_smith |
| 16:19 | amalloy | added in 1.6 |
| 16:19 | bbloom | tbaldridge: i agree that ordered choice pattern matching is problematic |
| 16:19 | bbloom | tbaldridge: for similar reasons i dislike peg grammars |
| 16:19 | tac | also, re: pattern matching... yeah. It sucks when order matters in your branches. |
| 16:19 | justin_smith | amalloy: oh, cool, added 1.6 so I wasn't familiar |
| 16:19 | Clarice | What's the point of some? if there's or? |
| 16:19 | justin_smith | and now I see you already said that :) |
| 16:20 | tac | done "properly", pattern matching should be order-independent always. |
| 16:20 | justin_smith | Clarice: Some takes only one arg |
| 16:20 | tac | It's just very convenient sometimes to break that rule |
| 16:20 | justin_smith | Clarice: I don't see how or would replace it at all |
| 16:20 | amalloy | justin_smith: 1.6 added a number of functions that distinguish between nil and false |
| 16:20 | bbloom | tbaldridge: also reading rich's comment about types, i think he's complaining about both product types and sum types, not about issues like vectors vs other sequentials |
| 16:20 | justin_smith | amalloy: cool, thanks, I wasn't aware |
| 16:21 | bbloom | tbaldridge: in particular with respect to pattern matching on sum types, they enforce exhaustiveness tests at all usage sites |
| 16:26 | bbloom | side note: i've never found a satisfactory academic treatment of tagged products, which is the only type that appears in real languages |
| 16:27 | bbloom | the closest i've seen is the notion that Foo(x,y) is actually dependently a typed (Foo,x,y) |
| 16:27 | noprompt | bbloom, dnolen_: is it possible to know what the namespace part of a symbol fully resolves to in cljs from a macro? for example if i (:require [om.core :as om]) and want to rewrite om/IRender as om.core/IRender. |
| 16:27 | bbloom | nevermind i've also never found a satisfactory academic treatment of the associativity of the binary product type constructor |
| 16:27 | justin_smith | noprompt: isn't that what ` does? |
| 16:27 | bbloom | justin_smith: that only works for the clj env |
| 16:27 | noprompt | justin_smith: not necessarily |
| 16:28 | justin_smith | ahh, OK |
| 16:28 | bbloom | justin_smith: sometimes you get lucky and the two overlap, like as with most of core |
| 16:28 | bbloom | noprompt: you'd have to use the @namespaces atom |
| 16:28 | noprompt | bbloom: on a scale of 0 to 1 how dicey is that. :P |
| 16:28 | bbloom | noprompt: i haven't done it yet, but i wanted to create a cljs-aware sytnax quote using my backtick library |
| 16:30 | noprompt | bbloom: that'd probably be helpful to me. i'm working on a clojurescript tracing library and having the symbol be fully resolved is helpful. |
| 16:30 | bbloom | noprompt: it should be quite easy to do, give it a go |
| 16:31 | Bronsa | noprompt: try using (cljs.analyzer/resolve-var &env 'om/IRender) |
| 16:31 | Bronsa | (from inside a "cljs" macro) |
| 16:31 | noprompt | Bronsa, bbloom: will give it shot. |
| 16:31 | bbloom | noprompt: https://github.com/brandonbloom/backtick/blob/4672faf9219a4a714afa27fda25da205d29dc60a/src/backtick.clj#L85-L101 |
| 16:32 | bbloom | noprompt: that handles all the edge cases for the jvm |
| 16:32 | Bronsa | bbloom: if only symbol resolution was that easy for cljs too |
| 16:32 | bbloom | Bronsa: all the dotted paths nonsense? |
| 16:32 | bbloom | :-/ |
| 16:33 | Bronsa | bbloom: js/, gclosure "namespaces" & "vars", Var.foo etc |
| 16:33 | bbloom | Bronsa: argh. indeed |
| 16:39 | Bronsa | bbloom: btw remember when I was thinking about macroexpanding js/foo into js* forms? |
| 16:40 | Bronsa | I actually did it for tools.analyzer.js, but then ended up reverting it and introduced a :js-var op instead |
| 16:40 | bbloom | yeah, extra ops is often a good call |
| 16:40 | bbloom | especially when it comes to host complexity |
| 16:40 | Bronsa | Having all interop forms macroexpand to a single special form is neat, but you lose a lot of context & info |
| 16:40 | elarson | in a lein project, I added a dependency for ring/ring-core "1.3.1" and running lein deps seemed to install it (it showed up in my ~/.m2/repository directory). but when I try to require it in the ns macro for my core.clj, I get FileNotFoundExceptions saying there isn't a .class or .clj file on the classpath with that name. |
| 16:41 | justin_smith | elarson: what are you trying to require? note that project names are not the same as namespace names |
| 16:42 | elarson | justin_smith: I've tried so many options, but specifically I wanted to use the functions in ring.util.time |
| 16:43 | justin_smith | elarson: can you paste your require form to refheap or a gist? |
| 16:43 | justin_smith | *your ns form (or require if you are doing it from a repl...) |
| 16:45 | elarson | justin_smith: https://gist.github.com/ionrock/ed1b8de49df61f228748 |
| 16:45 | hiredman | I have a protocol with a single function (f), and in a few places I call that function, in the places I call it (f x) I get compile time errors, but if I change it to (apply f [x]) no compile time errors and no errors at runtime |
| 16:45 | hiredman | (protocols suck) |
| 16:45 | justin_smith | elarson: also, based on the project.clj for ring-clojure, I think you want [ring "1.3.1"] |
| 16:46 | elarson | justin_smith: I have [ring/ring-core "1.3.1"] in dependencies. |
| 16:46 | Bronsa | hiredman: what's the compile time error? |
| 16:46 | amalloy | that's exciting, hiredman. any idea why? |
| 16:46 | Bronsa | I believe (f x) will go through the interface while (apply f [x]) won't |
| 16:47 | hiredman | Bronsa, amalloy: no lemme dig up the stacktrace |
| 16:47 | hiredman | it is the "no implementation of this protocol for this function" or whatever very confusing error protocols to that effect |
| 16:47 | amalloy | Bronsa: (f x) looks at the var at compile time. i'd be surprised if (apply f [x]) never used the interface |
| 16:48 | hiredman | the project is doing aot, I should see what happens if I remove that |
| 16:48 | hiredman | Oh, huh, actually, it maybe because I called the protocol function "wait" |
| 16:48 | hiredman | I wonder if that has some adverse interaction with the wait on Object |
| 16:48 | Bronsa | yeah that's likely the cause then hiredman |
| 16:49 | justin_smith | elarson: https://www.refheap.com/89587 I can use it from a brand new project |
| 16:49 | bbloom | hiredman: protocols define backing interfaces which have a shared global namespace :-( |
| 16:49 | justin_smith | elarson: by asking for [ring "1.3.1"] |
| 16:49 | Bronsa | amalloy: you might be right, I don't remember off the top of my head; looking in the source now |
| 16:49 | amalloy | hiredman: that sounds like it to me |
| 16:49 | bbloom | go gets this wrong too |
| 16:50 | amalloy | a protocol pitfall i'd not thought of |
| 16:50 | bbloom | same issue as java where there's a single namespace for methods |
| 16:50 | elarson | justin_smith: well, even though it is not working for me, I'm glad it works for someone ;) |
| 16:50 | justin_smith | elarson: that's using alembic.still inside a vanilla "lein new" project |
| 16:50 | elarson | that gives me a bit hope |
| 16:50 | justin_smith | try changing the project part of the dependency to just ring |
| 16:50 | hiredman | interesting, I guess that was the first time I had a non-higher order usage of that protocol |
| 16:51 | elarson | justin_smith: trying that now |
| 16:51 | Bronsa | amalloy: I'm looking at the macroexpansion of a defprotocol now, I don't see any reference to the interface method |
| 16:51 | hiredman | anyway, that was it |
| 16:52 | bbloom | Bronsa: doesn't the compiler discover protocol call sites? |
| 16:52 | elarson | justin_smith: changing the dependency seemed to be it! |
| 16:52 | elarson | thank you |
| 16:52 | Bronsa | bbloom: yes, we were talking about HOF usage of protocol functions |
| 16:52 | bbloom | oh ok |
| 16:52 | justin_smith | elarson: awesome - in the future, use the dep in the form you see it in the project.clj of the lib you are using |
| 16:53 | justin_smith | elarson: np |
| 16:53 | Bronsa | bbloom: f could be implemented as (defn f [this ..] (if (instance? this Interface) (.method this ..) ..)) but it doesn't look like it is |
| 16:53 | elarson | justin_smith: will do. that is helpful as well b/c I've seen some projects that don't include a lein dependency string to use. |
| 16:53 | Bronsa | it just uses the method cache |
| 16:54 | bbloom | Bronsa: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L508-L509 |
| 16:54 | Bronsa | blargh, (instance? Interface this) |
| 16:55 | Bronsa | bbloom: uh, hmm |
| 16:56 | justin_smith | elarson: tangentially, pallet/alembic is an awesome dep to have in your global profiles.clj, because it makes it very easy to temporarily try some dependency without having to restart your repl |
| 16:57 | Bronsa | ah nevermind, I see it now: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L571 |
| 16:59 | amalloy | hey, Bronsa, that's the one line in that file that i committed |
| 16:59 | Bronsa | yeah I remember now |
| 16:59 | bbloom | https://github.com/clojure/clojure/blame/1d856d485baeedd75c508495c5a966bf4d9a4375/src/clj/clojure/core_deftype.clj#L571 well i'll be dammed :-P |
| 17:00 | amalloy | bbloom: indeed, i did check git-blame before making my claim |
| 17:00 | Bronsa | defprotocol's impl is definitely not the easiest code to read |
| 17:01 | bbloom | Bronsa: not at all |
| 17:01 | bbloom | Bronsa: it's kinda crazy actually |
| 17:01 | Fare | frankly, I'd like to dislike clojure, but I can't. |
| 17:02 | justin_smith | "I just don't know how to System/exit you" |
| 17:08 | maacl | Hi guys, I have a Java interop question. I am trying to access the accept method of a com.sun.jersey.api.client.WebResource but I get No matching method found: accept for class which is clearly not correct as the method does exist. Can anyone help out? |
| 17:11 | puredanger | are you using Clojure 1.6+ ? |
| 17:11 | puredanger | that error message was improved to show the types (if known) in 1.6. if you are seeing unknown, then it has no type info |
| 17:12 | puredanger | you probably need to type hint either the resource or an arg if there is one |
| 17:12 | maacl | using 1.5.1 at the moement |
| 17:13 | puredanger | not sure I can tell you more without a gist, but most likely you just need a type hint |
| 17:15 | aperiodic | oh, those are var arg methods |
| 17:16 | maacl | puredanger: sorry, thought that was directed at me |
| 17:16 | aperiodic | which I think means you need (into-array String <collection of strings>) as the argument in the interop form |
| 17:16 | amalloy | maacl: it was |
| 17:18 | puredanger | maacl: it was directed at you :) |
| 17:18 | arohner | using core.async, if a bunch of consumers are waiting for the same event to finish, is it idiomatic to just close a channel to signify 'it's done'? |
| 17:18 | maacl | amalloy: oh, now I am completely confused |
| 17:18 | arohner | I don't really feel like muxing a chan for each consumer |
| 17:19 | puredanger | arohner: closing a channel does a good job of indicating "done" |
| 17:19 | aperiodic | maacl: you need a java array of the appropiate type to pass to the method |
| 17:20 | gzmask | how do I use math.floor in clojure? |
| 17:20 | amalloy | aw, i'm sad this doesn't work: $ ln -s /usr/bin/git ~/bin/git-git; git git commit |
| 17:21 | maacl | I am basically trying to implement this: https://gist.github.com/maacl/2cd4e05c53221d0c730a in Clojure |
| 17:21 | amalloy | i frequently forget and type too many gits |
| 17:21 | gzmask | i tried (Math.floor 0.01) gives error |
| 17:21 | arrdem | &(Math/floor 0.01) |
| 17:21 | lazybot | ⇒ 0.0 |
| 17:21 | arrdem | gzmask: ^ |
| 17:22 | aperiodic | maacl: (.accept resource (into-array MediaType [MediaType/TEXT_XML]) |
| 17:22 | Fare | -ETOOMANYGITS |
| 17:22 | amalloy | Fare: https://twitter.com/technomancy/status/327234371813781505 |
| 17:22 | gzmask | ahh, I thought / and . are interchangeable. thanks ! |
| 17:23 | Fare | when I watch TV and that's what I think |
| 17:23 | arrdem | gzmask: not in this context. . would be used to note an instance method, / is for static methods |
| 17:23 | maacl | aperiodic: Ah, and this is because accepts accepts multiple media types? |
| 17:24 | gzmask | i see. thx :) |
| 17:24 | justin_smith | maacl: clojure does not do the same varargs sugaring java does |
| 17:24 | justin_smith | maacl: varargs are really just an array as the last arg |
| 17:24 | aperiodic | maacl: yes, it's a var args method which in actuality means it takes an array of the method type |
| 17:24 | aperiodic | s/method/arg/ |
| 17:27 | maacl | aperiodic: got it,really bad at Java.. is it corectly understood that "MediaType... types" this is what indicates that it is a var args method? |
| 17:27 | bobpoekert | Is there a way to tell vimclojure to call pprint on a selection? copy/pasting into a repl is kind of annoying. |
| 17:28 | aperiodic | maacl: yup, the elipses after the argument type indicates var args |
| 17:28 | aperiodic | s/el/ell/ |
| 17:29 | maacl | aperiodic: great, thanks |
| 17:29 | aperiodic | well I guess it's one ellipsis |
| 17:29 | aperiodic | maacl: you're welcome |
| 17:30 | arrdem | bobpoekert: I think that vimclojure has been depricated for vimclojurestatic and fireplace.vim |
| 17:31 | arrdem | but I'm no longer a Vim clojurist so not sure. |
| 17:31 | bobpoekert | arrdem: |
| 17:31 | bobpoekert | it has |
| 17:32 | bobpoekert | but vimclojure is what I have set up |
| 17:32 | bobpoekert | and replacing my editor environment seems really risky |
| 17:32 | bbloom | bobpoekert: https://github.com/greglook/whidbey |
| 17:33 | bbloom | bobpoekert: will just pretty print every evaluation result to nrepl |
| 17:33 | bobpoekert | I don’t think vimclojure uses nrepl |
| 17:33 | bobpoekert | I think it uses nailgun |
| 17:33 | bbloom | bobpoekert: time to upgrade to fireplace :-) |
| 17:33 | bobpoekert | maybe I’ll do that when I have a spare two days :p |
| 17:33 | arrdem | yep it's just using nailgun to manage a raw clojure repl |
| 17:34 | aperiodic | FWIW vimclojure-static and fireplace.vim were both painless to set up, in stark contrast to vimclojure |
| 17:34 | arrdem | vimclojure is literally the reason I stopped using vim and transitioned to emacs :P |
| 17:34 | aperiodic | vimclojure was the worst |
| 17:34 | bobpoekert | but I’ve been using vimclojure for years and I have my .vimrc configured around it |
| 17:35 | bobpoekert | so I’d have to do some work to switch to something else |
| 17:36 | arrdem | I think you'll find that switching off of vimclojure to the nRepl tooling will pay off pretty quickly. but that's just my 0.02. |
| 17:39 | aperiodic | bobpoekert: well in the meantime, instead of copy-pasting, if you use screen or tmux, you could try the terrible hack that is vim-slime |
| 17:39 | aperiodic | https://github.com/jpalardy/vim-slime |
| 17:39 | bobpoekert | heheheh nice |
| 17:39 | aperiodic | but I agree with arrdem on this, you should put in the work to switch over to the new stuff |
| 17:39 | aperiodic | it's great |
| 17:40 | arrdem | I was only happy with clojure before making the Emacs jump |
| 17:40 | arrdem | now I'm in love |
| 17:40 | arrdem | but it's your time and you may have deadlines etc. |
| 17:41 | arrdem | I've had the luxury of being able to take a day and fix my tooling for the most part. |
| 17:43 | l1x | hey guys what is the best way to process a file that has multiple json entries? |
| 17:43 | justin_smith | l1x: it should be trivial to get all of it using cheshire |
| 17:44 | arrdem | justin_smith: interesting paper looking forwards to reading it in full |
| 17:46 | devn | hikari connection pooling + jtds, ever done it? |
| 17:46 | devn | (from clojure) |
| 17:48 | justin_smith | devn: have not used that pool, but with other pools it suffices to add a :datasource key to your connection info, with the value being the pool object |
| 17:48 | justin_smith | (assuming hikari uses the same interface for jdbc connection pooling that C3p0 does) |
| 17:49 | arrdem | Raynes: fs provides no resource handling just "real" files, correct? |
| 17:50 | l1x | justin_smith: thanks |
| 17:50 | Cheery | Hi. I'm not familiar with clojure. If you were to give it alternative syntax, what would I need to read for that? |
| 17:51 | Cheery | also is there a standard .json parser? |
| 17:51 | l1x | data.json |
| 17:51 | justin_smith | Cheery: for json, cheshire is best imho, but it comes with data.json |
| 17:52 | amalloy | Cheery: alternative syntax? like, you hate parens and want something better, or what? |
| 17:52 | arrdem | does anyone have a good hack for (.exists (io/resource ..))? |
| 17:53 | Cheery | amalloy: it's bit complicated I've noticed. Well I guess I could show you. |
| 17:53 | justin_smith | arrdem: (some? (io/resource foo)) |
| 17:53 | Cheery | http://cheery.github.io/lisp-editor/ |
| 17:54 | justin_smith | arrdem: but since false is not a valid URL, you can just check it for truthyness anyway |
| 17:54 | Cheery | amalloy: that kind of thing. It encodes it's output in .json, just because I was too lazy to implement an unique format for it. |
| 17:54 | l1x | arrdem: https://github.com/l1x/head-to-tail/blob/master/src/head_to_tail/helpers.clj#L23 |
| 17:54 | l1x | like this? |
| 17:55 | justin_smith | l1x: a valid resource may not be a file |
| 17:55 | arrdem | l1x: yeah that doesn't quite work. |
| 17:55 | justin_smith | l1x: it could be something from inside a jar |
| 17:55 | arrdem | justin_smith: good catch I didn't realize that io/resource would be nil if a matching file is not found. |
| 17:55 | Cheery | amalloy: it's using only a small subset of .json syntax, but to read in as clojure, I'd need to feed clojure something like this: cond:( (a ...) (b ...) else:( ...)) |
| 17:55 | justin_smith | arrdem: you can count on io/resource returning nil for things not on the classpath |
| 17:56 | justin_smith | arrdem: matching resource :) |
| 17:57 | amalloy | Cheery: the clojure syntax is the clojure syntax. there's no button to swap to some other syntax. you don't need to use parens or whatever, if you plan to implement your own reader, but you'll still have to pass the compiler the same set of list/vector/map objects |
| 17:57 | justin_smith | Cheery: you can make your own parser if you like with instaparse, but why not just generate valid clojure? it's a very automatic-generation friendly language |
| 17:57 | bbloom_ | and for a proof of concept, don't even bother with a string/file parser, just read in the JSON and write a recursive function to translate it to normal lists/vectors/etc |
| 17:58 | bbloom_ | then call eval |
| 17:58 | justin_smith | (inc bbloom_) |
| 17:58 | lazybot | ⇒ 1 |
| 17:58 | justin_smith | yeah that's smart |
| 17:58 | Cheery | hmm.. it's that simple? |
| 17:58 | justin_smith | (inc bbloom) |
| 17:58 | lazybot | ⇒ 41 |
| 17:58 | Cheery | okay. I'll do that. :) |
| 17:59 | Cheery | afterwards will do couple screencasts. it'll be fun. hopefully. |
| 17:59 | Cheery | hopefully, clojure has lexical scope? |
| 17:59 | Cheery | and call by value? |
| 18:00 | justin_smith | Cheery: yes on both counts |
| 18:00 | justin_smith | Cheery: and all the standard data types are immutible |
| 18:00 | Cheery | okay. then I know how to use it.. |
| 18:00 | justin_smith | Cheery: well - as long as you are comfortable coding without mutation - it is much different than normal common lisp code on that count |
| 18:01 | Cheery | completely without mutation? |
| 18:01 | amalloy | call by value is indistinguishable from call by reference if nothing ever mutates |
| 18:02 | Fare | not just without mutation, but also without block / return-from and other control structures. |
| 18:02 | justin_smith | Cheery: well, we cheat in some places, but explicit mutation is the exception |
| 18:02 | amalloy | Cheery: there are escape hatches to get mutation, but you don't need them much |
| 18:02 | Cheery | oh that's insanity. But hey I'll try it before condemning. |
| 18:02 | Fare | (does clojure have unwind-protect?) |
| 18:02 | justin_smith | Cheery: on the contrary, mutation is insane, don't you want some of this delicious Kool-Ade brand Fruit Drink? |
| 18:03 | amalloy | Fare: it has try/catch/finally |
| 18:03 | Fare | ok |
| 18:03 | Cheery | justin_smith: I have my own thanks :) |
| 18:05 | justin_smith | Cheery: one of the Big Ideas behind Clojure's design is to make it a sane environment for pervasive concurrency. Part of that is eliminating the need for locks by using data structures that implement structural sharing under the hood but don't have a semantics for mutation. We have a few "reference types" that represent a shared, thread safe, value that can be changed safely without breaking concurrently running code. |
| 18:06 | Cheery | hmm |
| 18:07 | justin_smith | I should probably s/eliminate/vastly reduce/ above |
| 18:09 | justin_smith | ,(let [a [0] b (conj a 1)] [a b]) ; Cheery: as an example |
| 18:09 | clojurebot | [[0] [0 1]] |
| 18:10 | justin_smith | the 0 "cell" is shared by a and b, but no normal code can change a such that b reflects that change (or visa versa) |
| 18:10 | justin_smith | though you can do evil things with reflection |
| 18:10 | justin_smith | (or knowing a few impl details) |
| 18:10 | arrdem | (inc undocumented impl details) |
| 18:10 | lazybot | ⇒ 1 |
| 18:10 | justin_smith | heh |
| 18:10 | amalloy | justin_smith: a list is probably better as an example than a vector |
| 18:11 | justin_smith | amalloy: fair point |
| 18:11 | Cheery | is inc a macro? |
| 18:11 | justin_smith | it's a bot command |
| 18:11 | amalloy | since they'll be more familiar to another lisper, and because vectors don't actually do much sharing for small vectors |
| 18:11 | justin_smith | Cheery: which is confusingly similar to clojure syntax, but completely different in behavior :) |
| 18:11 | casperc | i'm wondering, is it possible to make a function that returns the meta data of an input function? |
| 18:11 | casperc | I want to capture the name and ns of a function at runtime |
| 18:12 | Cheery | (inc 1) |
| 18:12 | lazybot | ⇒ 8 |
| 18:12 | bbloom_ | Fare: your evaluator is monadic? |
| 18:12 | Cheery | hm.. |
| 18:12 | justin_smith | ,(let [a 0 b (inc a)] [a b]) |
| 18:12 | clojurebot | [0 1] |
| 18:12 | amalloy | casperc: functions don't have namespaces or metadata; only vars do |
| 18:12 | Fare | bbloom: yes |
| 18:12 | Fare | well, it's a compiler, and it's not complete enough to evaluate, yet. |
| 18:12 | justin_smith | Cheery: if you use , you can get actual clojure code interpeted, the inc bot command is not clojure |
| 18:12 | Fare | getting there, slowly. Didn't make much progress last week. |
| 18:12 | Cheery | okay |
| 18:12 | Cheery | ,(inc 1) |
| 18:12 | clojurebot | 2 |
| 18:12 | Fare | most passes are monadic, a few are pure. |
| 18:13 | casperc | amalloy: yeah that's my problem i guess, so there is no way to do it at all? |
| 18:13 | Fare | the only monad I've been using so far is the state monad |
| 18:13 | justin_smith | Cheery: note how in my example I call inc on a, but a does not change |
| 18:13 | Cheery | oh wait. inc doesn't need to be a macro. value goes in, value goes out |
| 18:13 | justin_smith | right, without mutation, many macros don't have much justification for themselves any more |
| 18:13 | amalloy | justin_smith: i'm not really convinced by that |
| 18:13 | Fare | right now, I'm working on the code that will evaluate each python statement in the "smallest needed monad". |
| 18:14 | arrdem | casperc: well you could alter the defn and fn macros to capture *ns* and soforth as metadata.. |
| 18:14 | Bronsa | so it looks like vswap! will actually be a macro :/ |
| 18:14 | amalloy | like, setf doesn't need to exist, but in general i don't see the connection between macros and mutation |
| 18:14 | bbloom_ | Fare: there's no such thing as the MTL in clojure (as far as i know) nor would ir eally want it... but you can make a custom "python compiler monad" where the context is just a map, one of the things in that map is the state you need, and another thing is envs, continuation prompts, etc |
| 18:14 | justin_smith | amalloy: just referring to the need for macros with setf style stuff - we don't have much of that |
| 18:15 | Cheery | justin_smith: anyway if there's only few macros, it's nice. |
| 18:15 | Fare | the MTL ? |
| 18:15 | justin_smith | not that we don't still need macros |
| 18:15 | bbloom_ | Fare: here's a toy python interpreter in haskell that makes good use of fix & callCC for while loops: https://github.com/mattgreen/hython/blob/e341bd8f2c68ca8ce258cd276e2020205321d440/src/Interpreter.hs#L141-L149 |
| 18:15 | hiredman | Bronsa: I am not super surprised, rich rarely changes anything he has written |
| 18:15 | Fare | bbloom: thanks |
| 18:15 | Cheery | you've got callCC and you're doing javascript targets? |
| 18:15 | casperc | what I am really trying to do is to capture the input and output of certain functions and save that in a map or something with the ns/function-name as key |
| 18:16 | bbloom_ | amalloy: i've found that when mutation is involved, i write quite a few more macros |
| 18:16 | Cheery | or wait.. that was haskell |
| 18:16 | bbloom_ | amalloy: nothing that a function + thunk arguments couldn't handle, but evaluation control is more important with effects |
| 18:16 | Cheery | do you have call/cc? |
| 18:16 | bbloom_ | Cheery: no |
| 18:16 | Fare | I've been stuck last week on environment continuation analysis: finding which variables are live, whether return / raise / finally need to be captured, etc. |
| 18:16 | bbloom_ | Cheery: we only have the jvm's exception handling, sadly |
| 18:17 | Fare | the trick was proper representation of continuations in while loops. |
| 18:17 | Fare | (I desugar for into while, so while is my only loop) |
| 18:17 | Fare | I will also have to put consecutive def into a same letfn, which I'm not doing yet |
| 18:18 | bbloom_ | seems reasonable to make while primitive, rather than have to deal with fixed point combinators and all that jazz |
| 18:18 | Fare | while is my fix-point combinator of sorts |
| 18:18 | bbloom_ | exactly |
| 18:18 | Fare | especially due to the way I transform assignments into bindings |
| 18:19 | Fare | (but even if I didn't) |
| 18:19 | bbloom_ | in EClj (which i haven't worked on in months :-/) i modeled normal recursive calls with the y combinator, but modeled recur with the effect system |
| 18:19 | Fare | I can't "simply" desugar it into a higher-order function, because that would kill the visibility of the variables. |
| 18:20 | Cheery | bbloom_: hilariously I remember why I was repulsed from this language for so long. But I still think it's brilliant idea to implement support for clojure. |
| 18:20 | bbloom_ | recur was effectively a resumable exception, such that i could model the fact that you don't resume it explicitly |
| 18:20 | Cheery | I don't need to like it myself. |
| 18:20 | Fare | which visibility becomes a horrible matter in presence of try/except/finally, notably. |
| 18:20 | Fare | Cheery: repulsed from what language? |
| 18:21 | Cheery | from clojure. |
| 18:21 | bbloom_ | Cheery: your repulsion for clojure is not justified. the jvm, maybe, but clojure is full of damn good ideas that common lispers & schemers should pay attention to... even if it sacrifices many useful features on the alter of host interop |
| 18:21 | Fare | bbloom: what does EClj target? |
| 18:21 | bbloom_ | Fare: right now it's just an interpreter. i have half a JIT compiler written on my local machine i haven't shared yet |
| 18:21 | bbloom_ | runs on JVM |
| 18:22 | Cheery | bbloom_: yes. I think it deserves a look. |
| 18:22 | bbloom_ | my interpreter is hilarious slow and my jit is hilariously unfinished/broken :-) |
| 18:22 | Fare | uh, aren't exception expensive, such that this would make recur expensive? |
| 18:22 | Cheery | bbloom_: I also have one non-implemented jit |
| 18:22 | Cheery | :P |
| 18:23 | Cheery | there's nothing wrong in hilariously slow interpreters though. |
| 18:23 | bbloom_ | Fare: my interpreter is trampolined CPS, not real exceptions, and not monadic either |
| 18:23 | Cheery | bbloom_: cheney MTA CPS |
| 18:23 | Fare | as in (trampoline #(do that next)) ? |
| 18:24 | bbloom_ | Fare: not using standard trampoline b/c the thing that bounces on the trampolines contain a reified continuation |
| 18:24 | Fare | reified continuation as opposed to what? |
| 18:24 | Fare | oh, you mean a frame datastructure? |
| 18:25 | bbloom_ | Fare: yeah, that's what i mean |
| 18:25 | Fare | so you can implement, e.g. dynamic variables correctly |
| 18:25 | bbloom_ | well, sorta |
| 18:25 | Fare | don't you then get shift / reset for free? |
| 18:25 | Fare | (*marginally* free) |
| 18:26 | bbloom_ | let me clarify: clojure.core/trampoline detects fn? vs answer. and i detect fn?, answer, or "effect", which will talk to the outside world and then resume (0 or more times) |
| 18:26 | bbloom_ | Fare: yeah, the plan for eclj is to replace try/catch/etc with handle/raise for multi-prompt delimited continuations w/ effect handling |
| 18:27 | Fare | e means extended? |
| 18:27 | bbloom_ | extensible, as in extensible interpreters & extensible effects |
| 18:27 | Fare | or is that meant to become clojure 2.0 ? |
| 18:27 | bbloom_ | nah, it was meant for me to screw around |
| 18:29 | bbloom_ | just needed something beefier than a toy lambda calculus to explore novel implementation techniques |
| 18:29 | amalloy | if bbloom_ had the power to influence clojure 2.0 he'd be doing things less drastic than eclj |
| 18:30 | bbloom_ | amalloy: absolutely |
| 18:32 | bbloom_ | i'm not working on it as much b/c i had to resist the urge to make fundamental breaking design changes to clojure, so it stopped being fun |
| 18:32 | bbloom_ | may go back to it at some point |
| 18:32 | bbloom_ | or may just take the ideas and do a new lang all together :-P |
| 18:32 | bbloom_ | Fare: i'm curious to see how your python thing turns out tho |
| 18:33 | eric_normand | anyone know of a good resource for learning how to use the Google Closure library? |
| 18:33 | eric_normand | I specifically mean the class-oriented stuff |
| 18:33 | eric_normand | UI elements and so on |
| 18:34 | bbloom_ | eric_normand: https://developers.google.com/closure/compiler/docs/js-for-compiler is the best i know of for the "type system" |
| 18:35 | eric_normand | bbloom_: thanks |
| 18:36 | eric_normand | is Closure, the Definitive Guide any good? |
| 18:36 | bbloom_ | eric_normand: no idea |
| 18:36 | bbloom_ | there's also the old wiki: https://code.google.com/p/closure-library/w/list |
| 18:36 | bbloom_ | see "IntroToComponents" etc |
| 18:36 | eric_normand | I've heard good things but the book is from 2010 |
| 18:36 | eric_normand | and I don't want to plunk down the cash |
| 18:37 | bbloom_ | but honestly, the closure UI libs are baroque as hell |
| 18:38 | eric_normand | yeah |
| 18:39 | eric_normand | but the rich text editor works pretty well |
| 18:39 | eric_normand | maybe that's the deeper question |
| 18:39 | eric_normand | what's the best rich text editor in js? |
| 18:52 | danielszmulewicz | Hmm... I'm new to macros. In a macro body, can I replace `(defn ~fname ~args ~@body) with `(defn ~fname [] ~@body) if I know there won't be any args? |
| 18:54 | justin_smith | danielszmulewicz: absolutely - a macro just needs to return the form that eventually runs, so a literal [] works fine if that's always the result wanted |
| 18:54 | danielszmulewicz | justin_smith: Great. thanks! |
| 18:54 | danielszmulewicz | (inc justin_smith) |
| 18:54 | lazybot | ⇒ 69 |
| 18:54 | justin_smith | Duuude |
| 18:54 | justin_smith | (sorry) |
| 18:55 | danielszmulewicz | (inc justin_smith) |
| 18:55 | lazybot | ⇒ 70 |
| 18:55 | danielszmulewicz | So much fun... |
| 18:55 | justin_smith | now I can put that joke away, to be resurrected later when I get 350 more karma |
| 19:02 | teslanick | (dotimes 350 (inc ...)) ;; evil |
| 19:04 | gfredericks | ,(let [i 0] (dotimes [_ 350] (inc i))) |
| 19:04 | clojurebot | nil |
| 19:04 | PigDude | is there ever an excuse for calling a function in project.clj, like a large string? |
| 19:04 | gfredericks | "calling a function like a large string"? |
| 19:05 | PigDude | i don't see much harm of using `str' in project.clj |
| 19:05 | gfredericks | oh like to split a string across lines |
| 19:05 | PigDude | gfredericks: excuse = "a large string" |
| 19:05 | PigDude | yea |
| 19:05 | gfredericks | I don't think anything bad will happen |
| 19:05 | gfredericks | and project.clj is not exactly a giant technical-debt-concern |
| 19:05 | amalloy | yeah, seems fine to me, although like...you know you can just put a newline mid-string? |
| 19:06 | PigDude | amalloy: can't have the extra whitespace, not a big fan of the dedent |
| 19:06 | PigDude | amalloy: OSGi manifest crap |
| 19:06 | gfredericks | PigDude: could put it in a file? |
| 19:06 | amalloy | PigDude: what's that doing in your project.clj? |
| 19:06 | TEttinger | yeah, I'm wondering too |
| 19:07 | PigDude | amalloy: hehe a good question. actually it looks like i can have newlines in the setting in question, so no need for (str) actually |
| 19:07 | PigDude | amalloy: clojure project integrating w/ big java service |
| 19:07 | hiredman | way not have it in a file and have lein include that file in the jar? |
| 19:07 | PigDude | amalloy: builds OSGi module JAR |
| 19:07 | PigDude | hiredman: that sounds like a great idea, how do i do that? |
| 19:08 | hiredman | start here https://github.com/technomancy/leiningen/blob/master/sample.project.clj |
| 19:08 | amalloy | here is an interesting fact: (def x "y" z) succeeds; (def x y "z") of course fails, but the error message you get is "too many arguments to def" |
| 19:08 | PigDude | hiredman: i knew it :) |
| 19:08 | gfredericks | lol; hiredman is the master of "read this long thing first" |
| 19:08 | PigDude | gfredericks: ah i meant more like, half of leindocs are in that file :) |
| 19:09 | hiredman | I mean, I know it is possible, but it isn't like I keep a catalog of all possible lein options in my head |
| 19:09 | hiredman | so it is in there somewhere |
| 19:09 | hiredman | if worst comes to worst just stick it in resources/ |
| 19:09 | hiredman | in fact, why not do that? |
| 19:09 | PigDude | yea right now i'm using :manifest which seemed good but maybe i'll just break that out of the file |
| 19:10 | PigDude | hiredman: i thought the manifest is top-level, not in resources? |
| 19:10 | PigDude | hiredman: or i probably have no idea what i'm talking about, i'm not much of a 'java guy' yet |
| 19:11 | hiredman | oh, it has to go in the jar manifest? |
| 19:11 | PigDude | yea |
| 19:11 | PigDude | really long config option |
| 19:11 | hiredman | https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L415 |
| 19:11 | PigDude | i was getting ahead of myself because it actully can have newlines and whitespace |
| 19:11 | PigDude | well there it is from the horse's mouth |
| 19:11 | PigDude | :) |
| 19:12 | PigDude | specifically i wanted to join on commas and didn't want to require but of course i can use absolute reference |
| 19:12 | hiredman | you can call slurp or whatever there, even do templating |
| 19:12 | PigDude | thanks hiredman ! |
| 19:12 | PigDude | hehe `"Grunge-level" my.plugin/calculate-grunginess' |
| 19:12 | PigDude | => "Soundgarden" |
| 19:13 | hiredman | clojurebot: leiningen is a product of a grungy little burb just north of seattle |
| 19:13 | clojurebot | Roger. |
| 19:17 | hyPiRion | leiningen? |
| 19:17 | clojurebot | leiningen is behind your back in a good way |
| 19:20 | justin_smith | ~leiningen |
| 19:20 | clojurebot | leiningen is a product of a grungy little burb just north of seattle |
| 19:25 | numberten | is there a way to :keys destructure a map, and have it return an exception if a key is missing? |
| 19:26 | numberten | right now i'm using :pre to check to see if the keys exist, but I was wondering if something that does that already exists and I just haven't heard of it |
| 19:26 | aperiodic | numberten: you may be interested in schema. https://github.com/Prismatic/schema |
| 20:01 | casperc | (with-redefs [inc (constantly 1) |
| 20:01 | casperc | class (constantly 10)] |
| 20:01 | casperc | [(inc 1) |
| 20:01 | casperc | (class [])]) |
| 20:02 | casperc | ,(with-redefs [inc (constantly 1) |
| 20:02 | casperc | class (constantly 10)] |
| 20:02 | casperc | [(inc 1) |
| 20:02 | casperc | (class [])]) |
| 20:02 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 20:02 | justin_smith | casperc: the bots only do one liners |
| 20:02 | casperc | ,(with-redefs [inc (constantly 1) |
| 20:02 | casperc | class (constantly 10)] |
| 20:02 | casperc | [(inc 1) |
| 20:02 | casperc | (class [])]) |
| 20:02 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 20:02 | casperc | ah |
| 20:03 | casperc | (with-redefs [inc (constantly 1) class (constantly 10)] [(inc 1) (class [])]) |
| 20:03 | casperc | ,(with-redefs [inc (constantly 1) class (constantly 10)] [(inc 1) (class [])]) |
| 20:03 | clojurebot | [2 10] |
| 20:04 | casperc | hmm, the that redef clearly doesn't work :) |
| 20:06 | hyPiRion | inc is inlined, which is why it doesn't work |
| 20:10 | BAMbanda | What do you guys suggest as the idiomadic way to consume restful services with clojure |
| 20:11 | justin_smith | BAMbanda: for GET, slurp will often suffice. Use cheshire to decode json. For POST etc. clj-http.client is good |
| 20:11 | justin_smith | https://github.com/dakrone/clj-http |
| 20:13 | BAMbanda | justin_smith, thanks bud |
| 21:07 | clojer | Why does this work: (map-indexed (fn [x y] [x y]) [:a :b :c]) |
| 21:07 | amalloy | why wouldn't it work, clojer? |
| 21:07 | clojer | ... but this doesn't: (map-indexed #([%1 %2]) [:a :b :c]) |
| 21:08 | clojer | amalloy: See follow-up |
| 21:08 | amalloy | because #(x) is (fn [] (x)), not (fn [] x) |
| 21:10 | clojer | amalloy: Don't see the connection with your #(x) example |
| 21:10 | dbasch | clojer: because you’re calling a vector as a function |
| 21:10 | dbasch | you want #(do [%1 %2]) |
| 21:10 | amalloy | #([%1 %2]) is (fn [x y] ([x y])) |
| 21:10 | amalloy | dbasch: no, he wants vector |
| 21:11 | dbasch | ,(map-indexed vector [:a :b :c]) |
| 21:11 | clojurebot | ([0 :a] [1 :b] [2 :c]) |
| 21:11 | dbasch | &(map-indexed vector [:a :b :c]) |
| 21:11 | lazybot | ⇒ ([0 :a] [1 :b] [2 :c]) |
| 21:12 | clojer | dbasch: Tried that but confused with vec instead of vector thinking they were the same :( |
| 21:13 | dbasch | is the network lagging? |
| 21:14 | dbasch | amalloy: I sent dbasch: ,(map-indexed vector [:a :b :c]) about 30’ before your comment :) |
| 21:14 | amalloy | dbasch: you must have a really terrible internet connection |
| 21:15 | amalloy | or connection to freenode, anyway |
| 21:15 | dbasch | amalloy: I’m using astound, which is astoundingly bad |
| 22:37 | jkj | strange... lein uberjar does aot compiling alright |
| 22:37 | jkj | ...or lein with-profile uberjar compile |
| 22:38 | jkj | but lein compile does not aot compile the class, and import will fail |
| 22:38 | jkj | cannot figure out what causes this... the class is in project.clj in :aot vector |
| 22:57 | hiredman | jkj: you need to put (:gen-class) is the ns form of the class you want compiled |
| 22:58 | jkj | hiredman: it has.. and it does compile fine if i just lein uberjar first |
| 22:58 | jkj | if i lein something else first, then kabom |