Fork me on GitHub
#beginners
<
2021-03-15
>
sova-soars-the-sora01:03:16

I got a question a really cool question... how do I synchronize logins / authentication between two separate ring servers? They are hosted at the same IP but I suppose I could use something like webhooks(tm?) to send a CSRF-free POST to the other box when there's a successful login and have the other "box" set that person as logged in... ? Hmmm. What do you think friends?

aratare01:03:08

that’s prob what I would do too

1
fullNameHere01:03:08

Hey guys, How could this be improved? Signal-cone receives two parameters: 1. An array of numbers (all greater than 0) 2. An array of 3 arrays - each with 2 numbers (all greater than 0) We can only use a range in which the lowest & the highest number does not fall out of the range of either of the other ranges. So in this call it would be [9, 15] Once we have our range we need return which numbers fall within that range. So here it would be [9, 11, 15] (defn return-inner-ranges [ranges] (into [] (map (fn [x] (into [] (range (get-in x [0]) (inc (get-in x [1])))))) ranges)) (defn get-shortest-range [ranges] (let [chosen-range (first (sort (return-inner-ranges ranges)))] (vector (first chosen-range) (last chosen-range)))) (defn get-within-range [numbers range] (filter (fn [x] (and (>= x (get-in range [0])) (<= x (get-in range [1])))) numbers)) (defn signal-cone [numbers ranges] (get-within-range numbers (get-shortest-range ranges))) (signal-cone [3,4,7,8,9,11,15,18,23] [[10 20] [8 16] [9 15]]) Thanks in advance!!

sova-soars-the-sora01:03:32

@santosx99xx Could you give me another input and output example?

fullNameHere01:03:45

from what I understand, no more than 3 ranges are given. It would probably be like this [[5 6] [25 59] [2 77]]. [25 59] should get chosen. And it would return all numbers that fall inbetween those two

fullNameHere01:03:18

I guess only [59] would be returned.

sova-soars-the-sora01:03:07

let me know if i didn't understand the challenge, i'm under the impression it takes 2 inputs and produces one output set, right?

fullNameHere01:03:07

the first input being just numbers, the second being 3 ranges. Id have to choose the range that falls inbetween the other two. so given ranges [[8 78] [78 79] [1 5]] - [8 78] would get chosen. say you were given a vector of [0 1 2 3... 100] it would return [8 9 10 11... 78]

fullNameHere01:03:06

(signalCone [[8 78] [78 79] [1 5]] [0 1 2 3 4... 100]) -> [8 9 10 11... 78]

sova-soars-the-sora01:03:11

If I put in [23, 55] and [[5 6] [77 2] [25 59]] what comes out?

sova-soars-the-sora01:03:13

@santosx99xx please let me know if i'm way off. I think I get it. I want to check numbers in [stairway] to see if they fit in the range of each item in [gold silver bronze]. (check-if-medal-lives-in-stairway-range [stairway] [[gold] [silver] [bronze]]) So if [stairway] is 77,78,79,80 and [gold silver bronze] are [[8 78] [78 79] [1 5]] the result will be all the numbers of [stairway] that fit comfortable in [gold] or [silver] or [bronze] ... so here the output would be [77, 78, 79] from the inclusionary endcaps on [gold] and [silver]. I feel that with [gold silver bronze] it would be better to have a function that receives one [stairway] and one [medal] and returns the set that fits, endpoints included, from stairway into medal. And then I would call that function 3 consecutive times, once on gold, once on silver, and once on bronze, and throw them all into the same #{set} so only the uniques remain. How to check which numbers exist within a specific range? It's a cool question. I think you can call (range) on the endpoints in something like [gold] .. (range 0 5) to get [0 1 2 3 4] Then after you have the whole range splayed out, you can see which numbers exist in both [stairway] and [medal] and keep the overlapping ones. You can use (clojure.set/intersection ) and if the inputs have overlapping entries (entries in common) the result will be those.

fullNameHere01:03:05

Thanks, ill try that

sova-soars-the-sora19:03:23

did it work out =D?

fullNameHere21:03:13

I couldn't get it to work. But it wasnt that serious. It was posted in another slack channel, and it kinda peaked my interest for a bit. But I lost it.

sova-soars-the-sora22:03:32

Yeah I can dig that. Some programming challenges are fun. Do you enjoy coding interview questions?

fullNameHere23:03:32

I didn't know it was an interview question. It was posted in a js channel. I wrote my slightly different solution, then rewrote it in clojure. It was fun, but I haven't gone out of my way to do these types of challenges.

Audrius05:03:47

How to know what symbols can be used for vars and what not? Like , is ignored but . is a valid var name. What is the rule to know what is allowed?

Adie12:03:34

How to convert PersistenceList to vector in clojure?

sguessou13:03:16

Hello Antti 👍

Antti13:03:26

thanks, nice to be here

Singh14:03:51

