This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-05
Channels
- # announcements (10)
- # beginners (59)
- # calva (172)
- # cider (13)
- # clj-kondo (1)
- # cljdoc (10)
- # cljs-dev (4)
- # cljsrn (65)
- # clojure (144)
- # clojure-europe (2)
- # clojure-italy (26)
- # clojure-losangeles (1)
- # clojure-nl (14)
- # clojure-spec (26)
- # clojure-uk (91)
- # clojurescript (75)
- # core-async (53)
- # cursive (11)
- # datomic (16)
- # fulcro (42)
- # graalvm (29)
- # graphql (9)
- # kaocha (3)
- # leiningen (22)
- # off-topic (26)
- # qa (1)
- # re-frame (3)
- # reagent (7)
- # reitit (10)
- # rewrite-clj (56)
- # robots (1)
- # shadow-cljs (107)
- # spacemacs (10)
- # specter (5)
- # sql (15)
- # tools-deps (39)
- # vim (11)
I have a concurrency question. I've built this "n-body" simulator which currently does everything in a loop on a single thread and I now want to make it concurrent. All bodies are represented as maps with a mass, x y pos and a velocity vector [vx vy]. Three things need to happen. 1. Calculate forces applied to each body and update their velocity 2. Update the position of all bodies 3. Draw all the bodies What I'm wondering is should I use Refs or Agents for this?
That sounds like a hard problem to multithread. Where do you draw the boundary between what things can be calculated on separate threads.
@nicholas.jaunsen It might be worth looking at Rich's old Ants demo for inspiration
I am sure I am doing something dumb here and any help would be appreciated. I am trying to setup a http-kit server with compojure routing. If i curl the routes i get a 404 from http-kit. The relevant code and project.clj is here: https://gist.github.com/jldoubleu/d2f7d54d49875f0682831c792c31f7bf I was trying to follow the example outlined here: https://www.http-kit.org/server.html#routing.
solved. was missing an argument from the route definitions.
when to use go-block vs thread vs thread call? I know the second two return channels but why use what you pass in to thread and thread call in a go-block?
@mario.cordova.862 thread vs thread call -- what is thread call?
(thread (do-some-stuff) (do-more-stuff))
=> (thread-call (fn [] (do-some-stuff) (do-more-stuff)))
use that if you are doing blocking calls or any direct I/O -- use go
if you want a 'virtual' / 'green' thread if the only blocking calls you make are interactions with channels through <! >! or alts! alt!
If I am making an API call that takes 30 seconds to respond, should I be using the thread?
if you want to do that from a go block, have your go block call something that calls thread/thread-call
the reason is that go blocks are scheduled in a thread pool, and I/O that isn't channels can starve the pool or deadlock
when a go block reaches one of those operations, and it blocks, another go block will resume in its place
if you do something like a direct 30 second call in a go block, it will prevent other go blocks from running
Interesting, I didn't know... Just knew that it blocks at <!. I gotta dig deeper into this
Is it idiomatic to create namespaces for entities when working with clj/cljs? For example in a simple domain that has a Task
entity and a Task List
should I have two namespaces like so
;; src/taskmanager/task.cljs
(ns taskmanager.task
(:require [clojure.string :as str]))
(defn create
[body]
{:body (str/trim body)
:date-created (. js/Date now)
:date-completed nil})
(defn completed?
"Has the task been completed?"
[task]
(boolean (:date-completed task)))
(defn close
[task]
(if-not (completed? task)
(assoc task :date-completed (. js/Date now))))
;; src/taskmanager/tasklist.cljs
(ns taskmanager.tasklist
(:require [taskmanager.task :as task]))
(defn create
"Creates an empty task list"
[name]
{:name name :tasks []})
(defn add-task
"Adds a new task to the given task list"
[body list]
(let [t (task/create body)]
(update-in list [:tasks] conj t)))
(defn count
"Returns the total number of tasks within the given list"
[list]
(count (:tasks list)))
or would having a single tasks
namespace with all the functionality for managing task lists and tasks in make more sense?
Really just trying to understand if this is over engineering or actually good practice
I offend people with my huge namespaces, so don't take my word. but I probably wouldn't use namespaces for this
that being said, if your implementations start to grow (and continue to diverge) then splitting them in namespaces would be nice
Thanks for your input, I think you may have hit the nail on the head with splitting it up as it grows and I have a better idea of what data structures/functions are related and how
if what you want is constructors and methods, we have records and protocols for that, I'd be inclined to refocus the code to be about data flowing through rather than entities, or switch over to constructs that are explicitly designed for entity definition
I do sometimes wish that Clojure had something like first-class namespaces, which would make stuff like modeling entities as namespaces more tenable 😉 but what noisesmith said is 👌
@noisesmith So focus more on the use cases?
yes - my first approach would be to define things in terms of the operations on data
yes, and if an entity model is an improvement, that would use things that are designed for it - records implementing protocols being my first choice there
and it would probably just use / organize the functions I defined in the first pass
I see, I haven’t written any protocols yet, not entirely sure when to reach for them, is it usually when I have a function I want to call on different data types? Being able to close a ticket and a task list (for a bad example) I could have a protocol that defined a close
function and create two implementations of it for task list and task or would that be a multi method :thinking_face:
they are faster than multimethods iirc, so you want to use protocols when possible (e.g. you only need type based dispatch and not dispatch on value)
my usual decision is whether there's a group of related operations (protocols allow that) vs. a standalone polymorphic thing (multimethods allow that, with greater flexibility)
vs. a data operation that can be defined using clojure's collection ops that are already polymorphic and optimized and debugged (best option, when possible)
This is all great, thank you. I’m sure it will make more sense as time goes by and I gain more experience through trial and error
I’m still interested in possibly playing around with Clojure and Corda. I am looking at https://github.com/corda/cordapp-example/blob/release-V3/kotlin-source/src/main/kotlin/com/example/flow/ExampleFlow.kt and wondering: what is the recommended way to build something like the ExampleFlow… proxy
. gen-class
?
I don't know kotlin - is that inheriting any concrete classes or just implementing interfaces?