#clojure log - Jul 07 2015

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

2:42 tmtwd: so, I can write an app in clojure , put it into a jar, and then it can be deployed on any machine with a jvm?

2:42 justin_smith: tmtwd: yes, "lein uberjar" makes it pretty easy

2:42 tmtwd: that is sweet

2:43 so if I pass someone a jar to run, they needn't even know it was written in clojure?

2:44 justin_smith: tmtwd: not neccessarily, though it will contain clojure source code :)

2:44 tmtwd: thats really cool

2:44 justin_smith: tmtwd: I did have an issue with one client, where we couldn't use clojure any more because they discovered we were using clojure because they were trying to use static analysis tools, and those don't work on clojure.

2:45 that's was a weird way to say that

2:45 anyway, we secretly shipped clojure, and it was fine until they cound't run their SA tool

2:45 tmtwd: bummer

2:45 amalloy: justin_smith: their static analysis tools worked well enough to tell what language was being used. sounds good to me

2:46 justin_smith: amalloy: heh - they were source level analysis tools :P

2:46 but it wasn't until trying to run the tools that they noticed we were shipping .clj

4:19 J_A_Work: query about reagent and field focus: https://groups.google.com/forum/#!topic/reagent-project/RNk998XWxtw

4:24 joschka: What am I doing wrong that I have to evaluate my functions `in the correct order` after I do (cider-jack-in). A simple (cider-eval-buffer) doesn't do it, I always end up with an "Unable to resolve symbol x" error because some later on positioned function wasn't evaluated yet. The functions don't need to be in 'some order' in the file right?

4:24 I feel like such an idiot asking that question :D

4:27 upon starting using (cider-jack-in), (ns-publics) retuns an empty map, shouldn't all functions be evaluated anyway right from the beginning?

5:29 pyr: hi clojure!

5:30 is there a generally accepted way of using component when you need an arbitrary number of components for a specific functionality

5:30 e.g: your app may open one to n "input sinks" which will adhere to a specific protocol, but you can't know in advance how many

5:31 does component cater to this ?

7:20 magnars: joschka: Clojure is evaluated top-down, so you should define functions before they are used.

8:03 joschka: magnars: yes, thank you I already found (declare [&forms]) and all of the logic behind top down evaluation

8:50 elvis4526: hey, so i tried using H2 to mock a database, but my existing postgresql seem to not works right away with H2 :-()

8:50 I get this: "org.h2.jdbc.JdbcSQLException: Attempt to define a second primary key; SQL statement:"

8:51 Is there any specific way I need to handle references to other fields when using H2 compared to postgresql ?

8:53 uh, I think I just need to quote the identifiers

9:28 okay i just switched to sqlite instead lol

9:29 justin_smith: joschka: yes, in clojure functions need to be defined in order

9:29 joschka: amazing, but true

9:29 sorry, someone already said that

10:19 dstockto1: new videos seem to have been posted on clojuretv

10:21 puredanger: yeah, day 2 should be going up today

10:21 oddcully: woohoo

10:22 dstockto1: cool, still waiting for the om next one

10:22 puredanger: not sure they'll get to all of them today

10:40 nooga: anyone using manifold? I'm looking for a decent way to model a stream "valve"

10:49 Manaphy91: I have a big hash map that cause a stack overflow... I use it like an advice for a dynamic programming algorithm... how can I evaluate memory size of a data structure?

10:57 TimMc: Manaphy91: Three things.

10:57 expez: (ArrayList.) What is the .? I thought this was a reader macro?

10:58 TimMc: One, do you mean an out of memory error? I'm not sure how a hash map would cause stack overflow.

10:58 Two, advice... is this like memoization? Not really important here, just curious.

10:59 oddcully: expez: ctor call

10:59 expez: new ArrayList() in javanese

10:59 TimMc: Three, evaluating the size of a data structure in Clojure in particular and in the JVM in general is actually really difficult. Might be possible, but it basically isn't done.

10:59 Manaphy91: exactly memoization!!

10:59 expez: Manaphy91: the jvm doesn't have tail call elimination. You're likely using a recursive algorithm without using loop/recur. If you were actually running out of memory you'd get OutOfMemoryError and not StackOverflowError

10:59 TimMc: OK, cool. :-)

11:02 Manaphy91: exactly I obtain 'Exception in thread "main" java.lang.StackOverflowError, compiling:(/tmp/form-init8694410201665152526.clj:1:72)`

