Fork me on GitHub
#beginners
<
2019-04-01
>
Lucas Barbosa00:04:10

Does future-cancel do anything other than signal an interruption to that future's thread?

alexmiller01:04:15

not really, no

alexmiller01:04:58

it's going through an executor so there's some task mgmt over the top of that

Lucas Barbosa01:04:30

I see. I have a component that works in a background thread, and I was looking for a better way to implement a synchronous shutdown. This is the way I did it:

(defrecord ActionProcessor [event-queue
                            action-queue
                            execution-repository
                            stop-handle]
  component/Lifecycle
  (start [this]
    (let [should-stop? (atom false)
          stop-promise (promise)
          stop-handle  #(do (reset! should-stop? true) @stop-promise)]
      (future
        (loop []
          (when-let [action (q/take action-queue 1000)]
            (when-not (= :timeout action)
              (try
                (dispatch action event-queue execution-repository)
                (catch Exception ex
                  (.printStackTrace ex)))))
          (if @should-stop?
            (deliver stop-promise true)
            (recur))))
      (assoc this :stop-handle stop-handle)))
  (stop [this]
    (stop-handle)
    (assoc this :stop-handle false)))

Lucas Barbosa01:04:23

I have a feeling that there is a better way to do this

elamje04:04:18

@seancorfield What are some namespaces/functions you like from 1.10.1, that are currently under development?

seancorfield06:04:33

@j3elam There's almost nothing new in 1.10.1 compared to 1.10 (except bug fixes) but in 1.10, the interesting new stuff is clojure.datafy (in terms of new namespaces).

👍 4
valerauko07:04:29

can someone enlighten me what are the behavior differences between deftype and defrecord?

mfikes11:04:53

Another good pithy explanation I've seen is : - defrecord is for information - deftype is for mechanism

sylvain11:04:10

Can someone suggest a cleaner way to write stuff like this ? I want to use the "->" threading macro but the asserts get in the way.

Jephthah11:04:47

Hey guys, I just downloaded clojure via the installer for windows (it downloaded as powershell module). I need help getting it started.

Alex11:04:39

(-> a (foo1 “44) (#(assert (bar1 %))) etc..

Alex11:04:24

when a is not first arg, use #(fn %)

sylvain11:04:41

Nice! thanks.

Jephthah11:04:02

Anyone? 🙂

Alex11:04:18

Tried and failed to get Clojure working on Windows, sorry @inagbotamuno;[

Jephthah11:04:18

So no one here runs clojure on windows 😞

andy.fingerhut11:04:30

#Jephthah There is a channel #clj-on-windows that probably has the highest density of Clojure users on Windows on Slack.

lispyclouds12:04:26

@inagbotamuno I dont use windows but this seems to be an alternative way: https://lispcast.com/clojure-windows-8/

Jephthah12:04:19

Much appreaciated @rahul080327 😄

Jephthah12:04:29

*appreciated

tabidots12:04:47

@sylvain I don’t know if this is the best way to do it but the first thing I thought of was “nil-punning” by using if-let or when-let rather than ->. You would have to rewrite your functions to return either some value or nil depending on if they pass the test though.

leonoel12:04:00

@sylvain

(-> a
    (foo1 "44")
    (doto (-> bar1 assert))
    (foo2 33 22)
    (doto (-> bar2 assert)))

sylvain12:04:18

@leonoel I like this one. Thanks.

leonoel13:04:24

have a look at as->, too

leonoel13:04:12

it's sometimes convenient to capture an intermediate value inside a ->

sylvain13:04:11

Right but the nice thing about doto in this case is that it conveniently returns the threaded value because assert returns nil.

leonoel13:04:02

yes, very useful for side-effects (doto println) inside -> is a popular debugging trick

👍 12
yuhan13:04:32

also if you find yourself always calling (assert) on a function's return value, try taking a look at postconditions

jumar14:04:38

And beware that it throws AssertionError which may be surprising if you only catch Exception in your top-level logging handler

Roman Chvanikov14:04:24

Hi everybody, I’m a newcomer to the Cojure world and want to give it a try for the frontend part of my app (with ClojureScript). I’ve played around a bit and I know most of the theory basics, but still not feeling comfortable about designing an app, structuring code, working with libraries and other stuff you get with practice. So, what resources are typically recommended to newcomers for clojurescript development? Books, tutorials, screencasts, etc. - I’ve found a few but some of them seems outdated, so it’s hard to follow, and others have little to none reviews… Also, not just for clojurescript, but for clojure - are there any “must-read” resources?

Alex15:04:04

I enjoyed this

Alex15:04:44

It’s not pure CLJS, it’s CLJS with reagent.. but it was goood

Roman Chvanikov15:04:55

thanks @a.pittendrigh I was looking at reagent and re-frame choosing what to try out, will start with reagent then 🙂

Alex15:04:05

GL, HF 👍

Terdia0718:04:34

Hello everyone, nice to be here

zlrth18:04:05

any way to redef a a local binding defined by a let inside a function using with-redefs or similar?

zlrth18:04:24

use case is: i'm trying to write a quick-ish running integration test around a function that retries multiple times, and fails. in production, it retries a bunch of times with exponential backoff, in test, i want it to try fewer times with less backoff

noisesmith19:04:44

binding doesn't work on let bound values

👍 4
zlrth19:04:47

i've never used binding before, it looks like as of clojure 1.3 it's intended for dynamic, top-level-bound vars

noisesmith19:04:01

you can use with-local-vars, or refactor so you don't need to alter the locals

noisesmith19:04:33

let bindings aren't vars - there's no var to redef

zlrth19:04:34

cool thanks. considering i'm working from a test namespace, i don't even know how to refer to the let-bound binding. namespace/function.local-binding?

zlrth19:04:03

factoring it out seems better for a bunch of reasons

noisesmith19:04:16

there's intentionally no access without relying on fragile impelmentation details

noisesmith19:04:57

the common refactor is an optional map supplying override parameters, and an arity overload that supplies the default values

zlrth19:04:46

ah good to know. thanks

noisesmith19:04:47

so (defn frob ([x] (frob x {:timeout 1000})) ([x opts] (let [{:keys [timout]} opts] ...))

noisesmith19:04:06

in your test you provide the opts map, in normal code it shouldn't be needed

noisesmith19:04:26

you can even use this to mock out implementation details or side effects in tests

noisesmith19:04:46

also you usually want to merge opts on top of the default in the full arity version, rather than only providing if the opts map is absent

noisesmith19:04:02

so (def defaults {:timeout 1000}) (defn frob ([x] (frob x {})) ([x options] (let [opts (merge defaults options) {:keys [timout]} opts ...] ...))

👍 4
noisesmith19:04:30

I wonder if there's a doc / blog for that pattern somewhere, I see it so often with top level code that does IO and needs unit testing

👍 4