#clojure log - Feb 02 2014

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:45 insamniac: :( Faber

1:07 rovar: what would be an elegant way to un-interleave?

1:07 e.g. i have an alist and I want to break it out into 2 lists

1:17 fowlslegs: I am wondering what's causing this CompilerException... Seems like I am using recur from tail position.

1:17 http://paste.debian.net/79743/

1:18 Working on 4clojure #85 http://www.4clojure.com/problem/84 btw.

1:18 *#84

1:51 john2x: are records the idiomatic way to model a datastore entry? Or just plain maps?

2:13 seangrove: john2x: Typically just plain ol' maps

2:27 dsrx: ,(apply map vector [[:a 1] [:b 2] [:c 3]])

2:27 clojurebot: ([:a :b :c] [1 2 3])

2:27 dsrx: rovar: ^

2:29 amalloy: fowlslegs: nowhere inside of a for-expression is in tail position, really

2:29 rovar: dsrx, wowowow

2:30 mind is blown

2:33 hiredman: ~for

2:33 clojurebot: for is not a loop

2:47 chchjesus: lol

3:23 regexkind: hiya

3:23 has anyone on here made use of enlive?

3:24 rhg135: I have

3:24 But for scraping

3:24 regexkind: Yah that's what I'm trying to do

3:24 but not sure if you'd know this then:

3:24 do you know how to convert a collection of enlived data back into html?

3:25 like, I have a nested map, and I want the html back

3:25 rhg135: No idea sorry

3:25 regexkind: :/ ok

5:05 quizdr: is 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?

5:07 amalloy: &((juxt get nth) (list 1 2 3))

5:07 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: core$get

5:07 amalloy: &((juxt get nth) (list 1 2 3) 1)

5:07 lazybot: ⇒ [nil 2]

5:08 quizdr: amalloy the point you are making is that get is not available for lists, correct?

5:09 amalloy: yes; alternatively, get is always fast, while nth is willing to be O(n) if necessary

5:09 quizdr: but 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?

5:09 oh, even on a vector, nth is O(n)?

5:10 amalloy: no, i said "if necessary", which it's not for vectors

5:11 quizdr: ok. when adding to the end of a vector, is push or assoc by vector length as key a better choice?

5:11 amalloy: for vectors in particular, that's probably the only difference

5:11 push 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)

5:12 quizdr: got it.

5:13 final 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?

5:14 (inc amalloy)

5:14 lazybot: ⇒ 82

5:15 amalloy: sounds about right

5:15 quizdr: thanks, amalloy you are either up really early or really late, or what part of the world are you in?

5:16 amalloy: california, so up lateish

5:17 quizdr: indeed

5:20 does 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.

5:27 borkdude: How can I calculate (partitions (range 1 27) :min 6 :max 6) without running into memory errors...?

5:35 too many possibilities

5:36 finishingmove: what would be the idiomatic clojure way to do euler#1 (sum of multiples of 3 or 5 under 1000)

5:50 dsrx: finishingmove: what does your solution look like?

5:50 sm0ke: hey guys why isnt there a closed? open? in core.async?

5:51 quizdr: finishingmove 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

5:53 finishingmove: dsrx, 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?

5:55 quizdr: finishingmove regarding performance, reduce might be a better choice than apply

5:55 rue__: But correctness and clarity above all?

5:57 finishingmove: I read somewhere that apply is considered more idiomatic Clojure than reduce.

5:57 quizdr: really? that's interesting.

5:57 i'd like to see where that is written.

5:58 finishingmove: https://stackoverflow.com/questions/3153396/clojure-reduce-vs-apply

5:59 quizdr: since 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.

6:01 in that stackoverflow question, notice the comment by the very wise cgrand

6:01 finishingmove: now, 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?

6:03 quizdr: your 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

6:04 finishingmove: Ah, I see. I'm still new to lazyness... that makes sense though.

6:04 opqdonut: fikusz: for + it doesn't matter

6:04 oops

6:04 fikusz: ignore that

6:04 finishingmove: for + is doesn't matter, the multi-arity version of + is implemented using apply

6:05 so (apply + list) and (reduce + list) are exactly the same, the former just has one indirection

6:05 quizdr: opqdonut see this that suggests + is actually implemented using reduce: http://stackoverflow.com/a/3153643/768472

6:05 dsrx: I think you mean the multi-arity version of + is implemented using reduce

6:05 opqdonut: err, that's what I mean

6:05 *meant

6:05 dsrx: (which is in agreement with the last thing you said)

6:07 opqdonut: I'm not sure which form I prefer, but I kinda feel like using apply for + and merge etc. is appropriate

6:07 but it's only a couple of functions for which apply f and reduce f are the same thing

6:08 quizdr: the arguments against apply have more weight in other lisps, so likely don't factor into the clojure idioms

6:09 opqdonut: yeah

6:12 finishingmove: reduce reads better to me, so I'll be using that, since the "idiomatic apply" mythn got busted (more or less)

6:13 quizdr: i think your euler solution is not bad, the one contained in one form, not the one with the extra function

6:14 i'd bet it could be shorter, however. after doing many of the 4clojure problems i'm convinced there is always a shorter alternative

6:19 hyPiRion: I 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

6:19 deadghost: hmm what

6:19 I just tried it

6:19 reduce + and apply str have better performance

6:20 and now I'm aware I totally don't know what it's doing under the hood

6:20 hyPiRion: $source str

6:20 lazybot: str is http://is.gd/k4S9Km

6:21 piranha: is there $source command for cljs? :)

6:22 hyPiRion: instead of doing (str (str a b) c), (str a b c) creates a stringbuilder, which only creates a single string instead of several

6:23 deadghost: is stringbuilder javaspeak

6:23 finishingmove: sounds like something Gargamel invented and placed into the smurf village

6:24 quizdr: finishingmove actually it is.

6:26 for 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

6:27 deadghost: I like that guide

6:27 though I didn't read all of it

6:27 got me through cl -> clojure

6:27 quizdr: you should read all of it. it's not that long

6:27 and what are your thoughts on cl vs clojure?

6:28 deadghost: I didn't use cl for very long

6:28 but my impression is stuff works in clojure

6:28 and not so much in CL

6:29 quizdr: ha ha

6:29 well i do find clojure easier to learn than CL. the immutability actually helps the learning process i think

6:29 deadghost: I think I went though 3 libraries to scrape something

6:29 quizdr: and clojure is more elegant as a lisp-1

6:29 deadghost: and none of them worked all the way

6:30 documentation was spotty, quicklisp + asdf hard to figure out, and community not what I'd call friendly

6:31 quizdr, did you learn by book or what

6:31 I'd probably have a REALLY REALLY hard time with clojure if I didn't already 70% finish a CL book

6:31 quizdr: yes i learn mainly from books

6:32 though with clojure there are other fantastic sources of learning too

6:32 deadghost: is there a good first clojure book?

6:32 quizdr: for the basics in a quick and non-intimidating way, the Halloway book is good

6:32 not too long, but also not too deep

6:32 finishingmove: quizdr, 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

6:32 quizdr: finishingmove so am i

6:33 deadghost: the only clojure books I've thumbed through are web dev with clojure and clojure book

6:33 quizdr: i've read about 4 clojure books at this point

6:33 i still have dumb questions every now and then however

6:33 deadghost: I like clojure book but holy crap it is dense

6:33 quizdr: simple things i forget, because i'm also learning other languages for work, so it gets all mixed up in my head sometimes

6:34 deadghost: common lisp: a gentle introduction is symbolic computing is among my favorite books

6:34 because it's actually pretty gentle

6:35 quizdr: i think i have that one

6:35 i've got a ton of CL books

6:35 i try to implement their examples in clojure

6:35 deadghost: did you get into CL much

6:35 quizdr: it's fun and you learn quickly that way

6:35 jonasen_: Anyone seen "Symbol's value as variable is void: cider-repl-input-start-mark" when doing M-x cider-jack-in?

