#clojure log - Jun 20 2012

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

0:00 * Raynes sees your paste.lisp and raises you a refheap.

0:01 adu: refheap?

0:01 Raynes: It's just me shamelessly plugging. https://refheap.com

0:01 adu: oh it uses noir! :)

0:02 kenneth: okay, so i'm about to give up on jzmq

0:03 Turns: Refheap looks nice.

0:05 estebann: i looked at zeromq a few months ago in a c context and it looked pretty good -- except that its feature set didn't really match my needs.

0:05 What is wrong with it?

0:07 technomancy: the java libraries are a mess

0:07 estebann: ah, so just a bad port?

0:08 technomancy: it's also like ... not a message queue

0:08 so a lot of people are mislead by the name

0:09 estebann: right.. so was I

0:09 but it still seemed like a pretty cool idea

0:09 technomancy: sure, if you have room in your stack for a protocol that's not HTTP and not a message queue

0:10 cmajor7: what is an idiomatic way to store and pass a struct/data structure in clojure? e.g. Need to create a request via populating "pounds / ounces / price / country / width / length / height / girth / size" on it (all values are required). Taking it in as a map does not seem right.. or is that the way?

0:10 technomancy: use a map

0:11 amalloy: maps are the king of data

0:11 brehaut: and the data of kings

0:11 cmajor7: I see.. that is what I did.. just feels a bit off, cause it is more than.. 3,4 keys

0:12 and needs to be repeated in functions definitions / let bindings, etc..

0:13 amalloy: cmajor7: if the repetition is vexing, you can avoid it with macros

0:14 cmajor7: amalloy: thx. I'll look into it. it is not really 100% repeatable, so the macros will need to be somewhat smart..

0:16 Turns: cmajor7: More smart than just having default values?

0:17 estebann: why not define a type? <- (a genuine question)

0:17 cmajor7: Turns: well.. there is no really good defaults for it.. since it needs all the fields for each "request"

0:17 adu: ok

0:17 https://www.refheap.com/paste/3246

0:17 brehaut: estebann: what would defining a type buy you? <- geniune question

0:17 adu: why is it not working

0:17 amalloy: estebann: that's just static-typing fetishism. maps already do everything you need

0:18 brehaut: (genuine socratic question that is)

0:18 adu: json/parse-stream is returning {"hello" "world"}, but mustache/render is expecting {:hello "world"}, what to do

0:18 brehaut: adu: defs in fns are bad. use a let

0:19 cmajor7: estebann: you mean http://bit.ly/LzHPMI ?

0:19 adu: brehaut: I realize that, but I'm just trying to get it working, I'm going to refactor this code anyways

0:19 brehaut: cmajor7: type is almost certainly not what you want. estebann may have been referring to defrecord or deftype. in either case he is wrong

0:20 noidi: ,(keyword "hello")

0:20 clojurebot: :hello

0:20 adu: noidi: so (map keyword data)?

0:20 cmajor7: brehaut: I see. ok, good to learn about those as I go anyway :)

0:20 brehaut: cmajor7: most people suggesting 'type' are meaning 'class' anyway

0:21 cmajor7: I see.. well it is only natural coming form imperative universe

0:21 brehaut: cmajor7: but deftype is for low level stuff (not what you want) and defrecord defines a record type which is used like a map anyway, so unless you need those other features of records (participating in protocols for instance) you probably just want maps

0:21 noidi: ,(into {} (for [[k v] {:hello "world"}] [(keyword k) v]))

0:21 clojurebot: {:hello "world"}

0:22 adu: o wait

0:22 parse-stream takes an option :P

0:22 haha

0:22 noidi: oops, I got the input wrong. anyway, it should convert string keys to keywords :P

0:22 adu: , (into {} (for [[k v] {"hello" "world"}] [(keyword k) v]))

0:22 clojurebot: {:hello "world"}

0:22 adu: cool

0:23 cmajor7: brehaut: good stuff. next academic stop is at "participating in protocols defrecords"

0:23 brehaut: cmajor7: thats a complicated way of saying, requires type directed polymorphism

0:24 cmajor7: right I get thata.. just cool to project it to clojure world

0:24 no need for it in my use case, but still need to cover

0:25 brehaut: cmajor7: i think i have created 2 defrecords in anger in about 4 years of clojure

0:25 well, thats not fair, there havent always been defrecords

0:25 adu: noidi: yey it's working: https://www.refheap.com/paste/3249

0:26 thanks everyone

0:26 cmajor7: brehaut: ok, well I am only 4 defrecords behind..

0:26 what would be the clojure way go about templatizing XML (e.g. XML request) in order to layer this "{ :pounds :ounces :price :country :width :length :height :girth :size}" map on it… compose "str/replace"s or use some kind of templating engine?

0:27 adu: cmajor7: maybe what I just did?

0:28 brehaut: cmajor7: it would not be string munging

0:28 you could use either a templating engine (such as enlive) or you could just generate the elements and then serialise that to a string

0:29 cmajor7: brehaut: right, I don't want to do that, but I am looking at hiccup/enlive, and .. not sure if I need to bring them in for a "simple" overlay..

0:29 generating elements might be a bit messy, since there are a lot of them to generate + some protocol specific ones

0:30 and if the protocol changes.. code would need to change

0:30 the template code I mean

0:31 ok, I'll take a look at enlive, never used it before, and on github it says "a selector-based (à la CSS) templating", but I always hear good things about it..

0:31 brehaut: i think worrying about 'bringing in code' when its the size of enlive or hiccup is madness. just do it

0:31 or use the clojure.xml structures and use that

0:32 cmajor7: I see, that is what I did not know "how big/messy is enlive"..

0:32 brehaut: (ie, maps with keys :tag :attrs :contents from memory)

0:32 assume that no library in clojure other than clojure.core is big

0:33 and messy? everything is in its own namespace. doesnt matter how 'messy' it is

0:33 this isn't C, you dont have to be afraid of using someone elses wheel

0:33 cmajor7: I see, I just like a predictable number of wheels.. usually 4 :)

0:34 cool, will do. appreciate you help.

0:39 adu: brehaut: I refactored it: https://www.refheap.com/paste/3250

0:39 brehaut: much better

0:39 adu: :)

0:39 brehaut: although i think you mean :require when you say :use

0:40 adu: brehaut: I have no idea what the difference is

0:40 or import

0:40 brehaut: use brings all the public vars into the current namespace, require doesnt

0:40 you need to qualify any var with require

0:40 the fact that you have :as'd stuff with use indicates that you really want :require

0:40 adu: ok

0:41 brehaut: import is specifically for importing java classes

0:41 adu: ah ok

0:44 kenneth: omg, i'm about to swear off clojure. i'm *this* close

0:44 i love clojure, but java is a fucking abomination

0:44 adu: o yey I can rename my-render to render :)

0:44 kenneth: and every time i use clojure, i end up hating every minute of it because i spend 90% of my time fighting with java, and less 10% writing clojure

0:45 brehaut: you cant make a delorian monster truck without it being part monster truck

0:46 adu: kenneth: why not write it in clojurescript, then port back?

0:46 hashset: kenneth: what imperative language are you more comfortable with?

0:47 kenneth: hashset: how about C, for starters

0:47 * adu <3 C

0:47 Turns: kenneth: You prefer C over Java?

0:47 adu: but then I got the agile bug, and I try to write thousands of lines of code per day, and C holds me back

0:48 kenneth: i prefer many things over java, and c is pretty much at the top of the list

0:48 Turns: kenneth: That's amazing! What is it that you value that C provides and Java lacks?

0:48 kenneth: objective-c is pretty great, too. as for dynamic interpreted languages, ruby is fantastic. i love clojure as a language, too, it's pretty much one of my favorites

0:49 adu: I think C is more portable than Java

0:49 Turns: I am also very impressed by many things about Clojure.

0:49 Clojure is certainly a great improvement over all other forms of Lisp.

0:49 amalloy: why is it amazing that someone would prefer C to java?

0:49 kenneth: Turns: how about 1) not loading a gigabyte virtual machine, 2) not being insanely verbose and needlessly complex, 3) being more modern

0:50 adu: yeah, like TLS

0:50 kenneth: 3) is hard to believe, but these days C has fantastic concurrency libraries (libdispatch!), closures, macros

0:50 Turns: kenneth: Yeah, if you're counting bytes in memory, best to go with C. Not sure about those other two, though.

0:50 adu: C doesn't have closures

0:51 kenneth: adu: libsystem_blocks

0:51 if you use a modern compiler

0:51 here's an example that i do all the time in my code:

0:51 Turns: People have added closures to C? That's even more amazing.

0:52 kenneth: dispatch_async(queue, ^{ printf("Hello, world!\n");});

0:52 adu: kenneth: (1) that isn't a library (2) it isn't portable, it's apple only, and (3) it's nonstandard, and (4) the syntax screws with every C parser I've tried

0:52 kenneth: adu: if you're not into it, C++11 has lamdbas too

0:52 adu: the ^ syntax even screws up GCC-XML

0:52 kenneth: which isn't C

0:53 kenneth: GCC is pretty much an abomination too, IMHO. LLVM / Clang all the way

0:53 adu: agreed, LLVM rocks

0:54 kenneth: adu: but 1) fair point, it's not a *library* per se., 2) it was written by apple, but is by no means apple only. it works on most unixes, 3) that's true and 4) why would you need to use a c parser that *isn't* clang's?

0:55 if you're willing to depend on clang (which i am), then you're fine

0:55 Turns: I understand that Java is much more verbose than Clojure or any other functional language, but is it really so much more verbose than C?

0:55 kenneth: yes, i think it is, Turns

0:55 adu: kenneth: documentation generators, IDEs, syntax highlighers, pastebins, ctags, debugging, etc.

0:56 kenneth: in C you don't write FooBarRunnableFactory

0:56 hashset: but you write sizeOf :P

0:56 adu: so if clang has all those in every text editor, then no you don't need another parser

0:56 kenneth: you don't every little thing in classes that don't need to be, you have few source file, and no import insanity for example

0:57 TimMc: Wait, are we talking about C or C++?

0:57 Turns: I've grown to love how everything in Java is in classes. I can see why not everyone would agree, though.

0:58 adu: TimMc: I'm talking about parsing

0:58 TimMc: Oh, that was just a brief excursion.

0:58 (Was looking at the C++11 thing.)

0:58 kenneth: adu: for debugging lldb works fine with blocks, my code editors / syntax highlighters have no problems with the ^ syntax, and i don't use doc generators

0:58 so for me it works out

0:59 Turns: yeah, i love it when done right, as in in ruby

0:59 Turns: kenneth: It's not done right? What is wrong with it?

0:59 kenneth: because ruby turns it into an advantage with its dynamism

0:59 duck typing, monkey patching, retrospection

0:59 that's the kind of thing that makes objects everywhere awesome

0:59 Turns: kenneth: What's all that stuff?

1:00 brehaut: monkey patching is never a feature, and always an admission of defeat

1:00 adu: I think Go has duck typing

1:00 Leonidas: Turns: int is a class?

1:01 kenneth: Turns: duck typing means you don't care about what class you're using, just that it implements what you need (e.g., if you need to turn something into a float, you just care that it implements .to_f)

