Fork me on GitHub
#clojure
<
2021-05-03
>
zendevil.eth06:05:13

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-himik08:05:29

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

Jim Newton07:05:28

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

Old account10:05:17

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?

p-himik10:05:19

user=> (import '( File))
java.io.File
user=> (.getFreeSpace (File. "/"))
22677266432
user=> (.getAbsolutePath (File. "/"))
"C:\\"

Old account11:05:26

Nice! thank you 😉

👍 3
flowthing10:05:47

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=> (trace/trace-ns )
nil
;; 
user=> (#'ring.util.response/url-as-file url)
TRACE t84170: ( "/my/path/target/dev/public/js/app.js")
TRACE t84170: => #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=> (trace/untrace-ns )
nil
user=> (#'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.

flowthing10:05:52

Restarting the REPL fixes the issue, oddly.

afry15:05:19

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 🙂

afry15:05:52

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)

👍 3
ivana19:05:06

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?

Alex Miller (Clojure team)19:05:31

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

Alex Miller (Clojure team)19:05:46

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

Alex Miller (Clojure team)19:05:13

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

Alex Miller (Clojure team)19:05:51

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

Alex Miller (Clojure team)19:05:45

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

👍 3
2
ivana19:05:00

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?

Alex Miller (Clojure team)19:05:21

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

Alex Miller (Clojure team)19:05:44

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.

Alex Miller (Clojure team)19:05:38

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

ivana19:05:01

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.

Drew Verlee22:05:13

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.

Drew Verlee22:05:36

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

noisesmith22:05:56

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)

noisesmith22:05:11

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

Drew Verlee22:05:21

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

Drew Verlee22:05:36

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.

seancorfield23:05:11

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 🙂

Drew Verlee23:05:46

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

seancorfield23:05:13

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.

seancorfield23:05:39

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

seancorfield23:05:57

(and various other places in that file)

Drew Verlee00:05:53

In https://clojure.org/guides/repl/enhancing_your_repl_workflow#writing-repl-friendly-programs why is print-number-and-wait re definable here:

(future
  (run!
    (fn [i] (print-number-and-wait i))
    (range)))
But not here:
(future
  (run!
    print-number-and-wait
    (range)))

seancorfield01:05:57

Because a (fn [..] ..) compiles in a way that will still deref the name to get the current function value, but when passing a function by name the compiler derefs it to get the underlying function value.

👍 3
seancorfield01:05:14

(it’s a bit more complex than that but that’s the gist of it)

👍 3
noisesmith21:05:18

> 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

👍 3
Drew Verlee22:05:37

Thanks @U051SS2EU, that makes sense