Fork me on GitHub
#beginners
<
2021-11-11
>
seancorfield00:11:46

@ewolodzko If it helps, these are the only Contrib libraries that have .cljc and/or .cljs files:

core.async
core.logic
core.match
core.rrb-vector
core.typed
data.avl
data.xml
data.zip
math.combinatorics
test.check
tools.cli
tools.namespace
tools.reader

Erich Wolodzko15:11:42

That is helpful. Thank you!

quan xing07:11:25

(filter #(not ((second %) ""))
        (partition 2 ["Please enter an email address" not-empty
                      "Your email address doesn't look like an email address"
                      #(or (empty? %) (re-seq #"@" %))]))
this code ouput:
(("Your email address doesn't look like an email address" #function[macro.valid-fun/eval7680/fn--7683]))
and I expend code by myself
(defn foo[arg]
  (or (empty? arg) (re-seq #"@" arg)))

(filter #(not ((second %) ""))
        '(("Please enter an email address" clojure.core/not-empty)
          ("Your email address doesn't look like an email address" foo)))
and output result:
(("Please enter an email address" clojure.core/not-empty) ("Your email address doesn't look like an email address" foo))
why is the output different?

Fredrik07:11:57

Because in the second case, you are quoting the list, which means that the symbol foo is not resolved to the function with that name.

Fredrik07:11:19

Try replacing the list with

(list (list "Please enter an email address" clojure.core/not-empty)
      (list "Your email address doesn't look like an email address" foo))
and see what you get 🙂

zendevil07:11:42

how does one send a file to the client? I have an image file that I want to show in the client in path “foo/bar” (the path “foo/bar” is local to the server) where the path is stored in the db. I’m pulling the path from the db and I’m sending it in the response like: (io/file "foo/bar") But in the client, it’s showing up as the path string and not the actual file. How do I send the actual file? Do I have to send it as a data://.. string?

zendevil08:11:20

what if it’s a file to be pulled from s3?

thom08:11:22

In the simplest case you could redirect the browser to S3 but presumably that's not what you want. Generally for big dynamic outputs you'd use https://ring-clojure.github.io/ring/ring.util.io.html#var-piped-input-stream and stream the response (from clj-http or something). That prevents having to slurp it in its entirety as a string in memory.

zendevil08:11:30

I don’t exactly understand how piped-input-stream works. Suppose I have a file (io/file “foo/bar”), how do I send it in the response as a stream?

zendevil08:11:44

And how would the client read that stream and show that image?

thom08:11:06

So for a local file with a path it's still a simple file-response. You could also serve a FileInputStream as the body if you wanted more control over the response and content type. If it's an image then browsers should request and render that normally.

thom08:11:59

You only need the piped input stream stuff if you're reading the data from somewhere fancy or generating it, and if it's big enough to not want to hold all the bytes in memory at once.

Benjamin09:11:32

with aws ecs is there a way to run my app without docker?

delaguardo09:11:45

“Docker is the only container platform supported by Amazon ECS at this time.” from official https://aws.amazon.com/ecs/faqs/

Michaël Salihi10:11:35

Hi! I wonder what is the best Clojure approach to loop over vectors contained in map like that:

{:x [:a :b :c]
 :y [1 2 3]
 :z ["a" "b" "c"]}
Use recursion? Any clue?

Benjamin10:11:00

There is many ways of course, here for example with for

(let [m
      {:x [:a :b :c]
       :y [1 2 3]
       :z ["a" "b" "c"]}]
  (for [sx (vals m)
        item sx]
    item))

pavlosmelissinos10:11:55

You haven't given enough information. What's your goal? What result do you expect? E.g. do you want to apply a function to the map values but keep the shape of the data at the same time (still have a map in the end)? 1.11 will introduce update-vals and update-keys (There's an alpha version if you need it now) Another option is reduce-kv and then you can do whatever you want with each kv pair. Plain reduce also works. If your data is nested you might have to use clojure.walk A lot of options, it would help if you could be a bit more specific.

👍 1
Michaël Salihi14:11:39

Yes thanks for the advice, I'm going share more information. I would loop over values contained in the vectors and use them in a Reagent component column after column (not row). Ex. First iteration get :a 1 "a" and so on.

Michaël Salihi14:11:51

What do you recommend? To loop directly on this data or perhaps go through a step doing data massage in order to group the values by columns and then loop?

Michaël Salihi14:11:40

LMK if you need more information.

pavlosmelissinos14:11:44

Something like this?

(defn transpose-vals [m ks]
  (->> ((apply juxt ks) m)  ;; get the values in the order you want
       (apply map vector))) ;; transpose

;; e.g.
(transpose-vals
  {:x [:a :b :c]
   :y [1 2 3]
   :z ["a" "b" "c"]}
  [:x :y :z])
;;=> ([:a 1 "a"] [:b 2 "b"] [:c 3 "c"])
1. If you need a vector in the end you can use mapv instead of map 2. You lose the names of the "columns" but it's easy to reassemble them (the order is the same as in ks)

🙌 1
Michaël Salihi14:11:01

Yeah transposing seems to be what I need. I'm gonna test this right now! Thank you very much @UEQPKG7HQ

Michaël Salihi23:11:22

Like very much the idiom apply map vector 👍

clojure-spin 1
Benjamin12:11:14

(require '[clojure.spec.gen.alpha :as gen])
(require '[clojure.spec.alpha :as s])
(s/def ::items (s/and (s/* int?) vector?))
(type (gen/generate (s/gen ::items)))
=> clojure.lang.LazySeq
why does gen not generate a vector in this context? When I call conform it becomes a vector

alexmiller12:11:27

For s/and, it only gens from the first predicate, then filters with each subsequent

alexmiller12:11:10

So this will gen lists of item and then filter them all out

👍 1
Benjamin12:11:40

but it's the correct way to say vector of this stuff

alexmiller12:11:28

The general problem of specing a regex in a vector is actually difficult to make work for all of conform, unform, and gen simultaneously.(we have a fix for this in spec 2). But for this specific case I would use s/coll-of

👀 1
alexmiller12:11:25

You can use the :into and :kind flags to enforce the vector

🎉 1
FlavaDave19:11:07

I have an RN component

(defn goal-list []
  (let [goals (r/atom {:goal ""
                       :goal-list []})]
    (fn []
      [:> rn/View {:style {:margin 60}}
      [goal-input goals]
       [:> rn/View
        [:> rn/FlatList {:data  (:goal-list @goals)
                         :renderItem (fn [props]
                                       (let [item (:item (js->clj props :keywordize-keys true))]
                                         (r/as-element [goal-item item goals])))}]]])))
and then goal-item is:
(defn goal-item [item goals]
  [:> rn/TouchableOpacity {:on-press (fn [e] (swap! goals update :goal-list remove #(= item %)))}
   [:> rn/View {:style (.-listItem styles)}
    [:> rn/Text (str item)]]])
Im stuck figuring out writing the :on-press . it all renders fine but when i click on one of my items to call the :on-press i get Error: No protocol method ISwap.-swap! defined for type undefined:

aqua09:11:59

With my limited knowledge it seems like it should work! Maybe to debug, move the swap! statement to directly inside the let in goal-list, just to see if it works there... And if so move it deeper from there until you find the breaking point

sova-soars-the-sora22:11:39

Hi, i'm nRepl'ing to a live program of course 😄 and I'm wondering, can I change the :requires at the top of the file while running live? seems like it might need recompilation at that point :thinking_face:

FlavaDave22:11:05

so if you are using CIDER it is the C-c C-k

FlavaDave22:11:09

but if you are using anything else you need to find the equivalent of cider-load-buffer. it will likely have a similar name since a lot of alternative clojure IDE’s are build atop CIDER

sova-soars-the-sora22:11:25

so i'm cider-connecting to a remote repl ... modifying a function... but i also need to modify some includes (requires) at the top of the namespace ...

sova-soars-the-sora22:11:39

kinda complicated, it's a deployed jar

dpsutton22:11:33

have you tried it?

dpsutton22:11:16

conceptually there is no difference between running a repl locally and running a repl into your production jar. its all the same to Clojure

dpsutton22:11:15

and this is assuming the new reuired namespaces can be found in the jar. if its a new dependency you won’t have any luck

sova-soars-the-sora22:11:53

the dependency is in the jar, just not included in the very file yet

sova-soars-the-sora22:11:10

sounds like it will work, time to mess around 😄 ty

seancorfield23:11:42

@U3ES97LAC Yup, that will work. You can just update the ns form and then eval it into the REPL / live process and it will compile in just like any other form.

seancorfield23:11:47

I develop live against our legacy app like that all the time. I start it up and have it spawn a REPL for me to connect into, then I develop (the embedded Clojure part of it) just like any other Clojure app based on a REPL.

1
dpsutton23:11:41

your “production” app is the same as a dev setup with just a different main entry function. but nrepl and Clojure are all the same 🙂

dpsutton23:11:09

a super power of socket repls is how easy it makes it to repl into a “production” jar. love showing that off at work

😁 1
mortemeur23:11:05

If I wanted to create a website and wanted to make sure google saw it properly, should I use fulcro (which I know does awesome ssr) or can I use re-frame like I want to with some library?

sova-soars-the-sora00:11:53

I enjoy using Rum which has SSR provided your server-side components and client-side components are identical and you use rum/hydrate instead of /mount

drewverlee02:11:16

It doesn't matter to chrome.

drewverlee20:11:29

@U3ES97LAC help orient me, what does SEO care about in this context?

drewverlee20:11:41

I recall some discussion that some ways apps get bundled or built or deployed result in better SEO, but i can't recall anything about the topic, given its not something i think about a lot

sova-soars-the-sora22:11:36

Oh sure um My understanding is that google prefers sites that spit out HTML immediately so "server-side rendering" makes a site more searchable / indexable by search engines. If a site has to load the javascript asset and then render a dom, google says they index these pages, but I don't think they do. OR if they do, it's a very particular subset. I have not had luck with search engines indexing my Single-Page-Applications. Unless I introduce SSR (serverside-rendering), then when the crawler hits the endpoint it doesn't just get "<html w/ a .js file linked>" but it gets full HTML with text & stuff.

drewverlee23:11:09

Thanks for the explanation.