#clojure logs

2012-09-28

00:00uvtcshachaf: "Y'all're". Nice. :)
00:03SrPxshachaf: the x is a free variable on (fn [x] x)
00:03TimMcuvtc: "shouldn't've" is also nice
00:05uvtcTimMc: Oh, yes,. One of my personal faves. :)
00:05cjfriszSrPx: x is not free in (fn [x] x) because x is in the argument list of (fn [x] x)
00:05cjfriszSrPx: But x *is* free in (fn [y] x) because it *doesn't* appear in the argument list and is referred to in the body of the function
00:06SrPxIn mathematics, and in other disciplines involving formal languages, including mathematical logic and computer science, a free variable is a notation that specifies places in an expression where substitution may take place.
00:06SrPxo.o
00:06SrPxOh they have a different definition for CS
00:07SrPxSo x there is a free variable. Clojure looks that variable on the ns or in the next parent function?
00:08SrPx,(def x 4) (let [x 5] (fn [y] x))
00:08clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
00:08SrPx,(def x 4)
00:08clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
00:08eggsbySrPx: if you want the counter example: https://www.refheap.com/paste/5349
00:08SrPxoh
00:09cjfriszSrPx: It tries to find a value for x in the closest enclosing scope until it find a value
00:09cjfriszSo in your example, x in the body of (fn [y] x) will have the value 5 because x was bound in the scope of the let expression
00:10Sgeo_Grah, I hate having to think for two seconds about whether something that looks recursive like that is problematic in Cloure or not
00:10cjfriszIf x was not bound in the let, say if you used (let [z 5] (fn [y] x)), then x would have the value 4
00:10cjfriszBecause it would search each enclosing scope until it got to the outer environment (the ns, as you say) and find the value of 4 for x
00:11SrPxSo wait Clojure's scope is based on the ()'s?
00:11SrPx(this is a scope (this is another (and another)))
00:11cjfriszAs shachaf said, it's all about understanding free variables and lexical scope
00:11UrthwhyteI'm porting this code: https://gist.github.com/3140941 over to clojure as a learning exercise, am I confused as the best way to model it would be in clojure
00:12cjfriszSrPx: exactly
00:12Sgeo_cjfrisz, wait what?
00:12UrthwhyteI suppose instead of objects I should be using records?
00:12cjfriszSrPx: Scope is determined by the nesting of parentheses
00:14SrPxhmm
00:14Sgeo_That feels ... like it should be wrong
00:14shachafhi Sgeo_
00:15shachafWhat's wrong?
00:15Sgeo_Scope determined by nesting of parentheses. Surely you could do .. stuff that won't create a new scope, and could introduce a new scope without nesting
00:16SrPxI guess the problem is that I see (((fn [x] (fn [y] (+ x y))) 5) 4) just as a partial application. The interesting application of closure on my last language was that I could create a closed environment for a function. But I guess that has no sense without mutability
00:16eggsbyit's not the nesting of parens, is it? it's the lexical bindings via things like fns and let and with-bindings
00:17eggsbylike (do (one ..) (two ..)) separate parens same scope
00:17TimMcout and up
00:18cjfriszeggsby: So in your example, one and two have the same *enclosing* scope
00:18Sgeo_let can in priciple be reduced to applying an fn
00:18Sgeo_As long as the fn does lexical scoping stuff etc.
00:18cjfriszSgeo_: Yes
00:18Sgeo_Not particularly relevant to the discussion under discussion
00:19Sgeo_Suppose you had some macro that ... did weird stuff
00:19Sgeo_How about <<- from swiss-arrows
00:19SrPxSgeo_: interesting
00:19Sgeo_(<<- (let [a 1]) (let [a 2]) a) ; 2
00:20SrPxlike ((fn [x] (my stuff)) 5) = (let [x 5) (my stuff)) ?
00:20Sgeo_SrPx, exactly
00:20cjfriszSgeo_: What's teh code generated by your example?
00:20Sgeo_Except for your syntax error
00:20cjfrisz*the
00:21SrPxSorry for that. It is still complicated but ..
00:21Sgeo_(let [a 1] (let [a 2] a))
00:21cjfriszSgeo_: And there's your scope
00:21cjfriszSgeo_: To your point, macros can play with scope, but in general scoping is determined by the nesting or parens
00:22cjfriszSgeo_: And by play with scope I mean rearrange things in unintuitive ways
00:22cjfriszFor certain examples (i.e. that one)
00:24cjfriszUgh...I meant "nesting *of* parens," not "nesting *or* parens"
00:28Sgeo_"It's based on parentheses" does not generalize to non-Lisps
00:28cjfriszSgeo_: Kind...of?
00:28Sgeo_I think it's far more general, and far less fragile, to base it on conceptual nesting of scope-introducing constructs.
00:29SrPxIm testing some things, just to confirm, the difference between ' and ` is just that with ` you can use ~ not to quote a part of your list? '(a b c...)
00:29Sgeo_An fn introduces a scope to everything within its body
00:29Sgeo_,`(1 (+ 2 3) ~(+ 4 5))
00:29clojurebot(1 (clojure.core/+ 2 3) 9)
00:29Sgeo_,'(1 (+ 2 3) ~(+ 4 5))
00:29clojurebot(1 (+ 2 3) (clojure.core/unquote (+ 4 5)))
00:30Sgeo_Oh woah I didn't realize clojure.core/unquote existed
00:30Sgeo_I'm going to go ahead and say that I think that this in and of itself may make Clojure better than Common Lisp at some macro stuff.
00:31Sgeo_,'(`blah ~blah ~@blah)
00:31clojurebot((quote sandbox/blah) (clojure.core/unquote blah) (clojure.core/unquote-splicing blah))
00:31Sgeo_,'('blah `blah ~blah ~@blah)
00:31clojurebot((quote blah) (quote sandbox/blah) (clojure.core/unquote blah) (clojure.core/unquote-splicing blah))
00:31Sgeo_Hmm, that's weird that ' and ` are similar like that
00:31Sgeo_I'm confused now
00:33SrPxo.o
00:34Sgeo_,'('~foo `~bar)
00:34clojurebot((quote (clojure.core/unquote foo)) bar)
00:35Sgeo_uh
00:35SrPxwhat the ..
00:53mpanPeople who are using Clojure for web backends: is there something particular you're using for the frontends?
00:54akhudekmpan: clojurescript is neat, and has some very promising libraries, but it's not quite as mature as the clojure backend stuff yet
00:55mpanIs there a library that people are using to, say, synchronize state and display it?
00:56akhudekyou mean the sync client side state and server state?
00:56akhudekthere has been some discussion of functional reactive programming and a few experimental implementations for that
00:56akhudeknot sure of the state of them though
00:57akhudekone of the bigger efforts I've seen is https://github.com/ohpauleez/shoreleave
00:58akhudekalso look at http://clojurescriptone.com/
00:59mpanthanks
00:59SrPxCan this be shorter? (defn pow [a b] (Math/pow a b))
01:00akhudekyes (Math/pow a b)
01:01mpanhow is the presenter using the repl to change the browser state?
01:01SrPxakhudek: this is not the same
01:01akhudekI guess you want to pass it as a fn?
01:02akhudekdefining it the way you did is probably fine, could also do #(Math/pow %1 %2) for a one time use
01:03akhudektechnically (def pow #(Math/pow %1 %2) is shorter too, but I'd prefer your version for clarity
01:03akhudekmpan: I think that repl runs in the browser
01:04akhudekI haven't looked to much into clojurescriptone, so I'm not sure how much they get into interaction with a server backend
01:04mpanthink it's part of the core of cljs though
01:05mpanthink I see where they make the explicit connection, but still confused where what runs
01:05akhudekclojurescript runs in a browser, or some other javascript engine
01:06akhudekit has a repl that is distinct from the repl that would run on a server
01:06akhudekso you could actually envision both a server repl and a clojurescript repl running concurrently for dev purposes
01:06mpanthey're starting a server from the js from the browser?
01:06mpanwait, how?
01:07akhudekI'm not sure there is a server in that clojurescriptone demo
01:07akhudekit's been a while since I've looked at it
01:08akhudekbut you can do a browser repl like this: http://vimeo.com/29535884
01:10SrPxHow to include [org.clojure/math.numeric-tower "0.0.1"] from repl?
01:10akhudekSrPx: you need to pull it in as a lein dependency first
01:11mpanget it in your classpath (preferably: use lein for dep resolution), then "use" or "require" statement
01:11akhudekthen (use 'clojure.math.numeric-tower)
01:11SrPxokok got it
01:12SrPxand sorry but I have been googling for too long and couldn't find the syntax for requiring something and bringing part of it to scope
01:12mpanhave you got the jar already? (either directly or through lein)
01:12SrPx(require ['clojure.string [:refer upper-case]]) something like that
01:13SrPx(require ['clojure.string :refer 'upper-case]) ?
01:15mpanhttps://gist.github.com/287710 this is a tutorial for use with the ns statement, but there are corresponding require and use standalone forms
01:15SrPxBut i'm not using ns but (require)
01:15mpanhttp://clojure.org/cheatsheet the general cheatsheet has info on both
01:15mpanthe remainder of the syntax is the same
01:15SrPxok
01:15SrPxthanks
01:16mpan(I think; I hope)
01:21mpansrpx: also, in most use-cases, it's preferable to have the require/use along with your ns statement, rather than standalone
01:24SrPxns creates a namespace and uses it, right? mpan
01:25SrPxso it is like a thing you call once?
01:25SrPxI'm avoiding it because I do not understand. do I have to name it following some convention based on my files or something?
01:25mpanuh, usually it goes like this
01:25mpanyou have separate namespaces, one per file, with corresponding names
01:26mpanthe ns statement switches the currently-used namespace for evaluating stuff
01:26mpanso if you eval something, it's done so in a given namespace
01:26mpanso at the repl, you can use ns to switch to evaling stuff in the context of a different namespace
01:27mpanhttp://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html this might help
01:28mpanit covers both separating stuff into namespaces and bringing stuff in from them
01:29SrPxok thank you mpan
01:29mpanyou're always in some name space or another
01:29mpanand you could switch between them with ns calls
01:29mpanthe reason for the naming convention and file structure is so that the runtime knows where to look when you want to bring something in
01:36ori-lmpan: that's really useful
02:26ThorZaINtedwispken_barber, do you play StarCraft?
02:26RaynesMinerals.
02:27mpanis it just me or are there disproportionately many starcraft fans here?
02:28ThorZaINtedwispI noticed
02:28ThorZaINtedwispAlso, I got this schweet schweet 2rax reaper buold TvP where you pressure the front while loading a reaper behind their mineral line, god it's hard to deal with
02:29ThorZaINtedwispIt also gives you really quick stim and a quicker CC than if you keep making marauders
02:34mpanWhat are some use cases for metadata? Like, why would you choose it over putting fields directly into data?
02:34ifesdjee_mpan: first of, documentation, i'd say
02:35ifesdjee_mpan: you can also checkout robert-hooke for an interesting use-case for meta data
02:35Raynesmpan: For the most part, don't care.
02:35ifesdjee_mpan: https://github.com/technomancy/robert-hooke/blob/master/src/robert/hooke.clj#L51-56
02:35Raynesmpan: When you need metadata (which may never happen), you'll know exactly what it is for.
02:35Raynes:D
02:35RaynesYou'll realize "oshi-, I could use metadata for this"
02:36ifesdjee_i'd say when something belongs strictly to the function, that should be metadata
02:36ifesdjee_you can't carry hash around with your fn otherwise
02:36mpanoh cool
02:36mpanthanks you all
03:06ThorZaINtedwispRaynes, you play as well?
03:06RaynesNope.
03:54zoldar /j #neo4j
04:11ThorZaINtedwispzoldar, do you play StarCraft?
04:38zoldarThorZaINtedwisp: Long time ago I've played some, but rather single player campaigns, multiplayer was too hardcore for me. Why do you ask?
05:35mindbender1I think it's particularly good that clojure gives us the choice of rememberiance or forgetfulness
06:04marianoguerrahi! I catched a ExceptionInfo exception, how do I access it's data?
06:04marianoguerragoogle doesn't bring useful results :S
06:04marianoguerra(new to clojure)
06:04ordnungswidrigmarianoguerra: an exception or and exceptioninfo (what is that)?
06:05marianoguerraclojure.lang.ExceptionInfo
06:06ordnungswidrighuh, never heard of this :)
06:06clgvisnt that the one of slingshot?
06:06ordnungswidrigaccording to clojure.core doc you can access the data with (ex-data ei)
06:06marianoguerra(.getData error) does the tric
06:07marianoguerraordnungswidrig: yep, that works too, thanks!
06:07ordnungswidrigyou should use ex-data to not rely on implementation details
06:08clgvwhen does clojure throw those?
06:09ordnungswidrig(throw (ex-info {:there "is" :more "info"}))
06:09ordnungswidrigah, no
06:09ordnungswidrig(throw (ex-info "something weird happened" {:more :data}))
06:10clgvah lol thats brand new
06:10ordnungswidrig(try (...) (catch ExceptionInfo e (prn (ex-data)))
06:10clgvat least the interface dates 7 days ago
06:11ordnungswidrig*g*
07:32ThorZaINtedwispjcromartie, do you lpay StarCraft?
07:43mindbender1"A name is imposed on what is thought to be a thing or a state and this divides it from other things and other states. But when you pursue what lies behind the name, you find a greater and greater subtlety that has no divisions..." — Visuddhi Magga
08:39CheironHi, is it possible to use Scala classes from Clojure code?
08:43jsabeaudryCheiron, this seems to say yes: http://stackoverflow.com/questions/12053079/how-to-nicely-call-other-jvm-languages-from-clojure
08:45Cheironjsabeaudry: CompilerException java.lang.IllegalArgumentException: No matching ctor found is not fun at all :(
08:45jsabeaudryCheiron, is that following the example fromt he accepted answer in the SO question?
08:46Cheironi have scala code compiled into a jar file under lib directory
08:47Cheironi don't know if i have to supply type hints to scala functions
08:48jsabeaudryCan you try to instantiate another class of your lib that doesn't take any parameters?
08:49Cheironwill try
08:51Cheironyes i can
08:52jsabeaudryCheiron, great, then we know the problem
08:52jsabeaudryWhat parameters does your other class take?
08:52Cheironother java.util.File, another Scala class type and java.lang.Double
08:53LajjlaCheiron, do you play starcraft?
08:53CheironLajjla: should i?
08:53LajjlaNot at all, just wondering.
08:54CheironLajjla: :) no not really, i don't play sc
08:54jsabeaudryAnd how are you calling it?
08:54Cheiron(ScalaClass. file scala-instance double-value)
08:57jsabeaudryCheiron, my guess is that one of these parameters does not have the type you think it has. But I have never done scala, much less clojure-scala interop
08:57CheironAh, the scala class is declaring implicit after the constructor definition, is it matter?
09:01jsabeaudryThis says you should pass the implicit parameter explicitely: http://stackoverflow.com/questions/7808821/java-calling-scala-case-class-w-implicit-parameter
09:04Cheironjsabeaudry: true, will try it. thanks a lot !
09:14Cheironjsabeaudry: true, it is working now, a lot of thanks :)
09:15jsabeaudryCheiron, glad to hear it :)
10:00casioncould someone assist me on why this code is not working on the xml file in the paste? https://www.refheap.com/paste/5353
10:06abalonecasion: did you already try putting in the rest of the path to :MediaTrack ?
10:06clgvcasion: "not working" is not precise. you should post an error description. if you want to have the content you have to zip/node
10:07casionclgv: I get nil returned
10:07casionand no examples I've seen use zip/node… but I shall try
10:07casionabalone: yes I have
10:07clgvzip/node is for getting the content
10:09clgvall zipper tutorial I read used zip/node
10:09clgvcasion: but for that "nil" I guess something's wrong with the navigation path
10:11casionclgv: as far as I understand, xml1-> should be searching for a tag when I supply a keyword
10:11casionalong the whole tree
10:11jkkramercasion: If memory serves, (zf/xml1-> xmlzipper :Song :Attributes :List :MediaTrack) would be the right thing
10:12jkkramerplus zip/node if you want the actual node and not a zipper returned
10:12clgvcasion: there is nothing about searching the whole tree in the docs
10:12casionjkkramer: that returns nil as well
10:14clgvcasion: thats because your file has nodes with different types of children
10:14clgvcasion: just build a navigation path analogue to jkkramer's
10:15clgvthe first one in :Attributes causes the nil since there is no :List
10:16casionclgv: I don't understand that last line, why is there no :List in the first :Attributes?
10:17casionif I do just (zf/xml1-> xmlzipper :Song), I still get nil
10:17clgvbecause of your file in the gist. have a closer look and try to navigate by hand
10:18casionoh, I see...
10:18casionbut I don't get why :Song doesn't return anything either
10:38jonasencemerick: About your kibit issue. I'd like to attempt to make the necessary changes in cljx instead. Work started at https://github.com/lynaghk/cljx/commit/1bc64f2c8cbf690178b611e10b1776fcb996e225
10:41cemerickjonasen: I was thinking of that prior to filing the issue, but figured things like tagged literals would put it in kibit's scope.
10:41cemerickI'm not sure how it could be done in cljx though, since it needs to be able to operate on top-levels.
10:48abalonecasion: are you able to get what you want with zip/down zip/left zip/next and friends instead?
10:48casionabalone: yes
10:50jonasencemerick: That might be the case... but first I'd like to figure out sjacket. What does reply use sjacket for?
10:51cemerickjonasen: determining whether the content entered into the REPL is a complete form or not prior to sending it to the remote REPL.
10:52jonasencemerick: ok. I looked at the sjacket repo but found no docs or examples. Is the euroclojure video the best source to learn about sjacket?
10:52abalonecasion: i looked at my old code which requires zip-filter and then doesn't use it :-P i guess whoever helps you will end up helping me too.
10:53casionabalone: you're the 3rd person in here to tell me that exact thing :(
10:53cemerickjonasen: At present, unfortunately. I'm currently pestering cgrand to make some headway on docs.
10:53casion"Here's some code where I use… wait, I didn't use it"
10:53abalonecasion: whatever it is, it loves company
10:53cemerickFWIW, I've found it straightforward to use, YMMV.
10:54cemerickjonasen: (BTW, the munge-forms API shouldn't need to change; note that cljx is useful with non-files, so taking a reader for input is far preferred.)
10:54casionabalone: how did you end up doing things instead?
10:55casionand it in the previous statement being data.zip.xml
10:55abalonecasion: i ended up frowning and using zip/next instead.
10:55jonasencemerick: agreed, I'll change that
10:55casionabalone: you just walk the whole tree that way?
10:56abalonecasion: i didn't "just" walk. i frowned as well.
10:56cemerickjonasen: Thanks; my next project out enables one to use cljx at the REPL.
10:56casionabalone: :( I shall alert you if I manage to figure this out then. I'm quite stubborn
10:57casionI'll get it or give up on the project
10:57casionthe latter has yet to occur
10:57abalonecasion: "hope is a dangerous thing" just kidding of course. thanks in advance. alert those other folks too. maybe they're frowning.
11:01abalonecasion: do existing zip filter examples work?
11:01casionabalone: from what I've found on google, maybe half work… probably less than half
11:02casionI'm not sure how much, if any, of that is the fault of zip-filter/data.zip.xml or the authors of said code
11:03abalonecasion: oh. well if something works maybe you can slowly transform it into your example by steps
11:04casionabalone: I've been trying that, pulling directly from the data.zip.xml test cases
11:04casionI wonder if it's just my xml files I'm working with
11:05casionI think more likely that I'm an idiot and missing something
11:09jcromartiecasion: what is your issue? I just did some XML stuff and played with the clojure.data.zip.xml
11:09jcromartie(navigating the libraries and namespaces was a bit confusing at first)
11:09casionjcromartie: https://www.refheap.com/paste/5353, I'm having trouble pulling anything from that xml
11:10casionand yeah, I'm having troulbe with namespaces as well. For now I'm just :as silly-name to amuse myself in this time of frustration
11:10jcromartiecasion: yeah that predicate won't do anything
11:10jcromartieyou want the full path
11:10jcromartiethis isn't path :)
11:10casionjcromartie: would simply :Song work? I though it would change it to (tag= :Song)
11:10jcromartieXPath
11:10jcromartiestart from the beginning
11:11casionerr, should :Song work. It's not
11:11jcromartieyou don't have to specify the root element
11:11jcromartiesorry
11:11casionoh?
11:11jcromartieso (xml-> zipper :Attributes :List :MediaTrack)
11:12jcromartieor whatever
11:12casionoh, that works!
11:12jcromartiethat will return all media tracks
11:12casionhow would I deal with multiple roots?
11:12jcromartiecasion: you shouldn't have multiple roots, that is not valid XML
11:12casionjcromartie: I thought so :| but I do
11:13jcromartiecasion: if you want to deal with multiple <Song> elements then wrap them in a single root
11:13jcromartie<Songs><Song /><Song /><Song /></Songs>
11:13jcromartieor whatever
11:13jcromartiebut you definitely need a single root
11:14casionjcromartie: ok
11:14jcromartieif someone else is giving you XML with multiple roots, ask them to fix it, and/or munge the doc until they do
11:15casionjcromartie: unfortunately they insist that it's valid. So I've taken the stance of just assuming it is (for reasons unknown)
11:15casionI can wrap it though, no problem
11:15casionjcromartie: you've been a massive help, thank you :)
11:16hammer,(find-doc "clojurebot")
11:16clojurebotnil
11:16hammerhehe, you said
11:17hammeryou said it*
11:17jcromartiecasion: if they think multiple roots is valid, just direct them to any XML validator, or W3C http://www.w3.org/TR/REC-xml/
11:18casionjcromartie: will do, thank you
11:18jcromartieyou can have multiple elements in a document but they won't be roots
11:20jonasencemerick: I read the euroclojure slides for sjacket and found it really interesting! Do you know of any examples of a 'putback' function. I don't really know how i'd write one.
11:20casionthey a have project.xml that can have multiple root <song>
11:20casionand another workspace.xml which has (as far as I've seen) 6 levels of the same tag name
11:22cemerickjonasen: what would putback do?
11:25jonasencemerick: page 41 in the slides. The previous step (i.e. Expr->Expr2) is _exactly_ what kibit is trying to do. 'putback' is the part you would need for cljx I think
11:32TimMc(inc hammer)
11:32lazybot⇒ 1
11:33TimMccasion: This raises troubling questions about how *they* are parsing the XML.
11:33TimMcMy guess: Regular expressions. -.-
11:35hammerTimMc: what's that mean? you incremented me?
11:35casionTimMc: the authors have an open source project that's a precursor to this propietary one that uses some crazy Boost property tree stuff
11:35jsabeaudryhammer, that is love
11:36casionI don't know how it's done in the current software I'm working with (or against maybe more appropriate)
11:37casionand oddly enough, the software is the most stable and robust in its class
11:37TimMchammer: It's a karma plugin on lazybot.
11:38casionthe best part is that after parsing all these xml files, I have to rebuild it into something the software will accept
11:38cemerickjonasen: Yeah, I don't grok that yet either.
11:47alpheusIs there a function that returns attributes of a file, link count, in particular?
11:53hammeri want to run clojurebot on my own IRC server, but I'm stumped
12:02dhofstetalpheus: there is afaik no such function in clojure, but have a look at the readAttributes() method of the Files class: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html
12:09antoineBhello, assuming i want only use global vars through "binding" macro is there something special to do? (def ^:dynamic my-var) can be changed for instance
12:10jcromartieantoineB: that's it
12:11jcromartieantoineB: also understand that vars are thread-local bindings, too
12:11jcromartiewith (binding [*foo* bar] …)
12:12antoineBok
12:13AmarylHello, I have just begun to learn Clojure, and I have a stupid question. Could sb tell me the difference between (defn f[] (let [a 1 b 2] (println a b))) AND (defn f[] (def a 1) (def b 2) (println a b))
12:14hiredmanlet creates local bindings of names to values, def creates a global var
12:14jcromartie"global" var
12:15jcromartie(binding …) creates a thread-local reassignment, (set! …) changes the global value
12:15antoineB(def a something-new) work also?
12:15Amarylthat's what I understand, but when I execute the code in the online interpeter -> http://tryclj.com/ I can't access "a" and "b" outside the function in either case
12:15jcromartieoh sorry, confusing antoineB and Amaryl's questions :)
12:15jcromartieAmaryl: "let" creates local bindings
12:15rlbhiredman: yeah, coming from scheme, it took me a minute to realize that it wasn't doing what I thought it might be doing.
12:16jcromartiethey are not available outside
12:16rlb(in scheme internal defines are more or less like let)
12:16jcromartieantoineB: what are you trying to do? what's in your global var?
12:17antoineBmy gloabls var are just name (they don't carry anything outside binding macro)
12:18jcromartieAmaryl: the "def" inside a fn in tryclj.com is not behaving like it usually would, because tryclj is doing some sandboxing
12:18jcromartieantoineB: what's the purpose of them
12:19jcromartieantoineB: what I'm getting at is, are vars and bindings really the way to go here or do you want a ref or something else
12:20Amaryltanks jcromartie , let's install Coljure on my computer then :)
12:20jcromartieAmaryl: yeah! Leiningen is the easiest way to run Clojure, and it's in many package managers now
12:20shaungilchristwhat is the site which listed all the various clojure libs grouped by problem space?
12:21antoineBi think binding is the way to go
12:21jcromartieantoineB: so, one more time: what are the vars actually for?
12:21alpheusdhofstet: readAttributes should do it. Thanks.
12:21jcromartieantoineB: what does it represent?
12:21antoineBglobal state
12:24jcromartieantoineB: WHAT. ARE. THEY. FOR.
12:25jcromartieantoineB: current user? database connection? favorite flavor of ice cream? latest cat videos?
12:25jcromartiewhat?
12:25clojurebotwhat is wrong with you
12:25antoineBopengl state
12:25jcromartiethanks for the reality check, clojurebot
12:25hammerlol
12:25antoineBrelax jcromartie
12:37devthis there a more concise way to retrieve the 2nd-to-last el? (last (butlast (range 10)))
12:39technomancydevth: there's a patch to do that concisely, but it was rejected because it was "goofy"
12:40devthtechnomancy: ah ok
12:40scriptor(last (drop-last (range 10))) would only go through the collection once
12:41devthoh, right
12:41hiredmanbutlast is just as lazy as drop-last
12:41scriptorit's implemented with loop/recur
12:42hiredmanfuh
12:43hiredmanwas that always like that?
13:04loliveira byte_bucket: hi, i discovered what was happening.
13:18TimMcjcromartie: I chose to interpret clojurebot as addressing antoineB, actually.
13:20augustlis it safe to intern user input to keywords? The Ruby equivalent, symbols, never gets garbage collected, so that's not safe. Is Clojure keywords similar to Ruby symbols, or are Clojure keywords garbage collected?
13:20technomancyaugustl: since 1.3 they're GC'd
13:20augustlnice, thanks
13:21technomancyor possibly 1.2.1?
13:21augustlcheshire defaults to strings as keys, while my mongodb lib gives me keywords as keys, kind of cumbersome
13:22dakroneaugustl: you can easily change cheshire to return keys as keywords
13:22augustldakrone: goodie, then I'll do that
13:23augustlkind of expected cheshire to support that, especially since creating arbitrary keywords from user input run-time is safe
13:23dakroneaugustl: it just doesn't by default to ensure it can be as fast as possible
13:24augustlah, so it will create strings first anyway?
13:25dakronewell, keywords need to be created out of something in any case, and the string already exists because it's part of the json, are you concerned about the performance, or memory?
13:26augustldakrone: consistency is the most important thing right now
13:27dakronethen you should be able to have it return keys as keywords and not worry about it
13:27augustlkeywords are nice anyways, for (:foo bar) type access
13:28augustland since I'll probably use records in the future
13:29thorbjornDXis this a good way to get each element of a sequence and the one that came before it? (partition 2 (interleave myseq (rest myseq)))
13:29thorbjornDXit seems like I would be doing twice the work
13:29augustlthorbjornDX: sounds like reduce would work
13:31kenshoHi. I'm working with swing and I wrote a macro to make sure that code gets only executed on the EDT, like (edt! (whatever) (foobar)). This works nicely but I would like to introduce a way to turn that off globally, so that if the setting is false the macro doesn't introduce this check. I thought this would be possible with dynamic vars but I can't get it to work. I'm probably misunderstanding their purpose. I thought I could do (def
13:31kensho^:dynamic *force-edt* false) and then enable it with (set! *force-edt* true) but this always results in an error saying that the root binding can't be changed. I'm probably doing it wrong. What is the best way to achieve this kind of global setting (which is only supposed to be changed for dev ppurposes)?
13:34jsabeaudrykensho, perhaps an atom
13:34jsabeaudryI'm mostly a clojure noob so take that with a grain of salt
13:36augustlkensho: perhaps you should provide a function to set it anyway, so the actual thing you use to store the global setting is private
13:36technomancyuse an atom if you can. if it won't change at runtime you can use alter-var-root, but it's a bit messier
13:36augustl</randomthought>
13:36jcromartiekensho: the issue is the thread-local binding of vars
13:36jcromartiekensho: never mind I think you've figured it out
13:37kenshook thank you, I will use an atom then.
13:39mefestoI'm having trouble using lein-ring and stencil. Seems my views will not refresh unless I restart the ring server. Does anyone know what I could do to fix this?
13:45augustlmefesto: there's a known issue with lein ring and reloading in general, not sure if it's fixed, and not sure if there's another stencil specific issue around..
13:47technomancymefesto: auto-reload heuristics are virtually impossible to get right
13:47technomancymuch better to reload from within your editor
13:48mefestoi think the issue im having is that stencil is caching the views but it's not clear to me how to disable view caching for development
13:49mefestoall of my other code seems to be properly reloaded by lein-ring
13:52augustlwill a lazy list "cache" its results if it's iterated multiple times? Guess not.
13:52augustllazy sequence*
13:52TimMcaugustl: It's not caching, it's realization.
13:53TimMcaugustl: (map println (range 60)) will only execute println once for each element of the input, no matter how many times you walk it.
13:53augustlcalling (remove nil? ...) on a list. First going to count it, then if it contains more than 0 items, I'll do something with the list. Wondering if a count and later an iteration will "realize" the lazy sequence twice
13:53thorbjornDXaugustl: here's what I came up with: ##(reduce (fn [s b] (conj s [(second (first s)) b])) '() (range 6))
13:53lazybot⇒ ([4 5] [3 4] [2 3] [1 2] [0 1] [nil 0])
13:53augustlthorbjornDX: you can also give it an initial value of (first coll) and then reduce (rest coll) to avoid the nil
13:54augustlthorbjornDX: in other words, reduce takes an initial value as well as a list
13:54TimMcaugustl: (map inc (range)) looks like this in memory: (... magic!)
13:54augustlTimMc: wut :)
13:54TimMcaugustl: If you then (dorun (take 4 that-lazy-seq)), it looks like this: (1 2 3 4 ... magic!)
13:54jsabeaudry,(println (... magic!))
13:55clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: magic! in this context, compiling:(NO_SOURCE_PATH:0)>
13:55TimMcaugustl: It's only when you try to descend into the magic! bit that realization occurs, producing more cons cells.
13:55TimMcWalking those cons cells again doesn't do anything.
13:56TimMcIt's like a magician pulling scarves out of thin air -- once they're out, they're out.
13:56augustlTimMc: neat :)
13:56TimMcGo read LazySeq.java, you'll see how it works.
13:57augustlTimMc: I'll do that, tnx :)
13:58thorbjornDXaugustl: I guess I'm confused how to start off my reduce with a seq of a single vector. In my case, I can't just use first/rest when initializing it
14:00augustlthorbjornDX: what exactly are you trying to do?
14:01augustl##(+ 1 2)
14:01lazybot⇒ 3
14:01augustl##(let [my-coll (range 6)] (reduce (fn [prev curr] (conj prev curr)) [(first my-coll)] (rest my-coll)))
14:01lazybot⇒ [0 1 2 3 4 5]
14:01augustlthorbjornDX: ^^
14:02augustlquite silly though so I guess that's not what you're doing ;)
14:02thorbjornDXaugustl: see lazybot's response above, I just want to get pairs of items from a seq, so [0 1 2 3] -> ([0 1] [1 2] [2 3])
14:03jkkramer,(partition 2 1 [0 1 2 3])
14:03clojurebot((0 1) (1 2) (2 3))
14:04thorbjornDXjkkramer: ah, I think that's it :) thanks
14:05augustlis there a deep merge of maps+sequences around?
14:12TimMcaugustl: I think merges are hard to make semantically generic.
14:13augustlTimMc: makes sense, I don't need a generic merge anyway, the data I need to merge has a very specific structure
14:14TimMcJudicious application of merge-with and some custom fns would probably suffice.
14:15augustlis this a sensible way of "consuming" a sequence btw? I've ended up having a few of these in my code. https://www.refheap.com/paste/5355
14:16augustlthe idea is that merge-error updates the result (performs the merge)
14:16TimMcLooks like you want a reduce.
14:16hiredmanagumonkey: I would twiddle the argument order, sequences generally go last
14:16augustlhiredman: the idea is that the "result" is optional though
14:16augustlso you can jsut do (merge-errors errs)
14:17hiredmanaugustl: *shrug*
14:17TimMcaugustl: (reduce merge-error result errors), where merge-error takes [result error] instead of [error result].
14:17augustlhmm
14:17TimMc...for the binary form of merge-errors.
14:17augustlTimMc: will look into that, thanks
14:19augustlTimMc: (reduce merge-error (first errors) (rest errors)) :)
14:19TimMcnoooo
14:19augustlhmm, why not?
14:20augustl"errors" is a list of maps, and it needs to be able to merge the first with the second
14:20augustlso it seems like one less operation to me
14:20TimMcIsn't a result different from an error?
14:20augustlperhaps result is a bad name. I'm merging a bunch of error maps, the result is the merge
14:21TimMcSo merge-error takes [A A -> A]?
14:22augustlTimMc: yes (if I'm reading that correctly)
14:22TimMcOK. So the input is a list of errors, and the output is an error.
14:22TimMc(for merge-errors, plural)
14:23TimMcAnyway, "one less operation" is a bad reason to make code harder to reason about.
14:23augustlTimMc: true that
14:23augustlwhich one do you like best, now that you know more about what I'm trying to do?
14:25TimMcaugustl: https://www.refheap.com/paste/5356
14:26TimMcAnd if you really want performance, use the reducers lib -- you've got an associative reduction, so you can parallelize it.
14:26augustlnot on 1.5 yet :)
14:26augustlah, no need for an initial when it's the same collection, doh
14:27TimMcAnd reduce will handle the 0 and 1 corner cases for you.
14:27thorbjornDXman, code can be so cool. My code isn't :p
14:27thorbjornDX*yet
14:30hiredman /win 11
14:31jcromartieparallel reducers!
14:31augustlthat was fun :D https://www.refheap.com/paste/5357
14:34jcromartieI don't really understand what Noir adds over just using Compojure
14:35augustljcromartie: I'm using compojure, mostly because I didn't like (read: hated) the way Noir used thread local stuff for cookies etc
14:35augustlsomething as FP friendly as a web request/response cycle is best off written in a functional style if you ask me..
14:35jcromartieI think my first issue right off the bat is that (defpage …) doesn't give me a var in that namespace
14:36jcromartieit's just magic
14:36augustljcromartie: indeed, I had that issue too :)
14:36augustljcromartie: then I wanted to write a (defpage my-page-list ...), then I realized compojure is exactly what I want
14:36jcromartieno offense … obviously people are building sites with it
14:36jcromartieI'm trying to figure out how to add Swagger docs to Compojure routes now
14:37augustljcromartie: i also use compojure.core/routes a lot
14:37augustlinstead of defroutes
14:37jcromartieyeah
14:37augustlI prefer to just work with a set of handler functions
14:37jcromartieyeah, I tend to actually use the handers directly during development
14:37jcromartieto test/debug
14:38jcromartieor just explore
14:38augustlI also have a om nom system with a function that creates new handler functions with a specific environment/config
14:38augustlno singletons, yay
14:39augustlthe config is made available in the request, as :config
14:43jcromartieI'm not sure how to approach the documentation thing
14:43thorbjornDXwhat's wrong with #({:key1 % :key2 %2}) ?
14:43jcromartieshould I use metadata on handler vars?
14:43jcromartiethorbjornDX: it tries to call the map
14:44augustlthorbjornDX: #() assumes you want to call a function
14:44jcromartie,#(+ 1 2)
14:44clojurebot#<sandbox$eval27$fn__28 sandbox$eval27$fn__28@5c6ad9e9>
14:44jcromartieerr
14:44thorbjornDXjcromartie: ah, so I should use hash-map or something instead?
14:44jcromartiethorbjornDX: sure
14:44thorbjornDX,(#(+ 1 2))
14:44clojurebot3
14:44augustlthorbjornDX: if you just want to return a map you should use (fn [a b] {:key1 a :key2 b})
14:44augustl..afaik
14:44jcromartiethorbjornDX: or use (fn [x y] {:foo x :bar y})
14:45thorbjornDXaugustl: ah, okay. That's what I thought it would shortcut to, guess not
14:45jcromartieeither way
14:45hiredman,(macroexpand '#(x))
14:45clojurebot(fn* [] (x))
14:45hiredman,'#(x)
14:45clojurebot(fn* [] (x))
14:45jcromartieooh, very enlightening
14:45hiredman,(macroexpand '#({:a 1 :b 2}))
14:45clojurebot(fn* [] ({:a 1, :b 2}))
14:46jcromartie,'#(inc %)
14:46clojurebot(fn* [p1__161#] (inc p1__161#))
14:46thorbjornDX,(macroexpand '#({:a % :b %2}))
14:46clojurebot(fn* [p1__188# p2__189#] ({:a p1__188#, :b p2__189#}))
14:46jcromartieand now we know
14:46jcromartieclojurebot: I love you
14:46clojurebotNo entiendo
14:46jcromartielove is hard to understand
14:47thorbjornDXclojurebot: yo te amo
14:47clojurebotpaste is not gist.github.com
14:47hiredman~botsnack
14:47clojurebotthanks; that was delicious. (nom nom nom)
14:48augustlis there a way to turn :foo into "foo"?
14:48aperiodic,(name :foo)
14:48augustlnot ":foo", that's what str seems to do
14:48clojurebot"foo"
14:49augustlaperiodic: tnx
14:58augustlwhat's a good way to get the first item in a sequence that matches a predicate?
14:58augustl(first (filter pred coll)) comes to mind
14:59aperiodic,(doc some)
14:59clojurebot"([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"
14:59augustlaperiodic: thanks
14:59augustl(inc aperiodic)
14:59lazybot⇒ 2
14:59aperiodicde nada
15:00hiredmansome may or may not work, depending on your predicate
15:00hiredmanit returns the value of the "predicate"
15:00augustlmy predicate will return null or a map, so that should work me thinks
15:05TimMcRaynes: I tweaked refheap so I can run an internal pastebin where I work. :-)
15:05aperiodicaugustl: as long as it returns the map you want
15:05augustlaperiodic: yeah it does, seems to work just fine
15:07mpenetibdknox: ping
15:21RaynesTimMc: Cool!
15:31casionis there a better way to do something like (apply xml-> `(~zipper ~@path ~(attr :name)))
15:31casionit works, but it just seems wrong
15:34emezeskecasion: I think this does the same thing? (apply xml-> zipper (concat path [(attr :name)]))
15:34emezeskecasion: If you know path is a vector, you could conj (attr :name) onto it
15:35casionemezeske: it tries to treat the zipper as an arglist then
15:35emezeskeAn arglist?
15:36ohpauleezemezeske: Quick question - have you successfully used cljsbuild for node targets? If not, what needs to be done/where should I start looking (more than happy to patch whatever)?
15:36casionemezeske: a list of arguments, e.g. it applies each element of the zipper rather than passing the zipper
15:37hiredmancasion: apply only treats the last arg like that
15:37emezeskecasion: Huh? Only the last argument to apply gets expanded into arguments
15:37casion...
15:38emezeskeohpauleez: I don't use node.js myself. I don't think there's anything about lein-cljsbuild that would prohibit it, though.
15:38emezeskeohpauleez: lein-cljsbuild basically just passes options to the ClojureScript compiler
15:38emezeskeohpauleez: So if you can make it work with just the ClojureScript compiler, you should be able to use lein-cljsbuild
15:39emezeskeohpauleez: There's no REPL support for node.js in lein-cljsbuild though
15:39casionemezeske: well that works
15:39emezeskeGood deal.
15:39casionI wonder what I did to make it not work now :|
15:40casionsince that was the first thing I tried, I thought
15:40ohpauleezemezeske: Gotcha - thanks. I'm running into some issues, just wanted to see if there was anything hidden specific to node. (I'm seeing how viable it is to script in CLJS)
15:41emezeskeohpauleez: Feel free to open issues if you do run into lein-cljsbuild-specific problems.
15:41ohpauleezwill do - patches attached ;0
15:41ohpauleez;)
15:41ohpauleezthanks
15:42emezeskeGreat!
15:44augustlis there a function that checks if something is any kind of list/collection except a map?
15:44casionI had that exact code in earlier, and it was giving an error :(
15:44casionand I've since cleared the repl
15:45augustlsequential? seems to be what I want
15:45aperiodicaugustl: regarding collection attributes, http://www.brainonfire.net/files/seqs-and-colls/main.html is worth a read
15:46augustlaperiodic: nice, thanks
15:46aperiodic(inc TimMc)
15:46lazybot⇒ 17
15:46augustl(inc aperiodic)
15:46lazybot⇒ 3
15:47augustlyou're catching up :)
15:58TimMcIt's been a while since the karma counters were reset. :-P
15:58mefestowith refheap, is it possible to create a paste with multiple files of different content types?
16:00Raynesmefesto: No. That's on purpose. I plan to implement something that will serve the same practical purpose without being pointlessly attached to 'files'.
16:00RaynesBut you can't do that at all right now.
16:01mefestoRaynes: how's mongo db working out for this project?
16:01RaynesDelightfully.
16:08jcromartieRaynes: I don't believe you. Everybody hates Mongo now.
16:14thorbjornDXjcromartie: I like mongo, I use their mug every day!
16:15dansalmois there a way to remove an item in a nested structure by type such that (1 2 (3 [4])) becomes (1 2 (3))?
16:15dansalmoit seems easy to replace, but not remove
16:16dansalmoI have tried postwalk
16:16juhu_chapadissoc-in
16:19dansalmoI think dissoc-in only works for associative structures
16:19dansalmo:juhu_chapa I think dissoc-in only works for associative structures
16:19dansalmojuhu_chapa: I think dissoc-in only works for associative structures
16:20augustlare there any good collection types, other than maps, for lists with holes in it? currently doing something like {0 "abc" 6 "def"}
16:21augustlactual reason for asking: need to be able to detect different data types so I can separate "lists with holes in them" from normal maps
16:23emezeskeaugustl: Can you maybe do something like: (assoc {0 "abc" 6 "def"} :my-type :list-with-holes)
16:24emezeskeaugustl: And then inspect (:my-type some-map) to see if it's a :list-with-holes?
16:24Raynesjcromartie: Yeah, I just don't care.
16:24RaynesIf and when it breaks, I'll switch to something else.
16:24jcromartie:)
16:24augustlemezeske: that probably makes sense yeah
16:25RaynesThey can all kiss the back of my hand.
16:25augustlemezeske: then I can post-walk it to remove the type references, for serialization
16:25emezeskeaugustl: You can use multimethods to dispatch on that :my-type entry, too, which can be convenient
16:25TimMcmetadata! :-D
16:26TimMc&(meta (empty (with-meta [1 2 3] {:a 5})))
16:26lazybot⇒ {:a 5}
16:26TimMcOoh, good to know that works.
16:28thorbjornDXTimMc: does empty just clear out the collection, but preserve the meta-data then?
16:29TimMcYeah, it gives you an empty collection of the same type. I wasn't sur eabout the metadata.
16:29TimMcVrey handy for certain generic collection-munging fns.
16:30augustlwhat's "reduce1"? It's used in the implementation of merge-with
16:30thorbjornDXI have to play around w/ meta-data, right now I can only think of using it where I might otherwise use another key/val in a map, but that's just obfuscating things imo
16:31dansalmohttp://stackoverflow.com/questions/12646950/how-can-i-remove-an-item-by-type-from-a-nested-list-or-vector-in-clojure
16:32TimMcaugustl: Is it private to clojure.core?
16:33tbaldridgeagustl: reduce1, into1, etc. are used internally by clojure until it's able to bootstrap itself enough to create the normal reduce/into
16:34patchworkHas anyone used clojure.core.cache?
16:34TimMcDidn't it used to jut overwrite the def of reduce?
16:34augustlTimMc: hmm, perhaps
16:34patchworkI notice it is also immutable so do I need to put it behind a ref?
16:34augustltbaldridge: ah
16:34patchworkI worry about putting a cache behind a ref because I would be making so many updates to it
16:34patchworkor is that the accepted usage pattern?
16:35TimMcpatchwork: more likely behind an atom
16:35tbaldridgeaugustl: the full blown reduce checks the collection to see if it implements "fast-path" protocols. If the right protocols are implemented then it skips making a seq out of the collection.
16:36patchworkTimMc: Aha, I haven't used atoms much. Do I still update them with dosync, or is there something more efficient?
16:36patchworkjust wanting to make sure I am doing the most efficient thing (as the whole point of using a cache is efficiency!)
16:37emezeskepatchwork: Atoms are updated with (swap! ...)
16:37dansalmo(clojure.walk/postwalk #(if (vector? %) nil %) '(1 [2] 3 (4 [5] 6)))
16:38cemerickemezeske: it looks like cljsbuild does not support multiple source paths; do you know of a suggested way to make this jibe with cljs generated by cljx?
16:38patchworkemezeske: Aha! thanks
16:38dansalmo,(clojure.walk/postwalk #(if (vector? %) nil %) '(1 [2] 3 (4 [5] 6)))
16:38clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.walk>
16:38cemerick(short of crazy ignores and such…)
16:38TimMcpatchwork: Atoms are used for uncoordinated updates, whereas refs are used for coordinated updates. Atoms are lower overhead.
16:38emezeskecemerick: I haven't really used cljx; what kind of output does it produce?
16:38TimMcANd yeah, no dosyncrequired.
16:39patchworkTimMc: Perfect, exactly what I was looking for, thanks!
16:39cemerickemezeske: cljs files into a specified directory. The best I can think of at the moment is copying my regular cljs source dir's contents into the generated dir targetd by cljx, but that's a PITA.
16:39dansalmohow can I remove the vectors instead of just replacing them? (clojure.walk/postwalk #(if (vector? %) nil %) '(1 [2] 3 (4 [5] 6)))
16:40emezeskecemerick: If you have multiple :builds, they are all put on the classpath (and can thus access one another)
16:40dansalmoseems to not be a remove function for nested vectors or lists
16:40emezeskecemerick: Maybe have :builds {:cljx {...} :prod {...}} ?
16:41emezeskecemerick: Then :prod would see the sources from :cljx on the classpath.
16:42cemerickemezeske: oh, nm, I can just have cljx build into the :crossover-path; that's always included in the build, right?
16:43emezeskecemerick: I believe so.
16:43cemerickSounds like a winner.
16:44emezeskecemerick: The only hesitation I'd have is that the :crossover-path can be deleted whenever lein-cljsbuild feels like it
16:44cemerickDuct tape FTW!
16:44emezeskecemerick: Although I think it's only deleted on clean, in reality.
16:45cemerickRight; maybe I can hook the cljx process to always run before whatever gets triggered w/ cljsbuild auto…
16:45jcromartiewhat happened to visualvm on OS X?
16:45cemerickjcromartie: should be jvisualvm on your PATH
16:45jcromartieah
16:45jcromartiethere it is
16:45jcromartietanks
16:45jcromartie(planes, boats, etc.)
16:46cemerickemezeske: I've been tinkering with cljx, and it would seem to be a good alternative to the crazytime that are crossovers ;-)
16:48emezeskecemerick: It's definitely less of a hack
16:48emezeskecemerick: I don't like either option though, personally
16:49cemerickYeah, it's all matters of degree at the moment.
16:49emezeskeThe fundamental problem IMHO is the stupid :use-macros and :require-macros things
16:49cemerickThose are the smallest problems IMO.
16:50emezeskeI don't see any other problems really
16:50emezeskePut the platform-specific stuff in separate namespaces
16:50emezeskeAnd make sure the right platform-specific version is loaded
16:50emezeskeDone.
16:51cemerickThings like error handling can't really be split out.
16:52emezeskeSure it can. Move the error handling code to a platform-specific namespace, factor out any neutral code, and implement in terms of that
16:52cemerickhrmph.
16:53cemerickBeing able to write a catch clause or throw an exception reasonably without such gymnastics is nice.
16:53emezeskeI mean, for better or worse, error handling is platform-specific
16:53emezeskeI agree, but clj/cljs punt error handling to the platform :/
16:54cemerickWhich is fine at this point. Sorta. I have a cljx rule that swaps JVM exception classes for js/Error.
16:55emezeskeGnarly!
16:56cemerickerror handling is always going to be hosty. Maybe libraries can make up the middle ground eventually...
16:56cemerickemezeske: hah, is that a good or bad thing? :-P
16:56emezeskeYeah, a cross-platform slingshot would be pretty sweet
16:56emezeskecemerick: Both :)
16:57cemerickRighteous.
16:58thorbjornDXis (map (partial apply (fn [a b c])) myseq) pretty common practice?
16:59cemerickStill searching for a name for an nREPL middleware for cljx though. Nominations welcome. :-D
16:59technomancythorbjornDX: if you have to do anything fancy in a map function it's better to use for
17:00thorbjornDXtechnomancy: I'm just using map destructuring to extract an item and then filter by it (not map actually)
17:00S11001001thorbjornDX: comp is cool for that kind of thing
17:01thorbjornDX(filter (partial apply (fn [{a :a} b c & s] (a > 3)) myseq)
17:01cemerickdnolen: I wonder how many tweets @dnolen on twitter gets that are just absolutely incomprehensible to him. ;-)
17:01thorbjornDXS11001001: so I would comp my 'extraction' and 'check-value' function and map that to the outer sequence?
17:03BronsathorbjornDX: (> a 3)
17:03thorbjornDXBronsa: thanks, typo
17:03S11001001thorbjornDX: say you want all xs for which :score is positive: (filter (comp pos? :score) xs)
17:04thorbjornDXS11001001: that's fine, but I have a seq of seqs, ##(partition 2 1 (range 6))
17:04lazybot⇒ ((0 1) (1 2) (2 3) (3 4) (4 5))
17:04RaynesTimMc: What did you need to change to get it running internally?
17:05RaynesTimMc: If you generalized things to make it easier to change hostname and such, I'd accept that patch.
17:05thorbjornDXso would I just use (filter (comp pos? first :mykey) myseq)?
17:05RaynesI tried to make it possible to run refheap without calling it refheap, but I'll be damned if I know whether it actually can or not. :p
17:05S11001001thorbjornDX: put first last, but that's the idea
17:06thorbjornDXS11001001: my data structure is a bit different than that example: '(({:a 1 :b 2} {:a 2 :b 3}) ...)
17:06dnolencemerick: heh, are you referring to something specific?
17:07S11001001thorbjornDX: remember that some, in a sense, is a function that converts a question about one thing to a question about whether that thing exists in a seq of things
17:08S11001001thorbjornDX: the general pattern remains the same: (comp real-predicate extractor)
17:12TimMcRaynes: Alas, I just rampaged through the code and changed shit.
17:13TimMcripped out browserid, put a note at the top of the About page, changed the default language to Java (the main lang here), changed the title...
17:14RaynesCool
17:28thorbjornDXS11001001: thanks for your advice. I have to use comp (and :keywords) more :)
17:28jballancI feel like an idiot...how do I resolve a var?
17:28octagonhi, can anyone suggest a good reference for compiler design that would help me understand exactly what's going on in the clj and cljs compilers? I've read lots of things about interpreters and understand that pretty well, but for some reason the jump to compilation is giving me a lot of trouble
17:29jballancso: (def foo "bar") ((fn [var] (println ...do-something-here...)) #'bar)
17:29jballancwhoops...that should be #'foo
17:29jballanchow do I make that print "bar"?
17:30jkkramerjballanc: @var. i.e., (deref var)
17:30jballancdamnit...I knew it was something stupid
17:30jballancI kept thinking ref/deref and var/?
17:31jkkramerthere's also var-get, which does the same thing
17:31jballancoctagon: This is considered the gold standard text, I believe -- http://www.amazon.com/Compilers-Principles-Techniques-Tools-2nd/dp/0321486811
17:31jballancat least, enough so that the LLVM team choose a dragon as their mascot based on it
17:32octagonjballanc: thanks! my specific interest is in how the compiler was designed to take advantage of the underlying type system and other machinery already existing in JS and the JVM
17:33octagonjballanc: the dragon book is concerned with mostly lower level stuff, right?
17:34jballancyeah, that's probably a bit more theoretical than you're looking for
17:41dnolenoctagon: I also just recommend reading the CLJS compiler, it's not that big - ~1000 lines for the analyzer and ~800 lines for the compiler
17:42octagondnolen: that's basically what i've been doing, and experimenting a bit. the frustrating part is that my interpreter that i built has an analysis phase that is aaaalmost compilation, but there is some maddening little key thing i'm missing
17:44cemerickdnolen: oh, I msg'd @dnolen and Brenton last night, and he replied to me and him
17:45dnolencemerick: oh hah
17:45dnolenoctagon: can you be more specific?
17:48octagondnolen: i have an interpreter for a lisplike language that runs in cljs. i'd prefer to compile to cljs instead, for performance reasons. my interpreter already has an analysis phase that compiles the syntactic analysis into a cljs function, also expanding macros and whatnot. so i feel like i'm very close, but moving from an interpreter that has a separate analysis phase to a compiler is giving me trouble.
17:51jcromartieis there any reason not for using "let" around "def"? like (let [nf (NumberFormatter/getInstance)] (defn parse-num [x] (.parse nf (str x))))
17:52emezeskejcromartie: There's no compelling reason to avoid judicious use of that
17:54dnolenoctagon: that's pretty meta - interpreted lisp -> cljs -> js
17:54cemerickjcromartie: Closures are useful. Also, http://letoverlambda.com (warning, Common Lisp ;-)
17:54eggsbythe author of let over lambda is pretty... opinionated
17:55octagondnolen: it's worth using cljs if only for the persistent immutable data structures. it's hard to get that right when copying is expensive. my first iteration was in pure js and it had problems with that.
17:55jcromartieeggsby: indeed… "the most advanced language: COMMON LISP"
17:56dnolenoctagon: right, I'm fighting mutable JS atm myself
17:56eggsbyI'm trying to work my way through 'Lisp in Small Pieces'
17:56eggsbyit had the best name of the lisp books
17:57octagondnolen: i ended up defensively copying a lot of data that probably didn't need to be. most of the time the thing was copying data instead of doing work
18:03ohpauleezdnolen: Thanks for pointing me to those tickets. I'll take a stab at them this weekend (working on CLJS CLI apps right now - interesting to tackle)
18:03dnolenohpauleez: oh cool, thanks!
18:04dnolenohpauleez: if you do the unrolling bit I can probably look into the compiler part, just need to add some logic to the invoke case
18:04augustlhml, monger (the mongodb library) has keywords for keys on documents, but not for nested objects, they have strings as keys
18:04dnolenin the compiler
18:04ohpauleezdnolen: Cool, sounds good
18:33TimMcStarting a new thread -- is it weird to use future for that, given that I will never dereference it?
18:35ohpauleezTimMc: I missed the first part of that, but are you using futures just to send stuff to the background?
18:39TimMcYeah.
18:40ohpauleezTimMc: I do that often. It's also popular, if you need more control over how things get background, you create your own executor pool
18:46TimMcI'm so excited, I'm actually getting to do concurrency stuff.
18:47TimMcI finally get to use all these delicious primitives.
18:50ohpauleezTimMc: The future is wild
18:52TimMc:-P
19:32jondot`have a potentially boring question, looking at the language shootout, I see that clojure code is in most cases similar to java in size, and double that of ruby. from my personal experience, clojure gets me an insanely small LOC (less than my ruby code) - why would that be?
19:34technomancyjondot`: because the language shootout doesn't reflect real-world code
19:35dnolenjondot`: shoot out code is low level, also many of them are not that well written to take advantage of better ways to write that kind of kind post 1.3.0
19:35jondot`i just read that they measure code size in compressed gzip size and not LOC. wondering abotu that
19:35jondot`i'm wondering if that means that clojure code doesnt compress as well as java's
19:35technomancyclojure allows you to drop to really low-level code if you need speed at the expense of readability; ruby does not.
19:37jondot`technomancy: yes, i saw that in the best case, clojure is x18 times JRuby. since both are on JVM and both dynamic - how could that be?
19:37jondot`is it because clojure uses methodhandle and JRuby don't?
19:37technomancycould be a lot of reasons
19:37dnolenjondot`: big reason - Clojure's design takes performance seriously in a way Ruby never did.
19:37technomancymaybe no jruby fans care about the language shootout
19:37hiredmanclojure is not constrained by trying to backwards compatible with cruby
19:37jondot`i didn't see type hints i think
19:37technomancymaybe the language shootout doesn't enable invokedynamic
19:38dnolenjondot`: type hints don't equal speed in Clojure.
19:38dnolenjondot`: many things are fast that don't require type hints.
19:38jondot`i assume clojure uses MethodHandle?
19:40technomancyI don't think so
19:41technomancyanyway, don't make any decisions based on data from the language shootout
19:42hiredmanjondot`: the clojure compiler doesn't generate any code that won't run with java 1.5, so no methodhandles, invokedynamic, etc
19:42jondot`yep, i warned this is a bit of a boring question :)
19:42jondot`hiredman: i see
19:44bkirkbrianyone know how to diagnose "It's possible the specified jar is not in any repository." when lien doesn't say which JAR?
19:44bkirkbris/lien/lein/
19:52emezeskebkirkbri: Maybe paste the full output from lein?
19:54bkirkbriemezeske: Sure, here's all the output I get http://pastebin.com/hn48aVZt
19:56emezeskebkirkbri: Huh, I've not seen that particular error message before. I assume you checked for typos? :)
19:57bkirkbriemezeske: I did. The funny thing is that I didn't change the codebase and this started after a deps check that auto ran.
19:58emezeskebkirkbri: Did you try removing all the .lein* and lib/ and whatnot, e.g., starting totally fresh?
20:00bkirkbriemezeske: I'm using lein2, so no lib/ and I did try removing my ~/.m2 and pulling everything all over again.
20:01emezeskebkirkbri: :/
20:02bkirkbriemezeske: Weird, right?
20:07xeqibkirkbri: what version of lein?
20:07bkirkbrixeqi: 2.0.0-preview10
20:13bkirkbrithat's strange… added an exclusion and now it works.
20:13bkirkbrinot sure how that could have happened when the same project.clj and codebase has been working since yesterday.
20:14emezeskebkirkbri: Do you have any SNAPSHOT versions in your :dependencies ?
20:16bkirkbrinope, but it's possible that my deps have deps that are SNAPSHOT
20:16emezeskebkirkbri: I think "lein deps :tree" could be interesting
20:17bkirkbriemezeske: good call, that failed when deps was failing but I can run it now.
20:19bkirkbriemezeske: no SNAPSHOTs http://pastebin.com/vXpJ88Rt
20:21bkirkbriThe :exclusion that made it work was the one on clj-aws-s3
20:30TimMcIs there something that is the opposite of an agent? i.e., a fn that gets events (data) sent to it, not data that gets fns sent to it.
20:31TimMcOr do I just set up a blocking queue and run a fn in a loop waiting for data?
20:31octagonperhaps http://clojuredocs.org/clojure_core/clojure.core/add-watch ?
20:33TimMcHmm, seems roundabout.
20:34TimMcMaybe I'll just make something hacky and give it a pretty API.
20:37thorbjornDXis there a reasonable way to realize (or count) a seq until I get a nil value?
20:37octagonthorbjornDX: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/take-while ?
20:38thorbjornDXoctagon: awesome, I love how every possible higher-order function already exists :)
20:39octagonthorbjornDX: thank god for that
20:40emezeskeI mostly thank Rich Hickey for that
20:40thorbjornDXthank someone, for sure :)
20:40thorbjornDXRich et al
20:41octagonlol i meant like "whew, lucky those things are already written", not implying that God was responsible
20:41bkirkbriemezeske and xeqi, thanks for the help!
20:42emezeskeoctagon: I know you were just using an expression, but that won't stop me from joking about it! :P
20:42bkirkbrinot sure what the cause was, but at least it's working now...
20:42thorbjornDXcan this be shorter?: ##(take-while #(not (nil? %)) '(1 2 3 nil nil))
20:42lazybot⇒ (1 2 3)
20:42emezeskebkirkbri: Glad you're up and running. Too bad you didn't find the root!
20:42octagon(take-while identity ...) perhaps
20:43octagonsince nil is falsy
20:43bkirkbriemezeske yeah, i have a feeling it'll be back. though I hope not.
20:43emezeske,(take-while (complement nil?) [1 2 3 nil nil])
20:43clojurebot(1 2 3)
20:43emezeskeI guess technically that's longer :)
20:43octagonah true, identity is wrong there
20:44octagoncause you'd miss a false value
20:44bkirkbriyeah, (take-while identity) will stop at the first false
20:44thorbjornDXemezeske: complements to you :)
20:45octagon(comp not nil?) perhaps
20:45emezeskeoctagon: Why would you (comp not nil?) instead of (complement nil?) ?
20:46thorbjornDXI'd rather be idiomatic than as-short-as-possible
20:46octagonemezeske: haha you wouldn't
20:46emezeske:P
22:28mpanwow, job fair
22:29mpansome guy tried to convince me APL was just like Lisp
22:29mpano_O
22:29mpanI mean, I thought the CL folks didn't like it if you said Clojure was like Lisp
23:03ohpauleezI always thing there is a doc about not using (not (nil? x)) - and using something else instead
23:03ohpauleezam I crazy? or can someone tell me what I'm thinking of
23:03ohpauleezthink**
23:05ohpauleezoh duh, I can just use identity
23:05mpanwhat behavior are you looking for?
23:06mpan&(not (nil? false))
23:06lazybot⇒ true
23:06mpan&(identity false)
23:06lazybot⇒ false
23:06mpanidk if that case ever affects you, however
23:06mpanbut those aren't (in general) equivalent
23:10ohpauleezI'm looking for conditionals, not nil?
23:10ohpauleezis just identity
23:10ohpauleezfor general purposes
23:15ohpauleezoh for sure, I should have been more clear - it was a sequence of strings and nils
23:34Raynesohpauleez: Thanks for looking at that patch.
23:35ohpauleezRaynes: Np - I've been digging into a lot of node stuff, so i've been hitting all the node patches today
23:35ohpauleezand I'm familiar enough with all the CLJS source at this point