This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-24
Channels
- # announcements (4)
- # asami (5)
- # babashka (20)
- # beginners (94)
- # bristol-clojurians (1)
- # calva (23)
- # cider (2)
- # clj-commons (3)
- # clj-kondo (43)
- # cljfx (2)
- # cljs-dev (13)
- # clojure (112)
- # clojure-dev (44)
- # clojure-europe (17)
- # clojure-nl (5)
- # clojure-poland (12)
- # clojure-spec (2)
- # clojure-uk (3)
- # clojurebridge (1)
- # clojurescript (92)
- # cursive (17)
- # data-science (8)
- # datahike (1)
- # datalevin (1)
- # datomic (3)
- # deps-new (7)
- # events (2)
- # fulcro (40)
- # graalvm (110)
- # holy-lambda (16)
- # introduce-yourself (1)
- # lsp (13)
- # malli (8)
- # missionary (12)
- # off-topic (10)
- # pathom (13)
- # polylith (10)
- # portal (28)
- # re-frame (37)
- # reitit (1)
- # releases (1)
- # shadow-cljs (30)
- # spacemacs (1)
- # tools-deps (9)
- # xtdb (10)
another encode
question: how do I handle subsequences that I want to encode into single values? I've got some data like:
(let [data ["some text" "ex1.csv - file 1" "ex2.csv - file 2"]
expected-result ["some text" {"file 1" "ex1.csv" "file 2" "ex2.csv"}]]
(m/encode
[:catn [:txt [:= "some text"]]
[:subseq [:repeat {:encode/extract {:leave #(apply merge %)}}
[:re {:encode/extract {:enter #(let [[id fnum] (clojure.string/split % #"\s-\s")]
{fnum id})}}
#".* - file \d"]]]]
data
(mt/transformer {:name :extract}))
)
;; => ["some text" {"file 1" "ex1.csv"} {"file 2" "ex2.csv"}]
the #(apply merge %)
encoder works to merge the maps extracted if the :repeat
schema is a top-level schema, but not if it is a schema for a subsequence of a seqex.
am I pushing encode
too far here? should I be relying on parse
to do this kind of grouping?thinking about this a bit more, it doesn't seem like this is possible, as different values are being encoded depending on whether the sequex is top-level or a subsequence: top-level:
(let [data ["ex1.csv - file 1" "ex2.csv - file 2"]
expected-result {"file 1" "ex1.csv" "file 2" "ex2.csv"}]
(m/encode
[:repeat {:encode/extract {:leave #(apply merge %)}}
[:re {:encode/extract {:enter #(let [[id fnum] (clojure.string/split % #"\s-\s")]
{fnum id})}}
#".* - file \d"]]
data
(mt/transformer {:name :extract}))
)
;; => {"file 1" "ex1.csv", "file 2" "ex2.csv"}
so really the object of encoding is a complete vector, the vector of maps created after each string element gets encoded.
whereas with the subsequence, it's not a clearly delineated individual value:
["some text"
#_"start of subsequence in :repeat"
{"file 1" "ex1.csv"} {"file 2" "ex2.csv"}
... #_"arbitrary number of additional repeats"
#_"end of subsequence in :repeat" ]
and thus cannot be passed in as an argument to the function referenced in :encode/extract
, even if that function accepts varargs or an input sequence. so I think I need to rely on m/parse
to do the grouping I am hoping for here.Is there some way for having context sensitive transformers? e.g. when transforming a child in a coll, being able to take into account what happened to already transformed children
In other words, is transforming strictly context-free?
could you provide an minimalistic example when this would be useful. There was a discussion about this long ago, but a) there was no real-life examples for “why?” and b) context-free made performance optimization much easier. Happy to revisit, but need the a) 🙂
there was also a discussion just to implement all applications (validation, transforming) using walk. That was my original idea for Spec too (https://clojure.atlassian.net/browse/CLJ-2251).