#clojure log - Dec 19 2012

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

0:21 mpan: Is there an approach to making a quine other than the "program source as string literal with a hole" approach? (currently working on the 4clojure problem)

0:26 liszt: You can find fixed points of your language's evaluator / compiler.

0:27 mpan: but isn't that the original goal?

0:27 sounds a bit circular

0:27 or am I misinterpreting?

0:29 liszt: These are more like fixed points that take advantage of special cases of an interpreter.

0:31 mpan: I guess I was trying to ask how

0:31 liszt: Otherwise, your quine needs to have knowledge of itself self-embedded (otherwise, how is it going to know what to spit out?)

0:32 mpan: I was kind of hoping for a constructive version of a certain proof

0:32 wikipedia seems to suggest there's a nonconstructive one for existence

0:32 liszt: The constructive proof is a "program with a hole."

0:32 mpan: I'm honestly not sure why that bothers me

0:34 amalloy: mpan: yes, there is a good quine of a different sort in let over lambda

0:34 doesn't work in clojure because our backtick is implemented differently from CL's

0:34 http://news.ycombinator.com/item?id=2150805

0:35 mpan: what specific properties of backtick does it expect?

0:35 amalloy: in a sense that's a "program as quoted literal with a hole"

0:35 mpan: also, what does quote followed by unquote or quote followed by quasiquote even mean?

0:36 amalloy: well it expects '`(x ~y) to be read as (quote ((quote x) y)), i suspect

0:37 egghead: I enjoyed the minikanren quines from friedman & byrd's strangeloop talk

0:37 amalloy: whereas in clojure it reads as ##''`(x ~y)

0:37 lazybot: ⇒ (quote (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/x)) (clojure.core/list y))))

0:37 mpan: amalloy: can you explain that input please?

0:37 egghead: https://github.com/webyrd/quines these guys

0:38 mpan: egghead: wow that's cool

0:38 is it searching over valid programs until it hits quines?

0:38 amalloy: sorry, don't have the free time for a whole lesson on quoting now

0:38 egghead: ya mpan

0:39 mpan: thanks for the links you guys

0:39 will look into it further

0:39 egghead: the talk is great if you haven't seen it -- http://www.infoq.com/presentations/miniKanren

0:39 mpan: amalloy: it's an unusual corner case, right? not something necessary for normal usage?

0:40 amalloy: sure. clojure's backtick works fine for general use

0:40 dnolen: mpan: egghead: it works in Clojure now too http://github.com/namin/TAPL-in-miniKanren-cKanren-core.logic/blob/master/clojure-tapl/tapl/test/tapl/test/quines.clj

0:40 egghead: wow dnolen ! very cool :)

0:42 I really need to find an excuse to use core.logic at work...

0:43 amalloy: egghead: sneak it in starting with core.match

0:43 mpan: egghead: are you already using clojure at work?

0:43 egghead: ya mpan

0:43 mpan: awesome :)

0:43 btw mind if I ask where?

0:44 egghead: heh, sure. cj.com

0:44 mpan: cool

0:44 well thank you all

0:44 going to go read those links

1:55 amalloy: i can't believe that the windows java installer still defaults to "install the Ask toolbar and make Ask my default search engine"

2:02 Raynes: amalloy: Yeah, it did that to me.

2:03 amalloy: i bet the guys in ##java have no idea that this is the case, and would totally welcome my reporting it to them as a bug

3:46 wunki: maybe a strange question, but is it possible to get the namespace from where the function (in different ns) is called?