6:35 quizdr: i built some apps for myself in CL, simple things to parse text and store personal data. nothing too deep.

6:36 jonasen_ can't say i have

6:36 maybe something in your project.clj settings?

6:36 jonasen_: quizdr: I've tried with two different projects..

6:36 same result

6:37 deadghost: jonasen_, are you using melpa

6:37 jonasen_: deadghost: not sure

6:37 deadghost: where are you getting cider?

6:37 jonasen_: deadghost: M-x package-install

6:37 drorbemet: Hi, 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 ?

6:38 deadghost: jonasen_, did you include melpa in your package-archives list in .emacs?

6:38 jonasen_: deadghost: let me check

6:38 deadghost: because melpa has a tendency to screw things up

6:38 because it gets unstable stuff

6:39 drorbemet: http://richhickey.github.io/clojure-contrib/string-api.html#clojure.contrib.string/partition

6:40 jonasen_: deadghost: (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))

6:40 that's the only reference to package-archives in my init.el

6:40 deadghost: ok then the issue isn't from melpa

6:40 clojurebot: Titim gan éirí ort.

6:41 drorbemet: clojure.string/split is not lazy http://clojure.github.io/clojure/clojure.string-api.html#clojure.string/split

6:42 jonasen_: deadghost: ok. It magically started working again... not sure what I did wrong previously

6:43 deadghost: jonasen_, then all is well

6:43 for now

6:43 jonasen_: deadghost: yep. 'til next time... Thanks for your help

6:48 deadghost: jonasen_, 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

6:49 so it installs packages from a list on startup instead of M-x package-install

6:50 jonasen_: deadghost: thanks. I'll consider it.

6:57 quizdr: So 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?

7:38 sobel: i wish i could find SQL libraries that i don't hate

7:39 i reeeaaally don't want an ORM or a DSL in front of SQL, i just want simple parameter mapping like psycopg2

7:41 and 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

7:41 but so useful

7:42 i find it wrong and wrongful to a) put big queries in client code and b) deal with leaky abstractions like HoneySQL

7:43 the jdbc library shouldn't be trying to save the poor clojurist from dealing with SQL directly. it should make dealing with SQL directly conevient.

7:44 steckerhalter: a bear should not be a fish

7:49 sobel: well, i can't promote clojure as viable data access tool until i figure out decent jdbc usage

7:50 i can rewrite some queries but not all to work around array types

8:26 scape_: 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

8:27 sobel: no, the limitations of those DSLs are problematic, too

8:59 gfredericks: sobel: so I've done a lot of this sort of thing

9:00 sobel: 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

9:00 if 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

9:02 e.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

9:03 and 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

9:03 I 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

9:03 certainly it's no worse than in java

9:04 sobel: gfredericks: 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.

9:04 i mean, either it's isomorphic (and pointless in my view) or it's leaky

9:05 i also think constructing queries at runtime (especially in client code) is poor design

9:07 nail it down.

9:08 gfredericks: sobel: so do you embrace redundancy in your queries, or do you think there's some way of avoiding it in the data model?

9:08 sobel: what redundancy?

9:08 gfredericks: e.g., if I have two similar tables

9:09 and want to query them in similar but not identical ways

9:09 then either I have two queries with similar structure and thus shared information

9:09 or I'm creating the query programmatically

9:09 sobel: i would have to see more of the design in particular

9:09 gfredericks: well, how about the query-1! example

9:10 do you just append LIMIT 1 every time you make such a query?

9:10 repeating the logic?

9:10 LIMIT 2 rather

9:10 sobel: sec.. (phone)

9:20 llasram: gfredericks: 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

9:21 gfredericks: llasram: 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

9:22 it's all pure functions so it's simple to verify that it's doing what you think it is

9:22 SQL is the sad DSL :)

9:22 sobel: SQL is a category of database-specific DSLs

9:22 llasram: :-)

9:23 gfredericks: sobel: something data oriented would be more useful

9:23 rovar: errg..

9:23 I'm passing in [:6 2] to https://www.refheap.com/31630

9:23 and getting java.lang.IllegalArgumentException: No matching clause: [:6 2]

9:24 sobel: the common ground (standard SQL) is suitable for most data operations but most interesting things are not spec'd in the standard

9:24 rovar: I don't see how [[a 2]] doesn't match that

9:24 sobel: so you have DML that is fairly portable, at least, when the schema is implemented the same

9:25 gfredericks: sobel: suitable for low-level data operations maybe, but not trying to build abstractions on top of

9:25 sobel: exactly. it is not suitable for building DSLs on top of.

9:25 each SQL is its own DSL for its database.

9:25 gfredericks: I don't mean DSLs

9:26 sobel: first of all, if i have LIMIT 1 in a query in client code, i have lost

9:27 gfredericks: why's that?

9:27 sobel: if it's that important it should be a function or a view

9:28 karls: hey 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

9:29 gfredericks: karls: that's terribly interesting and I have no idea

9:29 sobel: if 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

9:29 gfredericks: karls: hash maps are used for larger maps; in general you can ignore the difference

9:29 sobel: okay, so you do your abstracting using db mechanism like functions/views

9:30 sobel: a LIMIT clause in client queries tells me it is peeking too deeply into the implementation

9:30 gfredericks: i wouldn't call it abstracting, but i do limit my public db interface that way

9:30 karls: gfredericks: hm.. this makes multimethods that dispatch on the class of an argument pretty annoying.

9:30 sobel: a table is an acceptable part of a public interface, but it should be intentional

9:31 gfredericks: sobel: which means your application logic is spread across your development language and your sql db code

9:31 karls: use IPersistentMap instead

9:31 sobel: don't tell me there's a bright line between storage logic, business logic, and application logic

9:31 because there isn't

9:32 the database enforces application design all the time

9:32 gfredericks: sobel: I'm not telling you anything I'm trying to noodle through the differences in how we approach problems

9:32 sobel: data structures are part of application logic

9:32 so i would say application logic is spread through client and database code

9:33 gfredericks: sobel: 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

9:33 sobel: gfredericks: 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.

9:34 gfredericks: sobel: 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

9:34 sobel: gfredericks: thanks, i do hope to crack this nut of appropriate data access!

9:34 karls: gfredericks: that sounds reasonable. how would i go about using that in a multimethod though?

9:34 gfredericks: karls: the same way you use the classes

9:35 sobel: let me know if you need help with java.jdbc & custom types

9:36 sobel: gfredericks: 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

9:37 llasram: sobel: OOC, where do you work, if you don't mind my asking?

9:37 sobel: llasram: it's a Chicago based finance co. called Enova

9:37 llasram: cool

9:38 sobel: there 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.

9:38 but 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.