1:01 brehaut: adu: i think go has something more akin to typeclasses / protocols than monkey patching

1:01 Turns: Wow, duck typing is horrible. It's like it is trying to kill abstraction and type safety!

1:01 kenneth: Turns: means you can add methods to already defined classes

1:02 adu: brehaut: there are 2 superconfusing techniques in Go: struct embedding and interface embedding

1:02 kenneth: monkey patching*

1:02 PeregrinePDX: Well monkey patching implies that you can add methods to defined classes dynamically at runtime.

1:02 adu: brehaut: I think struct embedding is monkey patching / mixins, and interface embedding is duck typing / typeclasses

1:02 clojurebot: c'est bon!

1:02 kenneth: and related, that you can add methods to objects and classes at runtime

1:02 and retrospection means you can inspect objects at runtime to see what they are, what they support, etc

1:02 brehaut: adu: duck typing is not typeclasses / polymorphism

1:03 adu: brehaut: then s/I think/I think not/

1:03 Turns: kenneth: I guess monkey patching could be useful, as long as it doesn't give you access to private members.

1:03 adu: brehaut: I've written lots of code in Go, but I've never understood those abstract terms

1:04 PeregrinePDX: Psh private members are an illusion in just about every language.

1:04 adu: I've also written lots of code in Haskell, so I'd like to say I understand typeclasses too

1:04 kenneth: Turns: duck typing is fantastic, it lets you define methods that take as an argument *something that is coercible to float via .to_f*, instead of an *int* specifically

1:04 brehaut: monkey patching is like a rube goldberg machine that eventually pulls a trigger on a gun aimed at your feet

1:04 kenneth: Turns: means for example if you write your own collection type things that have been written with the standard lib collection type in mind won't break, so long as you implement the original interface

1:05 adu: brehaut: that makes no sense

1:05 Turns: Haskell typeclasses is what I would want to use monkey patching for. You can add any method to an object anywhere, so long as you know how to implement it for that object, just like type classes in Haskell.

1:05 brehaut: Turns: exactly. typeclasses are the real solution to the hack that is monkey patching

1:05 Turns: kenneth: What you are describing as duck typing sounds exactly like what Java does.

1:06 kenneth: but back to my point about C, when you know what you're doing, you can write very concise and beautiful code, especially if you know how to use macros well

1:06 brehaut: also kenneth i think you mean introspection rather than retrospection?

1:07 kenneth: brehaut: er, yes

1:07 Turns: kenneth: Oh yeah, Java's got that.

1:07 adu: Turns: sounds like the Set Monad problem

1:08 kenneth: i'm working on a game in Obj-C / C and my entire game state is container in a 82 byte malloced pointer

1:08 my code is very well separated following the MVC pattern

1:08 Turns: kenneth: Just the sort of thing I would expect a C programmer to be pleased with: counting bytes.

1:08 adu: Go interfaces and Haskell typeclasses both have ways of "inheriting requirements", i.e. I'm defining something called X, and it must already be a Y

1:09 noidi: What's the difference between "Load file in REPL" and "Compile file in REPL" in CCW?

1:09 PeregrinePDX: A lot of languages have some form of fetishism. SO c programmers count bytes. So what.

1:09 kenneth: Turns: the comparable code in java would have 100+ objects in memory, a good dozen classes, most of them empty containers with a couple accessors

1:09 amalloy: retrospection is when you wish you had planned your interfaces more carefully

1:10 brehaut: (inc amalloy)

1:10 lazybot: ⇒ 24

1:11 kenneth: Turns: also in my case the conciseness of the data matters, because i need to embed the entire game state into a URL

1:11 so people can text each other self-contained levels

1:12 Turns: kenneth: How you store it in memory and how you output as a URL shouldn't be connected. That's unfortunate coupling!

1:12 adu: kenneth: brilliant

1:12 kenneth: in java i'd have to build serialization routines for a more concise data format. just an example of how java makes my life a pain and how it requires more code and worse, more classes, to do the same thing

1:13 PeregrinePDX: Why would you need to embed your entire game state into the url?

1:13 Turns: kenners: I'm sure making serialization for a game state of no more than 82 bytes wouldn't be hard.

1:13 adu: kenneth: so if people reverse engineer your url-encoding format, they can give themselves 1 billion hitpoints, and 1 trillion credits?

1:13 PeregrinePDX: I can see wanting to do so but needing to do so seems like an awkward requirement.

1:13 kenneth: PeregrinePDX: it's not a requirement, it's just a nice to have

1:14 but i'm not talking in absolutes here, i'm just showing how java is a pain in my ass for doing even the simplest thing

1:14 PeregrinePDX: So you wouldn't have to build serialization routines for java to make it encode your game state in a small space. Just if you wanted to make it feature identical to your other code.

1:14 brehaut: ,(char-array 84)

1:14 clojurebot: #<char[] [C@7777ac14>

1:14 brehaut: damn

1:15 i wish there was a way to just get hold of 84 bytes in java

1:15 kenneth: my entire game logic, state, and an objective-c wrapper class fits in a 300 line .m file

1:16 if i were writing this in java, i'd be drawing a diagram of interconnected classes and objects on a whiteboard at this point and creating a folder structure to sanely hold my code

1:16 Turns: I suppose C has its superior equivalent to Swing, too.

1:17 kenneth: never used pure C for building graphical user interface (aside from OpenGL), but in obj-c land UIKit & AppKit are fantastic libraries

1:18 https://gist.github.com/ac122324fbe724165d61

1:18 there's a couple prototypes and typedefs in the header too, but that's pretty much it

1:18 kay__: would it be out of line to ask what a .m file is?

1:18 Turns: kenneth: What would prevent you from simulating C in Java by making all your functions static members of as many or as few classes as you like?

1:18 tomjakubowski: kay__: an objective C source file

1:20 kenneth: Turns: well for one, you can't (sanely) do a callback pattern in java

1:20 because java doesn't support closures

1:20 (anonymous inner classes implementing Runnable do not count as a sane closure)

1:20 amalloy: brehaut: i don't understand. do you just want (byte-array 84), or is this some kind of sarcasm/joke?

1:21 brehaut: amalloy: it was some kind of sarcasm/joke

1:21 Turns: kenneth: What's wrong with anonymous inner classes?

1:21 brehaut: amalloy: with an added not looking at my apropos output hard enough

1:22 Turns: kenneth: Does that nonstandard C closer syntax do something that anonymous inner classes don't do?

1:22 kenneth: Turns: it's a syntactic nightmare, for one. secondly, you need to create an interface declaration for every "signature" you want your "closure" to have, IIRC

1:22 Turns: memory management and reference counting, for one. though i guess you don't have to deal with that since you have a GC

1:23 Turns: kenneth: How can you use a closure without a defined signature anyway?

1:24 kenneth: closures always have signatures, but you can define the type inline, or typedef it to give it a name if you'd like

1:24 no need to write protocols / interfaces for it

1:25 Turns: kenneth: What do you mean by "define the type inline"?

1:25 kenneth: Turns: you can write a function like this for example

1:27 void do_something(void(^callback)(int *err, char *data));

1:28 Turns: kenneth: Oh, I see. It's just a little less verbose than the Java equivalent.

1:28 kenneth: i.e. a function that takes an closure as its only argument, where the closure returns void and takes two arguments (a pointer to an int, and a string)

1:29 jhowarth: Is there anything special I need to do to get slime/swank to be able to work with my project after I do clojure-jack-in?

1:29 kenneth: not sure how i'd do this in java, but i'm pretty sure it involves writing an interface, then taking as argument that implements that interface, and then to use it i'd have to use an anonymous inner class that implements said interface

1:30 Turns: kenneth: Yeah, that's how.

1:30 kenneth: my point is not that java is not a capable language; that's been disproven by people smarter than myself

1:31 my point is that java makes programming painful and slow and is (to me) incredibly containing and frustrating

1:32 Turns: kenneth: Language preferences cannot be proven.

1:32 kenneth: even in C, these are things I can do on the fly as i code, and i really enjoy my time doing it

1:32 and i can pretty much dig in as long as i've got llvm and vim around (or even gcc/gdb, god forbid)

1:33 just thinking about using java without a massive IDE and its series of necessary tools makes my brain hurt

1:33 Turns: kenneth: I do that all the time. It's no problem, really.

1:34 kenneth: you're probably a much better java developer than i am

1:34 :p

1:34 speaking of which, if you know how to compile a JNI library and use it from a clojure project successfully, i'd love your help

1:34 Turns: kenneth: I doubt it. Worrying about memory management in a language with little or no static type checking and having to keep track of header files makes my brain hurt when I think about it.

1:35 kenneth: Wow. No wonder you're having troubles!

1:36 kenneth: i've spent the past three hours trying to use ømq in a clojure project and nothing works :p

1:36 Turns: kenneth: What sort of problem are you having, though? It seems to me like it should work just fine as long as you keep things persistent.

1:37 Sgeo: Hmm

1:37 I wonder if I could actually implement the Seer monad in Clojure

1:38 (Of course, that would require me to understand it)

1:38 kenneth: Turns: in my experience, the compiler is smart enough to warm me when i'm doing something stupid. but when i know what i'm doing and i'm explicit about it, it will let me do anything i want, which is great. and i love header files because it's like documentation that informs both the compiler and users of my code. it saves me from having to write javadoc type stuff

1:38 to each his own, tho

1:39 Turns: kenneth: Just glancing at the ZeroMQ wikipedia page makes me think using it from Clojure seems like an awful task!

1:40 kenneth: Turns: my problem is that `leon compile` fails. i've tried a couple things as suggested from online tutorials (since documentation is nonexistent) and each gives me a different failure

1:41 Turns: kenneth: What sort of failures are you talking about?

1:43 kenneth: Turns: for example, i get java.lang.ClassNotFoundException: org.zeromq.ZMQ.Socket (log_scale.clj:1)

1:44 and i have no idea how to debug it

1:44 i've compiled the JNI, i've added it to project.clj

1:44 https://gist.github.com/802b506d17c68150b293

1:44 here's my project.clj fwiw

1:44 and i'm trying to import [org.zeromq.ZMQ Socket]

1:45 Turns: kenneth: And you actually have that class in the classpath? I just have to ask that.

1:45 amalloy: i should really write a tool called leon. the amount of lein-typo google-juice it would get...

1:47 kenneth: Turns: presumably

1:48 Turns: if i extract the jar that lein installed i've got org/zeromq/ZMQ/ZMQ$Socket.class

1:48 also i verified that libjzmq is correctly in /usr/local

1:48 like i said, i have no idea how to debug this

1:48 Turns: kenneth: That doesn't look like the right class. ZMQ$Socket isn't the same as Socket.

1:49 kenneth: well, fwiw i get the same error if i try to use org.zeromq.ZMQ.ZMQ

1:49 which does look like a class

1:50 Turns: kenneth: Exactly the same error? Or ClassNotFoundException: org.zeromq.ZMQ.ZMQ.Socket?

1:51 kenneth: if i change the import to [org.zeromq ZMQ] i get a different exception (good sign?)

1:51 no jzmq in java.library.path