11:02 expez: oddcully: yes, but what is the '.'? I thought this was a reader macro, which would be replaced by a constructor call at read time, but the reader returns "(ArrayList.)". I suppose I've answered my own question, and the "." is another token the compiler reads and replaces with a call to the constructor.

11:05 Manaphy91: You need to read about loop/recur. This might be an OK source if you don't have your favorite clojure book at hand: https://blog.8thlight.com/patrick-gombert/2015/03/23/tail-recursion-in-clojure.html

11:06 oddcully: expez: ah sorry, i took that for an less advanced question

11:07 Manaphy91: expez: I know what are loop and recur... I don't understand why I obtan stackoverflow and I think it is due to extreme memoization....

11:09 expez: Manaphy91: That won't give you a StackOverflow error but a OutOfMemoryError. Allocate more memory to your jvm and you'll get the same result. Allocate a bigger stack and your program might start to run, depending on how deep the recursion is.

11:41 justin_smith: Manaphy91: memoization does not cause StackOverflow

11:41 Manaphy91: manual recursion (self call not using "recur") will

11:41 Manaphy91: recur isn't just for loop, it is for functions too

11:42 ,((fn [x] (if (> x 10) x (recur (+ x 3)))) 4)

11:42 clojurebot: 13

11:44 justin_smith: Manaphy91: oh, I just scrolled up - in order to use a hash map to drive a dynamic programming algo, I would use trampoline

11:44 (doc trampoline)

11:44 clojurebot: "([f] [f & args]); trampoline can be used to convert algorithms requiring mutual recursion without stack consumption. Calls f with supplied args, if any. If f returns a fn, calls that fn with no arguments, and continues to repeat, until the return value is not a fn, then returns that non-fn value. Note that if you want to return a fn as a final value, you must wrap it in some data structure and unpack it after trampoline returns."

11:44 Manaphy91: Yes, you are right!! I'm try to debug it! Any advice about debug in clojure? Usually i do a lein run and simply redirect output!!

11:45 justin_smith: Manaphy91: there's a few options. A simple one is to define an atom (def debug (atom nil)) and somewhere in your code call (reset! debug x), then you can play with that data as captured at that point in your code

11:45 Manaphy91: there's also tools.trace

11:45 Manaphy91: depending on editor preference, there is good debugging support in cursive (intellij idea) and cider

11:48 Manaphy91: I use vim, sorry but i'm not in emacs church...

11:48 I'm seeing tools.trace

11:50 justin_smith: Manaphy91: the atom based things has other variants too like (def debug (atom [])) ... (swap! debug conj {:context ... :values {...}})

11:52 Manaphy91: justin_smith: thanks!!

11:55 justin_smith: Manaphy91: my experience is that in a repl, if I can capture the values where the problem was happening, I can quickly sort out the answer (by rewriting interactively in the repl until I get the return value I want, or using those values as the basis for a unit test, or rewriting the code the generated those values...)

11:56 Manaphy91: one of the main things I have learned with Clojure is how sane values are. Functions and macros and Objects are so opaque and weird, but values are very straightforward.

11:59 Manaphy91: also, about the stack overflow / hashmap size thing - Clojure won't store a hash-map on the stack as far as I know

12:02 amalloy: it can't. objects are all on the heap, with only pointers on the stack

12:03 justin_smith: amalloy: I suspected that, but lacked proof / motivation to research right now :)

12:03 amalloy: the JIT may be able to move some stuff to the stack via escape analysis or something, i dunno

12:04 justin_smith: right, but the JIT is not about to "optimize" by blowing the stack

12:49 br0tat0chip: hi! i just started playing around with clojure and i got a little program working that updates some values in redis. does anyone have a good resource on websockets or how to get that to stream real time to a front end? ive done some research but not sure which is the simplest/straight forward way to go

12:58 elvis4526: I'm trying to understand clojure hiearchy system. I'm not sure I understand what you can use with (derive) ?

12:58 can you use something else than ::keyword ?

12:58 justin_smith: elvis4526: it creates heirarchies that will effect isa? and multimethod dispatch

12:59 elvis4526: you can use regular :keywords, or namespaced ::keywords, and use those keywords to mark more complex objects like records or maps

12:59 ,::foo ; just a shorthand

12:59 clojurebot: :sandbox/foo

13:00 justin_smith: elvis4526: the idea is that it creates an abstract heirarchy, decomposed from any concept of implementation or datatype

