Fork me on GitHub
#beginners
<
2020-11-14
>
st3fan00:11:08

Is there some convention for constant naming? BOT-NAME ? or maybe +bot-name+ ?

noisesmith00:11:24

all top level definitions should be constant / immutable, so having a "constant" isn't useful

noisesmith00:11:32

that's the typical style guide answer at least

noisesmith00:11:58

if anything we use names like *bot-name* for things that aren't constant

noisesmith00:11:19

I've seen +bot-name+ used by people who came from common lisp, but it's not a clojure idiom

st3fan01:11:40

Thanks those are good hints

st3fan01:11:18

I reached a major milestone .. my bot worked for the first time 🙂

upside_down_parrot 3
Thomas Tay05:11:22

Ngl the juxt function is pretty cool I read a blog post that used it in conjunction with sort-by, and it totally blew my mind as a beginner 🤯

hequ08:11:22

Any suggestions for stack (or even some template) if I'd like to start a new API project?

hequ08:11:12

should I just pick compojure? Or maybe reitit which is mentioned in compojure github page?

hequ09:11:14

Well I picked reitit and try to figure out that

Ben Sless09:11:32

The complete stack would be reitit, jsonista, muuntaja and malli

hequ09:11:03

thanks! will check those as well

herald11:11:32

Back to the topic of naming, is there a specific reason why style guides don't advocate naming reference types differently? Just adding a * to atoms seem very useful to me, so you don't have to backtrack their bindings to verify whether they've been deref'ed at a previous point (especially when passed across multiple functions).

Jim Newton12:11:05

I'm trying to implement parts of the clojure.reflect/type-reflect function in a Scala program, to do similar (but more limited) kinds of class reflection. I see that from a Class there is a method isInterface() which gives me the :flags :interface part. Does anyone know how the refl/type-reflect function figure out if the class is :public, :final, or :abstract. I don't see that in the code. Maybe it's hidden in a java function.

Jim Newton12:11:14

it looks like there is an integer (Long?) called the access bits. And I can and that integer with certain bit-masks to determine such information. But I don't see how to get the access bits integer.

