beginners 2021-03-26

anyone got experience with implementing https://en.wikipedia.org/wiki/Financial_Information_eXchange clients? are there resources in clj/java that can help one to get started?

is there any documentation that describes what the various metadata flags do? I realise it's extensible but I can't find anywhere that lists the "built-in" ones. specifically ^:redef

if the metadata controls the compiler, I'd expect it to show up in that file

Simple question here. I do this a lot: (if a a ...)

let [a (some-calc x y)
     a (if a a (some-alternative x y)]
But it dawns on me this is from my imperative mindset and not very lispy/functional. How do you deal with this?

(or a (some-alternative x y))

event better (or (some-calc x y) (some-alternative x y))

πŸ™Œ 2

This community rocks!! @delaguardo

what @delaguardo wrote. Using or is idiomatic.

Kirill Chernyshov 2021-03-26T11:23:25.075Z

or is a macro so it is safe to even have some sideeffects in some-alternative function

both and and or just return the last value (when true) since everything apart from nil and false is considered true in Clojure, so you will see a lot of succinct code that combines logic tests and nil punning in Clojure code.

πŸ™Œ 1

Hi there. What is the de facto way in Clojure to check if a string is an email address? Is regex matching my best option here?

There are a lot of resources that will tell you the best you can do is to determine if a string probably is an email address, and not necessarily a valid one.

You can google for some really hairy regexes that are intended to be a comprehensive match for any valid email address, but YMMV.

The site I'm working on now just has a simple regex that checks for "_@_._", and if it doesn't match, it just puts up a caption that says "Please be sure you are using a valid email address."

yeah I forgot how hairy email validation can become with regex

The only reliable way to check for valid email addresses is to send it an email with a link that has an embedded one-time token, and then see if they click the link.

☝️ 3

Alternately, there are online services that do mass-mailing that will offer you email validation services, which might be marginally better than a regex, if you don't mind paying.

I'm thinking like MailGun or MailChimp or something, but I don't remember which of them (if any) offers that service. I have seen it though.

This is for a personal project so I’ll just do some simply regex matching. Thanks a lot πŸ™‚

@rextruong first 8-9 minutes ofhttps://www.youtube.com/watch?v=9Q--oX5muxw covers email parsing with regexes

πŸ‘ 3

tl;dw "good luck" πŸ™‚

The phrase "exponentially diminishing returns" does come to mind πŸ™‚

There’s some java libraries like https://javaee.github.io/javamail/, but the simplest regex + sending an email is really best

I feel very stupid right now because this must be so basic and I can't figure it out... I want to create a function that wraps hiccup content

(defn wrap [content] ; content is a list of hiccup elements
  [:div {:id "Test"}
   ; insert content here, but not in a list, just all the individual elements
   [:div {:id "footer"} ...]
  ])
how do I do that? Or is that just the wrong approach?

You could use into effectively here.

you have a vector and a collection and want to return a vector of the concatenation. (into [:div {:id "footer"}] your-collection) is the most straightforward approach

I phrased it like this to point that the smallest reproduction of your issue doesn't have hiccup or divs or a function called wrap involved. often all these details mask the simple problem: (into [:a] [:b :c :d]) -> [:a :b :c :d]

hm ok I was hoping to be able to do something like in js where you can do

let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5, 6];
where arr2 would be [1, 2, 3, 4, 5, 6] then

there's no equivalent of the spread operator in clojure

okay thanks!

kind of interesting, I'd think that'd be a pretty cool thing to have

makes everything more succinct

you can post on http://ask.clojure.org . It's possible it's been brought up before. Possibly declined, possibly still open to it. Or perhaps no one has taken the time to ask about it

Alex Miller (Clojure team) 2021-03-26T17:04:40.104900Z

Don’t recall anyone asking for it

Alex Miller (Clojure team) 2021-03-26T17:05:10.106200Z

I mean, there’s concat, and cat transducer if you want vector

so my function would look like this:

(defn wrap [content] ; content is a list of hiccup elements
  (let [wrapper [:div {:id "test"}]
        footer  [
		          ; some more elements here
				]]
  (into (into wrapper content) footer)
it does what I want... idk it's just looking wrong somehow, like it could be much easier...

in JS I would've done

let wrap = (content) => [
   :div, {:id "test"},
   ...content,
   // footer elements
];
(I'm not comparing/complaining, I would've just hoped it was easier and hope there's a better way than what I do)

(reduce into wrapper [content footer])

or (into wrapper (concat content footer)) should work

(-> wrapper
    (into content)
    (into footer))
@azzurite This makes the flow more obvious, perhaps?

honestly idk why this wasn't obvious to any of us πŸ˜„

(concat wrapper content footer)

it needs to be a vector for hiccup

so you'd have to do (into [] (concat ...)) which is what i put above (into wrapper (concat content footer))

this is a great place to use cat - (into [] cat [...])

i always forget about cat

I see, yeah

thanks everyone

for some reason I like (vec (concat wrapper content footer)) best, just gets my intent across I feel

there's also (into [] cat [wrapper content footer])

does the same thing to the data, with less intermediate steps / lazy seqs

I still don't understand transducers and haven't found a good explanation... the official reference seems to assume too much of my intelligence πŸ˜„

my tl;dr is that they offer the same transformation steps as lazy seq operations, without needing a seq for input or output

this wouldn't matter if clojure was a "clever" compiler, but clojure is intentionally not one

sova-soars-the-sora 2021-03-26T18:41:05.110500Z

So let's say i've got a series of posts on a social-ish thing...

sova-soars-the-sora 2021-03-26T18:41:51.111300Z

and I want to have notifications for users... like if someone "reacts" to your post.

sova-soars-the-sora 2021-03-26T18:43:02.112600Z

i'm thinking: keep a "last-seen-notification" timestamp for each user, and then check it against the stored reactions... but i also want a way for users to mark certain notifications as seen... well i don't know if i want to go that fine-grain... but in general a way to see notifications for reactions. does it make sense to...

sova-soars-the-sora 2021-03-26T18:43:52.113400Z

mark notifications as "seen" ... or try and simply rely on latest-seen timestamp to do that difference?

sova-soars-the-sora 2021-03-26T18:44:22.114100Z

kinda a nebulous design-level question... but i'm a little unclear on doing the notifications bit so any words of help would be appreciated πŸ˜„

most notification systems are really bad, because when they were initially written the idea was "little ephemeral messages"

but no one actually wants that, what they want is basically "lightweight email"

meaning an inbox, where notifications persist, and you can mark them as read, and read old ones, etc

so I would try to ignore that you are implementing notifications, and instead look at imap, and the extensions to imap for push, for inspiration

sova-soars-the-sora 2021-03-26T19:25:45.120300Z

thank you

sova-soars-the-sora 2021-03-26T19:26:11.120900Z

that makes sense, "lightweight email." I am trying to keep a very reduced interface but a historical view on notifications is likely necessary.

sova-soars-the-sora 2021-03-26T19:35:47.121400Z

Do you reckon "mark as read/seen" and "Mark all as read/seen" would be sufficient with a boolean on each notif?

sova-soars-the-sora 2021-03-26T19:36:10.121700Z

hard-pressed to think of other use-cases.

if this is evaluated lazily, shouldn't i receive a false instead of an NPE?

(first (remove #(% nil) [int? zero?]))

calling first on (remove pred? coll) will realize every item in coll until one is truthy, so the error should be expected

you can replace zero? with (fnil zero? -1) (-1 was an arbitrary choice, plug in any non-zero)

or #(and (number? %) (zero? %))

thank you

to verify that chunkiness is the problem:

(defn dechunk [s]
  (lazy-seq
   (when-let [[x] (seq s)]
     (cons x (dechunk (rest s))))))

(first (remove #(% nil) (dechunk [int? zero?])))

I prefer creamy sequences over chunky, myself

i like the crunch of the chunk

you can also use transducers to avoid laziness if you prefer

personally I think laziness-by-default was a design mistake in Clojure

i have a user-supplied value that i need to apply a series of value checks to, defined in an external schema

schema as a vector that will provide a bottoms-up series of truthy tests to the value

was curious how to handle a nil

transducer version:

(into [] (comp (remove #(% nil)) (take 1)) [int? zero?])

you could also just use reduce

πŸ‘† 1

reduce will still need to be in transducer form, correct?

(reduce #(%2 1) [int? pos?]) => true
(reduce #(%2 1) [int? even?]) => false
(reduce #(%2 nil) [int? even?]) => NPE

or more appropriate non-transducer version:

(reduce #(conj %1 (%2 1)) [] [even? int?]) => [false true]

seems like you want short-circuiting, in which case you'd use and in the reduce to produce a single bool

yea. i think thats why i picked remove as the primary form. the first eval (int? even?) that returns false, i can take 1 and short circuit

but first calls seq, which is where your link on chunking comes into play

you can use reduced to short-circuit a reduce call: https://clojuredocs.org/clojure.core/reduced

thanks, darin. will check that out

in the case of transducers, do all of the comp params need to be transducable, too?

e.g. in the case of your example, you use (take 1) in it's transducer form

outside of a transducer context, i could use first. but it doesn't seem to want to apply here..

they all need to be transducers, yes. first doesn't have a transducer arity, I guess because take can do that already

(int? nil) => false
  (zero? nil) => NPE

sova-soars-the-sora 2021-03-27T00:14:10.128Z

that's curious.

chunking