13:01 you can even create purely functional anonymous local heirarchies (though derive uses the mutable global heirarchy by default)

13:02 elvis4526: okay but then why something like (derive :user ::record) doesn't work ?

13:03 justin_smith: elvis4526: oh, right - you do need to use namespaced keywords

13:03 I forgot

13:03 ,(derive :foo/bar :foo/baz)

13:03 clojurebot: nil

13:07 elvis4526: Oh okay - then i guess what I don't understand is namespaced keywords. What's the default namespace of :keyword ?

13:07 justin_smith: elvis4526: ##(namespace :foo)

13:07 lazybot: ⇒ nil

13:07 elvis4526: yep that's what I get in a fn

13:07 justin_smith: ,(namespace :foo/bar)

13:07 clojurebot: "foo"

13:07 elvis4526: why ?

13:07 justin_smith: ,(namespace ::foo)

13:07 clojurebot: "sandbox"

13:08 justin_smith: elvis4526: because :foo has no namespace, ::foo has your current namespace, and :bar/foo has "bar" as a namespace

13:08 maybe that doesn't really answer why though

13:53 amalloy: justin_smith: since you're listing valid namespace forms: do you remember what the rarely-seen ::foo/bar does?

13:54 justin_smith: amalloy: expands the alias in the current namespace for foo

13:54 eg if you had (require '[clojure.string :as s]) ::s/bar would be :clojure.string/bar

13:54 iirc

13:54 Bronsa: yup

13:54 amalloy: dangit nobody ever remembers that. how am i ever gonna get to be the joker if everyone gets my riddles

13:55 justin_smith: amalloy: you might be conflating your batman villians

13:59 elvis4526: okay, I'm trying to imitate the concept of "parent constructor" in an OOP paradigm

13:59 maybe this will be more clear

14:00 but I'm really confused with what exactly is the relation with (derive) and the multimethods system

14:00 justin_smith: elvis4526: there is no relationship of functionality, only a relationship of identity

14:01 elvis4526: if there is no extension of a multimethod to ::foo, but ::foo is derived from ::bar and the multimethod is extented to ::bar, the method for ::bar will be called

14:01 if that helps

14:02 puredanger: it allows you to create an arbitrary hierarchy, that will be used to find method matches as with the Java OO hierarchy

14:03 justin_smith: yeah, I think that's a better way to put it, thanks

14:06 puredanger: I believe that there is a section covering multimethod hierarchies in Joy of Clojure, although I don't have the second edition to verify

14:07 justin_smith: I fleshed out some multimethod / heirarchy examples on http://conj.io too

14:09 lvh: Is it okay to read resource files in project.clj? I have a few SSL certs/keys for testing (pem files), I need them as strings in env (using weavejester's environ)

14:09 The obvious way to add things to env is through project.clj

14:09 justin_smith: elvis4526: my examples here http://conj.io/store/v1/org.clojure/clojure/1.7.0-beta3/clj/clojure.core/defmulti/

14:11 elvis4526: specifically example 4 is all that is relevant here I guess

14:24 chomwitt: why (str ["3"]) => "[\"3\"]" ? why do we quote? doublequotes?

14:26 lvh: Can I use the contents of a file in project.clj? I'd prefer to not have to copy-paste a big blob, but it seems like everything's quoted and I can't actually eval a thing.

14:31 oddcully: chomwitt: have you meant ,(apply str ["1"]) maybe?

14:32 snowell: lvh: You can wrap your `defproject` in a `let` and eval things up there to use inside

14:32 Whether or not that's a good idea in practice I'll leave up to the experts :)

14:32 lvh: snowell: oh, I didn't realize that worked

14:32 I guess it makes sense that it would :)

14:44 arrdem: hyPiRion: can I make lein use a file other than project.clj for the same purpose as project.clj?

14:56 chomwitt: oddcully: nop

14:58 amalloy: arrdem: `ln -s my-dumb-file.xml project.clj`

15:07 arrdem: amalloy: I thought not

15:08 amalloy: arrdem: there was that april fools joke lein-xml

15:08 but it is not really what you want

15:09 the-kenny: well if lein-xml can read project.xml as xml we can at least represent the xml as sxml :)

15:11 * arrdem mutters about lack of really transactional filesystems and plan 9 namespaces

