This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-02
Channels
- # babashka (117)
- # babashka-sci-dev (6)
- # beginners (34)
- # biff (2)
- # calva (7)
- # clj-kondo (27)
- # clojure (6)
- # clojure-dev (8)
- # clojure-europe (41)
- # clojure-israel (1)
- # clojure-nl (1)
- # clojure-norway (2)
- # clojure-uk (1)
- # clojurescript (22)
- # cursive (3)
- # datascript (12)
- # dev-tooling (4)
- # emacs (13)
- # hyperfiddle (60)
- # introduce-yourself (8)
- # joyride (9)
- # lsp (46)
- # malli (3)
- # mranderson (75)
- # off-topic (40)
- # pathom (9)
- # pedestal (4)
- # reagent (11)
- # reitit (18)
- # releases (2)
- # shadow-cljs (81)
- # squint (18)
tldr: I'm wondering if there is a better pattern than the "http-context" where you need to pass around state that gets constantly updated. ... I'm writing a recursive descent parser that needs to keep track of the token stream .. a similar pattern used in my lexer actually (although I wrote a mutable version of that one as well that bugs me because mutable). Passing a state record down that gets updated and passed back up as you parse expressions (or lex tokens). All I can see is the word "state" throughout my code and it's bugging me lol. Is this where one would normally reach for an atom/ref/agent, etc? example for a binary expression:
(defmethod match :binary
[_ state left-fn right-fn token-types]
(let [lstate (left-fn state)
matched? (match? lstate token-types)]
(if-not matched?
lstate
(let [op (current lstate)
rstate (right-fn (advance lstate)) ;; matched so need to advance
lexpression (first (:expressions lstate))
rexpression (first (:expressions rstate))
fstate (store-and-advance rstate (ast/expression :binary
lexpression
op
rexpression))]
fstate))))
A program that "passes around state" is easier to test than a program whose 9,999 methods alter an atom. And after a failure wouldn't the atom have to be reverted back to some prior state in order for the next possibility to be tried? Of course if the state's appearance in the code is completely routine then you could automate it away with a macro, or if the code overall is quite routine then you could either code-generate it or otherwise make it data-driven to reduce the surface area of source code. But - in general - "passing around state" is one of the great things about not-OO.
Not sure if this will work for your situation, but take a look at interceptors
. Some links
http://pedestal.io/guides/what-is-an-interceptor
https://lambdaisland.com/episodes/interceptors-concepts
https://www.youtube.com/watch?v=bDN898hu_wQ
https://ericnormand.me/article/a-model-of-interceptors
https://quanttype.net/posts/2018-08-03-why-interceptors.html
https://github.com/metosin/sieppari
https://www.proctor-it.com/papillon-a-new-interceptor-library-for-clojurescript/
Thanks! Had forgotten about Pedestal's interceptors .. have used Pedestal before for a web service and quite liked the pattern there.
RE: code generation from data. I had thought about making a parser generator from the bnf grammar (since this is a toy) .. but decided I want to get to done before veering off into the weeds 🙂
If I have a text file containing:
- A
- a
- b
- B
- c
- C
What's the recommended way or libs to parse the file and generate something like:
[ [A [a b]] [B [c]] C ]
edit:
I also wonder how these nested data are generally represented?
If I use key value pairs to represent the data (something like json), the entry "C" doesn't have value at all.Looks like YAML, maybe you can use a YAML parser?
There are multiple ways to represent this, your suggestion is one example. For consistency, you could represent every (non-leaf?) item as [key children]
, turning C
into [C []]
and so on. Another option is to use maps:
{"A" ["a" "b"]
"B" ["c"]
"C" []}
Have a variable imgfmt and want to check if it equals one of several string values. Came up with two solutions but both seem a bit convoluted?
(some #(= imgfmt %) ["webp" "avif" "jpeg"])
or
(nil? ({"webp" true "avif" true "jpeg" true} imgfmt))
OK figured it out:
(some #{imgfmt} ["webp" "avif" "jpeg"])
I was about to suggest the reverse, define a set (def formats #{"webp" "avif" "jpeg"})
and use it as a function: (formats imgfmt)
ah yes, that's much nicer!
thanks
will need to get used to using sets
hey, i’m trying to use https://github.com/benedekfazekas/mranderson to shade my library’s dependencies so they won’t interfere with my other repos using this lib. anyone here has any experience using it and can help out?
I might not be the best person to answer your question, but I've made a few commits to MrAnderson, so I might be able to help. What problem are you having?
thanks, so basically it never compiles for me.
when using [thomasa/mranderson "0.5.3"]
and running lein inline-deps
i get
RuntimeException: No reader function for tag Inf, compiling:(mranderson/inlined/parallel/v0v10/parallel/core.clj:323:31)
when using [thomasa/mranderson "0.5.4-SNAPSHOT"]
the issue above is resolved and inline-deps complete, but then when i run
lein with-profile +plugin.mranderson/config test
there are many issues:
1. some source code gets a repeating prefix again and again, like mylib101012.mylib101012.mylib101012.mylib101012.mylib101012.some.ns
which i workaround via search&replace.
2. mranderson will inline and add prefix to code which is defined in :prefix-exclusions
- again search&replace to workaround
3. then i get NoClassDefFoundError: mylib01012/javax/net/ssl/SSLEngine
which i couldn’t resolve, i do see srcdeps/mylib101012/javax
but there’s no net
under it.
thanks for helping out!i get a sense that 0.5.4-SNAPSHOT might be still unstable, while 0.5.3 doesn’t play well with something in my lein environment
@U04H5V7URR9 is your library public? If so, can you share a link?
it’s a fork of https://github.com/fullcontact/full.aws/tree/0.10.9 by FullContact, based off tag 0.10.9
with deps modified to:
:dependencies [[org.clojure/clojure "1.8.0"]
[com.amazonaws/aws-java-sdk "1.11.16"]
[com.taoensso/faraday "1.7.1" ; DynamoDB sugar
:exclusions [com.amazonaws/aws-java-sdk-dynamodb joda-time]]
^:inline-dep [fullcontact/full.http "1.0.9"]
^:inline-dep [fullcontact/full.json "0.12.0"
:exclusions [com.fasterxml.jackson.core/jackson-core]]
[fullcontact/full.async "0.9.0"]
[fullcontact/full.core "0.10.1"
:exclusions [org.clojure/clojurescript]]
^:inline-dep [javax.xml.bind/jaxb-api "2.4.0-b180830.0359"]
^:inline-dep [com.fasterxml.jackson.core/jackson-annotations "2.6.0"]]
Not at a laptop at the moment to check, but I see Clojure 1.8.0 in the list there, and the error message mentions Inf. Reader syntax for ##Inf was added in a later Clojure version.
of interest: with @U0508JT9N's blessing I've just created a #C04HWRD2D32 channel.
Good eyeballs @U0CMVHBL2, no unit tests for that lib, eh @U04H5V7URR9? Would be nice to know if it works before applying MrAnderson.
yeah it works without mranderson, I've tried with clojure 1.9.0, and also clojure.tools that supports Inf and couldn't get it to compile still
If nobody else beats me to it, I can have a deeper peek sometime soon (maybe tomorrow) @U04H5V7URR9. Is your fork public?
that would be great! my fork is private, but other than the dependencies changes I didn't change a thing
Can you make it public? I would want to make sure I'm working with what you are working with.
I can try running mranderson on the official repo just to make sure I didn't screw anything up myself
also, I would mention I'm running with apple silicon M1 which has been the source of the most unusual bugs twice already, so maybe that's somehow related to this conundrum as well
But maybe you found a bug in MrAnderson too. Whatever the case, I expect we'll come to some solution.
let’s move to #C04HWRD2D32? it might get verbose 🙂