9:39 (and fair enough, he didn't know you could just pervert postgresql tables to serve blobs quite nicely)

9:40 karls: gfredericks: i'm still a bit confused. i thought multimethods dispatch on a value?

9:40 gfredericks: karls: how were you trying to use them before you started asking questions?

9:41 karls: in the case of a class, you just "switch" on the class name.

9:41 gfredericks: karls: IPersistentMap is a classname in that respect

9:41 quizdr: So when you pass args to a multimethod, those args are actually

9:41 evaluated for two different functions: the dispatch as well as the

9:41 multimethod. 2 procedures for the same args, where the first

9:41 procedure chooses the second procedure. sound correct?


9:41 yikes! sorry

9:41 gfredericks: ,(defmulti crepes class)

9:41 clojurebot: #'sandbox/crepes

9:42 gfredericks: ,(defmethod crepes java.lang.Number [x] (inc x))

9:42 clojurebot: #<MultiFn clojure.lang.MultiFn@1fdd37d>

9:42 karls: gfredericks: a multimethod that dispatches on the class of the second argument. and then i came across this {} vs (def m {}) issue.

9:42 gfredericks: ,(crepes 41)

9:42 clojurebot: 42

9:42 gfredericks: ,(defmethod crepes clojure.lang.IPersistentMap [m] (assoc m :num 42))

9:42 clojurebot: #<MultiFn clojure.lang.MultiFn@1fdd37d>

9:42 gfredericks: ,(crepes {})

9:42 clojurebot: {:num 42}

9:42 gfredericks: ,(crepes (array-map :a 9))

9:42 clojurebot: {:num 42, :a 9}

9:43 gfredericks: ,(crepes (hash-map :b 10))

9:43 clojurebot: {:b 10, :num 42}

9:43 gfredericks: karls: ^ looks like it all works?

9:43 karls: gfredericks: !

9:43 that's great!

9:43 gfredericks: thanks!

9:43 gfredericks: np

9:46 karls: gfredericks: that's really cool. i wasn't aware that IPersistentMap "counts" as a class.

9:47 gfredericks: interfaces are classes for a lot of purposes

9:47 ,(instance? clojure.lang.IPersistentMap {})

9:47 clojurebot: true

9:47 gfredericks: ^ that purpose is probably the most relevant

9:47 karls: indeed. that's really nice.

10:10 hyPiRion: ,(instance? clojure.lang.IPersistentCollection {})

10:10 clojurebot: true

10:22 AeroNotix: ,(anscestors clojure.lang.IPersistentCollection)

10:22 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: anscestors in this context, compiling:(NO_SOURCE_PATH:0:0)>

10:22 AeroNotix: ,(ancestors clojure.lang.IPersistentCollection)

10:22 clojurebot: #{clojure.lang.Seqable}

10:49 rovar: is 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:49 but when I run lein midje, it says it's not a task

10:49 :profiles {:dev {:dependencies [[midje "1.6.0"]]}

10:49 :plugins [[lein-midje "3.1.3"]]}

10:51 konr: what's the other special symbol valid inside macros, besides &form?

10:51 llasram: rovar: 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:51 konr: You mean &env ?

10:52 rovar: llasram, 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:52 konr: llasram: yes, thanks!

11:04 gfredericks: konr: (source defmacro) has those somewhere ;-)

11:13 fowlslegs: Hey 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:17 schmir: fowlslegs: http://stackoverflow.com/questions/7813497/clojure-what-exactly-is-tail-position-for-recur may help

11:19 it's not in tail position because it's enclosed by the outer for

11:38 technomancy: rovar: top-level :plugins is the usual way to go, but I'm surprised it doesn't work in :dev :plugins

12:52 gzymsiu: hi all

13:21 albert_: 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:27 that is, my namespacing of my javascript file via goog.provide("my.namespace") isn't being added to my code

13:28 even after including the gc aware file in my project.clj :libs

13:33 dnolen: albert_: you need to require it. Is there a point to not doing so?

13:34 albert_: dnolen: yes, the file depends on some clojurescript namespaces, so requiring results in a circular dependcy

13:35 dnolen: albert_: there's not much you can do except break the circularly dependency.

13:42 sdegutis: Well then.

13:50 gfredericks: somebody 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:51 borkdude: gfredericks that is indeed odd

13:51 gfredericks: ,(class {1 2})

13:51 clojurebot: clojure.lang.PersistentArrayMap

13:52 gfredericks: ,(def m {1 2})

13:52 clojurebot: #'sandbox/m

13:52 gfredericks: ,(class m)

13:52 clojurebot: clojure.lang.PersistentHashMap

13:52 gfredericks: I'm a little weirded out that I didn't know about this before

13:52 andyf: fowlslegs: The error message may be confusing, but I think it is because the recur is inside neither a loop nor fn expression.

13:53 * gfredericks wonders how much money he would have bet on the opposite

13:53 Bronsa: gfredericks: I have a patch in jira for that

13:53 let me find it

13:54 andyf: gfredericks: 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:54 Bronsa: gfredericks: http://dev.clojure.org/jira/browse/CLJ-944

13:54 andyf: you beat me :)

13:54 gfredericks: omg guy s/then/than/

13:54 * gfredericks runs around waving his grammar hands wildly

13:54 gfredericks: do I have permissions to edit the title?

13:55 I do!

13:55 is that going to distract anybody's inbox?

13:55 Bronsa: who cares.

13:55 andyf: Only the creator and 3 watchers, I think

13:55 gfredericks: okay well they deserve it then :)

13:56 okay finally the important aspects of this ticket have been attended to

13:56 andyf: Yeah, it is totally going to be fixed tomorrow now :-) (yes, sarcasm)

14:07 arrdem: augustl: interesting OS idea... I'll be watching with interest :D

14:09 augustl: are you planning to try and bootstrap a JIT'd environment, or shooting for something simpler?

14:25 augustl: arrdem: 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:27 arrdem: augustl: 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:28 AeroNotix: https://github.com/lshift/cloverage/issues/33

14:29 if anyone's interested^ weird error when using Cloverage with some macros I wrote.

14:29 gfredericks: Huh. 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:29 augustl: arrdem: sounds like we basically have the same idea :)

14:29 arrdem: augustl: :D

14:29 augustl: arrdem: 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:29 arrdem: gfredericks: that's data liveness analysis. old compilers topic.

14:30 gfredericks: arrdem: yeah no way could I be original

14:30 arrdem: augustl: JIT'd drivers? up top man, exactly what I wanted.

14:30 augustl: arrdem: if you're the only one that had an idea, it's probably a bad idea, as they say :)

14:31 someone 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:32 arrdem: haha, that's where all of this stuff starts... an idea and no code :P

14:32 bbloom: augustl: you should look the work from Alan Kay's Viewpoints research lab

14:32 augustl: they implemented a TCP/IP stack as a non-deterministic peg parser with ometa

14:33 augustl: arrdem: at least I'm past the infamous "mkdir ...." problem (I have a name for it)

14:33 bbloom: ah, very cool

14:33 I'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:33 bbloom: augustl: i was gonna write a big comment on HN, but decided not to bother with that hostile audience

14:33 arrdem: augustl: get a runtime first, then we can worry about building a saner filesystem :P

14:34 bbloom: augustl: yeah, you're basically doomed unless you pick a particular problem you want to solve

14:34 augustl: is the goal just to learn something for yourself?

14:35 augustl: bbloom: that is at least a part of it, I consider it a research project, not a practical OS anyone will ever run

14:36 bbloom: augustl: 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:37 there 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:37 i'm still not sure what camp i'm in :-)

14:37 one thing is for sure: hardware sucks :-P

14:37 arrdem: bbloom: common runtimes are awesome :D

14:37 augustl: bbloom: a month ago I thought doing it on bare metal would be cool

14:37 arrdem: augustl: oh gods why

14:37 augustl: but now that I haven't gotten anywhere... Perhaps a VM is a good first step.

14:38 bbloom: augustl: have you ever implemented your own little lisp or GC or anything like that?

14:38 augustl: maybe start there

14:38 augustl: ideally not with too many dependencies on the OS so it can run on the bare metal in the future :)

14:38 bbloom: it's a right of passage after all :-)

14:39 augustl: true that :) I've written a lisp in Ruby once, using ruby data so I didn't need a parser :)

14:39 bbloom: arrdem: at this point, it's not clear we as a discipline understand well enough to create a truly useful cross-language VM

14:39 augustl: parsing is it's own entire rabbit hole

14:39 you can fall down the parsing hole and never come out :-P

14:41 arrdem: bbloom: 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:41 bbloom: and that is, I think, good enough

14:42 bbloom: arrdem: that's a turing tarpit argument

14:43 arrdem: there are things we simply can't do on the JVM without being prohibitively complex or slow

14:44 arrdem: bbloom: the usual whipping boy being primitive arithmetic... yes.

14:45 bbloom: arrdem: or much more interesting features, like copy-on-write VM images, or delimited continuations, or more

14:49 arrdem: bbloom: 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:50 bbloom: arrdem: i think we need a lot more VM investment/research

14:50 arrdem: i think that multilanguage VMs are the future... they just aren't the present

14:51 frankly, as nice as clojure is on the JVM, it was designed to fit in to constrained hosts