15:29 {blake}: OK, I'm opening a DB connection like (def connection (up-connect)). But I want to put that in a function I can call at startup. Is possible? Or am I missing the boat/convention?

15:29 TimMc: something something component

15:30 {blake}: something something what? Is that what components are for? (Speaking of boats/conventions missed.)

15:31 TimMc: {blake}: https://github.com/stuartsierra/component might be appropriate for you

15:31 I've not used it myself, mind.

15:32 lodin_: Is it recommended to prefix a library's core namespaces with libraryname.core, where the core namespaces would be those that define public protocols, functions using those protocols, etc, and non-core would be data structures that implement the interfaces in the core?

15:32 {blake}: TimMc: Yeah, I've stared at it more than once. I somehow didn't think of it in this context.

15:32 But I guess that's "Database access: query and insert functions sharing a database connection" right there. :-/

15:34 TimMc: lodin_: "core" is just a default that lein uses because it needs *something* -- you don't want single-segment namespaces.

15:35 As for the overall pattern (ignoring the actual name), that's not a pattern I've seen, I think. Maybe a good idea, though!

15:35 lodin_: TimMc: Yeah, I know. I want to distinguish between the necessary parts of the library, and the "batteries included" part.

15:36 {blake}: Are there local statics?

15:37 lodin_: TimMc: The alternative would be to just have the core namespace in the library, and have all actual implementations in other libraries, but that doesn't feel quite right. (At it would e.g. make testing harder.)

15:37 amalloy: {blake}: in...what? clojure? java? some weird library? certainly not in the first two cases

15:37 but it's not 100% clear what you mean by local statics anyway. if you mean like in C, those are just sugar over a global static

15:38 jkni: lodin_: there's mention of that sort of organization using something like an impl namespace in Joy of Clojure 2e p. 199 but you won't really see it a lot at large

15:39 {blake}: amalloy: In an OO context, I would have a function that referenced a property. Like a DB connection. When you said "myconn := DB connection", the DB class would go look at connection, and return the value if the connection had been made, or make it, then return it, if not.

15:39 Even in a non OO context, I would have a function with a local static that did the same thing.

15:40 But if I say in Clojure (def connection)...and then later try to put something in connection? That's not even a thing, is it?

15:40 amalloy: {blake}: so, that is kinda dangerous to do carelessly because of multithreading

15:40 but you can easily enough define a delay that you deref every time, or a memoized function that you call or whatever

15:41 lodin_: TimMc, jkni: I'm going for this then. lib.core.X I mean.

15:41 {blake}: amalloy: Oh, a memoized function...yeah, that sounds right. That's what I'm trying to do, and I'd just forgotten how.