(def ^{:doc "The Java access bitflags, along with their friendly names and
the kinds of objects to which they can apply."}
  flag-descriptors
  (vec
   (map access-flag
        [[:public 0x0001 :class :field :method]
         [:private 0x002 :class :field :method]
         [:protected 0x0004  :class :field :method]
         [:static 0x0008  :field :method]
         [:final 0x0010  :class :field :method]
         ;; :super is ancient history and is unfindable (?) by
         ;; reflection. skip it
         #_[:super 0x0020  :class]        
         [:synchronized 0x0020  :method]
         [:volatile 0x0040  :field]
         [:bridge 0x0040  :method]
         [:varargs 0x0080  :method]
         [:transient 0x0080  :field]
         [:native 0x0100  :method]
         [:interface 0x0200  :class]
         [:abstract 0x0400  :class :method]
         [:strict 0x0800  :method]
         [:synthetic 0x1000  :class :field :method]
         [:annotation 0x2000  :class]
         [:enum 0x4000  :class :field :inner]])))

Jim Newton13:11:09

I think I found it. looks like class.getModifiers() gives me the integer.

Fra14:11:48

for some reason lein cljsbuild once compiles the code in core.js but not in main.js as I specified in project.clj .

cljs/core.js:3359: ERROR - Parse error. primary expression expected

Fra15:11:17

I had to downgrade from versions

:dependencies [[org.clojure/clojure "1.10.0"]
                 [org.clojure/clojurescript "1.9.521"]
                 [compojure "1.6.1"]
                 [ring/ring-defaults "0.3.2"]
                 [ring/ring-json "0.5.0"]]
to versions
:dependencies [[org.clojure/clojure "1.6.0"]
                 [org.clojure/clojurescript "0.0-2371"]
                 [compojure "1.3.1"]
                 [ring/ring-defaults "0.1.2"]
                 [ring/ring-json "0.3.1"]]
to make it work

st3fan17:11:48

Now using clojure.core.cache.wrapped to cache OAuth access tokens ..

(defn cached-authenticate [app event]
  (let [cache-key [(:name app) (get-in event [:installation :id])]]
    (cache/lookup-or-miss
     installation-access-token-cache cache-key
     (fn [_] (authenticate app event)))))

st3fan17:11:05

Can anyone recommend something that would allow me to delay incoming messages? I’m working with a webhook, but I do not immediately want to process those messages. Ideally I queue them and process them N seconds later. In the Go version of this GitHub app I am putting them in Redis queue and then poll them … I guess I could do the same, but maybe there is something simpler that doesn’t need an external store?

Sergio20:11:45

assuming you only want to work on memory

Louis Kottmann19:11:54

how can I treat a string as a file without writing it out? my google-fu failed me..

Ben Sless19:11:24

You mean writing to a Writable object in memory and not to disk?

Louis Kottmann20:11:42

I guess, something I could slurp for example

Louis Kottmann20:11:24

but yes, in memory

Ben Sless20:11:56

You need to create something like a ByteArrayOutputStream then wrap it in a writer

Ben Sless20:11:11

to which you can just .write normally

Ben Sless20:11:28

then just call str on the output stream to get the string

Louis Kottmann20:11:07

thanks, I managed to make it work

Louis Kottmann20:11:29

with (io/input-stream (.getBytes "text"))

st3fan01:11:45

Oh nice that is like Python’s StringIO

noisesmith16:11:38

if you need text rather than binary IO, stringreader is simpler

(cmd)user=> (java.io.StringReader. "Hello")
#object[java.io.StringReader 0x7a34b7b8 "java.io.StringReader@7a34b7b8"]
(ins)user=> (slurp *1)
"Hello"

noisesmith16:11:03

if you need binary io, add the extra arg to getBytes that specifies the encoding

noisesmith16:11:13

usually you want "UTF-8"

leif20:11:21

Is there a variant of clojure's read that will match parens for a partial read?

leif20:11:07

Basically, if I have the file:

(let [x 5
I'd like it to still be able to read the text so far, so it'd read to something like:
(let [x 5])

leif20:11:24

If, for example, clojurescript used only parens, I could just keep adding parens to the end until it successfully read, but since it doesn't, that wouldn't really work. (Or rather, it'd be much slower...)

leif20:11:35

(Because I'd have to permute all types of parens)

borkdude22:11:17

@leif so the file stops at 5?

borkdude22:11:31

@leif clj-kondo will give you this output:

$ echo "(let [x 5" > partial.clj
$ clj-kondo --lint partial.clj
partial.clj:1:6: error: Found an opening [ with no matching ]
partial.clj:2:1: error: Expected a ] to match [ from line 1

borkdude22:11:52

Potentially you could use that output to gradually fix the expression and then read it using a normal parser

borkdude22:11:34

@leif edamame (my Clojure parser) also has something similar:

user=> (require '[edamame.core :as e])
nil
user=> (e/parse-string "(+ 1 2 3")
Execution error (ExceptionInfo) at edamame.impl.parser/throw-reader (parser.cljc:92).
EOF while reading, expected ) to match ( at [1,1]

borkdude22:11:53

you could parse the exception, append the expected thing and try again

borkdude22:11:11

possibly we could also add the expected thing to the exception data

leif22:11:15

@borkdude Yup, as if the file stopped at 5.

leif22:11:10

So it looks like I'll have to catch the exception, try to parse the exception to get the correct ), ], or }, and then append that to the stream, and try again?

leif22:11:00

Would it be possible for edamame.core to attach some sort of data to the exception so that I wouldn't have to parse a string?

leif22:11:23

(parse the exception string)

borkdude22:11:28

That's what I suggested: > possibly we could also add the expected thing to the exception data It doesn't do that currently, but a PR for that is welcome

leif22:11:47

Ahhhh, okay, that makes a lot more sense.

leif22:11:55

(I missed that)

leif22:11:30

Oh cool, and it looks like this works with clojure and clojurescript, ya?

leif22:11:36

(At least based on the .cljc extension

leif22:11:55

Okay cool. I'll put together a PR later today.

leif22:11:59

Thanks for the suggestion.

borkdude22:11:43

@leif so throw-reader also can receive an optional data argument. So we could fill in {:edamame/expected-delimiter ...} there and that'll fix it.

borkdude22:11:00

That + a unit test