#clojure log - Jul 02 2015

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

0:32 Guest25706: hello world

0:34 is it possible to solve the knapsack problem using only datalog?

0:43 (= 1 1)

0:44 (+ 1 1)

0:44 clojurebot: 2

0:44 rhg135: false

0:44 Guest25706: (* 1 1)

0:44 clojurebot: 1

0:45 Guest25706: #t

0:45 skynet9001: apparently you can http://www.cs.ucla.edu/~zaniolo/papers/tplp01.pdf

0:56 vas: Hi everyone. A datomic query returns (appropriately)... ({:tag "whatever", :bid 17517, :pid 7535} {:tag "somethingelse", :bid 7551, :pid 6625}) ... I would like to count the number of values returned.. in this example there are 2. ({} {}) ...what's the right fxn for that?

0:56 Guest25706: heavy reading. thanks skynet.

1:02 vas: the correct answer was "count" xD

1:02 forgot I had a thread-through ->>

2:15 musty: I wonder how to ignore *is now known as* on irssi.

2:15 Empperi: hmm?

2:15 just type /ignore <user>

2:15 lumafi: /ignore #clojure NICKS

2:16 will ignore nick change messages

2:16 Empperi: ah those

2:16 darn

2:16 misunderstood you musty

3:57 tmtwd_: http://pastebin.com/HKjdqNCx anyone see the bug with this?

3:57 I get this error : Uncaught Error: No protocol method ISwap.-swap! defined for type number: 12