1:51 presumably indicating that it can't find libzmq

1:52 even though i do have this just in case: :jvm-opts ["-Djava.library.path=/usr/local/lib:/opt/local/lib:/usr/lib"]

1:53 (java.lang.UnsatisfiedLinkError)

1:54 oh wtf, where did my /usr/local/lub go

1:54 would lein ever nuke my usr local lib?

1:54 Turns: kenneth: I guess that means that at least you really have a class called org.zeromq.ZMQ. That is a good sign, actually!

1:55 kenneth: jesus

1:55 looks like lein rm'd my /usr/local/lib

1:55 what. the. fuck.

1:56 okay

1:56 Turns: I'm surprised that lein would do that!

1:56 _ato: you're running lein as root?

1:56 kenneth: me too

1:56 _ato: nope, but /usr/local is writable by me

1:57 _ato: ah

1:57 kenneth: re-did the make install on my compiled jzmq and looks like now it's picked up

1:57 progress

1:57 now my zeromq lib got nuked too

1:57 grr

1:57 good thing most of my libs were just symlinks and not binaries

1:58 otherwise iw ould be very fucked right now

1:58 Turns: kenneth: I can't really help you with making lein stop deleting things, but you should probably figure out why it is doing this stuff before you try to go any further.

1:59 kenneth: yeah, good point

1:59 got my libzmq back, good news. now i'm onto my next error: Could not locate org/zmq/clojure_zmq__init.class or org/zmq/clojure_zmq.clj

1:59 i take it that's related to the clojure-zmq package

2:00 Turns: Have those files been deleted too, I guess?

2:00 kenneth: nope, that's not in use lib that's in my project folder

2:01 Turns: Normally files that are where they are supposed to be can always be located. So there's not many things that could be causing that problem.

2:01 kenneth: if i unpack the clojure-zmq.jar i see org/zeromq/clojure.clj

2:02 only source file aside from example in the unpacked jar

2:02 _ato: the JVM (pre the new APIs in Java 7) is completely unaware of symlinks. Could you have had a symlink to /usr/local/lib and lein followed it when cleaning up the target directory?

2:02 Turns: kenneth: That's not one of the missing files, though.

2:03 kenneth: _ato: i don't think so, though i did try at one point to set :native-path to "/usr/local/lib"

2:03 my guess is that's the reason?

2:04 Turns: kenneth: Do you really have a package called org.zmq and one called org.zeromq? That's not a mistake?

2:26 kenneth: omg got it to compile

2:26 Turns: kenneth: How?

2:26 kenneth: taking it step by step

2:26 i had to make a bunch of changes

2:35 amalloy: Sgeo: the Seer monad? the well of google runs dry when i try to find that

2:37 Sgeo: amalloy, top answer to http://stackoverflow.com/questions/11060565/tying-the-knot-with-a-state-monad

4:45 noidi: I've added this to my project.clj: :dev-dependencies [[lein-midje "2.0.0-SNAPSHOT"]]

4:45 but running 'lein midje' gives me: midje is not a task.

4:46 I'm using Leiningen 2.0.0-preview6

4:46 clgv: noidi: you can omit adding it as dev dep. instead install it via lein plugin install lein-midje 2.0.0-SNAPSHOT

4:47 noidi: a side note: :dev-dependencies is not used in lein2 anymore

4:47 noidi: okay, thanks

4:47 that means the midje docs are out of date

4:47 clgv: noidi: you have to add midje as dependency though

4:48 lein-midje is only the plugin to run the midje tests you have written via leiningen

4:48 noidi: yeah

4:48 will midje be bundled in the uberjar, then?

4:48 if lein2 ignores dev-dependencies

4:49 or does it just not load its plugins from dev-dependencies?

4:49 clgv: noidi: you have to use the :profiles syntax in lein2. that should bge explained in the readme

4:50 noidi: ok

4:59 kral: namaste

5:02 noidi: what I ended up doing was :profiles {:dev {:plugins [[lein-midje....]]}}

5:02 the new profiles system looks great

5:02 now that I got the hang of it

5:03 clgv: still waiting for lein2 to be released as a stable version ;)

5:07 hyPiRion: clgv: lein2 is relatively stable unless you're depending on the repl in Windows.

5:07 clgv: hyPiRion: I like the maintainer to be confident that he can do a stable release ;)

5:37 noidi: clgv, apparently it's not that lein2 is buggy, but clojars.org needs some repo rework, and Phil wants to use the new repos as defaults in lein2 http://groups.google.com/group/leiningen/browse_thread/thread/40f8ed97f37a47e1

5:53 TEttinger: hyPiRion, what is so unstable about the lein2 REPL on windows?

5:54 I haven't encountered any issues in my (light) usage

6:18 clgv: noidi: who says it's buggy? I will upgrade when they say 2.0.0 is done. ;)

8:00 cshell: Is there a way to destructure a Java Pojo to a clojure map? ie. getName -> :name?

8:04 gstamp: (doc bean)

8:04 ohpauleez: cshell: bean

8:04 cshell: awesome, bean

8:04 haha

8:04 thanks guys

8:04 ohpauleez: np

8:06 wmealing: is clj-audio one of the saner ways to deal with microphones in clojure ?

8:06 if there is a better way, i'm open to suggestions

8:13 my google is failing me

8:18 clgv: wmealing: you can just take a well established java lib therefore

8:21 wmealing: clgv, like javax.sound.sampled and go from there ?

8:22 clgv: I dont know any lib for it. either you use a good lib via interop directly or you build a wrapper layer for better usage from clojure

8:28 * wmealing nods

11:18 edoloughlin: Catching up/migrating from 1.2->1.4. What's the current best practice for working with exceptions? Slingshot?

11:20 nDuff: slingshot is good stuff, yes

11:21 edoloughlin: I seem to remember an attempt to bring Lispy conditions to Clojure. Did that go anywhere?

11:25 foxdonut: edoloughlin: what does that mean? more parens?

11:27 edoloughlin: foxdonut: See http://clojuredocs.org/clojure_contrib/clojure.contrib.condition — The 'Where did clojure.contrib go?" page (http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go) says it was replaced by Slingshot, but it's not equivalent and seems to be removing functionality.

11:28 S11001001: slingshot is cooler

11:29 choose your own dispatch

11:29 clgv: regarding "Where did Contrib go?": I wonder when clojure.core.incubator gets merged into clojure.core? 1.4 would have been a chance...

11:29 S11001001: autounboxing

11:29 (you can get buried in those dumb runtimeexception boxes and it won't matter)

11:31 edoloughlin: S11001001: Ok. I didn't get a sense of these benefits from the slingshot github page...

11:33 nDuff: ...well, _some_ of the things I'd like slingshot to have are still in the current snapshot tree rather than in a release yet

11:33 ...such as being able to use multiple conditions for a single catch clause...

11:33 ...but yeah, that's a pretty darned trivial quibble, and one that'll fix itself with time.

11:34 gfredericks: there should be a term to insert into a version number to indicate "This is not my project but I want a release of the current edge snapshot so I'm throwing this up on clojars mostly just for myself."

11:34 maybe could include a SHA prefix as well

11:34 clgv: gfredericks: thats your group-id that says this ;)

11:35 gfredericks: clgv: hard to distinguish that from "I'm forking this project because the maintainer is lazy"

11:35 I guess if you were seriously forking you'd probably rename it :/

11:35 clgv: gfredericks: sounds almost the same ;)

11:35 the first comment I mean

11:35 gfredericks: okay, so the only thing is to put the SHA into the version number

11:36 clgv: I meant "forking" in a long term way

11:36 cemerick: gfredericks: "throwing this up on clojars for myself" should be replaced with "throwing this up into my private s3 repo for myself" https://github.com/technomancy/s3-wagon-private

11:36 gfredericks: cemerick: I'm not passionate enough to dispute that :)

11:37 TimMc: cemerick: And make it unbuildable for others? Nah, I cut a release like org.clojars.timmc/enlive and call it good.

11:38 gfredericks: cemerick: yeah there is that ^ case

11:38 clgv: nDuff: erm the last commit was the change to the next version so probably the changes you like are in a release of slingshot (0.10.3)

11:38 gfredericks: ooh oh oh; what happens to the diamond dependency situation when you've got two libs with different group/ids but identical namespaces? o_O

11:38 cemerick: That's degenerate.

11:39 * cemerick hopes clojars eventually shuts that route down.

11:39 cemerick: Maybe with Leiningen 3. :-P

11:39 gfredericks: A -> B -> enlive; A -> C -> org.clojars.timmc/enlive

11:39 maven will pull in both?

11:39 and clojure will be confused?

11:39 TimMc: Just block the regular enlive.

11:39 gfredericks: TimMc: so you have to be concious of the situation?

11:40 TimMc: Ah, I see... A wouldn't know.

11:40 But yes, the existing coordinate system is insufficient.

11:40 cemerick: gfredericks: yeah, you'd get both jars on the classpath, and whichever came first would win.

11:40 gfredericks: https://twitter.com/stuartsierra/status/214023282511450114

11:41 cemerick: quite right :-D

11:41 gfredericks: and with that ^, I'm back to working on work

11:41 TimMc: It should be group/artifact + publisher + version & variants

11:41 clgv: TimMc: :O

11:45 TimMc: clgv: Don't keep your mouth open like that, encoding bugs will fly in!

11:46 clgv: lol. dont worry, I dont do I/O right now - it's statistics right now

11:52 S11001001: edoloughlin: source docs

11:55 nDuff: clgv: Heh. Yay!

12:11 jonasen: dnolen: ping

12:14 dnolen: jonasen: pong

12:15 jonasen: dnolen: I've been running queries on cljs/core.cljs and I've found a few "interesting" things

12:15 dnolen: jonasen: shoot

12:15 jonasen: by which I mean, what in particular?

12:16 jonasen: for example, the assert macro is imported from the java side and expands to java.lang.AssertionException on the javascript side

12:17 so we should probably move it over to the clojurescript macro side

12:17 N8Dawg: i had a question around test coverage tools for clojure

12:17 does anyone know a good library, if one doesn't exist how useful would people find one?

12:18 dnolen: jonasen: huh, strange - we use assert in the tests and it works fine.

12:18 technomancy: ,google lein-guzheng

12:19 jonasen: dnolen: there are three usages of assert in cljs/core.cljs and the all expand to java.lang/AssertionException

12:20 technomancy: hiredman: looks like clojurebot has experienced an untimely demise

12:20 N8Dawg: take a look at guzheng

12:20 dnolen: jonasen: just tried in REPL I don't see this at all, so I need more info.

12:20 N8Dawg: technomancy: Thanks, that looks exactly what i'm looking for, i'll give it a whirl

12:21 jonasen: hmm.. I'll try to find more info then :), I'll get back to you on that particular issue later.

12:22 dnolen: jonasen: I just checked the source. assert macro is excluded in HEAD and assert is defined in core.clj compiler macros file.

12:22 jonasen: dnolen: ok. So this has been changed since the latest release then

12:26 dnm: technomancy: What's the weather there today?

12:26 jonasen: dnolen: https://github.com/clojure/clojurescript/blob/r1424/src/cljs/cljs/core.cljs#L1273

