beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
valerauko 2020-11-06T02:53:36.267500Z

I'm trying to figure out if the variation I see is because of GC or thread competition. Is there a way to see what calls get "paused" for GC?

2020-11-06T03:32:36.267700Z

Depending upon which GC algorithm you are using, it might be no calls, e.g. some GCs run in separate threads, without pausing any of your computation threads.

valerauko 2020-11-06T05:13:19.268100Z

makes sense. I'll read more on the subject!

Jim Newton 2020-11-06T08:03:05.269500Z

what is a non-sequence called in Clojure? In traditional lisps, non-lists are called atoms. But Clojure uses the word atom for something else.

2020-11-06T08:29:21.269600Z

Don't think there's a general name for that. At least never heard of one.

2020-11-06T08:30:52.269900Z

I normally just call things as they are: list, vector, map, set, symbol, keyword, number, string, etc.

Ben Sless 2020-11-06T08:40:14.270100Z

I think no one will be offended if you refer to it as a scalar

❀️ 2
Daniel Stephens 2020-11-06T09:39:11.270900Z

As far as I can tell, side effects are okay in reduce? Is that correct?

practicalli-john 2020-11-07T08:05:54.313Z

Sounds complex...

Daniel Stephens 2020-11-08T17:56:37.351500Z

I guess it kind of is, it is a bit of a unique case. it's a function that traverses a ktable within an open connection, sometimes it makes sense just to do something side effecting, i.e. for each value push a new message to kafka. In a few cases where we know the table is small I want to just get all the results into a seq to do something else with. reduce lets me either build a seq from each value, or do something side effecting and then throw the value away. I can't let things be too lazy as the connection might close before things are realised. I have actually hidden that behind two functions, one which just gets all values, and another which only allows side effects on each row, but since the underlying stuff is some funky java interop I only wanted to write the general version once.

Ben Sless 2020-11-06T09:55:30.271400Z

Yes, reduce is strict

Daniel Stephens 2020-11-06T09:55:49.271600Z

thanks!

πŸ‘ 1
Ben Sless 2020-11-06T09:57:54.271900Z

Take a look at run! for example. It is implemented with reduce

πŸ™ 1
Jim Newton 2020-11-06T10:21:19.272200Z

scalar? that's a pretty good name actually

Jim Newton 2020-11-06T11:45:24.274900Z

can someone remind me the idiom to use with try/`catch` to catch the exception if a condition, else don't catch it, or perhaps rethrow it? I was looking for an example in the https://clojuredocs.org/clojure.core/try and https://clojuredocs.org/clojure.core/catch, but I didn't see any.

Jim Newton 2020-11-06T11:46:46.275500Z

should I simply call throw on the given exception? will that destroy the stack trace?

2020-11-06T11:54:11.275700Z

Yes, calling throw on the given exception should do what you want. And it shouldn't destroy the stack trace. Also before throwing you have full access to the given exception meaning you can build new exception based on the stack trace from the one given

Jim Newton 2020-11-06T12:35:19.275900Z

I don't need it now, but if I test the exception object and decide to rethrow it, is it still subject to the other (catch ...) clauses in the same (try ...)? That could be good or that could be bad depending on the situation. It would be excellent if that were specified behavior.

Daniel Stephens 2020-11-06T12:43:24.277600Z

Am I missing a clojure.core fn to get the dispatch val of a multi-method given some input, I thought it would go hand in hand with get-method but I can't see anything obvious. Would it be bad to use ((.dispatchFn ig/init-key) "blah" "blah") or is that unlikely to change?

Jim Newton 2020-11-06T13:05:27.278500Z

Does anyone here also program in Scala? If so, maybe you can help me answer a https://clojurians.slack.com/archives/C16LEKSLT/p1604667792002600?

Louis Kottmann 2020-11-06T13:17:04.279700Z

how do you deal with exceptions that happen in anonymous functions that run in a future?

Louis Kottmann 2020-11-06T13:18:04.280900Z

I had to run the code without the future and de-anonymize the function to even get the exception to show up instead of being silently discarded, it was quite the painful debugging experience

2020-11-06T13:21:27.281Z

