#clojure logs

2014-02-02

00:45insamniac:( Faber
01:07rovarwhat would be an elegant way to un-interleave?
01:07rovare.g. i have an alist and I want to break it out into 2 lists
01:17fowlslegsI am wondering what's causing this CompilerException... Seems like I am using recur from tail position.
01:17fowlslegshttp://paste.debian.net/79743/
01:18fowlslegsWorking on 4clojure #85 http://www.4clojure.com/problem/84 btw.
01:18fowlslegs*#84
01:51john2xare records the idiomatic way to model a datastore entry? Or just plain maps?
02:13seangrovejohn2x: Typically just plain ol' maps
02:27dsrx,(apply map vector [[:a 1] [:b 2] [:c 3]])
02:27clojurebot([:a :b :c] [1 2 3])
02:27dsrxrovar: ^
02:29amalloyfowlslegs: nowhere inside of a for-expression is in tail position, really
02:29rovardsrx, wowowow
02:30rovarmind is blown
02:33hiredman~for
02:33clojurebotfor is not a loop
02:47chchjesuslol
03:23regexkindhiya
03:23regexkindhas anyone on here made use of enlive?
03:24rhg135I have
03:24rhg135But for scraping
03:24regexkindYah that's what I'm trying to do
03:24regexkindbut not sure if you'd know this then:
03:24regexkinddo you know how to convert a collection of enlived data back into html?
03:25regexkindlike, I have a nested map, and I want the html back
03:25rhg135No idea sorry
03:25regexkind:/ ok
05:05quizdris the primary difference between get and nth the matter of exception throwing vs returning nil? and as such, the decision on which to use is primarly a decision of which of these two outcomes you'd prefer?
05:07amalloy&((juxt get nth) (list 1 2 3))
05:07lazybotclojure.lang.ArityException: Wrong number of args (1) passed to: core$get
05:07amalloy&((juxt get nth) (list 1 2 3) 1)
05:07lazybot⇒ [nil 2]
05:08quizdr amalloy the point you are making is that get is not available for lists, correct?
05:09amalloyyes; alternatively, get is always fast, while nth is willing to be O(n) if necessary
05:09quizdrbut as for vectors, for example, then the quesiton would be simply a matter of how the function handles if something is not found (assuming you do not use the not-found parameter), true?
05:09quizdroh, even on a vector, nth is O(n)?
05:10amalloyno, i said "if necessary", which it's not for vectors
05:11quizdr ok. when adding to the end of a vector, is push or assoc by vector length as key a better choice?
05:11amalloyfor vectors in particular, that's probably the only difference
05:11amalloypush doesn't exist; conj is the way to go (if it weren't, there would be almost no reason for conj to work on vectors)
05:12quizdrgot it.
05:13quizdrfinal question of the hour: when deciding whether to use a key as lookup function, or the map as lookup function, it should likely depend on whether either the key or the map could be nil, true?
05:14quizdr(inc amalloy)
05:14lazybot⇒ 82
05:15amalloysounds about right
05:15quizdrthanks, amalloy you are either up really early or really late, or what part of the world are you in?
05:16amalloycalifornia, so up lateish
05:17quizdrindeed
05:20quizdrdoes anyone know of any useful step-by-step tutorial for getting a clojure web dev environment going on the likes of Linode? something for someone with nearly no sysops experience.
05:27borkdudeHow can I calculate (partitions (range 1 27) :min 6 :max 6) without running into memory errors...?
05:35borkdudetoo many possibilities
05:36finishingmovewhat would be the idiomatic clojure way to do euler#1 (sum of multiples of 3 or 5 under 1000)
05:50dsrxfinishingmove: what does your solution look like?
05:50sm0kehey guys why isnt there a closed? open? in core.async?
05:51quizdrfinishingmove I can think of a variety of ways to do it, all in a single form. consider reduce, map, maybe filter. combining them will give you what you want
05:53finishingmovedsrx, first I had something like (apply + (filter is-multiple-of-3-or-5 (range 1000))), where is-multiple-of-3-or-5 is a custom function using "or" and "mod", but then I figured I can do something like (apply + (distinct (concat (range 0 1000 5) (range 0 1000 3)))), so I am liking that one more, but I hope it doesn't have some big performance penalty?
05:55quizdrfinishingmove regarding performance, reduce might be a better choice than apply
05:55rue__But correctness and clarity above all?
05:57finishingmoveI read somewhere that apply is considered more idiomatic Clojure than reduce.
05:57quizdrreally? that's interesting.
05:57quizdri'd like to see where that is written.
05:58finishingmovehttps://stackoverflow.com/questions/3153396/clojure-reduce-vs-apply
05:59quizdrsince apply basically calls a function with the list as its arguments, it can be a problem if the list is very long. however i'm coming from common lisp where implementations can widely vary and allow as little as 50 function parameters, making apply dangerous. I'd have assume clojure followed this idiom, even if the same restrictions didn't apply.
06:01quizdrin that stackoverflow question, notice the comment by the very wise cgrand
06:01finishingmovenow, how would this work on a lazy list ? From what I understand, range, concat and distinct would all return a lazy sequence. Does that makes "reduce" more favorable than "apply" in this case?
06:03quizdryour list is clearly finite so i wouldn't think that matters in this case unless you knew in advance you were not going to need all the elements in the sequence. but you do need them, because you are adding them together, so whether it is lazy or not I would think be moot
06:04finishingmoveAh, I see. I'm still new to lazyness... that makes sense though.
06:04opqdonutfikusz: for + it doesn't matter
06:04opqdonutoops
06:04opqdonutfikusz: ignore that
06:04opqdonutfinishingmove: for + is doesn't matter, the multi-arity version of + is implemented using apply
06:05opqdonutso (apply + list) and (reduce + list) are exactly the same, the former just has one indirection
06:05quizdropqdonut see this that suggests + is actually implemented using reduce: http://stackoverflow.com/a/3153643/768472
06:05dsrxI think you mean the multi-arity version of + is implemented using reduce
06:05opqdonuterr, that's what I mean
06:05opqdonut*meant
06:05dsrx(which is in agreement with the last thing you said)
06:07opqdonutI'm not sure which form I prefer, but I kinda feel like using apply for + and merge etc. is appropriate
06:07opqdonutbut it's only a couple of functions for which apply f and reduce f are the same thing
06:08quizdrthe arguments against apply have more weight in other lisps, so likely don't factor into the clojure idioms
06:09opqdonutyeah
06:12finishingmovereduce reads better to me, so I'll be using that, since the "idiomatic apply" mythn got busted (more or less)
06:13quizdri think your euler solution is not bad, the one contained in one form, not the one with the extra function
06:14quizdri'd bet it could be shorter, however. after doing many of the 4clojure problems i'm convinced there is always a shorter alternative
06:19hyPiRionI think rhickey commented that you should reduce whenever it makes semantically sense, except when you're calling `str`. Then it's cheaper and better to use apply
06:19deadghosthmm what
06:19deadghostI just tried it
06:19deadghostreduce + and apply str have better performance
06:20deadghostand now I'm aware I totally don't know what it's doing under the hood
06:20hyPiRion$source str
06:20lazybotstr is http://is.gd/k4S9Km
06:21piranhais there $source command for cljs? :)
06:22hyPiRioninstead of doing (str (str a b) c), (str a b c) creates a stringbuilder, which only creates a single string instead of several
06:23deadghostis stringbuilder javaspeak
06:23finishingmovesounds like something Gargamel invented and placed into the smurf village
06:24quizdrfinishingmove actually it is.
06:26quizdrfor anyone interested there are some nifty examples on this page: http://java.ociweb.com/mark/clojure/article.html I like the comparision of get-in with reduce for searching nested maps
06:27deadghostI like that guide
06:27deadghostthough I didn't read all of it
06:27deadghostgot me through cl -> clojure
06:27quizdryou should read all of it. it's not that long
06:27quizdrand what are your thoughts on cl vs clojure?
06:28deadghostI didn't use cl for very long
06:28deadghostbut my impression is stuff works in clojure
06:28deadghostand not so much in CL
06:29quizdrha ha
06:29quizdrwell i do find clojure easier to learn than CL. the immutability actually helps the learning process i think
06:29deadghostI think I went though 3 libraries to scrape something
06:29quizdrand clojure is more elegant as a lisp-1
06:29deadghostand none of them worked all the way
06:30deadghostdocumentation was spotty, quicklisp + asdf hard to figure out, and community not what I'd call friendly
06:31deadghostquizdr, did you learn by book or what
06:31deadghostI'd probably have a REALLY REALLY hard time with clojure if I didn't already 70% finish a CL book
06:31quizdryes i learn mainly from books
06:32quizdrthough with clojure there are other fantastic sources of learning too
06:32deadghostis there a good first clojure book?
06:32quizdrfor the basics in a quick and non-intimidating way, the Halloway book is good
06:32quizdrnot too long, but also not too deep
06:32finishingmovequizdr, I actually had that link bookmarked :) I'm one of those people who herd up on resources and read before they dig into anything :P
06:32quizdrfinishingmove so am i
06:33deadghostthe only clojure books I've thumbed through are web dev with clojure and clojure book
06:33quizdri've read about 4 clojure books at this point
06:33quizdri still have dumb questions every now and then however
06:33deadghostI like clojure book but holy crap it is dense
06:33quizdrsimple things i forget, because i'm also learning other languages for work, so it gets all mixed up in my head sometimes
06:34deadghostcommon lisp: a gentle introduction is symbolic computing is among my favorite books
06:34deadghostbecause it's actually pretty gentle
06:35quizdri think i have that one
06:35quizdri've got a ton of CL books
06:35quizdri try to implement their examples in clojure
06:35deadghostdid you get into CL much
06:35quizdrit's fun and you learn quickly that way
06:35jonasen_Anyone seen "Symbol's value as variable is void: cider-repl-input-start-mark" when doing M-x cider-jack-in?
06:35quizdri built some apps for myself in CL, simple things to parse text and store personal data. nothing too deep.
06:36quizdrjonasen_ can't say i have
06:36quizdrmaybe something in your project.clj settings?
06:36jonasen_quizdr: I've tried with two different projects..
06:36jonasen_same result
06:37deadghostjonasen_, are you using melpa
06:37jonasen_deadghost: not sure
06:37deadghostwhere are you getting cider?
06:37jonasen_deadghost: M-x package-install
06:37drorbemetHi, which clojure function is best for partitioning a lazy string by pattern? clojure.contrib.string/partition looks like it but there is no clojure.string/partition ?
06:38deadghostjonasen_, did you include melpa in your package-archives list in .emacs?
06:38jonasen_deadghost: let me check
06:38deadghostbecause melpa has a tendency to screw things up
06:38deadghostbecause it gets unstable stuff
06:39drorbemethttp://richhickey.github.io/clojure-contrib/string-api.html#clojure.contrib.string/partition
06:40jonasen_deadghost: (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
06:40jonasen_that's the only reference to package-archives in my init.el
06:40deadghostok then the issue isn't from melpa
06:40clojurebotTitim gan éirí ort.
06:41drorbemetclojure.string/split is not lazy http://clojure.github.io/clojure/clojure.string-api.html#clojure.string/split
06:42jonasen_deadghost: ok. It magically started working again... not sure what I did wrong previously
06:43deadghostjonasen_, then all is well
06:43deadghostfor now
06:43jonasen_deadghost: yep. 'til next time... Thanks for your help
06:48deadghostjonasen_, idk how you have/like your packages set up but you might want to consider something like this in your .emacs: http://pastebin.com/YS0w2gTG
06:49deadghostso it installs packages from a list on startup instead of M-x package-install
06:50jonasen_deadghost: thanks. I'll consider it.
06:57quizdrSo when you pass args to a multimethod, those args are actually evaluated for two different functions: the dispatch as well as the multimethod. 2 procedures for the same args, where the first procedure chooses the second procedure. sound correct?
07:38sobeli wish i could find SQL libraries that i don't hate
07:39sobeli reeeaaally don't want an ORM or a DSL in front of SQL, i just want simple parameter mapping like psycopg2
07:41sobeland i don't want it to fight me on custom data types. postgres has a very useful type system that's been extended for json, hstore, inet, array, and geospatial types that are non standard
07:41sobelbut so useful
07:42sobeli find it wrong and wrongful to a) put big queries in client code and b) deal with leaky abstractions like HoneySQL
07:43sobelthe jdbc library shouldn't be trying to save the poor clojurist from dealing with SQL directly. it should make dealing with SQL directly conevient.
07:44steckerhaltera bear should not be a fish
07:49sobelwell, i can't promote clojure as viable data access tool until i figure out decent jdbc usage
07:50sobeli can rewrite some queries but not all to work around array types
08:26scape_sobel: to work around array types... is this within honeysql? have you given korma a chance. it's not ideal perhaps but might be a better choice
08:27sobelno, the limitations of those DSLs are problematic, too
08:59gfrederickssobel: so I've done a lot of this sort of thing
09:00gfrederickssobel: I'm interested in why you see honeysql as a leaky abstraction; to me it's just a way of assembling sql queries programmatically that uses data instead of string manipulation
09:00gfredericksif you're not making your sql queries programmatically it's not a big win, and it's not a big deal if you just decide not to use it
09:02gfrederickse.g., if I want to create a query-1! function that checks that the query gets exactly one result, and does it by adding "LIMIT 2" to the query, you can do that with honeysql without worrying about A) whether LIMIT always goes at the end or if there might be something extra after that I have to worry about when doing my string concatenation, and B) whether the incoming query already has a LIMIT clause on it
09:03gfredericksand regarding custom types, all the plumbing has been added to java.jdbc to handle this in both writes and reads; it's just not necessarily super convenient yet
09:03gfredericksI think the worst part is postgres arrays; for writing them I haven't figured out how to do it without mucking with some sort of baseTypeName in the jdbc interop
09:03gfrederickscertainly it's no worse than in java
09:04sobelgfredericks: honeysql is a leaky abstraction because it must track every bit of syntax in the sql dialect. i don't see the point of an isomorphic DSL.
09:04sobeli mean, either it's isomorphic (and pointless in my view) or it's leaky
09:05sobeli also think constructing queries at runtime (especially in client code) is poor design
09:07sobelnail it down.
09:08gfrederickssobel: so do you embrace redundancy in your queries, or do you think there's some way of avoiding it in the data model?
09:08sobelwhat redundancy?
09:08gfrederickse.g., if I have two similar tables
09:09gfredericksand want to query them in similar but not identical ways
09:09gfredericksthen either I have two queries with similar structure and thus shared information
09:09gfredericksor I'm creating the query programmatically
09:09sobeli would have to see more of the design in particular
09:09gfrederickswell, how about the query-1! example
09:10gfredericksdo you just append LIMIT 1 every time you make such a query?
09:10gfredericksrepeating the logic?
09:10gfredericksLIMIT 2 rather
09:10sobelsec.. (phone)
09:20llasramgfredericks: That looks pretty slick. I had not actually looked at honeysql but had also mentally slotted it into the "sad DSL" category. Actually looking at it, it looks great
09:21gfredericksllasram: yeah in my experience it's minimal enough to not be dumb, and whenever it "leaks" and can't do what you want you can drop back to strings with no problem
09:22gfredericksit's all pure functions so it's simple to verify that it's doing what you think it is
09:22gfredericksSQL is the sad DSL :)
09:22sobelSQL is a category of database-specific DSLs
09:22llasram:-)
09:23gfrederickssobel: something data oriented would be more useful
09:23rovarerrg..
09:23rovarI'm passing in [:6 2] to https://www.refheap.com/31630
09:23rovarand getting java.lang.IllegalArgumentException: No matching clause: [:6 2]
09:24sobelthe common ground (standard SQL) is suitable for most data operations but most interesting things are not spec'd in the standard
09:24rovarI don't see how [[a 2]] doesn't match that
09:24sobelso you have DML that is fairly portable, at least, when the schema is implemented the same
09:25gfrederickssobel: suitable for low-level data operations maybe, but not trying to build abstractions on top of
09:25sobelexactly. it is not suitable for building DSLs on top of.
09:25sobeleach SQL is its own DSL for its database.
09:25gfredericksI don't mean DSLs
09:26sobelfirst of all, if i have LIMIT 1 in a query in client code, i have lost
09:27gfrederickswhy's that?
09:27sobelif it's that important it should be a function or a view
09:28karlshey guys. quick question - why is it when i do (class {:key "val"}) => clojure.lang.PersistentArrayMap, but when i def the same thing and call class on the resulting var, it gives back clojure.lang.PersistentHashMap? https://www.refheap.com/31632
09:29gfrederickskarls: that's terribly interesting and I have no idea
09:29sobelif you look at the database in OO terms, most of the tables are private implementations. or should be. care must be taken to minimize the public interface or you end up with mad coupling
09:29gfrederickskarls: hash maps are used for larger maps; in general you can ignore the difference
09:29gfrederickssobel: okay, so you do your abstracting using db mechanism like functions/views
09:30sobela LIMIT clause in client queries tells me it is peeking too deeply into the implementation
09:30sobelgfredericks: i wouldn't call it abstracting, but i do limit my public db interface that way
09:30karlsgfredericks: hm.. this makes multimethods that dispatch on the class of an argument pretty annoying.
09:30sobela table is an acceptable part of a public interface, but it should be intentional
09:31gfrederickssobel: which means your application logic is spread across your development language and your sql db code
09:31gfrederickskarls: use IPersistentMap instead
09:31sobeldon't tell me there's a bright line between storage logic, business logic, and application logic
09:31sobelbecause there isn't
09:32sobelthe database enforces application design all the time
09:32gfrederickssobel: I'm not telling you anything I'm trying to noodle through the differences in how we approach problems
09:32sobeldata structures are part of application logic
09:32sobelso i would say application logic is spread through client and database code
09:33gfrederickssobel: I think clojureland people like to maximize their ability to try new things in seconds at the repl; so to the extent that trying new things requires installing things in the database that could be more dificult
09:33sobelgfredericks: that is not a clojureland thing, that is common to pretty much all devs who are not data engineers. that approach is just irrational when you already have a database in play.
09:34gfrederickssobel: okay; I don't have a good way to evaluate the different perspectives, so I will have to drop out of this discussion on account of Not Smart Enough
09:34sobelgfredericks: thanks, i do hope to crack this nut of appropriate data access!
09:34karlsgfredericks: that sounds reasonable. how would i go about using that in a multimethod though?
09:34gfrederickskarls: the same way you use the classes
09:35gfrederickssobel: let me know if you need help with java.jdbc & custom types
09:36sobelgfredericks: i actually will. looks like i won't get to spend today coding but over the next couple weeks i hope to have it all nailed down. if i can just get a library of functions based on about 6 queries to work well, i will have everything i need to write a sweet proof-of-principle app for work
09:37llasramsobel: OOC, where do you work, if you don't mind my asking?
09:37sobelllasram: it's a Chicago based finance co. called Enova
09:37llasramcool
09:38sobelthere is exactly one clojure app in production already. i'm tight with the guy that wrote it, and he's more or less my main inspiration to look into clojure.
09:38sobelbut i found out it doesn't even touch jdbc. i'd thought he was using our usual postgresql backend but he apparently went with some nosql db.
09:39sobel(and fair enough, he didn't know you could just pervert postgresql tables to serve blobs quite nicely)
09:40karlsgfredericks: i'm still a bit confused. i thought multimethods dispatch on a value?
09:40gfrederickskarls: how were you trying to use them before you started asking questions?
09:41karlsin the case of a class, you just "switch" on the class name.
09:41gfrederickskarls: IPersistentMap is a classname in that respect
09:41quizdrSo when you pass args to a multimethod, those args are actually
09:41quizdr evaluated for two different functions: the dispatch as well as the
09:41quizdr multimethod. 2 procedures for the same args, where the first
09:41quizdr procedure chooses the second procedure. sound correct?
09:41quizdr
09:41quizdryikes! sorry
09:41gfredericks,(defmulti crepes class)
09:41clojurebot#'sandbox/crepes
09:42gfredericks,(defmethod crepes java.lang.Number [x] (inc x))
09:42clojurebot#<MultiFn clojure.lang.MultiFn@1fdd37d>
09:42karlsgfredericks: a multimethod that dispatches on the class of the second argument. and then i came across this {} vs (def m {}) issue.
09:42gfredericks,(crepes 41)
09:42clojurebot42
09:42gfredericks,(defmethod crepes clojure.lang.IPersistentMap [m] (assoc m :num 42))
09:42clojurebot#<MultiFn clojure.lang.MultiFn@1fdd37d>
09:42gfredericks,(crepes {})
09:42clojurebot{:num 42}
09:42gfredericks,(crepes (array-map :a 9))
09:42clojurebot{:num 42, :a 9}
09:43gfredericks,(crepes (hash-map :b 10))
09:43clojurebot{:b 10, :num 42}
09:43gfrederickskarls: ^ looks like it all works?
09:43karlsgfredericks: !
09:43karlsthat's great!
09:43karlsgfredericks: thanks!
09:43gfredericksnp
09:46karlsgfredericks: that's really cool. i wasn't aware that IPersistentMap "counts" as a class.
09:47gfredericksinterfaces are classes for a lot of purposes
09:47gfredericks,(instance? clojure.lang.IPersistentMap {})
09:47clojurebottrue
09:47gfredericks^ that purpose is probably the most relevant
09:47karlsindeed. that's really nice.
10:10hyPiRion,(instance? clojure.lang.IPersistentCollection {})
10:10clojurebottrue
10:22AeroNotix,(anscestors clojure.lang.IPersistentCollection)
10:22clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: anscestors in this context, compiling:(NO_SOURCE_PATH:0:0)>
10:22AeroNotix,(ancestors clojure.lang.IPersistentCollection)
10:22clojurebot#{clojure.lang.Seqable}
10:49rovaris there a way to get lein to load a plugin? I'm trying to run lein midje.. I have it in my :profiles :dev :plugins
10:49rovarbut when I run lein midje, it says it's not a task
10:49rovar :profiles {:dev {:dependencies [[midje "1.6.0"]]}
10:49rovar :plugins [[lein-midje "3.1.3"]]}
10:51konrwhat's the other special symbol valid inside macros, besides &form?
10:51llasramrovar: It may need to be in your top-level `plugins`, or in your profiles.clj `:user` profile plugins. I'd need to look at the code to recall the order of profile application vs plugin-resolution
10:51llasramkonr: You mean &env ?
10:52rovarllasram, it works when I put it in my user profile, but I'm trying to make this project workable for export.. i'll try putting it into top level plugins
10:52konrllasram: yes, thanks!
11:04gfrederickskonr: (source defmacro) has those somewhere ;-)
11:13fowlslegsHey all! I'm working on 4clojure problem 84 http://www.4clojure.com/problem/84 and am running into problems with recursion in my script. It seems like I am recurring from tail position, but I'm getting an error that I'm not http://paste.debian.net/79743.
11:17schmirfowlslegs: http://stackoverflow.com/questions/7813497/clojure-what-exactly-is-tail-position-for-recur may help
11:19schmirit's not in tail position because it's enclosed by the outer for
11:38technomancyrovar: top-level :plugins is the usual way to go, but I'm surprised it doesn't work in :dev :plugins
12:52gzymsiuhi all
13:21albert_I'm trying to compile a google closure aware javascript file into my clojurescript compilation set. I noticed that when I do this and require the provided namespace in my clojurescript code via (:require [my.gc.ns]) it works, but If I dont require it, it doesn't seem to be added to the compilation set. Is there a way to get it added to the compilation set without having to require it in the clojurescript source file
13:27albert_that is, my namespacing of my javascript file via goog.provide("my.namespace") isn't being added to my code
13:28albert_even after including the gc aware file in my project.clj :libs
13:33dnolenalbert_: you need to require it. Is there a point to not doing so?
13:34albert_dnolen: yes, the file depends on some clojurescript namespaces, so requiring results in a circular dependcy
13:35dnolenalbert_: there's not much you can do except break the circularly dependency.
13:42sdegutisWell then.
13:50gfrederickssomebody was asking earlier why (def m {1 2}) creates a hash-map rather than an array-map, and I had no idea; does anybody else?
13:51borkdudegfredericks that is indeed odd
13:51gfredericks,(class {1 2})
13:51clojurebotclojure.lang.PersistentArrayMap
13:52gfredericks,(def m {1 2})
13:52clojurebot#'sandbox/m
13:52gfredericks,(class m)
13:52clojurebotclojure.lang.PersistentHashMap
13:52gfredericksI'm a little weirded out that I didn't know about this before
13:52andyffowlslegs: The error message may be confusing, but I think it is because the recur is inside neither a loop nor fn expression.
13:53Bronsagfredericks: I have a patch in jira for that
13:53Bronsalet me find it
13:54andyfgfredericks: CLJ-944 comments and analysis may shed some light on it. I believe there is a path through the code that does not create PersistentArrayMap's for small maps, whereas most others do
13:54Bronsagfredericks: http://dev.clojure.org/jira/browse/CLJ-944
13:54Bronsaandyf: you beat me :)
13:54gfredericksomg guy s/then/than/
13:54gfredericksdo I have permissions to edit the title?
13:55gfredericksI do!
13:55gfredericksis that going to distract anybody's inbox?
13:55Bronsawho cares.
13:55andyfOnly the creator and 3 watchers, I think
13:55gfredericksokay well they deserve it then :)
13:56gfredericksokay finally the important aspects of this ticket have been attended to
13:56andyfYeah, it is totally going to be fixed tomorrow now :-) (yes, sarcasm)
14:07arrdemaugustl: interesting OS idea... I'll be watching with interest :D
14:09arrdemaugustl: are you planning to try and bootstrap a JIT'd environment, or shooting for something simpler?
14:25augustlarrdem: thanks :) I do like the idea of JIT for the system language. Not sure how much work it is.. And the less work I have to do, the better :)
14:27arrdemaugustl: I'm just curious because a longtime idea of mine has been to take a Clojure-like system and build an OS based around jiting all the "immutable data" semantics out into a real metal-friendly runtime with programmer friendly semantics.
14:28AeroNotixhttps://github.com/lshift/cloverage/issues/33
14:29AeroNotixif anyone's interested^ weird error when using Cloverage with some macros I wrote.
14:29gfredericksHuh. I wonder if pure functions would allow you to do "reference prediction". E.g., "I'm going to just mutate this data structure assuming nobody will need the old copy, and if I turn out to be wrong we'll just back up."
14:29augustlarrdem: sounds like we basically have the same idea :)
14:29arrdemaugustl: :D
14:29augustlarrdem: hopefully the entire IP stack will be written in the JIT-ed system language. Why does IP need to be written in machine code?
14:29arrdemgfredericks: that's data liveness analysis. old compilers topic.
14:30gfredericksarrdem: yeah no way could I be original
14:30arrdemaugustl: JIT'd drivers? up top man, exactly what I wanted.
14:30augustlarrdem: if you're the only one that had an idea, it's probably a bad idea, as they say :)
14:31augustlsomeone on HN suggested forking an existing small OS, will probably do that, current progress is a basic understanding of EFI booting and no actual relevant code..
14:32arrdemhaha, that's where all of this stuff starts... an idea and no code :P
14:32bbloomaugustl: you should look the work from Alan Kay's Viewpoints research lab
14:32bbloomaugustl: they implemented a TCP/IP stack as a non-deterministic peg parser with ometa
14:33augustlarrdem: at least I'm past the infamous "mkdir ...." problem (I have a name for it)
14:33augustlbbloom: ah, very cool
14:33augustlI'm the first to admit that my lack of familiarity of prior art is disturbing to say the least.. :) Basically only Clojure and some Linux.
14:33bbloomaugustl: i was gonna write a big comment on HN, but decided not to bother with that hostile audience
14:33arrdemaugustl: get a runtime first, then we can worry about building a saner filesystem :P
14:34bbloomaugustl: yeah, you're basically doomed unless you pick a particular problem you want to solve
14:34bbloomaugustl: is the goal just to learn something for yourself?
14:35augustlbbloom: that is at least a part of it, I consider it a research project, not a practical OS anyone will ever run
14:36bbloomaugustl: do you have any need for it to actually boot? i think you might be interested in simply building a VM instead of an OS
14:37bbloomthere are lots of very smart folks who have worked on language VMs who think that multi-language VMs are kinda a bad idea, but there are other folks who think that multilanguage VMs are the OSes of the future
14:37bbloomi'm still not sure what camp i'm in :-)
14:37bbloomone thing is for sure: hardware sucks :-P
14:37arrdembbloom: common runtimes are awesome :D
14:37augustlbbloom: a month ago I thought doing it on bare metal would be cool
14:37arrdemaugustl: oh gods why
14:37augustlbut now that I haven't gotten anywhere... Perhaps a VM is a good first step.
14:38bbloomaugustl: have you ever implemented your own little lisp or GC or anything like that?
14:38bbloomaugustl: maybe start there
14:38augustlideally not with too many dependencies on the OS so it can run on the bare metal in the future :)
14:38bbloomit's a right of passage after all :-)
14:39augustltrue that :) I've written a lisp in Ruby once, using ruby data so I didn't need a parser :)
14:39bbloomarrdem: at this point, it's not clear we as a discipline understand well enough to create a truly useful cross-language VM
14:39bbloomaugustl: parsing is it's own entire rabbit hole
14:39bbloomyou can fall down the parsing hole and never come out :-P
14:41arrdembbloom: how so. We may not be able to build runtimes which are in some sense "optimal" for all languages, but that doesn't mean we don't know full well how to point multiple languages at a single common JIT'd runtime.
14:41arrdembbloom: and that is, I think, good enough
14:42bbloomarrdem: that's a turing tarpit argument
14:43bbloomarrdem: there are things we simply can't do on the JVM without being prohibitively complex or slow
14:44arrdembbloom: the usual whipping boy being primitive arithmetic... yes.
14:45bbloomarrdem: or much more interesting features, like copy-on-write VM images, or delimited continuations, or more
14:49arrdembbloom: we'll just have to see where the world goes. I think that while these things are indeed hard, working with metal is no nicer and that thanks to the reusability and performance gains which JIT'd systems _can_ offer we will see them increase in use whether or not we can do them "right".
14:50bbloomarrdem: i think we need a lot more VM investment/research
14:50bbloomarrdem: i think that multilanguage VMs are the future... they just aren't the present
14:51bbloomfrankly, as nice as clojure is on the JVM, it was designed to fit in to constrained hosts
14:51bbloomwhich was a brilliant move for rich's goals
14:51bbloombut if you've got research goals, i'd probably target the VM level
14:51gratimaxaside question, do you think we'll see more optimized dynamic language vms in the future? there must be quite a few hoops to jump getting a dynamic language like clojure running on the jvm
14:52arrdemgratimax: people will continue to run dynamic languages on VMs and they will continue to be slow
14:52bbloomgratimax: that's less true than you'd think. turns out that the JVM is basically already a dynamic language itself
14:52dnolengratimax: getting dynamic languages to run on the JVM isn't that hard. Making them as fast as Clojure however is another matter.
14:52arrdemgratimax: so much of compiler driven optimization is type dependant that static types and type analyisis are really critical to "high performance".
14:53bbloomarrdem: i'd argue that performance is about specialization, of which static types is only a small part of a balanced strategy :-)
14:55arrdembbloom: let me get my masters, then we can have this talk :P
15:20lvh_hi!
15:20gfrederickslvh_: hallo
15:20lvh_I want to write some clojurescript, and I have a porject which is perfect for a d3.js treemap
15:20lvh_is strokes the thing to use? or should I just use d3 directly
15:21lvh_it doesn't seem to hard either way; for d3 I can just do (-> (whatever) (something else0)
15:22dnolenlvh_: either approach is probably going to be OK. strokes just makes it so that you can use CLJS data structures instead of JS arrays / objects.
15:23lvh_oh. that seems like mostly a win except I don't expect to change the data at all
15:27i_swhere is this macro now? "-?>" ? (cant get search working for that term)
15:29rebcabini_s: github/rplevy/swiss-arrows
15:29rebcabini think that's what you're looking for
15:29bbloom(doc some->) ; i_s
15:29clojurebot"([expr & forms]); When expr is not nil, threads it into the first form (via ->), and when that result is not nil, through the next etc"
15:29i_sgreat, thank you
15:37lvh_is clojure.java.io still what I use to read a line from a file? It seems I want clojure.contrib.io maybe.
15:38llasramlvh_: clojure.contrib.* is ancient history
15:38lvh_is clojure.contrib.io.read-lines old and busted or something
15:38lvh_okay
15:39llasramlvh_: You want clojure.java.io/reader
15:39llasramlike: (with-open [inr (io/reader filename)] (->> inr line-seq do-stuff))
15:39lvh_so (first (line-seq (reader "fn"))?
15:39lvh_oh, okay.
15:40llasramYours is fine except you'll want to `with-open` the reader
15:40llasramWell, which means it needs to go lexically outside the rest of it :-)
15:40lvh_that closes the file, I'm guessing? anyway I'll go read clojure.java.io
15:40lvh_Thank you!
15:40llasramYeah -- its a macro which expands to a try..finally block
15:40llasramnp
15:41AeroNotixis anyone using Cloverage?
15:50AeroNotixdo my messages appear here?
15:50gfredericks,'yup
15:50clojurebotyup
15:50AeroNotixah ok
15:51gfredericksapparently cloverage coverage amongst the channel members is lacking
15:51gfredericksalso maybe sunday is slow
15:51AeroNotixgfredericks: I've asked this several times before and it seems that coverage data is not something that people use.
15:52llasramHmm?
15:52gfredericksAeroNotix: I saw another library the other day and was going to try it but haven't yet
15:52AeroNotixCloverage is the most widely developed, so far
15:52AeroNotixgfredericks: yes? Do you remember it?
15:52gfredericksI think it was the piplin fellah
15:52gfrederickslemmeesee
15:52AeroNotixok
15:53gfrederickshttps://github.com/dgrnbrg/guzheng
15:53gfredericksI hadn't heard of cloverage
15:53gfredericksI haven't been looking for a coverage tool though I just stumbled on guzheng
15:54AeroNotixgfredericks: cloverage seems to work fine... I've just come up against a bug, though. I'm generating defrecords with macros and it seems to choke on that
15:54AeroNotixand the output is a custom reporting output, so I can't plug it into e.g. cobertura
15:56AeroNotixok so guzheng didn't die when running
15:57gfredericksthe less catchy the name, the less it crashes
15:58AeroNotixgfredericks: any idea how to get the info out of it? It doesn't generate any files
15:58gfredericksAeroNotix: I know nothing about it, sorry
15:58AeroNotixgfredericks: cheers anyway
16:00AeroNotixgfredericks: I just use it to mean "thank you"
16:00AeroNotixbut that might be an Englishism
16:00gfredericksthat is what urban dictionary told me
16:00AeroNotixAmerican'ts might try to use it but they just sound weird saying "cheers"
16:00AeroNotixamericant's*
16:01AeroNotixlol spelling
16:01AeroNotixwhatever, it's late
16:01gfredericksthe weird part is the definition said you can also use it after *giving* something
16:01AeroNotixgfredericks: i've never used it like that, but English is full of contradictions
16:02gfredericks(inc english)
16:02lazybot⇒ 0
16:02gfrederickslol
16:02llasramnice
16:02gfredericksalright well now I can be british
16:02lvh_Hi! I'm parsing some apache log lines; I really only want the URL path
16:02lvh_is there a thing I can just use that will magically parse apache web server logs?
16:03llasramlvh_: There is almost certainly an existing Java library for that
16:04AeroNotixlvh_: qtile?
16:05lvh_I only know that as a window manager
16:05llasramYou know what, I'm going to downgrade that to "probably"
16:05lvh_llasram: there's a URL parsing lib for clj, but not really paths
16:05lvh_maybe it just magically works
16:06llasramlvh_: Oh, if you've already gotten the URL part, then there's lots of options for then parsing the URL
16:06lvh_llasram: no, I don't, sorry
16:06llasram,(.getPath (URI. "http://example.com/fun/time/path&quot;))
16:06clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: URI, compiling:(NO_SOURCE_PATH:0:0)>
16:06llasramPfft
16:06lvh_I have Apache web server log lines
16:06llasram,(.getPath (java.net.URI. "http://example.com/fun/time/path&quot;))
16:06clojurebot"/fun/time/path"
16:06lvh_I want the paths out of them
16:06llasramOk, I see
16:07llasramYeah -- so that seems like a really common task, but I don't know of an existing library right off the top of my head
16:07AeroNotixlvh_: yeah I just remember your handle in the context of qtile... not sure why
16:07lvh_I guess maybe I can do a regex match for "(?:GET|POST|PUT|DELETE) (.*) (?:HTTP)"
16:07lvh_what's not-greedy * spelled in clj/java?
16:07llasram*?
16:07clojurebot* is just for when you are lazy and sloppy
16:07llasramheh
16:08llasramHaha, here's an especially exciting regex solution: http://scalability.org/?p=3802
16:11lvh_,(re-find #"(?:GET|POST|PUT|DELETE) (.*?) (?:HTTP)" "121.243.231.243 - - [20/Jan/2014:06:31:43 +0100] \"GET /images/nav-off-bg.png HTTP/1.1\" 200 310 \"http://www.python.org/\&quot; \"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\"")
16:12clojurebot["GET /images/nav-off-bg.png HTTP" "/images/nav-off-bg.png"]
16:12lvh_I don't understand why that gives me two results.
16:12lvh_Didn't I just make the outside groups non-capturing?
16:13rue__lvh_: Non-capturing means into a numbered group
16:14rue__So you are still /matching/ the string, but your only match group is the middle string.
16:16lvh_rue__: I got the latter, not the former sentence.
16:16lvh_rue__: How do I get just the match group?
16:16rue__It’s the second value in your vector there
16:16lvh_rue__: Sure, but I mean in general
16:16lvh_sorry, I'm used to named groups
16:17rue__I’m not sure I understand? That’s how you’d do it… match, and then take the groups you’re interested in. There are zero-width negative modifiers (which leave out a matched part from the result, in effect), but I’m not sure it’s worth it
16:18oetjenjnon-capturing doesn't mean capture into numbered group, non-capturing means - as it implies - no capture at all ;) try the regex without non-caputing (and use capturing instead) and compare the results
16:19gfredericksI think lvh_ might want a single string back
16:19gfredericks,(re-find #".{3}" "hey look at this")
16:19clojurebot"hey"
16:19rue__#"(?<!GET|POST|PUT|DELETE) (.*?) (?!HTTP)", I think
16:19lvh_Sorry, I was confusing zero-width with non-capturing
16:19lvh_rue__: What's the difference between ?<! and ?!
16:20rue__Former is lookbehind, latter is lookahead
16:20TEttingerlvh, I believe re-find will always return a sequence of the full matched string as the first element, followd by any captured groups, if there are any groupings in the regex.
16:20rue__^
16:20oetjenjTEttinger, correct
16:21oetjenjunless there is no match, than re-find returns nil, iirc
16:21lvh_rue__: ah, thanks
16:21Wild_Catwouldn't you want re-groups instead, though?
16:21lvh_TEttinger: aha; so if I have one matched group...
16:21gfredericksTEttinger: it returns a string if there are no matched groupos
16:21gfredericksas I demonstrated above
16:21TEttingeryep
16:23rue__You have one not non-capturing group, which is returned :)
16:23KrajsnickHow come (filter even? (range 1 10)) works without wrapping the even? predicate but you can't use javas Character/isDigit ? Does it have something to do with the function needs to be a clojure function?
16:23elarsonI was trying to play with the clojure.data.csv module via a simple script with lein exec but I get a file not found exception when I require clojure.data.csv.
16:23gfredericksKrajsnick: yeah, java methods aren't first class in that way
16:23elarsonI understand I'm not getting the right classpath configured, but I sort of assumed lein was taking care of adding standard clojure libs
16:24KrajsnickAh okay, so as a rule of thumb when sending functions as arguments, wrap them if you're using java interop?
16:24gfrederickselarson: you have to add it to your :dependencies list
16:24gfredericksKrajsnick: yep
16:24Krajsnickthanks
16:24elarsongfredericks: is that something I can do in a single file? ie not via the project.clj
16:24gfredericksnot with leiningen
16:24elarsonthis is just a single file I'm wanting to run as a script
16:25gfredericksleiningen is pretty project-oriented
16:25gfredericksif it has any single-file features I don't know about them
16:26elarsonwell, I found out about lein-exec http://koodo.wordpress.com/2013/11/09/shell-scripting-with-clojure/
16:26lvh_Does #"whatever" actually compile the regex? I'm having difficulty figuring out what kind of object it is
16:26elarsonah and it looks in that blog I might abel to include some deps
16:26elarsongfredericks: thanks for the help
16:27gfrederickselarson: yeah that looks possible
16:27oetjenjelarson, have a look at https://github.com/mtyaka/lein-oneoff ... might be what you are looking for, too
16:27rue__lvh_: It’s a literal, isn’t it?
16:27elarsonoetjenj: great, will do'
16:27gfrederickslvh_: yeah I think it does
16:27gfredericks,(type #"foo")
16:27clojurebotjava.util.regex.Pattern
16:28lvh_Ah, I didn't know about type :)
16:28gfrederickslvh_: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L439
16:28gfredericksthe reader compiles it
16:29lvh_(def lines (with-open [inr (reader filename)] (->> inr line-seq (take 5)))) ;; IOException Stream closed java.io.BufferedReader.ensureOpen (BufferedReader.java:115)
16:29gfredericks,(type (read-string "#\"foo\""))
16:29clojurebotjava.util.regex.Pattern
16:29lvh_Why does that close it already? I'd expect to get the first five lines.
16:29gfrederickslvh_: because take is lazy
16:29hiredman,(doc line-seq)
16:29gfrederickstry adding (doall) after take
16:29clojurebot"([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."
16:30lvh_that'll be handy :) thanks :)
16:30lvh_(inc gfredericks)
16:30lazybot⇒ 39
16:31lvh_(why isn't it more like (swap! gfredericks inc)?)
16:31gfredericksthen less people would type it
16:31gfredericksinc! would be nice maybe
16:32lvh_oh, by the way, this is a paredit question, but I seem to remember that there was a way to change the paren-type (so e.g. I have al ist and I want a vector)
16:32gfredericksI think there is an easier way but I always do it by making a vector before the list, slurping the list in, then splicing everything in the list into the vector
16:33lvh_yeah, that's what I do too
16:33lvh_except in the opposite order
16:33lvh_but otherwise equivalent I think
16:34gfredericksI would think the opposite order would be more steps
16:34gfredericksN slurps instead of 1
16:37amalloyparedit-wrap-square reduces the number of steps, compared to square+slurp
16:37TEttingerlvh_:
16:37TEttinger,(re-find #"(?<=(?:GET|POST|PUT|DELETE) ).*(?= (?:HTTP))" "121.243.231.243 - - [20/Jan/2014:06:31:43 +0100] \"GET /images/nav-off-bg.png HTTP/1.1\" 200 310 \"http://www.python.org/\&quot; \"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\"")
16:37clojurebot"/images/nav-off-bg.png"
16:42dbaschanybody using the latest LightTable in OSX? I can't get instarepl to work
16:43elarsonthis might be a dumb question, but does a hashmap have to use a symbol as a key? I'd like to do {"First Name" "firstname"}
16:43llasram~tias
16:43clojurebottias is try it and see
16:43Guest80042dbasch: How is it failing? It works for me.
16:43gfredericks(inc llasram)
16:43lazybot⇒ 15
16:43elarsonllasram: well I did try it and it failed, which is why I asked
16:43gfredericksllasram: my first thought was "ooh ooh I know that one!"
16:43elarsonthe error wasn't really clear
16:43gfrederickselarson: what was it?
16:44dbaschGuest80042: I try to evaluate anything and I get an exception: http://pastebin.com/HfwKqU8c
16:44scape_,{"one" 1}
16:44clojurebot{"one" 1}
16:44elarsongfredericks: java.lang.IllegalArgumentException: Parameter declaration missing
16:44gfredericks,(defn foo {"foo" 42})
16:44clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Parameter declaration missing>
16:44TEttingerelarson, hashmaps can be anything for keys, but usually you use keys for getting from a hashmap because they let you do ##(:key {:key :value})
16:44lazybot⇒ :value
16:44gfrederickselarson: like that? ^
16:44scape_no defn
16:44scape_just def
16:45oetjenj,({"First Name" "a name} "First Name")
16:45clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading string>
16:45TEttinger##({"key" :value} "key") also works
16:45lazybot⇒ :value
16:45TEttingerbut not ##("key" {"key" :value})
16:45lazybotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
16:45Guest80042dbasch: Sorry, don't know what's going on there.
16:46seangrov`dbasch: Just a guess http://stackoverflow.com/questions/8801142/sonar-build-fails-with-nullpointerexception
16:46elarsonTEttinger: so that looks like I do need a symbol
16:46seangrov`Might need to upgrade your jre/jdk?
16:46elarsonbtw, here is what I was doing: https://gist.github.com/ionrock/8775341
16:46TEttingerkeywords are functions that can take a hashmap, but other types can be used if you have the hashmap as the fn
16:46gfrederickselarson: keys can be anything
16:46llasramelarson: defn vs dev
16:46scape_don't use defn
16:46llasramdef even
16:47dbaschseangrov`: I'm using build 1.7.0_09-b05, how about you?
16:47Guest80042dbasch: I'm using 1.7.0_51-b13
16:47elarson(inc llasram)
16:47lazybot⇒ 16
16:47elarsonthanks llasram
16:47llasramnp!
16:48gfredericksalso thanks scape_ who pointed it out first :)
16:48scape_going to slink away now
16:48scape_:D
16:48elarsonand thanks TEttinger confirming keys can be anything
16:48gfredericks,{{} {}}
16:48clojurebot{{} {}}
16:48dbaschI'll upgrade to the latest jdk7 and try again
16:48arrdemaugustl: oh gods and you want to do a rust kernel... I should just watch this repo now :P
16:48scape_i think keys being actual keys is much faster as a lookup in a map-- i assume at least
16:48gfredericks"actual keywords"
16:49scape_thanks yes gfredericks
16:49seangrov`dbasch: javac -version => javac 1.7.0_21
16:50scape_gfredericks: my middle name is frederick and last name starts with a g :D
16:51Guest96402dbasch, seangrov`: The bug says it affects version 6 but not 7, so it'll be weird if that corrects the problem
16:51dbaschGuest96402: that didn't fix it
16:51gfredericksScape Frederick Gorschtarch
16:51scape_ha
16:51gfredericksoh so the 's' in my nick must be fore "scape"
16:51dbaschGuest96402: the weirdest part is that the spinner doesn't stop after fetching dependencies
16:52scape_hah
16:52gfredericksg___ frederick s(cape_)
16:52dbaschI launch instarepl, it goes connecting... -> fetching dependencies... -> (nothing)
16:52dbaschbut the spinner doesn't stop
16:52seangrov`dbasch: It's probably failing to start some nrepl project, and then it has to wait ~30s or so for the threads to finally exit, and it's not communicating it to you
16:52Guest96402Hmm, what happens if you do a lein repl in the project directory?
16:53dbaschGuest96402: this is not in any particular project
16:53dbaschleon repo works fine in all my projects
16:53dbaschlein repl
16:54TEttingerI have dbasch's problem whenever I use light table
16:54oetjenjelarson, btw you can easily turn string into keywords with (keyword "Some string"), in case you use String keys because you got them from parsed content or something similar
16:54elarsonoetjenj: ah that is good to know
16:54elarsonthanks
16:54oetjenjyour welcome ;)
16:55seangrov`ibdknox: Where's the best place to get support for lighttable for dbasch and TEttinger? the ml?
16:55rebcabin,(keyword "what happens with spaces")
16:55clojurebot:what happens with spaces
16:56lvh_rebcabin: yeah I found this useful while interpolating some stuff from csv recently
16:56lvh_CSV keys contained gnarly things
16:56TEttingerrebcabin: ##(name (keyword "what happens with spaces"))
16:56lazybot⇒ "what happens with spaces"
16:56TEttingerinteresting that it still stores it
16:56llasramrebcabin: Most Clojure core functions are very much "garbage in, garbage out"
16:57gfrederickskeywords that don't appear in your source code are usually not a good idea
16:57gfredericksI wonder if that's why cheshire defaults to strings
16:58amalloygfredericks: creating keywords is expensive too
16:59lvh_gfredericks: hm. so my use case is "get some data from a csv, and interpolate into this template many times (and then mail it to people)"
16:59gfredericksamalloy: oh interesting
16:59lvh_gfredericks: so my source code never sees the keywords, but the template and the csv both do (and obviously have to agree on which point to what data)
16:59gfrederickslvh_: okay so the template is outside your source code?
16:59oetjenjI just tried LightTable InstaRepl on my Mac and it throws several exceptions on the console... seems to something wrong with it, i have JDK 7 installed
17:00scape_oetjenj: might want to make sure jre is removed
17:00dbaschoetjenj: google is not helpful either, the only match I find is my own pastebin
17:01oetjenjwell i am not using LT myself, i prefer sublime for small things and IDEA for more with a separate repl anyways
17:01dbaschscape_: an older version of light table worked fine for me, I updated to the newest and it stopped working
17:01lvh_gfredericks: Correct; I slurp it from a file
17:01gfrederickslvh_: what templating language?
17:01lvh_gfredericks: I don't really get to choose though because the interpolation lib insists on using :keywords
17:02amalloyi mean, i think it should default to strings anyway, for the reason you mentioned, but you also get a substantial speedup for using strings
17:02lvh_gfredericks: mustache, but I don't really care which one
17:02lvh_it's trusted source markdown; string interpolation would be totally fine if it supported named strings
17:02scape_I gave up on lighttable because I had to keep removing and reinstalling with some of the later versions. it was fun at first tho-- finally gave in to emacs ;)
17:02scape_sublime is a good middle ground tho
17:02scape_brb
17:02gfrederickslvh_: I think that feels close enough to using the keywords in your code
17:03Guest96402I'm pretty excited about lighttable. Not enough to use it for serious work, but it looks like a very solid foundation
17:04oetjenjLT REPL is driving me nuts, but that's just my preference i guess
17:04dbaschGuest96402: I was trying to set it up for a friend who doesn't want to use emacs, it doesn't work on his mac or mine
17:04rebcabinhttps://github.com/overtone/emacs-live‎
17:04rebcabintuned for Clojur
17:04rebcabinClojure* even
17:06Guest96402dbasch: I would suggest he try cursive for now. Haven't used it, but I hear good things about it, and it meets the not-emacs criterion.
17:06oetjenjeven though emacs traditionally is somehow connected to list ;) i never managed to make myself comfortable in it, i am more of a vi guy
17:06dbaschGuest96402: I'll check it out
17:06oetjenjGuest96402, dbasch cursive finally works nice, at least in ultimate, haven't tried the community edition
17:07oetjenjbut i'd assume it works the same
17:11lvh_I'm trying to produce a hierarchical count, so I'd like to end up with {:a {:b {:c 1 :d 1}}} from the 2-vec [:a :b :c] and [:a :b :d]
17:11gfrederickslvh_: that is totally possible
17:11lvh_I don't really know how to say "go down this map with these keys making thinsg as you go along"
17:11gfredericksupdate-in
17:11Guest96402update-in
17:11lvh_yay :) thanks
17:12amalloy&(reduce (fn [acc path] (update-in acc path (fnil inc 0))) '((a b c) (a b c)))
17:12lazybotjava.lang.ClassCastException
17:12amalloy&(reduce (fn [acc path] (update-in acc path (fnil inc 0))) {} '((a b c) (a b c)))
17:12lazybot⇒ {a {b {c 2}}}
17:12amalloy&(reduce (fn [acc path] (update-in acc path (fnil inc 0))) {} '((a b c) (a b d)))
17:12lazybot⇒ {a {b {d 1, c 1}}}
17:12amalloythere we go
17:12lvh_so that is spelled (update-in map keys inc)
17:12mrcheeks,(inc amalloy)
17:12clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: amalloy in this context, compiling:(NO_SOURCE_PATH:0:0)>
17:12mrcheeksheh
17:12mrcheeks~amalloy++
17:12clojurebotTitim gan éirí ort.
17:13gfrederickslvh_: and you use (fnil inc 0) so that it accepts nil the first time
17:13amalloygood effort, mrcheeks
17:13mrcheeks:-)
17:13Bronsa(inc amalloy) ;; there
17:13lazybot⇒ 83
17:13gfredericks(inc mrcheeks'-effort)
17:13lazybot⇒ 1
17:13lvh_gfredericks: oh, I guess I sort of excpected (inc) to return 0 maybe that's just silly :)
17:13gfrederickslvh_: ##(inc nil) is the more relevant call
17:13lazybotjava.lang.NullPointerException
17:14gfrederickswhich is different from ##(inc)
17:14lazybotclojure.lang.ArityException: Wrong number of args (0) passed to: core$inc
17:14lvh_gfredericks: yes
17:14gfrederickslvh_: and even if it did return 0 that'd be wrong for your case
17:14lvh_okay, cool thanks :)
17:15lvh_gfredericks: err, derp, yes; I was htinking of how you'd do it in python, which involves defaultdict(int), so what actually happens is when you access the thing for the first time you get int() (== 0), and then you increment :)
17:16gfredericksaaaah right
17:16gfredericksrubby has that too
17:16lvh_but instead what happens here is that fnil takes a function and returns a function that ... well; I guess we can all read the docstring it's pretty clear :)
17:17gfredericksdoes anybody think a feature like that is bad for some precise reason?
17:17lvh_a feature like what?
17:17gfredericksmaps that return default values
17:17gfredericksit'd be easy enough to do
17:18gfredericksjust mix in a little ztellman...
17:18lvh_they have their use cases I think :)
17:18lvh_but maybe that's just because I like them for python; perhaps I am just completely missing how you'd otherwise write them in clj
17:19oetjenjdon't maps already return a default value? :D
17:19llasramgfredericks: It breaks all kind of behavior, doesn't it? You have things "in" the map which aren't in the map `keys` etc
17:19Guest96402I've was thinking of something similar recently. The problem is how you deal with idioms like (into {} my-special-map)
17:19llasramfnil I think covers most of the behavior you'd actually want
17:19gfredericksllasram: Guest96402: yeah those are good points
17:20gfredericksit makes it feel more like a function than a data structure
17:20llasramYeah. And I think it makes more sense for mutable structures, which is how you usually use the defaulting there anyway -- what's the default value when you mutate the value for a key which doesn't exist yet?
17:21gfredericksthat applies just as well to immutable though
17:22llasramDoes it? Oh, I guess maybe if you had some sort of updating protocol or something
17:22llasramOtherwise just getting a default for anything seems weird
17:22llasramMy new standard for interface design decisions: I will avoid things which seem "weird"
17:23lvh_gfredericks: the reason I think it wouldn't make a lot of sense for clj is that to me, as a complete newbie, it feels like clojure tries very hard to have simple data structures and then a bunch of functions that do things with them
17:23lvh_whereas hey in python yes let's have another dict subclass
17:23gfredericksllasram: updating a mutable map still reduces to access + set; i.e., get + assoc
17:24llasramgfredericks: You and your "good points". Geez
17:24gfredericksclojurebot: python is <reply> yes let's have another dict subclass
17:24clojurebotYou don't have to tell me twice.
17:24llasramclojurebot: python?
17:24clojurebotpython is ugly
17:24llasramAww
17:24gfredericks~python
17:24clojurebotpython is "I think dropping filter() and map() is pretty uncontroversial…" — GvR
17:24gfredericks~python
17:24clojurebotpython is "I think dropping filter() and map() is pretty uncontroversial…" — GvR
17:24gfredericks~python
17:24clojurebotpython is (defmulti #^{:doc "docs for foo"} foo class)
17:25llasramIt's in in there somewhere :-)
17:25gfredericksthis is good reading
17:25goodger:(
17:25gfredericks~python
17:25clojurebotpython is "I think dropping filter() and map() is pretty uncontroversial…" — GvR
17:25AeroNotix~@python
17:25clojurebotExcuse me?
17:25AeroNotixWell, I thought you'd give me them all then
17:25llasramHah. Nice try :-)
17:26llasramI think the fact-chaining would make that tricky though
17:26llasram~amalloy
17:26clojurebotamalloy is the spotlight illuminating my dumb mistakes
17:26llasramWell, that one was probably direct :-)
17:27lvh_~lvh
17:27clojurebotHuh?
17:27amalloyi don't think there are any facts chaining from amalloy
17:27lvh_maybe one day I will be famous
17:27llasramamalloy: I thought I remembered one came up which you figured out went through like 3 hops. May be misremembering obvs
17:27amalloyclojurebot: lvh will be famous one day
17:27clojurebotGabh mo leithscéal?
17:27amalloyclojurebot: lvh |will| be famous one day
17:27clojurebotYou don't have to tell me twice.
17:28lvh_fwiw I am writing a free introductory course on cryptography that I hope to be releasing in the next 2 weeks
17:28lvh_so maybe that will work
17:28gfrederickstwo-time pads!
17:28gfredericksthe second-most secure cryptoscheme!
17:29llasramlvh_: You are a cryptographer?
17:29gfredericksclojurebot: a cryptographer is somebody who makes drawings and then hides them
17:29clojurebotIk begrijp
17:29lvh_Hey, that was dutch, sort of.
17:30lvh_llasram: Yes, if that includes applied cryptography. I don't actually design ciphers.
17:30Morgawrclojurebot is dutch? :o
17:31goodgercan't be
17:31goodgerit didn't choke half to death on the g
17:31lvh_llasram: Sorry, I should rephrase: I don't design ciphers that I intend people to seriously use, or that I publish :)
17:31llasramHeh
17:31lvh_LVH is totally the best mode of operation.
17:31Morgawrgoodger: true true
17:32Morgawrhghoodhgher*
17:33llasramlvh_: You totally had me going for a sec -- thought it must be one of those newer verifying block cipher modes
17:34lvh_llasram: Well, it actually is an AEAD mode.
17:34lvh_llasram: Overall, it's a pretty reasonable one too.
17:34llasramInteresting
17:35lvh_llasram: I also haven't published it because there's no reason you should be using it over GCM except maybe that GF(2**128) multiplications are really hard to do in constant time in software
17:36llasramIt's an interesting topic!
17:37Cr8I have a highlight for "crypto"
17:37gfredericksI just saw an extremely minor typo in a clojure docstring. there's basically no practical way for me to fix it without wasting 5 peoples' time is there? :/
17:38ivanfind more typos and make a bigger patch?
17:38gfredericksyep :(
17:38gfredericksmaybe I should start a typos branch
17:40llasramI thought clojure/core had adopted a more expedited process for obvious doc fixes
17:40gfredericksmaybe they did! that's why I asked
17:40Bronsanot really
17:41llasramI haven't tested it -- I just remember one of the cognitects saying something along those lines the last time I was around for an instance of The Great Patch Difficulty convo
17:45ivangfredericks: https://www.refheap.com/31866/raw
17:45gfredericksivan: nice
17:46gfredericksmine was s/and/an/ so would not be caught
17:47amalloyupto: almost as good a word as alot
17:47gfredericksamalloy: refers to a really tall thing
17:47gfredericksclojurebot: technomancy is the upto behind leiningen
17:47clojurebotIn Ordnung
17:48llasram(inc gfredericks)
17:48lazybot⇒ 40
17:52sobel+1 typos branch
18:03gfredericksI'll accept pull requests ;-) https://github.com/fredericksgary/clojure/tree/typos
18:03dbaschGuest96402: oetjenj upgrading the clojure plugin to 0.0.6 fixed the lighttable issue
18:04llasramgfredericks: Even from people w/o CAs?!?!?!
18:04llasram~guards
18:04clojurebotSEIZE HIM!
18:04gfredericksllasram: oh that does sound sticky
18:04oetjenjdbasch, thanks
18:04gfrederickslet's just say no
18:04llasramgfredericks: The die is cast -- your typo branch is the PR-accepting future of Clojure
18:04llasramOh, or not
18:15riz_hi
18:17riz_what does it mean by: Trying to convince others to use Haskell is permitted between 0200 and 0500 UTC.]
18:17riz_is it a joke or something which i don't get?
18:19llasramThere was an active member of the channel who went very pro-Haskell. That was an attempt at a compromise/joke
18:19amalloywait, was? did callen/bitemyapp leave while i was on vacation?
18:19llasramI haven't seen him around
18:19gfredericksI haven't seen him for a couple days maybe?
18:19pyrtsaI think he left.
18:19riz_hey are you the guy i talked to other night?
18:19gfredericks$seen bitemyapp
18:19lazybotbitemyapp was last seen talking on #clojure 1 week and 5 days ago.
18:19riz_i can't remember the name
18:19gfredericksoh wow
18:20amalloyi saw him in #haskell last night
18:20riz_i was here at like 4 am cause i couldn't sleep
18:20pyrtsaHe's active in #haskell.
18:20riz_so both haskell and clojure are functional
18:20riz_then what are the major differences?
18:20riz_is there something haskell can do that clojure can't?
18:21dsrxhaskell has the power to turn you into a weenie like no other language can
18:21deadghostidk man
18:21deadghostthere's js and ruby
18:23pyrtsaI'm kind of sad of how things went with him here. Yes, there was quite a lot of noise but actually a lot what he said makes sense, and with core.typed and possibly without being restricted to the JVM, Clojure could take steps in that direction.
18:23gfrederickspyrtsa: I'm curious what "how things went" means
18:24llasramriz_: Well, they're both Turing-complete :-)
18:25pyrtsagfredericks: I don't know if "ignorant" is the best word but...
18:26riz_aren't most programming languages?
18:26hiredmanI've had him on /ignore almost since he showed up, but I see lots of complaints in here, and else where about his behavior here
18:26gfredericksriz_: haskell is statically typed
18:26llasramriz_: Yeah, was a joke
18:26riz_ohhh
18:26riz_hehehe
18:26gfrederickshiredman: okay, I wasn't sure if there was some aspect that went beyond that, related to languages and such
18:27llasramriz_: statically typed, unhosted, pure functional. You get some of the best type-checking and type-based optimization in the industry
18:27hiredmanto balance out all the complaints, I've seen non-regulars in #clojure twice defend him (or make gestures inthat direction) counting pyrtsa's "I'm kind of sad"
18:28pyrtsa:)
18:28clojurebotexcusez-moi
18:28SegFaultAXamalloy: I had lunch with him on Thurs. He probably won't be hanging around #clojure much anymore.
18:28SegFaultAXAlthough still hacking Clojure regularly etc.
18:28amalloySegFaultAX: it sounds like you murdered him
18:28amalloyjust fyi
18:28SegFaultAXWell, ah.
18:29gfredericksamalloy: in a way that still lets him hack on clojure regularly
18:29llasramI'm not glad he's gone, but he wasn't always the most newbie-friendly voice
18:29SegFaultAXConsidering he came to my office, I think my co-workers would have noticed something :)
18:29riz_you mean haskell is more efficient than clojure?
18:29SegFaultAXgfredericks: I guess I was the one who did all the hacking?
18:30gfredericks#murderjokes
18:30pyrtsariz_: FWIW, for me, the biggest difference is that with Clojure, when losing context for a while, I tend to make lots of mistakes where I just forget to type some code somewhere. Like a function with 1 parameter too few. With Haskell, that can't easily happen.
18:30llasramriz_: JVM Clojure gets the JVM JIT, so no, not unilaterally for every algorithm, certainly not. It's just different trade-offs
18:31SegFaultAXAnyway, the point is he hasn't moved away from Clojure, just #clojure.
18:31SegFaultAXIf you want more details, PM or DM on Twitter.
18:33gfredericksriz_: being "functional" is almost the only thing the two languages have in common
18:33SegFaultAXllasram: For Clojure in particular, I would think most things in Haskell are faster. For Java in general, that's probably not the case.
18:34SegFaultAXClojure's overhead is significant.
18:34pyrtsagfredericks: Persistent data structures could be another common thing, unless you count it as part of the definition of "being functional".
18:34gfrederickspyrtsa: good point
18:34dnolenSegFaultAX: people make claims w/ out benchmarks. Last I checked really fast Haskell code looks pretty weird. Same as Clojure.
18:34hiredmanthe think with a channel like #clojure, is it is a very mixed bag, some people here write clojure professionally and want to talk shop, some are involved in the dev of the language and want to talk about estoic bits of it, some are just trying to get "hello world" working
18:34pyrtsaClojure's startup time is a pain. Haskell applications tend to start up very fast.
18:35SegFaultAXdnolen: It's just a guess, yea. But Clojure's overhead /is/ significant.
18:35dnolenSegFaultAX: so is idiomatic Haskell's
18:36hiredmanthe first and second crowds can appreciate "views", but when you are trying to help someone in the later case it is just a pain and being a dick
18:36gfredericks(inc hiredman)
18:36lazybot⇒ 36
18:36SegFaultAXdnolen: Sure, but Haskell is compiling down to something native. Clojure is compiling down to something with also significant overhead.
18:37SegFaultAXI don't have numbers or research to backup my guess. Just anecdotal experience.
18:37dnolenSegFaultAX: Clojure also compiles to something native due to the JVM.
18:37riz_sorry got disconnected
18:39pyrtsadnolen: To a degree, Haskell optimization can be guided with rewrite rules that don't particularly complicate the application-level code. I enjoyed the way BOS explained it in the latter part of this presentation: http://vimeo.com/52141702
18:39SegFaultAXdnolen: I don't have an axe to grind here. If you're saying idiomatic Clojure is as fast or faster than Haskell based on your real-world experience, I'll accept that.
18:39SegFaultAXThat hasn't been /my/ experience, or the experience of some others, but then I'm not at all an expert on this topic.
18:40oetjenjbesides all the technical diferences i think (although i never did any haskell programming, yet) the biggest difference is that haskell tends to be as pure functional as possible while clojure happily lives with tradeoffs, based on what i'ved read... isn't that right?
18:41SegFaultAXoetjenj: Well in the case of JVM clj, there isn't an option. You couldn't make a purely functional JVM anything.
18:41pyrtsaoetjenj: That's my view as well. Though there are internal differences within both communities, of course. Whether you use bindings or pass arguments explicitly, for an example.
18:41gfredericksyou could at the lang level
18:42hiredmanSegFaultAX: you absolutely could
18:42oetjenjSegFaultAX, yes i am aware of that
18:42SegFaultAXhiredman: You absolutely could not. At least, not at the JVM level.
18:42hiredmanthe interop would just be terrible
18:42SegFaultAXThe classloader is inherently side effecting and stateful, as a simple example.
18:43hiredmanSegFaultAX: the haskell runtime is also full of side effects and state, what is your point?
18:43gratimaxI'm pretty sure the biggest 'disability' clojure on the jvm has is being dynamic, and it is running on something optimized for java
18:43oetjenjin other words, even if you remove two tires from your car, you still don't have a motorbike ;)
18:43gratimaxHaskell runs on something optimized for haskell
18:43hiredmanrts(haskell runtime) is still written in C if I recall correctly
18:44gratimaxI know there's projects to port clojure to the python vm for instance, but I don't know performance-wise if there's much difference
18:44SegFaultAXhiredman: In Haskell, the core side effecting code is very deep and generally not something you can or should touch directly in application code.
18:44hiredmanhttps://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts
18:44SegFaultAXIn JVM, the necessary side effecting code is very close to you.
18:45hiredmanhttps://github.com/Frege/frege/
18:45gfredericksSegFaultAX: a lang can still be pure
18:45oetjenji mean, actually writing a complete side effect free program isn't of much use anyways, is there?
18:45SegFaultAXhiredman: That last one is an interesting project. callen was telling me about it recently.
18:46pyrtsaoetjenj: No one's writing one, of course. ;)
18:48SegFaultAXgfredericks: Semantically pure? Perhaps. But you wouldn't be able to leverage anything about the underlying platform at all. Why even use the JVM then?
18:48pyrtsaoetjenj: To say it in Rich Hickeyan terms, Haskell (code) being side effect -free is just a way of saying Haskell programs are values.
18:49gfredericksSegFaultAX: dunno; but it's an option :)
18:49SegFaultAXI'll revise my previous statement to "You couldn't build a meaningfully useful pure language on the JVM"
18:49oetjenjpyrtsa, hehe
18:49gratimaxpyrtsa: extend this by saying that haskell programs are actually composed IO monads, now you're getting somewhere
18:50pyrtsagratimax: Exactly.
18:52gratimaxSegFaultAx: you can't build a perfectly pure language that is useful, anywhere. Haskell uses io monads to get around this and stay 'mostly pure'. haskell-like languages do run on the jvm
18:52hiredmanbbloom should jump in at some point about memory allocation being a side effect that happens everywhere, and haskell not being able to statically protect against oomes, and static types being only one of many useful tools, etc
18:52gfredericksSegFaultAX: also s/dunno/GC/
18:52gratimaxIf you really wanted to, you could write a haskell IO analog in clojure with 'no side effects'
18:53gratimaxhttps://github.com/clojure/algo.monads/
18:53gratimaxbam, pure clojure!
18:54pyrtsaalgo.monads is quite hacky, though. Not too convenient to use.
18:55AeroNotixdoes doto throw away type hints?
18:55SegFaultAXgratimax: You're missing my point. To do anything useful on the JVM (even to use the stdlib) you have to admit side-effecting code all over the place.
18:55amalloyAeroNotix: wellllll, not any more than macros in general do. it sorta depends
18:56gratimaxSegFaultAX: you can abstract that away to something haskell-like, as I mentioned before.
18:58SegFaultAXgratimax: For most of the standard library, you'd have to abstract it to the point of re-implementation. So why even use it?
18:59gratimaxSegFaultAX: that was the whole point of clojure's immutable data structures, isn't it? all that was salvaged was strings and numbers, basically
18:59gratimaxso why even have immutable data structures? you need to implement it again anyway
19:00AeroNotixamalloy: well all of my dotos seem to complain about the calls being unable to be resolved.
19:00AeroNotixamalloy: even if I type hint the first expression
19:01SegFaultAXgratimax: Um, no? That isn't the point of them. It isn't to hide stuff from Java, it's to give you alternative data structures with different semantics that are easier to reason about.
19:01SegFaultAXYou can of course still call down to Java (and you frequently do, especially to leverage existing code)
19:02gratimaxSegFaultAX: well, people have still done nice IO to the point of having it 'nearly pure'
19:02gratimaxtake ring for example. you write web apps as composable handlers, not using sockets and whatnot
19:03dissipatewhy does (and) result in 'true' and (or) results in 'nil'?
19:03gfredericksmonoids!
19:03oetjenjiirc, clojure actually started out as a library of immutable data structures for java - at least i think recall rich saying that somewhere
19:03AeroNotixoetjenj: [citation needed]
19:03gfredericksdissipate: also (+) (*)
19:04gratimaxyou can argue, yes, ring isn't perfectly pure, because there's a run-jetty function, but it is still an abstraction of http servers without side effects
19:04dissipategfredericks, that's bizarre. why??
19:04lazybotdissipate: Uh, no. Why would you even ask?
19:04gfredericksdissipate: or were you asking about nil vs false?
19:04pyrtsadissipate: In general, the `and` and `or` macros do not return Booleans.
19:04oetjenjAeroNotix, i would if i could remember where i heard it, that's why i said if i recall correctly and not stated that as a fact...
19:04SegFaultAXgratimax: Ok, but you can't automatically hide the side effecting code of any random package. You might be able to do that for some or even most of the standard library, but certainly not 3rd party stuff.
19:04dissipategfredericks, no, wondering why 'and' with no arguments evaluates to 'true' but 'or' with no arguments evaluates to 'nil'
19:05dissipatepyrtsa, they don't??
19:05lazybotdissipate: Definitely not.
19:05pyrtsa´(or 1 2)
19:05pyrtsa,(or 1 2)
19:05clojurebot1
19:05dnolendissipate: he gave a hint with monoids
19:05gfredericksdissipate: also consider ##(concat)
19:05lazybot⇒ ()
19:06technomancygratimax: run-jetty is not part of ring-core fwiw
19:06gratimaxSegFaultAX: true. but most of the time there are clojure versions of these libraries that make you not think about side effects
19:06dissipatei don't get it but whatever. :O
19:06SegFaultAXgratimax: Most of the time? Wut?
19:07SegFaultAXDo you know how many packages exist in Maven Central?
19:07gfredericksdangit I chased somebody off
19:09gratimaxSegFaultAX: yes, there are probably hundreds of java packages all doing http and web stuff. but there still exists a nice clojure analog
19:11oetjenjgfredericks, but the answer would have been quite easy, wouldn't it? :D
19:11gratimaxSegFaultAX: I don't mean that you can definitely find a side-effect free version of every single java package. but for most high-level use cases there most likely exists something
19:12gfredericksoetjenj: is it? I'm not sure of a succinct thing except "monoids"
19:14dnolengratimax: Haskell actually has similar problems as Clojure in this regard because of unsafe*, thus Safe Haskell.
19:15gratimaxgfredericks: 'identity elements'
19:15gfredericksyeah
19:18pyrtsagratimax: Actually... if you care about more than the truthiness of the result, then neither `and` nor `or` has an identity element.
19:19pyrtsa(and (and) x) ≠ (and x (and))
19:20amalloywell, and has a left identity and or has a right identity
19:23tomjackdepends on your equivalence relation
19:23gratimaxI think this is really in how and/or are implemented, in a perfect world they wouldn't take values other than booleans
19:23pyrtsatomjack: I said "if you care about *more* than the truthiness".
19:24tomjackyeah :)
19:25amalloygratimax: that's a haskell "perfect world", but in clojure it's pretty handy to be able to write (or x default)