12:26 technomancy: dnm: in seattle? sunny and wonderful. 68℉

12:26 * dnm wishes he was in his place in Ballard today rather than in the white hot nuclear heart of the sun in D.C.

12:26 technomancy: hehe; yeah

12:26 dnm: Fuck this place. Seriously. Take this climate and shove it.

12:26 jonasen: dnolen: ^^ is that good style or should it be (.floor js/Math)

12:27 dnolen: jonasen: not sure yet - we want core.cljs to compile everywhere. so that might become a complier macro.

12:28 jonasen: dnolen: Do you mean you want to remove all js/foo from core.cljs?

12:29 dnolen: jonasen: yes

12:29 jonasen: dnolen: ok.

12:30 dnolen: Next one is at https://github.com/clojure/clojurescript/blob/r1424/src/cljs/cljs/core.cljs#L5702

12:31 dnolen: jonasen: ?

12:31 jonasen: I think that kind of form confuses the analyzer

12:31 dnolen: jonasen: why?

12:32 jonasen: first, the clojure reader expands it to (new cljs.core.PersistentTreeSet ...)

12:33 dnolen: jonasen: oh right oops that's a bug now. cljs.core/PersistentTreeSet

12:34 jonasen: dnolen: ok

12:34 it fails in resolve-var I think

12:34 or failed

12:35 dnolen: On that note. What's the point of this case: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/analyzer.clj#L165 ?

12:37 dnolen: There is a similar case in resolve-existing-var, and I've never really understood why they are present

12:39 dnolen: jonasen: I considered removing it at one point, but reluctant to address the likely breakage. patch welcome.

12:40 jonasen: I think it's a remnant from waaay back (before the js/* magic namespace)

12:41 dnolen: jonasen: we also didn't have proper property access syntax.

12:42 jonasen: dnolen: Removing it will probably break some code out there... but I think it should be removed

12:42 there is no equivalent on the clojure side

12:42 dnolen: jonasen: I agree - I meant breakage from within CLJS itself.

12:43 jonasen: dnolen: true, but they are fixable

12:43 dnolen: jonasen: one thing to consider is where cljs.core.PersistentTreeSet should actually be considered bad form. That's valid in Clojure JVM.

12:44 where -> whether.

12:44 jonasen: dnolen: I've been wondering the exact same thing :)

12:45 dnolen: jonasen: another reason i left that case alone.

12:46 jonasen: dnolen: the real problem with cljs.core.PersistentTreeSet is that the analyzer thinks that cljs is the namespace and core.PersistentTreeSet is the name

12:46 so it becomes cljs/core.PersistentTreeSet

12:49 dnolen: jonasen: yes resolve-var and resolve-existing var should be fixed. they should probably not create the ns field at all.

12:50 jonasen: related, type hints of either form should probably work.

12:50 jonasen: I think they should figure out the ns, isn't that what resolving means?

12:51 dnolen: cljs.core/List & cljs.core.List

12:51 jonasen: perhaps but how do you reconcile cljs.core.PersistentVector/fromArrays ?

12:51 jonasen: I supposed there could be check to see if the part before / is a type.

12:52 jonasen: dnolen: that's another thing I've been thinking about :)

12:54 isn't it the case that cljs.core.PersistentVector/EMPTY would correspond to a static field in java land, i.e. interop? And there are no static fields in javascript so that kind of interop form should maybe not even exist in ClojureScript?

12:56 dnolen: jonasen: you might want to refer directly to cljs.core.PersistentHashMap/EMPTY in CLJS - it's useful.

12:56 jonasen: usful - maybe, but misleading?

12:57 dnolen: jonasen: how?

12:57 jonasen: dnolen: In clojure that would be considered an interop form only

12:58 Bronsa: or a namespaced var

12:58 *symbol

12:58 jonasen: dnolen: if PersistentHashMap is implemented in pure clojurescript, why not simply a empty-persistent-hashmap form?

12:58 empty-persistent-hashmap var I mean..

13:00 dnolen: jonasen: Clojure interop forms are valid Clojure forms. at this point I think water under the bridge.

13:01 jonasen: I see little advantage to empty-persisistent-vector, persistent-vector-from-arrays etc.

13:03 solussd_: is it possible to add a static field to a record?

13:08 dnolen: jonasen: I have no definitive answers but this is how it was done. Changing it now seems like churn with little gain.

13:09 solussd_: no - but then again only ClojureScript has to core data structures actually written in Clojure.

13:11 jonasen: dnolen: My point is that java.lang.Math/PI means something specific in clojure land (interop to _static_ methods and fields). Such things are not necessary in javascript interop

13:12 so why not (.-EMPTY cljs.core.PersistentHashMap)

13:13 dnolen: jonasen: I don't see how we can guarantee that work on all hosts.

13:13 jonasen: the (set! cljs.core.PersistentHashMap/EMPTY ...) stuff is already suspect.

13:15 jonasen: likely we'll need some kind of static field construct that the compiler actually understands. in anycase, this probably something that needs wider discussion on dev ML - it's not something I'm clear on myself.

13:15 jonasen: dnolen: ok. More hammock time :)

13:15 hiredman: static fields for deftypes would be nice

13:17 and almost required for bootstrapping purposes

13:17 solussd_: dnolen: So I have some static data 'about' a record- any suggestions for a proper place to put it? specifically, I have records that implement a Version protocol and each record type needs to know its "version-prefix", which I wanted to be a static field on each record type, so I could ask a record type what its "version-prefix" is.

13:18 dnolen: solussd_: I think this conversation revealed that I have no suggestions :)

13:18 hiredman: solussd_: that's a def

13:20 dnolen: hiredman: jonasen: yes this conversation is definitely worthy of Confluence page and ML discussion. Seems useful for both Clojure JVM, and necessary to make cljs.core more portable.

13:20 jonasen: dnolen: In general, since you have implemented the collections in pure clojure(script) stuff like static fields shouldn't be necessary

13:30 dnolen: jonasen: perhaps - tho again I'm not sure polluting core.cljs with a bunch of deftype implementation specific top-levels is a gain.

14:20 kmicu: OutOfMemoryError GC overhead limit exceeded clojure.core/filter (core.clj:2463) :(

14:23 If anyone knows the optimal algorithm for counting inversions in vector?

14:24 gtrak: what is gvec.clj?

14:27 jonasen: gtrak: from the source " generic vector implementation for vectors of primitives"

14:29 gtrak: that sounds pretty neat

14:30 are the normal data-structures used too far down to be rewritten in clojure?

14:31 I guess you need like a self-hosting compiler to make that work

14:34 maybe to build a clojure-in-clojure you need to rely on initial class-gen from an older clojure

14:35 dnolen: gtrak: i take it you haven't been following CLJS closely.

14:35 * nDuff is vaguely surprised that he needs to do casting himself when calling a Clojure function hinted as expecting a Long with an Integer.

14:35 gtrak: dnolen: bits and pieces

14:35 I know that testing clj-in-clj was an intent of cljs

14:36 on top of protocols

14:36 dnolen: gtrak: gvec.clj was a proof of concept - CLJS takes it further. deftype & protocols were required to make the datastructures implementable in Clojure itself.

14:37 gtrak: ah, gotcha, very curious indeed :-)

15:24 uvtc: Hi #clojure. Yesterday some of us were discussing how we might make 3rd-party Clojure library docs available online (either via clojars.org, clojuredocs.org, or someplace else).

15:25 I came up with something very simple.

15:25 ohpauleez: "doc strings"

15:25 :)

15:25 uvtc: Here's a temporary demo: http://www.unexpected-vortices.com/temp/clojure-libs-doc/index.html

15:26 It requires that a project have its own "doc" directory. And I only know of 2 at the moment. So that's why there's only 2 entries in the Contents of that page.

15:26 But if anyone wants to add a doc dir to their lib, and follow the link to the "notify us" page, I'll add it.

15:26 (well, and if they want to write at least a doc/index.md file)

15:27 ohpauleez, this would be separate from docstrings.

15:27 ohpauleez: For sure, it looks solid

15:27 uvtc: technomancy, xeqi, dakrone ^^

15:28 ohpauleez, thanks.

15:30 tmciver: uvtc: is this intended to be an analogue of github's README.md? So you could just drop your README.md in the doc dir?

15:30 uvtc: tmciver, You could do that, yes. Though, this system requires that at least one file in doc is named "index.md".

15:31 You might also shorten the readme and move some or most of its content into a doc/index.md file.

15:32 I think I like the idea of a shorter readme, with more detailed documentation shifted to docs in a doc directory.

15:33 The way github works now, it's tempting to jam everything into your README.md.

15:35 tmciver: uvtc: this could be a nice idea but I don't think a lot of people are going to be in a hurry to duplicate documentation.

15:36 uvtc: tmciver, duplicate?

15:36 tmciver: uvtc: well the README is going to be a subset of what's in doc/index.md.

15:37 uvtc: personally I think I'd rather jam everything into the README. :)

15:37 uvtc: the function docstrings should take up the rest of the slack.

15:37 uvtc: and marginalia could be used to make something pretty from them.

15:38 imho

15:38 uvtc: tmciver, Yes, I very much like marginalia and the other autodoc-style tools. And I think it might be nice to use their output with github's "pages" feature.

15:45 Hm. Makes me wonder. Maybe I should instead use the existing README.md as the index.md...

15:46 nDuff: Blerg.

15:46 uvtc: Blerg?

15:46 jcromartie: so is Clojure still too heavy for Android?