14:51 which was a brilliant move for rich's goals

14:51 but if you've got research goals, i'd probably target the VM level

14:51 gratimax: aside 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:52 arrdem: gratimax: people will continue to run dynamic languages on VMs and they will continue to be slow

14:52 bbloom: gratimax: that's less true than you'd think. turns out that the JVM is basically already a dynamic language itself

14:52 dnolen: gratimax: getting dynamic languages to run on the JVM isn't that hard. Making them as fast as Clojure however is another matter.

14:52 arrdem: gratimax: so much of compiler driven optimization is type dependant that static types and type analyisis are really critical to "high performance".

14:53 bbloom: arrdem: i'd argue that performance is about specialization, of which static types is only a small part of a balanced strategy :-)

14:55 arrdem: bbloom: let me get my masters, then we can have this talk :P

15:19 * gfredericks assumes arrdem was sitting at his commencement using IRC on his phone and had to get up briefly to accept the diploma

15:19 * arrdem has a bachelors to finish and then will worry about getting said diploma

15:20 lvh_: hi!

15:20 gfredericks: lvh_: hallo

15:20 lvh_: I want to write some clojurescript, and I have a porject which is perfect for a d3.js treemap

15:20 is strokes the thing to use? or should I just use d3 directly

15:21 it doesn't seem to hard either way; for d3 I can just do (-> (whatever) (something else0)

15:22 dnolen: lvh_: 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:23 lvh_: oh. that seems like mostly a win except I don't expect to change the data at all

15:27 i_s: where is this macro now? "-?>" ? (cant get search working for that term)

15:29 rebcabin: i_s: github/rplevy/swiss-arrows

15:29 i think that's what you're looking for

15:29 bbloom: (doc some->) ; i_s

15:29 clojurebot: "([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:29 i_s: great, thank you

15:37 lvh_: is clojure.java.io still what I use to read a line from a file? It seems I want clojure.contrib.io maybe.

15:38 llasram: lvh_: clojure.contrib.* is ancient history

15:38 lvh_: is clojure.contrib.io.read-lines old and busted or something

15:38 okay

15:39 llasram: lvh_: You want clojure.java.io/reader

15:39 like: (with-open [inr (io/reader filename)] (->> inr line-seq do-stuff))

15:39 lvh_: so (first (line-seq (reader "fn"))?

15:39 oh, okay.

15:39 * lvh_ looks up the difference between the two threading macros

15:40 llasram: Yours is fine except you'll want to `with-open` the reader

15:40 Well, which means it needs to go lexically outside the rest of it :-)

15:40 lvh_: that closes the file, I'm guessing? anyway I'll go read clojure.java.io

15:40 Thank you!

15:40 llasram: Yeah -- its a macro which expands to a try..finally block

15:40 np

15:41 AeroNotix: is anyone using Cloverage?

15:50 do my messages appear here?

15:50 gfredericks: ,'yup

15:50 clojurebot: yup

15:50 AeroNotix: ah ok

15:51 gfredericks: apparently cloverage coverage amongst the channel members is lacking

15:51 also maybe sunday is slow

15:51 AeroNotix: gfredericks: I've asked this several times before and it seems that coverage data is not something that people use.

15:52 * gfredericks waves at the aussies going to work

15:52 llasram: Hmm?

15:52 gfredericks: AeroNotix: I saw another library the other day and was going to try it but haven't yet

15:52 AeroNotix: Cloverage is the most widely developed, so far

15:52 gfredericks: yes? Do you remember it?

15:52 gfredericks: I think it was the piplin fellah

15:52 lemmeesee

15:52 AeroNotix: ok

15:53 gfredericks: https://github.com/dgrnbrg/guzheng

15:53 I hadn't heard of cloverage

15:53 I haven't been looking for a coverage tool though I just stumbled on guzheng

15:54 AeroNotix: gfredericks: 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:54 and the output is a custom reporting output, so I can't plug it into e.g. cobertura

15:56 ok so guzheng didn't die when running

15:57 gfredericks: the less catchy the name, the less it crashes

15:58 AeroNotix: gfredericks: any idea how to get the info out of it? It doesn't generate any files

15:58 * AeroNotix reads the source

15:58 gfredericks: AeroNotix: I know nothing about it, sorry

15:58 AeroNotix: gfredericks: cheers anyway

15:59 * gfredericks did not know what "cheers" meant specifically until this exact moment

16:00 AeroNotix: gfredericks: I just use it to mean "thank you"

16:00 but that might be an Englishism

16:00 gfredericks: that is what urban dictionary told me

16:00 AeroNotix: American'ts might try to use it but they just sound weird saying "cheers"

16:00 americant's*

16:01 lol spelling

16:01 whatever, it's late

16:01 gfredericks: the weird part is the definition said you can also use it after *giving* something

16:01 AeroNotix: gfredericks: i've never used it like that, but English is full of contradictions

16:02 gfredericks: (inc english)

16:02 lazybot: ⇒ 0

16:02 gfredericks: lol

16:02 llasram: nice

16:02 gfredericks: alright well now I can be british

16:02 lvh_: Hi! I'm parsing some apache log lines; I really only want the URL path

16:02 is there a thing I can just use that will magically parse apache web server logs?

16:03 llasram: lvh_: There is almost certainly an existing Java library for that

16:04 AeroNotix: lvh_: qtile?

16:05 lvh_: I only know that as a window manager

16:05 llasram: You know what, I'm going to downgrade that to "probably"

16:05 lvh_: llasram: there's a URL parsing lib for clj, but not really paths

16:05 maybe it just magically works

16:06 llasram: lvh_: Oh, if you've already gotten the URL part, then there's lots of options for then parsing the URL

16:06 lvh_: llasram: no, I don't, sorry

16:06 llasram: ,(.getPath (URI. "http://example.com/fun/time/path"))

16:06 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: URI, compiling:(NO_SOURCE_PATH:0:0)>

16:06 llasram: Pfft

16:06 lvh_: I have Apache web server log lines

16:06 llasram: ,(.getPath (java.net.URI. "http://example.com/fun/time/path"))

16:06 clojurebot: "/fun/time/path"

16:06 lvh_: I want the paths out of them

16:06 llasram: Ok, I see

16:07 Yeah -- 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:07 AeroNotix: lvh_: yeah I just remember your handle in the context of qtile... not sure why

16:07 lvh_: I guess maybe I can do a regex match for "(?:GET|POST|PUT|DELETE) (.*) (?:HTTP)"

16:07 what's not-greedy * spelled in clj/java?

16:07 llasram: *?

16:07 clojurebot: * is just for when you are lazy and sloppy

16:07 llasram: heh

16:08 Haha, here's an especially exciting regex solution: http://scalability.org/?p=3802

