clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2021-05-03T00:15:41.457800Z

(dsfn foo
  ([& {:keys [^Int bar]}] 100)
  ([& {:keys [^String bar]}] "100"))
If I call (foo :bar "hi") will it pick the first or second?
(dsfn foo
  ([^Int bar] 100)
  ([^String bar] "100"))
Now if I call (foo "hi") will it pick the first or second? In my opinion both should behave the same, which would be that they match the second in both case.

2021-05-03T00:27:24.458100Z

I also think most of the time in Clojure allowing other keys might be best, that's the default everywhere and it's quite common to call something with a map that has more keys than what the function needs. Especially with Clojure 1.11 where both (foo :bar "hi") and (foo {:bar "hi"}) is a valid call to the function.

Crispin 2021-05-03T01:03:41.458400Z

talking TCP: after constructing the socket on the client side you need to bind the socket to the source IP you want before you connect. If your http client doesn't support that, you will need to modify it, or use one that does. https://linux.die.net/man/2/bind

Crispin 2021-05-03T01:05:16.458700Z

But AFAIK you can only bind to a source IP that is bound to a local interface. You can't spoof any old address. For that you would need some kind of raw packet injection.

2021-05-03T02:09:15.459200Z

In Clojure I think being open by default is a better default.

zendevil 2021-05-03T06:09:22.462700Z

zendevil 2021-05-03T06:11:13.464200Z

Iโ€™m using the manifold.stream library to send a message through a websocket:

(defn send []
    (manifold.stream/put! mysocket
         (generate-string
          {:type "unsubscribe"
           :product_ids ["ETH-USD"]
           :channels ["heartbeat"]})))
and running (send) in the repl works. However, when I make an http request from a client, and have the send function as the handler for my reitit route, I get the error in error.txt. The line 142 refers to,:
(def server
  (aleph.http/start-server server-handler {:port 8992}))
Why am I getting Address already in use?

p-himik 2021-05-03T08:31:29.465300Z

Because something else is already listening on that address. Maybe a different process, maybe same.

Jim Newton 2021-05-03T07:26:28.465100Z

ELS21 European Lisp Conference is now live and free https://www.twitch.tv/elsconf

Audrius 2021-05-03T10:10:17.466900Z

I check disk free with (.getFreeSpace (File. "/")) I wonder would it work in Windows OS as well :thinking_face: I just don't have conditions to test. Could someone apply this in their REPL?

flowthing 2021-05-03T10:35:47.468800Z

Any thoughts on what could be going on here?