Hello there, Is it possible to reassign atom with same value ? For example:

(def image (atom "Inital"))
(if (or (= (get-in data [:ParkCategoryId]) 1) (= (get-in data [:ParkCategoryId]) 5) (= (get-in park [:data]) 6) )
  (reset! image image)
  )
I tried doing this but getting error

vanelsas14:03:40

(reset! image image) -> (reset! image @image)?

🙌 1
dpsutton14:03:45

(swap! image identity) will keep the same value. you need to reset it to a value. image is an atom. (reset! image @image) is a way to do this. but what purpose do you want to achieve by setting something to its same value?

🙌 2
dpsutton14:03:32

are you triggering a watch?

Singh15:03:48

I am working on a function that is responsible for image icon In js I have as following

let image = 'inital';
   if (data.Available && data.AvailableFiltered)
        image = "AvailableNotCriteria";


    if (data.ParkCategoryId == 1 || data.ParkCategoryId == 5 || data.ParkCategoryId == 6)
        image = image;
    else if (data.ParkCategoryId == 2)
        image = "B_" + image;

This is in Js but this is what I am trying to do

Singh15:03:33

(if (or (= (get-in data [:ParkCategoryId]) 1) (= (get-in data [:ParkCategoryId]) 5) (= (get-in data [:ParkCategoryId]) 6) )
  (reset! image @image)
Is this the right way of doing it @U11BV7MTK , I am not to sure as I am new to clojure?

dpsutton15:03:12

yes, but again, it does nothing

dpsutton15:03:17

just don't do that

Mark Wardle15:03:48

Hi all. Are there some rules about fully qualified classes when using metadata? I get a

Syntax error (ClassNotFoundException) compiling deftype* at (com/eldrix/clods/fhir_r4.clj:49:1).
java.lang.Organization
error when using a metadata tag in definterface or deftype that is not fully qualified. So this works:
(deftype OrganizationResourceProvider [^ODS ods]
  IResourceProvider
  (getResourceType [_this] Organization)
  OrganizationGetResourceById
  (^{:tag org.hl7.fhir.r4.model.Organization
     Read true}                                            
    getResourceById [_this ^{:tag    org.hl7.fhir.r4.model.IdType
                            IdParam true} id]
This doesn’t:
(deftype OrganizationResourceProvider [^ODS ods]
  IResourceProvider
  (getResourceType [_this] Organization)
  OrganizationGetResourceById
  (^{:tag Organization
     Read true}                                            
    getResourceById [_this ^{:tag    org.hl7.fhir.r4.model.IdType
                            IdParam true} id]
Even though I have
(:import (ca.uhn.fhir.rest.server RestfulServer IResourceProvider)
         (ca.uhn.fhir.context FhirContext)
         (org.hl7.fhir.r4.model Organization IdType Address Identifier)
         (ca.uhn.fhir.rest.annotation Read IdParam))
in my namespace (ns) declaration. Shortened references seem to work in defn etc..

simongray15:03:40

@mark354 try (with-meta …) rather than ^{} for those cases where you are experiencing issues

simongray15:03:50

The ^{} shorthand is a reader macro so it occurs at read time, which means your Java classes have not been imported yet: https://clojure.org/reference/metadata#_metadata_reader_macros that is my guess anyway

Mark Wardle15:03:27

I think you’re right; the issue seems to affect only the metadata within definterface and deftype that are declaring the structure of the eventual java classes - the metadata within the forms making up runtime expressions can be short-form. I might just leave it as fully qualified class names but thanks for the with-meta pointer.

Mark Wardle15:03:04

Just got to ignore the advice of the IDE to shorten an already imported reference!

Michael Stokley17:03:36

i have a function i'm importing from a shared lib, and that function is throwing. the stack trace refers to line numbers and namespaces from the required lib, but not the namespace that requires it - not the namespace that actually invokes the required function. is there anything i can do about this to improve the stack trace?

hiredman17:03:33

the stacktrace while show everything that is on the stack when the exception is thrown

hiredman17:03:35

if it doesn't show your calling code it either isn't on the stack (because the called code is being run in another thread) or some tool you are using is eliding it when printing/presenting the stacktrace to you

hiredman17:03:30

so a first thing to do is to just enter *e in the repl after you get the exception (assuming the exception is thrown the context of evaluating an expression at the repl)

hiredman17:03:07

that should (but not always) get you the default clojure printing of the last exception throw in the repl, which should be complete

Michael Stokley17:03:24

> code it either isn't on the stack (because the called code is being run in another thread) i suppose with pedestal, it's on another thread

Michael Stokley17:03:53

i don't have access to *e because the error is being automatically caught and logged for me

hiredman17:03:01

if it is on another thread the information just isn't there

hiredman17:03:11

the stacktrace in an exception is literally a trace of the call stack as methods are called on the jvm, and each thread has its own call stack

Michael Stokley18:03:38

realizing the lazyseq returned by my function dramatically changes the stack trace for the better

Michael Stokley18:03:20

perhaps that means my original problem was the second explanation - that my tool/framework is eliding the trace

hiredman19:03:58

ah, well, lazy-seqs can behave similar to threads

hiredman19:03:25

well, not like threads

hiredman19:03:46

a lazy-seq suspends a computation to be completed at some other time

hiredman19:03:12

and the stack may be different between when it is suspended and when it is completed

Eric Casteleijn20:03:28

I have a question about lazy vs. non-lazy sequences and converting between the two. Here’s an interpreter session that’s illustrates my confusion:

(defn prnr [a] (prn a) a)
=> #'grdn.core/prnr

(->> [1 2 3 4]
     (map prnr)
     (take 1))
1
2
3
4
=> (1)
(->> (seq '(1 2 3 4))
     (map prnr)
     (take 1))
1
=> (1)
(->> (seq [1 2 3 4])
     (map prnr)
     (take 1))
1
2
3
4
=> (1)

blak3mill3r20:03:16

@thisfred you are calling a side-effecting function prnr inside your map over a sequence

Eric Casteleijn20:03:23

so if I pass a vector, map is not lazily evaluated, if I pass a seq literal it is, but if I convert a vector to a seq it once again isn’t.

Eric Casteleijn20:03:35

that’s the point

blak3mill3r20:03:38

and so you are seeing some of the implementation details of clojure sequences

blak3mill3r20:03:44

namely, that they are realized in chunks of 32

blak3mill3r20:03:50

this is done for efficiency

blak3mill3r20:03:09

if you instead do something like this, you'll see results that make sense, I suspect

🙏 1
blak3mill3r20:03:32

(doseq [a (take 1 [1 2 3])] (prnr a))

blak3mill3r20:03:02

the thing is that when you call map you are getting a new sequence, and it will be realized in chunks of 32, for efficiency

Eric Casteleijn20:03:05

thank you so much, I’ll read up on doseq

blak3mill3r20:03:25

that means that even though you end up discarding most of it (with take) your function that you pass to map still gets called for more elements of the seq

blak3mill3r20:03:28

you're welcome!

Eric Casteleijn20:03:37

that makes sense I guess, though I wish the documentation wouldn’t say map was lazy, in that case 😉

noisesmith00:03:44

laziness is not a promise that as few as possible elements are realized, it's the possibility that fewer than the total number are realized

noisesmith00:03:20

if your program logic depends on realizing only N items, either use take before map, or don't use laziness - laziness and side effects mix poorly in general

blak3mill3r20:03:53

You're not the first person to be confused by this

blak3mill3r20:03:07

however it does speed things up for clojure's lazy sequences

blak3mill3r20:03:13

Perhaps the docs could be improved

Eric Casteleijn20:03:17

(I know, side effects should probably be relegated outside of threading macros)

Eric Casteleijn20:03:36

Anyway, really helpful!

dpsutton20:03:55

compare with

(->> (seq (vec (range 99)))
     (map prnr)
     (take 1))

Eric Casteleijn20:03:14

Ooh, yeah, thanks, that demonstrates it beautifully

dpsutton20:03:57

so its still lazy, but they never give you (in the contract) the degree of laziness so to speak. and don't assume you know what it is, or rely on that for side effects or to prevent heavy computation

👍 2
andy.fingerhut20:03:51

It is lazy, but it is not strictly lazy :-)

😂 4
dpsutton20:03:02

another common gotcha that you might misinterpret at smaller repl-test-sizes is that maps might appear to be ordered (keys {1 1 2 2 3 3}) is (1 2 3) but they are not ordered. just a quirk of small sized maps using an optimization

Eric Casteleijn20:03:56

gotcha, thanks! I wasn’t expecting them to be, because of prior Python experience (although they since made the ordering stable there.)

Eric Casteleijn21:03:26

The actual use case we have is we want to return the first non-nil result of an expensive calculation mapped over a vector. My colleague just pointed out that this works instead of using map + first or (take 1):

(->> vector
     (some expensive-calculation))

Eric Casteleijn21:03:56

(just in case someone stumbles upon this in the future with that exact need 😉

andy.fingerhut21:03:45

That works, but the fact that the input is a vector means that it has already been fully realized. If every element is (or might be) expensive to calculate, and you don't need any after the first non-nil to be calculated, then that will cost more than a more lazy solution.

Eric Casteleijn21:03:19

Yeah, in this case the input is fully realized (passed in from the frontend)

andy.fingerhut21:03:21

Oh, sorry, I misunderstood your statement. Thinking more on the actual issue.

dpsutton21:03:26

if you want to control expensive evaluation using map and first is a poor way to get there. (loop [[x & xs] the-seq (when x (if-let [transformed (f x)] transformed (recur xs)))

👍 1
Eric Casteleijn21:03:15

(some f vector) is neat though