16:11 lvh_: ,(re-find #"(?:GET|POST|PUT|DELETE) (.*?) (?:HTTP)" " - - [20/Jan/2014:06:31:43 +0100] \"GET /images/nav-off-bg.png HTTP/1.1\" 200 310 \"http://www.python.org/" \"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\"")

16:12 clojurebot: ["GET /images/nav-off-bg.png HTTP" "/images/nav-off-bg.png"]

16:12 lvh_: I don't understand why that gives me two results.

16:12 Didn't I just make the outside groups non-capturing?

16:13 rue__: lvh_: Non-capturing means into a numbered group

16:14 So you are still /matching/ the string, but your only match group is the middle string.

16:16 lvh_: rue__: I got the latter, not the former sentence.

16:16 rue__: How do I get just the match group?

16:16 rue__: It’s the second value in your vector there

16:16 lvh_: rue__: Sure, but I mean in general

16:16 sorry, I'm used to named groups

16:17 rue__: 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:18 oetjenj: non-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:19 gfredericks: I think lvh_ might want a single string back

16:19 ,(re-find #".{3}" "hey look at this")

16:19 clojurebot: "hey"

16:19 rue__: #"(?<!GET|POST|PUT|DELETE) (.*?) (?!HTTP)", I think

16:19 lvh_: Sorry, I was confusing zero-width with non-capturing

16:19 rue__: What's the difference between ?<! and ?!

16:20 rue__: Former is lookbehind, latter is lookahead

16:20 TEttinger: lvh, 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:20 rue__: ^

16:20 oetjenj: TEttinger, correct

16:21 unless there is no match, than re-find returns nil, iirc

16:21 lvh_: rue__: ah, thanks

16:21 Wild_Cat: wouldn't you want re-groups instead, though?

16:21 lvh_: TEttinger: aha; so if I have one matched group...

16:21 gfredericks: TEttinger: it returns a string if there are no matched groupos

16:21 as I demonstrated above

16:21 TEttinger: yep

16:23 rue__: You have one not non-capturing group, which is returned :)

16:23 Krajsnick: How 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:23 elarson: I 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:23 gfredericks: Krajsnick: yeah, java methods aren't first class in that way

16:23 elarson: I understand I'm not getting the right classpath configured, but I sort of assumed lein was taking care of adding standard clojure libs

16:24 Krajsnick: Ah okay, so as a rule of thumb when sending functions as arguments, wrap them if you're using java interop?

16:24 gfredericks: elarson: you have to add it to your :dependencies list

16:24 Krajsnick: yep

16:24 Krajsnick: thanks

16:24 elarson: gfredericks: is that something I can do in a single file? ie not via the project.clj

16:24 gfredericks: not with leiningen

16:24 elarson: this is just a single file I'm wanting to run as a script

16:25 gfredericks: leiningen is pretty project-oriented

16:25 if it has any single-file features I don't know about them

16:26 elarson: well, I found out about lein-exec http://koodo.wordpress.com/2013/11/09/shell-scripting-with-clojure/

16:26 lvh_: Does #"whatever" actually compile the regex? I'm having difficulty figuring out what kind of object it is

16:26 elarson: ah and it looks in that blog I might abel to include some deps

16:26 * elarson continues reading a bit

16:26 elarson: gfredericks: thanks for the help

16:27 gfredericks: elarson: yeah that looks possible

16:27 oetjenj: elarson, have a look at https://github.com/mtyaka/lein-oneoff ... might be what you are looking for, too

16:27 rue__: lvh_: It’s a literal, isn’t it?

16:27 elarson: oetjenj: great, will do'

16:27 gfredericks: lvh_: yeah I think it does

16:27 ,(type #"foo")

16:27 clojurebot: java.util.regex.Pattern

16:28 lvh_: Ah, I didn't know about type :)

16:28 gfredericks: lvh_: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L439

16:28 the reader compiles it

16:29 lvh_: (def lines (with-open [inr (reader filename)] (->> inr line-seq (take 5)))) ;; IOException Stream closed java.io.BufferedReader.ensureOpen (BufferedReader.java:115)

16:29 gfredericks: ,(type (read-string "#\"foo\""))

16:29 clojurebot: java.util.regex.Pattern

16:29 lvh_: Why does that close it already? I'd expect to get the first five lines.

16:29 gfredericks: lvh_: because take is lazy

16:29 hiredman: ,(doc line-seq)

16:29 gfredericks: try adding (doall) after take

16:29 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

16:30 lvh_: that'll be handy :) thanks :)

16:30 (inc gfredericks)

16:30 lazybot: ⇒ 39

16:31 lvh_: (why isn't it more like (swap! gfredericks inc)?)

16:31 gfredericks: then less people would type it

16:31 inc! would be nice maybe

16:32 lvh_: 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:32 gfredericks: I 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:33 lvh_: yeah, that's what I do too

16:33 except in the opposite order

16:33 but otherwise equivalent I think

16:34 gfredericks: I would think the opposite order would be more steps

16:34 N slurps instead of 1

16:37 amalloy: paredit-wrap-square reduces the number of steps, compared to square+slurp

16:37 TEttinger: lvh_:

16:37 ,(re-find #"(?<=(?:GET|POST|PUT|DELETE) ).*(?= (?:HTTP))" " - - [20/Jan/2014:06:31:43 +0100] \"GET /images/nav-off-bg.png HTTP/1.1\" 200 310 \"http://www.python.org/" \"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\"")

16:37 clojurebot: "/images/nav-off-bg.png"

16:42 dbasch: anybody using the latest LightTable in OSX? I can't get instarepl to work

16:43 elarson: this 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:43 llasram: ~tias

16:43 clojurebot: tias is try it and see

16:43 Guest80042: dbasch: How is it failing? It works for me.

16:43 gfredericks: (inc llasram)

16:43 lazybot: ⇒ 15

16:43 elarson: llasram: well I did try it and it failed, which is why I asked

16:43 gfredericks: llasram: my first thought was "ooh ooh I know that one!"

16:43 elarson: the error wasn't really clear

16:43 gfredericks: elarson: what was it?

16:44 dbasch: Guest80042: I try to evaluate anything and I get an exception: http://pastebin.com/HfwKqU8c

16:44 scape_: ,{"one" 1}

16:44 clojurebot: {"one" 1}

16:44 elarson: gfredericks: java.lang.IllegalArgumentException: Parameter declaration missing

16:44 gfredericks: ,(defn foo {"foo" 42})

16:44 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Parameter declaration missing>

16:44 TEttinger: elarson, 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:44 lazybot: ⇒ :value

16:44 gfredericks: elarson: like that? ^

16:44 scape_: no defn

16:44 just def

16:45 oetjenj: ,({"First Name" "a name} "First Name")

16:45 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

16:45 TEttinger: ##({"key" :value} "key") also works

16:45 lazybot: ⇒ :value

16:45 TEttinger: but not ##("key" {"key" :value})

16:45 lazybot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn

16:45 Guest80042: dbasch: Sorry, don't know what's going on there.

16:46 seangrov`: dbasch: Just a guess http://stackoverflow.com/questions/8801142/sonar-build-fails-with-nullpointerexception

16:46 elarson: TEttinger: so that looks like I do need a symbol

16:46 seangrov`: Might need to upgrade your jre/jdk?

16:46 elarson: btw, here is what I was doing: https://gist.github.com/ionrock/8775341

16:46 TEttinger: keywords are functions that can take a hashmap, but other types can be used if you have the hashmap as the fn

16:46 gfredericks: elarson: keys can be anything

16:46 llasram: elarson: defn vs dev

16:46 scape_: don't use defn

16:46 llasram: def even

16:47 dbasch: seangrov`: I'm using build 1.7.0_09-b05, how about you?

16:47 Guest80042: dbasch: I'm using 1.7.0_51-b13

16:47 elarson: (inc llasram)

16:47 lazybot: ⇒ 16

16:47 elarson: thanks llasram

16:47 llasram: np!

16:48 gfredericks: also thanks scape_ who pointed it out first :)

16:48 scape_: going to slink away now

16:48 :D

16:48 elarson: and thanks TEttinger confirming keys can be anything

16:48 gfredericks: ,{{} {}}

16:48 clojurebot: {{} {}}

16:48 dbasch: I'll upgrade to the latest jdk7 and try again

16:48 arrdem: augustl: oh gods and you want to do a rust kernel... I should just watch this repo now :P

16:48 scape_: i think keys being actual keys is much faster as a lookup in a map-- i assume at least

16:48 gfredericks: "actual keywords"

16:49 scape_: thanks yes gfredericks

16:49 seangrov`: dbasch: javac -version => javac 1.7.0_21

16:50 scape_: gfredericks: my middle name is frederick and last name starts with a g :D

16:51 Guest96402: dbasch, seangrov`: The bug says it affects version 6 but not 7, so it'll be weird if that corrects the problem

16:51 dbasch: Guest96402: that didn't fix it

16:51 gfredericks: Scape Frederick Gorschtarch

16:51 scape_: ha

16:51 gfredericks: oh so the 's' in my nick must be fore "scape"

16:51 dbasch: Guest96402: the weirdest part is that the spinner doesn't stop after fetching dependencies

16:52 scape_: hah

16:52 gfredericks: g___ frederick s(cape_)

16:52 dbasch: I launch instarepl, it goes connecting... -> fetching dependencies... -> (nothing)

16:52 but the spinner doesn't stop

16:52 seangrov`: 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:52 Guest96402: Hmm, what happens if you do a lein repl in the project directory?

16:53 dbasch: Guest96402: this is not in any particular project

16:53 leon repo works fine in all my projects

16:53 lein repl

16:54 TEttinger: I have dbasch's problem whenever I use light table

16:54 oetjenj: elarson, 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:54 elarson: oetjenj: ah that is good to know

16:54 thanks

16:54 oetjenj: your welcome ;)

16:55 seangrov`: ibdknox: Where's the best place to get support for lighttable for dbasch and TEttinger? the ml?

16:55 rebcabin: ,(keyword "what happens with spaces")

16:55 clojurebot: :what happens with spaces

16:56 lvh_: rebcabin: yeah I found this useful while interpolating some stuff from csv recently

16:56 CSV keys contained gnarly things

16:56 TEttinger: rebcabin: ##(name (keyword "what happens with spaces"))

16:56 lazybot: ⇒ "what happens with spaces"

16:56 TEttinger: interesting that it still stores it

16:56 llasram: rebcabin: Most Clojure core functions are very much "garbage in, garbage out"

16:57 gfredericks: keywords that don't appear in your source code are usually not a good idea

16:57 I wonder if that's why cheshire defaults to strings

16:58 amalloy: gfredericks: creating keywords is expensive too

16:59 lvh_: 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:59 gfredericks: amalloy: oh interesting

16:59 lvh_: 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:59 gfredericks: lvh_: okay so the template is outside your source code?

16:59 oetjenj: I 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:00 scape_: oetjenj: might want to make sure jre is removed

17:00 dbasch: oetjenj: google is not helpful either, the only match I find is my own pastebin

17:01 oetjenj: well i am not using LT myself, i prefer sublime for small things and IDEA for more with a separate repl anyways

17:01 dbasch: scape_: an older version of light table worked fine for me, I updated to the newest and it stopped working

17:01 lvh_: gfredericks: Correct; I slurp it from a file

17:01 gfredericks: lvh_: what templating language?

17:01 lvh_: gfredericks: I don't really get to choose though because the interpolation lib insists on using :keywords

17:02 amalloy: i 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:02 lvh_: gfredericks: mustache, but I don't really care which one

17:02 it's trusted source markdown; string interpolation would be totally fine if it supported named strings

17:02 scape_: 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:02 sublime is a good middle ground tho

17:02 brb

17:02 gfredericks: lvh_: I think that feels close enough to using the keywords in your code

17:03 Guest96402: I'm pretty excited about lighttable. Not enough to use it for serious work, but it looks like a very solid foundation

17:04 oetjenj: LT REPL is driving me nuts, but that's just my preference i guess

17:04 dbasch: Guest96402: 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:04 rebcabin: https://github.com/overtone/emacs-live‎

17:04 tuned for Clojur

17:04 Clojure* even

17:06 Guest96402: dbasch: 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:06 oetjenj: even 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:06 dbasch: Guest96402: I'll check it out

17:06 oetjenj: Guest96402, dbasch cursive finally works nice, at least in ultimate, haven't tried the community edition

17:07 but i'd assume it works the same

17:11 lvh_: 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:11 gfredericks: lvh_: that is totally possible

17:11 lvh_: I don't really know how to say "go down this map with these keys making thinsg as you go along"

17:11 gfredericks: update-in

17:11 Guest96402: update-in

17:11 lvh_: yay :) thanks

17:12 amalloy: &(reduce (fn [acc path] (update-in acc path (fnil inc 0))) '((a b c) (a b c)))

17:12 lazybot: java.lang.ClassCastException

17:12 amalloy: &(reduce (fn [acc path] (update-in acc path (fnil inc 0))) {} '((a b c) (a b c)))

17:12 lazybot: ⇒ {a {b {c 2}}}

17:12 amalloy: &(reduce (fn [acc path] (update-in acc path (fnil inc 0))) {} '((a b c) (a b d)))

17:12 lazybot: ⇒ {a {b {d 1, c 1}}}

17:12 * gfredericks shakes fist at amalloy

17:12 amalloy: there we go

17:12 lvh_: so that is spelled (update-in map keys inc)

17:12 mrcheeks: ,(inc amalloy)

17:12 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: amalloy in this context, compiling:(NO_SOURCE_PATH:0:0)>

17:12 mrcheeks: heh

17:12 ~amalloy++

17:12 clojurebot: Titim gan éirí ort.

17:13 gfredericks: lvh_: and you use (fnil inc 0) so that it accepts nil the first time

17:13 amalloy: good effort, mrcheeks

17:13 mrcheeks: :-)

17:13 Bronsa: (inc amalloy) ;; there

17:13 lazybot: ⇒ 83

17:13 gfredericks: (inc mrcheeks'-effort)

17:13 lazybot: ⇒ 1

17:13 lvh_: gfredericks: oh, I guess I sort of excpected (inc) to return 0 maybe that's just silly :)

17:13 gfredericks: lvh_: ##(inc nil) is the more relevant call

17:13 lazybot: java.lang.NullPointerException

17:14 gfredericks: which is different from ##(inc)

17:14 lazybot: clojure.lang.ArityException: Wrong number of args (0) passed to: core$inc

17:14 lvh_: gfredericks: yes

17:14 gfredericks: lvh_: and even if it did return 0 that'd be wrong for your case

17:14 lvh_: okay, cool thanks :)

17:15 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:16 gfredericks: aaaah right

17:16 rubby has that too

17:16 lvh_: 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:17 gfredericks: does anybody think a feature like that is bad for some precise reason?

17:17 lvh_: a feature like what?

17:17 gfredericks: maps that return default values

17:17 it'd be easy enough to do

17:18 just mix in a little ztellman...

17:18 lvh_: they have their use cases I think :)

17:18 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:19 oetjenj: don't maps already return a default value? :D

17:19 llasram: gfredericks: It breaks all kind of behavior, doesn't it? You have things "in" the map which aren't in the map `keys` etc

17:19 Guest96402: I've was thinking of something similar recently. The problem is how you deal with idioms like (into {} my-special-map)

17:19 llasram: fnil I think covers most of the behavior you'd actually want

17:19 gfredericks: llasram: Guest96402: yeah those are good points

17:20 it makes it feel more like a function than a data structure

17:20 llasram: Yeah. 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:21 gfredericks: that applies just as well to immutable though

17:22 llasram: Does it? Oh, I guess maybe if you had some sort of updating protocol or something

17:22 Otherwise just getting a default for anything seems weird

17:22 My new standard for interface design decisions: I will avoid things which seem "weird"

17:23 lvh_: 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:23 whereas hey in python yes let's have another dict subclass

17:23 gfredericks: llasram: updating a mutable map still reduces to access + set; i.e., get + assoc

17:24 llasram: gfredericks: You and your "good points". Geez

17:24 gfredericks: clojurebot: python is <reply> yes let's have another dict subclass

17:24 clojurebot: You don't have to tell me twice.

17:24 llasram: clojurebot: python?

17:24 clojurebot: python is ugly

17:24 llasram: Aww

17:24 gfredericks: ~python

17:24 * oetjenj agrees!

17:24 clojurebot: python is "I think dropping filter() and map() is pretty uncontroversial…" — GvR

17:24 gfredericks: ~python

17:24 clojurebot: python is "I think dropping filter() and map() is pretty uncontroversial…" — GvR

17:24 gfredericks: ~python

17:24 clojurebot: python is (defmulti #^{:doc "docs for foo"} foo class)

17:25 llasram: It's in in there somewhere :-)

17:25 gfredericks: this is good reading

17:25 goodger: :(

17:25 gfredericks: ~python

17:25 clojurebot: python is "I think dropping filter() and map() is pretty uncontroversial…" — GvR

17:25 * gfredericks gives up

17:25 AeroNotix: ~@python

17:25 clojurebot: Excuse me?

17:25 AeroNotix: Well, I thought you'd give me them all then

17:25 llasram: Hah. Nice try :-)

17:26 I think the fact-chaining would make that tricky though

17:26 ~amalloy

17:26 clojurebot: amalloy is the spotlight illuminating my dumb mistakes

17:26 llasram: Well, that one was probably direct :-)

17:27 lvh_: ~lvh

17:27 clojurebot: Huh?

17:27 amalloy: i don't think there are any facts chaining from amalloy

17:27 lvh_: maybe one day I will be famous

17:27 llasram: amalloy: I thought I remembered one came up which you figured out went through like 3 hops. May be misremembering obvs

17:27 amalloy: clojurebot: lvh will be famous one day

17:27 clojurebot: Gabh mo leithscéal?

17:27 amalloy: clojurebot: lvh |will| be famous one day

17:27 clojurebot: You don't have to tell me twice.

17:28 lvh_: fwiw I am writing a free introductory course on cryptography that I hope to be releasing in the next 2 weeks

17:28 so maybe that will work

17:28 gfredericks: two-time pads!

17:28 the second-most secure cryptoscheme!

17:29 llasram: lvh_: You are a cryptographer?

17:29 gfredericks: clojurebot: a cryptographer is somebody who makes drawings and then hides them

17:29 clojurebot: Ik begrijp

17:29 lvh_: Hey, that was dutch, sort of.

17:30 llasram: Yes, if that includes applied cryptography. I don't actually design ciphers.

17:30 Morgawr: clojurebot is dutch? :o

17:31 goodger: can't be

17:31 it didn't choke half to death on the g

17:31 lvh_: llasram: Sorry, I should rephrase: I don't design ciphers that I intend people to seriously use, or that I publish :)

17:31 llasram: Heh

17:31 lvh_: LVH is totally the best mode of operation.

17:31 Morgawr: goodger: true true

17:32 hghoodhgher*

17:33 llasram: lvh_: You totally had me going for a sec -- thought it must be one of those newer verifying block cipher modes

17:34 lvh_: llasram: Well, it actually is an AEAD mode.

17:34 llasram: Overall, it's a pretty reasonable one too.

17:34 llasram: Interesting

17:35 lvh_: 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:35 * lvh_ shuts up about crypto now

17:36 llasram: It's an interesting topic!

17:37 Cr8: I have a highlight for "crypto"

17:37 gfredericks: I 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:38 ivan: find more typos and make a bigger patch?

17:38 gfredericks: yep :(

17:38 maybe I should start a typos branch

17:38 * gfredericks does

17:40 llasram: I thought clojure/core had adopted a more expedited process for obvious doc fixes

17:40 gfredericks: maybe they did! that's why I asked

17:40 Bronsa: not really

17:41 llasram: I 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:45 ivan: gfredericks: https://www.refheap.com/31866/raw

17:45 gfredericks: ivan: nice

17:46 mine was s/and/an/ so would not be caught

17:47 amalloy: upto: almost as good a word as alot

17:47 gfredericks: amalloy: refers to a really tall thing

17:47 clojurebot: technomancy is the upto behind leiningen

17:47 clojurebot: In Ordnung

17:48 llasram: (inc gfredericks)

17:48 lazybot: ⇒ 40

17:52 sobel: +1 typos branch

18:03 gfredericks: I'll accept pull requests ;-) https://github.com/fredericksgary/clojure/tree/typos

18:03 dbasch: Guest96402: oetjenj upgrading the clojure plugin to 0.0.6 fixed the lighttable issue

18:04 llasram: gfredericks: Even from people w/o CAs?!?!?!

18:04 ~guards

18:04 clojurebot: SEIZE HIM!

18:04 gfredericks: llasram: oh that does sound sticky

18:04 oetjenj: dbasch, thanks

18:04 gfredericks: let's just say no

18:04 llasram: gfredericks: The die is cast -- your typo branch is the PR-accepting future of Clojure

18:04 Oh, or not

18:05 * llasram goes back to the other side of the Rubicon

18:15 riz_: hi

18:16 * llasram waves

18:17 riz_: what does it mean by: Trying to convince others to use Haskell is permitted between 0200 and 0500 UTC.]

18:17 is it a joke or something which i don't get?

18:19 llasram: There was an active member of the channel who went very pro-Haskell. That was an attempt at a compromise/joke

18:19 amalloy: wait, was? did callen/bitemyapp leave while i was on vacation?

18:19 llasram: I haven't seen him around

18:19 gfredericks: I haven't seen him for a couple days maybe?

18:19 pyrtsa: I think he left.

18:19 riz_: hey are you the guy i talked to other night?

18:19 gfredericks: $seen bitemyapp

18:19 lazybot: bitemyapp was last seen talking on #clojure 1 week and 5 days ago.

18:19 riz_: i can't remember the name

18:19 gfredericks: oh wow

18:20 amalloy: i saw him in #haskell last night

18:20 riz_: i was here at like 4 am cause i couldn't sleep

18:20 pyrtsa: He's active in #haskell.

18:20 riz_: so both haskell and clojure are functional

18:20 then what are the major differences?

18:20 is there something haskell can do that clojure can't?

18:21 dsrx: haskell has the power to turn you into a weenie like no other language can

18:21 deadghost: idk man

18:21 there's js and ruby

18:23 pyrtsa: I'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:23 gfredericks: pyrtsa: I'm curious what "how things went" means

18:24 llasram: riz_: Well, they're both Turing-complete :-)

18:25 pyrtsa: gfredericks: I don't know if "ignorant" is the best word but...

18:26 riz_: aren't most programming languages?

18:26 hiredman: I'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:26 gfredericks: riz_: haskell is statically typed

18:26 llasram: riz_: Yeah, was a joke

18:26 riz_: ohhh

18:26 hehehe

18:26 gfredericks: hiredman: okay, I wasn't sure if there was some aspect that went beyond that, related to languages and such

18:27 llasram: riz_: statically typed, unhosted, pure functional. You get some of the best type-checking and type-based optimization in the industry

18:27 hiredman: to 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:28 * hiredman makes wiggling scale like motions with his hands

18:28 pyrtsa: :)

18:28 clojurebot: excusez-moi

18:28 SegFaultAX: amalloy: I had lunch with him on Thurs. He probably won't be hanging around #clojure much anymore.

18:28 Although still hacking Clojure regularly etc.

18:28 amalloy: SegFaultAX: it sounds like you murdered him

18:28 just fyi

18:28 SegFaultAX: Well, ah.

18:29 gfredericks: amalloy: in a way that still lets him hack on clojure regularly

18:29 llasram: I'm not glad he's gone, but he wasn't always the most newbie-friendly voice

18:29 SegFaultAX: Considering he came to my office, I think my co-workers would have noticed something :)

18:29 riz_: you mean haskell is more efficient than clojure?

18:29 SegFaultAX: gfredericks: I guess I was the one who did all the hacking?

18:30 gfredericks: #murderjokes

18:30 pyrtsa: riz_: 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:30 llasram: riz_: JVM Clojure gets the JVM JIT, so no, not unilaterally for every algorithm, certainly not. It's just different trade-offs

18:31 SegFaultAX: Anyway, the point is he hasn't moved away from Clojure, just #clojure.

18:31 If you want more details, PM or DM on Twitter.

18:33 gfredericks: riz_: being "functional" is almost the only thing the two languages have in common

18:33 SegFaultAX: llasram: For Clojure in particular, I would think most things in Haskell are faster. For Java in general, that's probably not the case.

18:34 Clojure's overhead is significant.

18:34 pyrtsa: gfredericks: Persistent data structures could be another common thing, unless you count it as part of the definition of "being functional".

18:34 gfredericks: pyrtsa: good point

18:34 dnolen: SegFaultAX: people make claims w/ out benchmarks. Last I checked really fast Haskell code looks pretty weird. Same as Clojure.

18:34 hiredman: the 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:34 pyrtsa: Clojure's startup time is a pain. Haskell applications tend to start up very fast.

18:35 SegFaultAX: dnolen: It's just a guess, yea. But Clojure's overhead /is/ significant.

18:35 dnolen: SegFaultAX: so is idiomatic Haskell's

18:36 hiredman: the 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:36 gfredericks: (inc hiredman)

18:36 lazybot: ⇒ 36

18:36 SegFaultAX: dnolen: Sure, but Haskell is compiling down to something native. Clojure is compiling down to something with also significant overhead.

18:37 I don't have numbers or research to backup my guess. Just anecdotal experience.

18:37 dnolen: SegFaultAX: Clojure also compiles to something native due to the JVM.

18:37 riz_: sorry got disconnected

18:39 pyrtsa: dnolen: 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:39 SegFaultAX: dnolen: 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:39 That hasn't been /my/ experience, or the experience of some others, but then I'm not at all an expert on this topic.

18:40 oetjenj: besides 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:41 SegFaultAX: oetjenj: Well in the case of JVM clj, there isn't an option. You couldn't make a purely functional JVM anything.

18:41 pyrtsa: oetjenj: 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:41 gfredericks: you could at the lang level

18:42 hiredman: SegFaultAX: you absolutely could

18:42 oetjenj: SegFaultAX, yes i am aware of that

18:42 SegFaultAX: hiredman: You absolutely could not. At least, not at the JVM level.

18:42 hiredman: the interop would just be terrible

18:42 SegFaultAX: The classloader is inherently side effecting and stateful, as a simple example.

18:43 hiredman: SegFaultAX: the haskell runtime is also full of side effects and state, what is your point?

18:43 gratimax: I'm pretty sure the biggest 'disability' clojure on the jvm has is being dynamic, and it is running on something optimized for java

18:43 oetjenj: in other words, even if you remove two tires from your car, you still don't have a motorbike ;)

18:43 gratimax: Haskell runs on something optimized for haskell

18:43 hiredman: rts(haskell runtime) is still written in C if I recall correctly

18:44 gratimax: I 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:44 SegFaultAX: hiredman: In Haskell, the core side effecting code is very deep and generally not something you can or should touch directly in application code.

18:44 hiredman: https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts

18:44 SegFaultAX: In JVM, the necessary side effecting code is very close to you.

18:45 hiredman: https://github.com/Frege/frege/

18:45 gfredericks: SegFaultAX: a lang can still be pure

18:45 oetjenj: i mean, actually writing a complete side effect free program isn't of much use anyways, is there?

18:45 SegFaultAX: hiredman: That last one is an interesting project. callen was telling me about it recently.

18:46 pyrtsa: oetjenj: No one's writing one, of course. ;)

18:48 SegFaultAX: gfredericks: 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:48 pyrtsa: oetjenj: To say it in Rich Hickeyan terms, Haskell (code) being side effect -free is just a way of saying Haskell programs are values.

18:49 gfredericks: SegFaultAX: dunno; but it's an option :)

18:49 SegFaultAX: I'll revise my previous statement to "You couldn't build a meaningfully useful pure language on the JVM"

18:49 oetjenj: pyrtsa, hehe

18:49 gratimax: pyrtsa: extend this by saying that haskell programs are actually composed IO monads, now you're getting somewhere

18:50 pyrtsa: gratimax: Exactly.

18:52 gratimax: SegFaultAx: 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:52 hiredman: bbloom 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:52 gfredericks: SegFaultAX: also s/dunno/GC/

18:52 gratimax: If you really wanted to, you could write a haskell IO analog in clojure with 'no side effects'

18:53 https://github.com/clojure/algo.monads/

18:53 bam, pure clojure!

18:54 pyrtsa: algo.monads is quite hacky, though. Not too convenient to use.

18:55 AeroNotix: does doto throw away type hints?

18:55 SegFaultAX: gratimax: 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:55 amalloy: AeroNotix: wellllll, not any more than macros in general do. it sorta depends

18:56 gratimax: SegFaultAX: you can abstract that away to something haskell-like, as I mentioned before.

18:58 SegFaultAX: gratimax: For most of the standard library, you'd have to abstract it to the point of re-implementation. So why even use it?

18:59 gratimax: SegFaultAX: that was the whole point of clojure's immutable data structures, isn't it? all that was salvaged was strings and numbers, basically

18:59 so why even have immutable data structures? you need to implement it again anyway

19:00 AeroNotix: amalloy: well all of my dotos seem to complain about the calls being unable to be resolved.

19:00 amalloy: even if I type hint the first expression

19:01 SegFaultAX: gratimax: 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:01 You can of course still call down to Java (and you frequently do, especially to leverage existing code)

19:02 gratimax: SegFaultAX: well, people have still done nice IO to the point of having it 'nearly pure'

19:02 take ring for example. you write web apps as composable handlers, not using sockets and whatnot

19:03 dissipate: why does (and) result in 'true' and (or) results in 'nil'?

19:03 gfredericks: monoids!

19:03 oetjenj: iirc, clojure actually started out as a library of immutable data structures for java - at least i think recall rich saying that somewhere

19:03 AeroNotix: oetjenj: [citation needed]

19:03 gfredericks: dissipate: also (+) (*)

19:04 gratimax: you 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:04 dissipate: gfredericks, that's bizarre. why??

19:04 lazybot: dissipate: Uh, no. Why would you even ask?

19:04 gfredericks: dissipate: or were you asking about nil vs false?

19:04 pyrtsa: dissipate: In general, the `and` and `or` macros do not return Booleans.

19:04 oetjenj: AeroNotix, 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:04 SegFaultAX: gratimax: 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:04 dissipate: gfredericks, no, wondering why 'and' with no arguments evaluates to 'true' but 'or' with no arguments evaluates to 'nil'

19:05 pyrtsa, they don't??

19:05 lazybot: dissipate: Definitely not.

19:05 pyrtsa: ´(or 1 2)

19:05 ,(or 1 2)

19:05 clojurebot: 1

19:05 dnolen: dissipate: he gave a hint with monoids

19:05 gfredericks: dissipate: also consider ##(concat)

19:05 lazybot: ⇒ ()

19:06 technomancy: gratimax: run-jetty is not part of ring-core fwiw

19:06 gratimax: SegFaultAX: true. but most of the time there are clojure versions of these libraries that make you not think about side effects

19:06 dissipate: i don't get it but whatever. :O

19:06 SegFaultAX: gratimax: Most of the time? Wut?

19:07 Do you know how many packages exist in Maven Central?

19:07 gfredericks: dangit I chased somebody off

19:09 gratimax: SegFaultAX: yes, there are probably hundreds of java packages all doing http and web stuff. but there still exists a nice clojure analog

19:11 oetjenj: gfredericks, but the answer would have been quite easy, wouldn't it? :D

19:11 gratimax: SegFaultAX: 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:12 gfredericks: oetjenj: is it? I'm not sure of a succinct thing except "monoids"

19:14 dnolen: gratimax: Haskell actually has similar problems as Clojure in this regard because of unsafe*, thus Safe Haskell.

19:15 gratimax: gfredericks: 'identity elements'

19:15 gfredericks: yeah

19:18 pyrtsa: gratimax: Actually... if you care about more than the truthiness of the result, then neither `and` nor `or` has an identity element.

19:19 (and (and) x) ≠ (and x (and))

19:20 amalloy: well, and has a left identity and or has a right identity

19:23 tomjack: depends on your equivalence relation

19:23 gratimax: I think this is really in how and/or are implemented, in a perfect world they wouldn't take values other than booleans

19:23 pyrtsa: tomjack: I said "if you care about *more* than the truthiness".

19:24 tomjack: yeah :)

19:25 amalloy: gratimax: that's a haskell "perfect world", but in clojure it's pretty handy to be able to write (or x default)

Logging service provided by n01se.net