#clojure logs

2013-06-16

00:01ambrosebsIs it possible to nest prefix lists in a require?
00:01tomjacknope
00:01ambrosebsthanks
00:15wei_How do I get the string name of a function (not symbol)? this doesn't work (let [f filter] (name f))
00:17tomjackyou should probably consider that impossible
00:18tomjackthe var has a .sym but that's not really public ##(.sym #'filter)
00:18lazybotjava.lang.SecurityException: You tripped the alarm! class clojure.lang.Var is bad!
00:20wei_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:22tomjackyou can ##(.getName (class filter)) but..
00:22lazybot⇒ "clojure.core$filter"
00:25dobry-den1off 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:28akhudek##(let [a [1 2 3] b [0 0 0 0 0]] (into a (subvec b (count a))))
00:28lazybot⇒ [1 2 3 0 0]
00:28akhudekassuming a is always smaller than b, and you want to overwrite b
00:32dobry-den1akhudek: nice, thanks.
00:41amalloytomjack: .sym on vars is silly: if you actually have a var, rather than a function, you can use the :name in its meta
00:42tomjacknice, and then you can get the ns via ns-name
00:42tomjackthanks
00:42tomjackI thought there was no public way
01:25samrathow do I get cond to print something then recursively call a function: https://www.refheap.com/15823
01:30tomjack~helpme
01:30clojurebotA 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:33samrattomjack: 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:37tomjackhmm
01:38samrattomjack: oh, wait. looks like it is working. I was just being impatient. Sorry
01:39tomjackthe timeout bit doesn't make sense to me
01:41tomjackit's supposed to test whether calculating the new score during a single step takes longer than the timeout?
01:42tomjackI 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:43samrattomjack: the function is supposed to dedicate only some limited time for a cipher
01:43samratafter that, if its not performing well, then stop it and try "improving" upon a new cipher instead.
01:44noonianhttp://docs.oracle.com/javase/6/docs/api/java/lang/System.html#currentTimeMillis()
01:44samrattomjack: I'm translating this from racket: http://blog.jverkamp.com/2013/01/25/an-optimal-alphabetizing-cipher/
01:45tomjackin that case, shouldn't the 'timer' val get passed down, rather than being recomputed every step?
01:45noonianit doesn't guaruntee to return ms, which could explain it taking longer
01:46tomjackthe racket example seems to pass timer down
01:47noonianah, 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:48noonianyou could use a loop/recur form here and have timer be a passed in
01:49noonianyou want timer to only be called once at the beginning since that is how you are calculating elapsed time
01:50tomjackwell, you want what's there in every case except the :else branch of the cond
01:50tomjackwhen the timer should be preserved
01:51samrattomjack: ah, thanks. It is working faster now.
01:51noonianthe 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:53noonianactually, each step is the time between the let and the cond case and not relating to the previous step
01:54samratnoonian: I'm passing the timer in the :else clause now.
01:56samratfor the other cases, I do want to reset the timer.
01:58noonianyou can just create a new timer and pass that in instead of the old one when you call monte-carlo in those cases
01:59noonianjust pass in the result of a new call to currentTimeMillis
02:03samratnoonian: hmm, would that be more "correct" than calling currentTimeMillis from the let block?
02:03samratnoonian: that is what the racket code does too, but I'd assumed it was the same thing
02:05tomjackyou added a timer arg to the fn but still have a let for timer?
02:05noonianI dont understand this syntax, do you call their version with any arguments?
02:05noonian(define (solve/monte-carlo [guess (random-key)]
02:05noonian
02:06samrattomjack: now I don't
02:07samratnoonian: yes. you can see it called there: (solve/monte-carlo (random-key) -inf.0 timeout (current-seconds))
02:08samratnoonian: those are the default values.
02:08samratin the (define ...), I mean
02:09nooniansamrat: I see, in the other version it isn't using a let, they are just the default values
02:12noonianbasically, 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:13noonianby 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:14nooniannotice that he calls (solve/monte-carlo) from the repl to test the output
02:14noonianwith no args
02:16tomjackthat's kinda neat
02:17tomjackguess I could make a macro for default args
02:18murtaza52how do I write this java code in clojure - > FileSystems.getDefault().getPath("logs", "access.log");
02:20tomjack(.getPath (FileSystem/getDefault) "logs" (into-array String ["access.log"]))
02:22tomjackvariadic java methods are just syntax sugar for passing an array
02:22tomjacksyntax sugar we don't have in clojure..
02:26nooniansamrat: 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:29samratnoonian: I'm going to try that. I got a StackOverflow after running the current version for a while.
02:30noonianyeah, racket guarantees to optimize tail calls, whereas clojure will not so you have to use loop/recur or higher order functions
02:33zRecursiveloop/recur ensures "tail recursive" ?
02:37noonianzRecursive: yep
02:38zRecursivenot direct though
02:39zRecursivemaybe it is due to JVM
02:39noonianI expect clojure will get automatic tail call optimization whenever java gets gets it, >= 1.8 probably
02:40zRecursiveif so, that will be great
03:04tomjack,((promise) 42)
03:04clojurebot#<core$promise$reify__6310@1211162: 42>
03:04tomjack,(def x ((promise) 42))
03:04clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
03:04callentomjack: surely you knew the def wasn't going to work?
03:04tomjackI thought clojurebot was wide open
03:05tomjackresult is java.lang.AbstractMethodError in clojure.lang.Compiler$InvokeExpr.eval
03:05tomjackbecause promises don't implement applyTo
03:06SNBarnettHi, why does (= java.lang.String (class "a")) return true but (case (class "a") java.lang.String true nil) return nil?
03:08amalloytomjack: promises aren't "publicly" IFn anyway, so...?
03:09tomjackoh, 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:09tomjack&(case 'java.lang.String java.lang.String true)
03:09lazybot⇒ true
03:20SNBarnetttomjack: cheers, any idea why the other form doesn't work?
03:21tomjackbecause the String class is not the symbol 'java.lang.String
03:21tomjackyou can't match a class with case
03:23SNBarnetttomjack: ah ok, thanks.
03:23noonian,(if java.lang.String true false)
03:23clojurebottrue
03:24tomjack"All manner of constant expressions are acceptable in case, including numbers, strings, symbols, keywords, and (Clojure) composites thereof."
03:24noonianyou're using case like a cond
03:26noonian,(case java.lang.String java.lang.String true "something" "a string" "default")
03:26clojurebot"default"
03:26noonianhmm
03:26tomjackinteresting https://www.refheap.com/f1c14b6df75de1e49da485e92
03:27SNBarnettnoonian: was trying to follow this example http://pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure
03:28noonianSNBarnett: yeah, I was wrong
03:28noonian,(case (class "a") java.lang.String true false)
03:28clojurebotfalse
03:30tomjackthat's just wrong
03:30tomjackambrosebs must not have tested it? :)
03:30hiredmanjava.lang.String is read is a symbol and eval'ed as a class
03:30hiredman,(case 'java.lang.String java.lang.String true false)
03:30clojurebottrue
03:30hiredmancase treats each possiblity has a constant (no eval)
03:32amalloytomjack: using #class to sneak eval into case will probably break if you AOT
03:32noonianyeah, case's doc states that test-constants must be compile time literals
03:33noonianand it looks like user written classes aren't compile time constants
03:38tomjackamalloy: doesn't look like it
03:39tomjackwell, at least, https://www.refheap.com/5bdb722fbaa0fa22dbfa970f9 seems to work
03:41amalloytomjack: 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:43tomjackI ran with java -jar on an uberjar
03:43tomjackbut I think I see how it's evil
03:45hiredmanthe 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:45tomjackah, interesting
03:45hiredmanacross jvm runs it has different hashcodes
03:46tomjackhmm, I'm always getting 1268575826
03:46amalloyhiredman: lazybot and clojurebot return different hash codes for String right now
03:46hiredmanhere String is always 1051225362
03:46tomjackhere String is 1145768891..
03:46hiredmanamalloy: yeah, I bet it is a lod order thing, so different jvm versions might be different
03:46tomjackso yeah, really evil :)
03:46hiredmanload
03:48hiredmanso 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:48tomjack&(.hashCode (java.net.URI. "/"))
03:48lazybot⇒ 47
03:49tomjack&(.hashCode #inst "2012")
03:49lazybot⇒ -1768894156
03:49tomjackcool
03:51tomjack&(.hashCode (java.util.UUID/fromString "b3da40ec-cbe2-4637-a0fa-de66b1293896"))
03:51lazybot⇒ 1777066027
03:55SNBarnettSo the best way to get around this is to just use cond?
03:57tomjackis it bad to close over an access to an :unsynchronized-mutable?
03:58tomjackI guess at best I'll get the old value
03:59tomjackyep
04:05amalloySNBarnett: or one of the many features intended for use in class-based polymorphism
04:06amalloyinterfaces, protocols, multimethods...
04:09SNBarnettamalloy: thanks for the suggestions
04:52john2xi'm having a hard time understanding loop and recur.. so recur's arguments need to match let's bindings?
04:53john2x*loop's bindings
04:58noonianyes, you can think of loops bindings as default values
05:00noonianer, initial values
05:05noonianyou can use recur without loop to that will call the actual function
05:10noonianjohn2x: these are at least conceptually the same, https://gist.github.com/lore17/7ea7af0218894405fab2
05:20tomjackif we require an implementation of equality for our values, maybe "you can put it in a map" is a good description
05:20tomjackthe example makes the "in practice, they're not values" for fns make sense to me
05:51mindbender1Is it possible to tell cljsc where to look for macros, say via options?
05:56tomjackmindbender1: I have this hack for that https://www.refheap.com/6540b2904cb1b419c22dcda05
06:19mindbender1tomjack: 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:20tomjackdunno what you're talking about, I thought cljsc was a shell script
06:21mindbender1*portability
06:22mindbender1I was referring to cljs.compiler
06:27berdarioHi, about the error I stumbled upon yesterday
06:27berdarioI just wrote a message to the clojurescript mailing list
06:28berdarioI reproduced it with my clone of the clojurescript repo, and with the repl sample
06:28berdariohttps://github.com/clojure/clojurescript/tree/master/samples/repl
06:28berdariothe message hasn't been approved yet
06:29berdariobut if there's anyone who has experience with cljs, that can help me understand what is going wrong, I'd appreciate
06:33tomjackmindbender1: ah.. macros are just require'd with require iirc, so no
06:45greywolveis there any way to restart the reload the brepl namespaces without having to completely restart the repl everytime you make code changes?
06:46Eucoohi
06:46mindbender1greywolve: (require *ns* :reload)
06:47berdariomindbender1: are you using clojurescript with a repl in the browser?
06:47Eucoohow do you guys manage long let bindings declaration? is it some kind of bad pattern?
06:47greywolvethanks ill try that ;p
06:47mindbender1berdario: yep
06:48berdariomindbender1: do you know of any common roadblocks? I spent hours trying to get it running, but nothing works
06:48berdariothe only instance in which I got the repl working, is with the lein-cljsbuild advanced sample... but that needs a ring server
06:48greywolveberdario
06:48greywolvewhats the problem?
06:49mindbender1I don't like and I don't use lein-cljsbuild workflow
06:49greywolvethe brepl is pretty simple to setup
06:49berdariothe repl doesn't get connected
06:49berdarioit just stays there... after I opened the page with the code for the connection
06:49greywolvehttps://github.com/magomimmo/modern-cljs
06:49berdarioI try some simple forms... like (+ 1 1) but the repl is completely unresponsive
06:49greywolvetry following those tutorials
06:50mindbender1berdario: you have to refresh the page
06:50greywolvehmm did you add the cljs code to connect to the brepl?
06:50mindbender1so that it hooks into the hung repl
06:50greywolvemindbender1: whats your cljs workflow? i'm still trying to find a good one
06:50berdariomindbender1: I tried to refresh a dozen times
06:50berdariogreywolve: that seems to require ring
06:51greywolveno it doesn't
06:51greywolveyou can use any web server
06:51berdariooh, good
06:51mindbender1cljs1 or more recently pedestal
06:51greywolvebut ring is convenient if you are also building a server side api for your app
06:52greywolvei want to try out pedastal
06:52greywolvemindbender1: do you use the brepl at all?
06:53greywolveberdario you can quickly test using python SimpleHTTPServer aswell
06:53berdarioyes, I usually use python3's http.server
06:53berdariobtw, I just noticed right now that I have a server somewhere stuck on port 8000
06:54mindbender1greywolve: more specifically I try to work with cemerick.piggieback
06:54berdarioI thought I killed all of the server I opened previously... and I have no other shell open
06:54greywolvemake sure your cljs code that connects to the repl, and the brepl server are the same port ;p
06:54greywolvethat could be the prob then
06:54mindbender1it provide a repl-env that plays nicely with nrepl
06:54greywolvemindbender1: i'm using that atm, but :cljs/quit doesn't work for me lol
06:55mindbender1for :cljs/quit to work you have to be able to have evaluated an expression
06:56mindbender1if you're were using nrepl.el with emacs then you could send an interupt to the process
06:57mindbender1I'm not familiar with sending an interrupt outside emacs nrepl
06:57berdariogreywolve: I always used port 9000, that shouldn't be it... I'm compiling the cljs now btw
06:59mindbender1In most cases you just have to keep pushing and tweaking to really be familiar with things
06:59greywolvemindbender1: ah ok, but you can just reload the namespaces and that works for you?
06:59berdariogreywolve: the modern-cljs tutorial doesn't work
06:59berdariosame problem as before
07:00greywolveweird! im doing it right now and its working fine ;p
07:00mindbender1In brepl, you use load-file or load-namespace
07:01berdarioit's really frustrating... I hoped to use cljs instead of resorting to the same old javascript
07:01berdariobut I can't see a way forward, if even the tutorials aren't working
07:01greywolveso 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:01mindbender1yes
07:01greywolveberdario: what os are you on?
07:02greywolvenice... i wish these things were better documented ;p
07:02berdarioubuntu 13.04
07:02finishingmoveI've got this using Compojure: (def app (handler/site app-routes)) . How would I add (handler/api api-routes) to that?
07:02mindbender1load-namespace is documented somewhere
07:02greywolveberdario: push your code to git a repo and ill try it on my side
07:02finishingmovedo i need to do a (def api ...) ?
07:03greywolveyeah "somewhere"
07:03greywolvelol
07:03berdariogreywolve: I'm just using a clone of modern-cljs I just got... no changes whatsoever
07:03greywolveoh dear
07:03greywolvethen it should definitely work
07:03mindbender1https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure
07:03greywolvethanks
07:03greywolve;)
07:04greywolvedoes (js/alert "hello") also hang?
07:04berdariogreywolve: yes
07:05mindbender1https://github.com/clojure/clojurescript/wiki/The-REPL-and-Evaluation-Environments
07:05greywolvealso did you check the network tab in dev tools (in chrome at least) to see if its connecting to the brepl?
07:05berdariogreywolve: uhm, I'm not using brepl, I'm just using the cljsbuild repl
07:06greywolveoh
07:06greywolvethen thats even stranger, that should be a snap to setup ;p
07:07berdariogreywolve: there're 2 requests
07:07berdarioone gets back a 200
07:07berdariothe other is pending
07:07berdariothe pending one, gets back 13 byte
07:07berdariobytes
07:07berdariogosh, now it works
07:08greywolvelol nice
07:11berdariogreywolve: well, thank you... I tried just now in my project, and I've been able to get it working there
07:12greywolveberdario: i didn't do much to help ;p haha glad its working though
07:12berdarioI 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:13berdarioso 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:13finishingmoveI want to be able to send / receive JSON with Compojure. Do I need some external libraries? And what would you recommend
07:14berdariogreywolve: 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:14berdariothere'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:15berdarioand obviously, if I run the repl through node.js, there's no way I can see to access the dom
07:16berdarioso, I'd need to run the repl without having a separate server, other than the cljsbuild repl listener
07:16berdariodo you know of any way to get what I want?
07:16greywolvewhats your overall goal ?
07:16greywolvei mean just in terms of what you are trying to build
07:18berdariosome 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:18berdarioI 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:19berdarioand yet, I could access the disk, save data locally and, etc.etc.
07:19berdarioright now I'm just experimenting around... nothing serious... it's sunday after all :)
07:20berdario(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:21greywolvewow 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:21berdarioyeah, the same... :)
07:22berdariobtw, it's kinda hard to use node-webkit with plain javascript imho
07:22berdariofor example, I started to work with some samples, and apparently the behavior of node-webkit when parsing the package.json changed
07:22greywolvehttps://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:22greywolveplain js is always hard i guess haha ;p
07:23berdariomoreover, 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:24berdarioso 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:24berdariogreywolve: agreed, unfortunately, to contribute to that I'd need to understand clearly how to access the objects that node-webkit makes avaialble
07:25greywolveperhaps that would be good experience for you ;)
07:25berdario(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:26berdarioI wonder if flamefork avoided the repl, and just kept compiling/running to try to see if it works
07:26greywolveis lighttable being developed in plain js or clojurescript?
07:26berdariogreywolve: clojurescript
07:26berdariounfortunately, it isn't open source (not yet at least) afaik
07:26greywolvemaybe ask chris what he thinks then ;p
07:27greywolveyeah the repl really speeds things up, compiling everytime is quite slow
07:28berdariogreywolve: on top of that, you have to package the things inside a .zip to run them in node-webkit
07:28greywolvegeez
07:28berdarioI was planning to add that command to the repl-launch command as soon as I'd got it working
07:28greywolvei like a very rapid feedback cycle
07:38murtaza52tomjack: how do I write this one - java.nio.file.Paths.get("myPath", "subPathA", "subPathB"); - in clojure
07:38murtaza52(.get java.nio.file.Paths "myPath" "subPathA" "subPathB") - this didnt work
07:44berdariomurtaza52: this works, but is ugly as hell
07:44berdario(java.nio.file.Paths/get "myPath" (into-array java.lang.String '("subPathA" "subPathB")))
07:44berdarioyou have to use /get, because it's a static method
07:45berdariothe into-array, is because the rest of the arguments is a vararg
07:45piskettiberdario: Do you explicitly have to use array when the java method takes varargs?
07:46berdariopisketti: it's the first time I stumbled upon a vararg :) I don't know if there's a cleaner way
07:46berdariomaybe 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:46murtaza52berdario: why leave the first arg out, and only apply into-array to the other two args
07:46piskettiHow about just calling them as varargs like you would in Java or in clojure ( & xs)
07:47piskettiIt doesn't work out of the box like that?
07:47berdariomurtaza52: this is the java signature: get(String first, String... more)
07:47berdariothe first argument is required
07:48berdariothis is relevant... but I haven't finished to read it yet https://groups.google.com/forum/?fromgroups#!topic/clojure/ZLIKz3bitoc
07:53murtaza52FileSystems.getDefault().getPath("logs", "access.log"); - how do I translate this to clojure ?
08:11piskettimurtaza52: without testing it, I'd say (.getPath (FileSystems/getDefault) "logs" "accessLog")
08:14murtaza52that works thanks
08:16piskettinp
08:28Okasu,'#=(apply * '#=(range 2 10))
08:28clojurebot#<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
08:28OkasuMeh.
08:28Okasu&'#=(apply * '#=(range 2 10))
08:28lazybotjava.lang.IllegalStateException: clojure.lang.LispReader$ReaderException: EvalReader not allowed when *read-eval* is false.
11:51uris77what is the right way to use apply with reverse?
11:51piranhacemerick: friend doesn't do any salting for passwords, right? Or bcrypt does that by itself?
11:51uris77for example (apply reverse [5 4 3 2 1])
11:51cemerickpiranha: bcrypt salts automatically
11:51uris77that doesn't work. Im a newbie :)
11:51piranhacemerick: ok, thanks
11:52hyPiRionuris77: It's just ##(reverse [5 4 3 2 1])
11:52lazybot⇒ (1 2 3 4 5)
11:53hyPiRionreverse takes a single sequence as input
11:53kmicu## *clojure-version*
11:53hyPiRion&*clojure-version* ;-)
11:53lazybot⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}
11:53hyPiRion,*clojure-version*
11:54clojurebot{:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}
11:54hyPiRionoh, clojurebot is bleeding edge
11:54kmicuvery bleeding
11:54MingqiI'm trying to write a web application use clojure. anybody can suggest a configuration solution in clojure?
11:55borkdudeMingqi take a look at Luminus or Pedestal
11:55hyPiRionMingqi: http://pedestal.io/ is a tool set/configuration for web apps
11:56kmicuIf you are not familiar with clojure stack, pedestal is not a good choice IMHO
11:56MingqiMichiel, thank you. I'm looking...
11:57borkdudeMingqi you looked up my first name? ;)
11:57MingqiYes, I got your full name
11:58hyPiRionOh, you're working for NSA?
11:58borkdudehaha
11:59Mingqiit's very simple. Just click your name and freenode will show your information: Michiel Borkent, London, UK ...etc
11:59Mingqiby the way, i'm using http://webchat.freenode.net/
11:59borkdudeI'm glad NSA thinks I'm in Londen
11:59borkdudeLondon
12:00hyPiRionborkdude: aren't there any Dutch freenode servers?
12:00hyPiRionI vaguely recall you're from there
12:00Mingqiwhich client you are using on Mac, I download a colloquy but doesn't work
12:01borkdudehyPiRion I don't think so, but I actually don't care which server I'm using
12:01borkdudeMingqi Textual
12:01pdkiirc there's a mac port of irssi
12:02borkdudeMingqi if you build it yourself using Xcode it is free
12:02pdki never got why xchat does that too
12:02hyPiRionfair enough. For some strange reason I thought latency would be critical for IRC just now.
12:02pdkthey're like "pay for the official build but you can still compile the same thing for free!"
12:03pdkthen everyone just turns around and uses 3rd party enhanced builds for free anyway
12:04borkdudeMingqi I used to use erc in emacs also
12:05borkdudeone thing that annoys me about Textual: it autojoins channels I visited before, I wonder if I can turn that off
12:05borkdudeI know how to turn off the autojoin, but it should not do it by default
12:08Mingqioh, damn! Textual also doesn't work. I believe it's China government block freenode.
12:10borkdudeMingqi hmm. or you are behind some firewall that blocks the irc port?
12:10borkdudeMingqi if the china government would block freenode, then why don't they block webchat as well
12:11MingqiYes, It's a BIG firewall built by China government, we call it GFW, great fire wall.
12:11borkdudeMingqi funny
12:12Mingqihttp://en.wikipedia.org/wiki/Great_Firewall_of_China
12:16uris77i 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:18borkdudeuris77 is the result of f1 an arg to f2, or do you want to apply f1 and f1 to the same args?
12:19uris77f2 should be applied to the result of (f1 [args])
12:19uris77i thought i could just use apply with any function to do this, but hit a wall with functions like reverse and rest
12:19borkdudeuris77 use comp
12:20uris77oh, nice
12:20uris77thanks alot
12:20borkdudeuris77 or simply write (f2 (f1 [args]))
12:27MingqiHi 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:28Mingqido you other suggestions for that?
12:31clj_newbHi, 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:33kmicu@google clojure debugger
12:34hyPiRion$google clojure debugger
12:34lazybot[Debugging in Clojure? - Stack Overflow] http://stackoverflow.com/questions/2352020/debugging-in-clojure
12:35kmicuSo many prefixes in so many channels.
12:36clj_newbsorry I should have express my question better. I meant more like setting breakpoints and the like, specifically for vim, but thanks anyway
12:38kmicu$google clojure debugging vim
12:38lazybot[dgrnbrg/vim-redl · GitHub] https://github.com/dgrnbrg/vim-redl
12:39kmicu"This plugin integrates Vim with a running Clojure JVM. It provides a repl that supports breakpoints..."
12:40clj_newbI 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:44cemerickOK, 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:45cemerickthe lib in question is http://davidbau.com/encode/seedrandom.js FWIW
14:11DenommusHi
14:20seancorfieldHi Denommus
14:20seancorfield(just to prove there are some live folks here on a quiet sunday)
14:21DenommusToday I may start writing about COA
14:55seancorfieldCOA?
15:05kmicuProbably CoA - clj on android
15:08jouiswalkeris there a way to specify that lein should just grab the latest release of a library?
15:11kmicuLATEST
15:12maio`my first clojar https://clojars.org/fun_migrations :)
15:12maio`what's the "promote" button @ clojars?
15:13kmicujouiswalker: but you should read http://nelsonmorris.net/2012/07/31/do-not-use-version-ranges-in-project-clj.html
15:14jouiswalkerkmicu: thats really helpful. thanks!
15:18borkdudeI read that in C you can mark a function 'pure' so the compiler can optimize. Is there any such thing in Clojure?
15:18borkdude(I guess not)
15:20xeqimaio`: 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:21xeqiit should become automatic eventually
15:21amalloyno, but clojure's functions are much more powerful. if you want to avoid repeated calls to a function, just memoize it
15:21jouiswalkerborkdude: I didnt know you could do that in c o_o
15:21borkdudeamalloy I guess in Haskell such a thing is going on a lot, without having to memoize anything
15:22amalloyjouiswalker: it's not in the standard, it's an extension that some compilers add
15:22amalloywell, in haskell every function is pure, so the hinting is implicit
15:25maio`xeqi: ok thanks
15:32jouiswalkerwow, this is really cool:
15:32jouiswalkerhttp://nakkaya.com/2011/01/04/duck-hunt-experiment/
16:37tomjackconsider a type where equality is decidable, but may take arbitrarily long to compute, regardless of the input 'size'. value or not? :)
16:38tomjackseems we want not just decidable equality but efficient equality..
16:39gfredericksare we talking about comparing functions again?
16:40tomjacknot functions, since that's undecidable. my point is that 'decidable equality' may not be enough
16:40gfredericksbecause it might be unbounded
16:41gfredericksI can imagine regexes being tough to compare :)
16:41tomjackthat makes me wonder if there is an Eq instance for (->) t with some finiteness constraint on t
16:42tomjackapparently it's decidable for true regular expressions?
16:42gfredericksright
16:42gfredericksalways have to distinguish CS regexes from real-world regexes :)
16:45gfredericksthe most remarkable thing I know about PRE's is that you can efficiently index all matching strings
16:45laliluna2
16:46tomjackpresumably the logarithm of the regular expression type is a character?
16:55hyPiRiongfredericks: what do you mean by efficiently? :p
16:55hyPiRionin terms of space or storage?
16:57gfredericksyou could efficiently in every practical sense implement something such as (nth #"foo(bar|baz{3,4})*bar" 999999999999999)
16:57gfredericksassuming the regex there is a PRE
16:58hyPiRiongfredericks: isn't that multibranching?
16:58gfrederickshyPiRion: I have no idea what that means
16:58hyPiRiongfredericks: there are multiple solutions to that answer
16:58hyPiRiondo you want one or all of them?
16:59gfredericksno there's one answer
16:59hyPiRionhuh. Then I'm not sure if I get what that indexing is.
16:59gfredericksI'm saying there's an ordering of all the distinct matches to that regex that is also efficiently indexable both ways
16:59gfredericksthe nth given up there can be implemented as well as its inverse
16:59hyPiRionah alright
17:00hyPiRionyeah, that makes sense
17:00gfredericksrelatedly, given a regex I can return an (infinite?) lazy seq of all distinct matches
17:00gfrederickshttps://github.com/fredericksgary/ranguages/blob/master/src/ranguages/counting.clj#L104
17:01hyPiRiongfredericks: now do it with shared structure
17:01gfrederickshaha
17:01hyPiRiongfredericks: oh right, you're a core.logic guy. How come (run* [q] (== q #{1 2})) completely blows my stack?
17:02gfredericksI don't think it oughta
17:02gfredericksunless sets are forbidden
17:02gfredericksthey must be :)
17:03gfredericksI don't know that they're explicitely supported
17:03hyPiRionwahh, there goes my idea
17:03hyPiRionOh well
17:03gfrederickshaha
17:03gfredericksmy expectation is that there's no obvious way to naively support them fully, same with maps
17:04hyPiRionOh right
17:04gfredericksunbound tails and all that
17:04hyPiRion(fresh [x y] #{x y})
17:04gfredericksI think there's been work on maps but haven't been following it
17:04hyPiRionWell
17:05hyPiRionthat implies (!= x y)
17:05gfredericksoh that's an interesting point as well
17:05tomjackCLP(Set) isn't implemented
17:05tomjacksets no longer implement even IWalkTerm
17:06hyPiRionI 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:07hyPiRionInteresting that different data structures actually gives an implicit constraint on the lvars
17:07gfredericksmembero is terrible for perf
17:07gfredericksat least if your collection is ground
17:08hyPiRiongfredericks: so e.g. (membero x [1 2 3]) is horrible perf-wise?
17:08gfredericksexactly
17:08gfredericksthat by itself might be okay
17:09gfredericksbut e.g., if you did that to 20 vars you'd be out of memory
17:09hyPiRionoh no
17:09hyPiRionthat totally destroys my idea
17:09gfredericksdon't worry! there is a solution!
17:10hyPiRionoh, what is this solution you're talking about?
17:10gfrederickshttps://www.refheap.com/15830
17:11tomjacksweet
17:11tomjackI have a ground coll that is the signature of my language and memberos all over the place
17:12hyPiRionoh great, now I'll happily use that because I have no idea why membero is slow and why that is faster
17:12gfredericksmembero is slow because it uses conde
17:12gfrederickswhich does interleaving
17:12hyPiRionoh right, I see
17:12gfrederickswhich is not necessary when the clauses are short and finite, like unifying with a ground value
17:12gfredericksso e.g., if you (membero x1 [1 2]) ... (membero x20 [1 2])
17:12gfredericksthen you effectively have a binary tree of depth 20
17:13gfredericksand conde will helpfully search the whole thing in parallel
17:13gfredericksbefore finding a single solution
17:13futilehappy father's day to anyone relevant
17:13gfrederickshappy belated fathers day to anyone relevant in the eastern hemisphere
17:15hyPiRionHumm. So in https://www.refheap.com/15831, would my horribly-named `compatiblo` be slow?
17:15hyPiRionAnd yeah, it's not efficient compared to another solution I'm keen on writing right after this
17:15tomjackyou can't use == on sets
17:15tomjackI think?
17:15hyPiRiontomjack: Well, it works perfectly fine over here!
17:16gfrederickswell if t1 and t2 are both non-ground...
17:16hyPiRionAll the sets are ground anyway, so could I replace it with something else?
17:16hyPiRiongfredericks: yeah, they're both non-ground
17:16gfrederickshyPiRion: yeah if p1 and p2 are sets and not logic vars you could (if ... s# u#) or something like that
17:17hyPiRionOh, okay, I'll have to read up on that I suppose
17:17gfredericksI'm confusing myself trying to reason about when it's okay to skip conde
17:17gfredericksso I'm going to stop
17:17futileso apparently The Incredible Machine relied heavily on the CPU's own speed
17:17futileso, playing it now in dosbox, it runs ridiculously too quick
17:18futileoh wait that's not related to Clojure
17:18futilesorry
17:19tomjackoh, == will just fallback to = if it doesn't know how to deal with something?
17:19hyPiRiongfredericks: well, I'll read up on it anyway
17:20gfrederickshyPiRion: if you watch the youtube of the last hangout it'll all get gone over in detail :)
17:20hyPiRionOh, awesome
17:21tomjackah yes https://www.refheap.com/86578ea53616bd29063e8a914
17:22gfrederickstomjack: huh weird; so (fresh [x] (== x (Object.))) always fails?
17:22gfredericksor wait I mean the other way around?
17:22gfrederickstime to test it
17:23gfrederickshrm no both succeed
17:23gfredericksthat I don't understand
17:23gfredericksoh unless that code you pasted doesn't run if either arg to == is an lvar
17:24tomjackseems relevant https://www.refheap.com/90aa9118ff169b3ebfdf257ac
17:24tomjackit will do the lvar unify-terms instead I guess, which causes a substitution?
17:24gfredericksright
17:31hyPiRiongfredericks: so what could I replace (== #{} ground-set) with? I naively tried (= ...), but it seems like it want a fn
17:31hyPiRion(And I'm a bit tired to dig more into core.logic right now so I just lazily ask you)
17:33gfrederickshyPiRion: (if (= #{} ground-set) s# u#)?
17:33tomjackwhy replace it?
17:33gfredericksgood point I guess tomjack just proved it should work
17:33gfredericksif by "ground set" you mean "an actual set" rather than an lvar with a value
17:34tomjackshould work even with an lvar, yes?
17:34hyPiRiongfredericks: a set with ground values
17:34hyPiRionwell yeah
17:35hyPiRionworks for me!
17:35gfredericksthen I won't bother figuring out what you meant :)
17:35tomjackhmm, wait, what?
17:35tomjackhttps://www.refheap.com/5550cbeb9859316c1819ca13b
17:36hyPiRiontomjack: oh yeah, I did that too
17:36hyPiRiondnolen said in #minikanren that he removed support for sets completely
17:36tomjackthis was why I thought "you can't use == on sets"
17:36tomjackbut I don't understand now why it doesn't work
17:36gfredericksI'm guessing you can (== aset anotherset) but not (== an-lvar a-set)
17:37hyPiRiontomjack: well, I'm not doing any unification at all, I'm essentially comparing two sets
17:37tomjackgfredericks: that appears to be the case
17:37hyPiRiontwo sets without any lvars in them
17:37gfredericksshould be fine then
17:37gfredericksit's just regular =
17:38tomjackI see, sets are tree terms
17:38tomjackand walk is identity on sets
17:38tomjackso walk* blows the stack..
17:39tomjackwonder if there should be a check there whether walk actually did anything
17:40tomjackno, I guess we'd just need an IWalkTerm for sets
17:40gfrederickstree term is some flag protocol?
17:40tomjackyes, but also all coll? are tree terms
17:41gfredericksah ha
17:45tomjackplease someone do CLP(Set) :)
17:49gfredericksif I attempted anything it'd probably be CLP(Q)
17:50gfredericksbut I'm a little worried about that drop-one function
17:50weavejesterJust released Ring 1.2.0-RC1
17:51weavejesterNext Ring version is going to have a much shorter development cycle :/
17:51gfredericks3
17:51akhudekweavejester: why the :/ ?
17:51weavejesterakhudek: Because I just checked when I released Ring 1.1.0 :)
17:53cemerickweavejester: 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:55weavejestercemerick: Doesn't Friend already depend on the 1.2.0 beta?
18:05hyPiRionweavejester: you've been on fire recently, props to that
18:20akhudekhmm, https://clojars.org/zip-visit what went wrong?
18:22akhudekwell, lein deps :verify works
18:29tomjackhmm, should IEnforceableConstraint not be empty/
18:29tomjackonce we've no longer "hard coded force-ans"
18:39tomjackseems like the ckanren way is to run all defined enforce fns
18:43tomjackdirect 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:43tomjackwhich seems.. weird
18:46ianeslickAnyone 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:46ianeslickI'm writing something like this; but wanted to make sure I'm not re-hashing old work.
18:47ianeslickThe 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:49ianeslickHierarchy: 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:50ianeslickOnly 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:27murtaza52I have a fn which is returning a lazy seq, and something is causing it throw away the first element
21:27murtaza52I just dont understand whats happening ?
21:27gfredericksme neither
21:29murtaza52what code is troubling you ?
21:29gfredericksyours
21:29murtaza52:)
21:29gfredericksbut you haven't told me much more about it so there's not much I can do about it :)
21:31gfredericksperhaps you could share your code?
21:31murtaza52yup posting the url - just a sec
21:31murtaza52https://github.com/murtaza52/clj-nio2/blob/master/src/nio2/watch.clj
21:32murtaza52The watch-seq fn at the end is giving trouble
21:33murtaza52its suppose to watch over a dir, and report any change events - like file creation, modification, deletion
21:33murtaza52it just doesnt report the first event immediately. It reports it along with the second
21:34gfredericksside note, apply concat can probably replace your flatten
21:34gfredericks~flatten
21:34clojurebotflatten 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:35gfredericksmurtaza52: so your issue is not that the return value is incorrect, just that it's not timed the way you would expect?
21:36murtaza52yup
21:36murtaza52here is a gist of using it in an repl - https://gist.github.com/murtaza52/5794159
21:36murtaza52so once this code is run, it basically blocks
21:37gfrederickswell I'm curious if maybe flatten was the actual issue
21:37murtaza52and then prints whenever an event happens
21:37murtaza52why would that be so ?
21:37gfredericksit might interact more strangely with laziness; it's too complicated for me to guess at
21:38gfrederickstry apply concat and see if that helps
21:38murtaza52yes it could be, I think it most probably is, bcoz it was working correct before
21:41gfredericksfascinating
21:41gfredericks(dec flatten)
21:41lazybot⇒ -1
21:41murtaza52apply concat also gives same behaviour
21:41murtaza52what is dec flatten
21:41gfredericksthat was just me publicly criticizing flatten
21:42murtaza52oh ok :) newbie to irc
21:44gfredericksI have no further guesses
21:45murtaza52it 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:45gfrederickso_O that's curious
21:46gfredericks,(take 3 (concat [1 2 3] (lazy-seq (Thread/sleep 3000))))
21:46clojurebot(1 2 3)
21:46gfredericksconcat you ain't so lazy is you
21:47gfredericks,(take 3 (concat [1 2 3] (lazy-seq (Thread/sleep 3000))))
21:47clojurebot(1 2 3)
21:47gfredericksoh nevermind
21:47gfredericksfalse goose herring
21:47gfrederickschase
21:48murtaza52do I have any other ways to flatten a seq
21:48murtaza52(apply identity [:as])
21:49murtaza52(apply identity [:as :b]) - an identity that will also work for a seq
21:49gfredericksI know of no reason why concat should have this effect
21:49murtaza52bcoz its a lazy seq concatenated to a lazy seq
21:50gfrederickssure but concat should not realize the second lazy seq at all until you need that part
21:50gfredericksand the test I did above confirms that it seems to be working properly
21:50murtaza52u know one curious thing I noticed - if I used flatten two times, e evaled the fn and then concat it to the whole,
21:50murtaza52then my timing was off by two events
21:51murtaza52so the more lazy constructs I am using the more the timing is getting off !!
21:51gfredericks,(take 3 (flatten [[1 2 3] (lazy-seq (Thread/sleep 9000))]))
21:51clojurebot(1 2 3)
21:51gfredericks^ suggests flatten works fine too
21:52VFeCurious if anyone understands why this is, I have a simple luminous web-app, configured with friend. and a relatively simple route (GET "/account" []
21:52VFe (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:54callenVFe: do you really need the full workflow stuff of Friend, or are you just doing the essentials of web app auth?
21:55VFeThis is just a side project for learning, not really for anything serious.
21:56murtaza52gfedricks: (flatten [(read-events ws) (repeatedly #(read-events ws))])
21:56callenVFe: https://github.com/bitemyapp/neubite/blob/master/src/neubite/middleware.clj https://github.com/bitemyapp/neubite/blob/master/src/neubite/routes/admin.clj
21:56callenVFe: using tools you don't understand will get you into trouble in a hurry.
21:56murtaza52gfredericks: the above one returns the first event immediately, but then clubs the second and third one
21:57murtaza52so its the use of flatten with repeatedly
21:58gfredericks,(take 3 (flatten [[1 2 3] (repeatedly #(Thread/sleep 10000))]))
21:58clojurebot(1 2 3)
21:58gfredericksrepeatedly is pretty innocent
21:59VFeAye, 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:59tomjack&(time (doall (take 3 (flatten (repeatedly #(do (Thread/sleep 1000) [:foo]))))))
21:59lazybot⇒ "Elapsed time: 4011.374677 msecs" (:foo :foo :foo)
22:00tomjackdoes that make sense?
22:00murtaza52nope sorry :)
22:00gfredericksoh hm
22:00tomjack&(time (doall (take 3 (repeatedly #(do (Thread/sleep 1000) [:foo])))))
22:00lazybot⇒ "Elapsed time: 3010.309 msecs" ([:foo] [:foo] [:foo])
22:00ddellacostahmm, all of a sudden clojurescript 1830 complaints in project…anyone know what the scoop is?
22:01gfredericks&(time (doall (take 3 (apply concat (repeatedly #(do (Thread/sleep 1000) [:foo]))))))
22:01lazybot⇒ "Elapsed time: 4012.558563 msecs" (:foo :foo :foo)
22:01tomjackddellacosta: are you writing a macro? did you print something during macroexpansion? that's my only guess
22:02gfredericksmurtaza52: 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:02ddellacostatomjack: 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:02tomjackno clue then
22:02murtaza52gfredericks: sorry I am missing the point
22:02ddellacostathought maybe I missed something, but poking around on the CLJS mailing list yields no clues
22:02ddellacostahmm
22:03gfredericksmurtaza52: the timings of ~4000ms should ideally be ~3000ms
22:03ddellacostamust be some dependent library being sneaky
22:03gfredericksi.e., it's realizing one step too far
22:03murtaza52how so, its returning only 3 values ?
22:03ddellacostaI miss lein pedantic's stern but loving touch
22:04gfredericksmurtaza52: I don't know _why_ it's doing it, I just know that it _is_, due to the fact that it took 4000ms
22:05gfredericksmurtaza52: i.e., this seems to be the same issue you're dealing with
22:05gfredericksand I can now investigate it without having to go through you
22:05gfredericksif tomjack knows what's up I'd be terribly interested
22:06murtaza52yup it makes sense
22:07murtaza52I will be away for 20 mins, so please ping me if anything comes up
22:07ddellacostanevermind, looks like it was my fault for using piggieback 0.0.5-SNAPSHOT.
22:09gfredericksthis is getting much weirder
22:09gfredericks&(time (doall (take 1 (apply concat (repeatedly #(do (Thread/sleep 1000) [:foo]))))))
22:09lazybot⇒ "Elapsed time: 4012.168009 msecs" (:foo)
22:09gfredericks^ (noting the `take 1`)
22:09tomjack:)
22:11tomjackI guess apply concat will always realize 4 things
22:11tomjack[x y & zs] gives two
22:11gfredericksI've been staring at the concat code and have no idea why that would be the case
22:11gfredericksoh hm
22:12tomjackyeah I dunno either
22:12gfredericksso it has to walk the arg seq to know which clause of concat to execute
22:12tomjackif you look at the stack inside the repeatedly fn it goes back to RT.boundedLength
22:12tomjackdunno if that's relevant
22:12tomjackcan't tell what the bound is
22:13gfredericks&(time (doall (take 1 (reduce concat (repeatedly #(do (Thread/sleep 1000) [:foo]))))))
22:13tomjackyeah I guess it makes sense
22:13lazybotExecution Timed Out!
22:13gfredericksoh
22:13gfredericksyes of course that would not work
22:14tomjackI think it's that (next zs)
22:14gfredericksbut it's all inside the lazy-seq thunk
22:14gfredericksI guess that doesn't matter
22:15tomjackhmm, yeah, I don't get it
22:15gfredericksinteresting. okay so anyhow the solution ought to be a replacement for apply concat
22:15tomjackI think if this is a problem, you're probably doing something wrong :)
22:16gfredericksreally? You're getting a lazy seq of groups of things and want to flatten that lazily?
22:16gfredericksseems reasonable to me
22:16tomjackif you care about whether one or two extra things are realized I mean
22:16tomjackit shouldn't matter
22:17gfredericksin the case of listening for events though
22:17gfredericksyou think using lazy seqs at all is bad?
22:17gfredericks(for that use)
22:18tomjackI don't understand the watch.clj code really
22:18tomjackbut apparently it's bad, because this is a problem :)
22:19tomjacklooks like it's lazy IO basically? yeah, bad
22:20gfredericksthis 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:20tomjackthat seems odd
22:20gfredericksin any case this seems to fix it: (defn concats [s] (lazy-seq (concat (first s) (concats (rest s)))))
22:21tomjacklazy seqs are pull-based, 'external events' suggests push
22:21gfredericksmurtaza52: ^, modulo tomjack's higher level criticisms
22:21gfrederickstomjack: so it only makes sense if the "pull" doesn't block prohibitively?
22:22tomjackwell it could still make sense that way
22:22gfredericksI think this is a pull
22:22tomjackas 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:23gfredericksand 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:24tomjackhmm
22:24tomjacks/well it could still make sense that way//
22:25gfredericksokay. so the lesson is don't use lazy seqs when you're dependent on clojure.core being maximally lazy
22:25tomjackmy opinion is probably worthless, I have developed the view that lazy seqs are fundamentally broken
22:26tomjackthe cases where you don't notice that they're broken are the cases where it's OK to use them :)
22:26gfredericksha
22:32gfredericksadmittedly there are two levels of laziness going on here
22:32gfredericksI think concat does fine with not realizing anything extra within the seqs you pass it
22:32gfredericksit's the fact that he's relying on the arg list itself being lazy that concat didn't expect
22:32gfredericksI think the signature of concat is maybe weird
22:32tomjackyeah, in retrospect it's not surprising
22:32gfredericksor at least the alternative should exist
22:32gfredericksI bet the majority of my uses of concat are with apply
22:32tomjackdunno what it would even mean for apply to be lazy in the seq
22:32gfredericksyeah that's not really feasible
22:32gfredericksbut concat doesn't have to be written variadically
22:32gfredericksand I think this illustrates that a non-variadic version (like the one I pasted above) could be valuable
22:32dnolenddellacosta: hmm, I just tried 1820 in a project everything seems fine here
22:33ddellacostadnolen: 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:33dnolenddellacosta: you must mean 1820?
22:33AlexEHi all - I'm having a weird problem in emacs paredit where typing a "(" adds an extra space in front of the opening parens
22:34ddellacostadnolen: 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:34AlexEIs anyone else seeing this? I causes problems for reader functions like: # ()
22:35gfredericksAlexE: not I
22:35cemerickddellacosta: whoops; that's a build on my local machine :-/
22:36cemerickSome vars in the cljs analyzer changed on master, which that snapshot is tracking.
22:36ddellacostacemerick: 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:36AlexEgfredericks - thanks, so you don't get an extra space in front when using paredit.el?
22:36gfredericksAlexE: nope, I've never seen that
22:36ddellacostagotcha
22:36gfredericksI'm probably not up-to-date though
22:37tomjackgfredericks: incidentally, concats is join, huh? :)
22:37AlexEhmm - it's definitely a paredit thing because disabling the mode solves the problem… but that's a very inefficient :-/
22:37gfrederickstomjack: is that a haskell name?
22:37AlexE...workaround
22:38tomjackyeah
22:38gfredericksI guess it is then
22:38gfredericksI would have guessed haskell just had a one-arg function called `concat`
22:38gfredericksbut you'd probably know better than me
22:39tomjackit has that too for lists
22:39gfredericksoh join is on a typeclass?
22:39gfredericksmonoids?
22:40gfredericksthis is monads isn't it
22:40gfredericksI've never had the names of the monadic functions too solidly in my head
22:40tomjackyeah
22:40gfredericksin 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:41tomjackif you read about monads outside haskell usually they're formulated in terms of join
22:41gfredericksno wai
22:41gfrederickst
22:41gfredericksthe core.logic word I'm thinking of is bind I think
22:41tomjackbind is the.. other.. way :)
22:43tomjackI always felt a little weird about #(apply concat %1)
22:43gfredericksis this worth proposing on clojure-dev?
22:43tomjack#(mapcat identity %) would be a suitable concats, yes?
22:44gfredericksmapcat uses apply concat
22:44tomjack:'(
22:46tomjack&(first (mapcat (constantly [:foo]) (repeatedly #(println "foo"))))
22:46lazybot⇒ foo foo foo foo :foo
22:46tomjackdelightful
22:46gfredericks:)
22:48tomjackso with a recursive mapcat thingy might you end up looking further and further ahead?
22:49tomjackor is the over-eagerness bounded at least
22:49tomjackI say 'thingy' because I have no idea what I'm talking about
22:52gfrederickstomjack: you mean the current impl of mapcat?
22:52gfredericksshould just be 4 args
22:54tomjackyeah I'm wondering if you can get yourself into situations where you're 4 elems too eager, then 8, then ...
22:55gfredericksokay so you're talking about a hypothetical different impl of mapcat?
22:55tomjackno a hypothetical use of current mapcat
22:55gfredericksunless you're calling it more than once somehow...
22:55gfrederickswhich I guess is what you meant by "recursive"
22:56tomjackyeah, though I really have no clue what that hypothetical use might be
22:57tomjackjust seems like a potential eagerness-leak waiting to happen
22:57cemerickdnolen: 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:57dnolencemerick: feel free open enhancement tickets for stuff you have in mind
22:57gfrederickstomjack: 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:58dnolencemerick: 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:58cemerickdnolen: you mean re: reflect stuff?
22:58dnolencemerick: yes
23:00cemerickdnolen: 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:00murtaza52tomjack:, gfredericks: great analysis. so maybe its not working bcoz concat is expecting two realized elements, while one is lazy and blocking.
23:01gfredericksmurtaza52: yeah, did you see my impl of `concats`?
23:01dnolencemerick: I don't see why this matters if all the calls are forced to sync
23:01dnolenforced to be sync
23:01dnolensync call to browser, sync call to server, return value to REPL
23:01murtaza52however 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:01murtaza52no let me try that.
23:02dnolencemerick: again, I don't know for sure, I'm just curious why this issue doesn't affect the normal REPL
23:02cemerickdnolen: perhaps; I don't know the goog xhr/channel APIs at all.
23:02gfredericksmurtaza52: apply concat realizes 4 arguments when you first force it, so I guess (apply concat [] [] [] [] ...) would work
23:02dnolencemerick: I do recall the reflect stuff uses xhr instead of the CrossPageChannel
23:03cemerickdnolen: because the browser-repl is enforcing response ordering on the channel
23:03dnolencemerick: xhr can be forced to be sync
23:03murtaza52why is that so, why 4 elements
23:03dnolencemerick: in anycase, it's an enhancement not a big deal
23:03dnolencemerick: just wondering if you dug into much, but it sounds like not - no problem
23:03cemericki.e. all the add-in-order business through an agent, etc
23:03gfredericksmurtaza52: eh, it's details; anyhow I just tested it and you can't escape one extra realization by simply adding more args
23:03dnolencemerick: k
23:04gfredericksmurtaza52: but my concats should solve it for you
23:04cemerickdnolen: 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:04murtaza52concats
23:04tomjackgfredericks: join is not good because it's taken by clojure.string/join?
23:04gfrederickstomjack: or just suggests that
23:05dnolencemerick: likely
23:05gfredericks_or_ suggests monads
23:05gfredericksI'm not 100% opposed. maybe it's good.
23:05dnolencemerick: thanks much for this anway, can't wait to see this stuff get hooked up to tools
23:07cemerickdnolen: 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:07cemerickdnolen: yeah, been using it for a long time myself. Invaluable IMO. Always-instant cljs REPL, etc.
23:07dnolencemerick: like just special forms for everything?
23:09murtaza52gfredericks: it works ! however now I dont know why it works !
23:09murtaza52why did it solve the problem :)
23:10cemerickdnolen: 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:10dnolencemerick: hum, I don't have strong opinions about it and you're messing around with this stuff a bit more.
23:11dnolencemerick: it just seemed like it would make tooling more awkard not having these things be first class - but perhaps the concern was misplaced.
23:12cemerickdnolen: I'm actually a bit behind what technomancy and co. are doing.
23:13cemerickThe 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:13tomjack&(apply (fn [x y & zs]) (repeatedly 100 #(println "foo")))
23:13lazybot⇒ foo foo foo foo nil
23:13tomjackmurtaza52: ^
23:13tomjackin other words, it's just a quirk of (apply concat ..)
23:14cemerickAll these things are why Dr. Racket and Lispworks are awesome, in addition to textual REPLs.
23:14cemerickdnolen: Anyway, once the patch makes it through safely, I'll see what I can do about making reflect stuff synchronous.
23:15gfrederickstomjack: murtaza52: http://dev.clojure.org/jira/browse/CLJ-1218
23:15dnolencemerick: k
23:15murtaza52in the above example, shouldnt it print it 100 times ?
23:15gfredericksmurtaza52: no because repeatedly is lazy
23:15dnolencemerick: in other news, your core.match bugs are getting crushed
23:15tomjackone might argue that it should print 0 times
23:15dnolenvery quickly
23:15gfredericksbut the function signature forces several realizations
23:16tomjack(well, 0 times wouldn't make sense in clojure, but..)
23:16cemerickdnolen: 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:16tomjackI still don't understand why it's 4 though
23:16dnolencemerick: heh, yeah it needed 15 hours of focused hacking to get out of the bog
23:16cemerickdnolen: I thought match had gotten passé for you? :-P
23:17dnolencemerick: 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:17dnolentwo years ago
23:18tomjackgfredericks: 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:18cemerickdnolen: heh, so your "fixed" comment was just you adding a testcase verifying the fix you actually made however long ago? :-)
23:18gfredericksyeah that wouldn't bother me too much
23:19gfrederickstomjack: in any case, I'm headed off. Thanks for learning me a clojure.
23:19murtaza52so its apply that causes a lazy seq to realize 4 times
23:19gfredericks...sorta
23:20gfredericksnot that apply could really do anything different
23:20tomjack&(apply (fn [x y z w v & us]) (repeatedly 100 #(println "foo")))
23:20lazybot⇒ foo foo foo foo foo foo foo nil
23:20dnolencemerick: heh yeah the "fix" wasn't really one thing, a lot of refactoring and simplifying
23:21murtaza52it realizes it the number of times its needs args, thats why the non vaiadic version works
23:21murtaza52I mean the times the fn needs args
23:22dnolenone nice outcome is that seq pattern matching can be salvaged
23:22dnolenwas going to give it the boot, but now it an vector matching can peacefully coexist
23:26cemerickdnolen: with all the same notation, etc?
23:27dnolencemerick: it just works, no backtracking weirdness
23:27cemericksweet
23:27dnolencemerick: however vector patterns still only work on *vectors*
23:27cemericksounds fine to me
23:27murtaza52gfredericks: so shouldnt this also realize just 4 elements
23:27murtaza52,(apply concat (repeat [:a]))
23:27clojurebot(:a :a :a :a :a ...)
23:27cemerickdnolen: sorry, wasn't meaning to be coy w/ 521 :-P
23:28dnolencemerick: 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:29cemerickdnolen: didn't think it was possible efficiently? I mean, once you're matching seqs generally, the general case is linear time, yes?
23:30dnolencemerick: it's not possible efficiently, but given a culture of destructuring seqs I'm not sure it matters much :P
23:30murtaza52tomjack: 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:30murtaza52(defn concats [s](lazy-seq (concat (first s) (concats (rest s)))))
23:30dnolencemerick: again it's not something I fully decided something to stew on
23:31cemericksure
23:31ddellacostadnolen, 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:31tomjackmurtaza52: in that case the first element of (concats foo) can be gotten from (first foo)
23:31cemerickddellacosta: clarify those pain points, please?
23:31tomjackconcats and rest are both lazy so..
23:32tomjackand (concat x y) won't realize y until necessary
23:32tomjackit's just (apply concat foo) that's a bit funny
23:33murtaza52so it will return (concat x []) or x, as y is not realized ?
23:33ddellacostacemerick: 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:35ddellacostacemerick: 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:35tomjack&(take 3 (concat (lazy-seq (println "foo") [1 2 3]) (lazy-seq (println "bar") [4 5 6])))
23:35lazybot⇒ (foo1 2 3)
23:35tomjack&(take 4 (concat (lazy-seq (println "foo") [1 2 3]) (lazy-seq (println "bar") [4 5 6])))
23:35lazybot⇒ (foo1 2 bar3 4)
23:35ddellacostaanyways, that's my wishlist…heh.
23:36cemerickddellacosta: 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:36cemericks/easier/more reliable
23:36cemerickwell, and easier, too :-P
23:37dnolencemerick: sounds awesome, will take a look soon, just want to wrap up a few more core.match things
23:37ddellacostacemerick: 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:37cemerickdnolen: sorry, wasn't trying to rush you :-)
23:38cemerickddellacosta: That's more clojurescript.test than piggieback or the REPL, I think: https://github.com/cemerick/clojurescript.test
23:39cemerickI 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:40ddellacostacemerick: 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:41murtaza52tomjack: gfredericks: thanks !
23:41ddellacostaI 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:41cemerickddellacosta: 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:42ddellacostacemerick: 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:43ddellacostacemerick: and so I'll start up a piggieback session, and load up a copy with the browser/repl connect code compiled in
23:43ddellacostaand it can be hit-or-miss.
23:43ddellacostaand in general it's just a pain to reload the code and have to re-set-up the cljs/repl connection
23:44cemerickoh, so you're still connecting at load time, etc
23:44ddellacostayeah, I mean, I have this kind of hack-y flow worked out
23:45cemerickI'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:45ddellacosta1) 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:45cemerickhrm
23:46cemerickddellacosta: any chance you're attempting to run multiple browser-repl sessions from a single Clojure runtime?
23:47ddellacostacemerick: 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:49ddellacostastarted 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:50cemerickI'm afraid to speculate, as my memory is a bit hazy about the failure modes at the moment. :-|
23:50cemerickddellacosta: 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:51ddellacostahaha, 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:51cemerickddellacosta: oftentimes, neither do I ;-P
23:51ddellacostahaha
23:52ddellacostawell, I'll read through your browser REPL code and see what I can learn.
23:54cemerickI 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:55callenseancorfield: so have you just not needed to-sql-time yet or what?
23:55ddellacostacemerick: 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:55callenseancorfield: you're importing java.sql.Timestamp, is there some problem I should be aware of?
23:55ddellacostanamespace -> environment I should say
23:56cemerickThe 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:56cemerickThat's mostly political though, not technical.
23:56ddellacostaah. Yeah, I stumble on namespace issues a lot in the cljs REPL
23:57callencemerick: I make an excellent Political Commissar for ensuring the comrades stick to the party line.
23:57callencemerick: I can provide my forged letters of recommendation from university if you like.
23:57cemerickddellacosta: like, an actual Plugin, i.e. rev up a jvm and such?
23:58callenalexbaranosky1: is there some documentation on dates/times and Korma that exists but I haven't discovered/
23:58ddellacostacemerick: 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:58cemerickcallen: I think perhaps a softer touch is called for. ;-P
23:59cemerickddellacosta: sounds a bit crazy :-) I think using the self-hosting cljs fork is probably more realistic.
23:59callencemerick: is good. I can strangle with velvet just as well as rope.
23:59callencemerick: maybe even give vodka before.
23:59cemerickddellacosta: Which perhaps isn't saying much?
23:59ddellacostacemerick: yeah, perhaps too much…heh. ;-)