Fork me on GitHub
#clojure
<
2021-07-02
>
hiredman00:07:38

json doesn't have a date type, so how is a json decoder supposed to know which string fields to treat as special dates?

nikolavojicic00:07:37

If you could provide value transformer function somehow... (fn [x] (if (inst-str? x) (Instant/parse x) x)) I'll probably use clojure.walk on decoded edn value

ikitommi00:07:37

you could use Jackson API directly:

(.readValue j/default-object-mapper (j/write-value-as-string (java.util.Date. 0)) java.util.Date)
; => #inst"1970-01-01T00:00:00.000-00:00"

👍 4
ikitommi00:07:04

… or describe your data with a schema/spec and derive the transformation using it. with #malli:

(require '[malli.core :as m])
(require '[malli.transform :as mt])

(def User
  [:map
   [:name string?]
   [:created inst?]
   [:tags [:set keyword?]]])

(def json->user (m/decoder User (mt/json-transformer)))

(def user
  {:name "liisa",
   :created #inst"2021-01-01T00:00:00.000-00:00"
   :tags #{:clj :cljs}})

(-> user
    (j/write-value-as-string)
    (j/read-value j/keyword-keys-object-mapper)
    (json->user)
    (= user))
; => true

ikitommi00:07:09

it’s also much faster than a generic walk over the data.

Mark McWiggins05:07:03

Has anybody heard of Android development being done with Clojure? Just wondered ..

seancorfield05:07:01

I think there have been several attempts over the years but I think Clojure's dynamic nature and startup time have made it difficult. I think this is the most recently-maintained effort https://github.com/clojure-android/neko ?

seancorfield05:07:08

I think people mostly go down the ClojureScript path and target React Native under the hood?

mpenet06:07:32

soon enough we would have clojuredart (people are working on it)

mpenet06:07:32

that would allow us to use flutter

borkdude08:07:21

this article gives a pretty good insight in the boot time issues on Android: https://blog.ndk.io/solving-clojure-boot-time.html

borkdude08:07:24

There are some attempts to leverage GraalVM on mobile. There is a #graalvm-mobile channel.

Jakub Šťastný14:07:40

@U04V15CAJ when you say on mobile, do you mean on mobile in general or would that rather be just Android (plus potentially some minor players that I might be unaware of)? I mean I cannot imagine Apple would allow different runtime for iOS.

borkdude14:07:11

Potentially both

mpenet14:07:43

you can run native code

mpenet14:07:56

I guess it would work with graal

mpenet14:07:00

since it works with flutter

borkdude14:07:05

yes, that's what's happening in #graalvm-mobile

borkdude14:07:11

shared lib compiled with graalvm

borkdude14:07:27

UI using whatever the framework du jour is

Jakub Šťastný15:07:34

@U04V15CAJ I wasn't aware of that. I never wrote an iOS app, although lately I got interested in the subject. I will join #graalvm-mobile then and see what's up! Would you have any pointers about using CJ/GraalVM for writing iOS app specifically, I'm all ears!

borkdude15:07:15

There's not a lot of experience with this yet, but people in that channel are experimenting

deas10:07:46

Building a microservice for kubernetes. Where should I be starting so basic things are properly plumbed. Logging, signal handling, request handlers etc?

kongeor12:07:04

I'm poking with futures, in this example:

(comment
  (def f3 (future (do (Thread/sleep 5000) 1)))
  (deref f3 3000 :timeout))
I'm getting :timeout as I would expect. But in this one, I don't:
(comment
  (def f2 (future
            (for [x (range 5)]
              (do
                (Thread/sleep 1000)
                x))))
  (deref f2 3000 :timeout))
here, I'm getting => (0 1 2 3 4). Why I'm not getting :timeout in this case?

p-himik12:07:00

for is lazy.

kongeor12:07:37

ah, right! thanks! Wrapping in doall does the trick.

restenb12:07:48

i need some inspiration. i have a bunch of validation to do involving Java classes that can throw, and I would like to both preserve any error message, and still have my is-thing-valid?functions return truthy/nil.

restenb12:07:49

the "obvious" solution is perhaps to lift the return of is-thing-valid? into a map like {:valid-thing? false :message "An error has ..."}

Joshua Suskalo12:07:04

Hey @alexmiller I just saw your talk with ClojureD about tools.build, and it looks really good! I do have one question about it: are there any plans to be able to include source dependencies and "prepare" them by enabling or disabling aliases? I saw there was some way to run an alias to do like a build step, but in one of my projects I have different native dependencies which need to be included based on the platform, and I'd like to be able to provide those by specifying aliases with the dependency.

Alex Miller (Clojure team)14:07:07

you mean aliases that vary depending on the project using it?

Joshua Suskalo14:07:42

Yes, specifically I have a game engine that depends on native libraries. I'd like to be able to write an application that depends on the game engine and tells it which dependency set to include based on an alias in the dependent application.

Joshua Suskalo14:07:59

The way I have this working now is that the game engine has two aliases, :windows, and :linux, and these two aliases include native dependency jars. I'd like to be able to say io.github.IGJoshua/s-expresso {:git/tag "v1.0.0" :deps/aliases [:windows]} or something to be able to "enable" those dependencies.

Joshua Suskalo14:07:49

And I want to know if there are plans to enable something like this within tools.build or new releases of tools.deps. It seems like it'd be within the scope, but I don't know if it's a direction you're intending to go.

Alex Miller (Clojure team)14:07:40

this is a bit beyond what will be provided initially - the alias to use for prepping is fixed, so either you would need two wrapper projects that did the right thing, or a prep program that knew based on some other information (presence of something on the classpath, env var, etc) what to do

Joshua Suskalo14:07:37

I see. That'd mean for now it'd be easier to just include a snippet to tell the user to include in their deps.

jumar12:07:33

I'm trying to wrap slingshot's try+/catch in a macro and it doesn't work for some reason. If I just call macroexpand-1 and capture and eval its output it works fine. But trying to eval it directly produces an error my.ns/_e - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-special-binding What am I doing wrong?

(defmacro test-it [name options params & body]
  `(defn ~name ~params
     (try+
      (println "Test it")
      [email protected]
      (catch map? _e (throw (RuntimeException. "error" (:throwable &throw-context)))))))

;; this throws an error:
;; my.ns/_e - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-special-binding
(test-it my-test {} [x y]
         (/ x y))

;; this can be evaluated without problems
(defn my-test [x y]
  (try+
    (println "Test it")
    (/ x y)
    (catch
        map?
        _e
      (throw
       (java.lang.RuntimeException.
        "error"
        (:throwable &throw-context))))))

Joshua Suskalo12:07:25

Your problem is that _e is being expanded to a qualified symbol.

Joshua Suskalo12:07:00

If you want a symbol that's local to that part of the code and can't be referenced by users of the macro, you should append # to the end of the symbol name, which will turn it into an auto-gensym.

Joshua Suskalo12:07:11

This is because you're quoting the form with `

Joshua Suskalo12:07:48

If you want a symbol with a specific name (maybe to allow users to reference it), you'd need to do it like so: ~'_e

jumar12:07:25

Got it: I For this one, using ~_e` and ~'&throwable works. Now I need to find out the reason for another issue I have when I wrap it with a hystrix's defcommand function O:-)

Joshua Suskalo12:07:52

If _e isn't supposed to be used, then prefer _e#

4
jumar12:07:41

Yes, that's a good idea!

Joshua Suskalo12:07:22

This is so that if you change the macro and allow user code inside the block where that's bound, it won't shadow any bindings made by the user.

restenb13:07:16

from the ex-datadoc: Returns exception data (a map) if ex is an IExceptionInfo. Otherwise returns nil.

restenb13:07:02

in what cases would it be nil? would it be nil for any typical java exception, which doesn't implement IExceptionInfo?

restenb13:07:37

could or should it be used to separate unexpected crash-type errors from other types of errors?

p-himik13:07:43

> would it be nil for any typical java exception, which doesn't implement `IExceptionInfo`? Yes. Or any subtype of IExceptionInfo that allows nil to be used for additional data (`clojure.lang.ExceptionInfo` does not allow that). With that being said, the answer to your last question depends on what "expected" means. If you rely on some specific field in ex-data, then perhaps. But if you just want to check for IExceptionInfo, then use instance?.

restenb13:07:58

it comes up in handling HTTP responses since f.ex. clj-httpstuffs the error response in there. but should it be some unexpected crash while handling the request it's nil, and I have to handle that and return a 500myself.

practicalli-john14:07:56

I am interested in understanding what the community and Clojure core team do to track and manage potential security issues with Clojure core and Clojure libraries. Are there any particular tools and other resources that are helpful? I appreciate that libraries can be kept up to date with lein ancient or clojure -M:outdated . Is there any recommended ways of tracking issues that are discovered / reported? I see that there is the Open Web Application Security Project https://owasp.org/ for general info and tracking I'm really just looking to have a better understanding of security around Clojure, the libraries I use and the applications I build. Thank you.

vemv14:07:09

lein-nvd has worked pretty well for me over the last couple years :) recently I contributed to it a new mode when using Lein as it can be subject to some problematic ambiguities. default deps.edn usage is less prone (but not free) of them it's all reflected in the README

practicalli-john07:07:49

Ah, it has a Clojure CLI alias too, I'll add that to the practicali/clojure-deps-edn project. Thanks, this is a very useful starting point.

👍 2
🙂 2
matheusashton14:07:52

hello! I have a kinda stupid question, I'm trying to use honeysql an it's helopers, I required them with [honeysql.helpers :as sql] and called like (sql/select ...)

matheusashton14:07:39

but when I tried to use (sql/select-distinct-on ..) it was crashing saying that this function does not exist in the package

matheusashton14:07:04

so I went to the documentation and saw that the package was actually honeysql.sql.helpers

matheusashton14:07:29

tried to require that way, but now I'm getting Could not locate honeysql/sql/helpers__init.class, honeysql/sql/helpers.clj or honeysql/sql/helpers.cljc on classpath.

matheusashton14:07:40

what am I doing wrong?

vemv14:07:55

check out how the ns is actually called, you got a small typo there https://github.com/seancorfield/honeysql/blob/develop/src/honey/sql/helpers.cljc

matheusashton15:07:28

oh, there was a major version bump, I just saw it now due to your comment, that may be it, thanks!

seancorfield17:07:19

@matheusashton The 2.0 version uses different namespaces (and different coordinates) so that people can use both versions side-by-side which makes it easier to migrate piecemeal from 1.0 to 2.0.

matheusashton17:07:46

yep, I've just noticed, thanks

borkdude14:07:21

@matheusashton There's also a #honeysql channel where you can ask questions about it

matheusashton15:07:03

oh sorry, didn't know, I'll ask there

borkdude16:07:43

no worries, you can ask here too, but the honeysql-knowledge is more concentrated there ;)

vemv20:07:45

random thought, but it would be so nice if java.util.concurrent.ExecutionException told you the id of the thread that threw the exception (e.g. from a (future)) would speed up some debugging

borkdude20:07:36

yes, lots of exceptions are like that: this is wrong, type x. yes, but perhaps tell me the concrete x?

vemv20:07:22

oh yes I'm happy this has improved with spec and related libs

ghadi20:07:22

j.u.c.EE always wraps another exception, which should point to context pretty well

vemv20:07:11

it points to the context in terms of a stacktrace N threads can share a very similar (or even identical?) stacktrace. Then thread id would make all the difference (assuming intentful naming of threads)

ghadi20:07:14

better to catch -> annotate -> rethrow

ghadi20:07:55

thread ID is one of infinitely many different things that can enrich an error context

👍 3
vemv20:07:38

good call, I should just make a wrapper if I'm so inclined :)