Fork me on GitHub

anyone got experience with implementing clients? are there resources in clj/java that can help one to get started?

Tim Robinson10:03:35

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))

🙌 6

This community rocks!! @U04V4KLKC


what @U04V4KLKC wrote. Using or is idiomatic.


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


Thanks a lot !! (and @U4P4NREBY @U04V4KLKC )


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.

🙌 3

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.

☝️ 9

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 of covers email parsing with regexes

👍 9

tl;dw "good luck" 🙂


The phrase "exponentially diminishing returns" does come to mind 🙂

Elliot Stern13:03:26

There’s some java libraries like, 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 . 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)17:03:40

Don’t recall anyone asking for it

Alex Miller (Clojure team)17:03:10

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"},
   // 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


That works too.


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


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


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...


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


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


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


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


hard-pressed to think of other use-cases.

Franco Gasperino23:03:07

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

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

Michael Gardner00:03:00

to verify that chunkiness is the problem:

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

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

Michael Gardner00:03:40

I prefer creamy sequences over chunky, myself

Franco Gasperino00:03:00

i like the crunch of the chunk

Michael Gardner00:03:22

you can also use transducers to avoid laziness if you prefer

Michael Gardner00:03:41

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

Franco Gasperino00:03:46

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

Franco Gasperino00:03:14

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

Franco Gasperino00:03:31

was curious how to handle a nil

Michael Gardner00:03:32

transducer version:

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

Michael Gardner00:03:52

you could also just use reduce

👆 3
Franco Gasperino00:03:28

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

Franco Gasperino00:03:00

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

Franco Gasperino00:03:10

or more appropriate non-transducer version:

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

Michael Gardner00:03:00

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

Franco Gasperino00:03:54

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

Franco Gasperino00:03:16

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

Darin Douglass00:03:51

you can use reduced to short-circuit a reduce call:

Franco Gasperino00:03:32

thanks, darin. will check that out

Franco Gasperino00:03:03

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

Franco Gasperino00:03:22

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

Franco Gasperino00:03:41

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

Michael Gardner00:03:01

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


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? %))

Franco Gasperino23:03:18

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