2013-06-16
| 00:01 | ambrosebs | Is it possible to nest prefix lists in a require? |
| 00:01 | tomjack | nope |
| 00:01 | ambrosebs | thanks |
| 00:15 | wei_ | How do I get the string name of a function (not symbol)? this doesn't work (let [f filter] (name f)) |
| 00:17 | tomjack | you should probably consider that impossible |
| 00:18 | tomjack | the var has a .sym but that's not really public ##(.sym #'filter) |
| 00:18 | lazybot | java.lang.SecurityException: You tripped the alarm! class clojure.lang.Var is bad! |
| 00:20 | wei_ | ok, thanks. just wanted a way to turn a list of functions into strings. i guess i can go the other way then, using resolve |
| 00:22 | tomjack | you can ##(.getName (class filter)) but.. |
| 00:22 | lazybot | ⇒ "clojure.core$filter" |
| 00:25 | dobry-den1 | off the top of the head any elegant way to merge vectors: [1 2 3] into [0 0 0 0 0] => [1 2 3 0 0] |
| 00:28 | akhudek | ##(let [a [1 2 3] b [0 0 0 0 0]] (into a (subvec b (count a)))) |
| 00:28 | lazybot | ⇒ [1 2 3 0 0] |
| 00:28 | akhudek | assuming a is always smaller than b, and you want to overwrite b |
| 00:32 | dobry-den1 | akhudek: nice, thanks. |
| 00:41 | amalloy | tomjack: .sym on vars is silly: if you actually have a var, rather than a function, you can use the :name in its meta |
| 00:42 | tomjack | nice, and then you can get the ns via ns-name |
| 00:42 | tomjack | thanks |
| 00:42 | tomjack | I thought there was no public way |
| 01:25 | samrat | how do I get cond to print something then recursively call a function: https://www.refheap.com/15823 |
| 01:30 | tomjack | ~helpme |
| 01:30 | clojurebot | A bug report (or other request for help) has three parts: What you did; what you expected to happen; what happened instead. If any of those three are missing, it's awfully hard to help you. |
| 01:33 | samrat | tomjack: if that was for me, I'm doing (do (println something) (monte-carlo ...)) and I get the printed text only when I interrupt the execution |
| 01:37 | tomjack | hmm |
| 01:38 | samrat | tomjack: oh, wait. looks like it is working. I was just being impatient. Sorry |
| 01:39 | tomjack | the timeout bit doesn't make sense to me |
| 01:41 | tomjack | it's supposed to test whether calculating the new score during a single step takes longer than the timeout? |
| 01:42 | tomjack | I guess what seems strange is that it's not really a 'timeout' - if it took 30s and the timeout was 1s, you'll find out that it 'timed out' after 30s |
| 01:43 | samrat | tomjack: the function is supposed to dedicate only some limited time for a cipher |
| 01:43 | samrat | after that, if its not performing well, then stop it and try "improving" upon a new cipher instead. |
| 01:44 | noonian | http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#currentTimeMillis() |
| 01:44 | samrat | tomjack: I'm translating this from racket: http://blog.jverkamp.com/2013/01/25/an-optimal-alphabetizing-cipher/ |
| 01:45 | tomjack | in that case, shouldn't the 'timer' val get passed down, rather than being recomputed every step? |
| 01:45 | noonian | it doesn't guaruntee to return ms, which could explain it taking longer |
| 01:46 | tomjack | the racket example seems to pass timer down |
| 01:47 | noonian | ah, that makes sense, (> (- (System/currentTimeMillis) timer) (* timeout 1000)) is not likely to be true because timer is the previous call to currentTimeMillis and the code will execute faster than your timeout |
| 01:48 | noonian | you could use a loop/recur form here and have timer be a passed in |
| 01:49 | noonian | you want timer to only be called once at the beginning since that is how you are calculating elapsed time |
| 01:50 | tomjack | well, you want what's there in every case except the :else branch of the cond |
| 01:50 | tomjack | when the timer should be preserved |
| 01:51 | samrat | tomjack: ah, thanks. It is working faster now. |
| 01:51 | noonian | the recursive call is the problem, (let [timer (System/currentTimeMilis) ...) is called in every recursive step, so you are calculating elapsed time since the last recursion instead of when you called the function in your code |
| 01:53 | noonian | actually, each step is the time between the let and the cond case and not relating to the previous step |
| 01:54 | samrat | noonian: I'm passing the timer in the :else clause now. |
| 01:56 | samrat | for the other cases, I do want to reset the timer. |
| 01:58 | noonian | you can just create a new timer and pass that in instead of the old one when you call monte-carlo in those cases |
| 01:59 | noonian | just pass in the result of a new call to currentTimeMillis |
| 02:03 | samrat | noonian: hmm, would that be more "correct" than calling currentTimeMillis from the let block? |
| 02:03 | samrat | noonian: that is what the racket code does too, but I'd assumed it was the same thing |
| 02:05 | tomjack | you added a timer arg to the fn but still have a let for timer? |
| 02:05 | noonian | I dont understand this syntax, do you call their version with any arguments? |
| 02:05 | noonian | (define (solve/monte-carlo [guess (random-key)] |
| 02:05 | noonian | |
| 02:06 | samrat | tomjack: now I don't |
| 02:07 | samrat | noonian: yes. you can see it called there: (solve/monte-carlo (random-key) -inf.0 timeout (current-seconds)) |
| 02:08 | samrat | noonian: those are the default values. |
| 02:08 | samrat | in the (define ...), I mean |
| 02:09 | noonian | samrat: I see, in the other version it isn't using a let, they are just the default values |
| 02:12 | noonian | basically, you wan't the current ms in the first 2 cases, and you want the snapshot of the ms when the function was first called in the else case |
| 02:13 | noonian | by binding timer in the let it gets bound to the new ms every recursive call and the else case always has the most recent time |
| 02:14 | noonian | notice that he calls (solve/monte-carlo) from the repl to test the output |
| 02:14 | noonian | with no args |
| 02:16 | tomjack | that's kinda neat |
| 02:17 | tomjack | guess I could make a macro for default args |
| 02:18 | murtaza52 | how do I write this java code in clojure - > FileSystems.getDefault().getPath("logs", "access.log"); |
| 02:20 | tomjack | (.getPath (FileSystem/getDefault) "logs" (into-array String ["access.log"])) |
| 02:22 | tomjack | variadic java methods are just syntax sugar for passing an array |
| 02:22 | tomjack | syntax sugar we don't have in clojure.. |
| 02:26 | noonian | samrat: in r5rs scheme, I would use a named let to achieve what hes doing, in clojure that is similiar to a loop/recur form. Basically you bind your default values in the loop form and change your calls to monte-carlo to calling recur |
| 02:29 | samrat | noonian: I'm going to try that. I got a StackOverflow after running the current version for a while. |
| 02:30 | noonian | yeah, racket guarantees to optimize tail calls, whereas clojure will not so you have to use loop/recur or higher order functions |
| 02:33 | zRecursive | loop/recur ensures "tail recursive" ? |
| 02:37 | noonian | zRecursive: yep |
| 02:38 | zRecursive | not direct though |
| 02:39 | zRecursive | maybe it is due to JVM |
| 02:39 | noonian | I expect clojure will get automatic tail call optimization whenever java gets gets it, >= 1.8 probably |
| 02:40 | zRecursive | if so, that will be great |
| 03:04 | tomjack | ,((promise) 42) |
| 03:04 | clojurebot | #<core$promise$reify__6310@1211162: 42> |
| 03:04 | tomjack | ,(def x ((promise) 42)) |
| 03:04 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 03:04 | callen | tomjack: surely you knew the def wasn't going to work? |
| 03:04 | tomjack | I thought clojurebot was wide open |
| 03:05 | tomjack | result is java.lang.AbstractMethodError in clojure.lang.Compiler$InvokeExpr.eval |
| 03:05 | tomjack | because promises don't implement applyTo |
| 03:06 | SNBarnett | Hi, why does (= java.lang.String (class "a")) return true but (case (class "a") java.lang.String true nil) return nil? |
| 03:08 | amalloy | tomjack: promises aren't "publicly" IFn anyway, so...? |
| 03:09 | tomjack | oh, I didn't know the IFn part was supposed to be hidden. but my point was really more: warning, this is what can happen when you don't implement applyTo |
| 03:09 | tomjack | &(case 'java.lang.String java.lang.String true) |
| 03:09 | lazybot | ⇒ true |
| 03:20 | SNBarnett | tomjack: cheers, any idea why the other form doesn't work? |
| 03:21 | tomjack | because the String class is not the symbol 'java.lang.String |
| 03:21 | tomjack | you can't match a class with case |
| 03:23 | SNBarnett | tomjack: ah ok, thanks. |
| 03:23 | noonian | ,(if java.lang.String true false) |
| 03:23 | clojurebot | true |
| 03:24 | tomjack | "All manner of constant expressions are acceptable in case, including numbers, strings, symbols, keywords, and (Clojure) composites thereof." |
| 03:24 | noonian | you're using case like a cond |
| 03:26 | noonian | ,(case java.lang.String java.lang.String true "something" "a string" "default") |
| 03:26 | clojurebot | "default" |
| 03:26 | noonian | hmm |
| 03:26 | tomjack | interesting https://www.refheap.com/f1c14b6df75de1e49da485e92 |
| 03:27 | SNBarnett | noonian: was trying to follow this example http://pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure |
| 03:28 | noonian | SNBarnett: yeah, I was wrong |
| 03:28 | noonian | ,(case (class "a") java.lang.String true false) |
| 03:28 | clojurebot | false |
| 03:30 | tomjack | that's just wrong |
| 03:30 | tomjack | ambrosebs must not have tested it? :) |
| 03:30 | hiredman | java.lang.String is read is a symbol and eval'ed as a class |
| 03:30 | hiredman | ,(case 'java.lang.String java.lang.String true false) |
| 03:30 | clojurebot | true |
| 03:30 | hiredman | case treats each possiblity has a constant (no eval) |
| 03:32 | amalloy | tomjack: using #class to sneak eval into case will probably break if you AOT |
| 03:32 | noonian | yeah, case's doc states that test-constants must be compile time literals |
| 03:33 | noonian | and it looks like user written classes aren't compile time constants |
| 03:38 | tomjack | amalloy: doesn't look like it |
| 03:39 | tomjack | well, at least, https://www.refheap.com/5bdb722fbaa0fa22dbfa970f9 seems to work |
| 03:41 | amalloy | tomjack: well, if you delete the .clj file and just run from the .class, i think it fails because the code generated by case assumes hashcodes are consistent |
| 03:43 | tomjack | I ran with java -jar on an uberjar |
| 03:43 | tomjack | but I think I see how it's evil |
| 03:45 | hiredman | the java.lang.String class always seems to have the same hashcode (must be a class loading order thing) but, for example, clojure.lang.RT doesn't |
| 03:45 | tomjack | ah, interesting |
| 03:45 | hiredman | across jvm runs it has different hashcodes |
| 03:46 | tomjack | hmm, I'm always getting 1268575826 |
| 03:46 | amalloy | hiredman: lazybot and clojurebot return different hash codes for String right now |
| 03:46 | hiredman | here String is always 1051225362 |
| 03:46 | tomjack | here String is 1145768891.. |
| 03:46 | hiredman | amalloy: yeah, I bet it is a lod order thing, so different jvm versions might be different |
| 03:46 | tomjack | so yeah, really evil :) |
| 03:46 | hiredman | load |
| 03:48 | hiredman | so for a given jvm the hashcode is always the same because the initialization of the jvm happens in a deterministic way, and the string String class is always loaded at the same time, but across jvm versions class deps change ect, so the initialization order may change |
| 03:48 | tomjack | &(.hashCode (java.net.URI. "/")) |
| 03:48 | lazybot | ⇒ 47 |
| 03:49 | tomjack | &(.hashCode #inst "2012") |
| 03:49 | lazybot | ⇒ -1768894156 |
| 03:49 | tomjack | cool |
| 03:51 | tomjack | &(.hashCode (java.util.UUID/fromString "b3da40ec-cbe2-4637-a0fa-de66b1293896")) |
| 03:51 | lazybot | ⇒ 1777066027 |
| 03:55 | SNBarnett | So the best way to get around this is to just use cond? |
| 03:57 | tomjack | is it bad to close over an access to an :unsynchronized-mutable? |
| 03:58 | tomjack | I guess at best I'll get the old value |
| 03:59 | tomjack | yep |
| 04:05 | amalloy | SNBarnett: or one of the many features intended for use in class-based polymorphism |
| 04:06 | amalloy | interfaces, protocols, multimethods... |
| 04:09 | SNBarnett | amalloy: thanks for the suggestions |
| 04:52 | john2x | i'm having a hard time understanding loop and recur.. so recur's arguments need to match let's bindings? |
| 04:53 | john2x | *loop's bindings |
| 04:58 | noonian | yes, you can think of loops bindings as default values |
| 05:00 | noonian | er, initial values |
| 05:05 | noonian | you can use recur without loop to that will call the actual function |
| 05:10 | noonian | john2x: these are at least conceptually the same, https://gist.github.com/lore17/7ea7af0218894405fab2 |
| 05:20 | tomjack | if we require an implementation of equality for our values, maybe "you can put it in a map" is a good description |
| 05:20 | tomjack | the example makes the "in practice, they're not values" for fns make sense to me |
| 05:51 | mindbender1 | Is it possible to tell cljsc where to look for macros, say via options? |
| 05:56 | tomjack | mindbender1: I have this hack for that https://www.refheap.com/6540b2904cb1b419c22dcda05 |
| 06:19 | mindbender1 | tomjack: I saw your hack. Good. But I was looking for a way to do it while in the repl. Say tell it to look here for macros. Because I'm passing in a bunch of files which it is compiling correctly but halts because the path where cljs-macros is located is not on classpath(deliberately for partability reasons). So I want it to look 'here'(a specific path) for the macros. |
| 06:20 | tomjack | dunno what you're talking about, I thought cljsc was a shell script |
| 06:21 | mindbender1 | *portability |
| 06:22 | mindbender1 | I was referring to cljs.compiler |
| 06:27 | berdario | Hi, about the error I stumbled upon yesterday |
| 06:27 | berdario | I just wrote a message to the clojurescript mailing list |
| 06:28 | berdario | I reproduced it with my clone of the clojurescript repo, and with the repl sample |
| 06:28 | berdario | https://github.com/clojure/clojurescript/tree/master/samples/repl |
| 06:28 | berdario | the message hasn't been approved yet |
| 06:29 | berdario | but if there's anyone who has experience with cljs, that can help me understand what is going wrong, I'd appreciate |
| 06:33 | tomjack | mindbender1: ah.. macros are just require'd with require iirc, so no |
| 06:45 | greywolve | is there any way to restart the reload the brepl namespaces without having to completely restart the repl everytime you make code changes? |
| 06:46 | Eucoo | hi |
| 06:46 | mindbender1 | greywolve: (require *ns* :reload) |
| 06:47 | berdario | mindbender1: are you using clojurescript with a repl in the browser? |
| 06:47 | Eucoo | how do you guys manage long let bindings declaration? is it some kind of bad pattern? |
| 06:47 | greywolve | thanks ill try that ;p |
| 06:47 | mindbender1 | berdario: yep |
| 06:48 | berdario | mindbender1: do you know of any common roadblocks? I spent hours trying to get it running, but nothing works |
| 06:48 | berdario | the only instance in which I got the repl working, is with the lein-cljsbuild advanced sample... but that needs a ring server |
| 06:48 | greywolve | berdario |
| 06:48 | greywolve | whats the problem? |
| 06:49 | mindbender1 | I don't like and I don't use lein-cljsbuild workflow |
| 06:49 | greywolve | the brepl is pretty simple to setup |
| 06:49 | berdario | the repl doesn't get connected |
| 06:49 | berdario | it just stays there... after I opened the page with the code for the connection |
| 06:49 | greywolve | https://github.com/magomimmo/modern-cljs |
| 06:49 | berdario | I try some simple forms... like (+ 1 1) but the repl is completely unresponsive |
| 06:49 | greywolve | try following those tutorials |
| 06:50 | mindbender1 | berdario: you have to refresh the page |
| 06:50 | greywolve | hmm did you add the cljs code to connect to the brepl? |
| 06:50 | mindbender1 | so that it hooks into the hung repl |
| 06:50 | greywolve | mindbender1: whats your cljs workflow? i'm still trying to find a good one |
| 06:50 | berdario | mindbender1: I tried to refresh a dozen times |
| 06:50 | berdario | greywolve: that seems to require ring |
| 06:51 | greywolve | no it doesn't |
| 06:51 | greywolve | you can use any web server |
| 06:51 | berdario | oh, good |
| 06:51 | mindbender1 | cljs1 or more recently pedestal |
| 06:51 | greywolve | but ring is convenient if you are also building a server side api for your app |
| 06:52 | greywolve | i want to try out pedastal |
| 06:52 | greywolve | mindbender1: do you use the brepl at all? |
| 06:53 | greywolve | berdario you can quickly test using python SimpleHTTPServer aswell |
| 06:53 | berdario | yes, I usually use python3's http.server |
| 06:53 | berdario | btw, I just noticed right now that I have a server somewhere stuck on port 8000 |
| 06:54 | mindbender1 | greywolve: more specifically I try to work with cemerick.piggieback |
| 06:54 | berdario | I thought I killed all of the server I opened previously... and I have no other shell open |
| 06:54 | greywolve | make sure your cljs code that connects to the repl, and the brepl server are the same port ;p |
| 06:54 | greywolve | that could be the prob then |
| 06:54 | mindbender1 | it provide a repl-env that plays nicely with nrepl |
| 06:54 | greywolve | mindbender1: i'm using that atm, but :cljs/quit doesn't work for me lol |
| 06:55 | mindbender1 | for :cljs/quit to work you have to be able to have evaluated an expression |
| 06:56 | mindbender1 | if you're were using nrepl.el with emacs then you could send an interupt to the process |
| 06:57 | mindbender1 | I'm not familiar with sending an interrupt outside emacs nrepl |
| 06:57 | berdario | greywolve: I always used port 9000, that shouldn't be it... I'm compiling the cljs now btw |
| 06:59 | mindbender1 | In most cases you just have to keep pushing and tweaking to really be familiar with things |
| 06:59 | greywolve | mindbender1: ah ok, but you can just reload the namespaces and that works for you? |
| 06:59 | berdario | greywolve: the modern-cljs tutorial doesn't work |
| 06:59 | berdario | same problem as before |
| 07:00 | greywolve | weird! im doing it right now and its working fine ;p |
| 07:00 | mindbender1 | In brepl, you use load-file or load-namespace |
| 07:01 | berdario | it's really frustrating... I hoped to use cljs instead of resorting to the same old javascript |
| 07:01 | berdario | but I can't see a way forward, if even the tutorials aren't working |
| 07:01 | greywolve | so if i have a namespace like mod.login in a file login.cljs, and i make changes to it, can i just go (load-namespace 'mod.login) without having to restart the brepl? |
| 07:01 | mindbender1 | yes |
| 07:01 | greywolve | berdario: what os are you on? |
| 07:02 | greywolve | nice... i wish these things were better documented ;p |
| 07:02 | berdario | ubuntu 13.04 |
| 07:02 | finishingmove | I've got this using Compojure: (def app (handler/site app-routes)) . How would I add (handler/api api-routes) to that? |
| 07:02 | mindbender1 | load-namespace is documented somewhere |
| 07:02 | greywolve | berdario: push your code to git a repo and ill try it on my side |
| 07:02 | finishingmove | do i need to do a (def api ...) ? |
| 07:03 | greywolve | yeah "somewhere" |
| 07:03 | greywolve | lol |
| 07:03 | berdario | greywolve: I'm just using a clone of modern-cljs I just got... no changes whatsoever |
| 07:03 | greywolve | oh dear |
| 07:03 | greywolve | then it should definitely work |
| 07:03 | mindbender1 | https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure |
| 07:03 | greywolve | thanks |
| 07:03 | greywolve | ;) |
| 07:04 | greywolve | does (js/alert "hello") also hang? |
| 07:04 | berdario | greywolve: yes |
| 07:05 | mindbender1 | https://github.com/clojure/clojurescript/wiki/The-REPL-and-Evaluation-Environments |
| 07:05 | greywolve | also did you check the network tab in dev tools (in chrome at least) to see if its connecting to the brepl? |
| 07:05 | berdario | greywolve: uhm, I'm not using brepl, I'm just using the cljsbuild repl |
| 07:06 | greywolve | oh |
| 07:06 | greywolve | then thats even stranger, that should be a snap to setup ;p |
| 07:07 | berdario | greywolve: there're 2 requests |
| 07:07 | berdario | one gets back a 200 |
| 07:07 | berdario | the other is pending |
| 07:07 | berdario | the pending one, gets back 13 byte |
| 07:07 | berdario | bytes |
| 07:07 | berdario | gosh, now it works |
| 07:08 | greywolve | lol nice |
| 07:11 | berdario | greywolve: well, thank you... I tried just now in my project, and I've been able to get it working there |
| 07:12 | greywolve | berdario: i didn't do much to help ;p haha glad its working though |
| 07:12 | berdario | I really have no clue what could've been going wrong... I literally tried dozen times with all kind of samples... at the beginning I wasn't using a server to serve the html |
| 07:13 | berdario | so surely that could've been the problem at first... but with the latest attempts, I used it, and so there was something else amiss |
| 07:13 | finishingmove | I want to be able to send / receive JSON with Compojure. Do I need some external libraries? And what would you recommend |
| 07:14 | berdario | greywolve: btw, I fear that this might not be enough for me... what I was trying to do was a clojurescript local application with node-webkit (the same technology used by lighttable) |
| 07:14 | berdario | there's a node-webkit-cljs project... but to debug the functions made available by node-webkit, I'd need to run it through it |
| 07:15 | berdario | and obviously, if I run the repl through node.js, there's no way I can see to access the dom |
| 07:16 | berdario | so, I'd need to run the repl without having a separate server, other than the cljsbuild repl listener |
| 07:16 | berdario | do you know of any way to get what I want? |
| 07:16 | greywolve | whats your overall goal ? |
| 07:16 | greywolve | i mean just in terms of what you are trying to build |
| 07:18 | berdario | some simple application to load html/css, ideally at the end it should be used for the layout of different kind of documents, not just web pages |
| 07:18 | berdario | I thought that using node-webkit was the easiest way to go, since this way I could directly have the content rendere in the page (maybe as an iframe?) |
| 07:19 | berdario | and yet, I could access the disk, save data locally and, etc.etc. |
| 07:19 | berdario | right now I'm just experimenting around... nothing serious... it's sunday after all :) |
| 07:20 | berdario | (obviously, I can access the disk from a plain web page application, localstorage, indexeddb and such... but I was thinking of doing that latter) |
| 07:21 | greywolve | wow this the first time ive seen node-webkit, looks awesome, but yeah using it from clojurescript i have no idea, its already hard enough just using clojurescript normally (for me anyway cause i'm new to it ) ;p |
| 07:21 | berdario | yeah, the same... :) |
| 07:22 | berdario | btw, it's kinda hard to use node-webkit with plain javascript imho |
| 07:22 | berdario | for example, I started to work with some samples, and apparently the behavior of node-webkit when parsing the package.json changed |
| 07:22 | greywolve | https://github.com/Flamefork/node-webkit-cljs looks like your best bet like you said, maybe you can help add some of the other missing api pieces |
| 07:22 | greywolve | plain js is always hard i guess haha ;p |
| 07:23 | berdario | moreover, you can't use nodejs's require freely... since many libraries try to access the document and window object upon startup.... but when inside nodejs's require, those aren't available... |
| 07:24 | berdario | so if I'd have used plain javascript, I'd have to hardcode the path to the js libraries in the html (like I've seen done in the various example)... something I looked to avoid by using clojurescript :D |
| 07:24 | berdario | greywolve: agreed, unfortunately, to contribute to that I'd need to understand clearly how to access the objects that node-webkit makes avaialble |
| 07:25 | greywolve | perhaps that would be good experience for you ;) |
| 07:25 | berdario | (aside from compiling some simple cljs files, this is the first time for me that I used clojurescript) so, I hoped to get a repl working working inside that |
| 07:26 | berdario | I wonder if flamefork avoided the repl, and just kept compiling/running to try to see if it works |
| 07:26 | greywolve | is lighttable being developed in plain js or clojurescript? |
| 07:26 | berdario | greywolve: clojurescript |
| 07:26 | berdario | unfortunately, it isn't open source (not yet at least) afaik |
| 07:26 | greywolve | maybe ask chris what he thinks then ;p |
| 07:27 | greywolve | yeah the repl really speeds things up, compiling everytime is quite slow |
| 07:28 | berdario | greywolve: on top of that, you have to package the things inside a .zip to run them in node-webkit |
| 07:28 | greywolve | geez |
| 07:28 | berdario | I was planning to add that command to the repl-launch command as soon as I'd got it working |
| 07:28 | greywolve | i like a very rapid feedback cycle |
| 07:38 | murtaza52 | tomjack: how do I write this one - java.nio.file.Paths.get("myPath", "subPathA", "subPathB"); - in clojure |
| 07:38 | murtaza52 | (.get java.nio.file.Paths "myPath" "subPathA" "subPathB") - this didnt work |
| 07:44 | berdario | murtaza52: this works, but is ugly as hell |
| 07:44 | berdario | (java.nio.file.Paths/get "myPath" (into-array java.lang.String '("subPathA" "subPathB"))) |
| 07:44 | berdario | you have to use /get, because it's a static method |
| 07:45 | berdario | the into-array, is because the rest of the arguments is a vararg |
| 07:45 | pisketti | berdario: Do you explicitly have to use array when the java method takes varargs? |
| 07:46 | berdario | pisketti: it's the first time I stumbled upon a vararg :) I don't know if there's a cleaner way |
| 07:46 | berdario | maybe there's a macro somewhere for it... but at the end, under the hood I think there's no way around using an array |
| 07:46 | murtaza52 | berdario: why leave the first arg out, and only apply into-array to the other two args |
| 07:46 | pisketti | How about just calling them as varargs like you would in Java or in clojure ( & xs) |
| 07:47 | pisketti | It doesn't work out of the box like that? |
| 07:47 | berdario | murtaza52: this is the java signature: get(String first, String... more) |
| 07:47 | berdario | the first argument is required |
| 07:48 | berdario | this is relevant... but I haven't finished to read it yet https://groups.google.com/forum/?fromgroups#!topic/clojure/ZLIKz3bitoc |
| 07:53 | murtaza52 | FileSystems.getDefault().getPath("logs", "access.log"); - how do I translate this to clojure ? |
| 08:11 | pisketti | murtaza52: without testing it, I'd say (.getPath (FileSystems/getDefault) "logs" "accessLog") |
| 08:14 | murtaza52 | that works thanks |
| 08:16 | pisketti | np |
| 08:28 | Okasu | ,'#=(apply * '#=(range 2 10)) |
| 08:28 | clojurebot | #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.> |
| 08:28 | Okasu | Meh. |
| 08:28 | Okasu | &'#=(apply * '#=(range 2 10)) |
| 08:28 | lazybot | java.lang.IllegalStateException: clojure.lang.LispReader$ReaderException: EvalReader not allowed when *read-eval* is false. |
| 11:51 | uris77 | what is the right way to use apply with reverse? |
| 11:51 | piranha | cemerick: friend doesn't do any salting for passwords, right? Or bcrypt does that by itself? |
| 11:51 | uris77 | for example (apply reverse [5 4 3 2 1]) |
| 11:51 | cemerick | piranha: bcrypt salts automatically |
| 11:51 | uris77 | that doesn't work. Im a newbie :) |
| 11:51 | piranha | cemerick: ok, thanks |
| 11:52 | hyPiRion | uris77: It's just ##(reverse [5 4 3 2 1]) |
| 11:52 | lazybot | ⇒ (1 2 3 4 5) |
| 11:53 | hyPiRion | reverse takes a single sequence as input |
| 11:53 | kmicu | ## *clojure-version* |
| 11:53 | hyPiRion | &*clojure-version* ;-) |
| 11:53 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 11:53 | hyPiRion | ,*clojure-version* |
| 11:54 | clojurebot | {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"} |
| 11:54 | hyPiRion | oh, clojurebot is bleeding edge |
| 11:54 | kmicu | very bleeding |
| 11:54 | Mingqi | I'm trying to write a web application use clojure. anybody can suggest a configuration solution in clojure? |
| 11:55 | borkdude | Mingqi take a look at Luminus or Pedestal |
| 11:55 | hyPiRion | Mingqi: http://pedestal.io/ is a tool set/configuration for web apps |
| 11:56 | kmicu | If you are not familiar with clojure stack, pedestal is not a good choice IMHO |
| 11:56 | Mingqi | Michiel, thank you. I'm looking... |
| 11:57 | borkdude | Mingqi you looked up my first name? ;) |
| 11:57 | Mingqi | Yes, I got your full name |
| 11:58 | hyPiRion | Oh, you're working for NSA? |
| 11:58 | borkdude | haha |
| 11:59 | Mingqi | it's very simple. Just click your name and freenode will show your information: Michiel Borkent, London, UK ...etc |
| 11:59 | Mingqi | by the way, i'm using http://webchat.freenode.net/ |
| 11:59 | borkdude | I'm glad NSA thinks I'm in Londen |
| 11:59 | borkdude | London |
| 12:00 | hyPiRion | borkdude: aren't there any Dutch freenode servers? |
| 12:00 | hyPiRion | I vaguely recall you're from there |
| 12:00 | Mingqi | which client you are using on Mac, I download a colloquy but doesn't work |
| 12:01 | borkdude | hyPiRion I don't think so, but I actually don't care which server I'm using |
| 12:01 | borkdude | Mingqi Textual |
| 12:01 | pdk | iirc there's a mac port of irssi |
| 12:02 | borkdude | Mingqi if you build it yourself using Xcode it is free |
| 12:02 | pdk | i never got why xchat does that too |
| 12:02 | hyPiRion | fair enough. For some strange reason I thought latency would be critical for IRC just now. |
| 12:02 | pdk | they're like "pay for the official build but you can still compile the same thing for free!" |
| 12:03 | pdk | then everyone just turns around and uses 3rd party enhanced builds for free anyway |
| 12:04 | borkdude | Mingqi I used to use erc in emacs also |
| 12:05 | borkdude | one thing that annoys me about Textual: it autojoins channels I visited before, I wonder if I can turn that off |
| 12:05 | borkdude | I know how to turn off the autojoin, but it should not do it by default |
| 12:08 | Mingqi | oh, damn! Textual also doesn't work. I believe it's China government block freenode. |
| 12:10 | borkdude | Mingqi hmm. or you are behind some firewall that blocks the irc port? |
| 12:10 | borkdude | Mingqi if the china government would block freenode, then why don't they block webchat as well |
| 12:11 | Mingqi | Yes, It's a BIG firewall built by China government, we call it GFW, great fire wall. |
| 12:11 | borkdude | Mingqi funny |
| 12:12 | Mingqi | http://en.wikipedia.org/wiki/Great_Firewall_of_China |
| 12:16 | uris77 | i wanted to write a function that takes 2 functions and some args, and applies those 2 functions to the args. That is why I was asking about (apply reverse [5 4 3 2 1]) |
| 12:18 | borkdude | uris77 is the result of f1 an arg to f2, or do you want to apply f1 and f1 to the same args? |
| 12:19 | uris77 | f2 should be applied to the result of (f1 [args]) |
| 12:19 | uris77 | i thought i could just use apply with any function to do this, but hit a wall with functions like reverse and rest |
| 12:19 | borkdude | uris77 use comp |
| 12:20 | uris77 | oh, nice |
| 12:20 | uris77 | thanks alot |
| 12:20 | borkdude | uris77 or simply write (f2 (f1 [args])) |
| 12:27 | Mingqi | Hi Michiel, both of Luminus and Pedestal you suggest are web framework. but I need a library to resolve my configuration problem: support structure data, like list, dictionary, just like json, but I also want to difference configuration for dev and production environment |
| 12:28 | Mingqi | do you other suggestions for that? |
| 12:31 | clj_newb | Hi, I've been looking for a while but I haven't found anything regarding clojure debugging with vim at all. Is it even possible? Can the current alpha release of light table debug? |
| 12:33 | kmicu | @google clojure debugger |
| 12:34 | hyPiRion | $google clojure debugger |
| 12:34 | lazybot | [Debugging in Clojure? - Stack Overflow] http://stackoverflow.com/questions/2352020/debugging-in-clojure |
| 12:35 | kmicu | So many prefixes in so many channels. |
| 12:36 | clj_newb | sorry I should have express my question better. I meant more like setting breakpoints and the like, specifically for vim, but thanks anyway |
| 12:38 | kmicu | $google clojure debugging vim |
| 12:38 | lazybot | [dgrnbrg/vim-redl · GitHub] https://github.com/dgrnbrg/vim-redl |
| 12:39 | kmicu | "This plugin integrates Vim with a running Clojure JVM. It provides a repl that supports breakpoints..." |
| 12:40 | clj_newb | I saw that, thanks kmicu, I guess it is the only option, but it forces me to change my vim clojure setup. Well thanks kmicu |
| 12:44 | cemerick | OK, what is the incantation to get an external javascript library folded into the gclosure compilation output? I've tried :libs, :foreign-libs, and even :externs just for laughs, with no results. |
| 12:45 | cemerick | the lib in question is http://davidbau.com/encode/seedrandom.js FWIW |
| 14:11 | Denommus | Hi |
| 14:20 | seancorfield | Hi Denommus |
| 14:20 | seancorfield | (just to prove there are some live folks here on a quiet sunday) |
| 14:21 | Denommus | Today I may start writing about COA |
| 14:55 | seancorfield | COA? |
| 15:05 | kmicu | Probably CoA - clj on android |
| 15:08 | jouiswalker | is there a way to specify that lein should just grab the latest release of a library? |
| 15:11 | kmicu | LATEST |
| 15:12 | maio` | my first clojar https://clojars.org/fun_migrations :) |
| 15:12 | maio` | what's the "promote" button @ clojars? |
| 15:13 | kmicu | jouiswalker: but you should read http://nelsonmorris.net/2012/07/31/do-not-use-version-ranges-in-project-clj.html |
| 15:14 | jouiswalker | kmicu: thats really helpful. thanks! |
| 15:18 | borkdude | I read that in C you can mark a function 'pure' so the compiler can optimize. Is there any such thing in Clojure? |
| 15:18 | borkdude | (I guess not) |
| 15:20 | xeqi | maio`: clojars doesn't require signed artifacts, but they are prefered. there is some work being done to make a repository of only signed artifacts. "promote" is currently a way to say make my jar available in the new repo |
| 15:21 | xeqi | it should become automatic eventually |
| 15:21 | amalloy | no, but clojure's functions are much more powerful. if you want to avoid repeated calls to a function, just memoize it |
| 15:21 | jouiswalker | borkdude: I didnt know you could do that in c o_o |
| 15:21 | borkdude | amalloy I guess in Haskell such a thing is going on a lot, without having to memoize anything |
| 15:22 | amalloy | jouiswalker: it's not in the standard, it's an extension that some compilers add |
| 15:22 | amalloy | well, in haskell every function is pure, so the hinting is implicit |
| 15:25 | maio` | xeqi: ok thanks |
| 15:32 | jouiswalker | wow, this is really cool: |
| 15:32 | jouiswalker | http://nakkaya.com/2011/01/04/duck-hunt-experiment/ |
| 16:37 | tomjack | consider a type where equality is decidable, but may take arbitrarily long to compute, regardless of the input 'size'. value or not? :) |
| 16:38 | tomjack | seems we want not just decidable equality but efficient equality.. |
| 16:39 | gfredericks | are we talking about comparing functions again? |
| 16:40 | tomjack | not functions, since that's undecidable. my point is that 'decidable equality' may not be enough |
| 16:40 | gfredericks | because it might be unbounded |
| 16:41 | gfredericks | I can imagine regexes being tough to compare :) |
| 16:41 | tomjack | that makes me wonder if there is an Eq instance for (->) t with some finiteness constraint on t |
| 16:42 | tomjack | apparently it's decidable for true regular expressions? |
| 16:42 | gfredericks | right |
| 16:42 | gfredericks | always have to distinguish CS regexes from real-world regexes :) |
| 16:45 | gfredericks | the most remarkable thing I know about PRE's is that you can efficiently index all matching strings |
| 16:45 | laliluna | 2 |
| 16:46 | tomjack | presumably the logarithm of the regular expression type is a character? |
| 16:55 | hyPiRion | gfredericks: what do you mean by efficiently? :p |
| 16:55 | hyPiRion | in terms of space or storage? |
| 16:57 | gfredericks | you could efficiently in every practical sense implement something such as (nth #"foo(bar|baz{3,4})*bar" 999999999999999) |
| 16:57 | gfredericks | assuming the regex there is a PRE |
| 16:58 | hyPiRion | gfredericks: isn't that multibranching? |
| 16:58 | gfredericks | hyPiRion: I have no idea what that means |
| 16:58 | hyPiRion | gfredericks: there are multiple solutions to that answer |
| 16:58 | hyPiRion | do you want one or all of them? |
| 16:59 | gfredericks | no there's one answer |
| 16:59 | hyPiRion | huh. Then I'm not sure if I get what that indexing is. |
| 16:59 | gfredericks | I'm saying there's an ordering of all the distinct matches to that regex that is also efficiently indexable both ways |
| 16:59 | gfredericks | the nth given up there can be implemented as well as its inverse |
| 16:59 | hyPiRion | ah alright |
| 17:00 | hyPiRion | yeah, that makes sense |
| 17:00 | gfredericks | relatedly, given a regex I can return an (infinite?) lazy seq of all distinct matches |
| 17:00 | gfredericks | https://github.com/fredericksgary/ranguages/blob/master/src/ranguages/counting.clj#L104 |
| 17:01 | hyPiRion | gfredericks: now do it with shared structure |
| 17:01 | gfredericks | haha |
| 17:01 | hyPiRion | gfredericks: oh right, you're a core.logic guy. How come (run* [q] (== q #{1 2})) completely blows my stack? |
| 17:02 | gfredericks | I don't think it oughta |
| 17:02 | gfredericks | unless sets are forbidden |
| 17:02 | gfredericks | they must be :) |
| 17:03 | gfredericks | I don't know that they're explicitely supported |
| 17:03 | hyPiRion | wahh, there goes my idea |
| 17:03 | hyPiRion | Oh well |
| 17:03 | gfredericks | haha |
| 17:03 | gfredericks | my expectation is that there's no obvious way to naively support them fully, same with maps |
| 17:04 | hyPiRion | Oh right |
| 17:04 | gfredericks | unbound tails and all that |
| 17:04 | hyPiRion | (fresh [x y] #{x y}) |
| 17:04 | gfredericks | I think there's been work on maps but haven't been following it |
| 17:04 | hyPiRion | Well |
| 17:05 | hyPiRion | that implies (!= x y) |
| 17:05 | gfredericks | oh that's an interesting point as well |
| 17:05 | tomjack | CLP(Set) isn't implemented |
| 17:05 | tomjack | sets no longer implement even IWalkTerm |
| 17:06 | hyPiRion | I was struggling since I didn't understand why (membero x some-set-here) crashed everything, and then I converted it into a vec it worked just fine |
| 17:07 | hyPiRion | Interesting that different data structures actually gives an implicit constraint on the lvars |
| 17:07 | gfredericks | membero is terrible for perf |
| 17:07 | gfredericks | at least if your collection is ground |
| 17:08 | hyPiRion | gfredericks: so e.g. (membero x [1 2 3]) is horrible perf-wise? |
| 17:08 | gfredericks | exactly |
| 17:08 | gfredericks | that by itself might be okay |
| 17:09 | gfredericks | but e.g., if you did that to 20 vars you'd be out of memory |
| 17:09 | hyPiRion | oh no |
| 17:09 | hyPiRion | that totally destroys my idea |
| 17:09 | gfredericks | don't worry! there is a solution! |
| 17:10 | hyPiRion | oh, what is this solution you're talking about? |
| 17:10 | gfredericks | https://www.refheap.com/15830 |
| 17:11 | tomjack | sweet |
| 17:11 | tomjack | I have a ground coll that is the signature of my language and memberos all over the place |
| 17:12 | hyPiRion | oh great, now I'll happily use that because I have no idea why membero is slow and why that is faster |
| 17:12 | gfredericks | membero is slow because it uses conde |
| 17:12 | gfredericks | which does interleaving |
| 17:12 | hyPiRion | oh right, I see |
| 17:12 | gfredericks | which is not necessary when the clauses are short and finite, like unifying with a ground value |
| 17:12 | gfredericks | so e.g., if you (membero x1 [1 2]) ... (membero x20 [1 2]) |
| 17:12 | gfredericks | then you effectively have a binary tree of depth 20 |
| 17:13 | gfredericks | and conde will helpfully search the whole thing in parallel |
| 17:13 | gfredericks | before finding a single solution |
| 17:13 | futile | happy father's day to anyone relevant |
| 17:13 | gfredericks | happy belated fathers day to anyone relevant in the eastern hemisphere |
| 17:15 | hyPiRion | Humm. So in https://www.refheap.com/15831, would my horribly-named `compatiblo` be slow? |
| 17:15 | hyPiRion | And yeah, it's not efficient compared to another solution I'm keen on writing right after this |
| 17:15 | tomjack | you can't use == on sets |
| 17:15 | tomjack | I think? |
| 17:15 | hyPiRion | tomjack: Well, it works perfectly fine over here! |
| 17:16 | gfredericks | well if t1 and t2 are both non-ground... |
| 17:16 | hyPiRion | All the sets are ground anyway, so could I replace it with something else? |
| 17:16 | hyPiRion | gfredericks: yeah, they're both non-ground |
| 17:16 | gfredericks | hyPiRion: yeah if p1 and p2 are sets and not logic vars you could (if ... s# u#) or something like that |
| 17:17 | hyPiRion | Oh, okay, I'll have to read up on that I suppose |
| 17:17 | gfredericks | I'm confusing myself trying to reason about when it's okay to skip conde |
| 17:17 | gfredericks | so I'm going to stop |
| 17:17 | futile | so apparently The Incredible Machine relied heavily on the CPU's own speed |
| 17:17 | futile | so, playing it now in dosbox, it runs ridiculously too quick |
| 17:18 | futile | oh wait that's not related to Clojure |
| 17:18 | futile | sorry |
| 17:19 | tomjack | oh, == will just fallback to = if it doesn't know how to deal with something? |
| 17:19 | hyPiRion | gfredericks: well, I'll read up on it anyway |
| 17:20 | gfredericks | hyPiRion: if you watch the youtube of the last hangout it'll all get gone over in detail :) |
| 17:20 | hyPiRion | Oh, awesome |
| 17:21 | tomjack | ah yes https://www.refheap.com/86578ea53616bd29063e8a914 |
| 17:22 | gfredericks | tomjack: huh weird; so (fresh [x] (== x (Object.))) always fails? |
| 17:22 | gfredericks | or wait I mean the other way around? |
| 17:22 | gfredericks | time to test it |
| 17:23 | gfredericks | hrm no both succeed |
| 17:23 | gfredericks | that I don't understand |
| 17:23 | gfredericks | oh unless that code you pasted doesn't run if either arg to == is an lvar |
| 17:24 | tomjack | seems relevant https://www.refheap.com/90aa9118ff169b3ebfdf257ac |
| 17:24 | tomjack | it will do the lvar unify-terms instead I guess, which causes a substitution? |
| 17:24 | gfredericks | right |
| 17:31 | hyPiRion | gfredericks: so what could I replace (== #{} ground-set) with? I naively tried (= ...), but it seems like it want a fn |
| 17:31 | hyPiRion | (And I'm a bit tired to dig more into core.logic right now so I just lazily ask you) |
| 17:33 | gfredericks | hyPiRion: (if (= #{} ground-set) s# u#)? |
| 17:33 | tomjack | why replace it? |
| 17:33 | gfredericks | good point I guess tomjack just proved it should work |
| 17:33 | gfredericks | if by "ground set" you mean "an actual set" rather than an lvar with a value |
| 17:34 | tomjack | should work even with an lvar, yes? |
| 17:34 | hyPiRion | gfredericks: a set with ground values |
| 17:34 | hyPiRion | well yeah |
| 17:35 | hyPiRion | works for me! |
| 17:35 | gfredericks | then I won't bother figuring out what you meant :) |
| 17:35 | tomjack | hmm, wait, what? |
| 17:35 | tomjack | https://www.refheap.com/5550cbeb9859316c1819ca13b |
| 17:36 | hyPiRion | tomjack: oh yeah, I did that too |
| 17:36 | hyPiRion | dnolen said in #minikanren that he removed support for sets completely |
| 17:36 | tomjack | this was why I thought "you can't use == on sets" |
| 17:36 | tomjack | but I don't understand now why it doesn't work |
| 17:36 | gfredericks | I'm guessing you can (== aset anotherset) but not (== an-lvar a-set) |
| 17:37 | hyPiRion | tomjack: well, I'm not doing any unification at all, I'm essentially comparing two sets |
| 17:37 | tomjack | gfredericks: that appears to be the case |
| 17:37 | hyPiRion | two sets without any lvars in them |
| 17:37 | gfredericks | should be fine then |
| 17:37 | gfredericks | it's just regular = |
| 17:38 | tomjack | I see, sets are tree terms |
| 17:38 | tomjack | and walk is identity on sets |
| 17:38 | tomjack | so walk* blows the stack.. |
| 17:39 | tomjack | wonder if there should be a check there whether walk actually did anything |
| 17:40 | tomjack | no, I guess we'd just need an IWalkTerm for sets |
| 17:40 | gfredericks | tree term is some flag protocol? |
| 17:40 | tomjack | yes, but also all coll? are tree terms |
| 17:41 | gfredericks | ah ha |
| 17:45 | tomjack | please someone do CLP(Set) :) |
| 17:49 | gfredericks | if I attempted anything it'd probably be CLP(Q) |
| 17:50 | gfredericks | but I'm a little worried about that drop-one function |
| 17:50 | weavejester | Just released Ring 1.2.0-RC1 |
| 17:51 | weavejester | Next Ring version is going to have a much shorter development cycle :/ |
| 17:51 | gfredericks | 3 |
| 17:51 | akhudek | weavejester: why the :/ ? |
| 17:51 | weavejester | akhudek: Because I just checked when I released Ring 1.1.0 :) |
| 17:53 | cemerick | weavejester: nice, looking forward to rolling with it. Might just peg friend 0.2.0 against ring 1.2.0 and save everyone a bunch of trouble. :-) |
| 17:55 | weavejester | cemerick: Doesn't Friend already depend on the 1.2.0 beta? |
| 18:05 | hyPiRion | weavejester: you've been on fire recently, props to that |
| 18:20 | akhudek | hmm, https://clojars.org/zip-visit what went wrong? |
| 18:22 | akhudek | well, lein deps :verify works |
| 18:29 | tomjack | hmm, should IEnforceableConstraint not be empty/ |
| 18:29 | tomjack | once we've no longer "hard coded force-ans" |
| 18:39 | tomjack | seems like the ckanren way is to run all defined enforce fns |
| 18:43 | tomjack | direct translation would seem to be an atom in clojure.core.logic with a map of enforce-fns, and other namespaces swap! their enforce-fn in |
| 18:43 | tomjack | which seems.. weird |
| 18:46 | ianeslick | Anyone aware of a Clojure datatype that provides an immutable view over traditional databases? Something like an Index or Table abstraction that works with DynamoDB, HBase, Cloudbase, etc. |
| 18:46 | ianeslick | I'm writing something like this; but wanted to make sure I'm not re-hashing old work. |
| 18:47 | ianeslick | The principle motivation is that none of the built-in abstractions really deal well with the notion of complex indexing or extracting ranges from a Collection based on something other than a numeric index. |
| 18:49 | ianeslick | Hierarchy: Peer/Connection (encapsulates a connection to a database), returns a Store object which you use to generate new versions of an Index. Similar to Datomic, except that we add the Store type to capture a table type that has a fixed schema for how keys/values are mapped to storage. |
| 18:50 | ianeslick | Only reason to do this vs. Datomic, other than cost perhaps, is that other stores provide the ability to better control data layout for queries and computational patterns of moving compute to data (map-reduce, etc) |
| 21:27 | murtaza52 | I have a fn which is returning a lazy seq, and something is causing it throw away the first element |
| 21:27 | murtaza52 | I just dont understand whats happening ? |
| 21:27 | gfredericks | me neither |
| 21:29 | murtaza52 | what code is troubling you ? |
| 21:29 | gfredericks | yours |
| 21:29 | murtaza52 | :) |
| 21:29 | gfredericks | but you haven't told me much more about it so there's not much I can do about it :) |
| 21:31 | gfredericks | perhaps you could share your code? |
| 21:31 | murtaza52 | yup posting the url - just a sec |
| 21:31 | murtaza52 | https://github.com/murtaza52/clj-nio2/blob/master/src/nio2/watch.clj |
| 21:32 | murtaza52 | The watch-seq fn at the end is giving trouble |
| 21:33 | murtaza52 | its suppose to watch over a dir, and report any change events - like file creation, modification, deletion |
| 21:33 | murtaza52 | it just doesnt report the first event immediately. It reports it along with the second |
| 21:34 | gfredericks | side note, apply concat can probably replace your flatten |
| 21:34 | gfredericks | ~flatten |
| 21:34 | clojurebot | flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with. |
| 21:35 | gfredericks | murtaza52: so your issue is not that the return value is incorrect, just that it's not timed the way you would expect? |
| 21:36 | murtaza52 | yup |
| 21:36 | murtaza52 | here is a gist of using it in an repl - https://gist.github.com/murtaza52/5794159 |
| 21:36 | murtaza52 | so once this code is run, it basically blocks |
| 21:37 | gfredericks | well I'm curious if maybe flatten was the actual issue |
| 21:37 | murtaza52 | and then prints whenever an event happens |
| 21:37 | murtaza52 | why would that be so ? |
| 21:37 | gfredericks | it might interact more strangely with laziness; it's too complicated for me to guess at |
| 21:38 | gfredericks | try apply concat and see if that helps |
| 21:38 | murtaza52 | yes it could be, I think it most probably is, bcoz it was working correct before |
| 21:41 | gfredericks | fascinating |
| 21:41 | gfredericks | (dec flatten) |
| 21:41 | lazybot | ⇒ -1 |
| 21:41 | murtaza52 | apply concat also gives same behaviour |
| 21:41 | murtaza52 | what is dec flatten |
| 21:41 | gfredericks | that was just me publicly criticizing flatten |
| 21:42 | murtaza52 | oh ok :) newbie to irc |
| 21:44 | gfredericks | I have no further guesses |
| 21:45 | murtaza52 | it works properly if I dont use apply concat or flatten, however then the signature of the fn changes. It is a forked repo I am trying to work with |
| 21:45 | gfredericks | o_O that's curious |
| 21:46 | gfredericks | ,(take 3 (concat [1 2 3] (lazy-seq (Thread/sleep 3000)))) |
| 21:46 | clojurebot | (1 2 3) |
| 21:46 | gfredericks | concat you ain't so lazy is you |
| 21:47 | gfredericks | ,(take 3 (concat [1 2 3] (lazy-seq (Thread/sleep 3000)))) |
| 21:47 | clojurebot | (1 2 3) |
| 21:47 | gfredericks | oh nevermind |
| 21:47 | gfredericks | false goose herring |
| 21:47 | gfredericks | chase |
| 21:48 | murtaza52 | do I have any other ways to flatten a seq |
| 21:48 | murtaza52 | (apply identity [:as]) |
| 21:49 | murtaza52 | (apply identity [:as :b]) - an identity that will also work for a seq |
| 21:49 | gfredericks | I know of no reason why concat should have this effect |
| 21:49 | murtaza52 | bcoz its a lazy seq concatenated to a lazy seq |
| 21:50 | gfredericks | sure but concat should not realize the second lazy seq at all until you need that part |
| 21:50 | gfredericks | and the test I did above confirms that it seems to be working properly |
| 21:50 | murtaza52 | u know one curious thing I noticed - if I used flatten two times, e evaled the fn and then concat it to the whole, |
| 21:50 | murtaza52 | then my timing was off by two events |
| 21:51 | murtaza52 | so the more lazy constructs I am using the more the timing is getting off !! |
| 21:51 | gfredericks | ,(take 3 (flatten [[1 2 3] (lazy-seq (Thread/sleep 9000))])) |
| 21:51 | clojurebot | (1 2 3) |
| 21:51 | gfredericks | ^ suggests flatten works fine too |
| 21:52 | VFe | Curious if anyone understands why this is, I have a simple luminous web-app, configured with friend. and a relatively simple route (GET "/account" [] |
| 21:52 | VFe | (friend/authorize #{::user} (layout/render "account.html"))) if I put it inside my test-routes in handler.clj, it works fine, but it I put it in any other defroute, it tells me I don't have access to the resource after logging in. |
| 21:54 | callen | VFe: do you really need the full workflow stuff of Friend, or are you just doing the essentials of web app auth? |
| 21:55 | VFe | This is just a side project for learning, not really for anything serious. |
| 21:56 | murtaza52 | gfedricks: (flatten [(read-events ws) (repeatedly #(read-events ws))]) |
| 21:56 | callen | VFe: https://github.com/bitemyapp/neubite/blob/master/src/neubite/middleware.clj https://github.com/bitemyapp/neubite/blob/master/src/neubite/routes/admin.clj |
| 21:56 | callen | VFe: using tools you don't understand will get you into trouble in a hurry. |
| 21:56 | murtaza52 | gfredericks: the above one returns the first event immediately, but then clubs the second and third one |
| 21:57 | murtaza52 | so its the use of flatten with repeatedly |
| 21:58 | gfredericks | ,(take 3 (flatten [[1 2 3] (repeatedly #(Thread/sleep 10000))])) |
| 21:58 | clojurebot | (1 2 3) |
| 21:58 | gfredericks | repeatedly is pretty innocent |
| 21:59 | VFe | Aye, I'm seeing that, that's why I'm trying to figure it out. Thanks for the information though, I always get a lot from new examples :) |
| 21:59 | tomjack | &(time (doall (take 3 (flatten (repeatedly #(do (Thread/sleep 1000) [:foo])))))) |
| 21:59 | lazybot | ⇒ "Elapsed time: 4011.374677 msecs" (:foo :foo :foo) |
| 22:00 | tomjack | does that make sense? |
| 22:00 | murtaza52 | nope sorry :) |
| 22:00 | gfredericks | oh hm |
| 22:00 | tomjack | &(time (doall (take 3 (repeatedly #(do (Thread/sleep 1000) [:foo]))))) |
| 22:00 | lazybot | ⇒ "Elapsed time: 3010.309 msecs" ([:foo] [:foo] [:foo]) |
| 22:00 | ddellacosta | hmm, all of a sudden clojurescript 1830 complaints in project…anyone know what the scoop is? |
| 22:01 | gfredericks | &(time (doall (take 3 (apply concat (repeatedly #(do (Thread/sleep 1000) [:foo])))))) |
| 22:01 | lazybot | ⇒ "Elapsed time: 4012.558563 msecs" (:foo :foo :foo) |
| 22:01 | tomjack | ddellacosta: are you writing a macro? did you print something during macroexpansion? that's my only guess |
| 22:02 | gfredericks | murtaza52: well I guess that reproduces it. I'm not sure what the difference is with what I was doing, or why it's behaving that way at all |
| 22:02 | ddellacosta | tomjack: sorry, should be more explicit: I can't even load up repl/start project all of a sudden today, which smells like it's bringing in a new dependency all of a sudden. |
| 22:02 | tomjack | no clue then |
| 22:02 | murtaza52 | gfredericks: sorry I am missing the point |
| 22:02 | ddellacosta | thought maybe I missed something, but poking around on the CLJS mailing list yields no clues |
| 22:02 | ddellacosta | hmm |
| 22:03 | gfredericks | murtaza52: the timings of ~4000ms should ideally be ~3000ms |
| 22:03 | ddellacosta | must be some dependent library being sneaky |
| 22:03 | gfredericks | i.e., it's realizing one step too far |
| 22:03 | murtaza52 | how so, its returning only 3 values ? |
| 22:03 | ddellacosta | I miss lein pedantic's stern but loving touch |
| 22:04 | gfredericks | murtaza52: I don't know _why_ it's doing it, I just know that it _is_, due to the fact that it took 4000ms |
| 22:05 | gfredericks | murtaza52: i.e., this seems to be the same issue you're dealing with |
| 22:05 | gfredericks | and I can now investigate it without having to go through you |
| 22:05 | gfredericks | if tomjack knows what's up I'd be terribly interested |
| 22:06 | murtaza52 | yup it makes sense |
| 22:07 | murtaza52 | I will be away for 20 mins, so please ping me if anything comes up |
| 22:07 | ddellacosta | nevermind, looks like it was my fault for using piggieback 0.0.5-SNAPSHOT. |
| 22:09 | gfredericks | this is getting much weirder |
| 22:09 | gfredericks | &(time (doall (take 1 (apply concat (repeatedly #(do (Thread/sleep 1000) [:foo])))))) |
| 22:09 | lazybot | ⇒ "Elapsed time: 4012.168009 msecs" (:foo) |
| 22:09 | gfredericks | ^ (noting the `take 1`) |
| 22:09 | tomjack | :) |
| 22:11 | tomjack | I guess apply concat will always realize 4 things |
| 22:11 | tomjack | [x y & zs] gives two |
| 22:11 | gfredericks | I've been staring at the concat code and have no idea why that would be the case |
| 22:11 | gfredericks | oh hm |
| 22:12 | tomjack | yeah I dunno either |
| 22:12 | gfredericks | so it has to walk the arg seq to know which clause of concat to execute |
| 22:12 | tomjack | if you look at the stack inside the repeatedly fn it goes back to RT.boundedLength |
| 22:12 | tomjack | dunno if that's relevant |
| 22:12 | tomjack | can't tell what the bound is |
| 22:13 | gfredericks | &(time (doall (take 1 (reduce concat (repeatedly #(do (Thread/sleep 1000) [:foo])))))) |
| 22:13 | tomjack | yeah I guess it makes sense |
| 22:13 | lazybot | Execution Timed Out! |
| 22:13 | gfredericks | oh |
| 22:13 | gfredericks | yes of course that would not work |
| 22:14 | tomjack | I think it's that (next zs) |
| 22:14 | gfredericks | but it's all inside the lazy-seq thunk |
| 22:14 | gfredericks | I guess that doesn't matter |
| 22:15 | tomjack | hmm, yeah, I don't get it |
| 22:15 | gfredericks | interesting. okay so anyhow the solution ought to be a replacement for apply concat |
| 22:15 | tomjack | I think if this is a problem, you're probably doing something wrong :) |
| 22:16 | gfredericks | really? You're getting a lazy seq of groups of things and want to flatten that lazily? |
| 22:16 | gfredericks | seems reasonable to me |
| 22:16 | tomjack | if you care about whether one or two extra things are realized I mean |
| 22:16 | tomjack | it shouldn't matter |
| 22:17 | gfredericks | in the case of listening for events though |
| 22:17 | gfredericks | you think using lazy seqs at all is bad? |
| 22:17 | gfredericks | (for that use) |
| 22:18 | tomjack | I don't understand the watch.clj code really |
| 22:18 | tomjack | but apparently it's bad, because this is a problem :) |
| 22:19 | tomjack | looks like it's lazy IO basically? yeah, bad |
| 22:20 | gfredericks | this is a new idea to me. I feel like modeling external events as a lazy seq is an oft-used example of the utility of lazy seqs |
| 22:20 | tomjack | that seems odd |
| 22:20 | gfredericks | in any case this seems to fix it: (defn concats [s] (lazy-seq (concat (first s) (concats (rest s))))) |
| 22:21 | tomjack | lazy seqs are pull-based, 'external events' suggests push |
| 22:21 | gfredericks | murtaza52: ^, modulo tomjack's higher level criticisms |
| 22:21 | gfredericks | tomjack: so it only makes sense if the "pull" doesn't block prohibitively? |
| 22:22 | tomjack | well it could still make sense that way |
| 22:22 | gfredericks | I think this is a pull |
| 22:22 | tomjack | as long as pulling doesn't cause something to happen in such a way that depending on how/when you pull, you get different results |
| 22:23 | gfredericks | and the issue is that if the second pull is going to block for a while then you're not seeing the first results because concat is waiting for the second batch before it gives you anything |
| 22:24 | tomjack | hmm |
| 22:24 | tomjack | s/well it could still make sense that way// |
| 22:25 | gfredericks | okay. so the lesson is don't use lazy seqs when you're dependent on clojure.core being maximally lazy |
| 22:25 | tomjack | my opinion is probably worthless, I have developed the view that lazy seqs are fundamentally broken |
| 22:26 | tomjack | the cases where you don't notice that they're broken are the cases where it's OK to use them :) |
| 22:26 | gfredericks | ha |
| 22:32 | gfredericks | admittedly there are two levels of laziness going on here |
| 22:32 | gfredericks | I think concat does fine with not realizing anything extra within the seqs you pass it |
| 22:32 | gfredericks | it's the fact that he's relying on the arg list itself being lazy that concat didn't expect |
| 22:32 | gfredericks | I think the signature of concat is maybe weird |
| 22:32 | tomjack | yeah, in retrospect it's not surprising |
| 22:32 | gfredericks | or at least the alternative should exist |
| 22:32 | gfredericks | I bet the majority of my uses of concat are with apply |
| 22:32 | tomjack | dunno what it would even mean for apply to be lazy in the seq |
| 22:32 | gfredericks | yeah that's not really feasible |
| 22:32 | gfredericks | but concat doesn't have to be written variadically |
| 22:32 | gfredericks | and I think this illustrates that a non-variadic version (like the one I pasted above) could be valuable |
| 22:32 | dnolen | ddellacosta: hmm, I just tried 1820 in a project everything seems fine here |
| 22:33 | ddellacosta | dnolen: yeah, it was totally a false alarm, my apologies--I had a snapshot version of Piggieback and it was somehow pulling in 1830 for some reason |
| 22:33 | dnolen | ddellacosta: you must mean 1820? |
| 22:33 | AlexE | Hi all - I'm having a weird problem in emacs paredit where typing a "(" adds an extra space in front of the opening parens |
| 22:34 | ddellacosta | dnolen: well, this may illuminate the error. I didn't look into it deeply, but it was clearly complaining about "1830." Let me take a closer look, maybe is something I should let cemerick know about |
| 22:34 | AlexE | Is anyone else seeing this? I causes problems for reader functions like: # () |
| 22:35 | gfredericks | AlexE: not I |
| 22:35 | cemerick | ddellacosta: whoops; that's a build on my local machine :-/ |
| 22:36 | cemerick | Some vars in the cljs analyzer changed on master, which that snapshot is tracking. |
| 22:36 | ddellacosta | cemerick: ah, haha…was wondering what was up with that. ;-) I should have known better than to use 0.0.5-SNAPSHOT anyways, I don't remember why I had it in there…but moving back down to 0.0.4 solved it, so I forgot about it and moved on. |
| 22:36 | AlexE | gfredericks - thanks, so you don't get an extra space in front when using paredit.el? |
| 22:36 | gfredericks | AlexE: nope, I've never seen that |
| 22:36 | ddellacosta | gotcha |
| 22:36 | gfredericks | I'm probably not up-to-date though |
| 22:37 | tomjack | gfredericks: incidentally, concats is join, huh? :) |
| 22:37 | AlexE | hmm - it's definitely a paredit thing because disabling the mode solves the problem… but that's a very inefficient :-/ |
| 22:37 | gfredericks | tomjack: is that a haskell name? |
| 22:37 | AlexE | ...workaround |
| 22:38 | tomjack | yeah |
| 22:38 | gfredericks | I guess it is then |
| 22:38 | gfredericks | I would have guessed haskell just had a one-arg function called `concat` |
| 22:38 | gfredericks | but you'd probably know better than me |
| 22:39 | tomjack | it has that too for lists |
| 22:39 | gfredericks | oh join is on a typeclass? |
| 22:39 | gfredericks | monoids? |
| 22:40 | gfredericks | this is monads isn't it |
| 22:40 | gfredericks | I've never had the names of the monadic functions too solidly in my head |
| 22:40 | tomjack | yeah |
| 22:40 | gfredericks | in fact the strongest evidence I can muster without googling is that core.logic uses the name `join` so it must be about monads :P |
| 22:41 | tomjack | if you read about monads outside haskell usually they're formulated in terms of join |
| 22:41 | gfredericks | no wai |
| 22:41 | gfredericks | t |
| 22:41 | gfredericks | the core.logic word I'm thinking of is bind I think |
| 22:41 | tomjack | bind is the.. other.. way :) |
| 22:43 | tomjack | I always felt a little weird about #(apply concat %1) |
| 22:43 | gfredericks | is this worth proposing on clojure-dev? |
| 22:43 | tomjack | #(mapcat identity %) would be a suitable concats, yes? |
| 22:44 | gfredericks | mapcat uses apply concat |
| 22:44 | tomjack | :'( |
| 22:46 | tomjack | &(first (mapcat (constantly [:foo]) (repeatedly #(println "foo")))) |
| 22:46 | lazybot | ⇒ foo foo foo foo :foo |
| 22:46 | tomjack | delightful |
| 22:46 | gfredericks | :) |
| 22:48 | tomjack | so with a recursive mapcat thingy might you end up looking further and further ahead? |
| 22:49 | tomjack | or is the over-eagerness bounded at least |
| 22:49 | tomjack | I say 'thingy' because I have no idea what I'm talking about |
| 22:52 | gfredericks | tomjack: you mean the current impl of mapcat? |
| 22:52 | gfredericks | should just be 4 args |
| 22:54 | tomjack | yeah I'm wondering if you can get yourself into situations where you're 4 elems too eager, then 8, then ... |
| 22:55 | gfredericks | okay so you're talking about a hypothetical different impl of mapcat? |
| 22:55 | tomjack | no a hypothetical use of current mapcat |
| 22:55 | gfredericks | unless you're calling it more than once somehow... |
| 22:55 | gfredericks | which I guess is what you meant by "recursive" |
| 22:56 | tomjack | yeah, though I really have no clue what that hypothetical use might be |
| 22:57 | tomjack | just seems like a potential eagerness-leak waiting to happen |
| 22:57 | cemerick | dnolen: should I wait for you to vet my latest patch before suggesting yet more changes I'd like to make to the cljs REPL(s)? :-P |
| 22:57 | dnolen | cemerick: feel free open enhancement tickets for stuff you have in mind |
| 22:57 | gfredericks | tomjack: so if there were a decent name for it besides join then we could propose that function gets added to core and mapcat gets rewritten |
| 22:58 | dnolen | cemerick: one question - on the async bit - I'm not sure why this isn't surmountable given how browser REPL works in the first place |
| 22:58 | cemerick | dnolen: you mean re: reflect stuff? |
| 22:58 | dnolen | cemerick: yes |
| 23:00 | cemerick | dnolen: not sure it can be, easily. e.g. (doc 'whatever) is entirely disconnected from the R-E-P loop, insofar as what it does is an out-of-band callback |
| 23:00 | murtaza52 | tomjack:, gfredericks: great analysis. so maybe its not working bcoz concat is expecting two realized elements, while one is lazy and blocking. |
| 23:01 | gfredericks | murtaza52: yeah, did you see my impl of `concats`? |
| 23:01 | dnolen | cemerick: I don't see why this matters if all the calls are forced to sync |
| 23:01 | dnolen | forced to be sync |
| 23:01 | dnolen | sync call to browser, sync call to server, return value to REPL |
| 23:01 | murtaza52 | however shouldnt this work - (apply concat [] (repeatedly #(read-events ws))) - the second element to concat will be realized when a system event happens. however this also behaves the same way |
| 23:01 | murtaza52 | no let me try that. |
| 23:02 | dnolen | cemerick: again, I don't know for sure, I'm just curious why this issue doesn't affect the normal REPL |
| 23:02 | cemerick | dnolen: perhaps; I don't know the goog xhr/channel APIs at all. |
| 23:02 | gfredericks | murtaza52: apply concat realizes 4 arguments when you first force it, so I guess (apply concat [] [] [] [] ...) would work |
| 23:02 | dnolen | cemerick: I do recall the reflect stuff uses xhr instead of the CrossPageChannel |
| 23:03 | cemerick | dnolen: because the browser-repl is enforcing response ordering on the channel |
| 23:03 | dnolen | cemerick: xhr can be forced to be sync |
| 23:03 | murtaza52 | why is that so, why 4 elements |
| 23:03 | dnolen | cemerick: in anycase, it's an enhancement not a big deal |
| 23:03 | dnolen | cemerick: just wondering if you dug into much, but it sounds like not - no problem |
| 23:03 | cemerick | i.e. all the add-in-order business through an agent, etc |
| 23:03 | gfredericks | murtaza52: eh, it's details; anyhow I just tested it and you can't escape one extra realization by simply adding more args |
| 23:03 | dnolen | cemerick: k |
| 23:04 | gfredericks | murtaza52: but my concats should solve it for you |
| 23:04 | cemerick | dnolen: not really, just trying to bring everything forward as it was; that said, I'm pretty sure no one actually uses the reflect stuff, given the output it was producing...? |
| 23:04 | murtaza52 | concats |
| 23:04 | tomjack | gfredericks: join is not good because it's taken by clojure.string/join? |
| 23:04 | gfredericks | tomjack: or just suggests that |
| 23:05 | dnolen | cemerick: likely |
| 23:05 | gfredericks | _or_ suggests monads |
| 23:05 | gfredericks | I'm not 100% opposed. maybe it's good. |
| 23:05 | dnolen | cemerick: thanks much for this anway, can't wait to see this stuff get hooked up to tools |
| 23:07 | cemerick | dnolen: FWIW, I think getting the reflective stuff out of the actual REPL will be less fragile / more capable in the end. Wouldn't be a function, but I think that's a small price now that I've gotten a fuller tour. |
| 23:07 | cemerick | dnolen: yeah, been using it for a long time myself. Invaluable IMO. Always-instant cljs REPL, etc. |
| 23:07 | dnolen | cemerick: like just special forms for everything? |
| 23:09 | murtaza52 | gfredericks: it works ! however now I dont know why it works ! |
| 23:09 | murtaza52 | why did it solve the problem :) |
| 23:10 | cemerick | dnolen: Dunno. Depends on just how much you want to jam in the REPL proper. Even pushing e.g. doc lookup through a dedicated nREPL op makes so much more possible w.r.t. customizable/localized experience -- more complicated things like macroexpansion and symbol lookup only get better. The line-by-line textual REPL is a *really* narrow keyhole. |
| 23:10 | dnolen | cemerick: hum, I don't have strong opinions about it and you're messing around with this stuff a bit more. |
| 23:11 | dnolen | cemerick: it just seemed like it would make tooling more awkard not having these things be first class - but perhaps the concern was misplaced. |
| 23:12 | cemerick | dnolen: I'm actually a bit behind what technomancy and co. are doing. |
| 23:13 | cemerick | The point is, one-off stuff like `doc` makes sense to have around, just because it's convenient, and generally works well in a terminal. Macroexpansion, symbol lookup, call-trace display/visualization, etc. etc....not so much. |
| 23:13 | tomjack | &(apply (fn [x y & zs]) (repeatedly 100 #(println "foo"))) |
| 23:13 | lazybot | ⇒ foo foo foo foo nil |
| 23:13 | tomjack | murtaza52: ^ |
| 23:13 | tomjack | in other words, it's just a quirk of (apply concat ..) |
| 23:14 | cemerick | All these things are why Dr. Racket and Lispworks are awesome, in addition to textual REPLs. |
| 23:14 | cemerick | dnolen: Anyway, once the patch makes it through safely, I'll see what I can do about making reflect stuff synchronous. |
| 23:15 | gfredericks | tomjack: murtaza52: http://dev.clojure.org/jira/browse/CLJ-1218 |
| 23:15 | dnolen | cemerick: k |
| 23:15 | murtaza52 | in the above example, shouldnt it print it 100 times ? |
| 23:15 | gfredericks | murtaza52: no because repeatedly is lazy |
| 23:15 | dnolen | cemerick: in other news, your core.match bugs are getting crushed |
| 23:15 | tomjack | one might argue that it should print 0 times |
| 23:15 | dnolen | very quickly |
| 23:15 | gfredericks | but the function signature forces several realizations |
| 23:16 | tomjack | (well, 0 times wouldn't make sense in clojure, but..) |
| 23:16 | cemerick | dnolen: yeah, I saw you got a second wind :-) Very excited to get back to the bits I have that use it, though I'm about 12 layers too deep at this point :-/ |
| 23:16 | tomjack | I still don't understand why it's 4 though |
| 23:16 | dnolen | cemerick: heh, yeah it needed 15 hours of focused hacking to get out of the bog |
| 23:16 | cemerick | dnolen: I thought match had gotten passé for you? :-P |
| 23:17 | dnolen | cemerick: we're all clear now, it's been really smooth sailing. Was far too obsessed with premature optimization two years - some embarassing stuff got purged. |
| 23:17 | dnolen | two years ago |
| 23:18 | tomjack | gfredericks: I think my position is still "if you require maximal laziness, you're doing it wrong" and would be surprised if the clojure team doesn't echo this cop-out :) |
| 23:18 | cemerick | dnolen: heh, so your "fixed" comment was just you adding a testcase verifying the fix you actually made however long ago? :-) |
| 23:18 | gfredericks | yeah that wouldn't bother me too much |
| 23:19 | gfredericks | tomjack: in any case, I'm headed off. Thanks for learning me a clojure. |
| 23:19 | murtaza52 | so its apply that causes a lazy seq to realize 4 times |
| 23:19 | gfredericks | ...sorta |
| 23:20 | gfredericks | not that apply could really do anything different |
| 23:20 | tomjack | &(apply (fn [x y z w v & us]) (repeatedly 100 #(println "foo"))) |
| 23:20 | lazybot | ⇒ foo foo foo foo foo foo foo nil |
| 23:20 | dnolen | cemerick: heh yeah the "fix" wasn't really one thing, a lot of refactoring and simplifying |
| 23:21 | murtaza52 | it realizes it the number of times its needs args, thats why the non vaiadic version works |
| 23:21 | murtaza52 | I mean the times the fn needs args |
| 23:22 | dnolen | one nice outcome is that seq pattern matching can be salvaged |
| 23:22 | dnolen | was going to give it the boot, but now it an vector matching can peacefully coexist |
| 23:26 | cemerick | dnolen: with all the same notation, etc? |
| 23:27 | dnolen | cemerick: it just works, no backtracking weirdness |
| 23:27 | cemerick | sweet |
| 23:27 | dnolen | cemerick: however vector patterns still only work on *vectors* |
| 23:27 | cemerick | sounds fine to me |
| 23:27 | murtaza52 | gfredericks: so shouldnt this also realize just 4 elements |
| 23:27 | murtaza52 | ,(apply concat (repeat [:a])) |
| 23:27 | clojurebot | (:a :a :a :a :a ...) |
| 23:27 | cemerick | dnolen: sorry, wasn't meaning to be coy w/ 521 :-P |
| 23:28 | dnolen | cemerick: I'll probably change that, but I'd rather get out solid release that doesn't have so many bugs before thinking about enhancements again. |
| 23:29 | cemerick | dnolen: didn't think it was possible efficiently? I mean, once you're matching seqs generally, the general case is linear time, yes? |
| 23:30 | dnolen | cemerick: it's not possible efficiently, but given a culture of destructuring seqs I'm not sure it matters much :P |
| 23:30 | murtaza52 | tomjack: why doesnt this version also block, doesnt it need atleast two elem to concat, why does it immediately return the first event, without waiting for the second event also to realize |
| 23:30 | murtaza52 | (defn concats [s](lazy-seq (concat (first s) (concats (rest s))))) |
| 23:30 | dnolen | cemerick: again it's not something I fully decided something to stew on |
| 23:31 | cemerick | sure |
| 23:31 | ddellacosta | dnolen, cemerick: just saw you folks talking about CLJS repl, I would love to help. I use it a lot via piggieback, and would be using it every day if I could get some of the kinks out. namespace stuff, connecting already existent project to repl are pain points for me. But not sure where to start with contributing. |
| 23:31 | tomjack | murtaza52: in that case the first element of (concats foo) can be gotten from (first foo) |
| 23:31 | cemerick | ddellacosta: clarify those pain points, please? |
| 23:31 | tomjack | concats and rest are both lazy so.. |
| 23:32 | tomjack | and (concat x y) won't realize y until necessary |
| 23:32 | tomjack | it's just (apply concat foo) that's a bit funny |
| 23:33 | murtaza52 | so it will return (concat x []) or x, as y is not realized ? |
| 23:33 | ddellacosta | cemerick: sure. 1) I have an existing project with browser connect code on the test build. When I open a piggieback session and then open the project w/connect CLJS in a browser, sometimes I have to hit reload a dozen times before the browser syncs up with the repl. This could just be my ignorance, but at least I'd love to help documenting the process. |
| 23:35 | ddellacosta | cemerick: 2) I want to have a testing flow like my clojure.test/midje flows, where I test in the repl, and reload the namespaces to call run-tests again. I started investigating how to integrate tools.namespace but not sure where to begin with this one. As it is, I end up re-compiling my tests every time and running via `lein cljsbuild test`. It's not as fast or nice as my clojure workflow. |
| 23:35 | tomjack | &(take 3 (concat (lazy-seq (println "foo") [1 2 3]) (lazy-seq (println "bar") [4 5 6]))) |
| 23:35 | lazybot | ⇒ (foo1 2 3) |
| 23:35 | tomjack | &(take 4 (concat (lazy-seq (println "foo") [1 2 3]) (lazy-seq (println "bar") [4 5 6]))) |
| 23:35 | lazybot | ⇒ (foo1 2 bar3 4) |
| 23:35 | ddellacosta | anyways, that's my wishlist…heh. |
| 23:36 | cemerick | ddellacosta: I did some serious surgery to the browser REPL that should make all that a lot easier. Pending dnolen's stamp of approval at the moment. :-) You can try out the 'browser-repl' branch on my cljs fork if you want. |
| 23:36 | cemerick | s/easier/more reliable |
| 23:36 | cemerick | well, and easier, too :-P |
| 23:37 | dnolen | cemerick: sounds awesome, will take a look soon, just want to wrap up a few more core.match things |
| 23:37 | ddellacosta | cemerick: okay, I think in fact you sent that to me via IRC a few weeks ago, and while it was super smooth to get going in a brand new browser env., I couldn't figure out how to sync it up to my existing codebase. Will take another look. |
| 23:37 | cemerick | dnolen: sorry, wasn't trying to rush you :-) |
| 23:38 | cemerick | ddellacosta: That's more clojurescript.test than piggieback or the REPL, I think: https://github.com/cemerick/clojurescript.test |
| 23:39 | cemerick | I don't use tools.namespace or midje, so perhaps my frame of reference is a bit off. But, I drive a lot of my testing through the REPL, and the above brings 98% of clojure.test to a CLJS repl. |
| 23:40 | ddellacosta | cemerick: yeah, I'm using clojurescript.test (thanks, I use so much of your code every day these days!), but that first issue I was talking more just about connecting a running CLJS browser session (by that I mean my app up and running in a browser) to a repl, rather than testing it |
| 23:41 | murtaza52 | tomjack: gfredericks: thanks ! |
| 23:41 | ddellacosta | I guess maybe what I can help most with at this point is testing and adding documentation. But we are still in a very early period I guess with integrating CLJS into a real workflow, so I don't want to codify anything prematurely, if that's the right way to put it. |
| 23:41 | cemerick | ddellacosta: you mean, after you've been fiddling with the app in the browser for a while, and then you have trouble connecting it to the browser-REPL? |
| 23:42 | ddellacosta | cemerick: yeah, I mean, so often I'll load up my app in the browser, and I'll want to test the current state of some variables or how something behaves, or attach an event listener dynamically (for example) |
| 23:43 | ddellacosta | cemerick: and so I'll start up a piggieback session, and load up a copy with the browser/repl connect code compiled in |
| 23:43 | ddellacosta | and it can be hit-or-miss. |
| 23:43 | ddellacosta | and in general it's just a pain to reload the code and have to re-set-up the cljs/repl connection |
| 23:44 | cemerick | oh, so you're still connecting at load time, etc |
| 23:44 | ddellacosta | yeah, I mean, I have this kind of hack-y flow worked out |
| 23:45 | cemerick | I'm afraid I've been running my own patched build of cljs for so long, I've forgotten all the little nuances of the original browser-repl. |
| 23:45 | ddellacosta | 1) load piggieback in repl 2) reload browser 3) type (.log js/console "connected?") in repl 4) if it doesn't connect right away, reload browser until it kicks in and "connected?" gets dumped out in my browser console. |
| 23:45 | cemerick | hrm |
| 23:46 | cemerick | ddellacosta: any chance you're attempting to run multiple browser-repl sessions from a single Clojure runtime? |
| 23:47 | ddellacosta | cemerick: well, I'm definitely not calling cemerick.piggieback/cljs-repl more than once (just one repl running) if that's what you mean, but I'm not sure what the effects of reloading the browser are. |
| 23:49 | ddellacosta | started to dig into the cljs browser/repl code one day, and I didn't get far before I got distracted by higher priority stuff. I think I just need to sit down and really try understanding all the sub-systems involved, then maybe I can contribute more. But I'd really love to get this tooling nicer, as I think it would help the eco-system in general. |
| 23:50 | cemerick | I'm afraid to speculate, as my memory is a bit hazy about the failure modes at the moment. :-| |
| 23:50 | cemerick | ddellacosta: For sure, there's a ton of work to be done around getting ClojureScript and its associating tooling up to snuff. *very* early days, as you said. |
| 23:51 | ddellacosta | haha, no worries. Yeah, at this point it's all kind of "good enough for now, look into it when I have time." But when I saw you folks talking about it I thought I'd pipe up as I am happy to contribute, just not sure where to start. |
| 23:51 | cemerick | ddellacosta: oftentimes, neither do I ;-P |
| 23:51 | ddellacosta | haha |
| 23:52 | ddellacosta | well, I'll read through your browser REPL code and see what I can learn. |
| 23:54 | cemerick | I think once the browser-repl is settled down, that'll make things a lot more pleasant all around. Esp. if your tools have multisession nREPL support, you should end up being able to load code into either your Clojure backend or currently-connected cljs browser effectively without needing to think about which is which too much. |
| 23:55 | callen | seancorfield: so have you just not needed to-sql-time yet or what? |
| 23:55 | ddellacosta | cemerick: that would be fantastic. Another thing we were tossing around was the idea of a browser plugin which would just pop open a running CLJS repl for you, within the current namespace of the running CLJS loaded |
| 23:55 | callen | seancorfield: you're importing java.sql.Timestamp, is there some problem I should be aware of? |
| 23:55 | ddellacosta | namespace -> environment I should say |
| 23:56 | cemerick | The really hard part will be getting all of the Clojure-supporting tools to support analogous cljs nREPL ops and such so that things more sophisticated than eval and load-file work the same way. |
| 23:56 | cemerick | That's mostly political though, not technical. |
| 23:56 | ddellacosta | ah. Yeah, I stumble on namespace issues a lot in the cljs REPL |
| 23:57 | callen | cemerick: I make an excellent Political Commissar for ensuring the comrades stick to the party line. |
| 23:57 | callen | cemerick: I can provide my forged letters of recommendation from university if you like. |
| 23:57 | cemerick | ddellacosta: like, an actual Plugin, i.e. rev up a jvm and such? |
| 23:58 | callen | alexbaranosky1: is there some documentation on dates/times and Korma that exists but I haven't discovered/ |
| 23:58 | ddellacosta | cemerick: yeah, it wasn't too thought out, but was more pie-in-the-sky, "wouldn't that be nice?" I had only thought of it on Mac OS X honestly, as you could trigger Terminal, and I'm not sure what you would need on Windows/Linux. |
| 23:58 | cemerick | callen: I think perhaps a softer touch is called for. ;-P |
| 23:59 | cemerick | ddellacosta: sounds a bit crazy :-) I think using the self-hosting cljs fork is probably more realistic. |
| 23:59 | callen | cemerick: is good. I can strangle with velvet just as well as rope. |
| 23:59 | callen | cemerick: maybe even give vodka before. |
| 23:59 | cemerick | ddellacosta: Which perhaps isn't saying much? |
| 23:59 | ddellacosta | cemerick: yeah, perhaps too much…heh. ;-) |