15:47 * nDuff keeps forgetting the less-awful way to do (into {} (map #(vector [(get-key %) (get-value %)] inputs))

15:48 S11001001: ,(doc juxt) ; nDuff

15:48 clojurebot: "([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"

15:48 S11001001: or something, some parens right there?

15:50 nDuff: S11001001: Hmm; I thought there was a way to build a map without generating intermediate vectors for the k/v pairs...

15:50 S11001001: I imagine zipmap just generates intermediate vectors

15:50 llasram: nDuff: With reduce?

15:50 S11001001: anyway, a list of two-tuples is no more expensive than two lists of same length

15:50 gtrak: (doc 'map-entry)

15:50 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol>

15:50 nDuff: hmm; apply array-map looks like it does the trick

15:51 Vinzent: nDuff, zipmap?

15:53 gtrak: https://github.com/flatland/useful/blob/develop/src/useful/map.clj just creates clojure.lang.MapEntry instances, maybe that's faster?

15:53 mk: how do changes to inter-dependent identities work?

15:53 nDuff: Vinzent: That works; graci.

15:54 mk: suppose I have a string, "abcd", and an index position of 3 (between c and d).

15:54 if I change the string atom, deleting the b, I'd like the index atom to change to 2

15:55 what's the correct way to do this?

15:55 Vinzent: mk, maybe watchers could help

15:56 mk: unfamiliar with watchers

15:56 are they just listeners?

15:57 uvtc: tmciver, thanks for the feedback. Will change to use the readme as the main doc landing page.

15:57 thanks, dakrone, for the offline help

15:57 nDuff: ...hrm; putting (#(map str %)) halfway through a long -> pipeline is kinda' icky.

15:58 Vinzent: mk, yeah

15:59 mk: do watchers operate on state value?

15:59 Vinzent: nDuff, you can use (-> a (->> (map f))) instead

15:59 mk, what do you mean?

15:59 mk: (I'm trying to look up docs on watchers)

15:59 nDuff: Vinzent: ...ahh; much nicer. Thanks!

16:00 tmciver: uvtc: sure. I'm not saying a doc dir isn't a good idea, but maybe you could fallback to the README when the doc dir is missing.

16:00 mk: Vinzent: err, maybe explaining another problem will help

16:00 uvtc: tmciver: ✓

16:00 mk: suppose you have two positions marked by pipes: ab|c|de, in the string "abcde"

16:01 I now delete bcd, leaving (presumably) a||e

16:01 the problem is that if I want to undo the change, I can't simply operate on the string atom

16:02 I have to alter the two position atoms - but in different ways

16:02 Vinzent: nDuff, I've peeped it in the kotka.de blog :)

16:02 mk: their values are presently identical, so I have to somehow keep track of their previous states. If I inject bcd back into the middle of ae, I want neither a||bcde nor abcd||e

16:03 Vinzent: mk, just keeping log of operations is a no way?

16:04 mk: well, it would be complicated because I would have to keep a log of "position movement" operations, and I'd like the "string atom" manipulation to be ignorant of what happens to the positions

16:05 a log of deltas is simple enough for the string itself: delete 1 to 4 (inverse is: insert bcd at 1)

16:07 giving each position a similar history seems incorrect

16:07 Vinzent: hm, why not save the cursor and mark positions too?

16:07 mk: (I'm unsure if I'm explaining this clearly)

16:08 Vinzent: what do you mean?

16:08 Vinzent: I mean in the string's log

16:08 delete 1 to 4, cursor was at 2

16:10 by the way, are you writing an emacs clone in clojure or what? :)

16:10 mk: there might be a multitude of cursors/carets/positions (regex find, for example), and it seems strange to mix the two histories

16:11 Vinzent: something like that. Mostly just playing around with understanding how identity works in various cases. I'm a fan of how clojure distinguishes values and identities, but certain things become much more complicated

16:12 wink: hm, what's the most idiomatic way to put let/if-let/when-let into each other? one outer let and if inside, or try with some if-let...

16:13 Vinzent: I probably don't understand then... By what rule you want to determine the cursor position after an undo? I thought cursor position should be restored to whatever it was before deletion and mark should stay the same

16:13 ohpauleez: wink: can you use `and`?

16:13 mk: Vinzent: define mark?

16:14 Vinzent: that thing which got swapped with cursor position when you're hitting C-x C-x

16:14 wink: ohpauleez: there's one "or" right now

16:15 kovasb: unless the strings are huge, why store the edit histories rather than the old strings themselves

16:16 ohpauleez: wink: can you paste/gist an example? More than happy to help

16:16 mk: Vinzent: well, the point and mark (if I have my terms right) would probably be aPbcdMe, and the operation deletes everything between point and mark. There are also two positions or cursors between the point and mark: ab|c|de

16:17 ohpauleez: kovasb: - are you coming tonight? I was digging through session the other night and I wanted to pick your brain about an idea

16:17 kovasb: yup! will b there

16:17 ohpauleez: Awesome

16:17 kovasb: sounds good. apologies for the ugly source

16:17 ;)

16:18 ohpauleez: haha, no worries, I made it through. Also, Shoreleave is a train wreck to read right now

16:18 kovasb: lol

16:18 wink: ohpauleez: https://www.refheap.com/paste/3263

16:18 mk: if I don't have to worry about positions, I think that I can handle things easily - I mark each insert operation as either before or after the cursor (this corresponds to backspace vs delete)

16:19 kovasb: sometimes you just gotta write one to throw away

16:19 wink: I mean, I can get it to work with almost every combo, but how it is nice and short? :)

16:19 ohpauleez: wink: I got this, hang on

16:19 mk: (undoing a delete inserts the characters after the cursor, undoing a backspace, before)

16:21 this might be making things a bit more concrete - the general problem is how state changes work when some identities (atoms) depend on others

16:21 kovasb: yes, that is a big problem

16:22 "top people are working on it"

16:22 http://www.youtube.com/watch?v=q6-rQ6Jay6w

16:23 ohpauleez: wink: https://www.refheap.com/paste/3265

16:23 one line

16:23 Vinzent: mk, oh, so it's like registers, got it (wrongly interpreted the term "cursor").

16:23 wink: ohpauleez: oh, thanks

16:23 ohpauleez: np!

16:24 wink: clever use of -> I must say.

16:24 ohpauleez: wink: Maps and keywords rock

16:24 wink: happy enough to not wonder wtf is going on :)

16:25 ohpauleez: wink: You could also just drop the let completely

16:25 Vinzent: mk, I think you can have one one Buffer record with fields :text, :point, :mark, :registers in an atom and some protocol for operations, so you could define delete, backspase, killing region, etc

16:26 bigbob38: hi all. I'm trying to use xuggle from clojure, and basically wanted to port this: http://goo.gl/evyZw so far I've nly come up with this monstrosity of a function, which is basically a line-for-line translation from java: https://gist.github.com/2961994

16:26 anyone have any tips as to how I might start refacoring this? I'm kind of new at java interop

16:27 pipeline: i'm no pro at interop either

16:27 but

16:27 the function you wrote has a lot of side effects anyway

16:27 and is calling into java code that is effectively imperative

16:27 i don't know that there necessarily exists an elegant way to do this

16:28 mk: Vinzent: perhaps, but I'm not sure how that would... work

16:28 bigbob38: ok that makes me feel a little better at least, that I'm not missing something major

16:28 Vinzent: also, I'm not sure now why to worry about registers at all... You can just check if register's position are greater than the buffer length's and jump to max position then. Does it makes sense?

16:29 mk, hey, what about collaborating on this idea?

16:30 mk: Vinzent: perhaps I misunderstand registers then. Perhaps thinking of them as footnote positions, or comment positions, etc.?

16:30 Vinzent: aren't we already? :)

16:31 notbrent: guys: what book would you recommend for a clojure beginner coming from a ruby/js background?

16:31 or gals ;)

16:32 bigbob38: joy of clojure is pretty good

16:32 cgag: clojure programming is solid

16:32 mhanson: I'm reading Joy of Clojure right now, and it's fantastic so far.

16:32 Vinzent: bigbob38, first thought: you can write (if x ...) instead of (if (not (nil? x)) ...)

16:32 notbrent: two votes for joy of clojure!

16:32 mk: I've heard good things about that newer book

16:32 mhanson: I'm a Rubyist mostly, with little Lisp experience.

16:32 ohpauleez: Joy of Clojure is one of my favorite books

16:32 to date

16:33 notbrent: has anyone read russ olson's ruby books, eg eloquent ruby, and enjoyed them?

16:33 mk: I've forgotten the name now - clojure programming? I've heard it was better than JoC

16:33 notbrent: those were my favorite rubybooks

16:34 Vinzent: mk, yeah, probably something like that... By "collaborating" I meant creating a github project, etc :)

16:34 mk: notbrent: you might consider searching the channel logs

16:34 cgag: I really like it, and i think it'd be more helpful for someone without much lisp experience

16:34 notbrent: mk: good idea

16:34 ohpauleez: mk, Joy of Clojure is definitely targeted at readers who are already familiar with Clojure and are settling in

16:34 it answers a lot of "when" and "why" not "what"

16:35 why is X in the language, and when should I use it over something else

16:35 Wild_Cat: so JoC is more about the ecosystem and best practices than about the language itself?

16:35 mk: Vinzent: oh, I have nothing that concrete at the moment :) though I wouldn't mind

16:36 ohpauleez: Wild_Cat: I would say it very much covers the language, but it's not a guide to learn a lisp or help you bend your brain into functional programming approaches

16:36 Also, reading the ClojureScript source is an awesome way to gain a lot of Clojure knowledge

16:36 bigbob38: Vinzent: thanks! missed that, I copied that part right from stackoverflow heh

16:37 ohpauleez: And as stated a few days ago. Reading the Ring source is amazing

16:38 mhanson: I'm reading SICP at the same time I'm reading JoC to help fill in my missing functional/Lisp knowledge.

16:38 ohpauleez: mhanson: That's a great idea and approach

16:38 follow that up with a read of On Lisp and you'll be a pro

16:38 mk: the state-changing problem I'm talking about is pretty generic. It also applies to alterations to a program. The repl often replaces functions, and it would be interesting to see how undo (especially partial undo) works there

16:39 dgrnbrg: hello clojurians, i am seeing some really weird behavior in my clojure environment. I am launching clojure with a complex proprietary jvm runner, and somehow clojure.core/int is broken. I get (= java.lang.Long (class (int 3))), whereas in normal clojure environments (int 3) should return a java.lang.Integer

16:40 mk: ,(class (int 3))

16:40 clojurebot: java.lang.Integer

16:40 Vinzent: mk, actually, I just want to write an org-mode like todo-manager, but hadn't have enough courage to start :) Do you have jabber or something?

16:40 dgrnbrg, it depends on the clojure version afaik

16:41 mk: dgrnbrg: perhaps the runner replaces all ints with longs?

16:41 Vinzent: dgrnbrg, it gives me long too on 1.3

16:41 dgrnbrg: i'm using 1.3

16:41 borkdude: ,(class (int 3))

16:41 clojurebot: java.lang.Integer

16:41 borkdude: &(class (int 3))

16:41 lazybot: ⇒ java.lang.Integer

16:41 Vinzent: ,*clojure-version*

16:41 dgrnbrg: ,(identity *clojure-version*)

16:41 clojurebot: {:interim true, :major 1, :minor 4, :incremental 0, :qualifier "master"}

16:41 {:interim true, :major 1, :minor 4, :incremental 0, :qualifier "master"}

16:41 borkdude: &(clojure-version)

16:41 lazybot: ⇒ "1.4.0"

16:42 dgrnbrg: hmm

16:42 well, that doesn't help much, heh

16:42 borkdude: on 1.3 it gives me long as well

16:42 dgrnbrg: if (int 3) gives a long, how can I coerce to an int?

16:43 maybe I should try upgrading to 1.4

16:43 Vinzent: that's exactly what I wanted to say :)

16:43 mk: Vinzent: start a project on github and I'll follow, but I can't tell if I can much time (for even my own projects)

16:43 dgrnbrg: how can I exclude clojure 1.3 from every plugin ni my dependencies?

16:44 i have 20-30 plugins, and i don't know who is pulling me back to 1.3

16:44 ohpauleez: dgrnbrg: [vimclojure/server "2.3.3" :exclusions [org.clojure/clojure]]

16:44 using exclusions, but if your project depends on 1.4, it'll use 1.4

16:44 dgrnbrg: i have [org.clojure/clojure "1.4.0"] as the first dependency

16:44 but it seems to be using 1.3 anyway

16:45 ohpauleez: bizzaro

16:45 dgrnbrg: i have to integrate w/ a lot of legacy code

16:45 which is actually kind of awesome that things work at all

