Fork me on GitHub

i just need 8 bytes, it seems is 16 bytes, can not store as a interger in db?


you can change it with less bytes. For Example, less length for unix timestamp epoch, or use ip address instead of MAC address, or use less length for seq.

Suren P10:03:37

This has turned out to be kind of ungoogleable, why do people write ~ in their clojure code? What is the convention?


This is a way to get the scope inside a qouted macro


that is if you quote a macro to create a list of the symbols, ~ will actually expand (eval) the part you use it with


maybe have a look at something like that:

Suren P10:03:23

Thanks, haven't gotten around to reading about macros yet.

Lennart Buit06:03:08

I like how this is called weird_characters


Where is the best channel to report documentation improvements? Github? I am under the impression that there is something wrong with


clojuredocs is a community driven site


if you want to improve the docstring of a clojure function itself, you can first discuss in #clojure-dev and ask if it’s worth posting an issue

👍 5

and if it is, you can go sign up for the CA and open a JIRA ticket

Alex Miller (Clojure team)15:03:48

the snark is really unnecessary


I think the docs for reify says a lot about how but misses the point for what "reify" does. Under the perspective of somebody who came across that function in a codebase, and looked it up, the expectation was to find some definition like the one in Stu's+Aaron's Book:

Reify lets you create an anonymous instance of a datatype that implements either a protocol or an interface.


Snark removed, just a joke, didn’t mean anything by it 🙂

Noah Bogart15:03:36

I have a design/architecture question: I I have some logic that's repeated in a couple different places, and I want to DRY it a bit. The only way I've figured out how to do so is to build a "wrapper" that takes in 5+ functions and then uses those to pivot or pass the necessary data around. I've looked into multi-methods that's not quite what I need (because I'd end up just repeating myself in each method)

Noah Bogart16:03:13

Does anyone have resources or suggestions as to how to pull abstractions out without turning it into a weird "mess"?

Noah Bogart16:03:18

If this were more OOP, I'd build an interface or base class, write the base logic in a method on it, and then inherit and write the variations in each child, relying on the parent to provide the abstraction, but I'm dealing with generic data structures (maps as my main data object)


if you need something like an interface you can write a Protocol


but I’m not sure if that make sense in your situation


what could also work: (merge {:fn1 default-fn1 :fn2 default-fn2} {:fn-1 override-fn1})?

Noah Bogart16:03:19

With my current proposed changes, it'd look like this:

(let [wrapped-damage (prevent-wrapper :runner
                                      (fn [target args] [:damage :damage-prevent (:type args)])  ;prevent-loc-fn
                                      (fn [target args] (:type args))                            ;card-prevent-fn
                                      (fn [target args] "Runner to prevent damage")
                                      (fn [target args] "Prevent damage?")
  (defn damage
    "Attempts to deal n damage of the given type to the runner. Starts the prevention/boosting process and eventually resolves the damage."
    ([state side type n] (damage state side (make-eid state) type n nil))
    ([state side type n args] (damage state side (make-eid state) type n args))
    ([state side eid type n {:keys [unpreventable unboostable card] :as args}]
     (swap! state update-in [:damage :damage-bonus] dissoc type)
     (swap! state update-in [:damage :damage-prevent] dissoc type)
     (trigger-event state side :pre-damage type card n)
     (let [n (damage-count state side type n args)]
       (if (pos? n)
         ;; This is where all of the old logic would have gone (very messy)
         (wrapped-damage state side eid n (assoc args :type type))
         (effect-completed state side eid))))))

Noah Bogart16:03:28

and that doesn't feel quite right to me


@nbtheduke Could you implement a protocol to define the interface that each child (w/ variations) will implement. The common code can be in functions that take realizations of this protocol as argument?


If possible, I would also try to write most of the logic as pure functions and do the mutations (swap!) "outside".

✔️ 5
Noah Bogart16:03:59

I'd love to do that, but sadly, the engine leans very heavily on that kind of stuff


Yeah, if the API is already heavily stateful, don't bother 🙂


also have the two swaps! just update :damage once rather than do it twice

✔️ 10
Noah Bogart16:03:51

I'm reading the official clojure page on protocols ( now! any other protocol references I should look into?


worth noting the most recent development with protocols, in Clojure 1.10:

Matt Butler17:03:05

Is there a way to fully realise a data structure (all sub values) for the purpose of performance testing?


@mbutler doall, generally. Do you have lazy seqs within lazy seqs?


Postwalk with identity would probably do the trick

Matt Butler17:03:22

Yeah that was the first thing I thought of but felt a bit gnarly.

Matt Butler17:03:22

It's a big old data structure of maps and lazy seqs. Wanted a easy solution. Calling str on it atm. Appears to work

Matt Butler17:03:39

Although I admit inelegant


Is there a way to attach metadata to a map that gets purged whenever the map is modified in any way? (e.g. a new key is assoc’ed, etc)


not really. you could maybe create your own type that implements the metadata protocols in a specific way


@lilactown ah ok, unfortunate. I was wondering if I could use such a feature to make runtime checks of validity against a spec cheap. e.g. I could do a s/valid? check, and cache the result on the object (as metadata), so that future checks would be a simple look-up


(if the map doesn’t change)


@hmaurer why not cache it in an atom or something and look it up in there?


yep could do that too


good point