3:57 ```

3:58 IAE: Hello, I was wondering if somebody could please help me out with a hopefully simple problem related to counting objects.

3:59 I have a record Cell, (defrecord Cell [visited? valid-dirs open-dirs]), that I create multiple times when generating an initially closed maze

3:59 When I go to test this, I create two mazes: (def tiny-maze (create-maze 1)) (def small-maze (create-maze 2))

4:00 Whave have dimensions 1x1 and 2x2, so a maze with 1 cell and four cells respectively

4:00 However, when I test with (is (= 1 (count (:cells tiny-maze)))) (is (= 4 (count (:cells small-maze))))

4:00 I get 3 and 4

4:00 I noticed that in the first instance it counts the parameters contained in the single cell instead of counting the cell object as one

4:01 I'm not sure why it does that or how I could fix it

4:11 So I noticed that, in the instance of my (create-maze 1), it does not create a list of Cell elements. So I tried wrap my maze-creating code with (into [] (...)); which now returns [[:visited? false] [:valid-dirs #{}] [:open-dirs #{}]]

4:11 However, this still returns three

4:16 kungi: IAE: how do you construct the size 1 maze? It sounds to me like you somewhere conjoin the content of your cell instead the cell itself.

4:19 tmtwd_:I think this is wrong: #( (swap! @myval inc) )

4:19 HUgeneral: whats wrong?

4:19 kungi: tmtwd_: It should be #(swap! @myval inc)

4:20 HUgeneral: Yes it should? I have no idea what you are talking about. sorry

4:20 IAE: kungi: (defn create-maze [size] "Create a maze sizeXsize large." (Maze. (if (= 1 size) (create-cell) (...))))

4:20 tmtwd_: yes

4:20 tried it, but it didn't work

4:20 IAE: kungi: where (defn create-cell "Creates an unvisited cell with no valid directions." ([] (Cell. false #{} #{})) ([valid-dirs] (Cell. false valid-dirs #{})))

4:20 tmtwd_: same error

4:21 kungi: tmtwd_: I saw it now :-) dont deref the atom. use (swap! atom fn)

4:21 tmtwd_: kungi, thanks :)

4:21 kungi: HUgeneral: I am not addressing you? Your highlights must be wrong :-)

4:22 tmtwd_: easy to miss :-)

4:22 HUgeneral: sorry this is my first time here

4:23 vas: Does anybody have experience in saving a graph to a database (like the similarity values of my posts to one another into datomic) ?

4:23 kungi: HUgeneral: Then welcome! :) First time on #clojure or on IRC in general?

4:23 vas: welcome HUgeneral =]

4:23 HUgeneral: irc in general. It is all really confusing

4:23 tmtwd_: huh, it works now, but it still throws an error Uncaught TypeError: cljs.core.swap_BANG_.call(...).call is not a functionsyntax_reagent_demo.core.two_headers @ core.cljs:21executeDispatch @ react.inc.js:3297SimpleEventPlugin.executeDispatch @ react.inc.js:15709forEachEventDispatch @ react.inc.js:3285executeDispatchesInOrder @ react.inc.js:3306executeDispatchesAndRelease @ react.inc.js:2679forEachAccumulated @ react.

4:23 inc.js:17600EventPluginHub.processEventQueue @ react.inc.js:2886runEventQueueInBatch @ react.inc.js:10747ReactEventEmitterMixin.handleTopLevel @ react.inc.js:10773handleTopLevelImpl @ react.inc.js:10859Mixin.perform @ react.inc.js:16683ReactDefaultBatchingStrategy.batchedUpdates @ react.inc.js:9199batchedUpdates @ react.inc.js:14914ReactEventListener.dispatchEvent @ react.inc.js:10953

4:23 oops sorry for that

4:23 HUgeneral: Thanks

4:24 vas: IRC is "multiplayer notepad," don't be overwhelmed ^_^

4:24 kungi: HUgeneral: When a line starts with a name you normally address a person.

4:24 IAE: sorry I don't see the problem

4:25 HUgeneral: So am I addressing someone?

4:26 IAE: kungi: Yeah, I figured it out. I shouldn't have treated a maze with dimension 1 as a special case. Thanks for the support!

4:27 vas: HUgeneral: currently, not specifically. but if you were to start your message with someone's-nickname: they would most likely have some sort of notification (depending on their IRC client)

4:27 IAE: way to go!

4:27 HUgeneral: okay, gotcha. thannks!

4:28 vas: i'm pretty newb to IRC myself, but some friends have used the IRC scripting language to make phenomenal things... absolutely mind blowing...

4:28 whole RPGs and stuff

4:28 HUgeneral: I had a friend turn me to it today. I dont understand the language what so ever

4:29 vas: Clojure or IRC? or both?

4:29 HUgeneral: irc. I found clojure online

4:30 along with haskell.

4:33 vas: Clojure is sweet. I don't know anything about Haskell. Have you looked at any books or tutorials yet?

4:34 HUgeneral: no?

4:34 clojurebot: no is tufflax: there was a question somewhere in there, the answer

4:34 HUgeneral: should I?

4:34 kungi: HUgeneral: if you desire to learn clojure ... you should.

4:35 HUgeneral: yeah I am about to go to bed. I will read up on it there.

4:36 Thanks all

4:36 IAE: Have a good night!

4:36 kungi: vas: Haskell is definitely worth a look. It approaches functional programming quite differently than Clojure

4:37 j-pb: yeah, haskell takes the hardened fortress approach, while clojure is the guerilla tactic :D

4:37 vas: kungi: do you feel like your clojure or understanding of programming has improved with looking/learning [at] both?

4:37 j-pb: totally get that vibe! haha :D *pew pew pew*

4:38 kungi: vas: yes

4:38 j-pb: vas: it will certainly broaden your mind, but if you are a newb to either, I'd reccomend with picking one and sticking with it

4:39 kungi: You should look at one new programming language every year and see how it approaches things differently.

4:39 vas: thanks j-pb. i'm gonna try to dig my well deep on clojure's field first.

4:39 kungi: that's the most amazing thing i've ever read a coder say, i think.

4:40 j-pb: ha, theres even a Rich Hickey quote on this: Rich Hickey says - You don't level up by switching games all the time, but by sticking with one long enough to gain advanced skills. And, you need to be careful to recognize the actual game involved. Programming mastery has little to do with languages, paradigms, platforms, building blocks, open source, conferences etc.

4:40 HUgeneral: I will stick with one and stay there lol

4:41 vas: clojure does so many things correctly/rightly imho that it really deserves a good look/learn. maps and keywords... so awesome. also lisp in general! "implement a linked list" how about i just use a better language xD

4:41 rritoch: vas: Once you have a few languages under your belt you should also look into compiler design. When you see how the compiler-compiler's work, you'll fully understand why certain languages are the way they are. Clojure is more interpreted so to understand it you don't need to look any further than clojure's source code.

4:43 kungi: And instead of writing cool clojure code I have to fiddle with html/css to create a nice looking questionaire form. Sometimes I hate my job.

4:43 HUgeneral: how to send a personal message? lol

4:43 kungi: HUgeneral: /query nickname

4:44 vas: I think you can do /msg ? or /message

4:45 noidi: clojure does not have an interpreter

4:45 it's all compiled

4:45 (the official JVM implementation, that is)

4:45 rritoch: noidi: compiled? lol

4:46 noidi: Clojure compiles stubs which call an interpreted infrastructure.

4:46 noidi: Its ingenious, but I wouldn't ever say its compiled.

4:48 noidi: what do you mean by an interpreted infrastructure?

4:48 rritoch: nodi: One sec, let me check the core, there's some stuff there that really makes it clear.

4:49 nodi: Take a look at this code here. https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L937-L947

4:50 nodi: All mathematical operations are method calls, they aren't compiled.

4:51 vas: Would you say that it's compiled when you make a .jar of something, though?

4:52 noidi: isn't that +' function compiled into JVM bytecode?

4:52 sorry, I just don't see an interpreter here :)

4:52 rritoch: vas: I believe it is just compiling stubs which contain the code required to perform the methods defined in your symbols. I haven't looked into all the details of the compilation but if you look at your stacktraces you can see the stub calling your methods.

4:53 vas: Even when it's compiled.

4:53 err... nodi

4:57 vas: interesting. seems like a hybrid approach

4:58 noidi: that's a Clojure function that calls a Java method, and it's compiled into JVM bytecode

4:58 where's the interpreter?

4:59 here's the bytecode for +' https://www.refheap.com/104678

5:01 rritoch: nodi: Look at line 71 21

5:02 21 invokestatic clojure.lang.Numbers.addP(java.lang.Object, java.lang.Object) : java.lang.Number [71]

5:04 vas: Very interesting

5:04 rritoch: noidi: I haven't done much at the compiler level of clojure, but all forms are interpreted, they aren't compiled, and therefore, by definition, it's an interpreter.

5:06 noidi: The stub itself is compiled by clojure, and javac compiled the clojure source code, but the forms themselves are not truly compiled. As vas stated, it's a hybrid.

5:13 noidi: if you compile a function that calls a Java method, of course you'll find a reference to that method in the resulting bytecode

5:18 https://www.refheap.com/104680

5:20 the forms I entered into the REPL were compiled into JVM bytecode

5:20 not interpreted

5:22 rritoch: nodi: What about it? Line 53 just calls the invoke method of foo, I don't see how that isn't interpreted.

5:24 err, correction, line 53 calls the invoke method of clojure.lang.IFn, butthat eventually calls the invoke method of foo

5:25 nodi: No matter how you look at it, it is interpreted.

5:25 err, noidi... I need to start using tab completion

5:29 noidi: A better example to see what's happening is to look at (seq (.getStacktrace (Thread/currentThread)))

5:31 err, getStackTrace

5:40 TreeNode: (defn hello [] «hello to all!»)

5:43 noidi: rritoch, if it's interpreted, where's the interpreter? :)

5:44 rritoch: noidi: It is in fragments, split between the RT class and the Compiler class.

5:45 noidi: if the JVM jumps into that piece of bytecode compiled from the bar function, there's nothing in there to start an interpreter

5:46 it's bar's body compiled to bytecode

5:47 put the var #'foo on the stack, use it to look up the object representing the function foo, then put the constants 1 and 2 on the stack, and jump into foo's invoke method

6:04 rritoch: noidi: Either way, this one generated instruction looks like it's going to make my life hell. https://www.refheap.com/104678#L-36 I do pretty much consider these things stubs because none of the mathematical operations are compiled into bytecode.

6:10 noidi: That one line of code though means I need to swap out the namespaces in clojure before the classes are loaded which means my original plan of swapping out namespaces from a clojure compiled OSGI activator isn't going to be an option. It gets interned just by loading the class.

6:20 I guess if I can get my hands on the bundles classloader from the lifecycle listener before the clojure bundle is loaded than I can create the new namespace container there.

6:21 Well, actually before it's started, and after it's loaded. As long as the activator doesn't get loaded until it's started. If the activator is loaded before I can swap out the namespace container, there will be a lot of bugs.

6:43 This is way easier than I thought, a sure sign it isn't going to work.

6:47 aztak: rritoch: you're doing Clojure in OSGi?

7:05 rritoch: aztak: I'm trying to turn clojure into an OSGI bundle, in an OSGI compatible way, complete with Clojure-Imports and Clojure-Exports manifest headers to import and export clojure namespaces.

7:06 aztak: I've already used clojure in OSGI and the big problem was namespace conflicts since it doesn't matter that they were loaded from different bundles, they're still using the same clojure classes, so they are sharing the same namespaces container.

7:07 aztak: rritoch: If the clojure code is compiled to java-classes then the BND tool (maven-bundle-plugin etc.) can introspect the bundle to create the proper Import-Package/Export-Package directives. But perhaps that's not an option for you?

7:08 Bronsa: rritoch: reading the backlog now. your claims that clojure isn't compiled is nonsense

7:08 rritoch: aztak: Yes, but if you have two bundles with the same clojure namespace, they conflict instead of staying in their own isolated environments because they're still sharing the same namespace container.

7:09 aztak: rritoch: which namespace is that? The actual clojure runtime classes?

7:09 Bronsa: rritoch: having a runtime lib != being interpreted

7:09 aztak: Or are you saying that the bundles actually contain classes with the same namespaces (== packages)?

7:09 Bronsa: rritoch: clojure is always (well 95%) compiled to bytecode and executed JIT

7:12 Empperi: I didn't even bother to take part in this conversation earlier but yes, clojure is always compiled to bytecode, even when using REPL

7:14 rritoch: Bronsa: Nearly all of it is just calls to java functions, I don't see where loops or mathematical operations are being compiled, unless there's a key part of the compiler that I'm missing, which is quite possible since I haven't done much with the compiler.

7:14 Bronsa: For that matter, I'm not even sure if the conditional logic, like if statements, are compiled, though I didn't actually look.

7:14 Bronsa: rritoch: loops are compiled, mathematical ops are "compiled" too into jvm arithmetic bytecodes in some cases

7:14 rritoch: they are

7:15 Empperi: indeed they are

7:15 Bronsa: rritoch: compiling to java methods is still compiling anyway. by your logic even java is interpreted

7:16 Empperi: everything you write in clojure will eventually end up being compiled to bytecode and then executed on top of JVM with JIT

7:16 Bronsa: Empperi: well not actually *everything*. clojure does have a small interpreter for really simple expressions

7:16 rritoch: Bronsa: Ok, if they are, they are, I just haven't seen it, and when I made adjustments to the mathematical classes, without making any adjustments to the compiler, it just worked without any problems.

7:17 Bronsa: Empperi: for example `(def foo 1)` will not be JITed

7:17 Empperi: "without any adjustments to the compiler" - wait a minute, of what compiler are talking about?

7:17 rritoch: aztak: clojure.lang.Namespace#namespaces is the container I'm talking about

7:17 Empperi: Bronsa: well that would make sense since vars are dynamic and you can do that runtime directly

7:18 rritoch: aztak: All bundles end up sharing the same instance of that, so to be able to share namespaces between bundles, but still have their own versions of some namespaces, additional features are needed.

7:18 Bronsa: Empperi: not that the interpreter is necessary at all, it's just probably a perf/memory optimization to avoid allocating a new class when not necessary

7:19 Empperi: yeah

7:19 aztak: rritoch: so you want one isolated Clojure runtime per bundle? That would mean that bundles cannot share objects/data with each other, right?


7:19 Bronsa: (actually there are a few bugs and removing the interpreter is not possible)

7:20 aztak: rritoch: so you basically want to "load" clojure-code from another bundle into the clojure runtime of another bundle?

7:20 Bronsa: rritoch: well the mathematical classes are part of the runtime lib -- they have nothing to do with the compiler

7:20 aztak: (I'd suggest using java semantics - classes/packages/etc - when dealing with OSGi *grin*)

7:21 Empperi: or well, they do. But only in linking semantics

7:21 Bronsa: rritoch: the compiler is just aware-enough of them to figure out when it's possible to do some inlining/compile away those method calls

7:21 Empperi: isn't inlining done mostly by JIT?

7:21 Bronsa: if you compile (defn x [] (inc 1)) you'll see that there's no method call

7:21 Empperi: to my knowledge it is

7:22 rritoch: aztak: No, I want all bundles which depend on the same version of clojure to be using the same instances of the namespaces that they choose to import, but still have their own non-conflicting namespaces. Ie. be able to import from two different packages even if one of those packages depends on the other import @ a different version.

7:22 Bronsa: Empperi: clojure has some logic for manual inlining of mathematical ops, helps avoid unnecessary boxing/use fast bytecodes

7:22 Empperi: see Intrinsics.java

7:22 Empperi: nothing too comprehensive I think though

7:23 JVM JIT inlining is pretty darn effective

7:23 although it is limited to only 9 steps by default

7:23 but sure it is wise to do some preprocessing inlining for simple cases

7:24 rritoch: aztak: So if bundle A depends on version 1.0 of bundle B, and version 1.0 of Bundle C, but bundle B depends on Version 1.2 of Bundle C, Bundle A still gets the namespaces from version 1.0 of Bundle C while Bundle B is getting the 1.2 version.

7:24 Empperi: what you can do without runtime information

7:25 rritoch: aztak: That runs into problems with a large team, especially when everyone wants to use the same clojure namespace for their activator.

7:26 aztak: rritoch: are you perhaps running into the equivalent of this: 1


7:27 http://njbartlett.name/2011/09/02/uses-constraints.html

7:27 rritoch: aztak: Either way, my initial version attached the namespace container to thread-local memory, and that worked OK when there werne't thread pools involved. It needed to be done on a fork of clojure though. Now that I've found a way to replace the namespaces container with reflection, I'm going a different route and trying to link the namespaces container, by their bundle classloader.

7:27 wink: why did I read that url as 'ninjabartlett.name' at a glance? it's clearly too hot to work..

7:28 rritoch: aztak: Either way, Java 9 may be OSGI enabled, so it is a good time to be dealing with these issues.

7:28 aztak: rritoch: sounds like a dangerous path.. But best of luck :)

7:29 rritoch: aztak: No, that wasn't the issue, OSGI didn't care, it didn't even know the conflict existed

7:30 aztak: I haven't done much Java/Clojure embedding stuff... but can you create an explicit Clojure runtime instance or is the runtime tied to a class-loader instance?

7:30 rritoch: aztak: Bundle A would load and have its own namespace internalized so OSGI didn't care, the namespaces get interned into the Namespace.namespaces property, Bundle B would then load, all classes are internalized so OSGI doesn't care, but now when it interned it's code to Namespace.namespaces, it would quietly overwrite the code for bundle A, so bundle A would never see its own code again.

7:31 aztak: In JRuby you can instantiate a Ruby runtime explicity. That way you can get more control over script-loading.

7:31 and even provide the proper runtime instance to bundles using an Osgi ServiceFactory or an extender-bundle.

7:32 would be nice if that was possible in Clojure as well.

7:32 CRaaS - ClojurRuntimeAsAService :)

7:33 rritoch: aztak: Most people who want multiple namspeaces are using a shim, https://github.com/tobias/clojure-runtime-shim, but since they're loaded by different ClassLoaders they can't share namespaces directly.

7:34 namspeaces=namespaces

7:34 64MAC8X5W: whoami

7:34 hello

7:35 aztak: ah, yeah - I've seen that one. A work-around because Clojure doesn't have runtime instances per se?

7:35 rritoch: aztak: Either way, that method can work, but it creates a condition where each bundle gets it's own runtime, which isn't ideal.

7:35 aztak: rritoch: if you provide a runtime manager in a ServiceFactory or in an extender bundle you could decide which bundles would share runtimes and which bundles would get their own.

7:36 (you may need to allow the classloader for a runtime to be dynamically extended when needed though)

7:36 rritoch: aztak: So to facilitate versioned namespaces in a single runtime I need to takeover the Namespace.namespaces property, and in this current incarnation of the concept, I'm trying to associate the appropriate namespaces container, using the current context classloader , which should have a parent of the BundleClassloader which is what's actually being registered to import/export namespaces from.

7:37 aztak: not sure about your use-case - but if possible, stay away from the thread-context class-loader :). It's evil and non-standardized.

7:38 rritoch: aztak: Sure, but that would be an all-or-nothing proposition. I'm only working on the partial sharing. Matching how OSGI shares packages.

7:40 aztak: Currently I have .... public class DeligatingNamespaceRegistry extends ConcurrentHashMap<Symbol, Namespace> , and it has it's own "registrations" which is a ConcurrentHashMap<ClassLoader, ConcurrentHashMap<Symbol, Namespace>> , I was originally going to have these environments initialized from the activator.

7:42 aztak: But then I realize that clojure has static initializers which cause some namespaces to be interned immediatly, so I'm now creating a BundleListener to create the namespace isolations (with imports and exports) when the bundle goes into a "STARTING" state.

7:44 aztak: Anyhow, if it works it will make it possible to have multiple versions of clojure available in the same OSGI system, and the ability to share the clojure namespaces themselves, not just the packages.

7:46 This depends on how clojure uses the context ClassLoader. If clojure is wrapping the current context classloader, than it would work fine, because clojure will wrap the bundle classloader, and this system will apply the correct namespaces.

7:47 If clojure just wraps the system classloader, than everyone will be sharing the same main namespaces, and I'm back to the same problem I started with.

7:49 aztak: Actually the thread context classloader is exactly what I'm using, as long as it has a parent classloader which is the bundle classloader, everything should work. If it doesn't than I'll need another approach, possibly going back to using thread-local memory.

8:06 aztak: rritoch: (sorry for not replying -- I had to attend a meeting)

8:06 rritoch: is this closed-source or do you have a repo somewhere with your code so far?

8:07 rritoch: aztak: No problem, I'm still quite far from being able to test this stuff.

8:07 aztak: As of now it's closed source only because the code is in bad shape, more //TODO than implementation, lol

8:08 aztak: once it's at least in testability mode I'll release it open source.

8:08 aztak: :)

8:10 rritoch: Looks like I need one extra clojure header, "Clojure-Enable" just in case they don't have any imports or exports, though I'm fairly sure not importing clojure.core will end badly, but seeing clojure interns it automatically, it may no longer be an issue since I'm now attaching before the bundle is started.

8:25 I guess I am really in a hurry to test this, first time I've ever used "//TODO: Do something" but it's the unregister method which I don't care about, I can deal with cleaning up the mess if it works.

8:44 my-name-is-gaz: Hey #clojure :)

8:44 I don't know if anyone can help me

8:44 But what interface would I need to support to have something respond to keywords being used as an accessor? Like in a map

8:44 (:key obj)

8:45 justin_smith: my-name-is-gaz: ILookup

8:45 my-name-is-gaz: excpet obj isn't a map, it's some horrible thing I built :D

8:45 Cheeers man :D

8:45 justin_smith: my-name-is-gaz: an easy way to do this is defrecord

8:45 my-name-is-gaz: Any hints on tips on what docs I should be looking at if I have a similar q in the future?

8:45 Bronsa: IKeywordLookup actually

8:45 my-name-is-gaz: yeah I have that now

8:45 justin_smith: defrecord can be extended to arbitrary interfaces, protocols, etc. and also automatically supports keyword lookup

8:46 my-name-is-gaz: But I want a vector to store the data for efficiencies sake but still use :x :y :z etc for acces (nth d 0) 1 2 etc

8:46 Bronsa: ILookup is for (get x :foo) , IKeywordLookup is for (:foo x) IIRC

8:46 my-name-is-gaz: these things change quite a bit

8:46 justin_smith: my-name-is-gaz: records already use a vector for efficiency for the defined keys don't they?

8:46 my-name-is-gaz: and it's making my clojurescript bog a bit :D

8:47 Bronsa: justin_smith: better, they use direct class fields

8:47 justin_smith: Bronsa: oh, I thought (get x :foo) was what (:foo x) turned out to be

8:47 my-name-is-gaz: Looking at the js produced it seemed to be allocating on each keyword / val

8:47 which would make sense to maintain persistence

8:47 justin_smith: my-name-is-gaz: so a record would do faster lookup anyway

8:47 my-name-is-gaz: oh, js? that's completely different!

8:47 Bronsa: justin_smith: no, (:foo x) actually can be faster than (get x :foo) for records

8:47 justin_smith: aha

8:47 my-name-is-gaz: but that may optimise out when it goes through the closure comp

8:48 justin_smith: my-name-is-gaz: all the stuff we have been saying is about jvm clojure

8:48 my-name-is-gaz: haha I'm doing optimisation too early as a displacement activity :D

8:48 justin_smith: my-name-is-gaz: you didn't say this was cljs

8:48 my-name-is-gaz: sorry :D

8:48 justin_smith: my-name-is-gaz: in cljs, an array is really a hash lookup anyway, so the "optimization" you are doing shouldn't exist, iirc

8:48 my-name-is-gaz: Same set of interfaces tho?

8:49 justin_smith: my-name-is-gaz: no, the cljs interfaces are different

8:49 my-name-is-gaz: kind of, cljs puts a layer of allocation on top of the js implementation to maintain persistence

8:50 justin_smith: my-name-is-gaz: point being, on the js level there isn't a true indexed array, it's actually a hashmap

8:50 my-name-is-gaz: js array lookups for small maps are bodged to be fast on most browsers if they're not sparse

8:50 I think they get classified internally as a seperate type of class on most JS engines

8:51 and then if you turn it into a non sparse array everything recompiles and judders to a halt :D

8:51 justin_smith: my-name-is-gaz: sure, but they aren't doing something cljs can't/doesn't do to speed up lookup are they? anyway, you'll likely find better info on #clojurescript

8:51 my-name-is-gaz: Oh! Sorry again :D Ijust searched for clojure irc channel :D

8:51 n00b!

8:51 :D

8:51 Thanks tho, interesting and v helpful of you :)

8:52 justin_smith: my-name-is-gaz: core protocols in cljs are defined starting here https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L384

8:52 my-name-is-gaz: Before all that I'll do the right thing and measure some bench marks

8:52 justin_smith: my-name-is-gaz: looks like on cljs you might actually want ILookup like I first suggested?

8:52 my-name-is-gaz: The source is the docs for this stuff really isn't it? That's cool

8:53 justin_smith: my-name-is-gaz: well, in this case the source is very straightforward to scan for the answer

8:53 I am sure there are actual docs somewhere too

8:54 my-name-is-gaz: thanks justin, much appreciated

9:02 tmtwd: http://pastebin.com/60j9wbYT Is there a way to dynamically add a :p into a function (cljs)?

9:03 and what do you call a function that just contains html elements?

9:03 justin_smith: tmtwd: a function that returns [:p ... ] should work

9:03 snowell: tmtwd: You would write a different function that returns the [:p ] vector, then reference that component in your two-headers function

9:03 justin_smith: [p-generator]

9:04 for reagent, that is

9:04 tmtwd: what is a p-generator?

9:04 justin_smith: tmtwd: the function

9:04 tmtwd: justin_smith, oh

9:04 justin_smith: I just made up a name - but that's how you do it with a reagent component

9:04 if you are more generically just generating hiccup, don't do it that way

9:04 tmtwd: but I don't want it do display :p right away

9:04 I want it to display :p after a user clicks a button for exampl

9:05 justin_smith: well [foo state] then

9:05 and clicking the button should alter state

9:05 state being a reagent state atom

9:05 assuming you are talking reagent here...

9:05 tmtwd: what is foo?

9:05 justin_smith: a function

9:05 tmtwd: i see

9:05 justin_smith: reagent will call that function with the state atom as an arg, when the state atom is altered

9:06 this is the concept of a reagent component

9:07 tmtwd: shouldn't it be [foo @state]?

9:07 or you don't want to deref an atom?

9:07 justin_smith: tmtwd: depends, should foo be able to alter state? I mean you can do either one

9:07 I think

9:07 but in my codebase we always pass in the atom itself

9:07 tmtwd: ah okay :)

9:08 justin_smith: since that gives each component the option of updating any other component as needed

9:09 tmtwd: so I need to def an atom like this : (def state (atom ":p 'yo'")) ?

9:09 justin_smith: tmtwd: are you using react?

9:09 tmtwd: justin_smith, yes

9:09 justin_smith: *reagent

9:09 tmtwd: yes, reagent

9:10 justin_smith: OK, then you need to create a special kind of atom, a reagent atom

9:10 I'd look at the reagent docs, there's a lot to learn - I could tell you a lot of it here but you are probably better off reading the actual docs

9:11 tmtwd: ok

9:11 justin_smith: reagent atoms are special because they keep track of the modifications you make, and know which components to update based on what those components access

9:22 j-pb: justin_smith: I sometimes wonder why reagent doesn't hook into the regular listener capabilities of normal atoms

9:23 justin_smith: j-pb: consider the fact that you can make another reagent atom out of one subtree of a reagent atom

9:23 there's something special allowing things like that, clearly

9:23 j-pb: yeah true

9:29 justin_smith: are cursors that much used in practice though? They are broken in Om and they're broken in reagent too.

9:31 can't wait for dnolen's euroclojure talk on om.next :D

9:31 word of mouth has it, that it replaces cursors with pull syntax requests into datomic and datascript

9:32 justin_smith: j-pb: broken in reagent how? We'd been planning an update to use them, after seeing a demo at the local clojure meetup

9:35 j-pb: justin_smith: Om cursors can suddenly point to the wrong thing, when elements are added or removed from vectors, afaik. Since this problem is inherent to cursors, I don't see how reagent can avoid this.

9:36 justin_smith: j-pb: wait, is this about splitting the mounted component, or using a sub-tree of the state atom as an arg instead of the full atom? because I don't see how the latter could do that, and that was the feature I was talking about.

9:37 j-pb: the point of the feature being that you can move the data that the component watches in a refactor, without needing to change the component

9:40 j-pb: I mean what you get when you call (cursor ra [:foo :bar])

9:44 justin_smith: j-pb: is this similar to a reaction?

9:44 j-pb: justin_smith: I could be wrong, but when you have a component with local state associated with a path in the global state, and that path goes through a vector, changing the number of elements in the vector, should be able to screw up that matching

9:46 justin_smith: j-pb: in my app's state, I would never use a vector for anything that isn't a homogenous group where every sibling should be treated identically

9:46 j-pb: which is why I thought you might be talking about components (where elements of a vector wouldn't actually be identical, they would be different components)

9:47 j-pb: ah yeah

9:47 justin_smith: I'd think subtrees under keyed entries in a map would be handled properly

9:48 j-pb: well, with homogenous elements its not that bad, but even there, say you have one element in edit mode, and you delete it, then the next element would be in edit mode

9:48 I might be wrong though, it's been a loong time that I looked at cursors, and I remember vaguely, asking if this can actually happen, and I think david said yes

9:49 but it's so long ago that I don't trust my memory

9:49 justin_smith: in my design edit mode would be a key inside the item that the component watches though... how would that transfer to a neighbor?

9:51 now I really want to know if a) I'm naive and haven't built anything big enough to understand this issue or b) reagent's design avoids this issue somehow...

9:51 kungi: I am trying to create a string from the local time with clj-time: (f/unparse-local (f/formatter "yyyy-MM-dd HH:mm:ss.SSS") (lt/local-now))

9:52 j-pb: justin_smith: could also be that om avoids this, I stumbled upon this in kovasb's Session, but he extends cursors to sets and seqs

9:52 kungi: But this triggers the following CLassCastException: org.joda.time.DateTime cannot be cast to org.joda.time.ReadablePartial

9:55 nevermind I got it

10:02 dnolen: j-pb: cursors do not have the problem you are describing

10:03 j-pb: dnolen: how are you detecting a deletion then?

10:03 dnolen: j-pb: I'm not going explain this. It works people have written massive applications with cursors.

10:04 j-pb: hint, where to look in the code :)?

10:04 dnolen: Sorry

10:04 j-pb: dnolen: like I said, maube it was just a problem with Session, creating cursors from sets

10:05 dnolen: You're talking a version from 16 months ago, bugs get fixed

10:05 j-pb: dnolen: yeah, like I said, this was ages ago

10:08 sharms: Can anyone help me figure out why this code throws an artity error? http://pastebin.com/Q0KF88rS

10:09 justin_smith: sharms: fields-joined you have a function that takes one arg

10:09 but you are mapping over two collections

10:09 (line 6)

10:09 sharms: oooh its inside the function

10:09 not the actual calling of my top level one

10:10 which I should have noticed since the error message references the anonymous function fn--21231 or whatever

10:10 j-pb: sharms: main/crud-update/fn--28254 part behind the last / is the fn where the error occured, the fn--something stands for an anonymous fn

10:10 justin_smith: main/crud-update/fn--28254 that translates to "in namespace main, function crud-update, in an anonymous fn"

10:10 sharms: and not crud-update

10:10 thanks again appreciate all of the help

10:11 one day I hope to ask a question which is actually complex haha

10:11 justin_smith: sharms: this is why I prefer the form (fn field-joiner [x] (string/join " " x)) - the error message is much more informative in that case

10:11 sharms: cool I will check that one out

10:11 j-pb: justin_smith: great trick

10:11 justin_smith: sharms: it's just a regular anonymous function, with an extra "name" arg

10:12 j-pb: yeah, I figured it out from an fn that needed the name arg to do a self call, then I realized the stack trace was so much more clear...

10:12 j-pb: haha

10:13 justin_smith: ,(fn [] :x)

10:13 clojurebot: #object[sandbox$eval25$fn__26 0x351a3269 "sandbox$eval25$fn__26@351a3269"]

10:13 justin_smith: ,(fn x-keyword [] :x)

10:13 clojurebot: #object[sandbox$eval51$x_keyword__52 0x7c05ab8c "sandbox$eval51$x_keyword__52@7c05ab8c"]

10:25 fikusz: I want to wrap my own macro around the cljs macro 'go' from core.async. I understand that cljs macros need to be defined in clj, but I can't seem to require the original macro from cljs.core.async.macros in my clojure code

10:25 I get java.lang.ClassNotFoundException: cljs.core.async

10:28 justin_smith: fikusz: what does your requiring code look like?

10:28 fikusz: (:require [cljs.core.async.macros :as as])

10:28 in the ns macro

10:29 justin_smith: fikusz: that form only works inside ns

10:29 fikusz: justin_smith: I'm inside ns

10:29 justin_smith: oh, missed that, sorry

10:30 fikusz: justin_smith: np

10:30 justin_smith: it seem my problem is not with requiring

10:31 justin_smith: I noticed if I remove the call to go, the error disappears

10:31 justin_smith: fikusz: for that you may need :require-macros

10:31 or you could not call go, if that suffices

10:32 fikusz: justin_smith: I'm in clojure myself, not clojurescript (since I'm writing my own macro too)

10:32 justin_smith: oh, then why would you ask for cljs.anything?

10:32 just require clojure.core.async

10:32 there is no .macros

10:32 there is not cljs

10:32 fikusz: justin_smith: because I want to write a macro for cljs

10:32 justin_smith: sorry, right

10:32 fikusz: justin_smith: as far as I understand I need to write that in clojure

10:33 justin_smith: yeah, I'm not sure how that part works actually myself (when you need to use clojure to write macros for core.async that refer to cljs code)

10:33 but I do know that your macros can invoke code that you don't require from the namespace of the macro

10:33 usually that's terrible, but it is sometimes useful

10:34 ,(defmacro psychic [] '(foo))

10:34 clojurebot: #'sandbox/psychic

10:34 fikusz: justin_smith: I'll try to check if cljs.async.macros has some dependencies I'm missing

10:34 justin_smith: ,(defn foo [] :hello)

10:34 clojurebot: #'sandbox/foo

10:35 justin_smith: ,(psychic)

10:35 clojurebot: :hello

10:37 rritoch: In the current state of clojure, if your accessing clojure from java does the runtime need to be started or is it automatic?

10:38 sharms: I am getting Lazy-seq back from: (apply str (interpose ", " fields-assigned)) - I read online that I can use pr-str or doall to realize it, but if I wrap it in either I still get back "clojure.lang.LazySeq@..."

10:42 snowell: sharms: You could wrap it in an (into []) and pr-str that

10:42 sharms: I think I need to wrap the fields-assigned in a do-all one level inside and that might work too

10:43 but I was wondering if there is a function which works at the top-level

10:45 yeah I tried (into []) and (doall) with the map statement inside, still gives me lazy-seq

10:45 I am not understanding something fundamental about lazyness and forcing realization for side effects

10:47 as far as I can tell doall is not recursive

10:48 so I guess my question is, if I am writing data to a file, that is considered a side effect and I must wrap all of my maps in doall?

10:48 map statements that is

10:49 ddellacosta: sharms: I don't understand why you'd be getting that back from a pr-str or doall. Can you provide a gist or something with the code in context?

10:50 sharms: http://pastebin.com/d0zyUKYF

10:56 Cr8: s/apply str/apply pr-str/

10:57 on 8

10:57 er no

10:57 derp derp

10:58 ddellacosta: Well, that will prevent it from dumping out a bunch of LazySeqs

10:59 sharms: just for fun, I am using x = {:table-name "variance", :fields {:id "SERIAL", :is_exception "boolean", :is_obsolete "boolean", :is_disabled "boolean"}}

11:01 ddellacosta: so yeah, the problem with that apply there is that it isn't forcing realization of the lazyseqs inside of the lazyseq produced by interpose in that line

11:01 sharms: ie if I switch updates-line from apply str -> doall, it still gets a lazyseq as a result

11:01 so is the idomatic way to wrap every single thing in a doall?

11:02 ddellacosta: but let's take a step back--what do you want to produce here? I line that is like "colA = foo, colB = bar, ..." etc.?

11:02 sharms: exactly

11:02 ddellacosta: okay

11:02 sharms: and I am trained in the art of non-functional programming, so I have highly likely used the wrong paradigm or mindset

11:03 rritoch: aztak: I put the repo online, it compiles, that's all I can say about it at this point, but you can see the direction it's heading... https://github.com/rritoch/clj-osgi-namespaces

11:04 ddellacosta: &(clojure.string/join "" (interpose ", " (reduce-kv #(conj %1 (str (name %2) " = " %3)) [] {:id "SERIAL", :is_exception "boolean", :is_obsolete "boolean", :is_disabled "boolean"})))

11:04 aztak: rritoch: Cool! :) I'll have a look - not sure if I can provide any useful input in a while though.

11:04 ddellacosta: hmm, is lazybot gone then? or am I forgetting how it works?

11:04 sharms: I think its a comma

11:04 ddellacosta: oh, I'm blocked from that still I think, but let's see

11:04 sharms: ,(clojure.string/join "" (interpose ", " (reduce-kv #(conj %1 (str (name %2) " = " %3)) [] {:id "SERIAL", :is_exception "boolean", :is_obsolete "boolean", :is_disabled "boolean"})))

11:04 ddellacosta: ,(clojure.string/join "" (interpose ", " (reduce-kv #(conj %1 (str (name %2) " = " %3)) [] {:id "SERIAL", :is_exception "boolean", :is_obsolete "boolean", :is_disabled "boolean"}))

11:04 clojurebot: eval service is offline

11:04 "id = SERIAL, is_exception = boolean, is_obsolete = boolean, is_disabled = boolean"

11:05 ddellacosta: yeah, that second one is your response. :-)

11:05 but anyways, that's the gist of it

11:05 oh, forgot the quotes though

11:05 rritoch: aztak: The project isn't an uber priority for me, the sytem I'm building is actualy java+spring+osgi , but I miss my REPL :)

11:05 sharms: that is cool and looks good - I am still worried that I don't understand the fundamentals of lazy-seqs - if I can't realize them via doall and pr-str, I think I am missing something

11:06 Cr8: it's not that, your code was just calling str on a seq

11:07 aztak: rritoch: I made a hack a while ago to "publish" an nRepl instance to the JVM by installing a bundle.. Haven't had the time to follow up on that one in a while though.

11:07 Cr8: ,(str (seq [1]))

11:07 clojurebot: "(1)"

11:07 Cr8: d'oh

11:07 ,(str (map inc [1])

11:07 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

11:07 Cr8: ,(str (map inc [1]))

11:07 clojurebot: "clojure.lang.LazySeq@21"

11:07 Cr8: there we go

11:08 ,(pr-str (map inc [1]))

11:08 clojurebot: "(2)"

11:08 ddellacosta: yeah sharms ^ that one line with apply str/interpose

11:08 isn't working because it's got a lazy seq of lazy seqs

11:08 sharms: ,(pr-str (str (map inc [1])))

11:08 clojurebot: "\"clojure.lang.LazySeq@21\""

11:09 ddellacosta: sharms: so with what you just typed, that str has already returned the string-ified lazy-seq before it gets to pr-str

11:09 aztak: rritoch: not in any way complete, but it sorta worked: https://github.com/metamorph/osgi-clj-repl

11:09 rritoch: aztak: Heh, well that's exactly what I'm looking for, just something that I can use to poke around, but eventually I'll need something with authentication. Exposing a REPL internet side is a bit of a security issue.

11:09 ddellacosta: so it's not going to realize the lazy-seq retunred by map

11:09 Cr8: str just calls the java .toString on non-strings

11:09 ddellacosta: returned*

11:10 Cr8: ,(.toString [1])

11:10 clojurebot: "[1]"

11:10 Cr8: vectors implement it, so do non-lazy seqs

11:10 ddellacosta: sharms: i.e. if you've got that str in there doesn't matter if you wrap it in doall or pr-str, it's already been converted to a string per .toString. There is no longer any lazy-seq in there to realize.

11:10 Cr8: lazy ones, potentially being infinite, don't

11:10 sharms: ok so I should really avoid (str) like the plague is what I am taking away from this

11:10 ddellacosta: unfortunately this isn't haskell. :-)

11:10 j-pb: dnolen: hm, could be that I'm just using Om wrong, but that behaviour is not fixed in Om 8.8 see https://gist.github.com/anonymous/4d8e6f0e0d638dfd0a47

11:11 ddellacosta: sharms: no, that's not the point--you have to just be aware of what is getting evaluated when

11:11 I use str all the time

11:11 dnolen: j-pb: I'm not going to explain Om to you.

11:11 ddellacosta: it's is quite useful

11:11 Cr8: if you know you have strings and you want to concat them, use str

11:11 dnolen: j-pb: it's used in production in many companies and they don't have problems with deletions.

11:11 rritoch: aztak: Well I've bookmarked and watched it. It saves me from re-inventing the wheel when I get to that point.

11:11 Cr8: if you have an arbitrary clojure data thing you want a representation of, use pr-str

11:12 if you want the .toString of something, use str

11:12 dnolen: j-pb: such things are best directed to #clojurescript, but I recommend reading the tutorials and looking at Om Todo, I can't be of any more help sorry.

11:12 sharms: ok thank you for the help I appreciate it, I am going to try and digest the advice you have given

11:12 Cr8: which would be if you're interop'ing with some java lib with useful .toStrings, for example

11:13 j-pb: dnolen: you don't have to, I'm just saying that cursors will create a mismatch of state/reference on deletions, your heuristic in Om, seems to be, removing components from the tail if a vector shrinks, but this means that state will be associated with the wrong data

11:14 ddellacosta: j-pb: don't much understand what you mean--most operations on cursors follow the semantics of basic clojure data structure operations, no?

11:14 j-pb: dnolen: and this is a bug to me, if you don't think so, that's ok

11:14 rritoch: aztek: My next hell is trying to share a single Web Context with multiple bundles. A task that will likely be impossible without the REPL to poke around with. Luckly there's a few other things I can work on to avoid that project.

11:14 j-pb: ddellacosta: yeah, but take the basic Om introduction for example, it involes removing entries from a contact list

11:14 ddellacosta: and I'm one of those people using Om every day, all day, in a production environment...removal of items has never been an issue.

11:15 ...

11:16 j-pb: ddellacosta: if you have local state at the same time, for example you have contacts highlighted or in edit mode in local state, once you delete an elemt from the collection, these states will point to the wrong entries

11:16 ddellacosta: I posted a gist, you can do a lein new mies-om hello-world, paste the code in the core and see for yourself

11:17 ddellacosta: j-pb: ...and that's your responsibility to manage. It's not Om's fault if such a thing happens...? I'm failing to understand your point

11:17 also don't know what you mean by "highlighted or in edit mode in local state"

11:18 j-pb: ddellacosta: any local state, highlighting or editing was just an example

11:18 ddellacosta: again, if you're talking about associating arbitrary items in app data with items in component local state, that is absolutely on the application developer to manage

11:18 but maybe I'm misunderstanding

11:18 as it is, I've never ever had a problem with Om similar to what you've talked about that wasn't my own doing, or at least enforced by the semantics of React, finally

11:19 dnolen: j-pb: what you're saying doesn't make any sense.

11:20 component local state has nothing to do with cursors at all.

11:20 component local state mappings are done via React keys.

11:20 hellofunk: j-pb: i just ran your gist, what is the problem you are having anyway? it removes the :ref 3 as you expect

11:20 dnolen: if you delete an entry, all the components wills get re-rendered because all their indexes must necessarily change

11:21 j-pb: hellofunk: and changes the mapping of local state to cursored element

11:21 dnolen: j-pb: it does not

11:21 ddellacosta: j-pb: local state has nothing to do with cursors

11:21 j-pb: either I'm making an obvious mistake in that gist, or it does indeed happen

11:22 ddellacosta: j-pb: the obvious mistake you are apparently making is assuming Om has some responsibility to manage associations between what you've put into component local state and app data

11:22 dnolen: j-pb: because you're not supplying react keys, I already said this

11:23 j-pb: please don't make blanket statements if you don't understand how the thing actually works

11:23 the code is just wrong

11:23 ddellacosta: anyways, I've gotta go, good luck (especially to dnolen if you continue to try to explain this...haha ;-)

11:23 sharms: ddellacosta, Cr8: Ah ha! I figured it out, if I call flatten on them first, then apply str, all is well

11:24 j-pb: dnolen: yeah, with react keys you can probably circumvent this, but this doesn't change that this illustrates the problem with cursors

11:24 hellofunk: j-pb: i see what you are saying, and I understand your confusion. However, trying to blend your local state to the app state like this is a recipe for bugs in general is not how you should approach things.

11:24 dnolen: j-pb: it has nothing to do with cursors, stop saying that

11:24 if you wrote this in React same bug

11:24 wrong state

11:25 j-pb: dnolen: yeah, it's reacts semantics bleeding though

11:25 dnolen: bleeding?

11:25 j-pb: must be a german expression I badly translated,

11:25 hellofunk: j-pb: the behavior in your gist is exactly *correct* -- the individual components remain in existence, the data you pass to them changes, that's the whole point

11:26 j-pb: the last component that was created is the one that goes away when the data no longer needs to build it. the others remain alive.

11:28 tbaldridge: In react, can't you tag individual elements with ids? that way React can reorder/splice lists of components? I don't understand the problem at hand, but that might help.

11:28 dnolen: j-pb: anyways not a bug, never was a bug, and this stuff is documented and well understood by React & Om users.

11:28 j-pb: dnolen: shining through, in german you can say "bleed through" :)

11:33 tbaldridge: yeah I know

11:35 hellofunk dnolen: yeah I know that you accept that as a part of interacting with react, I still think that juggling cursors, state, and react-id's is an unpleasent way to program

11:35 dnolen: j-pb: I already it doesn't have anything to do with cursors

11:35 result would be identical with pure props

11:36 I have nothing more to say about this.

11:46 j-pb: dnolen: btw, this discussion with justin_smith, wasn't about that Om should change, just that reagent shouldn't try to be like Om

12:01 kungi: `:questionaire/2-3-keine-angabe