3:57 ivan: wunki: if you have the var, something like (:ns (meta #'map))

3:57 oh, you want to see the caller's namespace?

3:58 wunki: I think it was a bad understanding on my part. When printing *ns* in the namespace of the function, the value is that of the *ns* where the function is called

3:58 so that would fix my need

3:59 amalloy: wunki: no, *ns* is the namespace at compile time

4:00 ivan: I'm sure there's a crazy thing that can walk up some stack frames, but maybe you just want to pass *ns* everywhere, or write a macro that passes *ns*?

4:01 wunki: amalloy: ah, then I'm wrong again :)

4:01 ivan: yes, I will just pass the namespace on

4:02 thanks for the help guys

4:05 roryg: 

4:07 ro_st: why would i be getting an AbstractMethodError when trying clojure.walk/postwalk on this map? https://www.refheap.com/paste/7715

4:08 this is a normal map, not one of datomic's lazy loading entity maps

4:15 borkdude: goat moaning

4:17 ivan: ro_st: works for me, Clojure 1.5

4:18 ro_st: thanks for the report, ivan

4:19 noidi: works in the tryclj.com REPL as well

4:19 ro_st: mind pasting your dependency string from project?

4:19 so i can drop it in here

4:19 noidi: maybe `data` doesn't contain what you think it does?

4:19 ro_st: ahhhh hold on. that deeper {:db/id …} is still a datomic entity

4:19 in memory

4:20 after adding pr-str, read-string to the threading macro, it works

4:22 thanks for the sanity check, folks

4:22 ivan: too bad it prints as something it's not

4:22 ro_st: yeah. it's a special lazy-loading map

4:23 looks and acts like a map, but isn't one

4:23 ivan: :ps-this-lazy-map-will-blow-up-in-your-face true

4:23 ro_st: -grin-

5:42 mindbender1: anyone playing with clojurec

5:43 is it usable for system programming stuff yet

5:43 wunki: ivan: (defmacro some-macro [] `(some-function ~*ns*)) calls `some-function` with the namespace where the macro is used. Somehow this works.

5:45 cmdrdats: ibdknox: how does Light Table connect to projects? nRepl?

6:13 clgv: cmdrdats: you can find out by executing (loaded-libs)

6:13 if it is nrepl you should see it being loaded

6:58 cmdrdats: clgv: cool, thanks - i'll do that

7:01 (filter #(.contains (name %) "nrepl") (loaded-libs)) => ()

7:03 clgv: cmdrdats: that works. testes in CCW^^

7:03 I get: (clojure.tools.nrepl clojure.tools.nrepl.ack ...)

7:05 cmdrdats: cool - i'm curious to know how light table connects and what it's longer running goal for project connectivity is

7:05 I would love to see nrepl support since it's becoming quite ubiquitous

7:10 clgv: cmdrdats: you mean how it evaluates code.

7:10 ro_st: i think he means how it connects to the running jvm for a given lein project

7:12 cmdrdats: clgv: as ro_st points out, yes :)

7:15 clgv: thats also how it evaluates code ;) :P

7:15 cmdrdats: yes, true :)

7:15 but I don't mind too much if it wants to do something else too

7:25 i also really really wish that all other clojure IDE's would implement paredit-forward-slurp-sexp, paredit-forward-barf-sexp and the backward variants…

7:25 make the playing field a little more even

7:27 ro_st: and the parens aware selection and navigation stuff

7:28 all of paredit, really. nothing major -grin-

7:28 cmdrdats: hehe, true

7:28 should be standard fare

7:33 clgv: cmdrdats: huh? do you use more than one IDE for development?

7:34 cmdrdats: i'm using emacs primarily, but always testing the waters

7:35 and giving emacs to a newbie is a very daunting task, so like to have backups for such cases

7:35 paredit makes emacs worth suffering through though

7:36 clgv: well CCW has a lot of paredit stuff as well - probably not complete...

7:36 ro_st: yup. you can't avoid the pain of building up the muscle memory. especially as someone used to windows text editing

7:39 cmdrdats: clgv: i saw the paredit.clj for ccw - looking promising

7:40 https://github.com/laurentpetit/paredit.clj/blob/master/src/paredit/core.clj

7:41 hmm, looking at it - is :paredit-expand-right the one where it moves the paren along a form?

7:43 mindbender1: is there a clean way of recovering from a BindException without having to restart the repl. In my case the exception is persisting even after trying with other ports

7:47 clgv: cmdrdats: I only know the keyboard keys not the implementation names ;)

7:49 cmdrdats: clgv: haha - ok, so do you have a keyboard key that does that? :D (ie) this => (ie this)

7:49 borkdude: C-) right?

7:49 forward-slurp or smth

7:49 clgv: cmdrdats: humm if so I dont know ;)

7:50 currently I use a pretty limited set of those operations ;)

7:50 cmdrdats: borkdude: ye, but for ccw :)

7:51 clgv: it changes clojure coding from carving a static blob into a completely dynamic, fluid experience…

7:51 ro_st: great way to put it

7:51 it makes coding a speed of thought thing

7:52 cmdrdats: (let [x]) (calc) => (let [x (calc)])

7:52 prime example :P

7:52 bosie: how would i translate this java code "string.getBytes(Charset.defaultCharset)" to clojure?

7:52 specifically, the Charset.defaultCharset throws me

7:53 i did (.getBytes string)

7:53 cmdrdats: Charset/defaultCharset ?

7:53 clgv: cmdrdrats: hmm gotta try that and remember it. I am already glad for paren level selection^^

7:53 bosie: namespace Charset is not known

7:54 cmdrdats: hmm, java.nio.Charset ?

7:54 clgv: borkdude: humm C-) does not work here

7:54 ro_st: you have to import it first

7:54 bosie: (import java.nio.charset.Charset)

7:54 borkdude: clgv (paredit-forward-slurp-sexp)

7:55 clgv: borkdude: whats the name in the settings?

7:55 bosie: hmm no

7:55 borkdude: clgv what settings? nm

7:56 clgv: borkdude: CCW "Keys" settings

7:56 borkdude: clgv ah, I don't know =)

7:56 cmdrdats: clgv is in ccw, borkdude in emacs, i'm guessing :)

7:56 bosie: so how would i call a static method on java.nio.charset.Charset? i tried Charset/defaultCharset and (.defaultCharset Charset)

7:57 borkdude: bosie (java.nio.charset.Charset/defaultCharset args)

7:57 bosie: oh

7:57 i see

7:57 cmdrdats: (.getBytes string (java.nio.charset.Charset/defaultCharset)) should work?

7:57 bosie: i didn't "wrap" java.nio.charset.Charset/defaultCharset as a function call

7:58 thanks

7:59 stupid me, gah.

8:02 borkdude: bosie at least I'm not the only one making stupid mistakes, so tnx ;)

8:04 cmdrdats: not that stupid, i can see how one would make the mistake

8:04 Charset/defaultCharset looks more like a constant that a method call :P

8:04 borkdude: cmdrdats yes of course =)

8:05 clgv: ,java.nio.charset.Charset/defaultCharset

8:05 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to find static field: defaultCharset in class java.nio.charset.Charset, compiling:(NO_SOURCE_PATH:0)>

8:06 clgv: ,(java.nio.charset.Charset/defaultCharset)

8:06 clojurebot: #<UTF_8 UTF-8>

8:06 clgv: no it's a function^^

8:06 borkdude: "Unable to find static field. Did you mean to call a method?" helpful error messages project ;)

8:07 clgv: ,(java.nio.charset.Charset/availableCharsets)

8:07 clojurebot: #<SecurityException java.lang.SecurityException: denied>

8:07 clgv: lol^^

8:07 &(java.nio.charset.Charset/availableCharsets)

8:07 lazybot: ⇒ #<UnmodifiableSortedMap {Big5=Big5, Big5-HKSCS=Big5-HKSCS, EUC-JP=EUC-JP, EUC-KR=EUC-KR, GB18030=GB18030, GB2312=GB2312, GBK=GBK, IBM-Thai=IBM-Thai, IBM00858=IBM00858, IBM01140=IBM01140, IBM01141=IBM01141, IBM01142=IBM01142, IBM01143=IBM01143, IBM01144=IBM01144,... https://www.refheap.com/paste/7717

8:09 cmdrdats: :P

8:09 clgv: &(count (java.nio.charset.Charset/availableCharsets))

8:09 lazybot: ⇒ 161

8:13 Fauno1: &(System\currentTimeMillis)

8:13 lazybot: java.lang.RuntimeException: Unsupported character: \currentTimeMillis

8:13 Fauno1: &(System/currentTimeMillis)

8:13 lazybot: ⇒ 1355922372489

8:16 clgv: &(java.util.Calendar/now)

8:16 lazybot: java.lang.NoSuchFieldException: now

8:38 solussd: core.logic is so cool… I need ideas for how to use it!

8:39 llasram: solussd: "This is a really awesome hammer. Now I just need to find some nails..."?

8:40 * Bergle_1 hoards his nails.

8:41 ejackson: solussd: it can be used for _.0 :)

8:41 solussd: exactly. well, maybe more like "this is a really awesome lithium polymer battery powered screwdriver, now I just need some screws"

8:43 ejackson: i know the feeling well

8:43 solussd: I need to find a way to sneak it into some production code at work. :)

8:46 Bergle_1: there exists a special hell for those who sneak new tech into prodution code.

8:46 ejackson: its called 6 months time

8:50 solussd: :)

8:51 I'll pit new, un-battle-tested clojure code against anything our .net team writes any day

8:51 ro_st: +1

8:52 cmdrdats: +5

8:52 solussd: it's certainly possible to write bugs in clojure, but it's a lot harder- and when you do, they're much easier to find, imo.

8:53 ro_st: all together now: Clojure is easier to reason about

8:56 noidi: I find random Clojure code immensly more understandable than random Java code, because Clojure code largely consists of calls to standard library functions that we all know and love

8:56 whereas in Java you'll have 20 layers of custom-built crap that's different in each project

8:57 ro_st: i'm going to go back to clojurebook.com over the year-end break. haven't looked at it since two weeks i spent reading it before writing a single line of code. going to be quite interesting to see how i've changed :-)

8:57 solussd: exactly. Clojure gives you uniform interfaces to your data- which is usually stored in something that implements IPersistentCollection. In java, each object has a proprietary interface.

8:58 jballanc: anyone here have experience using http.async.client?

9:11 borkdude: jballanc only indirectly, through twitter-api :)

9:11 jballanc: if I'm reading the source correctly, it seems to do a lot of polling, no?

9:12 or wait...maybe not

9:12 borkdude: jballanc ask neotyk whenever he is here, or on twitter

9:12 jballanc: cool, will do :)

9:30 acron^: How do I select a value in a list? I have ["hello"] and I just want "hello"

9:31 cark: ,(first ["hello"])

9:31 clojurebot: "hello"

9:31 cark: note that ["hello"] is a vector, not a list

9:31 acron^: sorry :)

9:31 cark: =)

9:32 acron^: perfect, thank you

9:32 (first (vals (select-keys params [:name]))) <- is there a nicer way to do this ?

9:33 Ember-: acron^: also, if you have multiple strings in a list/vector and you want to use em all as parameter for something else you can use apply

9:33 ro_st: (str 1 2) same as (apply str [1 2])

9:33 Ember-: ,(str apply '("foo" "bar"))

9:33 clojurebot: "clojure.core$apply@fd3b2c4(\"foo\" \"bar\")"

9:33 Ember-: oops :)

9:33 cark: (get {:name "john" :id 1} :id)

9:33 Ember-: other way around!

9:34 cark: ,(get {:name "john" :id 1} :id)

9:34 clojurebot: 1

9:34 Ember-: ,(apply str '("foo" "bar"))

9:34 cark: or

9:34 clojurebot: "foobar"

9:34 cark: ,(:id {:name "john" :id 1})

9:34 clojurebot: 1

9:34 cark: or

9:34 ,({:name "john" :id 1} :id)

9:34 clojurebot: 1

9:36 cark: (first (vals (select-keys params [:name]))) there should be some hall of fame for such roundabout snipets =P

9:43 augustl: is it possible to delete stuff from a schema in datomic? (Read: create a new transaction with a datom that removes it). Or does the schema have to be valid for all old and new data ever added (which it wouldn't be if I "deleted" an attribute)?

9:44 ro_st: not possible, because there will always be datoms that use that schema

9:44 simply stop using it in your code

9:44 not ideal, i know. we're lucky in that we get to rebuild our database and leave the crud behind, but at some point it's going to be unavoidable

9:44 augustl: my system allows users to specify a schema. Seems like for now the best way to solve it is to store the schema and data as strings (via JSON or something), since I only query it via Lucene anyway.

9:45 as in, don't use datomic for the dynamic schema stuff, and only store "now" in lucene

9:45 ro_st: happily, you can add metadata to retired schema and have your app warn when used

9:47 augustl: ro_st: I suppose another alternative is to create completely new schemas when the user modifies the current one (by removing an old attribute, for example)

9:47 ro_st: you mean new databases?

9:48 augustl: and have a datom somewhere that tells me which schemas that is the current one

9:48 hmm yeah I guess so :)

9:48 that would mean migrating all the data too though..

9:48 at least the current data

9:49 ro_st: yup. i'm currently finding out how much fun that is; i'm trying to do it programmatically by exporting data appropriate for d/transact to run

9:49 running into issues, though.

9:50 augustl: but since I don't actually need to query the user made schemas with datomic (as mentioned I do that through lucene) I can just store the dynamic data as json or whatever. I just need to use it to build views showing the history of changes etc

9:50 acron^: ^ cheers for that guys :)

9:50 helpful as always

9:51 cark: i've only been doing clojure a week so my code is pretty horrendou,s I don't doubt :P

9:51 augustl: ro_st: thanks for the input

9:52 ro_st: curious, what's your use case, augustl? what do your users put in their database?

9:52 augustl: ro_st: it's a power user system for event agencies (conferences etc, not programmatic events), where the user can specify the fields for attendants per event

9:53 so a user might remove an attribute where some attendants already has data in it, but that doesn't mean deleting that attribute from the history of changes to the attendant data, etc

9:54 or add a new attribute at any time during an event

9:54 ro_st: i think you'd be far better served by marking those fields as deleted with some sort of additional metadata and filtering them out in your app code

9:55 altering schemas such that you have to migrate data will be a lot more painful. i speak from experience. i currently have two Free transactors running and two nrepls and i'm iteratively producing and attempting to transact data from one to the other

9:55 augustl: ro_st: do you have any clue how datomic handles adding new stuff to the schema "run-time", as per a users request?

9:56 as in, is adding attributes "slow" and should only be done in migration tasks where stuff is taken down, etc?

9:56 ro_st: why two transactors? can't have two databases with the same name. even at different points in time.

9:56 adding attributes is no slower than adding 'normal' data

9:56 augustl: ah

9:57 ro_st: it's just asserting facts, albeit into a special partition which is used to validate incoming data in transactions and attributes in queries

9:57 :db.part/db

9:58 all the processing around schema occurs when transacting or querying data that uses said schema. i don't think it's possible to assert changes to schemas that affect indexes

9:58 augustl: interesting, so schema is mostly validation?

9:58 ro_st: at least, i know they're working on it

9:59 well, it also specifies performance critera such as indexing, and then typing and cardinality, as you know :-)

10:00 feel free to take all this with a pinch of salt. i speak more from experience than from intimate knowledge of their code :-)

10:02 aaaand i'm off. good luck augustl

10:02 augustl: thanks :)

10:04 cark: acron^: hehe sorry didn't mean to offend. learning is always like that =)

10:04 acron^: No offence taken :)

10:05 cark: =)

10:12 jsabeaudry: Is there a way to print compojure routes? (bonus points for printing parameters too)

10:14 weavejester: jsabeaudry: Not currently

10:15 augustl: route info as metadata on handler functions? :)

10:15 weavejester: Yeah, that's one approach I'm considering

10:15 jsabeaudry: weavejester, ok, thanks for the info

10:16 weavejester: Another is to put something on top of Compojure that's more restrictive but more transparent

11:03 gfredericks: is there really not a clojure.core/array?

11:03 tsdh: gfredericks: clojure.core has amap, aset, areduce, etc.

11:04 gfredericks: I want to check if something is an array

11:05 tsdh: gfredericks: (.isArray (class obj))

11:05 gfredericks: yeah I was just concluding that myself

11:05 tsdh: :-)

11:05 gfredericks: tsdh: thanks

11:05 tsdh: You're welcome

11:15 hyPiRion: I wonder if we get 1.5.0 as a Christmas present

11:15 or if it's a present for like, May or something.

11:24 gfredericks: should korma's str-value function (convert a value into a SQL string) be a multimethod or a protocol?

11:26 hyPiRion: gfredericks: Will all values of same type have the same representation as a SQL string?

11:26 If so, then yes. Otherwise no. Protocols = dispatch on class

11:28 gfredericks: currently the function is a cond that checks map? keyword? nil? true? false? coll? :else

11:32 I guess coll? isn't easily supported with protocols or multimethods :/

11:32 hyPiRion: java.util.Collection

11:33 ?

11:33 $source coll?

11:33 lazybot: coll? is http://is.gd/9uZURt

11:34 hyPiRion: clojure.lang.IPersistentCollection

11:36 * gfredericks hrms

11:37 hyPiRion: But that's an interface, eh.

11:38 gfredericks: you can extend a protocol to an interface

11:41 clgv: hyPiRion: but that should work. since `isa?` is used

11:41 hyPiRion: gfredericks: What happens if you extend two interfaces, and both are implemented on the object you're dispatching?

11:42 Just pick one of them?

11:43 gfredericks: hyPiRion: I think it defers to the JVM dispatch semantics? which I don't understand.

11:44 hyPiRion: whut

11:44 gfredericks: can't you define a java method that takes a java.util.List in one declarationd an a java.util.Map in another?

11:44 hyPiRion: I should know this, but I don't, hmm.

11:45 gfredericks: yeah, sure thing

11:45 gfredericks: hyPiRion: so I don't know what the jvm does with that

11:45 hyPiRion: You can implement two interfaces with the same method name and same signature, even. That's not what protocols do though

11:46 gfredericks: It'll statically dispatch based on type

11:46 It happens compile-time.

11:46 gfredericks: no I mean class Foo{ void bar(List x){ ... } void bar(Map x){ ... } }

11:47 * gfredericks has to go to a meeting

11:47 gfredericks: but assume I have another class ListAndMap implements List, Map {}

11:47 and then I pass that to Foo#bar

11:47 hyPiRion: gfredericks: Oh right

11:47 gfredericks: which definition does it call?

11:47 hyPiRion: You have to specify the type then

11:47 cast it to one of the interfaces

11:48 otherwise Java complains, afaik

11:51 clgv: hyPiRion: multimethods usually complain if they cannot decide and then you need to tell it which case to prefer

11:51 grc`: Namespace question I think. I want to call a function held in a list. It doesn't seem to be being resolved, At the REPL > print returns core$print but (first '(print)) gives me an unqualified "print". What am I missing?

11:52 clgv: grc`: `resolve`

11:52 grc`: clgv: Thanks

11:52 clgv: though that gives you the variable and not a symbol with attached namespace

11:55 hyPiRion: Eventually you could do backquote instead

11:55 ,(first `(print))

11:55 clojurebot: clojure.core/print

11:56 hyPiRion: ,print

11:56 clojurebot: #<core$print clojure.core$print@28c36197>

12:14 nDuff: I have a method with an argument list of ^Boolean [^long tsOld, ^long tsNew, ^double secondsPerBatch], invoked from a gen-class as #^{:static true} [windowBatch [long long double] Boolean]

12:15 ...however, at runtime, use results in NoSuchMethodError clojure.lang.IFn$LLDO.invokePrim(JJD)Ljava/lang/Boolean;

12:16 ...any pointers in terms of what I'm missing?

12:17 hyPiRion: nDuff: I'll pop up a minimal example

12:18 https://www.refheap.com/paste/7723

12:18 I suspect you're missing the :methods part

12:19 nDuff: hyPiRion: Not the case, sadly.

12:19 hyPiRion: My code, in context, is at https://gist.github.com/73899d73914b4da15d3d

12:21 hyPiRion: Hmm, have you tried to put the method at the start of the :methods vector?

12:21 nDuff: hyPiRion: ...the exception is thrown by boundsetter.miniepl$_export_Fn_windowBatch.invoke, which wouldn't exist at all if gen-class weren't creating that method.

12:27 technomancy: ^:this-metadata-intentionally-left-blank

12:29 nDuff: Not hinting the return type does indeed fix things up.

12:30 technomancy: I wonder if we'll get an influx of new-language-new-years-resolution folks in January

12:31 gfredericks: I'm gonna work through one 4clojure problem every day!

12:31 hyPiRion: technomancy: Is that common?

12:31 technomancy: hyPiRion: I don't know; I picked it up in November as an early new-years thing just because of a pragprog book sale =)

12:32 hyPiRion: It's not a resolution then, it's curiosity :)

12:32 TimMc: ,(-> (with-meta 'cons {:car 1 :cdr (with-meta 'cons {:car 2 :cdr (with-meta 'cons {:car 3 :cdr 'nil})})}) meta :cdr meta :car)

12:32 clojurebot: 2

12:33 technomancy: the Pragmatic Programmer book recommends learning a new language every year

12:34 hyPiRion: Well, if I had a ton of books about programming languages, I'd say that too.

12:34 technomancy: haha

12:34 ejackson: yeah, they (or somebody else) upped that to one a week didn't they. Madness.

12:35 hyPiRion: ejackson: I think 7 langs in 7 weeks was mostly to let you taste different paradigms.

12:36 Not to learn the languages

12:36 I killed your joke now, didn't I?

12:38 gtrak: technomancy: how long does it take to learn lisp?

12:38 technomancy: gtrak: depends on your definition of "learn" and "lisp" =)

12:39 you could probably learn lisp 1.5 in a couple weeks

12:39 gtrak: exactly :-), what's it mean to learn a language every year?

12:39 I can probably learn enough ruby to write a web service in a week..

12:40 or... I can learn more clojure... how about, 'learn a lot of things every year'

12:40 technomancy: yeah, the point is not to stagnate; "learn one language a year" is an audacious way of stating it but certainly not the only way

12:40 it is a great way to get your point across to new developers in a punchy one-liner though!

12:41 hyPiRion: Especially if you use juxt.

12:41 technomancy: all hail the juxt

12:41 tbaldridge: and I'd put in that 1 paradigm per year is a good starting place. Study prolog, erlang, haskell, as different ways of seeing the same problem.

12:41 Just don't learn Java, then C#, then C++, then Python, the Ruby

12:42 hyPiRion: tbaldridge: Agreed. Going from C++ to Java isn't going to take a year.

12:42 tbaldridge: That's just stagnating, imo

12:42 gtrak: I think fads and switching all the time are a little harmful

12:42 it's not useful advice to the people who need it

12:42 technomancy: "We play both kinds of music here; country and western." <- yeah, I know Java and C++

12:43 tbaldridge: My point is, some people say "I'm going to branch out" and then they go learn yet one more OOP language.

12:43 gtrak: the alan perlis quote is better, "A language that doesn't affect the way you think about programming, is not worth knowing."

12:43 tbaldridge: (inc gtrak)

12:43 lazybot: ⇒ 2

12:43 hyPiRion: (inc alanperlis)

12:43 lazybot: ⇒ 1

12:43 tbaldridge: (map inc [gtrak alanperlis])

12:43 technomancy: gtrak: 2 or 3 years in and you won't be a junior developer anymore; you'll be confident enough to know when your own sense of what to do should override what you read in a book =)

12:44 sgeo: Java might be worth learning for a hypothetical person

12:44 technomancy: which is a lot like other truisms like "never use alter-var-root" and "eval is evil"

12:44 sgeo: Say they go from Haskell to Scheme to ... I don't know, PostScript

12:44 gtrak: technomancy: I think that kind of knowledge isn't accidental... and you won't get it from passively switching frameworks/languages all the time

12:45 technomancy: not sure what passively switching languages means?

12:45 TimMc: ~#19

12:45 clojurebot: 19. A language that doesn't affect the way you think about programming, is not worth knowing. -- Alan J. Perlis

12:45 sgeo: Introduction to class-based OO might be interesting to them

12:45 hyPiRion: ,(doseq [person '[gtrak alanperlis]] (println `(~'inc ~person)))

12:45 clojurebot: (inc gtrak)

12:45 lazybot: ⇒ 3

12:45 clojurebot: (inc alanperlis)

12:45 lazybot: ⇒ 2

12:45 tbaldridge: showoff

12:46 gtrak: err, you know... I won't feel comforted by having met his criteria... and that's what it takes to be confident about overriding what the book says. That sense of self-direction should be there a priori.

12:47 just because I used an abstract-factory pattern, it doesn't mean I'm doing good OO..

12:48 passively-switching implies there's a way to mindlessly meet the criteria, and being mindful is the right answer

12:48 tbaldridge: in other words: cargo cult

12:49 technomancy: sure; that's higher-order advice

12:49 egghead: very cool 4clojure fork gfredericks

12:49 sgeo: What fork?

12:49 technomancy: while it's relevant, "use critical thinking" is not really the kind of thing that necessarily belongs in a programming book

12:50 egghead: sgeo: it's core.logic problems instead of general clojure problems: http://4clojure.gfredericks.com

12:50 sgeo: egghead, that's awesome

12:51 Topics: Me

12:52 Err, is it currently broken, or do I just have the wrong answer>

12:52 The latter

12:53 jsabeaudry: ,(.putShort (java.nio.ByteBuffer/allocate 2) 0xf000)

12:53 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for short: 61440>

12:53 jsabeaudry: Any idea how I can do this while keeping the hex format?

12:53 In java I beleive it would only be a cast

12:54 TimMc: You mean, convert it to a signed short?

12:55 egghead: sgeo: I am stuck on the second, maybe it is borken...

12:55 shouldn't (run* [q] succeed) always be true so '(_.0) ?

12:56 jsabeaudry: TimMc, possibly, the important is to write those bytes in the bytebuffer, It seems I can .(.putChar (char 0xf000)) but that is a bit ugly

12:57 ejackson: egghead: maybe _0 ?

12:58 TimMc: jsabeaudry: Sneaky. I forgot that the JVM had an unsigned type of the same size.

12:58 egghead: ah, that was it, thanks ejackson

12:58 jsabeaudry: TimMc, do you know how I can make a signed short out of the litteral 0xf000?

12:59 technomancy: man, it's weird to see people mention clojure on gnome blogs I've been reading since 2004

13:02 mattmoss: ,(class 0xf000)

13:02 clojurebot: java.lang.Long

13:02 mattmoss: ,(let [a 0xf000] (if (< a 0x8000) a (- a 0x8000)))

13:02 clojurebot: 28672

13:04 mattmoss: hmm

13:04 ,(let [a 0xf000] (if (< a 0x8000) a (- a 0x10000)))

13:04 clojurebot: -4096

13:04 jsabeaudry: In java one can simply do "(short)0xf000" is there an equivalent in clojure?

13:05 mattmoss: (short (if (< 0xf000 0x8000) a (- a 0x10000)))

13:05 ,(short (if (< 0xf000 0x8000) a (- a 0x10000)))

13:05 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0)>

13:05 TimMc: jsabeaudry: Doesn't that truncate in Java?

13:06 &(apropos 'short)

13:06 lazybot: java.lang.RuntimeException: Unable to resolve symbol: apropos in this context

13:06 TimMc: &(use 'clojure.repl)

13:06 lazybot: ⇒ nil

13:06 TimMc: &(apropos 'short)

13:06 lazybot: ⇒ (shorts short-array short aset-short unchecked-short shorten-url bitly-shortener shortener shorten shorten-custom shorten-isgd isgd-shortener)

13:06 zerokarmaleft: unchecked?

13:06 mattmoss: ,(short (if (< 0xf000 0x8000) 0xf000 (- 0xf000 0x10000)))

13:06 clojurebot: -4096

13:06 zerokarmaleft: ,(unchecked-short 0xf000)

13:06 clojurebot: -4096

13:07 jsabeaudry: ohhhh

13:07 mattmoss: well, that's cool

13:07 TimMc: &(unchecked-short (int Character/MAX_VALUE))

13:07 lazybot: ⇒ -1

13:34 hyPiRion: ,0xffffffff

13:34 clojurebot: 4294967295

13:34 hyPiRion: Oh, it's parsed as a long?

13:36 TimMc: 0xfffffffffffffffffffffffffffff

13:36 ,0xfffffffffffffffffffffffffffff

13:36 clojurebot: 83076749736557242056487941267521535N

13:36 TimMc: Or bigger!

13:38 hyPiRion: Well, it's a Java wart removed at least

13:38 int n = 0xffffffff; would make n = -1

13:41 TimMc: ew

13:43 public platonicint n = 0xffffffffffffff;

13:43 Oh for a full numeric tower...

14:06 hyPiRion: oh darnit

14:08 I just realized I'm trying to create a macro, but I'm not sure what it's supposed to do or what it is supposed to get as input. The only thing I know is that my I need it somehow.

14:08 s/my//

14:11 egghead: hey gfredericks I'm doing this core.logic 4clojure and I think one of them might be unsolvable

14:11 problem 41

14:11 can run* take two params or only one?

14:12 shouldn't it be (run* [q] (fresh [a b] (== q [a b] ...

14:14 AimHere: run* can take two parameters

14:16 TimMc: hyPiRion: Sounds like you're gonna have a bad time.

14:16 amalloy: egghead: (run* [a b c] (...)) is equivalent to (run* [q#] (fresh [a b c] (== q# [a b c]) (...))), iirc. something close to that, anyway

14:22 hyPiRion: TimMc: I figured out what I was interested in, not just let me write a doc for it so I don't forget it agani

14:22 s/not/now/

14:24 alex_baranosky: does Korma run on 1.2.1

14:25 hyPiRion: TimMc: https://www.refheap.com/paste/7726

14:26 Was a bit hard to grasp the idea at first, but it looks okay now.

14:28 amalloy: hyPiRion: why is this a macro? i see very little reason for it to not be a function

14:29 and several reasons for it not to be a macro

14:30 TimMc: hyPiRion: The binary case doesn't make sense -- fn-a is ~@-inserted?

14:30 Also, what is the "g" in the doc?

14:30 hyPiRion: TimMc: fn-a is a form

14:30 I need to sleep. g is b

14:31 example call: (fn2->fn3 (a some params to it) (b some params))

14:31 where a and b return fns

14:31 TimMc: and you named it fn3->fn2

14:31 hyPiRion: and a calls b if some condition is met

14:32 TimMc: right. That's what I meant.

14:32 ;(

14:33 amalloy: that expands to (fn [x y z] (let [b (b some params), g (...)] ((a some params to it b) y z)))

14:33 hyPiRion: amalloy: correct.

14:33 bosie: why would #"google\\..+" not match "google.com" ?

14:34 amalloy: too many \s

14:34 TimMc: bosie: No need to double-escape in Clojure regexp literals.

14:34 bosie: TimMc: \. doesn't compile though?

14:34 TimMc: Except where it comes to quotes, of course.

14:34 amalloy: of course it does

14:35 &(re-find #"google\..+" "google.com"

14:35 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

14:35 hyPiRion: ,(re-find #"google\..+" "google.com")

14:35 clojurebot: "google.com"

14:35 amalloy: &(re-find #"google\..+" "google.com")

14:35 lazybot: ⇒ "google.com"

14:35 bosie: amalloy: "RuntimeException Unsupported escape character: \. clojure.lang.Util.runtimeException (Util.java:170)"

14:35 hyPiRion: zing

14:35 amalloy: &(re-find #"google\\..+" "google\\.com")

14:35 lazybot: ⇒ "google\\.com"

14:35 hyPiRion: bosie: you sure you have # prepended to ""

14:35 bosie: hyPiRion: dang

14:35 brehaut: bosie: what are you wanting this regexp for?

14:36 mpan: where can I find the core.logic version of 4clojure which was mentioned earlier? I'm probably googling for the wrong keywords

14:36 dnolen: mpan: http://4clojure.gfredericks.com

14:36 bosie: brehaut: i want to define some regex and see if any of them are contained in a string

14:36 amalloy: hyPiRion: imo this macro is bonkers, but if you specifically want exactly what you have...well, i think you're bonkers too, but you can't do it with a function

14:36 mpan: dnolen: Thank you!

14:38 TimMc: bosie: That much was obvious. :-)

14:39 brehaut: bosie: anything more specific?

14:39 TimMc: (He's probably asking because you are probably reimplementing something needlessly or even dangerously.)

14:39 brehaut: TimMc is correct

14:40 hyPiRion: amalloy: Without context it is indeed.

14:40 amalloy: gfredericks: http://4clojure.gfredericks.com/problem/2 is a lot harder than you intend it to be, because the user has to somehow guess that the answer is '[_0]

14:40 hyPiRion: and without context I am as well.

14:40 bosie: brehaut: well, i want to skip certain domains

14:40 brehaut: domains which are given as a list

14:40 brehaut: bosie: and you want to find these domains in a full urI/uri string?

14:40 bosie: brehaut: yes

14:41 brehaut: i read in a list of full uri strings

14:41 mpan: would you like to match example.com/google or not?

14:41 brehaut: bosie: perhaps something like https://github.com/cemerick/url/

14:41 would be smarter

14:41 bosie: mpan: i wouldn't skip it

14:41 brehaut: or perhaps java.net.URL

14:42 amalloy: it would be better written, IMO, like: (= '[_0] (run* [__] succeed)). not a challenging problem to solve, but teaches the user that succeed is a goal, that "anything" is represented as _N, and that run* doesn't care what name you give the result

14:42 bosie: brehaut: how so?

14:42 brehaut: mpan: use an existing URL parsing implementation, and just ask it for the domain

14:43 bosie: brehaut: the list of URLs i want to skip doesn't specify the domain per se. e.g. i would say any google domain

14:43 mpan: bosie: in the sense that URLs have semantic information in their components, and just regexps don't quite represent that fully

14:43 bosie: mpan: sure

14:43 mpan: might or might not make a difference in your particular use-case

14:44 dnolen: amalloy: +1

14:44 bosie: brehaut: i am not sure what you are suggesting. wouldn't i still need the regex?

14:44 brehaut: parse each full uri string from the list and check it against the list of blacklisted domain regexes?

14:44 mpan: bosie: but you'd be specifically matching against a particular component not the whole url

14:45 brehaut: mpan has it

14:45 bosie: mpan: ok

14:45 TimMc: bosie: What do you want to do in each of the following cases? "http://docs.google.com/&quot;, "http://google.com.example.net/&quot;, "http://example.net/google.com/etc"

14:46 bosie: TimMc: block, dont block, block

14:46 TimMc: That last one, you'd really want to block it?

14:46 bosie: TimMc: isn't the domain in the last one example.net?

14:47 TimMc: Yes.

14:47 bosie: then yes

14:47 TimMc: Oh, is example.net on the blacklist?

14:47 bosie: ah sorry, don't block

14:47 TimMc: OK.

14:48 hyPiRion: hm

14:48 TimMc: Regexes are not a great tool to use for filtering on highly structured strings with escaping rules and optional parts.

14:49 bosie: How about http://xgoogle.com/ ?

14:49 bosie: TimMc: dont block

14:49 TimMc: What you want is a tool that can take a URL string and answer the question "Is the host of this URL equal to or a subdomain of google.com?"

14:50 bosie: TimMc: yes and with https://github.com/cemerick/url/ i could get the host

14:50 TimMc: Hmm, it's not quite enough, is it...

14:51 That doesn't help with FQDNs.

14:51 amalloy: dnolen: for some reason the _ character renders as invisible in gfredericks's 4clojure (when i type it into the code editor), but it renders fine on 4clojure.com. do you have a similar issue?

14:51 brehaut: ,(map #(.split (.getHost (java.net.URL. %)) ".") ["http://docs.google.com/&quot;, "http://google.com.example.net/&quot;, "http://example.net/google.com/etc"])

14:51 clojurebot: (#<String[] [Ljava.lang.String;@5573990b> #<String[] [Ljava.lang.String;@1844cd01> #<String[] [Ljava.lang.String;@4cef0919>)

14:52 amalloy: brehaut: for a less painful experience, try clojure.string/split

14:52 brehaut: ,(map #(clojure.string/split (.getHost (java.net.URL. %)) ".") ["http://docs.google.com/&quot;, "http://google.com.example.net/&quot;, "http://example.net/google.com/etc"])

14:52 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.regex.Pattern>

14:52 bosie: TimMc: hm, if i just have a list of domains and append all TLDs

14:52 TimMc: brehaut: Try this on: http://www.google.com.:80/

14:52 dnolen: amalloy: haven't actually tried the core.logic problems yet.

14:52 brehaut: TimMc: ha of course

14:53 llasram: https://github.com/damballa/inet.data

14:53 amalloy: TimMc: wait, what's the last . there doing?

14:53 brehaut: (inc TimMc)

14:53 lazybot: ⇒ 24

14:53 dnolen: amalloy: _ in the editor works fine for me in Safari

14:53 brehaut: amalloy: its the top level dot. its implicit

14:53 llasram: brehaut: ^^

14:53 bosie: TimMc: cemericks' url is clever enough for that

14:54 TimMc: amalloy: It's a Fully Qualified Domain Name. If you leave off the dot, DNS resolution may use the gateway's search domain.

14:54 This is why you use a library. :-)

14:55 brehaut: llasram: nice

14:55 bosie: check out llasram's link above

14:55 amalloy: no kidding? i didn't know about that. so if you have some evil isp whose dns redirects "foo" to mycrappysearchwithads.com?q=foo, they're not allowed to do that for "foo."?

14:55 llasram: Oh, I missed who needed this :-)

14:56 TimMc: amalloy: I think that uses a different (non-standard) mechanism.

14:56 llasram: I haven't had a personal reason to add direct URL handling, but once you parse the domain out of URL, you can check for membership in a set or use a Mozilla PSL format list to identify the E2LD label

14:58 TimMc: bosie: (inet.data.dns/domain-subdomain? "google.com." "www.google.com") => true

14:58 oooh, it only does proper subdomains, that's no good

14:58 llasram: TimMc: domain-contains? Does both

14:59 bosie: TimMc: since its just for a personal clj project, and since i only been programming clojure since monday or sth, i think i will just let it slide and go on with it ;)

14:59 TimMc: bosie: Why? You've just been handed a library that will take care of all the tricky details.

15:00 bosie: TimMc: right

15:01 TimMc: (fn bad? [url] (some #(->> (java.net.URL. url) (.getHost) (inet.data.dns/domain-contains? %)) #{"google.com" "bing.com"})

15:01 )

15:01 And [inet.data "0.5.1"] in your project.clj.

15:02 cemerick: someone should make one of the bots yell at anyone pasting code using a java.net.URL ctor

15:02 TimMc: cemerick: clojure.java.io something?

15:02 cemerick: parse error

15:03 brehaut: cemerick: :'(

15:03 bosie: TimMc: i am not sure what your code is supposed to do

15:04 TimMc: bosie: That function ("bad?") checks if a URL is at any of a set of hosts.

15:04 bosie: TimMc: i rephrase: considering i dont have the domain....

15:04 lemme try

15:04 cemerick: brehaut: ?

15:04 brehaut: cemerick: i brought up that ctor, sorry

15:04 cemerick: and, for that matter, TimMc :-P

15:04 llasram: TimMc: Actually, `domain-contains?` just tests a single domain. For testing set-membership: (let [bad-domains (inet.data.dns/domain-set "google.com" "bing.com")] (get bad-domains input-domain))

15:04 TimMc: Well, the blacklist would be passed in as a second argument.

15:04 cemerick: ah

15:05 brehaut: cemerick: to my knowledge cemerick.url is not on clojurebots deps

15:05 cemerick: java.net.URL is fairly evil

15:05 brehaut: probably a good thing at the moment

15:05 hyPiRion: anything java.* is fairly evil

15:05 TimMc: cemerick: As in, that constructor throws errors on malformed URLs, so we shouldn't use it?

15:05 hyPiRion: except .lang

15:05 llasram: God yes. It's hash code depends on the IP address the domain name resolves to :-(

15:05 brehaut: hyPiRion: java.util.concurrent is a pot of gold

15:05 TimMc: llasram: wat

15:06 hyPiRion: brehaut: util has some nuggets, but for Clojure dev they aren't that needed

15:06 llasram: TimMc: Exactly. Fortunately, you can use java.net.URI most places that want a java.net.URL

15:06 amalloy: &(hash (java.net.URL. "sfdasdfaf.com"))

15:06 lazybot: java.net.MalformedURLException: no protocol: sfdasdfaf.com

15:06 amalloy: &(hash (java.net.URL. "http://sfdasdfaf.com"))

15:06 lazybot: ⇒ -593009291

15:06 brehaut: hyPiRion: concurrent queues are endorsed by rhickey as something we should be using more of ;)

15:07 TimMc: cemerick: So I should use...

15:08 brehaut: hyPiRion: somewhere in http://skillsmatter.com/podcast/scala/the-language-of-the-system he says that the reason theres no clojure wrapper for those queues is because there is nothing to add, and that they are great

15:09 hyPiRion: brehaut: I stand corrected, apparently.

15:10 brehaut: ive been itching for a reason to use a blocking priority queue for ages now, but have had no good reason

15:10 mehwork: what's a good persistant key/value database to use with clojure? Something that a noob like me can setup and use quickly for a verrry small application

15:10 cemerick: TimMc: It only supports the schemes/protocols it supports, and is inextricably linked to the horrific java.net.URLConnection and all of its (bad) implementation details

15:11 technomancy: mehwork: couch is pretty accessible

15:11 bosie: TimMc: seems to work

15:11 brehaut: mehwork: couch on cloudant.com is super easy to set up too

15:12 TimMc: &(.getHost (java.net.URI. "http://www.google.com./&quot;))

15:12 lazybot: ⇒ "www.google.com."

15:12 TimMc: cemerick: ...so I should use...

15:12 mehwork: brehaut: hmm, i want to just have it easy to setup on my own linux box and distribute the program easy, rather than it using an exteran service

15:12 S11001001: TimMc: exploding fish! :)

15:12 TimMc: java.net.URI? some Clojure core fn? some library?

15:12 cemerick: TimMc: oh, sorry: clj-http, which uses the Apache HTTP libraries underneath

15:12 TimMc: Hrm.

15:12 cemerick: Just Works™

15:13 technomancy: mehwork: sleepycat is supposed to be great for that; I wonder if anyone's done a clojure lib for it

15:13 bosie: TimMc: the function you gave me above (bad?)

15:13 cemerick: technomancy: GPL-only still, IIRC

15:13 technomancy: mehwork: if you don't mind SQL I think the JDK ships with an embedded DB. derby maybe?

15:13 cemerick: oh right

15:13 cemerick: Yeah, derby (now called JavaDB IIRC) is a serious piece of kit

15:14 bosie: TimMc: thank you

15:14 technomancy: huh, actually sleepycat invented their own license; fun

15:14 cemerick: I abused the snot out of that when it was still an IBM project.

15:14 brehaut: cemerick, technomancy: derby ~= sqlite with less suck?

15:14 TimMc: bosie: No problem.

15:14 cemerick: since when?

15:14 brehaut: *very* full-featured in-process relational db

15:15 technomancy: brehaut: from what I gather

15:15 bosie: TimMc: and it reduced my code by about 2/3 too :/

15:15 cemerick: it was the basis of IBM's Java impl of DB2 for years

15:15 brehaut: cemerick, technomancy: thanks. thats worth remembering

15:15 oh wow

15:15 cemerick: stored procs, crazy index options, different storage backends, etc, etc

15:16 it's possible you need to go use Derby proper to get all that; I don't know what pieces they took (or didn't) when it got folded into the JDK

15:16 brehaut: hah, i was just hoping for columes are more than jsut strings and table changes were sane

15:17 technomancy: brehaut: by sane you mean "not mysql"?

15:18 brehaut: technomancy: of course! but mysql is still better than sqlite in that regard

15:18 mehwork: technomancy: ok thanks

15:18 technomancy: yes, except for the part where mysql pretends to support concurrency =)

15:18 brehaut: technomancy: ahaha

15:19 at least sqlite doesnt have airs

15:19 mehwork: what's airs

15:19 hyPiRion: Isn't mysql like, trying to break the SQL specification in as many creative ways as possible?

15:19 mehwork: hyPiRion: hence the name 'my'sql

15:19 brehaut: hyPiRion: "its not so much of a specification as a guideline"

15:20 mehwork: (not that that's where they got the name, but you couldn't tell)

15:20 if there's one thing the industry needs more of, it's defacto standards

15:20 technomancy: hyPiRion: specifically the fact that adding a column to a table can lock the table while every single row is modified

15:21 I don't think the SQL standard says anything about that but it's still an amazing disaster.

15:21 bosie: is there a shorter way of saying (not (nil? (some...))) ?

15:22 hyPiRion: uhh

15:22 mehwork: isnt the not redundant

15:22 (3rd day of clojure, i could easily be very wrong)

15:23 bosie: mehwork: hah, same timespan as me ;)

15:23 hyPiRion: ,(some #(`%%%) [nil false true])

15:23 clojurebot: true

15:23 mehwork: on the 3rd day of clojure, my irc gave to me...

15:24 hyPiRion: (not-any? ...)

15:24 sheesh, nevermind me today.

15:24 mehwork: does not mean the bitwise op or did you mean not=

15:25 bosie: mehwork: http://clojuredocs.org/clojure_core/clojure.core/not

15:25 hyPiRion: bosie: (boolean (some ...))

15:26 If you want to do falsey to false and truthy to true.

15:26 bosie: hyPiRion: well, coming from some, it only converts nil to false. the rest should stay the same

15:26 hyPiRion: right?

15:26 hyPiRion: ,(boolean 3)

15:26 clojurebot: true

15:27 hyPiRion: ,(some #(`%%%) [nil false 3])

15:27 clojurebot: 3

15:27 S11001001: ,(let [falze (Boolean. false)] [falze (boolean falze)])

15:27 clojurebot: [false false]

15:27 bosie: hyPiRion: but some only returns a "true value" or nil

15:27 hyPiRion: bosie: yeah?

15:27 S11001001: ,(let [falze (Boolean. false)] [(if falze "true!" "false!") (if (boolean falze) "true!" "false!")])

15:27 clojurebot: ["true!" "false!"]

15:28 bosie: hyPiRion: i wasn't sure if you disagreed about my statement that it has no impact when used in combination with some

15:28 hyPiRion: bosie: It converts truthy to true, and nil to false.

15:28 S11001001: iow boolean sometimes converts true to false :)

15:28 bosie: hyPiRion: yes

15:28 mehwork: what about not-any? nil?

15:28 why is that wrong

15:30 bosie: mehwork: wouldnt it be (not (not-any? ... '(1 2 3 4 5)) ?

15:30 mehwork: one thing that i'm not liking about clojure is how things that read the clearest aren't necessarily the best way to do things, unlike in some other languages. Though it's too early to really tell yet

15:31 bosie: mehwork: give an example

15:31 mehwork: (not-any? nil? [1 2 3]) => true but (not-any? nil? [1 2 3 nil]) => false

15:31 maybe i misunderstood the question

15:33 bosie: mehwork: you did misunderstand. it was the opposite. if there isn't any hit in the list, it should return false, otherwise true

15:33 mehwork: ah

15:35 hyPiRion: (def any? (comp boolean some))

15:36 mehwork: i think (boolean (some nil? [...])) reads the clearest then

15:37 hyPiRion: oh, so we're working on nil? here?

15:37 bosie: hyPiRion: why did you define it like that? i did (defn any? [fn coll] (boolean (some fn coll)))

15:37 hyPiRion: ,((comp boolean some) identity [nil nil nil false true])

15:37 clojurebot: true

15:37 hyPiRion: Doesn't really matter.

15:37 bosie: hyPiRion: no, not really. but any boolean function would do

15:38 thanks hyPiRion

15:39 mehwork: thanks for your question bosie, it's helping me learn. +1 if it was stackoverflow

15:39 hyPiRion: you're welcome

15:40 bosie: mehwork: haha. just be grateful that this is a seriously friendly and helpful channel ;)

15:41 mehwork: it'd be cool if there was a gaming style irc plugin or client that let you rate peoples' answers so next to my name would be my rep score like mehwork 0>

15:41 and it would be based off channel, so in php i might have a 5000

15:42 TimMc: lazybot has a karma plugin.

15:42 S11001001: (inc technomancy)

15:42 mehwork: or maybe it would just be better if i stfu

15:42 lazybot: ⇒ 43

15:42 TimMc: $karma amalloy

15:42 lazybot: amalloy has karma 35.

15:42 mehwork: that was cool

15:42 bosie: $karma TimMc

15:42 lazybot: TimMc has karma 24.

15:42 bosie: (inc TimMc )

15:42 lazybot: ⇒ 2

15:42 mehwork: i'm gonna kill myself now since all my ideas have already been done. What's the point

15:42 bosie: $karma TimMc

15:42 lazybot: TimMc has karma 24.

15:42 amalloy: mehwork: i thought of that already

15:42 mehwork: hahaha

15:43 S11001001: bosie: space

15:43 bosie: (inc TimMc)

15:43 lazybot: ⇒ 25

15:43 mehwork: (dec mehwork)

15:43 lazybot: You can't adjust your own karma.

15:43 TimMc: bosie: The karma plugin isn't particularly clean -- you'll note that it doesn't actually operate on s-expressions.

15:43 heh

15:43 bosie: TimMc: oh well.... ;)

15:47 hyPiRion: Better to let clojurebot prepare it for you first

15:47 mehwork: maybe it could auto inc people who receive a thanks

15:47 hyPiRion: ,'(inc TimMc #_ foo)

15:47 clojurebot: (inc TimMc)

15:47 lazybot: ⇒ 26

15:48 llasram: Oh, which means

15:48 ,'(inc llasram #_ hehe)

15:48 clojurebot: (inc llasram)

15:48 lazybot: ⇒ 3

15:48 hyPiRion: yeah

15:48 llasram: I'm going to sneak in here one day when no one is watching and give myself ALL THE KARMA

15:48 terom: Watch for overflow...

15:48 hyPiRion: ,(dotimes [_ 3] (println '(inc hyPiRion)))

15:48 TimMc: llasram: Just come in under a different nick. No one will know it is you!

15:48 clojurebot: (inc hyPiRion)

15:48 lazybot: ⇒ 5

15:48 clojurebot: (inc hyPiRion)

15:48 lazybot: ⇒ 6

15:48 clojurebot: (inc hyPiRion)

15:49 lazybot: ⇒ 7

15:49 hyPiRion: It's easy to abuse in that sense.

15:49 callen: hyPiRion: nice.

15:49 TimMc: hyPiRion: Hey, did that bot quine succeed?

15:49 hyPiRion: TimMc: Raynes killed it :(

15:49 callen: (inc hyPiRion)

15:49 lazybot: ⇒ 8

15:50 TimMc: lazybot: ...

15:50 S11001001: mehwork: patches thoughtfully considered

15:50 TimMc: lazybot: WHy do you listen to that other bot? It is trouble!

15:50 callen: S11001001: and then rejected out of hand after an appropriate amount of time has passed.

15:50 llasram: &'(inc llasram #_ and-yet...)

15:50 lazybot: ⇒ (inc llasram)

15:50 S11001001: callen: even so

15:50 callen: (inc llasram)

15:50 lazybot: ⇒ 4

15:50 llasram: lazybot known not to listen to himself

15:51 hyPiRion: ,(println "$timer 0:0:1 Why do I even have this timer")

15:51 clojurebot: $timer 0:0:1 Why do I even have this timer

15:51 lazybot: Timer added.

15:51 llasram: er, knows even

15:51 lazybot: Why do I even have this timer

15:51 llasram: haha

15:51 The bot equivalent of "why are you hitting yourself?"

15:51 (inc hyPiRion)

15:51 lazybot: ⇒ 9

15:51 callen: ,(println "This is bot abuse yo.")

15:51 clojurebot: This is bot abuse yo.

15:51 callen: b

15:52 ^^ that was me going C-x b in Emacs. Wrong focus. Sigh.

15:52 amalloy: we know, man. a message "b", or "xb", means: "i'm using emacs"

15:53 callen: amalloy: I'm continually surprised by the relatively large number of Clojure vi users.

15:53 hyPiRion: The bots are dangerous though

15:53 "echo foo"

15:53 good.

15:53 ,(nth (iterate #(str % "echo ") "") 20)

15:53 clojurebot: "echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo echo "

15:54 hyPiRion: Now replace every second with a call to a ,(println ) to clojurebot, and havoc is all loose

15:54 amalloy: *shrug* vim isn't as great as emacs, but they're both miles ahead of the text editors a lot of people use. i find it hard to object to anyone using a good editor

15:55 S11001001: callen: Needs a message filter confirming "b", "xb", and "ls". Actually it's probably in there somewhere, waiting to be turned on

15:55 callen: amalloy: no no, I take no issue with it, I just find it surprising for a Lisp.

15:55 hyPiRion: S11001001: ls?

15:55 ls -a

15:55 lazybot: bin etc lib lost+found root selinux src swap sys tmp usr

15:55 callen: pwd

15:55 lazybot: #clojure

15:55 callen: ls -alh ./bin

15:55 lazybot: bin data dev etc home lost+found media mnt opt srv swap tmp usr

15:55 callen: ls -alh ./bin/data/

15:55 lazybot: bin data home media mnt usr

15:55 callen: ls -alh ./bin/data/home/

15:55 lazybot: data home lib media opt selinux

15:55 callen: ls -alh ./bin/data/home/media/

15:55 lazybot: bin boot data dev home lib lost+found opt proc selinux sys tmp usr

15:55 callen: ls -alh ./bin/data/home/media/selinux/

15:55 lazybot: bin dev src swap tmp

15:55 AimHere: rm -rf /home

15:57 amalloy: lazybot - the funniest little honeypot in #clojure

15:57 callen: like /bin/data/home/media/selinux/ wasn't obvious

15:57 gives me an idea for mischief with ln though.

15:58 amalloy: hm?

15:58 clojurebot: benchmarking is https://github.com/hugoduncan/criterium

15:58 callen: "You are in room with many directories, all look like"

15:58 You could treat it as a graph theoretic problem

16:00 amalloy: sadly only 3 of lazybot's 5 unix-joke commands have ever been triggered

16:00 callen: amalloy: clearly it needs documentation.

16:00 rhdoenges: I misread that as "sedly" and laughed

16:01 callen: sed

16:01 llasram: whoami

16:01 lazybot: llasram

16:01 llasram: Hey!

16:01 callen: dd if=/dev/fd0 of=/dev/sda1 bs=512 count=2

16:01 TimMc: set -o vi

16:01 callen: chsh /bin/echo

16:01 rhdoenges: who

16:02 callen: echo "bwahahaha" > /bin/login

16:02 lazybot: "bwahahaha" > /bin/login

16:02 rhdoenges: ls -l *

16:02 lazybot: lib media proc sbin selinux srv swap sys tmp

16:02 rhdoenges: ls tmp

16:02 lazybot: data dev etc home lost+found selinux srv swap tmp usr var

16:02 rhdoenges: wheeee

16:02 amalloy: i have to say the fifth one is pretty lame, so you all can be forgiven for not finding it without reading the source

16:03 mutt callen@whatever.com

16:03 lazybot: Woof!

16:03 hyPiRion: heh

16:03 rhdoenges: Ha Ha Ha

16:03 callen: astronomy

16:03 astronomy 94043

16:03 ...

16:03 llasram: ed

16:03 callen: fuck

16:04 kill

16:04 amalloy: none of the stuff from the github repo works.

16:04 amalloy: dafuq.

16:04 amalloy: well, there are two reasons for that

16:04 callen: guards

16:04 hyPiRion: ~guards

16:04 clojurebot: SEIZE HIM!

16:04 amalloy: one is you're a bit crap at triggering commands: they start with $

16:04 callen: ~kill

16:04 clojurebot: Cool story bro.

16:04 callen: $kill

16:04 lazybot: KILL IT WITH FIRE!

16:04 callen: $shell ls -alh

16:04 lazybot: callen: It is not the case that you don't not unhave insufficient privileges to do this.

16:05 callen: $astronomy 94043

16:05 lazybot: Percentage of moon illuminated: 46; Age of moon: 7; Current time: 12:57; Sunset: 16:53; Sunrise: 7:18.

16:05 amalloy: the other is that a lot of the plugins are disabled for the lazybot instance in here

16:05 callen: $say hello

16:05 lazybot: callen: It is not the case that you don't not unhave insufficient privileges to do this.

16:05 joevandyk: I think my first clojure project will be a library that can work with queue_classic (postgresql job queue -- https://github.com/ryandotsmith/queue_classic). I'm still very new to clojure and jvm. Using lein 2.0. Should I create a plugin, app, or default project?

16:05 llasram: echo ,(println "echo hmm")

16:05 lazybot: ,(println "echo hmm")

16:05 clojurebot: echo hmm

16:05 lazybot: hmm

16:05 callen: $setnick greyape

16:05 lazybot: callen: It is not the case that you don't not unhave insufficient privileges to do this.

16:05 callen: $coin

16:05 lazybot: callen: Heads.

16:05 rhdoenges: $bf

16:05 hyPiRion: Oh lord, can you guys just go /msg lazybot please?

16:05 lazybot: {:ptr 0, :cells {}}

16:06 []

16:06 rhdoenges: sorry :)

16:06 callen: amalloy: pardon me for not memorizing the bot prefixes of all 50 of the bots I share a channel with.

16:07 TimMc: &((fn a [m n] (cond (zero? m) (inc n) (zero? n) (recur (dec m) 1) :else (recur (dec m) (a m (dec n))))) 3 1)

16:07 lazybot: ⇒ 13

16:07 TimMc: &((fn a [m n] (cond (zero? m) (inc n) (zero? n) (recur (dec m) 1) :else (recur (dec m) (a m (dec n))))) 4 1)

16:07 lazybot: java.lang.StackOverflowError

16:07 TimMc: wheee Ackermann

16:07 S11001001: joevandyk: default

16:08 amalloy: TimMc: it's more fun to write ackermann with trampolined CPS so it runs forever

16:08 callen: TimMc: for some reason I thought that would get trampolined.

16:08 TimMc: amalloy: Too lazy.

16:08 callen: I must not understand recur.

16:08 TimMc: callen: It involves a non-tail call.

16:08 amalloy: callen: no, you missed the (a m (dec n))

16:08 * callen nods

16:09 amalloy: TimMc: https://gist.github.com/4023304

16:10 a CPS version, but not a trampolined-CPS version. improvement an exercise for the reader

16:10 (and also a version that consumes no stack)

16:10 technomancy: joevandyk: default would be best

16:12 TimMc: Whoa, gist changed.

16:12 ...for the better. It now has diffs.

16:13 amalloy: TimMc: it's had diffs for years

16:13 and they were easier to get to before

16:13 well, sorta. i guess it's a tradeoff in terms of ease

16:14 squidz: should I stick to only using multimethods, as they seem to be most powerful, or should I fall back on protocols if nedded?

16:16 dnolen: squidz: stick with multimethods, you'll eventually figure out when you actually need protocols.

16:16 squidz: in ClojureScript they're a bit more useful since the DOM APIs can be quite hostile.

16:17 callen: dnolen: weird, my understanding was that the advice was to use protocols first, then upgrade to multimethods when you needed more power.

16:17 dnolen: would you mind sharing some wisdom there?

16:17 squidz: squidz: okay so it will be better if I stick with multimethods. other polymorphism techniques can be refined later. Sounds good thanks

16:17 callen: squidz: you just addressed yourself :)

16:17 squidz: yeah a little too much wine

16:17 i meant to address dnolen

16:21 dnolen: callen: I don't feel inclined to use protocols unless I'm doing something "low-level". Clojure data types + fns are usually sufficient. multimethods provide some polymorphism w/o forcing you do go off into the design weeds.

16:22 nDuff: Hmm.

16:22 dnolen: protocols usually mean deftype/record which are tedious if eeking performance doesn't matter. It's easy to screw up a protocol desing.

16:22 squidz: dnolen: do you have any code i can look at on github?

16:22 * nDuff (by contrast) finds himself using protocols much more frequently than multimethods

16:22 crease: dnolen: mdunno, in big systems too many multimethods can get really gnarly

16:23 amalloy: as someone who overuses protocols, i suggest you stick with multimethods until you find performance forces you to use protocols (hint: it won't)

16:23 squidz: crease: really why is that?

16:23 dnolen: crease: if you have too many multimethods that's a sign of a other problems I think.

16:23 callen: dnolen: seems sensible. Thanks for explaining that.

16:24 dnolen: squidz: Look at core.match or core.logic. You have been warned :)

16:24 crease: squidz: protocols do this big dance about exactly what they're doing - it's easy to see what's going on.

16:24 squidz: dnolen: alright ill see if i can find a good example of multimethods in those packages

16:25 dnolen: squidz: oh you don't want to look at those projects for multimethod usage.

16:25 squidz: if I was going to rewrite core.match, I'd probably do it with multimethods. protocols are a good fit for core.logic tho.

16:26 crease: dnolen, squidz: also protocols play nice with reify

16:26 tbaldridge: squidz: almost the entire ClojureScript compiler is one massive multimethod

16:26 squidz: dnolen: okay, do you have any good github examples using multimethods

16:26 tbaldridge: doing that with protocols would be a pain

16:26 squidz: tbaldridge: thanks

16:27 dnolen: tbaldridge: yes! if you want polymorphic behavior on data instead of custom types - multimethods win hands down.

16:27 custom types bring their own burden

16:28 jsabeaudry: When using ring-jetty-adapter I see that responseBufferSize has enormous impact on performance, is there a similar setting when using aleph?

16:29 squidz: are multimethods more functional then?

16:30 oskarth: how can this be made shorter/better? ##(mapv #(vec (rseq %)) (apply mapv vector [[1 2] [3 4] [5 6]]))

16:30 lazybot: ⇒ [[5 3 1] [6 4 2]]

16:31 oskarth: (behaviour is correct, transpose and reverse)

16:31 crease: dnolen: I know of no unburdened multiple-dispatch convention. multimethods have closed dispatch functions etc

16:32 tbaldridge: squidz: if you want an indepth lesson on Clojure polymorphism and why each method exists, I suggest http://vimeo.com/53223938#at=0

16:32 callen: http://stackoverflow.com/questions/8070368/clojure-multimethods-vs-protocols <--- this is the sort of reasoning that led me to believe that I should resort to protocols first.

16:33 technomancy: callen: terrible advice

16:33 jkkramer: using multimethods sometimes requires care with dependency ordering if your method implementations aren't centralized. You may find yourself requiring a namespace entirely for the side effect of implementing a method

16:33 * technomancy votes it down

16:33 callen: technomancy: so I've heard so far.

16:33 jkkramer: still, I pretty much always reach for multimethods first when I need extensibility/polymorphism

16:33 ferd: Starting a simple REST service using MongoDB: How do you guys normally validate the structure of a "document" comming from a client before persisting it ?

16:33 callen: technomancy: you know how Stack Overflow works. First guy out the gate with a semi-plausible answer wins the magic karma.

16:34 wisdom, correctness, completeness be damned.

16:34 squidz: after reading a bit of JOC i get the feeling that multimethods are prefered

16:34 callen: I find it hilarious that they expend zero effort addressing this, yet are super-concerned about shutting down joke threads.

16:35 squidz: tbaldridge: thanks for the video ill check it out

16:35 crease: multimethods are awesome and to the point in localized, high-level places where you need a certain very particular kind of arbitrarily sophisticated dispatch. protocols are much better, IMO, for everything else - you know where you stand with them.

16:35 joevandyk: https://gist.github.com/243d4dc223878317a4ee -- what am i doing wrong here? i was hoping to make db a curried function

16:35 tbaldridge: squidz: yeah it goes into a bit more discussion of why protocols exist in the first place.

16:38 technomancy: callen: added a comment; hopefully it makes things clearer

16:38 but it's something people are widely confused about =(

16:39 bsteuber: joevandyk: see http://clojuredocs.org/clojure_core/clojure.core/partial to get an idea how partial is being used

16:41 so do (def db (partial sql/with-connection ...))

16:41 callen: technomancy: thank you :)

16:41 brehaut: technomancy: striking another blow for monomorphism :)

16:42 callen: technomancy: another amusing fact is that he uses Clojure's code to justify his position

16:42 as if all code should be written in the manner its own implementation was.

16:45 technomancy: it's good that you can if you need it.

16:45 but geez; if you're 2 weeks in you guaranteed don't need it.

16:46 gtrak: I've never yet written a multimethod... I can get by with protocols and simple data structures.

16:47 If I started trying to do double-dispatch with protocols, I'd reach for one, I guess.

16:49 crease: seriously, neither multimethods nor protocols are panaceas, and they can both lead to their own distinct problems. Can we be more specific about how multimethods are better than protocols? I'm not speaking from nostalgia for OOP here

16:50 technomancy: multimethods are just vars; they're first-class and work with all the built-in tools we have for dealing with Clojure data

16:50 bsteuber: multimethods aren't a pain in the ass when part of your stuff is AOT-compiled oO

16:50 gtrak: arbitrary-function of its arguments means it's some kind of control-flow that can't be wrapped up in a type, I guess.. and the global extension mechanism and type hierarchies (haven't used those ever, either)

16:51 technomancy: crease: if you reload a defrecord then old instances of the record are still of the old class

16:51 crease: so you can have two objects that are completely indistinguishable from each other except they are mysteriously not equal

16:53 crease: technomancy: you're right, that's bad

16:53 technomancy: crease: for regular clojure code if you AOT and the .class file is inaccessible, it falls back to the JIT version

16:53 but with protocols this doesn't work

16:53 bbloom: tpope: would be nice to have a :Reconnect command. sometimes i kill my repl for some reason and then I need to run the little :Connect wizard and type the port by hand

16:54 or at least provide repl-port as a default so i can slam <CR> a bunch of times in the wizard

16:54 technomancy: crease: also not being able to change your arglists without changing how you dispatch can lead to a mess for future changes

16:55 joevandyk: bsteuber: like this? https://gist.github.com/a8b10140d489bac627e6

16:56 callen: I found out yesterday that Node.js has an implementation of Django/Jinja style templates already. I was galled.

16:56 bsteuber: joevandyk: yes the partial part looks good to me - can't judge the sql stuff though since I never use it :)

16:56 callen: well, "javascript". It works in the client-side too. http://paularmstrong.github.com/swig/

16:57 joevandyk: bsteuber: "clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Can't take value of a macro: #'clojure.java.jdbc/with-connection, compiling:(src/queue_classic/core.clj:14)"

16:57 bsteuber: ah it's a macro

16:57 right now I get it, my bad :)

16:57 joevandyk: bsteuber: the original was (sql/with-connection "conn-string" (username (first (sql…))

16:58 and i wanted to issue sql without the sql/with-connection stuff

16:59 TimMc: Complaint: apropos doesn't tell me where it found things

16:59 bsteuber: joevandyk: I added a comment

17:00 the indentation sucks, but you get the idea

17:01 so you can't partial on a macro, you have to write a macro yourself

17:01 joevandyk: bsteuber: ah, ok

17:01 that works great, thanks!

17:01 bsteuber: that's the disadvantage of macros, you lose a lot of compasability

17:02 gtrak: bsteuber: definline is like a function and a macro combined, you can partial on it

17:02 crease: technomancy: I can see how multimethods distance from the leaden guts of ossified, inexpressive type systems makes them more dynamic and revisable in some ways. I haven't run into the AOT issues you've mentioned but they sound nasty.

17:03 technomancy: crease: granted I probably hear the worst horror stories about protocol problems coming from lein bugs, but the reason you don't hear a lot about multimethods is that they're really straightforward (apart from the stupid defonce behaviour) and they pretty much always just work

17:03 bsteuber: crease: I pretty much spend the whole work day debugging some AOT-protocol-issues oO

17:04 which of course means I'm lucky since I can work with clojure xD

17:05 actually today our problems started when switching from AOT to non-AOT compilation - usually it's the other way around..

17:05 TimMc: bsteuber: Reminds me of a friend-of-a-friend who almost died when he stopped drinking massive quantities of Mountain Dew every day.

17:06 amalloy: TimMc: brb telling all my friends

17:06 bsteuber: never seen that drink in europe - so I think I know it from south park oO

17:06 TimMc: (The carbonation had been masking a serious medical problem.)

17:07 bsteuber: Just a soda.

17:08 bsteuber: So what's happening with non-AOT compilation that's problematic?

17:09 bsteuber: well I got a defrecord with some inline implementations of protocols which come from another namespace (acutally another project)

17:09 joevandyk: anyone use vimclojure? i like it, but i'd rather the output be put into a separate vim session -- anyone know if that's possible? (i have multiple monitors, and want the output to go to the other monitor

17:10 (or if vimclojure can write the output to a file or a terminal or something, that would also work)

17:10 bsteuber: and since we stopped using aot everywhere, in the unit tests clojure claims the protocol not to be implemented on that type

17:10 TimMc: Ah, I think I see.

17:10 bsteuber: but the bug vanished after moving the definition to an extend-type

17:11 gtrak: bsteuber: is it clojure 1.3?

17:11 bsteuber: I will probably send a clojure bug report once I have a minimal example for that

17:11 happened in both 1.3 and 1.4

17:11 the defrecord also implemented deref, not sure if that can be part of the problem

17:11 gtrak: did you import without require? that might be why

17:12 bsteuber: didn't import at all since everything's wrapped in functions

17:12 crease: At the same time, mutating record definitions themselves is a peculiar way to achieve flexibility, and you can't easily revise the dispatch fns of multimethods, either. In my experience, reify and extend-protocol provide enormous flexibility, and the definitions of protocols only really commit you to arities; multimethods commit to full-blown functions.

17:12 gtrak: when you import, you implement the interface... which may not exist yet

17:13 bsteuber: what's wrapped in functions? the definition of the record?

17:13 technomancy: it's easy to work around the defonce flaw of multimethods; just (def mymulti nil) before every defmulti

17:13 bsteuber: gtrak: no the constructer calls I mean

17:13 technomancy: nice, should remember that :)

17:14 technomancy: bsteuber: ugly but obvious

17:14 gtrak: bsteuber: not sure I get it, then

17:14 amalloy: technomancy: you are missing out on a golden opportunity to make your code confusing

17:15 bsteuber: technomancy: a propos ugly: with leiningen, we have some funny setup where about 10 projects want to share a special mvn repository

17:15 amalloy: (def mymulti (fn [x] (x :foo))) (defmulti mymulti mymulti)?

17:15 technomancy: amalloy: whoa niiiiiice

17:15 bsteuber: technomancy: we tried to hack that into the user profile, but the jar task then removes that profile for compilation

17:15 amalloy: that actually probably doesn't work. but you can at least give it a garbage value first, and then re-def it to a real value

17:15 technomancy: bsteuber: have you tried using project middleware?

17:15 yeah the user profile is definitely not the right place for that

17:16 amalloy: i take it back, it totally does work

17:16 bsteuber: technomancy: not sure if anyone tried, I will read it up first :)

17:16 technomancy: bsteuber: but if the repo is not likely to change it's probably best to just copy it into each project.clj

17:16 explicit is better than implicit

17:16 bsteuber: mm that's what I proposed ^^

17:17 clojure hackers are just sort of negative when it comes to redundancy..

17:18 technomancy: the property of having each project be entirely self-contained is extremely valuable

17:19 bsteuber: technomancy: yes before that we did tons of magic in our own compandy-lein-plugin, with some weird consequences ^^

17:19 * technomancy has less and less patience for magic as he gets older

17:19 SegFaultAX: Has anyone here ever used mongo to build a real-time analytics service?

17:19 bsteuber: mm, I feel like I am starting to get older, too...

17:21 and I'm just 29 :)

17:21 well maybe that's already old for a hacker..

17:21 gtrak: technomancy: that's one good principle I learned from python

17:21 technomancy: bsteuber: me too but I use Debian Stable and Emacs, so that adds another level of greybeard get-off-my-lawn-ness

17:21 amalloy: bsteuber: don't strain yourself; just relax while we grab a wheelchair for you

17:21 hyPiRion: technomancy: At least you're not running lenny

17:22 bsteuber: XD

17:22 technomancy: gtrak: funny; it's one bad principle I learned from Ruby by omission

17:22 gtrak: hahaha

17:22 it's in the 'zen of python'

17:22 bsteuber: I think I learned it by readying other people's clojure code and realize how it sucks if you're not the author and know what you meant ^^

17:23 or no, actually by having to *modify* other people's code :)

17:25 SegFaultAX: Do people usually put all their analytics data in one big table/collection?

17:26 technomancy: SegFaultAX: at heroku we just finally moved our last metrics off that approach

17:26 SegFaultAX: technomancy: What's the underlying datastore?

17:26 gtrak: SegFaultAX: if I understand what you're asking, it's do people use schemas?

17:26 SegFaultAX: technomancy: And how are you sharding the data now? By object type?

17:26 gtrak: Not even kinda.

17:26 technomancy: SegFaultAX: we were using postgres, but now we keep it in memory and calculate running stats on them that we feed into librato

17:27 https://github.com/ryandotsmith/l2met

17:27 SegFaultAX: technomancy: What kinds of time series are we talking about?

17:28 technomancy: connections per minute, median/perc95/perc99 of total response time, exception count, etc

17:28 SegFaultAX: technomancy: Over the entire routing mesh?

17:28 technomancy: SegFaultAX: my work is primarily on the build pipeline, but the routing team uses the same metrics processing

17:29 SegFaultAX: technomancy: What kind of read/write throughput were you able to do with postgresql?

17:29 technomancy: SegFaultAX: I don't recall; it was very heavily sharded

17:29 SegFaultAX: I imagine it was a lot of atomic counter increment/decrements.

17:30 technomancy: there's also https://github.com/heroku/pulse but this one kind of sucked because all the metrics were hard-coded in so you had to redeploy if you wanted to change anything. having the metrics embedded in the log stream is a lot more flexible.

17:30 the postgres solution was already being phased out when I started on this team

17:30 SegFaultAX: technomancy: Any idea why?

17:32 technomancy: vaguely the impression I got was that a database just isn't appropriate for this kind of thing; you don't care about persistence

17:32 SegFaultAX: technomancy: Also, your librato bill must be insane.

17:33 S11001001: speaking of bills, where are you going to put the leiningen bins now, technomancy?

17:33 SegFaultAX: technomancy: That's the problem though, in our particular situation we kinda do. For each object, we could have minutely, hourly, daily, weekly, monthly, and yearly aggregates.

17:34 technomancy: SegFaultAX: gotcha; we collapse things in l2met and then have them deal with storing the history of a single metric

17:34 s/them/librato/

17:34 but we don't go that far back

17:34 SegFaultAX: technomancy: Yea, it's probably less important to see how many connections you had on Dec 1, 2010 @ 11:30a PST.

17:35 technomancy: still, I think there's value in separating out the two operations: turning raw logs into aggregates should be different from storing and displaying the collapsed metrics.

17:35 SegFaultAX: technomancy: Unfortunately, that's exactly the type of query we have to support :(

17:35 technomancy: the input of the aggregation phase is infeasible to persist anywhere but S3 but not necessarily the metrics themselves

17:36 SegFaultAX: technomancy: Does your log aggregation service use mapreduce?

17:36 technomancy: TBH one of my favourite things about it is that I don't have to know anything about it =)

17:37 I just point my log drain at it and give it my librato creds and the metrics just start rolling in

17:37 SegFaultAX: technomancy: Hah, true. So, when you want to add a new metric, do you just add a new log entry and deploy the code?

17:37 technomancy: yeah, it's really nice

17:37 SegFaultAX: technomancy: That's pretty slick.

17:38 technomancy: there are certain cross-cutting calculations that style doesn't support though

17:38 like if you want to alert when the difference between two metrics gets too large

17:38 SegFaultAX: technomancy: Right, but it's fine for simple sums and counts.

17:38 technomancy: Well that's post-processing that could be handled at the eg librato level.

17:39 technomancy: the implementation's all open if you don't mind reading some ruby: https://github.com/ryandotsmith/l2met

17:39 SegFaultAX: technomancy: It's not really up to the metrics engine to also apply /meaning/ to the metrics.

17:39 technomancy: under 1kloc it appears

17:39 yeah, good point

17:39 SegFaultAX: technomancy: Great, I'm going to read it now.

17:40 technomancy: SegFaultAX: if you haven't seen mcgranaghan's conj talk from last year about logs as streams of data, it provides some good context

17:40 SegFaultAX: technomancy: Happen to have a link handy?

17:40 technomancy: sure: http://blip.tv/clojure/mark-mcgranaghan-logs-as-data-5953857

17:40 SegFaultAX: technomancy: Cheers.

17:41 seangrove: Ah, ffs

17:42 Subscribed someone to a mailing list on accident, and then replied to the entire clojure mailing list, instead of just him, trying to tell him

17:42 mehwork: alright i have the basics of clojure down in a repl. How do i run a .clj script on the command line though?

17:42 SegFaultAX: seangrove: First world email problems. ;)

17:42 seangrove: Heh, I suppose. Face is red though

17:43 technomancy: it's ok; nobody reads the mailing list anymore =\

17:43 amalloy: seangrove: please unsubscribe me too!

17:44 pjstadig: seangrove: i read in digest, so i won't see your faux pas until tomorrow morning

17:44 but thanks for the heads up

17:44 seangrove: Ah, nice. A rolling indiscretion.

17:45 pjstadig: what goes on the Internet, stays on the Internet...forever

17:45 mehwork: pjstadig: not if you duckduckgo

17:52 TimMc: heh

17:53 SegFaultAX: technomancy: So I haven't looked at the source yet because I'm watching the talk first, but are you actually marshalling Ruby objects as your log format?

17:53 technomancy: Or perhaps, how literal is l2met with respect to this talk?

17:53 the-kenny: seangrove: hah, noticed this a few minutes ago! :D

17:53 callen: mehwork: don't propagate other peoples' marketing campaigns, it's in poor taste.

18:01 technomancy: SegFaultAX: his talk is more about pulse; l2met was a later development

18:01 SegFaultAX: technomancy: What was wrong with pulse? It seems pretty awesome.

18:02 seangrove: technomancy SegFaultAX: same question, I'm thinking of using pulse soon

18:02 SegFaultAX: technomancy: You mentioned that it required redeploy, what's the alternative? How do you add new metrics without a redeploy.

18:02 seangrove: Have you seen McGranaghan's talk?

18:02 seangrove: Yeah

18:03 technomancy: SegFaultAX: the most obvious problem was that it had all the metric definitions hard-coded in, requiring a redeploy to update them. but the real problem was that it became unmaintained.

18:03 storing the metric definitions in a DB or in the log stream itself is a much better way to go

18:03 seangrove: The DSL for defining the metrics seemed like a great idea though

18:03 SegFaultAX: technomancy: Are you aware of any of the fundamental/architectural differences with l2met?

18:04 technomancy: SegFaultAX: the main thing is that, where the definitions are kept. but l2met can also be a lot simpler because it only supports a fixed set of stastistics, whereas pulse stats can be arbitrarily complex.

18:04 SegFaultAX: technomancy: Wouldn't that incur loads of extra overhead though? If it constantly has to query the database to get the latest metric definition?

18:05 technomancy: Would you mind giving an example of what a definition might look like?

18:05 technomancy: SegFaultAX: that's pretty easy to work around; you could have metric definition updates trigger a message on a queue that would cause reloads

18:05 definitions in pulse?

18:05 SegFaultAX: technomancy: Yea.

18:06 seangrove: There were examples in the talk worth checking out

18:06 technomancy: SegFaultAX: https://github.com/heroku/pulse/blob/master/src/pulse/def.clj#L305

18:06 clojurebot: Titim gan éirí ort.

18:07 SegFaultAX: technomancy: I see. So does l2met actually store clojure forms in the database/configuration files?

18:07 technomancy: SegFaultAX: no, there's no Clojure involved. it reads key=value pairs out of log streams

18:07 possibly json too?

18:07 SegFaultAX: json does seem like the obvious choice instead of clojure literals.

18:08 technomancy: anyway, it certainly would have been feasible to turn pulse into l2met, but for nontechnical reasons it didn't happen like that at Heroku, probably because starting a new implementation makes experimentation a lot easier vs hacking on a production service that everyone relies upon

18:09 I think to keep things terse most logging is done as a bunch of k=v instead of json because nesting is almost never needed

18:10 pulse was also problematic in that it was nearly impossible to develop on locally; you had to deploy it to staging to test any of your changes.

18:10 SegFaultAX: technomancy: Are special characters url encoded or something on the wire?

18:10 technomancy: it was implemented in a repl-hostile way

18:10 SegFaultAX: that'd be handled by https://github.com/heroku/logplex; not something I'm familiar with

18:11 basically all you do is println and it gets routed to the right consumers

18:14 bbloom: Raynes: thanks for tentacles, it's working nicely

18:15 Raynes: bbloom: <3

18:15 bbloom: would be nice to set my auth with a dynamic var though, rather than manually having to pass options everywhere

18:15 Raynes: Some people hate the dynamic var approach.

18:15 Not sure why. I'm indifferent.

18:15 technomancy: it's the worst when it's the only option

18:15 bbloom: does that some people include you?

18:15 ah

18:15 technomancy: not bad if you get both

18:15 bbloom: yeah, what technomancy said

18:15 Raynes: I agree with technomancy, I think.

18:15 * technomancy glares at c.j.jdbc

18:16 Raynes: bbloom: I'd take a patch for that, fwiw.

18:16 hyPiRion: It's good if makes the common case readable and every case possible, methinks.

18:16 And it's simple, of course.

18:17 bbloom: Raynes: already sent you a PR to update the readme

18:17 Raynes: Whoa crap

18:17 All of a sudden just got all my email for today.

18:19 bbloom: heh, i'll look into the dynamic var too

18:31 Raynes: boom https://github.com/Raynes/tentacles/pull/20

18:35 callen: bloom says boom.

18:35 bbloom: BlOOM

18:36 callen: carthago delenda est: http://paularmstrong.github.com/swig/

18:36 bbloom: anyway, Raynes, i'm using tentacles to walk a few levels of my followers graph and map their locations. going to stalk some new yorkers when i get to town :-)

18:38 hyPiRion: Sometimes, I'm glad I live far away from every other Clojurian

18:38 callen: hyPiRion: only sometimes? I live in the bay area. The Clojurians here are lucky I don't commit suicide and haunt them with my ghost.

18:39 bbloom: just trying to build up my network in a new city

18:39 hyPiRion: callen: Is it that bad?

18:39 bbloom: always good to know smart people wherever you go!

18:39 hyPiRion: I thought the violence only occured during full moons.

18:39 callen: hyPiRion: the only thing that's bad is how deep my discontent with the state of templating.

18:40 is the depth of*

18:40 hyPiRion: heh, I think I heard about that.

18:41 technomancy: sure sucks that nobody has written just the right software for you

18:41 callen: technomancy: I'm past that. I'll just start writing it and stop as soon as Santiago writes a better one.

18:42 technomancy: oh good, heh

18:42 I mean I don't like what's out there either, but I don't actually write web apps

18:42 I mean, I do like hiccup, but I don't collaborate with designers on web apps

18:42 whatever

18:43 bbloom: i'm simply 100% convinced that html is object code

18:43 callen: out of spite, version 0.0.1 of the library will be translated from the Node.js version.

18:43 hyPiRion: It's good we bring this template-problem up again, I think we should discuss it more than

18:44 /s/more than we did yesterday

18:44 technomancy: oops; what have I done

18:44 callen: hyPiRion: what part of "carthago delenda est" didn't you Latin? :D

18:44 technomancy: hyPiRion: he's writing code now; that's an improvement =)

18:44 mehwork: what's 0.0.1 mean? a bug fix for a nonexistant project - where the bug fix is that there's something there now? :p

18:44 callen: technomancy: I've even named it. That's at least one of the two difficult things in CS.

18:44 technomancy: next up is caching compiled templates.

18:45 technomancy: mehwork: "Fixes these bugs: 0) project didn't exist, [...]"

18:45 callen: I could deploy an empty namespace to clojars for the lulz.

18:45 mehwork: an easy patch to merge

18:45 callen: ,(merge nil nil)

18:45 clojurebot: nil

18:45 callen: walla.

18:45 dhm: callen: i think enlive has a good model for the caching behavior you mention

18:46 mehwork: the journey of a 1000 miles begins with a first commit

18:46 s/miles/SLOC

18:46 callen: dhm: you really don't want to talk to me about other template libraries.

18:46 dhm: I know you think you're being helpful, but just don't.

18:47 hyPiRion: I find good design harder than cache invalidation. Naming things is still hard.

18:47 * dhm smiles while nodding and backing up slowly

18:50 bbloom: Raynes: i updated that PR, but didn't test it my tiny change. i take no responsibility if it explodes and kills everyone on the space station

18:52 mthvedt: for some people i've worked with, a journey of a thousand SLOC is performed in a single commit

18:53 mehwork: and all in one function

18:55 but the software industry hires unqualified programmers like they were needing 'doctors' in a 3rd world village. Anyone will do

18:55 hyPiRion: Not everyone does that

18:56 mehwork: i know a couple php guys that are like a taxi driver in america who was a heart surgeon in his home country

18:56 well i'm sure most clojure shops don't

18:57 bbloom: i've seen php guys who would be better off as taxi drivers calling themselves "CTO" and impressing VCs :-P

18:58 mehwork: it sounds like the next generation of people isn't liketly to produce that many new software engineers either.

18:59 hmm anyone know what's better congomongo or monger ?

18:59 bbloom: mehwork: there will always be self taught engineers, that's sorta the magic of the internet: it's built by geeks and first-and-foremost for geeks

18:59 mehwork: yeah

19:00 although i prefer the term nerd to geek

19:01 geeks always make me think of trendy nerds - e.g., people who instagram all day thinking their computer geeks

19:01 *they're

19:02 hrm both congomongo and monger have their last github commits at 9 days ago. So much for using active development to weed out which one to pick

19:03 congomongo seems to have better docs, so going with that i guess

19:45 clj-newb-234: in clojure, can protocols inherit from other ptrotocols?

19:45 i.e. can I define an "IAnimal", then have "ICat" "IDog" inherit IAnimal ?

19:46 brehaut: no

19:46 clj-newb-234: is there a good rationale/writeup explainign why protocol inheritance is a bad idea?

19:47 technomancy: because writing Clojure programs to handle cats and dogs is not very common? =)

19:48 clj-newb-234: because inheritance is OO-ish, and Clojure is functional ?

19:48 AimHere: I think the lisper explanation is that Lisp is more flexible anyways and you can knock up a bespoke implementation for all your inhertiance needs fairly easily

19:51 casperc: Is there any way ti get the doc string of all the publics of a namespace?

19:51 clj-newb-234: yeah, I think it literally invole writing a new macro

19:51 probably some combination of the namespace functions + meta

19:51 technomancy: casperc: (map (comp :doc meta val) (ns-publics 'clojure.set))

19:51 clj-newb-234: that's exactly what I meant to say

19:52 amalloy: hah. what a literal interpretation, technomancy: I want all the docstrings, don't really care what functions they're attached to

19:52 casperc: Ahh awesome :)

19:52 amalloy: (map (juxt key (comp :doc meta val)) (ns-publics 'clojure.set))

19:52 technomancy: amalloy: here's a pile of strings; go do ... stringy things to them or something.

19:52 casperc: I was having trouble with the doc macro, but that works like a charm

19:52 clj-newb-234: technomancy: did you have that code handy from previous work, or did you come up with that on the fly?

19:52 technomancy: oh snap, juxt saves the day

19:53 clj-newb-234: I do a lot of tooling, so I've come to appreciate the finer points of vars and metadata =)

19:53 clj-newb-234: technomancy: is any of your tools opensource, I feel I can learn a thing or two from someone who recites clojure one liners on teh fly

19:54 AimHere: He has a github

19:54 technomancy: sure: https://github.com/technomancy

19:54 here's a fun one I documented pretty thoroughly: http://technomancy.us/148

19:54 clj-newb-234: did you fork leiningen, or did you actually write leiningen?

19:54 technomancy: lots of crazy var manipulation in there

19:54 I wrote it =)

19:55 madsy: technomancy is our man :)

19:55 casperc: indeed :)

19:55 technomancy: amalloy's snippet is better though; he used juxt without being gratuitous, which is always a neat trick

19:55 mpan: lein is awesome but sometimes I worry because I don't know how to work without it

19:55 madsy: mpan: Why would you want to?

19:55 mpan: btw is there an inside joke about "juxt" or something?

19:56 casperc: just one more question now that we are talking about tooling/meta data. Can i get the source from the symbol in the same way?

19:56 mpan: madsy: some sites accept clojure as a language but they specifically ask for e.g. a single file w/ a single ns w/ specific whatevers

19:56 amalloy: it's easy. java -cp `40 lines of bash` clojure.main -m my.main.ns

19:56 madsy: mpan: That's like worrying about not being able to code in C without a C compiler

19:56 technomancy: mpan: (first (sort-by greatness (vals (ns-publics 'clojure.core)))) ; -> #'juxt

19:56 mpan: haha

19:57 technomancy: casperc: unfortunately no, you have to hit the filesystem or use the serializable-fn library

19:57 amalloy: technomancy: unintentionally dissing functions since 2008

19:57 technomancy: casperc: try (source source) for the former; https://github.com/technomancy/serializable-fn for the latter

19:57 mpan: https://www.interviewstreet.com/recruit/challenges/faq/view example of somewhere that accepts clojure as a language but requires single clj file with conventions

19:57 technomancy: amalloy: you mean the bit about gratuitousness?

19:58 mpan: it's actually a minor pain to deal with their conventions because I learned lein first and it's all I know

19:58 amalloy: no, i mean ##(first (sort-by :greatness) [{:f :useless :greatness -10} {:f :awesome :greatness 20}])

19:58 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: core$sort-by

19:58 amalloy: &(first (sort-by :greatness [{:f :useless :greatness -10} {:f :awesome :greatness 20}]))

19:58 lazybot: ⇒ {:f :useless, :greatness -10}

19:58 technomancy: oops!

19:58 madsy: mpan: If it concerns you, then by all means, learn how to strap the clojure compiler with the proper paths

19:59 casperc: technomancy: cool, i'll take a look at the serializable-fn lib :)

19:59 amalloy: (comp - greatness) for all your sorting needs

19:59 technomancy: casperc: unfortunately it's not that useful if you want source of other libs that don't use serializable-fn

19:59 madsy: mpan: But if you're productive with leinigen, I don't see the problem

19:59 mpan: madsy: is there a way to do that other than bare jars on the classpath and calling the jvm?

19:59 madsy: mpan: If there is, I don't know about it.

20:00 technomancy: mpan: export LEIN_FAST_TRAMPOLINE and run `lein trampoline compile :all` or whatever and you can see the actual java invocations inside the target/trampolines directory

20:00 warning: it ain't pretty

20:00 madsy: mpan: From what I know, the three options are lein, vanilla Clojure and Eclipse

20:01 technomancy: there are some that use maven or gradle too

20:01 mpan: how do they deal with compilation? at the repl?

20:02 amalloy: the one option is lein. clojure without lein is unmanageable; and eclipse uses lein

20:02 technomancy: amalloy: I think it's technically optional?

20:02 madsy: Oh, I thought the Eclipse plugin had its own thing

20:02 amalloy: well, maybe it is. i don't know that much really

20:02 casperc: technomancy: I am basicly trying to crawl the namespaces of a jar, and I already loaded the namespace so I was hoping i could just get the mapping from the symbol to the actual code in some easy way

20:03 mpan: does lein expect you to name your namespaces in any particular way?

20:03 technomancy: casperc: tried the source macro?

20:03 mpan: no requirements beyond that of clojure itself

20:03 mpan: ah thanks

20:03 casperc: technomancy: something like mapping over the ns-publics with source but that obviously doesn't work :(

20:04 technomancy: casperc: oh, because source is a macro?

20:04 hyPiRion: Well, that's a new one.


20:04 clojurebot: #<VecNode clojure.core.VecNode@736c772f>

20:04 casperc: yep

20:04 hyPiRion: Not seen that before.

20:04 technomancy: we reimplemented source at a seajure meeting

20:04 but I don't think we actually pushed that one to github

20:04 ,(source source)

20:04 clojurebot: Source not found

20:04 technomancy: =(

20:04 ,(clojure.repl/source clojure.repl/source)

20:04 clojurebot: Source not found

20:04 egghead: why might core.logic return '[_0 _0] as a result when I am only asking for q

20:05 technomancy: casperc: well, you can see how it's implemented and steal its guts

20:05 casperc: technomancy: would be useful if doc and source were functions instead (or had function versions) so you could get the source for a symbol in a var

20:05 technomancy: yeah that might be the best solution actually

20:05 technomancy: casperc: agreed, but clojure.repl isn't intended primarily for programmatic use

20:05 amalloy: egghead: (run* [q] (conde [succeed succeed])), right?

20:05 technomancy: anyone building editor tooling on top of it will have to roll their own anyway

20:05 amalloy: would be the easiest way to get that result

20:06 mpan: when using core.logic to solve a "board game" of variable size, is it recommended to use one var for the board position or one var per element of the board position?

20:07 bbloom: mpan: it's probably wise to have one lvar per degree of freedom

20:07 mpan: bbloom: thanks

20:07 bbloom: mpan: consider the sudoku example

20:07 mpan: btw what if you can't properly separate the dfs?

20:08 egghead: hmm, must be something I'm not understanding amalloy -- I'm working on the 4clojure problems, mind if I pm you ?

20:08 bbloom: mpan: what do you mean by "dfs" ?

20:08 mpan: er, degrees of freedom

20:08 just realized that was ambiguous

20:08 sorry

20:09 although I suppose that's more a problem of expressing the task rather than solving it

20:09 amalloy: go ahead

20:10 bbloom: mpan: dunno enough about your problem to provide guidance, and i don't have a lot of experience designing logic programs yet

20:10 mpan: it pays to have some understanding of how the backtracking and search strategy works, so that you can reason about the size of the search space

20:11 mpan: is it possible to ask for the search to go a certain way, as if you were writing an explicit solver?

20:11 bbloom: mpan: don't think so yet, i know dnolen was talking about adding something for that

20:14 casperc: technomancy: actually the underlying source-fn seems to do the trick :)

20:14 tomoj: if there were a catch* macro that just expanded to catch (say in cljs/core.clj..), I think you could get clojure-mode to indent try*/catch* correctly :/

20:15 hyPiRion: ,(let [[f & r] (drop 281 (vals (ns-publics 'clojure.core)))] (remove f r))

20:15 clojurebot: ()

20:15 casperc: technomancy: so combined with your meta trick i think I am set to crawl a namespace. Thanks for the help!

20:16 hyPiRion: That's my new way of getting an empty list.

20:16 technomancy: casperc: cool

20:16 bbloom: mpan: see http://www.mozart-oz.org/documentation/fdt/

20:17 mpan: oh cool

20:17 thank you

20:17 amalloy: tomoj: no you couldn't, because catch doesn't macroexpand its input

20:17 bbloom: mpan: in general, you can use a "distribution strategy" to guide the search. with a carefully selected distribution, you can optimize a variable (ie minimize or maximize)

20:17 mpan: or just get to some number of solutions faster

20:17 tomoj: amalloy: huh?

20:18 amalloy: tomoj: (defmacro catch* [& xs] `(catch ~@xs)) (try (...) (catch* Exception e)) ;; doesn't act like a catch

20:20 tomoj: oh, because try doesn't macroexpand?

20:20 er, try*

20:20 amalloy: yeah, that's what i meant

20:20 tomoj: well, would have to add catch* as another special

20:20 amalloy: tomoj: catch is already not a special

20:20 it's just a secret thing that the try special looks for

20:21 tomoj: then would have to add it there

20:21 amalloy: yes

20:21 tomoj: maybe someday clojure-mode will just be able to do the right thing

20:22 hyPiRion: Hum, is there any way of getting the global hierarchy somehow?

20:24 amalloy: &@#'clojure.core/global-hierarchy

20:24 lazybot: ⇒ {:parents {}, :descendants {}, :ancestors {}}

20:25 hyPiRion: Well, that was rather empty.

20:26 bbloom: amalloy: &@#' to you too

20:26 that's quite the metacharacter mouthful

20:26 mpan: what is # in that usage?

20:27 overloading confused me

20:27 hyPiRion: ,(isa? clojure.lang.PersistentArrayMap clojure.lang.IPersistentMap)

20:27 clojurebot: true

20:27 hyPiRion: ,(isa? clojure.lang.PersistentArrayMap clojure.lang.IPersistentMap @#'clojure.core/global-hierarchy)

20:27 clojurebot: #<NullPointerException java.lang.NullPointerException>

20:27 bbloom: #'x is short for (var x)

20:27 hyPiRion: bzz.

20:27 bbloom: ,#'assoc

20:27 clojurebot: #'clojure.core/assoc

20:28 mpan: oh, because 'x is just a sym if unresolved?

20:28 hyPiRion: any sym is just a sym

20:28 mpan: I was accidentally conflating the sym with the var to which the sym referred

20:29 hyPiRion: heh

20:30 bbloom: mpan: resolved is different than derefed

20:31 mpan: vars are reference types, just like atoms, but referring to one in source is automatically deref-ing them

20:31 ,['assoc `assoc #'assoc]

20:31 clojurebot: [assoc clojure.core/assoc #'clojure.core/assoc]

20:31 bbloom: ,(map class ['assoc `assoc #'assoc])

20:31 clojurebot: (clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Var)

20:31 bbloom: ,(deref #'assoc)

20:31 clojurebot: #<core$assoc clojure.core$assoc@2cb15301>

20:31 bbloom: ,(class (deref #'assoc))

20:31 clojurebot: clojure.core$assoc

20:32 bbloom: ,(fn? (deref #'assoc))

20:32 clojurebot: true

20:32 bbloom: there we go :-P

20:32 hyPiRion: ,((juxt 'dissoc #'dissoc dissoc) {} nil)

20:32 clojurebot: [nil {} {}]

20:33 mpan: so resolving is getting the fully-qualified var? and derefing is getting what is held in the var?

20:33 bbloom: mpan: the terminology might be a little fuzzy

20:33 ,(clojure.core/resolve 'assoc)

20:33 clojurebot: #'clojure.core/assoc

20:33 technomancy: resolving is getting the var

20:33 mpan: also, why does the language have both vars and atoms?

20:34 technomancy: vars are only mutable in order to support interactive development

20:34 they don't have CAS semantics

20:34 atoms are there to call out explicit mutable places

20:34 bbloom: mpan: vars are thread locals, atoms are shared storage

20:34 mpan: so don't use vars as "storage"?

20:35 technomancy: mpan: not for things that could change at runtime

20:35 mpan: all right

20:35 thank you all for clarifying

20:36 technomancy: well you can use them with binding

20:36 but that's not really storage

20:53 TimMc: mpan: vars, refs, atoms, agents

20:57 rbxbx: In compojure to compose routes does one simply need to thread them through each other and then mount the result of that as your app (ie: in handler/api)

20:57 https://www.refheap.com/paste/7735

20:58 where task-routes and app-routes were defroutes'd

20:58 amalloy: rbxbx: (routes x y) is a route that tries x, and falls back to y if that doesn't work

20:58 brehaut: rbxbx: overthinking it

20:58 amalloy beat me

20:59 rbxbx: amalloy brehaut cheers :)

21:14 seangrove: Anyone using shoreleave?

21:14 I'm updating a publishized atom, but none of the callbacks are being fired

21:15 Usually it's because I've forgotten something very basic, but can't seem to track it down

21:18 hyPiRion: ,((juxt #(`%%%) number?) (/ 0.0 0.0))

21:18 clojurebot: [NaN true]

21:25 TimMc: :-P

21:26 seangrove: Wow, actually, all of shoreleave pubsub seems to have stopped working

21:26 What could I possibly have done...

21:27 * seangrove should be committing more frequently

21:29 hyPiRion: no bisect for you

21:31 Bronsa: ,'#(`%%%)

21:31 clojurebot: (fn* [p1__27#] ((quote p1__27__28__auto__) p1__27# p1__27#))

21:31 Bronsa: heh, clever

21:32 TimMc: It's *very* clever. Even if the arg is a map, it won't contain the gensym as a key.

21:33 Bronsa: yeah

21:33 TimMc: At best, you could fool it with a reify'd thingum.

21:37 hyPiRion: ##(#(`%%%) (reify clojure.lang.ILookup (valAt [this x y] "NOPE")))

21:37 lazybot: ⇒ "NOPE"

21:38 hyPiRion: clever

21:39 Bronsa: lol

21:39 TimMc: You can break all sorts of things with reify.

21:40 brehaut: i <3 reify

21:41 hyPiRion: ,(#('+%&`%&)) ; ~= (gensym)

21:41 clojurebot: rest__27__28__auto__

21:41 TimMc: (throw (proxy [Throwable] [] (getCause [] this))) <-- fun times

21:42 * brehaut opens a new repl…

21:42 TimMc: Good call.

21:42 It just hangs.

21:42 brehaut: apparently so

21:42 hurrah for reply supporting ctrl+c

21:42 TimMc: hmm

21:43 Is that the new lein repl, or am I thinking of nREPL?

21:43 brehaut: both

21:43 reply is an nrepl client

21:43 its both a standalone thing and the new lein repl

21:43 TimMc: Ah, OK.

21:43 brehaut: trptcolin has done a good job

21:44 TimMc: Speaking of which, I need to figure out how to use Home and End in lein2 repl.

21:44 brehaut: what to do?

21:46 TimMc: Well, I get "H" and "F" printed out instead of cursor navigation.

21:46 hyPiRion: rlwrap?

21:46 TimMc: Installed.

21:46 brehaut: oh weird

21:46 hyPiRion: C-a and C-e then

21:46 TimMc: hyPiRion: For now, yes.

21:46 brehaut: yeah, C-a and C-e is what i use

21:46 home and end scroll the terminal

21:47 (on my mac)

21:47 hyPiRion: But yeah, I know the issue. I just tell myself I'm not enough of an emacs-user to complain about it.

21:47 I shouldn't complain about C-a and C-e.

21:48 ,(#('!,*%&) :a :b :c)

21:48 clojurebot: (:a :b :c)

21:48 hyPiRion: ,(#(`[[~@%&]](+)) :a :b :c)

21:48 clojurebot: [:a :b :c]

21:48 brehaut: hyPiRion: celebrating 25 years of perl?

21:49 hyPiRion: brehaut: Yeah - by practising my swearjure skills

21:49 TimMc: ~factorial

21:49 clojurebot: factorial is not something you need alphanumeric characters for: https://gist.github.com/3036120

21:49 TimMc: (inc swearjure)

21:49 lazybot: ⇒ 1

21:49 hyPiRion: heheheh, I love it

21:49 oh, factorial

21:49 clojurebot: factorial is not something you need alphanumeric characters for: https://gist.github.com/3036120

21:49 TimMc: ~botsnack

21:49 clojurebot: Thanks! Can I have chocolate next time

21:50 bbloom: TimMc: aw c'mon now, (= (*) 1) is cheating

21:50 TimMc: bbloom: Cheating?

21:50 bbloom: gotta define the set of natural numbers recursively

21:50 TimMc: heh

21:50 My goal was not, in fact, obfuscation.

21:50 brehaut: TimMc: have seen a doctor about htat?

21:51 TimMc: brehaut: The link?

21:51 brehaut: indeed

21:51 TimMc: clojurebot: botsnack is <reply>Thanks! Can I have chocolate next time?

21:51 clojurebot: what time is it?

21:51 hyPiRion: We should indeed make a clojure compiler in swearjure sometime.

21:52 TimMc: Oh, wow... you can't define a factoid ending in a question mark. (Trying to replace the one without.)

21:52 brehaut: TimMc: i also couldnt work out how to define a factoid that looked like defining a factoid

21:52 mpan: is there like some sort of existing reference material for punctuationjure?

21:52 perhaps an explanation of why it works/how it bootstraps?

21:53 hyPiRion: $source apply

21:53 lazybot: apply is http://is.gd/VOGQDY

21:53 TimMc: mpan: Beyond the comments in the factorial link? I don't think so.

21:53 There's also the partial version at the bottom, which might help.

21:53 ppppaul: i want to test some uri's out in clojure

21:53 how do?

21:54 TimMc: mpan: Here's the process I went through to write rest: https://gist.github.com/3916042

21:54 ppppaul: i see in datomic a ref to java.net.URI for using uri's in the db... i would like to test some out to see if my data is a uri or not

21:55 mpan: TimMc: thanks. but what was the "factorial link"?

21:55 TimMc: https://gist.github.com/3036120, from ~factorial

21:56 hyPiRion: ,(#('!%&`#{~@%&}) 1 2 3)

21:56 clojurebot: #{1 2 3}

21:56 TimMc: ppppaul: You just want to see if something is an instance of java.net.URI?

21:56 mpan: TimMc: how are you simulating the recur call?

21:57 TimMc: mpan: What recur?

21:57 This isn't functionally equivalent to rest.

21:57 hyPiRion: heh

21:57 mpan: for the factorial example

21:57 TimMc: I should make that clearer.

21:57 mpan: one of your fns knows itself?

21:58 hyPiRion: y-combinator

21:58 TimMc: Not quite the Y combinator, but very close to it.

21:59 mpan: that's possible in punctuationjure? =o

21:59 TimMc: Oh, wait... no, I don't think this uses that trick.

21:59 mpan: See https://gist.github.com/3916042#file-rest-swear-clj-L21

21:59 hyPiRion: Oh sweet, I managed to do map

21:59 Always been bothered by that bugger.

21:59 ,(#('!%`{~%~@%&}) 1 2 3 4)

21:59 clojurebot: {1 2, 3 4}

22:00 mpan: oh, you're exploiting maps?

22:00 TimMc: mpan: In the roughest version, yes. The final version uses a vector.

22:01 In swearjure, functions can only take one argument.

22:01 mpan: would it be possible without exploiting other things being callable?

22:01 TimMc: I just make that one argument a vector of all the fns + some data.

22:01 ppppaul: TimMc, i want to see if some string is a uri via Java.net.URI (because that's what datomic uses)

22:01 TimMc: Each fn knows the indices of the fns it needs to call.

22:02 ppppaul: Oh, testing if a string is a valid URI? That sounds... fraught.

22:02 ppppaul: gah

22:02 well, i have an idea of what shape of string i want to put in the db, so i just want to sanity check that i can type it under uri

22:03 mpan: is there a single-step partial evaluator?

22:03 TimMc: ppppaul: And throw if it isn't?

22:03 mpan: and if so, would that help in understanding?

22:03 ppppaul: yeah

22:03 TimMc: ppppaul: ##(java.net.URI. "Let's see!")

22:03 lazybot: java.net.URISyntaxException: Illegal character in path at index 5: Let's see!

22:03 ppppaul: oh

22:03 TimMc: mpan: Eh?

22:03 ppppaul: i forgot the trailing dot

22:03 :)

22:04 TimMc: ppppaul: :-)

22:04 ppppaul: ##(java.net.URI. "/things")

22:04 lazybot: ⇒ #<URI /things>

22:04 ppppaul: :D

22:04 mpan: erm, just abstractly, the evaluator keeps rewriting an expr until it gets the result? is that a good/bad way to think about it?

22:04 TimMc: ppppaul: Amazing! This is a case of the proximate problem being the one that needs solving!

22:05 ~xy problem

22:05 clojurebot: "There is no problem in computer programming which cannot be solved by an added level of indirection." -- Dr Maurice Wilkes

22:05 TimMc: ...although that's a terrible name, and I will fix that factoid some day.

22:05 ppppaul: ok, so now i'm curious as to your opinion as to if it would even be worth while using uris in clojure over strings... is it easy to deal with uris?

22:05 mpan: (at least, for the subset of the language which is referentially transparent)

22:06 ppppaul: ##(print (java.net.URI. "/things"))

22:06 lazybot: ⇒ #<URI /things>nil

22:06 TimMc: ppppaul: I don't know. I'm not as up to speed on URIs/URLs on the JVM as some other folks here.

22:06 brehaut: TimMc: thus three star programmers

22:07 bbloom: mpan: clojure's evaluator is a more traditional top to bottom left to right evaluation strategy

22:07 TimMc: brehaut: ?

22:07 bbloom: mpan: it's not a rewrite rule strategy

22:07 ppppaul: what color are the stars?

22:07 bbloom: mpan: you go from the inside out, starting with the left most argument

22:07 TimMc: mpan: If you're asking if swearjure evaluation can be modeled on substitution... I think so?

22:07 brehaut: ppppaul: depends on your text editor

22:07 http://c2.com/cgi/wiki?ThreeStarProgrammer

22:07 ppppaul: oh wow, haven't seen c2 in a while

22:08 brehaut: and yet it looks exactly the same

22:08 TimMc: the original wiki

22:08 mpan: I'm wondering if I could ask for intermediates in the evaluation of swearjure

22:08 ppppaul: eleven stars!

22:08 mpan: something with less "magic"

22:09 hyPiRion: mpan: being with different characters

22:09 ,,

22:09 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

22:09 TimMc: mpan: I don't think there's mutation in swearjure. There are other "side-effects", such as exceptions.

22:09 mpan: bbloom: is it ok to pretend the two are equivalent?

22:09 hyPiRion: *begin

22:09 bbloom: mpan: not sure

22:10 TimMc: mpan: Well, the rest.swear.clj link should help, since it's the "same" function at different stages of swearingness.

22:10 mpan: TimMc: does it help to read it forwards or backwards?

22:10 hyPiRion: top-to-bottom, I suppose?

22:11 TimMc: Top to bottom.

22:11 mpan: how are you getting from having 0 to making 1?

22:11 hyPiRion: ,(*)

22:11 clojurebot: 1

22:11 mpan: OH

22:12 I thought you had an "inc" equivalent

22:12 thanks

22:12 TimMc: Yeah, *I* can't read the final form.

22:12 hyPiRion: inc is ##(+(*) ... )

22:12 lazybot: java.lang.RuntimeException: Unable to resolve symbol: ... in this context

22:12 TimMc: mpan: inc is (+ x (*)) :-P

22:12 mpan: I thought you could "make" inc without "having" 1

22:12 was expecting peano numbers

22:13 TimMc: Nope, those wouldn't interoperate.

22:13 hyPiRion: hmm.

22:13 TimMc: You could use them internally, I guess.

22:13 mpan: erm, I meant like, using a construction with "expr making 0" and "expr making fn which is inc"

22:13 TimMc: I don't think you can get Church numerals, by the way -- lambda calculus requires nesting of fns.

22:14 devn: Has anyone seen datomicism?

22:14 https://github.com/shaunxcode/datomicism

22:14 So cool.

22:14 TimMc: "please do not look at the code" -- good quote out of context

22:14 devn: There aren't screenshots, but please, check it out.

22:15 hyPiRion: TimMc: could you grab metadata in swearjure?

22:15 devn: Navigating and toying around with the codeq schema is much more playful, like you're in a REPL.

22:15 hyPiRion: &(-> '(x) meta vals first)

22:15 lazybot: ⇒ 1

22:16 Bronsa: wtf

22:16 ppppaul: codeq is pretty sweet

22:16 Bronsa: oh lol

22:16 devn: the schema is tough to understand

22:16 ppppaul: all datomic schema is hard to understand

22:16 devn: you really need a tool like this to play with it

22:16 ppppaul: check out datomic-simple

22:16 https://github.com/cldwalker/datomic-simple

22:17 ppppaul: i'm using zololabs stuff

22:17 i may switch if this is better

22:17 i got the tests to switch :D

22:17 devn: datomic is to lucene as datomic-simple is to solr

22:18 ppppaul: i'm looking at it right now, with my eye-balls

22:18 devn: ppppaul: you need to drag and drop the widgets in the top bar into your workspace

22:18 i missed that in the README and was confused as to why nothing worked at first

22:19 ppppaul: what is this zololabs stuff you speak of?

22:19 ppppaul: zololabs demonic

22:20 the little-documented datomic wrapper thingy

22:20 devn: where'd you hear about it?

22:20 ppppaul: strangeloop vid

22:20 devn: damn! i missed strangeloop this year.

22:20 who gave the talk?

22:20 brainproxy: ppppaul: did you work through the day of datomic materials and the tutorial on docs.datomic.com?

22:20 ppppaul: the guy in the github photo

22:21 i don't think i did the day of datomic

22:21 brainproxy: ppppaul: I found the day of datomic stuff especially helpful, learned a lot from the samples in that repo

22:21 ppppaul: i looked at seatle

22:21 devn: there are some fairly recent updates to the day-of-datomic material

22:21 the docs on datomic.com are a bummer

22:21 brainproxy: https://github.com/Datomic/day-of-datomic/

22:21 ppppaul: i'll look at the day of datomic... i've learned a lot about datomic from the #datomic channel and via tests i've wrote

22:21 devn: anyone who claims otherwise is proud they managed to figure out what datomic is and how to use it

22:22 brainproxy: devn: agreed, the docs are thin

22:22 devn: and out of date

22:22 ppppaul: oh i've seen day of datomic... didn't look through it much, though

22:22 brainproxy: ppppaul: there's some nice stuff in there, make sure to look at everything

22:22 my co-worker and i basically learned datomic by working through it

22:22 devn: i went on a datomic github repo hunt and found a bunch of good stuff, https://github.com/shaunxcode/datomicism being my favorite of the bunch

22:22 ppppaul: oh shit. tutorial is big :(

22:23 i couldn't get datomicism to work

22:23 devn: ppppaul: use codeq to analyze a repo, then start the datomic rest service

22:23 ppppaul: what didn't work?

22:23 ppppaul: have you got it working on a mem db, or do i have to use dev?

22:23 i don't know if i've used the rest service yet...

22:24 devn: ppppaul: you need the datomic rest service running

22:24 ppppaul: probably haven't

22:24 brainproxy: ppppaul: don't forget you can use local storage in free mode

22:24 devn: which, again, documentation!

22:24 ppppaul: that could be why i didn't get it working

22:24 i know i can use local storage, right now i'm writing tests

22:24 devn: i feel like everyone might be using datomic already if they just paid a couple of people to keep docs up to date

22:25 to improve them, etc.

22:25 *shrug*

22:25 ppppaul: i'm used to lack of documentation, doesn't bother me anymore

22:25 hyPiRion: TimMc: 1 without (*) (ish)

22:25 ppppaul: i just want shit to work and to have some support behind it

22:25 hyPiRion: ,(let [! meta] ((!,'(+))((`[~@(->,'(?)!)](+))(+))))

22:25 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

22:25 hyPiRion: &(let [! meta] ((!,'(+))((`[~@(->,'(?)!)](+))(+))))

22:25 lazybot: ⇒ 1

22:25 brainproxy: the (lack of) documentation wouldn't be so bad if the code base was open source :p

22:25 devn: ppppaul: i haven't done much to this recently, but: https://github.com/devn/codeq-playground

22:25 ppppaul: catnip helps me see any hidden docs :)

22:26 TimMc: hyPiRion: oh hell

22:26 I can't parse that right now, I have to get some work done before bed. I'll sleep on it.

22:26 hyPiRion: I think I can get stuff now, sec.

22:26 like letters

22:26 devn: ppppaul: check out script/datomic-rest

22:26 this is documented in some blog post somewhere hidden on the internet

22:27 but that's how you run it

22:27 ppppaul: thanks devn

22:27 looking at it now

22:27 TimMc: hyPiRion: The key is to get ahold of symbol and var or eval.

22:27 mpan: you're allowed to self-refer by name inside a let?

22:27 ppppaul: the datomic rest service will hook into mem dbs too? or just local?

22:27 hyPiRion: TimMc: Yeah, I'm cheating by saying meta = !

22:27 mpan: or am I misunderstanding what you're doing with "!" ?

22:27 hyPiRion: not using any vars though

22:27 devn: patches welcome btw -- if you're playing with datomic and codeq id like some help building up codeq-playground and datomic-playground (https://github.com/devn/codeq-playground & https://github.com/devn/datomic-playground)

22:28 mpan: oh whoops

22:28 devn: ^- ppppaul

22:28 mpan: completely mis-parsed that

22:28 hyPiRion: hm

22:28 mpan: not sure how I read a destructuring inside that :/ my bad

22:29 ppppaul: (def uri "datomic:free://localhost:4334/unique") this is how i set up a local db?

22:29 cool

22:29 hyPiRion: &(#((%,'(+))((`[~@(->,'(?)%)](+))(+))) meta)

22:29 lazybot: ⇒ 1

22:29 ppppaul: haven't seen that before

22:29 devn: hyPiRion: why are you writing that garbage?

22:29 just for fun?

22:29 hyPiRion: devn: Because I should go to bed

22:30 devn: hyPiRion: i wish i could find some code that chouser wrote in this channel like 3 years ago

22:30 hyPiRion: It originally started with me not wanting to create tests

22:30 ppppaul: devn, in my tests i'm using d/with, do you think this is sane, or should i just use regular transactions with a temp mem db?

22:30 mpan: hyPiRion: what is your current goal?

22:30 brainproxy: seeing if he can make denser line-noise than a 25 year perl hacker

22:30 hyPiRion: mpan: For tonight? getting a character I suppose

22:30 in swearjure

22:31 devn: ppppaul: i think a temp mem db -- people are always going to these great lengths to stub out solr or elasticsearch or whatever, and it just strikes me as a fool's errand

22:31 brehaut: brainproxy: APL solved that problem years ago

22:31 mpan: are there string/character constants floating around in the ns?

22:31 devn: ppppaul: just like you'd use postgres or mysql with a develeopment and test db, i think it's fair to use a datomic mem DB

22:31 hyPiRion: mpan: yeah, in the metadata

22:32 brainproxy: brehaut: true ... though I wonder if J took it a step further

22:32 ppppaul: i tried it to see how the code would look... had my whole setup in a let statement with a single test for the body

22:32 mpan: only in the metadata? :/

22:32 ppppaul: i couldn't eval anything but the whole let form :(

22:32 devn: J and APL. Fun times.

22:32 heh

22:32 mpan: a company at the job fair said they primarily used J... and they were very proud of it

22:32 ppppaul: your (def rules) in playground are big... wow

22:32 mpan: and they kept telling me how it was just like lisp

22:33 which... I don't... I can't comprehend :/

22:33 devn: APL, J, K => APL: J/K

22:33 amalloy: hyPiRion: \( <== a character, in legal swearjure! you can move on to a new goal now

22:33 devn: what is swearjure?

22:33 hyPiRion: amalloy: alphanum then

22:33 mpan: an esoteric programming language indeed

22:33 ppppaul: i am swearjure

22:33 * p_l recalls significant part of APL done in CL reader macro

22:34 mpan: hyPiRion: can you do char arithmetic?

22:34 hyPiRion: mpan: not yet

22:34 mpan: hyPiRion is it not the same as numeric arithmetic?

22:34 hyPiRion: I don't know if it's even possible

22:34 devn: ppppaul: heh, im quite serious -- what the hell is swearjure?

22:34 hyPiRion: mpan: no

22:34 devn: just obfuscated clojure?

22:34 hyPiRion: ,(+ \a \c)

22:34 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number>

22:34 mpan: actually, why can't you go fishing for char?

22:34 ppppaul: I AM SWEARJURE!

22:35 hyPiRion: because I need alphanums for it

22:35 heh

22:35 mpan: can't you do the same fishing in your ns by index trick as before?

22:35 devn: ,(+ (int \a) (int \c))

22:35 clojurebot: 196

22:35 ppppaul: i think, therefore i swearjure

22:35 hyPiRion: mpan: trying to now

22:35 mpan: does "fishing" generalize to any core function?

22:36 (provided you were willing to construct large enough int constants)

22:36 devn: ppppaul: do you know what swearjure is or do I need to keep "fishing"?

22:37 ppppaul: phish

22:37 i claim to be swearjure, but nobody listens

22:37 you must seek your swearjure, and fish it

22:37 devn: ppppaul: seriously though -- is it a library or something or what?

22:38 i googled it and im coming up empty handed

22:38 amalloy: please enlighten me.

22:38 hyPiRion: &(#((%,#'+)((`[~@(%,#'+)](+(*)(*)))(+))) meta)

22:38 lazybot: ⇒ "clojure/core.clj"

22:38 ppppaul: google has refs to swearjure, but only in this channel

22:38 hyPiRion: hmm

22:38 mpan: I'm beginning to wonder if you could bootstrap something compiler-like with a small set of primitives

22:38 devn: hyPiRion: what is swearjure?

22:38 * ppppaul anticipates being indexed

22:39 hyPiRion: ~factorial

22:39 clojurebot: factorial is not something you need alphanumeric characters for: https://gist.github.com/3036120

22:39 hyPiRion: ^

22:39 mpan: rather than attempting each particular core fn, you just come up with some way to get something arbitrary from core

22:39 hyPiRion: It's clojure without alphanumeric characters

22:39 mpan: and with core you bootstrap... erm... a "compiler"

22:39 devn: hyPiRion: THANK YOU! jesus man, was starting to go a little crazy with the cryptic answers

22:40 hyPiRion: (*) and (+) seem like they're primitives to me if that's the goal

22:40 bbloom: devn: i think cryptic answers is sorta the point of swearjure

22:40 hyPiRion: &(#(`[~@((%,#'+)((`[~@(%,#'+)](+(*)(*)))(+)))](+)) meta)

22:40 lazybot: ⇒ \c

22:40 hyPiRion: AHA

22:40 * devn pukes blood

22:40 mpan: is there a higher level overview of that strategy?

22:41 besides attempting to parse the string?

22:41 hyPiRion: devn: yeah, that's what I know

22:41 oh, I can get symbols

22:41 mpan: I vaguely recall someone doing this to python/ruby and they were fishing around in the globals for the stuff they wanted

22:42 devn: python/ruby/perl*

22:42 hyPiRion: javascript

22:42 mpan: can you get the [java] methods of an object?

22:42 devn: 1 + {}

22:42 ppppaul: <3 day of datomic

22:42 hyPiRion: mpan: through reflection, possibly

22:42 ppppaul: i'm going to shave

22:43 devn: cool.

22:43 mpan: that would get you toString among other potentially useful bits

22:43 and dot is free!

22:43 TimMc: devn: Blame gfredericks for swearjure.

22:43 mpan: woohoo!

22:43 TimMc: (inc gfredericks)

22:43 lazybot: ⇒ 12

22:43 devn: TimMc: it's fun and all, but it's killing me inside

22:43 TimMc: devn: hyPiRion also goes for a level of obfuscation beyond what I feel is strictly good taste. ;-)

22:44 hyPiRion: &(#(`[(`[~@((%,#'+)((`[~@(%,#'+)](+(*)(*)(*)(*)))(+)))](+(*)))](+)) meta)

22:44 lazybot: ⇒ ((clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat ((p1__13332__13333__auto__ (var clojure.core/+)) (((clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (p1__13332__13333__auto__ (var clojure.core/+))))) (... https://www.refheap.com/paste/7742

22:44 hyPiRion: wooo

22:44 mpan: whoooo

22:44 hyPiRion: wow, with apply I can do everything

22:44 devn: TimMc: in football this kind of thing is called a "gadget play"

22:44 (american football)

22:45 gadget being the operative word

22:45 mpan: why are you so attached to "meta", though?

22:45 TimMc: Good source of strings.

22:45 hyPiRion: mpan: Can't do anything without it

22:45 mpan: is there not something else floating around you could substitute with?

22:46 actually, can you get anything useful out of empty string?

22:46 devn: i agree with mpan, seems like a lack of imagination

22:46 mpan: I mean, I understand it would be amazing if you had meta

22:46 but are there other strings out there?

22:47 devn: sure..

22:47 ,*

22:47 mpan: I think when they did this in other languages they had easier access to string constants

22:47 clojurebot: #<core$_STAR_ clojure.core$_STAR_@470384ef>

22:47 TimMc: ,[`~@"hello"]

22:47 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: splice not in list>

22:47 TimMc: ,`[~@"hello"]

22:47 clojurebot: [\h \e \l \l \o]

22:47 TimMc: And it's a damn shame we can't do char arithmetic.

22:48 * Hodapp looks at TimMc

22:48 TimMc: Well, OK, a minor shame.

22:48 mpan: uh, could someone tell me again how you were getting the seq of all the stuff in core?

22:48 TimMc: ,````etc ;; mpan

22:48 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/seq)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/concat)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/list)) (clojure.core/list (clojure.core/seq #))))) (clojure.core/list (clojure.core/seq (clojure.core/concat (clo...

22:49 mpan: erm, I mean, I thought you had a way to enumerate a seq of everything in core

22:49 or was that just misunderstanding and wishful thinking?

22:50 devn: I think it's cool you can do that on some level, and feel free to tell me I'm a freedom-hating asshole the next time you see me, but why are you wasting your time with this bullshit?

22:50 why not do something useful?

22:51 mpan: devn: one reason is that it's oddly related to the fundamentals of computing stuff

22:51 TimMc: devn: Sometimes you want to watch Requiem For a Dream; sometimes you want to watch the Life of Brian.

22:51 devn: it's a self-made puzzle for people content on avoiding real work

22:51 mpan: i can dig that, and i get it

22:51 but at a certain point the analogy breaks down

22:51 mpan: I'm avoiding packing my belongings and going home from school =P

22:51 TimMc: mpan is correct as well.

22:51 devn: it's not.

22:51 mpan: my semester just ended and I've got a bit to do... stuff

22:52 TimMc: devn: I actually don't spend my time working on Swearjure -- it was mostly a couple of bursts of activity.

22:52 modulo some screwing around on IRC

22:52 hyPiRion: ,(`[~@```+](+))

22:52 clojurebot: clojure.core/seq

22:53 TimMc: devn: It's a fiar criticism, though.

22:53 brehaut: hyPiRion: ◎_◎

22:53 mpan: what if you could make some sort of "interpreter"?

22:53 I'm hesitant to use these terms because this is so far beyond my usual expectations of said terms

22:54 TimMc: ,(`[~@'`[~@[]]](+)) ;; hyPiRion

22:54 clojurebot: clojure.core/apply

22:54 hyPiRion: oh sweet

22:55 my life is complete

22:55 mpan: can you make the sym for fn?

22:55 hyPiRion: ,((`[~@'`[~@[]]](+))(`[~@```+](+))[1 2 3])

22:55 clojurebot: [1 2 3]

22:55 hyPiRion: huh

22:56 TimMc: ,(class (`[~@'`[~@[]]](+)))

22:56 clojurebot: clojure.lang.Symbol

22:56 TimMc: Well, crud.

22:57 OK, that's enough for me tonight. For serious, this time.

22:57 hyPiRion: ,`[#'~(`[~@'`[~@[]]](+))]

22:57 clojurebot: [(var clojure.core/apply)]

22:57 hyPiRion: ,`([#'~(`[~@'`[~@[]]](+))](+))

22:57 clojurebot: ([(var clojure.core/apply)] (clojure.core/+))

22:58 hyPiRion: it's a damn shame we can't resolve them

22:58 Oh well, night

22:58 mpan: night

22:59 TimMc: g'night

22:59 mpan: ok I think I know why I was confused

22:59 someone earlier had a need to enumerate all of a namespace?

23:00 would that be applicable to swearjure?

23:01 hyPiRion: mpan: yes, if we could iterate over the vars

23:02 mpan: that would be (almost) everything we wanted

23:02 hyPiRion: with them we could do anything

23:02 mpan: didn't you have arbitrary string construction, though?

23:02 hyPiRion: string splicing, nothing else

23:03 mpan: what about str->sym and sym->referent

23:03 ?

23:03 hyPiRion: ,(symbol "foo")

23:04 clojurebot: foo

23:04 mpan: I'm sorry. I keep confusing myself occasionally with other conversations from slightly earlier.

23:04 hyPiRion: ,(resolve (symbol "str"))

23:04 clojurebot: #'clojure.core/str

23:04 hyPiRion: ,((resolve (symbol "str")) 1 2 3)

23:04 clojurebot: "123"

23:04 hyPiRion: that's the idea.

23:04 mpan: didn't you get one of those two though already? is what I meant

23:05 hyPiRion: only symbols

23:05 not their resolved variant

23:05 mpan: what about

23:05 bootstrapping through ns-* functions?

23:05 if we could fish one of them out?

23:06 but sadly that sounds circular to me :( because where do we get the ns functions other than by enumerating the ns :/

23:06 hyPiRion: exactly

23:06 mpan: is there an act of reader-abuse which will get you one of the ns-* functions?

23:07 newb: Newb question - how do I add two lazy sequences together, e.g. add [1 2 4 8...] to [9 10 11 12 ...] to get [10 12 15 20 ...] ?

23:07 mpan: map them with +

23:07 hyPiRion: newb: (map +

23:08 mpan: we're exploring

23:08 ,(map + (range) (iterate inc 1000))

23:08 clojurebot: (1000 1002 1004 1006 1008 ...)

23:09 newb: Didn't realise map took multiple args! Thanks!

23:12 mpan: dot is free, and it is so tempting

23:12 if only you could construct arbitrary symbols

23:13 it would free you from the need for resolve/eval/apply/etc

Logging service provided by n01se.net