16:45 ystael: if (class (int 3)) is java.lang.Long in 1.3, does that necessarily mean that the result of (int 3) is a native long, or merely that the result of (int 3) boxes to a Long?

16:47 llasram: ystael: My understanding is the latter. `int` calls RT.intCast, which returns an int. That int then just get boxed to a Long

16:47 raek: ystael: the latter

16:48 llasram: dgrnbrg: Do you need an int or an Integer? If you need the former, you can always construct it explicitly

16:48 dgrnbrg: llasram: i need Integer--I'll give that a shot

16:48 you mean like Integer/valueOf?

16:49 cemerick: You should *always* construct an Integer if you actually want an integer.

16:49 dgrnbrg: cemerick: why does (int) exist then?

16:49 aperiodic: java interop?

16:50 cemerick: yeah, it's a coercion operator

16:50 (int …), (long …), et al. should be reserved for interop

16:50 dgrnbrg: i am doing interop, though

16:50 i thought

16:50 does clojure not use java's boxing rules?

16:50 i.e. short int long all box to Long?

16:51 cemerick: dgrnbrg: in 1.3, yes; that was fixed in 1.4 IIRC

16:51 llasram: dgrnbrg: Right, exactly (re: Integer/valueOf)

16:51 dgrnbrg: got it, thanks

16:51 ystael: dgrnbrg: lein deps :tree is handy for debugging dependency mysteries

16:51 dgrnbrg: if only i was just using leiningen

16:52 i have modified eval-in-subprocess to do…special things to play nicely in my environment

16:53 and lein deps doesn't work for me either

16:53 Vinzent: mk, well I don't have any code\time yet too - I just wish to discuss design problems such as the one you've raised. About functions: I have no idea how it's implemented in emacs, but the first thing coming to mind is to intercept redefenitions and just save previous versions in the var's meta

16:53 dgrnbrg: so i use a 2ndary project to create an uberjar, then i use a lein plugin i wrote to mix that uberjar into my proprietary blend

16:59 mk: Vinzent: that might work, though it might get messy if... suppose you want an "area" revert/undo, where only the changes to the function/paragraph are undone, as well as a global, as well as snapshot saving (and "area" snapshots)

17:00 I think these things are rather complicated at the moment for me, but very interesting

17:01 I've also been thinking of "revision levels" in programs - how certain parts of a program are locked down, and how this lockdown is the only thing that distinguishes source from program from data

17:03 in most languages, the only thing you can alter is the data that the program works with, and there are various methods of revision (assignment, instantiation)

17:03 Vinzent: mk, if I understand correctly, the area undo would work the same: you just need to compute what functions are affected by changes in that area

17:05 mk: but some languages (clojure, languages with an eval) give the programmer methods of revising the data of the program itself

17:07 Vinzent: right (areas are just... ranges, or substrings, in this case) but this is potentially problematic if areas overlap (as when merge conflicts occur). I suppose with clearly-defined "areas" like functions, this might be less of a problem...

17:08 brehaut: eval is ussually not the tool you are looking for

17:08 Vinzent: yeah, and not all languages with eval support this kind of dynamism in the development process (like slime does)

17:08 brehaut: partial application is a better tool for generating new functions at runtime

17:09 Vinzent: mk, hmm, how could they overlap? Undos\revers are sequential, no?

17:09 brehaut, I think he's rather talking about development process

17:10 mk: brehaut: right. But the interesting thing is that eval is basically a compiler, so even taking into account the fact that the way a program edits itself and the way a human edits a program should be different, perhaps that says something about compilers and source code. Also, the repl is essentially an eval, no?

17:10 brehaut: its not basically a compile. it is a compile

17:11 and only the 'e' of repl is an eval

17:12 mk: brehaut: yes, but the r, p, and l might as well be silent

17:13 brehaut: err

17:15 mk: Vinzent: usually they are sequential, but if I edit a first paragraph, then the second, then merge paragraphs, then perform a few edits, and then I want to undo the first edit... then it's complicated. I think someone was working on this - right, the "patch theory" for darcs. http://www.math.ucla.edu/~jjacobson/patch-theory/

17:16 brehaut: there's nothing substantial when it comes to "read" and "print" - I guess they indicate where the input comes from and where the output goes

17:19 Vinzent: I think the solution to the original problem might actually be to just track a history of changes. I think that the "elegant" alternative that I suspected existed is just to replay the whole edit history from revision 0

17:21 Vinzent: mk, by the way, reading and printing are substantial - lisp's eval works with datastructures, not with raw text

17:22 uvtc: Ok, a project's README.md is now its landing page at http://www.unexpected-vortices.com/temp/clojure-libs-doc/index.html . However, I don't see any use in having docs there for a project with only a readme, since you could just see the readme at github for that.

17:23 technomancy, ^^ (wait TeXnomancy?)

17:23 TeXnomancy: hehe

17:23 uvtc: There is a TeXpert in the house.

17:23 TeXnomancy: my bouncer is acting up, so I'm shadowing myself

17:24 mk: Vinzent: right, the implementation, yes

17:24 TeXnomancy: I am actually not that good at TeX

17:24 brehaut: I think the secret to TeX is just rerunning the latex command over an unchanged document until it looks like what you expect

17:24 uvtc: The first thing a trained TeXpert is conditioned to say is that they're not very good at TeX --- otherwise everyone asks them to help them with "just one minor thing"...

17:25 TeXnomancy: I did my clojurewest presentation in latex but I probably won't do it again

17:25 earned that nerd merit badge, moving on

17:25 brehaut: TeXnomancy: next up: write it all in factor

17:26 TeXnomancy: brehaut: my conj one was elisp

17:26 brehaut: that wins.

17:26 uvtc: TeXnomancy : after discussing Clojure lib docs yesterday, this is what I came up with: http://www.unexpected-vortices.com/temp/clojure-libs-doc/index.html .

17:27 TeXnomancy: uvtc: looks like a great start

17:27 uvtc: Needs more projects with docs so that they can be included though.

17:27 TeXnomancy: submitting pull requests to get your project added to that list would be a cool way to go

17:27 uvtc: Leiningen's got a pile of doc/*.md files

17:28 uvtc: TeXnomancy, leiningen added!

17:29 TeXnomancy: cool

17:30 solussd_: can protocol functions be optional? afaict I can neglect to implement some of a protocol

17:30 dabd: i am using clojure jack in to start swank server. If I add a dependency to project.clj is there a way to avoid having to restart REPL after running lein deps?

17:31 TeXnomancy: uvtc: any further plans before you announce it?

17:31 dabd: nothing yet unfortunately

17:32 uvtc: I wanted to show it off here before asking about hosting on clojuredocs.org.

17:32 TeXnomancy: uvtc: maybe a table of contents as a sidebar?

17:32 instead of having to hit up "all of this lib's docs"

17:33 uvtc: TeXnomancy, also, it would be nice to get some more projects listed.

17:33 TeXnomancy: and I'm not sure about the word "lib", it's a bit loaded. "project" is probably better?

17:33 and maybe the link text in the toc should be the first h1 in the md file

17:34 guess I need to switch from ```clj to ```clojure

17:35 uvtc: TeXnomancy, thanks for the feedback. I need to go right now, but will get back to this.

17:35 TeXnomancy: excited to finally see a documentation effort designed to unify rather than start their own thing