15:41 justin_smith: {blake}: an option I have done lately is to use an agent for things like that (agent instead of atom because atoms retry, and I wouldn't really want to retry db connection process)

15:41 TimMc: amalloy: Oho, C-M-SPC leaves the point where it is. This is better than my approach for copying sexps. :-P

15:42 justin_smith: {blake}: though if it won't be altered or redefined at runtime, a delay or memoize makes sense, yeah

15:42 amalloy: TimMc: it even lets you copy *multiple* sexps easily!!1!

15:42 TimMc: yeah

15:42 {blake}: justin_smith: I'll check it out. Yeah, I don't want to use delay.

15:43 justin_smith: {blake}: why not a delay? you would want to alter it later?

15:43 {blake}: I mean, the larger situation is that I have "(def connection (up-connect user pass))" and that gets called when I making the WAR, which upsets my dev-ops guys.

15:43 er, no "I" there.

15:43 justin_smith: {blake}: right, and a delay prevents that

15:44 though it requires a deref, but so would eg. an agent

15:44 and a deref vs. needing to call a memoized fn is like, 6 of one half dozen of hte other

15:45 {blake}: Oh, sorry. I think of delay as "delay(milliseconds)". =P

15:45 justin_smith: ,(def d (delay (println "FORCED!")))

15:45 clojurebot: #'sandbox/d

15:45 justin_smith: ,d

15:45 clojurebot: #object[clojure.lang.Delay 0x5d27ad7d {:status :pending, :val nil}]

15:45 justin_smith: ,@d

15:45 clojurebot: FORCED!\n

15:45 justin_smith: ,d

15:45 clojurebot: #object[clojure.lang.Delay 0x5d27ad7d {:status :ready, :val nil}]

15:45 justin_smith: ,@d

15:45 clojurebot: nil

15:46 {blake}: justin_smith: Groovy. Thanks!

15:46 (inc justin_smith)

15:46 lazybot: ⇒ 271

15:46 justin_smith: I like delay for things that won't be rebound, it's simpler (weaker) than the other reference types

15:46 which means I can trust it more

15:46 {blake}: Well, I'm gonna make my own reference type. With blackjack and hookers. In fact, forget the referencing!

15:57 amalloy: justin_smith: there was a fun bug in the error-handling for delay in versions earlier than like 1.4 or so

15:57 justin_smith: oh?

15:58 amalloy: eg, consider (let [s "whatever", t nil] (delay [(.length s) (.length t)]))

15:59 well, actually, it is better like this: (let [s "whatever"] (delay [(.length s) (/ 1 0)]))

15:59 the first time you dereference that delay, you get an aritmeticexception about divide by zero, as you'd expect

15:59 if you dereference it a second time, you get a null pointer exception on s

16:00 TimMc: hah, right

16:00 amalloy: (this isn't true anymore, but it was then)

16:00 TimMc: This is the :once thing.

16:00 amalloy: yes

16:01 the macroexpansion of delay promises to call the thunk only once, but if the thunk threw an exception it would actually be called multiple times

16:01 Bronsa: amalloy: how was it fixed? by caching the exception?

16:01 amalloy: yes

16:01 you could also imagine fixing it by throwing a BrokenPromiseException or whatever

16:02 {blake}: Why would there be a null pointer exception on s the second time?

16:02 Bronsa: :once can be really tricky

16:02 {blake}: the local is set to null after it's used

16:03 {blake}: a memory optimization that clojure uses to avoid blowing up the heap in certain situations

16:03 {blake}: Right, but--okay, so that's what gets cached, the null.

16:03 justin_smith: any votes for best kafka wrapper for clojure?

16:03 {blake}: samsa/core?

16:04 (I'm kidding. Don't go looking for that.)

16:04 justin_smith: {blake}: if I ever make a kafka wrapper for clojure I will name it starvation-artist

16:05 dnolen: Bronsa: on my work machine ~40ms for clojure.tools.reader to read cljs.core, ~70ms for cljs.tools.reader

16:05 TimMc: Hey, can someone remind me of the common problem people encounter with protocols where they implement the wrong thing? Like, the interface or something?

16:05 dnolen: I believe my work here is done :D

16:05 justin_smith: TimMc: like they import the protocol as a class but don't require the ns?

16:06 that's common enough an error

16:06 amalloy: TimMc: implementing the interface is fine. a problem is *using* the interface via (.m x) instead of the protocol function via (m x)

16:06 TimMc: No, something that causes Foo != Foo errors.

16:06 amalloy: TimMc: reloading

16:06 justin_smith: TimMc: reloading

16:06 TimMc: amalloy: Hmm, maybe that was it.

16:06 {blake}: Nice. I think I would make one called "Gatekeeper" that didn't work but just lagged and lagged and lagged, and then finally said "This was assigned only to you".

16:06 dnolen: Bronsa: nearing 2 orders of magnitude speed improvement over master

16:06 TimMc: I think this one wasn't about reloading.

16:07 Bronsa: (inc dnolen)

16:07 lazybot: ⇒ 22

16:07 Bronsa: dnolen: can't wait for a patch :)

16:07 dnolen: Bronsa: question is when/how you want it

16:07 it relies on *ns* being present, which requires ClojureScript master

16:07 and resolve-ns, things like that

16:08 Bronsa: dnolen: right. As I said a while ago, we need to release the new t.r at the same time as the new cljs

16:09 dnolen: I'll take the patch whenever it's ready and you tell me when you're ready to release cljs, I'm in no hurry

16:09 dnolen: Bronsa: OK it might be a while then - switching to analyzer/compiler perf work now

16:28 expez: Is cljs in cljs going to eliminate :refer-macros?

16:29 Bronsa: expez: IUC there will be no changes to how ns/macros work

16:43 nemelex: i'm new to clojure, can anyone tell me why i'm being silly by expecting this to work? ... http://pastebin.com/xKvzLVNa

16:45 justin_smith: nemelex: where is the entry namespace? why is it referred to but not required?

16:46 wait, that's probably just a small mistake in simplifying the code

16:46 nemelex: sorry, i skipped that ns off, but it is there - it's my internal thing

16:46 justin_smith: "Wrong number of args (0) passed to: PersistentArrayMap" means "too many parens around a hashmap"

16:46 ,({})

16:46 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: PersistentArrayMap"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: PersistentArrayMap"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 28]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" 0]\n [cloju...

16:46 justin_smith: viz

16:47 you'd have to look at the code for create to see where that is happening I guess

16:47 nemelex: ah ok, i assumed it was happening when i was passing body to create

16:48 i'll have another look -- thanks

16:57 markmm: Is there a emacs shortcut to sync the cider repl with a buffer you have changed

16:57 ?

16:58 arrdem: markmm: with or without saving the buffer?

16:58 markmm: C-c C-k will reload a file

16:58 markmm: arrdem: Ok thanks

16:59 arrdem: I think C-c C-l will evaluate the buffer whether it's saved or not but I'm not sure

17:04 markmm: arrdem: Yes it does do that, just tested it thanks

17:29 cfleming: amalloy: Sorry, I've been offline at a conference. The expiration is only for the beta, once it's stable upgrades will not be required.

19:35 whodevil: hello, I'm using lein ring uberwar then deploying it to tomcat which is running in debug mode, for some reason when I connect cursive to tomcat, it is not finding the namespaces. Is there something special I have to do to get cursive to pick up the bread crumbs?

19:40 ok, I'm dumb, nevermind nothing to see here.

20:00 tolstoy: When using datomic free in-memory, is there a way to remove all the AWS dependencies other than exclude each and every one of them?

20:04 arrdem: Nope. Welcome to raw Maven.

20:04 tolstoy: Oy. ;)

