2012-08-04
| 01:09 | Frozenlo` | Is there clojure/clojurescript libraries to simulate mechanical or electrical systems? (à la Bret Victor would be nice) |
| 01:57 | Bastianx9 | || Paypal Account Full Information || Payment Method Liberty Reserve Only || Paypal Account Full Information || Payment Method Liberty Reserve Only || Paypal Account Full Information || Payment Method Liberty Reserve Only || |
| 02:16 | mdeboard | itext is the worst. |
| 02:19 | aperiodic | you mean that PDF parsing library? |
| 02:40 | mritz | whats the best way to have leon 1 and 2 both installed |
| 02:40 | mritz | is there like a virtual environment ? |
| 02:42 | eggsby | why not just have lein and lein2 in your $PATH ? |
| 02:47 | amalloy | mritz: just install them both, that's all there is. give the two scripts different names |
| 02:50 | mritz | amalloy: Thanks! that worked |
| 04:20 | leafw | hi all. If I have an int like (bit-shift-left 255 24), and I want to store it in an array of primitive ints, how can I cast it to signed int to do so? Clojure, righly so, complains that it can't be casted because it is out of range |
| 04:21 | leafw | i.e. how to store an unsigned int 0xff000000 in a java primitive int, which is signed? |
| 04:31 | pyrtsa | leafw: Don't know of a direct way, but this works for 32 bit: (defn int* [x] (let [i (bit-and 0x7fffffff x)] (Integer. (if (< x 0x8000000) x (+ -0x80000000 i))))) |
| 04:32 | leafw | pyrtsa: thanks. I am hoping there is a better way, for example casting to int at the right places within bit-and, bit-or, etc. |
| 04:32 | leafw | otherwise performance will suffer lots |
| 04:33 | pyrtsa | Like I said, I don't know of any. :/ |
| 04:35 | leafw | ,(byte 0xff) |
| 04:35 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for byte: 255> |
| 04:35 | leafw | that made no sense to me |
| 04:35 | leafw | so clojure considers hexadecimal not as bits filled in but as actual numbers |
| 04:39 | hyPiRion | leafw: Makes perfect sense |
| 04:39 | hyPiRion | ,0xff |
| 04:39 | clojurebot | 255 |
| 04:39 | leafw | hyPiRion: so what is the right way to do bit-wise math in clojure? |
| 04:40 | amalloy | leafw: there is no such thing as unsigned on the jvm |
| 04:40 | leafw | how to pack 4 bytes into one int? |
| 04:40 | leafw | mind giving an example? |
| 04:40 | leafw | amalloy: I am aware. In the java side, one always masks first to 0xff |
| 04:40 | hyPiRion | leafw: ##(ubyte 0xff) |
| 04:41 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: ubyte in this context |
| 04:41 | hyPiRion | oh, its name is something else, lemme check it up |
| 04:44 | leafw | no suggestions in the clojure cheatsheet for byte similar to ubyte |
| 04:44 | mdeboard | Did I reinvent the wheel here https://gist.github.com/3256063 |
| 04:45 | raek | leafw: unchecked-bit-shift-left |
| 04:45 | mdeboard | wrt metadata on proxies |
| 04:45 | hyPiRion | ,(unchecked-byte 0xff) |
| 04:45 | clojurebot | -1 |
| 04:45 | hyPiRion | ,(unchecked-byte 0xffff) |
| 04:45 | clojurebot | -1 |
| 04:45 | leafw | aha |
| 04:45 | leafw | thanks |
| 04:45 | leafw | so the unchecked math is what will do it |
| 04:46 | leafw | thanks a lot! |
| 04:46 | hyPiRion | no problem, it's hard to find |
| 04:46 | leafw | the cheatsheet doesn't list the bit-wise ops under the unchecked section |
| 04:51 | leafw | raek: Unable to resolve symbol: unchecked-bit-shift-left in this context |
| 04:51 | leafw | raek: so unchecked math must be invoked in a binding or something line that |
| 04:52 | raek | leafw: hrm, that functions does not exist, but other unckecked version for other operators do |
| 04:53 | raek | you can always do this: (unchecked-int (bit-shift-left 255 24)) |
| 04:54 | raek | 'unchecked-int' works as (int) in java (it throws away all but the 32 lowest bits) |
| 04:54 | amalloy | mdeboard: i think you may have just reinvented being crazy |
| 04:54 | leafw | ,(unchecked-int (bit-shift-left 255 24)) |
| 04:54 | clojurebot | -16777216 |
| 04:54 | leafw | good! |
| 04:54 | leafw | thanks raek |
| 04:55 | amalloy | like, ignoring whether proxy is the right answer ( i don't know what a PdfReader is, these implementations of the meta functions don't make sense |
| 04:55 | raek | I'm not totally sure how *unchecked-math* is used |
| 04:55 | leafw | lack of examples hinders it suse |
| 04:55 | raek | I think you are supposed to 'set!' it before you eval the defns or something |
| 04:55 | leafw | google is full of past examples, but unchecked math has changed lots over time |
| 04:56 | leafw | there is a *math-context* for with-bindings |
| 04:56 | leafw | http://clojuredocs.org/clojure_core/clojure.main/with-bindings |
| 04:56 | leafw | without an explanation on what it is for |
| 05:37 | leafw | I got the bit-wise math to work. In short, to imitate the java side of things with truncating primitives, one has to use unchecked-long (the only kind of cast that doesn't result in a reflection warning when using bit-or, bit-and, etc.) |
| 05:37 | leafw | all bit-wise operators are used as normally one would. |
| 05:38 | leafw | and it is true that operations on primitive types return primitives: no boxing warnings |
| 05:40 | leafw | suprisingly one gets boxing warnings when feeding byte, short, or int into bit-and, for example. Only a long would avoid the reflection warning. |
| 05:41 | leafw | I'd asume that byte/short/int would automatically promote to long |
| 05:44 | alexyakushev | What is the best exception to throw if macro was used incorrectly (wrong number of arguments, for instance)? |
| 05:45 | hyPiRion | Exception. |
| 05:45 | hyPiRion | It kind of depends, though. Do you want it to be compile-time or runtime? |
| 05:45 | alexyakushev | Compile time, I guess |
| 05:46 | leafw | the good news is that bit-or with more than 2 arguments runs at the same speed as an unrolled set of bit-or's |
| 05:47 | hyPiRion | Then go with Exception. Runtime should be RuntimeException |
| 05:47 | alexyakushev | And what about this "CompilerException java.lang.RuntimeException" Clojure uses for symbols not resolved? |
| 05:52 | hyPiRion | ,foo |
| 05:52 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)> |
| 05:52 | hyPiRion | ,(doc resolve) |
| 05:52 | clojurebot | "([sym] [env sym]); same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)" |
| 05:53 | hyPiRion | bleh |
| 05:53 | hyPiRion | ,(source resolve) |
| 05:53 | clojurebot | Source not found |
| 05:55 | hyPiRion | Ah, resolve is a runtime error, but I don't know about CompilerException. It's not the compiler there's some issue with when you're using the wrong number of arguments. |
| 05:55 | hyPiRion | ,(let [foo (fn [] (resolve 'bar))] nil) |
| 05:55 | clojurebot | nil |
| 05:55 | hyPiRion | ,(let [foo (fn [] (resolve 'bar))] (foo)) |
| 05:55 | clojurebot | nil |
| 05:57 | alexyakushev | OK, thank you. Exception will do |
| 06:00 | hyPiRion | Clojure isn't all that into Java-exceptions as far as I get it - it's better to have a descriptive error message. |
| 08:51 | hcumberdale | ;) |
| 08:52 | hcumberdale | My blog in clojure is finished ;) |
| 09:09 | horofox | hcumberdale: share it. |
| 10:51 | pandeiro | is there a good reason that predicate functions should only return true or false/nil? i find myself creating pseudo-predicates that return a val or nil; is that a bad pattern? |
| 10:53 | duck1123 | I think it depends on the predicate fn, a lot of them return the val for truthy |
| 10:54 | cshell | seems more robust to return the val or nil |
| 10:56 | duck1123 | of course, sometimes writing it to return the val may make that predicate slower. In both cases you'd have the test, but if you want to return the value, you'd need an if and then return the input |
| 10:57 | duck1123 | (fn [x] (> x 7)) vs (fn [x] (when (> x 7) x)) |
| 10:59 | pandeiro | duck1123: right, in my case i need to retrieve the val anyway, so why not return the val |
| 10:59 | pandeiro | seems it would make no sense to convert val to boolean and then retrieve the val again |
| 10:59 | pandeiro | but maybe the wiser people know a reason that would make sense |
| 11:04 | alexyakushev | duck1123: Why would returning a value make the predicate slower? Is there any difference in performance between returning a boolean or a reference to an object? |
| 11:06 | pandeiro | alexyakushev: think he means if you add the conditional (when...) |
| 11:06 | Chousuke | generally you should only return true or false explicitly in two cases: you're expecting the function to be used in Java code or when you want to return true for nil/false input |
| 11:21 | Bronsa | is there a function that trasforms [1 2 3 4] to ((1 3) (2 4))? |
| 11:21 | gfredericks | what's the rule there? |
| 11:22 | gfredericks | what does it do with [1 2 3]? or [1 2 3 4 5 6]? |
| 11:22 | gfredericks | do you only care about 4-tuples? |
| 11:22 | Bronsa | one element in the first list, one in the other |
| 11:22 | Bronsa | i can do that with ((juxt keys vals) (apply assoc {} coll)) |
| 11:22 | Bronsa | buyt it feels too much like cheating |
| 11:23 | gfredericks | ,(partition 1 2 [1 2 3 4]) |
| 11:23 | clojurebot | ((1) (3)) |
| 11:23 | gfredericks | hm |
| 11:23 | Bronsa | yeah i tried partition |
| 11:24 | gfredericks | there are proably 40 cludgy ways to do it |
| 11:31 | gfredericks | ,(let [pairs (partition 2 (range 6))] [(map first pairs) (map second pairs)]) |
| 11:31 | clojurebot | [(0 2 4) (1 3 5)] |
| 11:31 | gfredericks | that's the cleanest I can think of |
| 11:31 | Bronsa | oh, cool thanks! |
| 11:33 | mdeboard | amalloy_: lol. I'd like to hear more about the dumb things I did wrong. |
| 11:33 | mdeboard | amalloy_: (seriously) |
| 11:43 | mdeboard | amalloy_: https://github.com/mattdeboard/clj-itext/blob/master/src/clj-itext/core.clj is the full file. PdfReader is a class from iText, a PDF-processing library. It has a very painful API. So when you say I've reinvented being crazy wrt my usage of metadata, I'm assuming what you really mean is "that's dumb." Why? I was basically just using it to store metadata about the PDF on the class instance. |
| 11:46 | pyrtsa | gfredericks, Bronsa: Here's a little simpler still: |
| 11:46 | pyrtsa | ,(apply map list (partition 2 (range 6))) |
| 11:46 | clojurebot | ((0 2 4) (1 3 5)) |
| 11:47 | Bronsa | eg! thanks |
| 11:59 | gfredericks | pyrtsa: oh of course |
| 12:00 | pyrtsa | gfredericks: To be honest, it wasn't that obvious to me at first either. |
| 12:01 | Bronsa | this is funny http://i.imgur.com/GzpUF.png |
| 12:04 | gfredericks | pyrtsa: the (map list ...) things does matrix transpose; I just didn't realize that's what he was asking for |
| 12:05 | Bronsa | gfredericks: yeah, sorry if I didn't explain myself properly |
| 12:06 | Bronsa | thanks both anyway :) |
| 12:12 | gfredericks | Bronsa: oh no it was me |
| 12:20 | sproust | ist |
| 12:20 | sproust | technomancy: I just saw nrepl.el |
| 12:20 | sproust | technomancy: got a few questions about it. |
| 12:21 | sproust | Why two modes? I saw there's a major and a minor mode. If it's meant to be used with clojure-mode, why not just have a minor mode? |
| 12:34 | duck1123 | "code generated by ClojureScript macros must target the capabilities in ClojureScript" -- does that mean I can't make a macro that calls console.log ? |
| 12:34 | duck1123 | I'm getting odd errors when I try |
| 13:01 | sproust | technomancy: Ah. never mind. Figured it out, forgot the repl installs its own mode. |
| 13:45 | Frozenlo` | I get this error when I try to evaluate a function: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentCollection. |
| 13:45 | Frozenlo` | The function evaluates fine by itself, but when I add a given macro in it, it chokes. Any idea why? |
| 13:48 | pandeiro | does himera only work with lein <2? anyone know? |
| 13:49 | pandeiro | i get an error: Problem requiring leiningen.js hook |
| 13:49 | mdeboard | Frozenlock: Not without seeing the code |
| 13:51 | Frozenlock | mdeboard: https://gist.github.com/3258950 the macro is used near the end of the function. |
| 13:51 | mdeboard | Frozenlock: You're missing something |
| 13:52 | mdeboard | oh, nm, there the signature defintiion |
| 13:52 | Frozenlock | You litteraly, or in my understanding? |
| 13:52 | mdeboard | didn't see it |
| 13:52 | mdeboard | why do you have a vector in your args like that |
| 13:53 | Frozenlock | that? [[fetch-fn coll & {:as args}]] |
| 13:53 | mdeboard | yeah |
| 13:53 | mdeboard | is thata macro thing I'm not familiar with? |
| 13:54 | Frozenlock | (with-random (fetch ....)) would be single argument. With the added vector I use destructuring to directly get the components. |
| 13:55 | Frozenlock | Could it be that the arguments aren't evaluated, thus I don't have a map as a I was expecting, but simply a symbol? |
| 13:56 | treehug | are there refactoring tools for clojure like for example: extract sexp to local variable, rename symbol in sexp, etc? |
| 13:56 | mdeboard | Dunno, seems weird. On line 31, the (fetch (...)) expression is going to be evaluated before it's passed to (with-random) |
| 13:56 | Frozenlock | So the query-map in `:where query-map' will not be a simple symbol if I understand correctly. |
| 13:57 | mdeboard | I dunno, that is some weird-to-me syntax (but I'm not an expert by any stretch) |
| 13:57 | Frozenlock | ok, thanks anyway. |
| 14:00 | mdeboard | What is that function signature supposed to do? Destructure? I've literally never seen a vector used as a symbol |
| 14:02 | mdeboard | supposed to represent* |
| 14:02 | Frozenlock | If you are talking about the macro, yes it's for destructuring. |
| 14:02 | mdeboard | That shouldn't be in the function signature though |
| 14:02 | Frozenlock | Signature? |
| 14:03 | mdeboard | in ``(defn foo [a b] (+ a b))`` ``[a b]`` is the signature |
| 14:04 | mdeboard | destructuring should be in binding statements like let/for/etc. |
| 14:04 | metellus | mdeboard: you can destructure in a function signature |
| 14:04 | mdeboard | I see |
| 14:06 | mdeboard | That seems weird, since if you're just destructuring in the signature why not just pass the function the destructured args in the first place? |
| 14:06 | metellus | Frozenlock: based off of this http://stackoverflow.com/questions/11170424/maintaining-agent-state-while-returning-in-clojure and completely making things up, I'd say that you need to put "fetch-fn coll & {:as args}" into parentheses |
| 14:07 | gfredericks | mdeboard: in a lot of cases that could mean spreading implementation information all around your code rather than keeping it in one place |
| 14:07 | metellus | mdeboard: so instead of (some-fn some-vec) you'd have to do soething like (let [;destructuring goes here] (some-fn args))? |
| 14:10 | mdeboard | or just restructure in a different let statement, it's just a convention that I've never seen before (except obv like `(defn foo [x & [y z]] (stuff x y z))` |
| 14:11 | Frozenlock | I think I should be using a function instead of a macro in this case. Let me try that... |
| 14:16 | muhoo | i've seen a lot of people writing functions with quoting and unquoting ` ~ ' etc, i call the "funcros" |
| 14:17 | gfredericks | muhoo: misquote is good for ` without symbol expansion |
| 14:17 | gfredericks | i.e., for just the unquoting mechanisms |
| 14:21 | muhoo | yeah, the first time i saw gensyms and syntax-quotes in a non-macro, i was confused. then i figured out how useful it could be. |
| 14:22 | gfredericks | ,`foo# |
| 14:22 | clojurebot | foo__27__auto__ |
| 14:22 | Frozenlock | Meh, it works as a simple function and without the quoting unquoting stuff. Perhaps I was trying to be to fancy. |
| 14:51 | mdeboard | funcros |
| 14:51 | mdeboard | I liek that. |
| 15:14 | sjl | I'm trying to eliminate reflection and can't seem to figure out the magic type hinting incantations... anyone feel like taking a look? https://gist.github.com/3259412 |
| 15:20 | sjl | oh sweet, I think I found it |
| 15:26 | antares_ | sjl: you more likely want to use hints before locals: ^String s, not s ^String (…). Also, the last parameter needs to be passed as a java array, so see clojure.core/into-array |
| 15:27 | sjl | antares_: actually this does the trick: https://gist.github.com/3259412 |
| 15:27 | sjl | antares_: there's an alternate version of that method that takes a set instead of that weird java varargs |
| 15:27 | sjl | antares_: I just had to inform clojure that (set foo) does indeed produce a persistenthashset |
| 15:28 | antares_ | sjl: it is still less common to hint expressions if you bind them to locals but ok. And interop with variadic methods is a common source of confusion so I decided to mention it. |
| 15:29 | antares_ | sjl: to hint on core Clojure types, it is probably a better idea to use interfaces (IPersistent*) |
| 15:29 | antares_ | also, you probably can just hint it has java.util.Set? |
| 15:29 | sjl | maybe |
| 15:29 | antares_ | the Java method is likely to be expecting j.u.Set, not a specific Clojure interface |
| 15:30 | antares_ | Clojure sets implement the read-only part of j.u.Set |
| 15:30 | sjl | ah |
| 15:33 | pandeiro | anyone noticed a bug with goog.json.parse() ? JSON.parse() is parsing my string just fine, goog.json.parse() isn't |
| 16:44 | wtetzner | pandeiro: what string are you trying to parse? |
| 16:51 | pandeiro | wtetzner: sorry i figured it out - goog.json.parse uses eval, which is prohibited in chrome extensions |
| 16:52 | antares_ | pandeiro: are you writing a chrome ext in cljs? |
| 16:52 | pandeiro | kinda silly that goog.json.parse doesn't first check for a native method imo, but whatever |
| 16:52 | pandeiro | antares_: i am |
| 16:52 | pandeiro | and i'm loving it |
| 16:53 | emezeske | pandeiro: That is really cool! |
| 16:55 | pandeiro | emezeske: yeah my first try was a couple of months ago, i wanted to convert himera to a chrome extension that would allow using CLJS on any random webpage |
| 16:55 | pandeiro | but i ran into the no eval() problem |
| 16:55 | pandeiro | there is a workaround tho, eventually i will get on that |
| 16:56 | emezeske | pandeiro: Oh, neat, the extension would like see a special script tag and send it off to himera seamlessly? |
| 16:56 | pandeiro | emezeske: ah no, just to be able to screw around in cljs on any random page |
| 16:56 | emezeske | pandeiro: I see |
| 16:57 | emezeske | pandeiro: Cool stuff |
| 16:57 | pandeiro | eventually have a store of convenience functions, like get-all-links |
| 16:57 | pandeiro | yeah, eventually i'll get there |
| 16:57 | pandeiro | with cljsbuild it has been very easy throwing together an extension |
| 16:57 | emezeske | nice! |
| 16:57 | pandeiro | since you can output to multiple files easily |
| 17:05 | pandeiro | say i have a flattened seq like (:head :sub :sub :sub :head :sub :sub :head :sub :sub :sub) and i want to restore the hierarchy like ([:head (:sub :sub :sub)] ...) |
| 17:09 | pandeiro | i got to using partition-by to get ((:head) (:sub :sub :sub) (:head) (:sub :sub) ...) ... trying to figure out the next step |
| 17:11 | gfredericks | pandeiro: (->> % (partition 2) (map (fn [[[h] subs]] [h subs]))) |
| 17:12 | pandeiro | gfredericks: my mind reached its recursion limit with that destructuring |
| 17:12 | pandeiro | but thank you, am trying to parse |
| 17:12 | gfredericks | it's just pulling the head and the subs out of your ((:head) (:sub :sub :sub)) |
| 17:26 | Frozenlock | Is there a way to use drag/drop in html5 without javascript? |
| 17:30 | Raynes | Rewriting all the temp file/dir stuff and making other things less weird. |
| 17:30 | Raynes | Going to commit-bomb the repo soon. |
| 17:33 | antares_ | Raynes: (with the towlie voice) don't forget to use travis-ci |
| 17:33 | Raynes | antares_: I'm not already doing that? |
| 17:33 | Raynes | Hrm. |
| 17:33 | Raynes | Guess I just haven't worked on fs in a while. |
| 17:33 | Raynes | I'll get that set up before releasing. |
| 17:35 | Raynes | Also, if anybody has ever found something weird or un-nice in fs, nows your chance to get it fixed while I'm on a roll. |
| 17:35 | Raynes | I didn't write the vast majority of this code and I haven't used fs a whole lot, so I'm not the one who would know about issues. |
| 17:36 | Frozenlock | Well, a more detailed readme could be nice. (to know what that's all about) |
| 17:37 | Raynes | It's all about the fs, man. |
| 17:37 | Frozenlock | *cricket* |
| 17:40 | technomancy | Imma let you finish but reiserfs was the best fs of all time |
| 17:40 | Raynes | technomancy: You're so hip and with it. |
| 17:40 | danlarkin | murders your wife ✓ |
| 17:45 | amalloy | mdeboard: you aren't actually storing the metadata, though. like, your implementation of withMeta returns a map, instead of a new object with new metadata |
| 17:46 | amalloy | which is, in turn, what makes with-proxy-meta's implementation so bizarre. with-proxy-meta should be able to just be a simple call to ##(doc vary-meta) |
| 17:46 | lazybot | ⇒ "([obj f & args]); Returns an object of the same type and value as obj, with (apply f (meta obj) args) as its metadata." |
| 17:47 | technomancy | so what if namespaces were persistent? |
| 17:47 | technomancy | what if new definitions were append-only and old function definitions stayed around until there were no other references to them? |
| 17:48 | technomancy | if you used nix-style hashing and dependency closures, you could keep multiple versions of a library in memory in the same classloader |
| 17:50 | technomancy | you could theoretically have every version of every clojure function loaded at once without conflict |
| 17:51 | gfredericks | technomancy: so you just solved dependency management then? |
| 17:52 | technomancy | no, I just told you how to solve it. go implement it. |
| 17:52 | Spaceghostc2c | Hagelberg! |
| 17:53 | technomancy | me? |
| 17:54 | gfredericks | ~hagelberg |
| 17:54 | clojurebot | Gabh mo leithsc?al? |
| 17:59 | jayunit100__ | trying to convert csv to json |
| 18:00 | jayunit100__ | any hints on the standard lib to do this csv i/o (clojure) |
| 18:00 | jayunit100__ | trying [clojure-csv/clojure-csv "2.0.0-alpha1"] |
| 18:19 | Frozenlock | What's the way to add a favicon in noir? |
| 18:23 | Raynes | Frozenlock: https://github.com/Raynes/refheap/commit/3fa0100722faad54418a1e712dcf0176463b789d |
| 18:24 | jayunit100__ | (:import [java.io StringReader]) <-- this seems to fail |
| 18:24 | Frozenlock | Raynes: Thanks! |
| 18:27 | jayunit100__ | ah dsantiago ! |
| 18:27 | jayunit100__ | I'm using your csv parser now :) |
| 18:27 | jayunit100__ | dsantiago: ^^ … thanks :) |
| 18:28 | dsantiago | Oh, cool. |
| 18:28 | dsantiago | I've been speeding it up lately. |
| 18:28 | jayunit100__ | cool! |
| 18:28 | jayunit100__ | Caused by: java.lang.IllegalArgumentException: Unable to resolve classname: long |
| 18:28 | jayunit100__ | ^^ anyone ever see this error before? |
| 18:30 | jayunit100__ | ah i think its clojure class path related |
| 18:30 | jayunit100__ | or maybe its leon related. |
| 18:31 | dsantiago | Did you hint something to be a long or try to create one like (long. …) or anything like that? |
| 18:35 | jayunit100__ | looks like you have to reload lein reps or something maybe . |
| 18:35 | jayunit100__ | no its not in my source, it seems to be in a jar. |
| 19:23 | Frozenlock | Is there a forum library for clojure? |
| 19:37 | mdeboard | amalloy: I see, noted |
| 19:38 | cmajor7 | forgot where I read how to force (re)compilation on save.. e.g. I have it working nicely with clojurescript via "lein-cljsbuild".. I am sure there is something similar (and probably simple) for clojure itself |
| 19:39 | cmajor7 | is it just another lein plugin? |
| 19:40 | xeqi | cmajor7: web service? |
| 19:40 | xeqi | ring.middleware.reload I think |
| 19:41 | cmajor7 | xeqi: thx. no, simpler :) just clojure code |
| 19:41 | weavejester | cmajor7: (:require blah.core :reload) |
| 19:42 | weavejester | cmajor7: Er, I mean: (require 'blah.core :reload) |
| 19:42 | weavejester | Too used to the ns macro |
| 19:42 | cmajor7 | once I save any clojurescript file, it gets recompiled right away, and I can see in a console whether there are any errors. just wanted to do the same thing with clojure itself |
| 19:43 | cmajor7 | weavejester: so I would need to append :reload to every namespace… I have ~ 15 files, is that the only way? |
| 19:43 | weavejester | cmajor7: There's also :reload-all, which reloads a namespace and all its dependencies. |
| 19:43 | amalloy | i don't think it's ever right to put :reload into your namespace definition |
| 19:44 | cmajor7 | I think there is something similar in emacs land (swank?), but I am using vi. not sure if that matters |
| 19:44 | amalloy | that's only intended for repl usage |
| 19:44 | weavejester | amalloy: Right, but I'm assuming cmajor7 is reloading via the REPL... |
| 19:44 | weavejester | cmajor7: Is that right? |
| 19:45 | amalloy | (as an aside, you forgot the []s in (require '[blah.core :reload])) |
| 19:45 | amalloy | or i dunno, maybe it works outside |
| 19:45 | cmajor7 | weavejester: I just want to start "something", that would be running, and every time I save my code, I it gets recompiled, and that "something" reports exceptions/errors/etc.. |
| 19:46 | emezeske | cmajor7: I think most people use vimclojure or swank or something similar for that |
| 19:47 | emezeske | cmajor7: I have heard of people adding hooks to their editors that automatically reload the current file on save |
| 19:47 | weavejester | cmajor7: Usually I just use SLIME for that. I believe VimClojure might have something similar. And some of the various IDEs might have that, too. |
| 19:47 | emezeske | s/swank/slime |
| 19:47 | cmajor7 | emezeske: I use vimclojure, but as far as I understand you need to always force the compilation e.g. "\ef" |
| 19:47 | cmajor7 | which pops up an internal vim buffer that you have to switch to and close |
| 19:48 | cmajor7 | or worse scroll up to actually see the exception |
| 19:48 | emezeske | You don't have to switch to it, you can do \p to close it |
| 19:48 | cmajor7 | feels like 4 extra steps for every save.. |
| 19:48 | emezeske | And you can set options for where it appears, and how big |
| 19:48 | emezeske | You can just leave it open... |
| 19:48 | cmajor7 | right, but if there is an exception, you have to switch to it to scroll up |
| 19:49 | weavejester | cmajor7: Isn't that an issue with screen size more than anything? I mean, if the stacktrace scrolls off screen, then you'd have the same problem with whatever, right? |
| 19:49 | mdeboard | amalloy: With the definition of withMeta, I spent a few hours last night trying to figure out how to extend an Object instance with the IObj interface. I basically just hacked at it until it works. I couldn't find an example implementation of withMeta (except for one really crummy blog post from 2009) |
| 19:49 | cmajor7 | I just really like what "lein-cljsbuild" does, and I find it hard to believe there is nothing similar for clojure itself? |
| 19:50 | amalloy | mdeboard: just look at the examples in clojure.lang |
| 19:50 | amalloy | they're in java, but it's pretty easy |
| 19:50 | mdeboard | amalloy: I tried to find it in the source last night but I think I was exhausted |
| 19:51 | mdeboard | I found the IObj.java and IMeta.java classes, but there's no actual code there, just interface defs |
| 19:51 | weavejester | cmajor7: I haven't heard of anything. I find it more useful to have errors integrated with my editor. However, it would be pretty trivial to create something like it. Just combine clj-stacktrace, ns-tracker, and :reload-all in a loop. |
| 19:51 | weavejester | I imagine it would be 8 lines of code or something. |
| 19:52 | mdeboard | er, I should say, no function definitions, not no code :P |
| 19:52 | amalloy | look at, eg, PersistentHashMap |
| 19:55 | muhoo | cmajor7: i think noir does it on page reload |
| 19:55 | cmajor7 | weavejester: I see. still find it odd. do you actually go an extra step every time to see if your code is solid? e.g. 1. save it 2. force compilation 3. go scroll the exception ? |
| 19:56 | mdeboard | amalloy: I see... so, do I need to specify a constructor for this PdfReader class that has a signature that includes metadata? Based on PersistentHashMap, I'm not sure how to do something similar for this class instance. PersistentHashMap implements the IObj interface out of the box; PdfReader not. |
| 19:56 | weavejester | cmajor7: No, I just use SLIME. |
| 19:57 | amalloy | just...implement withMeta to call proxy-meta or whatever it is |
| 19:57 | cmajor7 | muhoo: noir does, but if you work with 3 files simultaneously, going from one vim buffer to another and back, saving each, noir does not help you here (nor it should) |
| 19:57 | cmajor7 | weavejester: I see. how does it work in slime? |
| 19:57 | cmajor7 | it auto recompiles on save? |
| 19:57 | amalloy | you really don't want to recompile on save |
| 19:58 | weavejester | cmajor7: No, but it saves if you trigger a compile without saving, IIRC |
| 19:58 | cmajor7 | amalloy: why not? |
| 19:58 | muhoo | cmajor7: i dunno then. i was poking in the cljsbuild source, and stumbled across the function that checks the filesystem for changed files, but didn't read it in depth. you could probably adapt that to a lein plugin that does that for clj instead of cljs |
| 19:58 | weavejester | cmajor7: And the error is reported through SLIME, so the top part of the stack trace is shown |
| 19:59 | weavejester | muhoo: There's a library called ns-tracker that does that for clojure |
| 19:59 | cmajor7 | weavejester: pretty similar to vimclojure.. although the bottom of the exception is shown.. ) |
| 19:59 | amalloy | for example, you don't want to recompile a protocol implicitly, because then implementations of it won't match up anymore |
| 20:00 | weavejester | cmajor7: Why not add a key binding that saves, compiles, then goes to the top of the exception? |
| 20:02 | cmajor7 | amalloy: does sound like a special case, and implementations can be also recompiled after the protocol, can they?. I am not saying it should be enabled by default, but there should be something that does it as an option. |
| 20:05 | cmajor7 | weavejester: might work, but still a bit rough. let's say you are working through several files related to one another. ideally there should be a single console that shows you errors/[OK]s/exceptions every time you save and go to another file. so your mental flow is not interrupted.. (may be it's just me though) |
| 20:09 | muhoo | it is funny to me how personal and unique everyone's workflow can be. mine is quite idiosyncratic. |
| 20:10 | amalloy | cmajor7: just write a little shell script that compiles everything, eg: echo "(require 'my-app.core)" | lein repl, and then open another console that runs: watch my-script.sh |
| 20:11 | amalloy | there's no need for it to happen when you save, or be incremental and mess with your open session |
| 20:12 | cmajor7 | amalloy, weavejester: thx, I'll experiment |
| 20:26 | gfredericks | does the new finite-domain stuff in core.logic not play well with negative numbers? |
| 20:29 | gfredericks | I get no results with (interval -100 100) (even though I should), but changing it to (interval 1 100) gives results. |
| 20:43 | mdeboard | Man the people who wrote iText must hate programmers |
| 20:44 | mdeboard | or love carpal tunnel syndrome or I dunno |
| 20:55 | amalloy | i can sympathize with hating programmers |
| 20:58 | mdeboard | amalloy: That is obvious, but that's why we like you. To be fair to the itext people I'm sure they're in backward compatibility hell. I know they are actually because they put all their backward compatibility burden on me |
| 21:09 | mdeboard | Is there a way to invoke (proxy) in such a way that the class being extended doesn't get constructed first? I've been reading the source for the macro and am assuming not. |
| 21:10 | mdeboard | I think that's the sort of thing Python's ``object.__new__`` method is there for; curious if there's an analog in Clojure specifically for Java interop. |
| 21:14 | amalloy | sorry mdeboard, that is not possible on the jvm |
| 21:42 | mdeboard | amalloy: Cleaned that up then https://github.com/mattdeboard/clj-itext/blob/master/src/clj-itext/core.clj#L43 |
| 21:43 | mdeboard | removed `with-proxy-meta' since it was redundant |
| 21:43 | amalloy | don't call `merge`. withMeta is "here is your new metadata" |
| 21:45 | mdeboard | which merge is redundant? in the withMeta definition? |
| 21:45 | amalloy | not redundant, incorrect |
| 21:46 | amalloy | (and yes, that one) |
| 21:46 | amalloy | (meta (with-meta x y)) should return y in all cases |
| 21:46 | mdeboard | Oh, I see what you're saying then. with-meta completely replaces the metadata. |
| 21:46 | mdeboard | I misunderstood how that worked. |
| 21:48 | mdeboard | ##(doc vary-meta0 |
| 21:48 | mdeboard | ##(doc vary-meta) |
| 21:48 | lazybot | ⇒ "([obj f & args]); Returns an object of the same type and value as obj, with (apply f (meta obj) args) as its metadata." |
| 21:48 | mdeboard | I see. |
| 21:52 | amalloy | what, does chas say something misleading about metadata? |
| 21:52 | mdeboard | No, I just don't believe in taking personal responsibility |
| 21:54 | mdeboard | But seriously, having no Java background whatsoever the proxy/gen-class bit specifically could use somewhat better documentation. Maybe it's more transparent if you've got a background in Java |
| 22:06 | mdeboard | amalloy: Done, thanks for the tough love |
| 22:06 | mdeboard | I work better when I think someone thinks I'm an idiot |
| 22:08 | amalloy | haha |
| 22:08 | amalloy | you should pair with hiredman |
| 22:10 | danlarkin | bahahahah |
| 22:10 | mdeboard | Why, does he think I'm an idiot? :P |
| 22:10 | mdeboard | or does he just think everyone is |
| 22:11 | muhoo | ,*ns* |
| 22:11 | clojurebot | #<Namespace sandbox> |
| 22:11 | muhoo | ,(= :sandbox/foo ::foo) |
| 22:11 | clojurebot | true |
| 22:12 | cmajor7 | once friend authenticates a user, it puts "{ :username.. :password… :roles.." under the identity into a session. Is there a way to make friend to keep additional user details there? (e.g. user-id) |
| 22:13 | muhoo | well, you can using ring |
| 22:13 | muhoo | just add whatever you want to the :session |
| 22:14 | xeqi | cmajor7: try returning more data from you're credentials-fn |
| 22:14 | cmajor7 | yea, I just did, it still hangs on to those 3 |
| 22:15 | muhoo | cmajor7: are you writing a custom workflow? |
| 22:15 | cmajor7 | muhoo: yes, but it is not going to be a part of friends identity + needs to be handled separately => not nice |
| 22:15 | muhoo | i wrote one for google step2 auth, but it's been months now and my memory fails me |
| 22:16 | cmajor7 | muhoo: no this particular one is a built in "interactive-form" |
| 22:16 | muhoo | oh, so you're out in ring? |
| 22:17 | muhoo | not inside a (defn workflow ... ) ? |
| 22:17 | cmajor7 | muhoo: I am home at the moment |
| 22:17 | muhoo | hehe |
| 22:17 | muhoo | i mean not you specifically, but your code :-) |
| 22:18 | cmajor7 | there is a "credentials-fn" that returns the auth |
| 22:18 | cmajor7 | which is the only "data hook" into friend that is used |
| 22:18 | muhoo | :credential-fn i expect |
| 22:18 | muhoo | no "s" |
| 22:18 | cmajor7 | the app is of course ring based. noir to be exact |
| 22:19 | cmajor7 | right. "bcrypt-credential-fn" if you want to be really accurate |
| 22:19 | muhoo | cool, so my guess is you have something like this in your server.clj: https://www.refheap.com/paste/4047 |
| 22:20 | cmajor7 | yep. very similar |
| 22:20 | cmajor7 | no "step2" though |
| 22:20 | muhoo | well, of course |
| 22:20 | muhoo | that was my test code |
| 22:21 | muhoo | alright, so you're using creds/bcrypt-credential-function. what does it return? |
| 22:21 | cmajor7 | so once the user is authed, only username, password and roles make it to the identity |
| 22:21 | muhoo | somewhere, something returns a ring response, which has (or can have) a :session key in it |
| 22:22 | cmajor7 | muhoo: it returns a map of those 3. I tried to add other keys there, but they get ignored, since only those 3 seem to be read by friend |
| 22:22 | muhoo | by interactive-form |
| 22:23 | clj_newb_29840 | is there any standard toolkit for keeping _data structures_ updated on client/server over clojurescript/clojure? |
| 22:23 | clj_newb_29840 | i.e. I'd like ot find the right abstractions so I have some data structure so that its state is automatically synched over both the server and the client |
| 22:24 | xeqi | cmajor7: strange, returning extra-keys there works for me |
| 22:25 | muhoo | cmajor7: ok i see this (assoc-in [:session ::identity] auth)) |
| 22:25 | cmajor7 | muhoo: right, http://bit.ly/PUxKWX |
| 22:25 | cmajor7 | xeqi: interesting.. which key did you try, if you don't mind |
| 22:26 | muhoo | so whatever is returned in auth, from the who-knows-where-that-comes-from, should end up in your session |
| 22:26 | cmajor7 | I tried, id, user-id, but no go.. |
| 22:26 | xeqi | :extra |
| 22:27 | xeqi | but the only one creds/bcrypt-crednental-fn removes is :password |
| 22:27 | xeqi | blah, I can't spell today |
| 22:27 | muhoo | i remember i spent days tracing through the (authenticate* ..) function to figure out how all this works, but i've long since forgotten |
| 22:28 | muhoo | with like printlns everywhere |
| 22:36 | cmajor7 | xeqi: yep, works now. had to restart the server |
| 22:36 | cmajor7 | I wonder why… since I did clear the session (it does it on logout) |
| 22:39 | xeqi | noir's reload doesn't work with middleware |
| 22:44 | Frozenlo` | Anyone wants to critic my website? (general layout, colors, etc...) Made with love with Noir :) https://bacnethelp.com |
| 22:47 | Frozenlock | I'm pretty sure I have tunnel vision right now, so please be direct. |
| 22:48 | emezeske | Frozenlock: Whoa, I worked on a BACnet stack once |
| 22:48 | Frozenlock | emezeske: Yay! BACnet friend :) |
| 22:48 | emezeske | Frozenlock: I wrote the MS/TP layer :) |
| 22:48 | Frozenlock | The C stack? |
| 22:48 | emezeske | Yeah, it was all C. Well, actually, C++ |
| 22:48 | xeqi | Frozenlock: I can't read the example at all |
| 22:48 | xeqi | well, barely |
| 22:48 | Frozenlock | Oh I only do BACnet/IP with this. |
| 22:49 | Frozenlock | xeqi: Colors? |
| 22:49 | emezeske | Yeah, MS/TP is a bitch to set up, and tends to require custom code most of the time :/ |
| 22:49 | muhoo | cmajor7: right, i had to do stuff like this https://www.refheap.com/paste/4048 and this (def rel (reloader #'-main)) and this https://www.refheap.com/paste/4049 |
| 22:49 | cmajor7 | xeqi: ah.. makes sense, good to know (about noir reload) |
| 22:49 | emezeske | Frozenlock: BACnet/IP is so much better |
| 22:49 | Frozenlock | emezeske: And it's slooooow :) |
| 22:49 | emezeske | Frozenlock: omg yeah |
| 22:50 | mdeboard | Frozenlock: Where are you hosting your images? |
| 22:50 | mdeboard | oh, I see you just acknowleged |
| 22:50 | mdeboard | Frozenlock: Only thing I'd say is have your links open up in new windows |
| 22:50 | mdeboard | target="_blank" etc |
| 22:51 | Frozenlock | mdeboard: All the links? |
| 22:51 | cmajor7 | muhoo: hmm.. I wonder whether I should just jump a level down to compojure.. so far noir introduces more problems than it solves.. |
| 22:51 | Frozenlock | Seems it would be intrusive. |
| 22:51 | xeqi | Frozenlock: http://imgur.com/s4qnX is what I get on ff14.0.1 |
| 22:51 | mdeboard | Frozenlock: well just external, like the one to github imo |
| 22:51 | muhoo | cmajor7: you wouldn't be the first to do that. i think that's why they broke out a lot of noir-ish stuff into lib-noir |
| 22:51 | Frozenlock | Hmm that would be wise... |
| 22:52 | cmajor7 | muhoo: also, how do you usually debug through a 3rd party libs? (you said to did do it with friend's "authenticate*") |
| 22:52 | xeqi | cmajor7: I use compojure over noir |
| 22:52 | muhoo | cmajor7: i'm old-skool. lots of printlns :-) |
| 22:53 | muhoo | and the repl helps a lot too, though not so much with web authentication stuff that requires a browser |
| 22:53 | cmajor7 | muhoo: so you get the source, and depend on the source.. and then mod it in the friend's branch itself? |
| 22:53 | xeqi | Frozenlock: oh, if I hover over it then it expands and becomes brighter |
| 22:53 | Frozenlock | xeqi: Is that too discrete? If you hover it should change transparency... |
| 22:53 | emezeske | cmajor7: If you are doing anything complex with routing, noir tends to just get in the way |
| 22:53 | cmajor7 | xeqi: you mean you use noir, but drop back to compojure for routes? |
| 22:53 | muhoo | oh, that? yes, i git cloned'ed friend, then ln -s'ed it into the "checkouts" directory in the lein project |
| 22:54 | xeqi | cmajor7: sorry, I mean use compojure, don't use noir |
| 22:54 | cmajor7 | emezeske: yea I noticed that doing xhr.. :) |
| 22:54 | emezeske | cmajor7: ;) |
| 22:54 | cmajor7 | xeqi: I see.. do you roll out your own "defremotes"? |
| 22:55 | muhoo | isn't defremote from fetch? |
| 22:55 | cmajor7 | muhoo: yea, but fetch is noir..ish |
| 22:55 | Frozenlock | And here is a project I'm logging https://bacnethelp.com/project/4ffac84b44ae35711d15d214 |
| 22:56 | Frozenlock | So my most urgent change should be to open external links in another window. |
| 22:57 | mdeboard | Frozenlock: Also see about solving package dependencies |
| 22:57 | mdeboard | not website-related but you'd be a hero |
| 22:57 | mdeboard | I could also use a drink |
| 22:57 | xeqi | cmajor7: I haven't used clojurescript much yet, but that would be the way I lean |
| 22:57 | Frozenlock | package dependencies? For the network scanner? |
| 22:58 | xeqi | though I'm interested in what shoreleave does for remotes |
| 22:58 | xeqi | just haven't explored it yet |
| 22:58 | mdeboard | Frozenlock: Oh, no, I Meant for software development in general |
| 22:58 | Frozenlock | I _really_ appreciate your feedbacks btw! |
| 22:59 | mdeboard | (I'm deliberately being obtuse) |
| 22:59 | Frozenlock | mdeboard: Could you give me an example? |
| 22:59 | xeqi | ah, looks like it does the same thing as fetch |
| 22:59 | Frozenlock | Dependencies are in the project.clj file... am I missing something? |
| 23:00 | mdeboard | I was just making a joke that was in hindsight really stupid |
| 23:00 | Frozenlock | It's hard to transmit sarcasm with text :P |
| 23:00 | mdeboard | yeah, you'd think I'd have learned in 20 years |
| 23:02 | cmajor7 | xeqi: yep http://bit.ly/OBWSWk |
| 23:03 | muhoo | yeah, i think rhickey and stuart holloway both did talks about "easy" vs "simple" |
| 23:03 | muhoo | stuff like noir and fetch is great if you're coming from rails and are used to the "easy" approach. but aren't necessarily "simple" once you dive into them. |
| 23:05 | mdeboard | Frozenlock: You should move that "How to scan your network" numbered list up "above the fold" imo, and put your "Download" button right there in the "1!" <p> |
| 23:06 | Frozenlock | Ah! Yes! |
| 23:07 | xeqi | Frozenlock, mdeboard: I agree. and if you can get it so that is the first thing the eye jumps to even better |
| 23:07 | xeqi | currently my eye jumps to the "Scan and see ..." blue banner |
| 23:08 | xeqi | muhoo: yeah, cemerick was horrified at the hoops I had to jump through to get a working noir/fetch + friend example |
| 23:13 | muhoo | xeqi: is that posted somewhere? i'd be curious to see it |
| 23:14 | xeqi | muhoo: https://github.com/xeqi/friend-fetch-example |
| 23:14 | xeqi | interesting part is https://github.com/xeqi/friend-fetch-example/blob/master/src/friendly/server.clj |
| 23:17 | muhoo | hmm, there's a lot going on there |
| 23:19 | muhoo | it looks a lot less complex than what i had to go through to get google step2 workflow working, but a lot more complex than perhaps it could be. |
| 23:20 | xeqi | muhoo: yeah, it could be cleaned up |
| 23:20 | xeqi | step2 definitly looks more complicated |
| 23:20 | xeqi | is it a multistep workflow? |
| 23:31 | m0smith | I am trying to wrap my brain around event processing in a purely functional environment |
| 23:32 | m0smith | How can the state of the world be passed around? |
| 23:33 | mdeboard | (##doc ref) |
| 23:34 | Raynes | That was creatively failed. |
| 23:34 | mdeboard | m0smith: Clojure has tools that allow you to introduce state to your application if necessary. |
| 23:34 | mdeboard | ##(doc ref) |
| 23:34 | lazybot | ⇒ "([x] [x & options]); Creates and returns a Ref with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn :min-history (default 0) :max-history (default 10) If metadata-map is supplied, it will be come the meta... https://www.refheap.com/paste/4050 |
| 23:34 | m0smith | mdeboard: I am trying to avoid that is possible |
| 23:34 | mdeboard | m0smith: Are you talking about cljs or clj? |
| 23:35 | m0smith | both actually |
| 23:35 | m0smith | The problem arises from cljs not having blocking deref |
| 23:36 | m0smith | so how to get the same code base to run in both environments. javascript is all about callbacks but that assumes a shared state, I think. |
| 23:36 | emezeske | m0smith: For state in cljs, there's a good chance you want to use an atom |
| 23:37 | muhoo | you could pass the state in the callback? |
| 23:38 | muhoo | oic, it'll depend on the state which may have mutated by the time the callback gets called. hmm. |
| 23:39 | m0smith | muhoo: I am writing a multi-player game so the state is the current state of the game which I want to protect from cheating code |
| 23:39 | mdeboard | Never done anything with asynchrony with Clj* but I was under the impression from what I do know that you could use watches to do event handling |
| 23:39 | mdeboard | ##(add-watch) |
| 23:39 | lazybot | clojure.lang.ArityException: Wrong number of args (0) passed to: core$add-watch |
| 23:39 | mdeboard | ##(doc add-watch) |
| 23:39 | lazybot | ⇒ "([reference key fn]); Alpha - subject to change. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any regis... https://www.refheap.com/paste/4051 |
| 23:39 | mdeboard | fail tonight |
| 23:42 | muhoo | m0smith: sounds like fun. it sounds like you'll want a mirror of the state in the server and on all the clients. |
| 23:43 | muhoo | the only time i've done this (js, not cljs), i had the server broadcasting all the updates of each player to each client. |
| 23:43 | m0smith | muhoo: Exactly. The game engine would have the real state and when it is a players turn, the client is sent the current state |
| 23:44 | m0smith | I also thought of supporting events from the clients to get the current state or send a message, etc. |
| 23:44 | muhoo | the server was basically this, but it didn't keep much state: https://github.com/kenrestivo/simple-clojure-websocket-chat |
| 23:44 | m0smith | I am just having a brain cramp meshing the game loop with asynchronous calls without something like an agent |
| 23:44 | m0smith | that can block |
| 23:45 | muhoo | started as a chat thing, then ended up as a gameserver of sorts, more or less unwillingly |
| 23:46 | m0smith | or do I just trash the game loop and handle everything through asychronous events? |
| 23:47 | muhoo | it's worth a try. also, there's a neat aleph framework for doing async stuff too |
| 23:47 | m0smith | which is then how to maintain state without a stuffing it in a global ref ... |
| 23:47 | muhoo | well, state is state. you have to store it somewhere |
| 23:48 | m0smith | with a game loop/lazy-seq the state is simply passed around to the functions |
| 23:50 | muhoo | do any of those functions do i/o? |
| 23:51 | m0smith | I am separating all the user stuff into different threads so no |
| 23:51 | muhoo | oh. hmm. |
| 23:52 | muhoo | concurrency with refs. i haven't done much with it, but i'm told that clojure makes it more manageable. |
| 23:53 | m0smith | The more I think and talk about it the more a shared state atom or agent supporting an event system may solve the problems I am facing |
| 23:54 | muhoo | sounds reasonable to me. might be a fun way to play around with clojure's concurrency features. |
| 23:54 | m0smith | And it should mesh better with most UIs as they are almost all event based at some level |
| 23:56 | m0smith | https://github.com/m0smith/crossfire is the code I am talking about. It is a Battleship-ish game. Now all it does is allows 3 computer players to battle. |
| 23:56 | muhoo | enjoy :-) |
| 23:57 | m0smith | thx. This has really helped me make decide the direction to go |