This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-05-04
Channels
- # announcements (4)
- # aws (3)
- # babashka (58)
- # beginners (59)
- # biff (6)
- # cider (3)
- # clj-kondo (48)
- # clj-on-windows (1)
- # cljdoc (1)
- # clojure (136)
- # clojure-europe (19)
- # clojure-gamedev (7)
- # clojure-germany (2)
- # clojure-nl (7)
- # clojure-norway (1)
- # clojure-portugal (1)
- # clojure-uk (4)
- # clojurescript (41)
- # community-development (2)
- # core-async (5)
- # cursive (10)
- # data-oriented-programming (1)
- # data-science (1)
- # datahike (5)
- # datomic (58)
- # docker (2)
- # emacs (13)
- # figwheel-main (19)
- # fulcro (12)
- # graalvm (9)
- # holy-lambda (41)
- # honeysql (14)
- # introduce-yourself (3)
- # jobs (4)
- # lsp (11)
- # nrepl (1)
- # off-topic (9)
- # other-languages (2)
- # pathom (22)
- # portal (5)
- # re-frame (17)
- # remote-jobs (4)
- # reveal (14)
- # shadow-cljs (1)
- # tools-build (7)
- # tools-deps (47)
- # xtdb (8)
- # yada (2)
There's something I don't understand about recur
. I have the following code which is the outer form of a model of an "epistemic network", used in philosophy of science to model how beliefs spread among scientists
(defn play [game]
(loop [game (round game)]
(if (or (converged? game) (> (:rounds game) 10000))
(assoc game :converged (converged? game))
(recur (play game)))))
(let [game (make-game (make-cyclic-graph 6) :n 1 :A-success-prob 0.5 :B-success-prob 0.7)]
(play game))
I think I'm using recur correctly, right?
At any rate, it often works, but when it goes above ~2700 rounds without converging it blows the stack. The round
function is a composite of three other functions operating on the game: take-action
, update-params
, and update-beliefs
. The traceback says the stack overflow happens in a let
form within update-params
, which I'll paste below
(defn update-params
"[network node n] update the beta distribution parameters for a node based on the node and its neighbours. Returns an updated graph
[game] update params for all the players in a game. Returns an updated game
"
([network node n]
(let [node-attrs (uber/attrs network node)
nodes (conj (uber/neighbors network node) node)
all-attrs (map #(uber/attrs network %1) nodes) ;;; <- this is a typical line marked in the traceback.
a-attrs (filter #(= (:action %) :A ) all-attrs)
b-attrs (filter #(= (:action %) :B ) all-attrs)
a-result-sum (reduce + (map :reward a-attrs))
b-result-sum (reduce + (map :reward b-attrs))]
(uber/add-attrs network node
{:alpha-A (+ (:alpha-A node-attrs) a-result-sum)
:beta-A (+ (- (:beta-A node-attrs) a-result-sum) (* n (count a-attrs)))
:alpha-B (+ (:alpha-B node-attrs) b-result-sum)
:beta-B (+ (- (:beta-B node-attrs) b-result-sum) (* n (count b-attrs)))
}
)))
([game]
(let [network (:network game)
update-fn #(update-params %1 %2 (:n game))]
(assoc game
:network (reduce update-fn network (uber/nodes network))
:updates (inc (:updates game))))))
you can try this lib - https://github.com/xapix-io/paos but wsdl is very complicated technology and it might not work well enough
thanks. I have read that . It's too complicated to use. for example : call add method for calculate 1+2 😭
(let [soap-service (wsdl/parse "")
srv (get-in soap-service ["CalculatorSoap12" :operations "Add"])
soap-url (get-in soap-service ["CalculatorSoap12" :url])
content-type (service/content-type srv)
headers (service/soap-headers srv)
mapping (service/request-mapping srv)
context (assoc-in mapping ["Envelope" "Body" "Add" "intA" :__value] 1)
context2 (assoc-in context ["Envelope" "Body" "Add" "intB" :__value] 2)
body (service/wrap-body srv context2)
parse-fn (partial service/parse-response srv)]
(-> soap-url
(client/post {:content-type content-type
:body body
:headers headers})
:body
parse-fn))
;; => {"Envelope" {"Header" {"__value" nil}, "Body" {"AddResponse" {"AddResult" {"__value" "3"}}}}}
i would totally recommend creating a java lib and calling it from clojure
calling ws is a real PITA and have many, many special cases
"pain in the ass" 🙂
btw, even with a java lib call to Calculator service might be even more complex because of java interop.
why ? java is fine for calling WS
(defn soap-service [url]
{::soap-service (wsdl/parse "")})
(defn invoke [service object method arguments]
(let [{::keys [soap-service]} service
srv (get-in soap-service
[object :operations method])
soap-url (get-in soap-service [object :url])
content-type (service/content-type srv)
headers (service/soap-headers srv)
mapping (service/request-mapping srv)
context (reduce (fn [ctx [arg v]]
(assoc-in ctx ["Envelope" "Body" method arg :__value] v))
mapping
arguments)
body (service/wrap-body srv context2)
parse-fn (partial service/parse-response srv)]
(-> soap-url
(client/post {:content-type content-type
:body body
:headers headers})
:body
parse-fn)))
and then
(let [service (soap-service "")]
(invoke service "CalculatorSoap12" "Add" {"intA" 1 "intB" 2}))
Thank you !! @U3JH98J4R I'll try it.
@U025AG2H55F I think that paos is not too complicated with refactoring of the example and creating some supporting functions. Assigning params can be done with reduce,
@U025AG2H55F just checkng back in did this solve your issue?
use java ?
How can I mix java file and clj in deps like this?
:paths ["src" "java-src"]
but I run in calva show 'import error'On the general question. I've written a short blog article about it: https://blog.agical.se/en/posts/mixed-clojure-and-java/ See if that setup is different in some significant way to the one you have, maybe?
I put the class files in java-src is ok . but put the class in target/classes
show "unable to resolve classname". in my deps.edn add this. :paths ["src" "java-src" "resources" "config" "target/classes"]
Hi , I am new to clojurescript development and I am having trouble with code Navgiation in VS code using the Calva Extension , When I press F12 to go to namespaces/function definitions vscode transitions to loading state and cannot navgiate to the targeted codeblock These are my configs
{:lein true
:nrepl {:port 8777}
:builds {:app {:target :browser
:output-dir "resources/public/js/compiled"
:asset-path "/js/compiled"
:modules {:app {:init-fn stellar.awesome-o.core/init
:preloads [devtools.preload
re-frisk.preload
;; day8.re-frame-10x.preload
]
:main {:init-fn stellar.awesome-o.core/init}}}
;; :release {:build-options
;; {:ns-aliases
;; {day8.re-frame.tracing day8.re-frame.tracing-stubs}}}
:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true
;; "day8.re_frame.tracing.trace_enabled_QMARK_" true
stellar.awesome-o.config/base-uri #shadow/env "APP_URL"}
:devtools {:http-root "resources/public"
:http-port 8280
}}}}
Lein Project.clj
(defproject stellar.awesome-o "1.0.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.10.1"]
[org.clojure/clojurescript "1.10.597"
:exclusions [com.google.javascript/closure-compiler-unshaded
org.clojure/google-closure-library
org.clojure/google-closure-library-third-party]]
[thheller/shadow-cljs "2.8.83"]
[reagent "0.10.0"]
[re-frame "0.11.0"]
[day8.re-frame/http-fx "v0.2.0"]
[hickory "0.7.1"]
[garden "1.3.9"]
[ns-tracker "0.4.0"]
[com.taoensso/timbre "4.10.0"]
[day8.re-frame/http-fx "v0.2.0"]
[reagent-utils "0.3.3"]
[mattinieminen/re-fill "0.2.0"]
[re-pollsive "0.1.0"]]
:plugins [[lein-garden "0.3.0"]
[lein-shell "0.5.0"]]
:min-lein-version "2.5.3"
:jvm-opts ["-Xmx1G"]
:source-paths ["src/clj" "src/cljs"]
:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"
"resources/public/css"]
:garden {:builds [{:id "screen"
:source-paths ["src/clj"]
:stylesheet stellar.awesome-o.css/screen
:compiler {:output-to "resources/public/css/screen.css"
:pretty-print? true}}]}
:shell {:commands {"open" {:windows ["cmd" "/c" "start"]
:macosx "open"
:linux "xdg-open"}}}
:aliases {"dev" ["with-profile" "dev" "do"
["run" "-m" "shadow.cljs.devtools.cli" "watch" "app"]]
"prod" ["with-profile" "prod" "do"
["run" "-m" "shadow.cljs.devtools.cli" "release" "app"]]
"build-report" ["with-profile" "prod" "do"
["run" "-m" "shadow.cljs.devtools.cli" "run" "shadow.cljs.build-report" "app" "target/build-report.html"]
["shell" "open" "target/build-report.html"]]
"karma" ["with-profile" "prod" "do"
["run" "-m" "shadow.cljs.devtools.cli" "compile" "karma-test"]
["shell" "karma" "start" "--single-run" "--reporters" "junit,dots"]]}
:profiles
{:dev {:dependencies [
[re-frisk "1.3.2"]
[binaryage/devtools "1.0.0"]]
:source-paths ["dev"]}
}
:prep-tasks [["garden" "once"]])
Also , I am using the Reframe framework and want to be able to easily navigate to my events and routes , is there any useful tool for this ?
I’m not immediately sure what’s going on with the code navigation, but @U0ETXRFEW may be able to help you further soon (I’m a bit busy today). clojure-lsp allows you to navigate to re-frame events and subs and is built into Calva, so that should be working for you. (You can go to definition of a re-frame keyword and find all references.)
If that’s not working, maybe clojure-lsp is not starting correctly for you, or there is some other issue related to it going on.
How are you starting the REPL, @U02JS8BDHB9?
Hi again ,thank for the quick help . It's much appericiated , as mentioned I was starting my REPL In the wrong configuration ( Lein + ShadowCljs ) I started the repl using lein dev with my dev profile and connected to it using the connect to a repl in your project option in Calva As for the Code navigation issues, it was due to an overlap with the Clojure Extension which I think is incompatible with calva ( I think this is even mentioned ) I turned off the clojure extension and it worked!

Great! Did you get the re-fram handler navigation to work as well? That should be independent on the REPL, even working when the REPL is not started, since it is a static service provided by clojure-lsp.
It's great that you got rid of the overlap. Probably a lot of users that fall into that trap... However, I'm thinking that the re-frame navigation shouldn't be affected. I could be wrong, and what matters is that it is working for you now! 😃
(instant/read-instant-date "2022-03-22T23:41:37.984-05:00")
=> #inst"2022-03-23T04:41:37.984-00:00"
(instant/read-instant-date "2022-03-22T23:41:37.984-0500")
Execution error at log-reader.schema/eval6320 (form-init5628881862092164982.clj:1).
Unrecognized date/time syntax: 2022-03-22T23:41:37.984-0500
I was surprised to see the latter case isn't handled, or offset without :
Is there a convenient way to get around this or lightweight library that is more permissive? I could delve into SimpleDateFormat shennanigans, but seems a shame when the out of the box solution is so close@mkeller02 what is the target object you are trying to get?
read-instant-date returns a java.util.Date read-instant-timestamp returns a java.sql.Timestamp
Oh, my fault. I'll correct the latter. But it's the same result
(instant/read-instant-date "2022-03-22T23:41:37.984-0500")
Execution error at log-reader.schema/eval6324 (form-init5628881862092164982.clj:1).
Unrecognized date/time syntax: 2022-03-22T23:41:37.984-0500
I don't know what library you are using, but java ships with date parsers for java.util.Date and java.time.Instant and both of those parsers are configurable (you give it a format string that describes the parts of the string to parse into a date)
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html is for Instants and https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html is for Dates
Is there a way to apply a macro to multiple expressions?
For example, I have 3 expressions and want dosync
for each of them, i.e, a separate transaction for each expression.
when in doubt, add more macros
(defmacro nsync [& exprs]
(cons 'do
(map (fn [expr] `(dosync ~expr)) exprs)))
(macroexpand '(nsync (a) (b) (c)))
(do (clojure.core/dosync (a)) (clojure.core/dosync (b)) (clojure.core/dosync (c)))
This macro works, thanks! I haven't studied macros yet so the code seems a little bit obscure but nevertheless it enforces the feeling for me that with Clojure you can do wonderful things:)
P.S. I tried to implement the same thing with anonymous function but I was doing it in a rather naive way: (map #(dosync %) [expr1 expr2 expr3])
which obviously didn't work because of No transaction running
.
macros are just functions that take code and return code. this macro takes
(nsync (a) (b) (c))
and returns
(do (dosync (a)) (dosync (b)) (dosync (c)))
the problem with yours is that expr1/2/3 will be evaluated before they reach the function whereas the macro receives the arguments unevaluated
macros can also be thought of as compiler extensions written by the user