12:01 ,:questionaire/2-3-keine-angabe

12:01 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :questionaire/2-3-keine-angabe>

12:02 kungi: O.o

12:02 Why does this keyword lead to an exception?

12:03 oddcully: kungi: the leading number

12:03 Bronsa: kungi: numbers are not allowed

12:03 kungi: ,:3

12:03 clojurebot: :3

12:03 kungi: ,:3-2

12:03 clojurebot: :3-2

12:03 Bronsa: kungi: an implementationd etail

12:03 detail*

12:04 oddcully: ,::1-way

12:04 clojurebot: :sandbox/1-way

12:04 TMA: ,:foo/bar

12:04 clojurebot: :foo/bar

12:05 kungi: Bronsa: thank you

12:06 Bronsa: kungi: IIRC there's a ticket to make the reader more strict

12:07 kungi: Bronsa: nice idea. It's the first real weirdness I encounter with clojure

12:07 j-pb: kungi: yeah I agree :D

12:07 Bronsa: kungi: oh there are a lot of weird edge cases like this if you try and find them :)

12:08 kungi: Bronsa: I am not trying to find them thank you

12:08 TMA: ,:1-

12:08 clojurebot: :1-

12:08 TMA: ,'1-

12:08 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 1->

12:09 TMA: ,(symbol? :foo)