yes, it is unclear from documentation but expressions in catch evaluated outside of try context

Louis Kottmann 2020-11-06T13:28:56.281500Z

should I not use futures for non-trivial work?

Louis Kottmann 2020-11-06T13:32:39.281900Z

ah, it was slingshot's throw+ / try+ that somehow hid all that

2020-11-08T23:44:42.384Z

What I mean is, if you do care, then dont implement a fire and forget behavior. The "forget" part implies that you don't care if it succeeds or not.

2020-11-08T23:45:46.384200Z

So I assume you want to say log a message, output an error metric, perform a retry, etc. So for any of these, you need to explicitly handle the error

2020-11-08T23:48:06.384400Z

You can also check the status of the futures from the main thread without blocking, if you want to handle them here (or since you're error handling is a side effect as well, you can handle them in the future thread).

2020-11-09T00:00:19.384600Z

So like in your main thread, you could check if the future is realized? yet, and if it is, check if it errored and do whatever you want in that case.

2020-11-09T00:00:38.384800Z

But in your case, probably just have a try/catch inside the future itself.

Louis Kottmann 2020-11-09T01:45:20.387200Z

right, I have a try/catch in the future

Louis Kottmann 2020-11-09T01:46:07.387600Z

but I start to feel like I'm using futures incorrectly, and should be using another multithreading technique more appropriate

2020-11-09T05:09:13.388800Z

I can't speak to that, but it's fine to use futures to fire async tasks that only do a side effect. Just make sure you try/catch them.

(future
  (try (task)
  (catch Throwable t
    (handle-error t))))

2020-11-09T05:21:16.389400Z

You can make yourself a little util for it:

(defn fire-async
  [task error-handler]
    (future
     (try (task)
     (catch Throwable t
       (error-handler t)))))

2020-11-09T05:32:47.389700Z

With future, you can fire an infinite number of concurrent tasks. There will be one thread per concurrent task. So at 100 concurrent tasks, you will have 100 threads. As the number of concurrent tasks goes down, the number of threads will go down as well, but it will lag behind, as threads wait for 60 seconds in the hope they can be reused.

2020-11-09T05:42:02.390Z

This means that in theory, you could run out of memory if you fire too many concurrent tasks. And really, it will be the total set of concurrent futures and agent send-off executing in your program.

2020-11-09T05:44:02.390200Z

That's why sometimes people will recommend in server code where you can't predict how much concurrency you'll end up having (nothing upstream of the future call is bounded for example), to either use your own executor service. Or to change the default executor for future to a bounded one, or to use core.async with bounds.

Louis Kottmann 2020-11-09T10:21:49.404400Z

thank you very much

Louis Kottmann 2020-11-09T12:03:27.409200Z

actually, with core.async, I could probably create a ~10 channels that work concurrently, with extra work waiting in the queue and when my program exits, I could ensure they are all done with alts! which is neat (I wondered how I could do that)

Louis Kottmann 2020-11-09T12:03:34.409600Z

I will play around with that

2020-11-09T19:06:13.433700Z

When your app closes, running futures will prevent it from shutting down, so it will wait for all futures to complete as well, nothing will get interupted

2020-11-09T22:01:49.446700Z

Even if you call shutdown-agents this will be the case. All running future and agent actions will need to first complete before the app terminates

2020-11-06T13:37:53.282100Z

you can write defmulti with a var in place of dispatch function

(defmulti foo some-dispatch-fn)
this function you can use to get dispatch value
(some-dispatch-fn "blah")

Karo 2020-11-06T13:41:12.283400Z

Hi all, "lein ring server" command is for starting ring server, what is the command to stop already running server?

agile_geek 2020-11-06T14:00:57.283500Z

It should behave like Java does. So if the exceptions in the catches are in an inheritance hierarchy the most specific one is the one caught. A re-throw would not be caught in the same try-catch but, obviously, any finally expression is eval'ed at the end.

Test This 2020-11-06T15:01:29.289700Z

Hi! What is an easy way to save different configurations for test and production? I want to use a different database name when running tests and a different database for development/production code when not running tests. I first thought of hardcoding the database name in the dbfuncs.clj file (using def. But then I changed it to a function. I need to now add code that reads the database name from somewhere. Is it possible to say something like: if running tests then use dbname gamesdbfortest and if not running tests then use dbname gamesdb?

(def hds-opts (atom nil))

(defn db-config
  [dbname]
  {:dbtype "postgres" :dbname dbname})

(defn set-datasrc 
  [dbname] 
  (let [^HikariDataSource hds (connection/->pool HikariDataSource (db-config dbname))]
    (reset! hds-opts (j/with-options hds {:builder-fn rs/as-unqualified-lower-maps})))) 

Louis Kottmann 2020-11-06T15:14:01.290500Z

there's environ and lein-environ, works well for me

2020-11-06T15:17:36.291100Z

Not sure if it’s relevant, but in Java every non-main thread discards unhandled exceptions by default, but you can change that behaviour as described here: https://stuartsierra.com/2015/05/27/clojure-uncaught-exceptions

Louis Kottmann 2020-11-06T15:30:47.291500Z

thanks, I'll add that, even though I mostly use futures

mafcocinco 2020-11-06T15:36:46.293100Z

(Hopefully) simple question about clj-time: Is it possible (and if so, how) to get out non-traditional date values? For example, I would like to get day-of-year, week-of-year and day-of-week from a parsed UTC date.

mafcocinco 2020-11-06T15:37:47.293900Z

I suppose on day-of-week can just translate from text abbreviation to a numeric value, so nvm about that one. πŸ™‚

Test This 2020-11-06T15:46:56.295300Z

@lkottmann Thank you. Will look into environ. I am using deps.edn so the other may not work.

Test This 2020-11-06T15:49:34.296900Z

Anyone has deps.edn examples for environ? I see only lein and boot examples in the readme.

Michal 2020-11-06T15:53:24.298600Z

Hi guys, can anyone help me and translate the following code snippets into json structure or something I could understand. I don't have a Clojure background and I need to recreate a similar structure in a javascript. i will appreciate your help

(merge {:event/stream :users
                           :event/partition-key user-id
                           :event/type :users/created
                           :event/actors #{:user-id :referring-user-id}
                           :user-id user-id
                           :referring-user-id referring-user-id}
                          (select-keys new-user [:first-name :last-name :username :email]))
And this one:
{:event/type :users/created
                   :event/created-at (java-time/instant)
                   :user-id #uuid "d415fb11-3d42-4a5d-911e-484b1baad7af"}

2020-11-06T15:53:44.298700Z

Pretty sure futures are dispatched on non-main threads, so unless your code is catching exceptions and doing something with them, they’ll disappear silently (as per JVM default behaviour).

2020-11-06T15:54:53.298900Z

the translation is trivial, what's the specific issue you are having?

2020-11-06T15:55:28.299100Z

{:foo/bar baz} in a clojure data literal becomes {"foo/bar": baz} in json

2020-11-06T15:55:57.299300Z

or "foo_bar" if you prefer - json doesn't have namespaces so there's no direct equivalent

Michal 2020-11-06T15:59:17.299500Z

does it mean the

{:event/type :users/created
                   :event/created-at (java-time/instant)
                   :user-id #uuid "d415fb11-3d42-4a5d-911e-484b1baad7af"}
Will be translated into something like:
{"event/type": "users/created", 
"event/created": "2020-06-02T21:34:33.616Z",
"user-id": "d415fb11-3d42-4a5d-911e-484b1baad7af"
}
as a json object

Michal 2020-11-06T15:59:35.299700Z

Thank you @noisesmith for a quick reply

dpsutton 2020-11-06T16:02:53.300Z

(println (json/generate-string {:event/type :users/created
                        :event/created-at (java-time/instant)
                        :user-id #uuid "d415fb11-3d42-4a5d-911e-484b1baad7af"}))

{"event/type":"users/created","event/created-at":"2020-11-06T16:02:42.287334Z","user-id":"d415fb11-3d42-4a5d-911e-484b1baad7af"}

dpsutton 2020-11-06T16:03:23.300200Z

you can check what it serializes to to double check your work. or let cheshire do the work for you

dpsutton 2020-11-06T16:03:46.300400Z

the json alias here is cheshire.core

Michal 2020-11-06T16:12:03.300600Z

Great! As I think that's all what I need to know πŸ™‚ Thanks guys and have a good weekend!

seancorfield 2020-11-06T17:47:29.301300Z

@mafcocinco As one of the clj-time maintainers, I'll remind you that the library is deprecated and we recommend folks use Java Time instead, either directly via interop or through one of the available wrappers (which are listed on the clj-time README).

mafcocinco 2020-11-06T17:59:17.301500Z

cool thanks.

2020-11-06T19:58:47.302300Z

No, a thrown exception inside the future is returned as the value of the future

2020-11-06T19:59:06.302500Z

And the future :status will be :failed

Marcus 2020-11-06T20:22:39.303700Z

which libraries do you use for data visualization? (charts / graphics)

uosl 2020-11-07T17:04:27.322500Z

vega-lite is the way to go. Oz is good for getting started, but it's pretty easy to create your own wrapper around vega-embed when you need more flexibility.

Marcus 2020-11-07T18:02:25.326700Z

Can both be used from Clojure and not ClojureScript?

uosl 2020-11-08T10:41:45.343300Z

Yes

Ryan Domigan 2020-11-06T20:44:08.308300Z

Hi, I'm trying to get a Clojure+ClojureScript project working with figwheel-main. I'm somewhat stymied by CORS errors -- do I need to allow calls from localhost:9500 on my server at localhost:8080 or is there any way to just serve everything from the same port?

practicalli-john 2020-11-06T21:03:12.308400Z

https://github.com/metasoarous/oz

practicalli-john 2020-11-06T21:05:48.308700Z

https://github.com/juxt/aero is a very good library for managing different environments

practicalli-john 2020-11-06T21:08:31.309Z

I think it's just Ctrl-c to kill the process. Using wrap-reload with ring can reduce the need for restarting the server, although it's still required when adding dependencies.

practicalli-john 2020-11-06T21:12:06.309200Z

Use doseq if its only side effects

Ryan Domigan 2020-11-06T21:20:33.309400Z

Adding Access-Control-Allow-Origin and Access-Control-Allow-Credentials to the headers works. I guess that'll be that.

Louis Kottmann 2020-11-06T21:51:43.309600Z

The problem comes from futures that I never dereference

Louis Kottmann 2020-11-06T21:52:01.309800Z

Are they ever cleaned up btw?

2020-11-06T22:04:38.310Z

you can configure your cljs output options and a "wrap-resource" ring middleware to serve the cljs from the same port that you serve your site pages

2020-11-06T22:11:24.310200Z

When the reference to the future is gone, it will be garbage collected

2020-11-06T22:12:33.310400Z

Why would you care about a failed future you don't deref? This fire and forget behavior would imply to me that you choose to not care about what happens to the task

2020-11-06T22:25:01.310600Z

True, I do use scalar for non collections

Ryan Domigan 2020-11-06T22:54:56.311100Z

I can serve the js which figwheel builds but it doesn't live reload for me (although it does fix the cors issue). I've been using ` (defn app [] (html [:head [:title "Welcome to blah"]] [:body [:div {:id "app"} [:script {:src "cljs-out/dev-main.js"}]]]))`

teodorlu 2020-11-06T23:16:00.311700Z

I think Figwheel uses websockets to make live reload work. In that case, you might have to forward websockets traffic as well as static files. I would start by looking for websockets traffic in the browser's network monitor.

Daniel Stephens 2020-11-06T23:28:08.311900Z

forgot to press enter, sorry! Unfortunately in my case I don't own the defmethod, it's integrant/init-key, the method it uses is anonymous and delegates to a private method, .dispatchFn worked fine for me for now, just suprised there wasn't something in core for it

Daniel Stephens 2020-11-06T23:30:57.312100Z

Thanks, I actually was replacing a bit of code that was using a doseq as I needed it sometime to be side effecting and othertimes not and to give back all of the values. reduce gives me the best of both πŸ‘