user=> (def url (URL. "file:/my/path/target/dev/public/js/app.js"))
#'user/url
user=&gt; (trace/trace-ns <http://clojure.java.io|clojure.java.io>)
nil
;; <https://github.com/ring-clojure/ring/blob/99ece0b95293c6b45e1bdb03a99ab1d597117ac9/ring-core/src/ring/util/response.clj#L173-L178>
user=&gt; (#'ring.util.response/url-as-file url)
TRACE t84170: (<http://clojure.java.io/as-file|clojure.java.io/as-file> "/my/path/target/dev/public/js/app.js")
TRACE t84170: =&gt; #object[java.io.File 0x17ed6543 "/my/path/target/dev/public/js/app.js"]
#object[java.io.File 0x17ed6543 "/my/path/target/dev/public/js/app.js"]
user=&gt; (trace/untrace-ns <http://clojure.java.io|clojure.java.io>)
nil
user=&gt; (#'ring.util.response/url-as-file url)
nil ;; :butwhy:
Why in the world does ring.util.response/url-as-file return what I expect when I trace it, but not when I don't? Same thing if I copy the impl of that function into my own ns: it returns the File I expect, but if I call the original function, it returns nil. I'm kinda running out of ideas.

flowthing 2021-05-03T10:40:52.469Z

Restarting the REPL fixes the issue, oddly.

p-himik 2021-05-03T10:58:19.469200Z

user=&gt; (import '(<http://java.io|java.io> File))
java.io.File
user=&gt; (.getFreeSpace (File. "/"))
22677266432
user=&gt; (.getAbsolutePath (File. "/"))
"C:\\"

Audrius 2021-05-03T11:00:26.469400Z

Nice! thank you ๐Ÿ˜‰

๐Ÿ‘ 1
2021-05-03T15:33:19.472800Z

Hey all, do you have a library recommendation for parsing plain text RFC 5322 emails into Clojure data structures? I've been looking into this library so far: https://github.com/owainlewis/clojure-mail. My main beef with it is that it's oriented towards both fetching the emails from the server and then reading them, but I've already got the text of the emails themselves, and just need to parse them into something that's easier to work with programmatically. If you've got any other recommendations I'd be much obliged ๐Ÿ™‚

2021-05-03T15:44:52.473400Z

For those also looking for a good library, this seems to work pretty well: https://github.com/clojusc/rfc5322 The documentation is limited, but the source is fairly straightforward to grok (calling rfc5322.core/convert on your email doc will do the trick)

๐Ÿ‘ 1
2021-05-03T17:23:08.474300Z

javamail

2021-05-03T19:23:06.476800Z

Hello. How can I create an object with my custom public fields, accessible for set/get, and with overriden toString method (in order to pass it to some java lib, uses it) more efficient and idiomatic way?

alexmiller 2021-05-03T19:25:31.477500Z

in general, most ways that you can create Java classes using Clojure will be typed primarily with Object parameters and returns, which is generally not too friendly to Java consumers

alexmiller 2021-05-03T19:25:46.477900Z

the best way to do this is to define the Java API you want in Java with Java interfaces

alexmiller 2021-05-03T19:26:13.478500Z

that lets you type it the way you want, provide javadoc, etc

alexmiller 2021-05-03T19:26:51.479300Z

the factory or service implementation can use the Clojure Java API to invoke Clojure functions through a shim and return objects (defrecord, deftype, etc) that implement the Java interfaces

alexmiller 2021-05-03T19:28:45.480600Z

I have a worked example (details of the Clojure impls probably not exactly what you want/need, but useful in the large) at https://github.com/puredanger/clojure-from-java

๐Ÿ‘ 1
1
2021-05-03T19:32:00.483900Z

So I should create some code in raw Java and the use this class via interop in Clojure? And this way alows typify all the needed things and avoid reflection. But if I tried to keep all the things in Clojure< I can find some existed Java class with an Object type public field, proxy on it and overwrite its toString method?

alexmiller 2021-05-03T19:33:21.484400Z

you are creating Java interfaces and then using Clojure to provide the implementations of those interfaces

alexmiller 2021-05-03T19:34:44.485700Z

you can't really overwrite a Java class's methods via Clojure. you can implement Object in defrecord or deftype to provide a toString() method.

alexmiller 2021-05-03T19:35:38.486600Z

having gone down both of these paths, fighting to do it all in Clojure is not worth the effort. if you want a good Java API for Java consumers, making it in Java is much easier

2021-05-03T19:38:01.488300Z

Of course, and in Java I haven't a problem with it. I just tried to find the best way of integrate some java lib in Clojure project. Thanks alot, I'l think on your suggestions.

2021-05-03T22:16:13.493300Z

Doing a learning exercise here, so i understand how to get the specific components in question to work, but don't understand why. In this case, the example is using rings wrap-reload as discussed here https://github.com/ring-clojure/ring/issues/104. The author and all around awesome dev Weavejester says > The wrap-reload middleware reloads namespaces. It doesn't require a var, but you do need to be careful of the order of evaluation. But i'm having trouble parsing that idea and to boot, I can't find a single example where people aren't passing a var. Regarding "order of evaluation" the function claims to reload given namespaces based on request, so what how i'm in control of any ordering? When i look at the function internals it seems to just call clojure require on every file in the directory. Which right away i would assume would do nothing sense there already loaded: > Loads libs, skipping any that are already loaded.

2021-05-04T21:00:18.086400Z

> The var works becsuse it makes the server reread the expressions each time? apologies if this was addressed already but no - using the var means an extra deref step is used each time to get the content of the var, that's all

๐Ÿ‘ 1
2021-05-04T22:16:37.086700Z

Thanks @noisesmith, that makes sense

2021-05-03T22:18:36.494100Z

i guess regarding the last part, it's passing the :reloaded option to require, which forces an update.

2021-05-03T22:19:56.494300Z

you'd have control if it used :reload-all and if you use a top level def to define your server you wouldn't need a var (but would need to restart the server on reload, which seems silly)

2021-05-03T22:20:11.494500Z

to me using a var to hold the handler is the natural thing

2021-05-03T22:24:21.494700Z

The var works becsuse it makes the server reread the expressions each time?

2021-05-03T22:32:36.494900Z

I suppose I'm also confused why, if it's the natural thing to do, it wouldn't be more clear. I guess clarity depends on perspective.

seancorfield 2021-05-03T23:17:11.495200Z

Iโ€™ll just pop in to say โ€œI generally recommend folks avoid reload-related automation like this because it can and does break and/or cause mysterious problemsโ€ โ€” if you start your server from your REPL, you can eval changes into the live, running app without code-reloading. And now Iโ€™ll go away again ๐Ÿ™‚

2021-05-03T23:36:46.495400Z

@seancorfield come back. I would assume running run-jetty from me cider repl would do just that, but I assume I'm missing something

seancorfield 2021-05-03T23:44:13.495600Z

You need to use a Var to reference the handler when building the middleware and when starting the server, not just the plain function name.

seancorfield 2021-05-03T23:44:39.495800Z

(thatโ€™s mentioned in the REPL guide on http://clojure.org under writing REPL-friendly code, I think)

seancorfield 2021-05-03T23:45:57.496300Z

(and various other places in that file)