beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
st3fan 2020-11-14T00:46:08.211600Z

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

2020-11-14T00:49:24.212200Z

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

2020-11-14T00:49:32.212500Z

that's the typical style guide answer at least

2020-11-14T00:49:58.212900Z

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

2020-11-14T00:51:19.213700Z

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

st3fan 2020-11-14T01:08:40.213900Z

Thanks those are good hints

st3fan 2020-11-14T01:23:18.214600Z

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

1
2020-11-14T05:58:22.216Z

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 🤯

hequ 2020-11-14T08:24:22.216600Z

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

hequ 2020-11-14T08:28:12.216700Z

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

hequ 2020-11-14T09:12:14.216900Z

Well I picked reitit and try to figure out that

Ben Sless 2020-11-14T09:38:32.217300Z

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

hequ 2020-11-14T09:46:03.217500Z

thanks! will check those as well

uosl 2020-11-14T11:57:32.219900Z

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 Newton 2020-11-14T12:50:05.222700Z

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 Newton 2020-11-14T12:56:14.224Z

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 Newton 2020-11-14T13:01:09.224500Z

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

gibi 2020-11-14T14:14:48.225700Z

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

gibi 2020-11-14T15:01:17.225900Z

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

st3fan 2020-11-14T17:20:48.227300Z

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

st3fan 2020-11-14T17:23:05.229200Z

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?

lispyclouds 2020-11-14T18:09:11.229800Z

maybe something based on java's LinkedBlockingQueue? https://gist.github.com/mjg123/1305115/72434dd5da89e5a83c91facb0b7687d6b7e66836

Louis Kottmann 2020-11-14T19:44:54.230700Z

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

2020-11-15T16:34:38.252400Z

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"

2020-11-15T16:35:03.252600Z

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

2020-11-15T16:35:13.252800Z

usually you want "UTF-8"

Ben Sless 2020-11-14T19:49:24.230800Z

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

Louis Kottmann 2020-11-14T20:18:42.231200Z

I guess, something I could slurp for example

Louis Kottmann 2020-11-14T20:29:24.231400Z

but yes, in memory

Ben Sless 2020-11-14T20:29:56.231600Z

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

Ben Sless 2020-11-14T20:30:11.231800Z

to which you can just .write normally

Ben Sless 2020-11-14T20:30:28.232Z

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

2020-11-14T20:48:21.233Z

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

2020-11-14T20:49:07.234100Z

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

Louis Kottmann 2020-11-14T20:50:07.234900Z

thanks, I managed to make it work

2020-11-14T20:50:24.235400Z

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

Louis Kottmann 2020-11-14T20:50:29.235600Z

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

2020-11-14T20:50:35.235900Z

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

Sergio 2020-11-14T20:55:47.236Z

Seems like a good case for a channel https://clojuredocs.org/clojure.core.async/chan

Sergio 2020-11-14T20:57:45.236200Z

assuming you only want to work on memory

borkdude 2020-11-14T22:24:17.236800Z

@leif so the file stops at 5?

borkdude 2020-11-14T22:25:31.237300Z

@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

borkdude 2020-11-14T22:26:52.238Z

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

borkdude 2020-11-14T22:45:34.238500Z

@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]

borkdude 2020-11-14T22:45:53.238900Z

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

borkdude 2020-11-14T22:46:11.239200Z

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

2020-11-14T22:47:15.239700Z

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

2020-11-14T22:49:10.240700Z

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?

borkdude 2020-11-14T22:49:19.240900Z

yeah

2020-11-14T22:52:00.241600Z

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?

2020-11-14T22:52:23.242300Z

(parse the exception string)

borkdude 2020-11-14T22:52:28.242500Z

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

2020-11-14T22:52:47.242800Z

Ahhhh, okay, that makes a lot more sense.

borkdude 2020-11-14T22:52:55.243200Z

This is the line where it throws that exception: https://github.com/borkdude/edamame/blob/9101156cdcf5ad7b287e160cc28145913bd14d78/src/edamame/impl/parser.cljc#L123

2020-11-14T22:52:55.243300Z

(I missed that)

2020-11-14T22:53:30.243900Z

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

borkdude 2020-11-14T22:53:36.244300Z

correct

2020-11-14T22:53:36.244400Z

(At least based on the .cljc extension

2020-11-14T22:53:42.244600Z

)

2020-11-14T22:53:55.244900Z

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

2020-11-14T22:53:59.245100Z

Thanks for the suggestion.

borkdude 2020-11-14T22:55:43.246200Z

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

borkdude 2020-11-14T22:56:00.246400Z

That + a unit test