20:05 arrdem: That'd actually be an interesting project, define logical groups of dependencies and write a Maven wrapper that can describe exclusions and replacements...

20:05 tolstoy: Seems like of datomic-free doesn't support aws, etc, it ought not to depend on it.

21:20 jefelante: #/python

21:20 oops

22:37 puredanger: arrdem: you can do that in Maven with profiles

23:27 gfredericks: has anybody implemented a clojure collection that can keep arbitrary updated aggregations about itself?

23:27 I think finger trees can do that, but might be too general?

23:28 TEttinger: updated aggregations?

23:28 like remembering history?

23:28 gfredericks: no

23:29 like a map-reduce for arbitrary functions

23:29 I want to say just reduce but you wouldn't want it to be order sensitive

23:30 so the same kind of thing the hipster datastores use

23:30 TEttinger: I have no idea what you mean

23:30 gfredericks: word count!

23:30 TEttinger: do you mean a storage for transducers or something?

23:30 gfredericks: [{:sentence "hello there"} {:sentence "some more words"}]

23:30 ^ the collection would have precomputed the word count to be 5

23:30 TEttinger: ahhhhh

23:31 gfredericks: and as you add/update items in the collection it efficiently updates the word count

23:31 amalloy: i think such a thing is too general to have an efficient implementation really, aside from one that says "you do all the work yourself"

23:31 gfredericks: really? what about the hipster databases?

23:31 amalloy: you need some constraints on what the function can do

23:32 gfredericks: yeah it'd have to be whatchamacallit

23:32 commutative

23:32 turbofail: and associative

23:32 gfredericks: the reduce part I mean

23:32 yeah

23:32 reducers already has this kind of logic does it not?

23:32 amalloy: it also has to be invertible, or something like it

23:32 gfredericks: I don't think so; maybe I didn't explain it well

23:33 if an item changes you just recompute the function for that item

23:33 amalloy: gfredericks: but then you need some properties for the function "combining" all this stuff at the top level

23:34 gfredericks: just the commutative/associative part, right?

23:34 amalloy: no

23:34 gfredericks: if you store a tree of values

23:34 then you just walk up to the root

23:34 doing your log(n) work

23:34 ttt_fff: are the slides from https://www.youtube.com/watch?v=ByNs9TG30E8& available anywhere? I want to know what om next isa bout without watching 46 minutes of video

23:35 amalloy: gfredericks: that is basically what finger trees do, and the thing you're storing is the measure, as i recall

23:35 if you make the measure be something or other, then finger trees can efficiently concat/split

23:35 gfredericks: amalloy: yeah I figured finger trees could, I just didn't know off the top of my head if they were so general that you'd have to do manual work to wire it up

23:35 amalloy: but you can make it be something else and then you can keep a running sum of (f x)

23:39 ttt_fff: WTF IS OMNEXT about ?

Logging service provided by n01se.net