17:50 dabd: I added [incanter "1.3.0" :exclusions [swank-clojure]] to my dependencies but got the following error: Could not find artifact org.mongodb:mongo-java-driver:pom:2.6.5 in clojars (https://clojars.org/repo/)

17:50 Failed to collect dependencies for clojure.lang.LazySeq@2af2b9aa

17:50 Is 1.3.0 the correct version for incanter?

17:55 ezyang: How does Clojure find out about Java classes which it needs to create new classes of?

17:56 (via it's compilation process in clojure.lang.Compiler)

17:59 KirinDave: Is slingshot… supposed to work?

17:59 As according to its readme?

17:59 Becuase throw+ works, but catch+ seems to be failing to catch...

18:00 hiredman: (try+ is what you want, is there a catch+?

18:01 mebaran151: I don't think it uses catch+; it just rewrites catch clauses

18:01 KirinDave: Sorry

18:01 mebaran151: a catch inside try catch is just magically enabled to be smarter

18:01 KirinDave: yeah

18:02 (try+ … (catch [:type :ramuh.data.job/invalid-input] …)) never catches

18:02 However if I catch all exceptions and print it out, it shows: clojure.lang.ExceptionInfo: throw+: [:type :ramuh.data.job/invalid-input ...]

18:03 So clearly throw+ is doing its job. I am just failing to catch.

18:04 raek: KirinDave: are you re-throw+-ing the exception in the catch body?

18:04 KirinDave: No.

18:05 I want to handle it.

18:05 dakrone: KirinDave: (catch [:type :foo] ...) would catch something like (throw+ {:type :foo}), are you throwing a map or a vector?

18:05 raek: and the thing you throw looks like {:type :ramuh.data.job/invalid-input, ...}, right?

18:05 KirinDave: Ah, in one case I accidentally throw a vector becuase the object I throw is constructed over the run.

18:06 * TeXnomancy kinda wishes slingshot had stuck with just throwing maps

18:06 KirinDave: Wasn't (into {} my-constructed-thing) in one path

18:06 raek: (I had this problem recently: https://github.com/scgilardi/slingshot/issues/25)

18:06 KirinDave: That's lame

18:06 Why can I throw a vector?

18:06 And then render it uncatchable?

18:06 TeXnomancy: KirinDave: "it's more general"?

18:06 dakrone: KirinDave: because you could do (catch vector? v ...)

18:06 KirinDave: Yeah but if you cannot catch it...

18:06 hiredman: it is actually still catchable

18:06 KirinDave: Oh

18:06 TeXnomancy: you can still catch it; catch can be given an arbitrary predicate

18:06 KirinDave: Interesting.

18:06 Not sure I agree with the idea, but interesting.

18:07 If we're going to give up on Common Lisp error handling (i.e., the awesome way), then it seems weird to try and fancy it up.

18:07 TeXnomancy: I'm not sure how awesome the awesome way is if you don't have everyone on board.

18:08 ohpauleez: it's still pretty f'in awesome

18:08 haha

18:08 But you can't get correct interop

18:08 KirinDave: Yeah

18:08 ohpauleez: which is a total shame

18:08 KirinDave: That it won't work right with interop isn't necessarily a reason to ditch it.

18:08 It's not not a reason, I guess. :)

18:09 TeXnomancy: So I made good on what I said. We're entirely phasing out Scala now.

18:09 TeXnomancy: mwahaha

18:09 KirinDave: No one besides me could code with it anyways...

18:09 TeXnomancy: I guess that probably made the decision easier =)

18:09 KirinDave: Yeah well there is a new super-smart kid from MIT here

18:10 and he was like, "Lisp? We could code in Lisp? Okay yea i am on board."

18:10 Then proceeded to stay up for 2 days straight bootstrapping some stuff into Storm.

18:10 TeXnomancy: haha; go MIT

18:10 KirinDave: Then I pretended to be all upset while winking heavily and sighed to my team and said, "I guess we'll go with this. Shame to the enthusiasm of youth."

18:10 And no one could bitch at me for trying another language pivot on the shop.

18:11 TeXnomancy: strategic.

18:11 KirinDave: Strategery

18:11 Yeah well sometimes to make a good thing tasty one must consider the source.

18:14 TeXnomancy: KirinDave: is your pipeline by any chance final-fantasy-themed?

18:15 KirinDave: TeXnomancy: It is actually a rule.

18:15 TeXnomancy: Fenix, Ramuh, Alexandr are already in use.

18:15 Whyt too

18:15 The only NON-FF-summons component is a project that was a one-off that grew into production, which is our storm topology repo bergenholm.

18:16 TeXnomancy: It's how we differentiate Clojure services from non-Clojure services; no one else but us can spell them.

18:17 TeXnomancy: I would like to draw your attention to https://github.com/technomancy/lein-play and the fact that you can make the final fantasy victory fanfare play when the tests succeed; that is all.

18:17 KirinDave: Amazing

18:17 I can do this.

18:17 Lein2 compatible?

18:18 TeXnomancy: I think you should be good if you use :plugins rather than :dev-dependencies

18:18 if not let me know; I can make it happen

18:18 KirinDave: Okay

18:18 I actually have a really nice orchestratic version

18:20 TeXnomancy: Gotta be mp3?

18:21 TeXnomancy: KirinDave: looks like that's the only thing this lib supports. probably wouldn't be hard to find another audio engine.

18:27 dabd: where did 'positions' from clojure.contrib.seq go in 1.4.0?

18:28 muhoo: TeXnomancy: moved to the lone star state, have ya?

18:28 KirinDave: TeXnomancy: Can't get it to fly, lein1 or lein2

18:28 Oh well

18:29 TeXnomancy: KirinDave: can you open an issue so I'll remember to get back to it?

18:29 KirinDave: TeXnomancy: Sure. Maybe it's just classpath woes

18:29 "Put X on your classpath" is sort of like saying, "Please feel free to argue with the jvm for 20 minutes."

18:30 TeXnomancy: oh yeah, this was from back when lein and the project had their classpaths overlap

18:30 and probably the fact that lein-play is added to lein's classpath dynamically confuses it

18:33 muhoo: cemerick: what should :login-failure-handler return? a ring response?

18:33 mebaran151: dabd: how about (fn [pred s] (map second (filter (comp pred first) (map vector s (range))))) for the same functionality?

18:35 muhoo: cemerick: because, in openid/handle-return, if login-failure-handler returns a ring map, then workflow will consider that success and pass it up to authenticate* as an auth map

19:17 brainproxy: suppose I want to dynamically create a File that, say, enlive will think is a proper file an fill it with, say, the return of (hiccup/html ...)

19:17 is (as-file ...) a good place to start

19:17 ?

19:22 antoineB: hello i would like to take the last digit of a number?

19:23 ,(last (str 123))

19:23 clojurebot: \3

19:24 brehaut: ,(mod 123 10)

19:24 clojurebot: 3

19:25 brehaut: or, if you wish to have it as a char

19:25 ,(char (+ (mod 1234 10) (int \0)))

19:25 clojurebot: \4

19:26 antoineB: i just want to check that last digit of two number are different

19:26 brehaut: antoineB: using last will cause a seq over your string to be created and then walked in its entirity.

19:26 ,(not= (mod 1234 10) (mod 1235 10))

19:26 clojurebot: true

19:28 brehaut: or, if you abhore the repeatition

19:28 ,(apply not= (map #(mod % 10) [1234 2345]))

19:28 clojurebot: true

19:28 antoineB: ok

19:38 wmealing: I'm having a problem with java interop, not being a java programmer makes it somewhat harder, i'm wondering if someone could take a look at https://github.com/wmealing/soundlevel/blob/master/src/soundlevel/core.clj and tell me why i'm failing.

19:38 I think its in mixer-supports-recording

19:41 xeqi: &(.getClass String)

19:41 lazybot: ⇒ java.lang.Class

19:41 xeqi: wmealing: TargetDataLine is already a class (line 8)

19:41 wmealing: ok, so (Line$Info. TargetDataLine))

19:42 smooth ok

19:42 so now i have some mixers that can record

19:43 which is.. more what i expected

19:43 thankyou.

19:45 OwenOu: hi guys, i would love to read clojure's source code, but not sure where to start, could anyone give me a pointer?

19:45 appreciate any suggestions :)

19:46 S11001001: core.clj

19:46 it is the standard lib, the part written in clojure anyhow

19:46 brehaut: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj

19:47 OwenOu: the easiest way to get started is with the 'source' function in your repl

19:47 S11001001: from there, you'll see many references to the java bits; take a look at those references as they interest you

19:47 brehaut: ,(source source)

19:47 clojurebot: Source not found

19:47 S11001001: does source include comments?

19:47 TeXnomancy: don't look too closely at the java though

19:47 brehaut: ok so the bot hates it

19:48 xeqi: &(clojure.repl/source source)

19:48 lazybot: ⇒ Source not found nil

19:48 OwenOu: brehaut: thanks, but what would u recommend the starting point on the java side?

19:48 brehaut: S11001001: does the orriginal code include sources :P

19:48 err comments

19:48 OwenOu: i guess my question is i would love to know how the language is implemented on top of macro

19:48 brehaut: if you havent dived into the clojure side yet, you probably arent ready for the java side

19:49 S11001001: yep, and something of a narrative in its ordering too

19:49 brehaut: OwenOu: form is read by the read -> (macro expansion * repeat as necessary) -> compiler

19:50 S11001001: like, there are multiple impls of some bits, as more stuff gets bootstrapped

19:50 brehaut: S11001001: i think its better to get started with functions you know in isolation

19:50 starting at the top of core.clj and working your way down is diving into the very deep end

19:51 OwenOu: you'll probably find it more enlightening to play around with macroexpand and macroexpand-1 in a repl than by diving deep into the compiler

19:52 S11001001: start at bottom then

19:52 into is down there I think

19:52 OwenOu: brehaut: i see, thanks for the recommendation, i would also be interested to know how the expanded macros are compiled to bytecodes

19:53 brehaut: S11001001: so why not just start with source?

19:53 S11001001: frinstance, heres the sole comment before destructure ";redefine let and loop with destructuring"

19:53 S11001001: it's still a narrative to start at bottom

19:53 yeah, that's neat

19:53 brehaut: followed by 60 lines of uncommented code

19:54 S11001001: just the sort of interesting bits that vanish with tools

19:54 brehaut: S11001001: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L3905-3965

19:54 what interesting bit vanishes with tools there?

19:54 S11001001: that very comment

19:55 brehaut: that comment gives you basiclly no information about how destructure works

19:55 S11001001: you referenced a comment that, in itself, is a perfect demonstration of the value of perusing core.clj directly

19:55 it refers to "redefine"

19:55 well, what is that?

19:55 it's intriguing to first encounter

19:55 brehaut: nowhere in destructure does let get redefined

19:56 S11001001: why is that relevant?

19:57 it's the comment that hints at something deeper, not the code, in this instance

19:57 brehaut: because thats all the comment says. if you are a newb, wanting to get started reading the source, it doesnt matter that destructure is used later. of course its used later. you want to understand one function at a time, and that comment is not at all elucidating about destructure

19:57 BrianG: hi

19:58 S11001001: yes, and as a clojure newbie, I would have preferred not to be so boxed in, one function at a time

20:03 antoineB: how to make an integer divide?

20:04 ok it is quot

20:05 gfredericks: $findfn 7 4 1

20:05 lazybot: [clojure.core/quot clojure.core/unchecked-divide-int clojure.core/compare]

20:06 TeXnomancy: heh, compare

20:07 gfredericks: $findfn 7 4 7/4

20:07 lazybot: [clojure.core//]

20:07 S11001001: how many functions does that try?

20:08 gfredericks: 7/4 functions

20:09 TimMc: S11001001: It's great for finding weird things like...

20:09 $findfn + 3 4 7

20:09 lazybot: [clojure.core/trampoline]

20:09 TimMc: I like that trampoline can be used as an almost-synonym for the nonexistent "call" fn.

20:09 amalloy: S11001001: all of clojure.core, clojure.string, clojure.set, and maybe one other

20:10 $findfn * 3 3

20:10 lazybot: [clojure.core/max-key clojure.core/cond clojure.core/dosync clojure.core/sync clojure.core/char-escape-string clojure.core/*data-readers* clojure.core/deliver clojure.core/with-loading-context clojure.core/default-data-readers clojure.core/*clojure-version* cloj... https://www.refheap.com/paste/3267

20:10 amalloy: huh. some of those make little sense. i was expecting deliver

20:11 TimMc: it's there

20:11 &(doc sync)

20:11 lazybot: ⇒ "Macro ([flags-ignored-for-now & body]); transaction-flags => TBD, pass nil for now Runs the exprs (in an implicit do) in a transaction that encompasses exprs and any nested calls. Starts a transaction if none is already running on this thread. Any uncaught exce... https://www.refheap.com/paste/3268

20:12 S11001001: IIRC it implements dosync, which is thin sugar

20:13 TimMc: Hrm, OK...

20:13 Indeed.

20:19 y3di: all you need is love... xD

20:32 * gfredericks goes to look for the "clojure.core//" exception in the clojure reader

20:33 TeXnomancy: gfredericks: it's under the "If your name is Rich [...]" section

20:34 gfredericks: TeXnomancy: some statements are equally plausible when interpreted seriously or jokingly

20:34 ah found it

20:34 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L311

20:35 faxinating

21:05 brooksbp: hello

21:05 new to clojure

21:05 how do I go about debugging this:

21:05 UnsupportedOperationException nth not supported on this type: Character clojure.lang.RT.nthFrom (RT.java:835)

21:08 tmciver: brooksbp: could you post the offending code to refheap.com?

21:08 zomg: brooksbp: based on the message I would say that you are attempting to use nth on a type which is not a list or such

21:08 S11001001: brooksbp: runtime or while loading

21:08 brooksbp: S11001001, runtime

21:09 S11001001: Look up the stack until your own code

21:09 brooksbp: Calling a function which calls a ton of other code, so no idea where it may be

21:09 I am not calling nth

21:09 But I am trying to do destructuring on a string... can't you do that?

21:10 Right, I was hoping for some way to step through the code. Is that possible?

21:10 S11001001: a little, but it's probably overkill. Just look for your code on the stack

21:10 then you'll know what you called that eventually bombed

21:11 brooksbp: there's no call stack

21:11 I mean, it wont print one

21:11 hiredman: ,(let [[[foo]] "foo"] )

21:11 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Character>

21:12 brooksbp: I apply the function to an arg in the repl, and that exception message prints

21:12 hiredman: ,(let [[foo] "foo"] foo)

21:12 clojurebot: \f

21:16 S11001001: brooksbp: use jack-in, or (try blah (catch Exception ex (.printStackTrace ex)))

21:17 maybe there is a shortcut for normal repl

21:18 amalloy: (.printStackTrace *e)

21:19 gfredericks: (pst), no?

21:22 brooksbp: (defn- myfun [arg1 [first-char & xs :as arg2]] ...func body...)

21:23 (myfun 1 "mystring")

21:23 how do you destructure the second arg?

21:23 S11001001: gfredericks: slimer for life :)

21:23 gfredericks: I don't think you can do that directly with strings

21:23 or sets

21:24 ,((fn [[a b]] [b a]) #{4 5})

21:24 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: PersistentHashSet>

21:24 gfredericks: ,((fn [[a b]] [b a]) "ha")

21:24 clojurebot: [\a \h]

21:24 gfredericks: oh works with strings

21:24 brooksbp: okay so what's your issue?

21:25 you say "how do you destructure the second arg?" but you appear to already be doing that

21:25 brooksbp: I am getting an exception when invoking that func... I must be passing it gibberish

21:25 Thought I was destructuring improperly

21:26 gfredericks: ,((fn [arg1 [first-char & xs :as arg2]] [arg1 first-char xs arg2]) :foo "bars")

21:26 clojurebot: [:foo \b (\a \r \s) "bars"]

21:33 brooksbp: Is it possible to use reduce with a line-seq?

21:33 (reduce fn [] (line-seq rdr))

21:33 I want to reduce fn over every line... but line-seq doesn't return a collection..? How to do..?

21:35 S11001001: Just try

21:35 gfredericks: line-seq doesn't return a collection?

21:35 S11001001: reduce, map, et al all take seqs, not just colls

21:36 ,(coll? (map identity '(42)))

21:36 clojurebot: true

21:36 S11001001: ugh

21:36 well whichever, it'll work

21:36 gfredericks: ,(->> 943 range (map inc) coll?)

21:36 clojurebot: true

21:36 gfredericks: ,(doc coll?)

21:36 clojurebot: "([x]); Returns true if x implements IPersistentCollection"

21:37 gfredericks: ,(coll? "coll?")

21:37 clojurebot: false

21:37 gfredericks: oh I guess that was obvious

21:37 S11001001: ,(reduce + 0 (map long "hi there")) ;hmm...

21:37 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number>

21:37 brooksbp: ok... I must paste the code... I am trying, but...

21:38 S11001001: pick a fun

21:38 brooksbp: https://www.refheap.com/paste/3270

21:38 I am calling parse-file

21:39 and the exception hits when invoking build-ir

21:39 S11001001: you should also paste full backtrace

21:39 brooksbp: oops... the vector brackets around (strip-line (line-seq rdr)) are not suppose to be there

21:39 S11001001: and, use map, you are giving seq to string function

21:40 brooksbp: (map strip-line (line-seq rdr)) ?

21:40 why map?

21:41 S11001001: you want the long answer or really long answer? ;)

21:41 brooksbp: really long answer

21:43 S11001001: okay, what is strip-line?

21:43 that is, what kind of arg does it take, and what does it return?

21:43 brooksbp: a function: string -> string

21:43 S11001001: okay, what does line-seq return?

21:44 wait, are you haskellian?

21:44 brooksbp: enough to know about currying

21:44 S11001001: ok, let's continue

21:44 line-seq is?

21:44 brooksbp: my issue is that i dont understand seqs

21:44 i dont know what line-seq is

21:44 looking up..

21:44 S11001001: let's pretend they are lists

21:45 line-seq is stream -> seq string

21:45 a seq of strings

21:45 brooksbp: ok so map is appropriate

21:45 S11001001: aye

21:45 brooksbp: but why doesn't the reduce work?

21:46 even if i do: (reduce build-ir [] (map strip-line (line-seq rdr)))

21:47 fails with an airity exception to build-ir

21:47 (defn- build-ir [ir [first-char & xs :as line]]

21:47 as far as i can tell, reduce passes build-ir 2 args... build-ir takes 2 args... second one is destructured

21:48 S11001001: paste trace?

21:48 brooksbp: doh.. wrong function

21:48 wkelly: brooksbp: your build-ir works fine for me

21:48 oh, too late

21:49 * brooksbp turns back to silently hacking away

21:50 S11001001: good luck

21:52 brooksbp: back again

21:52 is there a better way to do this: https://www.refheap.com/paste/3271

21:54 brehaut: brooksbp: what is ir, and what is it supposed to be doing?

21:55 gfredericks: spanish verb meaning "to go"

21:55 brooksbp: ir is a vector of maps

21:55 I want to pop off a map, conj to it... then put it back in the vector

21:56 gfredericks: ,(assoc-in [{} {} {} {} {} {}] [3 :foo :bar] :baz)

21:56 wkelly: brooksbp: assoc-in

21:56 clojurebot: [{} {} {} {:foo {:bar :baz}} {} ...]

21:56 brooksbp: [{:a 1 :b 2} {:c 3}] -> {:d 4} ===> [{:a 1 :b 2} {:c 3 :d 4}]

21:58 gfredericks: ,(let [ms [{:a 1 :b 2} {:c 3}]] (update-in m [1] merge {:d 4}))

21:58 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: m in this context, compiling:(NO_SOURCE_PATH:0)>

21:58 gfredericks: ,(let [ms [{:a 1 :b 2} {:c 3}]] (update-in ms [1] merge {:d 4}))

21:58 clojurebot: [{:a 1, :b 2} {:d 4, :c 3}]

22:00 gfredericks: ,(let [ms [{:a 1 :b 2} {:c 3}]] (-> ms pop (conj (-> ms peek (merge {:d 4})))))

22:00 clojurebot: [{:a 1, :b 2} {:d 4, :c 3}]

22:00 brooksbp: this is difficult to understand

22:01 gfredericks: more lets then

22:01 ,(let [ms [{:a 1 :b 2} {:c 3}], new-last (merge (last ms) {:d 4})] (conj (pop ms) new-last))

22:01 clojurebot: [{:a 1, :b 2} {:d 4, :c 3}]

22:01 brooksbp: still... just getting familiar with everything in the clojure cheat sheet

22:02 gfredericks: hmm

22:02 so pop will pull the last thing off a vector

22:02 conj will put something back on the end

22:02 thus the (conj (pop ms) new-last)

22:03 brooksbp: I get conj pop peek

22:03 but update-in

22:03 and merge

22:03 gfredericks: oh we didn't even use that in the last iteration

22:03 brooksbp: and these other map fns

22:03 gfredericks: merge isn't necessarily necessary; your requirements were a bit ambiguous

22:03 you can use assoc instead of merge probably

22:06 brooksbp: you have to specify a number as an index when you use update-in

22:06 gfredericks: right

22:06 so depending on what you have available that might be easy or hard

22:06 brooksbp: is there a way to do this, but always the last element in the vector?

22:06 gfredericks: yeah, use pop/peek/conj instead

22:06 brooksbp: :)

22:06 gfredericks: you could define an update-last helper function

22:07 (defn update-last [v f & args] (-> v pop (conj (apply f (peek v) args))))

22:07 brooksbp: is there a reason to merge two maps instead of conj'ing them?

22:08 gfredericks: ,(conj {:foo 4} {:bar 5})

22:08 clojurebot: {:bar 5, :foo 4}

22:08 gfredericks: ,(conj {:foo 4 :faz 38} {:bar 5 :bing 498})

22:08 clojurebot: {:bar 5, :bing 498, :foo 4, :faz 38}

22:08 gfredericks: I am baffled

22:08 brooksbp: ?

22:08 brehaut: merge is just a reduce of conj

22:08 gfredericks: I had no idea that worked

22:08 brooksbp: oh

22:08 I see what you mean

22:08 brehaut: conj on maps gets a seq from the second map, which returns a seq of keypairs

22:09 gfredericks: ,(conj {} [1 2])

22:09 clojurebot: {1 2}

22:09 gfredericks: ,(conj {} [[1 2]])

22:09 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Vector arg to map conj must be a pair>

22:09 brehaut: oh, my bad

22:09 gfredericks: there must be a special case for maps as second arg

22:09 brehaut: oh, it may be that its particular about wanting a MapEntry

22:10 gfredericks: well a bare pair is accepted

22:10 also a bear pear

22:10 brehaut: ,(conj {} [(clojure.lang.MapEntry. :a 1)])

22:10 brooksbp: ,(conj {}{})

22:10 clojurebot: {}

22:10 #<IllegalArgumentException java.lang.IllegalArgumentException: Vector arg to map conj must be a pair>

22:10 brooksbp: race!

22:11 brehaut: ,(conj {} [:a 1] [:b 2])

22:11 clojurebot: {:b 2, :a 1}

22:11 * brehaut brain asplodes

22:11 brehaut: i would have thought i would have this down by now

22:12 gfredericks: maps-as-second-arg is a special case; esplains everything

22:12 brehaut: it does

22:12 xeqi: ,(conj {:a 1} (seq {:b 2 :c 3}))

22:12 clojurebot: {:b 2, :c 3, :a 1}

22:12 gfredericks: brooksbp: so apparently you can do it all sorts of ways

22:12 xeqi: stop wronging me!

22:13 okay maybe vectors are a special case

22:13 xeqi: heh, I was curious

22:13 brehaut: xeqi: im boggled now

22:13 gfredericks: if a vector, assume it's a pair

22:13 xeqi: (class (seq {}))

22:13 gfredericks: ,(conj {} [1 2 3])

22:13 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Vector arg to map conj must be a pair>

22:13 gfredericks: ^ aHA

22:13 xeqi: ,(class (seq {}))

22:13 clojurebot: nil

22:13 gfredericks: ,(seq {})

22:13 clojurebot: nil

22:14 xeqi: ,(class (seq {:a 1}))

22:14 clojurebot: clojure.lang.PersistentArrayMap$Seq

22:14 xeqi: ,(class [[a 1]])

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

22:14 xeqi: ,(class [[:a 1]])

22:14 clojurebot: clojure.lang.PersistentVector

22:15 brooksbp: ,(conj {} {:a 1} {:b 2})

22:15 clojurebot: {:b 2, :a 1}

22:17 brooksbp: ,(conj {} '(1,2))

22:17 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry>

22:33 amalloy: brehaut: the implementation/contract of (conj some-map anything) is horrible

22:34 brehaut: amalloy: i have decided there's an unholy implicit union type in there

22:34 amalloy: i say it this way because the implementation accident in APersistentMap has become a contract in IPersistentMap merely by being in the wrong place at the wrong time

22:35 and now everyone has to implement that horrible implicit union in exactly the same awful way or else they don't work the way people expect

22:36 brehaut: right

22:48 gfredericks: people who know what an implicit union is are smarter than me

22:49 but not taller

22:49 except for technomancy

22:52 TimMc: gfredericks: Java has implicit union types: String|Null :-P

22:55 adu: gfredericks: did you make a video recently?

22:55 gfredericks: adu: not on purpose

22:55 adu: oh ok

22:55 gfredericks: I mean I took a video on my phone of my son waddling around

22:56 tmciver: yeah, I think that's the one adu was talking about. :)

22:56 gfredericks: also I _watched_ a video recently, which is a related activity

22:58 trptcolin: gfredericks: your past 10 minutes here looks like most of my campfire conversations at work. i lol'ed.

23:00 * gfredericks can sleep soundly now

23:01 adu: gfredericks: good night, sorry for confusing you with someone else

23:05 gfredericks: adu: no trouble whatsoever

Logging service provided by n01se.net