Fork me on GitHub
#beginners
<
2019-09-25
>
seancorfield00:09:02

@davidomarfch I think the most fundamental thing is that the semantics of Clojure -- including compilation to JVM bytecode on the JVM -- is to work one top-level form at a time, exactly like the REPL does.

seancorfield00:09:18

As Stu Halloway has observed in several talks, you could just start a REPL and feed all your code to it (in the appropriate "bottom-up" order) without needing to actually read any files at all.

seancorfield00:09:32

So when you run a process with a REPL inside it, you're interacting directly with Clojure's compiler -- and the live, running application. And since Clojure 1.8 you can start any Clojure process with a Socket REPL (just using JVM options) and connect to that REPL -- in a production app if you want -- and you have the exact same form-by-form compile-and-evaluate process going on.

seancorfield00:09:19

That all means that the RDD workflow has immediate feedback on everything you write. You can evaluate forms from your editor (into the REPL / into the live, running application) without even saving the file. Write an expression, press a hot key, see the result as it affects your program.

seancorfield00:09:23

For most other languages, their "REPL" is an add-on shell feature, and often an interpreter rather than integrated into the compiler/runtime like Clojure's.

davidomarfch00:09:44

I can't grasp the importance of it yet. Mainly because I'm not really familiar with the semantics of Clojure. Is it related to how we can do this: https://www.braveclojure.com/assets/images/cftbat/read-and-eval/lisp-eval.png ?

davidomarfch00:09:12

I think I'll read about semantics. Thanks for guiding me, @seancorfield.

andy.fingerhut00:09:34

Perhaps this may sound contradictory to the goals of Clojure, but one thing that makes the REPL useful is the mutability that is part of Clojure. Every time you defn a function that you defn'd before, all references to it elsewhere refer to the new one, not the old one (there are some exceptions to it that I don't have a complete list in my head of, e.g. when you direct the Clojure compiler to use direct linking, which is off by default when you compile your own code).

noisesmith17:09:35

I think a good summary of it is "unless you ask for direct linking, usages of the var will automatically see new definitions (while usages of its current value will be immutable, eg. capturing the result of a first class function)"

andy.fingerhut18:09:07

Yeah, I was thinking about all of the other cases, e.g. multimethods, protocol functions, etc., that get a little hairy to summarize.

andy.fingerhut18:09:38

With normal Clojure functions, most of those cases are irrelevant.

noisesmith18:09:29

oh yeah, good point

andy.fingerhut00:09:03

It isn't a contradiction to the goals of Clojure at all -- typically such mutations are done manually, not millions of times under programmatic control the way data mutations typically occur in programming languages where mutability is the default.

seancorfield01:09:31

@davidomarfch Have you watched Stu's talks? Running With Scissors and REPL-Driven Development.

davidomarfch02:09:15

I didn't think about that, but makes sense.

davidomarfch02:09:17

No, I haven't. But I'm doing it right now.

sfyire10:09:42

Is there a type of transducer that can be put in a pipeline which forces all prior operations to fully complete?

sfyire10:09:42

I'm running into([]) twice at the moment to force the first set of operations to complete just wondering if there's a nicer way

oliv20:09:29

hey guys, need to communicate with amazon sqs, which library are you guys using ?

charles.fourdrignier20:09:47

I used this. https://github.com/cognitect-labs/aws-api Very "Clojure way of doing things".

oliv20:09:25

hey @charles.fourdrignier, looks interesting, do you have any public example. could not be able to find out sqs examples

oliv20:09:55

interesting on how to listener for new messages properly

charles.fourdrignier20:09:44

You could watch at this talk (https://www.youtube.com/watch?v=ppDtDP0Rntw) to understance the philosophy and apply it to SQS. Here is a snippet from my code.

(def sqs-client (aws/client {:api :sqs :region REGION}))
(def s3-client (aws/client {:api :s3 :region REGION}))

(defn delete-message [receipt-handle]
  (let [encoded-handle receipt-handle #_(java.net.URLEncoder/encode receipt-handle)]
    (aws/invoke sqs-client { :op :DeleteMessage :request
                            {:QueueUrl QUEUE_URL :ReceiptHandle encoded-handle}})))

(defn read-messages []
  (:Messages
   (aws/invoke sqs-client { :op :ReceiveMessage
                           :request {:QueueUrl QUEUE_URL :MaxNumberOfMessages 10 } })))
Hope it helps.

oliv20:09:15

hey, thanks @charles.fourdrignier

oliv20:09:59

doing now !

charles.fourdrignier20:09:19

Note that could not "listen" a SQS. You could just come back every X minutes to check if new messages are presents.

oliv20:09:31

yeah, SQS do not push messages, we have to go there every x sec to fetch new ones

oliv20:09:42

pull based model

iagwanderson20:09:41

hi ppl, how can I convert an # inst (java.util.Date) to a java.time.Instant?

alexmiller20:09:17

Call .toInstant ?

iagwanderson20:09:12

(Y) thanks that was simple 😃