12:09 clojurebot: false

12:10 j-pb: how is that weird :)?

12:11 oddcully: ,(keyword? :1-way)

12:11 clojurebot: true

12:12 TMA: ,(:foo {:foo :bar})

12:12 clojurebot: :bar

12:12 TMA: ,('foo {'foo :bar})

12:12 clojurebot: :bar

12:12 TMA: ,(1 {1 :bar})

12:12 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval73 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval73 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n [c...

12:13 j-pb: ,({1 :bar} 1)

12:13 clojurebot: :bar

12:14 TMA: symbol and keyword look sufficiently alike (and unlike say numbers), yet they are not related

12:14 j-pb: yeah true

12:14 TMA: ,({1 :bar} {{1 :bar} :quux})

12:14 clojurebot: nil

12:15 TMA: if that's not counterintuitive (aka weird) then what is?

12:16 j-pb: TMA, well if you think about it in terms of IFn implementations it's pretty intuitive :D

12:16 Bronsa: TMA it's not unintuitive at all, really

12:18 TMA: for me at least, it is unintuitive; it is the same level of unituitiveness as (or nil 1 2) returning some other "unfalse" value than 1

12:18 ,(or nil 1 2)

12:18 clojurebot: 1

12:22 TMA: ,`(** ++ , %)

12:22 clojurebot: (sandbox/** sandbox/++ sandbox/%)

12:23 TMA: ,`(*1* +1+ %1%)

12:23 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: +1+>

12:24 TMA: *, + and % are obviously symbol constituent characters. *1* is a symbol, why +1+ is not?

12:24 why the inconsistence?

12:25 that's what is counterintuitive in the naming

12:25 Bronsa: because +1 is a number while *1 is not?

12:28 TMA: ,`(/ // /a /1 foo/a foo/1 foo// foo//1 a/ a//)

12:28 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: //>

12:29 TMA: Bronsa: why should be that relevant?

12:30 Bronsa: TMA why shoudln't it? writing +1+ is no differnt than writing 45d

12:30 obviously not a valid number

12:30 j-pb: ,'+1+

12:30 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: +1+>

12:30 j-pb: ah

12:30 TMA: Bronsa: exactly. therefore obviously a symbol name

12:31 Bronsa: what?

12:31 clojurebot: what is http://gist.github.com/306174

12:33 TMA: ,45d

12:33 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 45d>

12:35 TMA: if 45 is OK and 45 d is acceptable too, why it is not parsed as 45 and d? multiple parentheses are parsed as one parenthesis = one token, there is no need to put spaces in them because "((" is not a valid parenthesis token, even though "(" is

12:36 Bronsa: ,45M

12:36 clojurebot: 45M

12:36 Bronsa: now imagine if your semantics were in place and you typo'ed 45MyClass

12:36 TMA: if the "45" then "d" interpretation does not look correct then there is one obviois solution -- make 45d a symbol

12:36 Bronsa: please no

12:37 scottj: TMA: if (foobar) doesn't exist would you expect Clojure to turn it into (foo bar)?

12:37 j-pb: TMA: you can always (symbol "something")

12:38 Bronsa: digits are not valid leading chars for a symbol nor is +- followed by a digit

12:38 TMA: j-pb: which then cannot be referred to in a simple and pleasant way

12:38 Bronsa: that's documented.

12:38 and it's not going to change so this discussion is meaningless

12:38 j-pb: TMA: early failure is more important in this case, imagine the number of times you want a symbol wthat looks like a number, and the number of times you have a typo in a number

12:40 TMA: Bronsa: I am trying to understand _why_ has clojure departed from the lisp tradition.

12:41 j-pb: TMA: because the lisp tradition often means theoretical nicety is more important than day to day usefullness

12:41 TMA: and clojure seems to prefer day to day usefullness to living in an ivory tower

12:41 Bronsa: TMA there are more significant areas in which clojure has departed from the lisp tradition.

12:44 wasamasa: huh, I thought you could define constants wrapped in +

12:44 ,+foobar+

12:44 clojurebot: #error {\n :cause "Unable to resolve symbol: +foobar+ in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: +foobar+ in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: +foobar...

12:44 wasamasa: SEE

12:53 TMA: ok. I don't have the data on the failure modes of other programmers; I have only my own. And as I do not use inline numerical constants too much, I might underestimate the importance of an early failure there

13:18 snowell: Hmm. I have a sequence of java objects and I wanted to map a function call

13:19 I found that (map .stringValue myCol) doesn't work; you have to do (map #(.stringValue %) myCol)

13:19 Any special reason it doesn't try to resolve .stringValue as a function call?

13:21 Eh, I guess the anonymous function is process at runtime instead of compile-time. That's probably the entirety of the reason

13:23 sharms: snowell: what about (map str myCol)

13:24 snowell: Well in this case, I believe stringValue and toString function differently

13:24 stringValue comes from an interface

13:27 amalloy: snowell: because stringValue is a method, not a function

13:27 ambrosebs: Bronsa: I'm resolving :host-interop calls by piping ast nodes back into (-> ast analyze-host-expr validate) after adding type hints manually to the arguments. This gives back a resolved call. The problem seems to be emit-form seems to return the same output regardless.

13:28 Does that ring a bell?

13:28 snowell: amalloy: You know, until just now I've always kind of used those words interchangeably. I don't know what's real anymore

13:28 amalloy: methods exist in java, and functions exist in clojure

13:28 snowell: Makes sense

13:28 amalloy: clojure functions are values, which can be stored in locals or in vars or whatever

13:29 methods are something only the compiler can touch

13:29 ambrosebs: Bronsa: the problem is (eval (emit-form checked-ast)) gives a reflection warning, even though it seems like I've resolved the nodes manually.

13:29 amalloy: (because they aren't values)

13:30 Bronsa: ambrosebs: I'm sorry I don't have time today -- can you send me a mail with an example? I'll take a look tomorrow

14:45 seangrove: gfredericks: Thanks, sounds excellent! I'll look into both of those points,

14:49 gfredericks: And I don't suppose there's an easy way to get it to generate certain character sets, e.g. Japanese/Korean/Tamil/etc.?

14:49 gfredericks: seangrove: oh hey actually

14:50 seangrove: I have this regex->generator function which probably doesn't support the regex character classes you'd need already, but probably could with a small bit of effort

14:51 https://github.com/gfredericks/test.chuck#string-from-regex

14:51 if it's worth the effort to you I'd be happy to try to point out where the changes would go

14:51 seangrove: Yeah, I'd be willing to give it a go

14:52 gfredericks: are you familiar with the jvm regex features for the sort of charsets you're after?

14:53 seangrove: Ah, I'm actually in cljs for now :P

14:53 Might be a bit of a deal breaker

14:53 gfredericks: oh man yep

14:53 any idea if js regexes have such things?

14:54 it'd still be a big effort, I'm just curious

14:54 seangrove: Possibly http://stackoverflow.com/questions/6787716/regular-expression-for-japanese-characters

14:54 Looks like the same idea, finding the right ranges

14:54 AnonGen: Can someone please tell me a good video for begginers?

14:55 I found a Rich hickey video on Utube but it was not for newbs

14:55 seangrove: gfredericks: Also, here's what I have for generating strings of 10 chars - any way to change that to a *minimum* of 10 chars? (gen/fmap clojure.string/join (gen/vector gen/char-alphanumeric 10))

15:01 gfredericks: seangrove: oh jvm has a special thing for specifying these blocks: http://docs.oracle.com/javase/7/docs/api/java/lang/Character.UnicodeBlock.html#forName%28java.lang.String%29

15:01 my lib (on the jvm) could work with raw ranges already

15:02 seangrove: yeah one idea is you could generate one fixed-length string and one variable length string and combine them together

15:03 seangrove: gfredericks: Clever!

15:03 gfredericks: seangrove: if such a thing starts to offend your readable code sensibilities you might be interested in https://github.com/gfredericks/test.chuck#for

15:04 seangrove: an alternative is more args to gen/vector, specifying a min and max size, which has the obvious downside of having to specify a max size; I think it will generate larger strings right off the bat as well

15:08 seangrove: Ahem... (gen/fmap (fn [[fxd vr]] (clojure.string/join (into fxd vr))) (gen/tuple (gen/vector gen/char-alphanumeric 10) (gen/vector gen/char-alphanumeric)))

15:08 I'll keep that for now, but will look into test.chuck on the next generator :)

15:10 gfredericks: yet another library that problably doesn't work with cljs; diving into the whole test.check cljs world is pretty high on my todo list

15:10 I wonder what the best practice for contrib libs & cljc is

15:11 I assume rewriting in cljc would be a pretty big breaking change

15:11 and yet you could imagine cljc is more important for libs than for apps

15:11 seangrove: Seems important to me, but I jump between the two constantly

15:12 Things will probably coalesce sooner or later with some pretty clear/easy paths to getting things cross-platform

15:12 Not a ton of experience with it quite yet though, I think

15:13 gfredericks: once support for 1.6 isn't valuable it'll be easy

15:13 in the interim though...

15:14 augustl: is there anything in ring for responding with multipart/form-data?

15:16 amalloy: responding wih form-data? isn't that generally something that clients use to submit?

15:17 augustl: yeah, but liberator wants to write the response in the same content-type as the request

15:19 amalloy: augustl: that sounds like a misunderstanding of liberator

15:20 ie, you misunderstanding liberator, not liberator misunderstanding http

15:21 augustl: it seems that in liberator, if the client doesn't specify an accept header, liberator will respond with the same content-type as in the request

15:52 Seylerius: There a clojure lib for interacting with git?

16:02 Found it: clj-jgit.

16:16 the-kenny: augustl: won't liberator respond with the first value in :available-media-types?

16:17 augustl: the-kenny: hmm, I didn't know the ordering matters

16:17 the-kenny: for :available-media-types it does.

16:18 augustl: and then I can just return a blank string or whatever for the weird client that requests Accept: multipart/form-data :)

16:30 Seylerius: Hmm... Any decent reST parsers for clojure?

16:30 I can't find any—they all seem to hand off to sphinx or something.

16:31 wasamasa: why could this only be the case...

16:31 surely not ReST being a python-centric thing explicitly intended to be extensible in python for custom directives!

16:32 Seylerius: Fair point.

16:32 wasamasa: so far the only alternative implementation I've seen was in CL and did replace their directives with something homegrown

16:32 Seylerius: wasamasa: Got a preferred alternative? Markdown? Maybe Org?

16:33 wasamasa: Seylerius: not really

16:33 Seylerius: I suppose I'll just stick to markdown. Thanks for the info.

16:33 j-pb: markdown probably, wasn't there a HN post a few days ago about mardown rendering in cljs?

16:33 wasamasa: well, then you'll have the problem that the implementations don't agree on something actually standard

16:34 and that sucks

16:34 the only option to end this madness is to implement commonmark

16:34 org-mode is pretty emacs-centric

16:34 jackhill: pandoc support (at least) a large subset of ReST, so a non-python parsers isn't out of the realm of possibility

16:34 j-pb: yes there was :) http://carmenla.me/blog/posts/2015-06-22-reagent-live-markdown-editor.html

16:34 wasamasa: and the rest, hmm

16:35 j-pb: wasamasa: yeah, thats true and horrible about md

16:35 wasamasa: they sure look niche to me, but eh, in the end it's just markup

16:35 j-pb: welllllllll, actually writing hiccup code isn't that bad

16:35 wasamasa: if I just need to write something to communicate with people, it doesn't really matter what I pick

16:36 j-pb: yeah

16:38 wasamasa: the converting possibilities of both org-mode in emacs and pandoc are pretty nice to have though if you need to turn the documents into a different representation or format

16:38 j-pb: I wish instaparse was reversible :D

16:38 write it in whatever html abstraction you like, normalise it to hiccup, and emit it to whatever

16:40 HUgeneral: Anyone have problems with clojure repl on android?

16:40 amalloy: why would you normalize to hiccup? hiccup's main advantage is it's easy to write by hand; if you are generating markup from something else, use enilve/c.d.xml style tags, which are much easier to manipulate programmatically

16:40 Seylerius: I'm contemplating another evil plot, is the deal, and the goal is something between github and newsroom software, aimed at bringing github/bitbucket collaborative features to short-to-medium content creation. I'm aiming at having decent integration with static-site-generators like octopress and pelican, so that the tool can be used to deploy content as well, hence the need to decide on a format. I don't want to reimplement a

16:40 static-site-generator, which means I need to use either reST or markdown, most likely.

16:41 I've liked the structure of reST a little better, in the past, but octopress only supports markdown. So MD's probably the better choice.

16:43 snowell: Anybody know how to coerce a value into a java primitive int?

16:43 I can only seem to get Integers

16:43 ,(type (int 5))

16:43 clojurebot: java.lang.Integer

16:44 Bronsa: snowell: type takes an Object, it will be boxed

16:44 (let [x (int 4)] ;; x is unboxed )

16:44 snowell: Well I'm using it in a function call, e.g., (.insertColumnSelectionAt (int i) (ColumnSelection…))

16:45 And getting "No matching method found: insertColumnSelectionAt for class java.lang.Integer"

16:45 Because it's expecting an int

16:45 Bronsa: snowell: primitive integers can't be method targets

16:45 snowell: maybe you meant (.insertColumnSelectionAt (ColumnSelection. ..) (int i)) instead?

16:46 snowell: public void insertColumnSelectionAt(int theIndex, ColumnSelection theSelection)

16:46 Bronsa: snowell: well you need the target class

16:46 foo.bar(baz) is (.bar foo baz) in clojure

16:46 snowell: Right...

16:46 Oh

16:46 Bronsa: you'd invoke that method like target.insertColumnSelectionAt(i, selection) in java

16:47 snowell: Is there any way I can erase the last couple minutes so nobody can read it?

16:47 Bronsa: you're missing the `target`

16:47 snowell: I've been writing clojure code for months… so this is pretty embarrassing :/

16:48 (inc Bronsa)

16:48 jhn: I'm trying to figure out why the following isn't working as I expect, and what I can do: https://gist.github.com/jhn/bc797e8a107609425919

16:48 Bronsa: sigh. lazybot is missing again

16:48 snowell: He was here yesterday

16:49 jhn: i think it has to do with (product) being lazy, but I'm not really sure what the correct approach would be

16:50 amalloy: jhn: you are calling set functions on a thing that is not a set

16:50 ie, a lazy seq is not a set

16:50 jhn: i see.

16:52 amalloy: why does it work the first time, though?

16:53 meaning, the first time I work the "crashes" version, on a fresh atom, it works

16:53 and sets it the atom properly. but the second time I call it it fails

16:53 I would expect the first time to fail as well?

16:54 wow typos are eating me alive today...

16:54 amalloy: just bad luck. it'll happen to work sometimes if one of the inputs is a set and the other isn't

16:54 based on which way difference chooses to do stuff

16:56 jhn: bad luck? but this always happens the first time. here's what I mean: https://gist.github.com/jhn/bc797e8a107609425919#file-t2-clj

17:03 amalloy: yes, i mean you are breaking the contract of set/difference, so anything that happens is just luck from your perspective

17:03 it happens to work if the non-set argument is larger than the set argument, or maybe if it's smaller, i forget

17:04 j-pb: the reason is this check

17:04 https://github.com/clojure/clojure/blob/b5d0e84f92038449312bea4c31dcdedd499e28b8/src/clj/clojure/set.clj#L53

17:05 ah no sorry, I read your code differently

17:05 curious

17:06 amalloy: j-pb: there is a particular reason why it happens, but the point is you shouldn't have to read the source. you know you are breaking the contract of calling a function, so anything good or bad that happens is just a coincidence

17:07 j-pb: amalloy: yeah, doesn't mean you won't learn something by understanding why it fails though :)

17:07 jhn: amalloy: to be fair, i'm curious as to the specific reason, but I agree.

17:07 thanks guys!

17:07 j-pb: ah no I think my first assumption was correct

17:08 jhn: let me think about this for 2 mins :D

17:09 jhn the thing that crashes is your difference call, (btw you never use its return value I'd guess you want something like (rese! tat diff)

17:10 jhn: j-pb: yeah, that's just a simplified version of the function that reproduced my bug.

17:11 j-pb: jhn: is (products) the same on both calls?

17:11 jhn: yes

17:14 Seylerius: Are there any java/clojure static site generators?

17:16 j-pb: jhn: do the values of (products) repeat?

17:16 jhn: or are they all unique

17:17 Seylerius: plenty :), you mean to generate static html?

17:17 jhn: they're a list of maps that don't have any dups.

17:17 j-pb: Seylerius: laser, enlive, stencil

17:17 Seylerius: from the to of my head :)

17:18 jhn: alright, if you look at this line

17:18 https://github.com/clojure/clojure/blob/master/src/clj/clojure/set.clj#L53

17:18 Seylerius: j-pb: Thanks. I'll take a look at those.

17:19 j-pb: Seylerius: hiccyp is also really important :)

17:19 hiccyp

17:19 hiccup

17:19 * Seylerius nods

17:20 j-pb: jhn: in your initial iteration that statement will be

17:20 ,(< (count [1 2 3]) (count #{}))

17:20 clojurebot: false

17:20 j-pb: and in the ones after that

17:20 ,(< (count [1 2 3]) (count #{1 2 3}))

17:20 clojurebot: false

17:20 j-pb: lol

17:20 note to self, go to bed it's late in germany

17:23 jhn: second best guess, its actually line https://github.com/clojure/clojure/blob/master/src/clj/clojure/set.clj#L59 when you call it the first time, s2 will be empty and the reduce will just shortcut to s1

17:23 ,(reduce disj [1 2 3] #{})

17:23 clojurebot: [1 2 3]

17:23 j-pb: but if it's non empty as in the follwing iterations, you'll call disj on a seq, which isn't defined (a vector in this case)

17:24 ,(reduce disj [1 2 3] #{1 2 3})

17:24 clojurebot: #error {\n :cause "clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentSet"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentSet"\n :at [clojure.core$disj invoke "core.clj" 1452]}]\n :trace\n [[clojure.core$disj invoke "core.clj" 1452]\n [clojure.core.protocols$iter_reduce invoke "protocols.cl...

17:24 j-pb: jhn: and that's your explanation :)

17:42 jhn: j-pb: I'll definitely dig in after work. thanks a lot!

17:43 j-pb: jhn: just wrap the (products) cal in a (set (products))

17:43 jhn: yeah, that's what I ended up doing

17:43 j-pb: k :)

17:45 bitts: Is there a way to refer to the map you're building? Like this.. (assoc {} :a 4 :b (:a this-map))

17:48 arrdem: bitts: In the general case, no. You can use as-> or let to bind the previous partial form to a name and then manipulate it, but there is no support in the assoc function for this.

17:49 bitts: arrdem: thanks.

17:49 j-pb: bitts: clojure doesn't allow for circular datastructures afaik

17:50 bitts: which is a good thing tm :)

17:51 arrdem: You can make circular datastructures, but it requires some legwork.

17:51 j-pb: bitts: clojure has immutable _persistent_ datastructures that are values, thus there is no reference concept

17:51 which means you can't persist somethign circular without infinite memory

17:51 arrdem: That's not the correct sense of persistent.

17:51 j-pb: arrdem: can you think of a way doing some nifty closure nesting and magic

17:52 arrdem: not using something like transient

17:52 arrdem: how so?

17:53 arrdem: "Persistent" refers to the fact that "old" values are still legitimate and unchanged (immutable).

17:53 Persisting datastructures via pr and read-string is different altogether.

17:53 j-pb: yeah, but this has the neat side effect, that they are also "pesistent" in the serializable sense

17:55 arrdem: You can't make a circular immutable datastructure without a reference type. I forget how it worked, but there was a demo here a long time ago of an infinite seq constructed by delivering a delay to itself.

17:55 bitts: by building the {} with reduce you can refer to things in the {} as you're building them, from within the reduce function.

17:55 amalloy: arrdem: a promise

17:55 arrdem: there we go thanks amallo.

17:56 j-pb: amalloy, arrdem: yeah but a promise is not an immutable/persistent value ;)

17:56 amalloy: which is of course another mutable reference, even though it mutates only once

17:56 j-pb: and a reference type

17:56 yeah :)

17:56 amalloy: j-pb: but because clojure's sequence interface is open to extension, you can easily create an infinite self-referential sequence

17:57 j-pb: amalloy: sequences are not pesistent imho

17:57 amalloy: because of the deferred evaluation

17:57 amalloy: that is not really a thing you can have an opinion about, much less a humble one

17:57 (reify ISeq (next [this] this) (first [this] 1)), plus various other junk to satisfy irritating interfaces

17:59 j-pb: amalloy: yeah, but sequences are not really immutable, they encapsulate a reference type

17:59 a kinda, sorta promise in the form of a function

17:59 amalloy: even worse, they aso encapsulate side effects, so I'd argue that they're not a datastructure at all

18:00 (unless you count functions as datastructures)

18:08 lvh: If I have a fn that expects something slurpable but I have it as a string right now, what do I do? StringReader it?

18:09 arrdem: lvh: you could do that, but having a single function handle your IO and processign is probably a design mistake...

18:09 *processing

18:09 Makes it harder to test yadda yadda

18:09 lvh: arrdem: I agree in general, but it's a convenience function I didn't write: https://github.com/aphyr/less-awful-ssl/blob/master/src/less/awful/ssl.clj#L134-L138

18:10 And part of the reason why I want it to take strings is precisely so it becomes more testable :)

18:12 bitts: arrdem: consider (assoc {} :a (reduce f [] coll) :b (can't sum :a values) ) you could do this.. (reduce (fn [m x] (assoc m :a 5 :b (:a m))) {} coll)

18:17 j-pb: bitts: hu? :b will be nil

18:18 ,(reduce (fn [m x] (assoc m :a 5 :b (:a m))) {} [1 2 3])

18:18 clojurebot: {:a 5, :b 5}

18:18 j-pb: ah sorry

18:18 amalloy: arrdem: it's nice for libraries to accept Reader instead of String or whatever, so it can consume the input lazily and so on

18:18 j-pb: ,(reduce (fn [m x] (assoc m :a 5 :b (:a m))) {} [])

18:18 clojurebot: {}

18:18 j-pb: ,(reduce (fn [m x] (assoc m :a 5 :b (:a m))) {} [1]), three times the lucky charm :)

18:18 clojurebot: {:a 5, :b nil}

18:18 j-pb: bitts: because this is equivalent to

18:19 ,(let [m {}, m {:a 5 :b (:a m)}, m {:a 5 :b (:a m)}] m)

18:19 clojurebot: {:a 5, :b 5}

18:20 j-pb: amalloy: yeah but slurp seems a bit too general

18:29 bitts: j-pb: I do this all the time to collapse a collection pf maps into a single map.

18:32 j-pb: for instance adding up like like keys or conj-ing like keys in each map into a vector.

19:05 Seylerius: ,(map #(if-not (number? %) %) [:a 1 :b 2 :c 3])

19:05 clojurebot: (:a nil :b nil :c ...)

19:07 Seylerius: ,(remove nil? (map #(if-not (number? %) %) [:a 1 :b 2 :c 3]))

19:07 clojurebot: (:a :b :c)

19:07 * Seylerius nods

19:11 Seylerius: How do I use .startsWith?

19:12 Ah, nvm.

19:15 arrdem: Is there a way to make leiningen fuse the install and uberjar tasks?

19:16 It looks like when I do lein do clean,install,uberjar it recompiles everything for no reason.

19:27 hyPiRion: arrdem: Oh yeah, that's https://github.com/technomancy/leiningen/issues/1816

19:28 arrdem: Neat.

19:47 hyPiRion: well in lieu of that I managed to use make to cache jars and escape rebuilds...

19:49 amalloy: when i use make for java projects i remember i'm an old man

19:50 arrdem: ugh why is the version string evaluated when the k/v pairs are quoted...

19:50 s/string/form/g

22:02 ddellacosta: ,(println "testing")

22:02 clojurebot: eval service is offline

22:02 ddellacosta: &(println "testing")

22:05 puredanger: Assuming you're a mod, but let me know if there's a better person to ask this. Is there some way I could get access to clojurebot? I was blocked more than a year ago, for a completely unknown reason, and it appears that lazybot is not running any more, so I can't run code on #clojure at all. I've tried asking politely but have gotten no response from hiredman: https://github.com/hiredman/clojurebot/

22:05 issues/5

22:06 that link again was: https://github.com/hiredman/clojurebot/issues/5

22:06 It's a bit frustrating that a user can be blocked from accessing clojurebot based on someone's personal whim, with no explanation.

22:06 puredanger: I'm an op but don't know anything about clojurebot

22:07 ddellacosta: puredanger: a, sorry--I thought the mods had some control over what bots ran. My mistake!

22:50 TEttinger: ddellacosta: hiredman has you on ignore for forgotten reasons, but it seems like he isn't revisiting past ignores. it isn't that hard to run a lazybot if you have a server or old computer handy!

23:03 TimMc: ddellacosta: amalloy_ is an op of this channel, but that's unrelated to the bots. I mean, he happens to run lazybot, but it's not related to him having channel op permissions.

23:03 The bots are not official, in other words.

23:04 arrdem: I think there's a case to be made that this is a defect rather than a feature. Clojure/Org dreaming goes here.

23:05 TimMc: You think only official bots should be present here?

23:06 arrdem: With the disclaimer that I'm also on hiredman's blacklists, I think it's kinda unreasonable to say that ddellacosta and I have no recourse or appeal to what seem to be general community resources.

23:07 Consider the exension of this argument that it would be no problem if Clojars ip banned me with no expalantion.

23:08 ,1

23:08 clojurebot: eval service is offline

23:08 TimMc: I see those as hugely different.

23:09 arrdem: How so? Just as I can run another IRC bot I could run my own Maven servers.

23:09 TimMc: Don't get me wrong, I think it's quite rude of him, but it's nothing more than a public repl. You have a repl of your own, and you can paste the results in here.

23:09 And most of the time, you can use lazybot to the same effect.

23:10 Clojars is baked into a build tool. Clojurebot is not.

23:10 arrdem: I would argue that Clojurebot is baked into IRC and every newbie learns to use it.

23:11 More on this later.

Logging service provided by n01se.net