Fork me on GitHub
#clojure
<
2015-09-01
>
jaju02:09:36

@ghadi: Thank you! I think I have a legitimate need, but wanted to check if it is a strict no-no, or any downsides. simple_smile

rymndhng05:09:10

is it possible to gracefully cancel a future using future-cancel or should I stick with using an atom/promise to notify when it should sotp

serce09:09:00

Hello! Anyone know cool library, which can make recursive diff's between clojure edn maps and have ability to apply diffs? My goal is sync big map structure between client and server by passing diffs

robert-stuttaford10:09:30

clojure.data/diff

plexus10:09:03

yeah but there's no clojure.data/patch 😛

serce10:09:22

@jrotenberg: yes, i agree with @plexus, clojure.data isn't convenient for my purposes

pupeno15:09:01

Is anybody familiar with io.aleph.dirigiste.Pools.java? https://github.com/ztellman/dirigiste/blob/master/src/io/aleph/dirigiste/Pools.java. I’m trying to understand the semantics of utilization in the utilizationController.

rymndhng17:09:10

@serce if you find one tell me too 😛 clj-diff wasn’t general enough for me either 😞

meow17:09:01

I need a sanity check on some code I've written. It's an L-system, or Lindenmayer System, which is a simple rewriting system. The code does exactly what I want it to do to support an API that allows replacement values to be functions that will get called as well as replacements that can have optional state data associated with them, also know as a Parametric L-System. The question I have has to do with how I keep track of this optional data internally by using an atom that I pass into another function that is expected to update the atom. It works, but I'm just not sure it's the right way to go.

meow17:09:27

The module docstring is longer than the actual code. simple_smile

meow17:09:11

the main function that gets called iteratively looks like this:

(defn process
  "Returns new [word state] pair resulting from rewriting each module in the
   original word and updating the properties in state."
  [rules generation word state]
  (let [new-state (atom {})
        new-index (atom (int 0))
        rewriter (partial rewrite rules generation word state new-state new-index)
        new-word (doall (mapcat rewriter (map vector (range) word)))]
    [new-word @new-state]))

meow17:09:39

And the rewriting piece looks like this:

(defn rewrite
  "Returns [module] or a successor module if module is found in the rules
   mapping. If successor is a function it will be called."
  [rules generation word state new-state new-index [index module]]
  (if-let [e (find rules module)]
    (let [successor (val e)
          successor (if (fn? successor)
                      (successor generation word state index module)
                      successor)
          successor (split-successor successor new-state @new-index)]
      (swap! new-index + (count successor))
      successor)
    (do
      (swap! new-index inc)
      [module])))

jonas17:09:39

@meow: Why the cast to ‘int’ in (atom (int 0))? I don’t think an atom can hold a primitive?

meow17:09:01

@jonas: I'm pretty sure it can. The code works.

alexmiller17:09:27

it can't hold a primitive

jonas17:09:35

@meow: yes it’ll work, but it’s immediately turned into an Integer

alexmiller17:09:40

it will be boxed by the jvm

jonas17:09:12

or perhaps a Long? Not sure

alexmiller17:09:29

the AtomicReference will hold an object - will be a Long in this case

meow17:09:41

Okay, that was leftover from me thinking I might try to use data.int-map for the state map, but int-map doesn't exist in cljs and I want to use this code in cljs as well.

meow17:09:54

Anyhow, it just feels like I've compromised my lower level functions by expecting them to update the atoms I'm passing to them. On the other hand, the code is easy to understand and it works and I'm not sure the low level functions are useful elsewhere anyway. They're really just specific applications of replace anyhow. But am I missing something here? I don't have that much experience with purely functional code.

meow17:09:01

Although it was fun to get bitten by lazy seqs until I added doall

meow17:09:19

Actually, this is the really evil function:

(defn split-successor
  "Returns a sequence of modules, updating new-state with any successor data."
  [successor new-state index]
  (doall
    (for [[n, module] (map vector (range) successor)]
      (if (list? module)
        (let [[module data] module]
          (swap! new-state assoc (+ index n) data)
          module)
        module))))

alexmiller17:09:16

generally I strive to make as many functions as possible pure functions that take data and return data and as few as possible aware of state

jonas18:09:16

@meow: Is this the basic idea of an L-System ^^

jonas18:09:29

That’s what I got from reading the wikipedia article

meow18:09:33

@jonas: yes

meow18:09:16

(take 15 (iterate (partial replace rules) '[a])) would also work

meow18:09:18

Now just make it context-sensitive, stochastic, and parametric

meow18:09:41

So you can define a grammar like this:

{:axiom ['(:A {:age 0})]
    :rules {:A #(vec ['(:B {:age 0}) :- (list %5 {:age (age %3 %4)}) :- '(:B {:age 0})])
            :B (fn [g w s i m] ['(:A {:age 0}) :+ (list m {:age (age s i)}) :+ '(:A {:age 0})])}}

jonas18:09:49

simple_smile Sounds like that will take a while

meow18:09:17

It's done

meow18:09:56

It works

meow18:09:36

It just has a few functions that aren't pure but I'm not sure making them pure is going to be a big improvement.

al3x18:09:22

Hey, thanks @alexmiller simple_smile Most of my coding is in Clojure these days. This seems like a great resource.

alexmiller18:09:42

it is, glad you found it :)

serce18:09:22

@malcolmsparks: thank you, i will look into it

ztellman18:09:33

@pupeno feel free to email me, or to post something at https://groups.google.com/forum/#!forum/aleph-lib if you have questions about Dirigiste

not-much-io18:09:28

Can anyone help with this problem of params inside a POST disappearing? And less importantly a problem with response being a single semicolon. -> https://gist.github.com/not-much-io/764c5bb5b46c804b6a42

jonas19:09:51

@not-much-io: cljs-ajax defaults to transit so you might want to add :format :json or something like that. Then you can use wrap-json-params to add the body to :params

jonas19:09:20

or, if you want to use transit you can perhaps use https://github.com/jalehman/ring-transit instead

not-much-io19:09:16

@jonas: Thanks, I will try json.

nberger19:09:04

@not-much-io what @jonas said. To help in debugging but also as a ring logging solution you might want to check ring-logger (shameless plug)

not-much-io19:09:03

@jonas: Thanks, it worked. @nberger will check out simple_smile

meow19:09:23

just for the record, (take 15 (iterate (partial replace rules) '[a])) does not work the same, close, but no cigar

meow19:09:31

my mistake

wei20:09:17

does anyone use monroe as their emacs nREPL client? recently started having problems with exceptions not displaying in the REPL buffer.

wei20:09:38

actually only the return value gets displayed, any other output is dropped

sdegutis22:09:02

How do you tend to write your full-system Clojure tests?

sdegutis22:09:57

Question: Do you generally just write (Date.) or do any of you use a wrapper library for this?

jeffmk23:09:04

For anything non-trivial I’d use clj-time.

sdegutis23:09:09

@jeffmk: Why not just Java's Date utils?

jeffmk23:09:19

I’m not super familiar with Java’s Date stuff, but it doesn't look like very idiomatic Clojure. I’m guessing clj-time is much more pleasant to use for more most use cases.

jeffmk23:09:31

I guess the choice depends on what you’re doing. For an API wrapper I wrote recently, I’m hesitant to pull in clj-time as a dep, and thinking I just might use java Date / Calendar myself.

sdegutis23:09:16

@jeffmk: clj-time wraps Joda-Time which is just Java. And Java's Date stuff can't be idiomatic Clojure because it's not Clojure it's Java.

sdegutis23:09:43

@jeffmk: We're using chee.datetime right now for the exact purpose you just mentioned.