Fork me on GitHub
#beginners
<
2019-09-13
>
johnjelinek00:09:41

I've got this:

(def instance-type [InstanceClass/BURSTABLE3 InstanceSize/LARGE])
and I can call a method like this:
(InstanceType/of (first instance-type) (second instance-type))
but is there a way to just pass in instance-type as if it were the collection of args to InstanceType/of?

johnjelinek00:09:58

or is this the closest I can get?

(let [[class size] instance-type]
   (InstanceType/of class size))

andy.fingerhut01:09:36

If InstanceType/of were a Clojure function, you could use apply, but apply will not help if it is a Java method, not a Clojure function.

hiredman02:09:54

You can use reflection to pass an array of arguments

hiredman02:09:02

or methodhandles

hiredman02:09:15

(let [a (into-array Integer/TYPE (range 10))
      b (int-array 10)]
  (.invokeWithArguments (.findStatic (java.lang.invoke.MethodHandles/lookup)
                                     System
                                     "arraycopy"
                                     (java.lang.invoke.MethodType/methodType
                                      Void/TYPE
                                      [Object
                                       Integer/TYPE
                                       Object
                                       Integer/TYPE
                                       Integer/TYPE]))
                        [a
                         (int 0)
                         b
                         (int 0)
                         (int 10)])
  (vec b))

pferron04:09:02

Is there a way to pass an existing collection of keys to clojure.spec.alpha/keys?

(def ks [:a/b])
(s/keys :req-un ks)
Syntax error macroexpanding s/keys
Don't know how to create ISeq from: clojure.lang.Symbol

seancorfield04:09:55

@pferron Not easily in Spec1. It will be supported by Spec2.

pferron04:09:03

OK, thank you. Looking forward to it 🙂

seancorfield04:09:14

What we do with Spec is to use the spec itself as the system of record for the keys -- so we define the spec, then we introspect it to get the list of keys and use that in our code.

Shaitan06:09:01

how to read from this data structure: #:db{:id 17592186046711} . it is from datomic

jumar06:09:58

What do you mean by "read"

jumar06:09:27

In case #:db is unfamiliar that's a namespaced map. The same thing as {:db/id}

jumar06:09:35

(keys #:db{:id 17592186046711})
;;=> (:db/id)

Shaitan06:09:49

oh thank you!!

jumar06:09:58

Why did you delete the message?

Shaitan06:09:06

accidentally

jumar06:09:24

Ah, ok 🙂. Shouldn't do that in general (unless it's something rude, offensive, etc.)

👍 1
nitaai09:09:36

Hi. I am having troubles extending a type with a protocol defined in other namespace, namely StreamableResponseBody from ring.core.protocols. Firstly, how do I require the protocol properly in my namespace?

nitaai09:09:20

I am doing simply (require 'ring.core.protocols) and (extend-type ... ring.core.protocols.StreamableResponseBody ...), but getting an error java.lang.IllegalArgumentException: interface ring.core.protocols.StreamableResponseBody is not a protocol.

nitaai10:09:25

Ok, problem solved. I need to reference the protocol as ring.core.protocols/StreamableResponseBody.

Adrian Smith11:09:45

I just discovered you can define your tests inside the meta data of a function, are there any pitfalls to doing this as a kind of documentation?

delaguardo11:09:57

clojure.test is doing similar inside of deftest macro. You can also use clojure.test/test-var to execute your tests in the context of clojure.test

delaguardo12:09:09

https://gist.github.com/DeLaGuardo/55ae4be5a932cf32b0f1e828e5109bb6 you can run it clj -Sdeps '{:deps {some {:git/url ":55ae4be5a932cf32b0f1e828e5109bb6.git" :sha "87da16f6ec05b7dcfa4f28590eed0894c3a2ddbf"}}}'

Jakob Durstberger13:09:21

Hello, maybe someone here can help me out. I started looking into luminus and I want a little service with 2 endpoints one for retrieving a value and one for updating it. At this point I don't want to mess about with data bases. I found mount but my value is always coming back as 42 when calling GET These are my routes:

["/number"
    {
     :get (constantly (ok {:number @state/number}))
     :post (fn [{:keys [body-params]}]
             (swap! state/number (fn [_] (:number body-params)))
             (ok {:number @state/number}))
     }]])
File with state:
(ns todo-service.state
  (:require
   [mount.core :as mount]))

(mount/defstate number
  :start (atom 42))
I think I might be fundamentally misunderstanding something about mount.

dpsutton13:09:08

in your repl, what's the state of state/number. It is probably not 42

dpsutton13:09:03

but read the docstring of constantly again

Jakob Durstberger13:09:08

Yeah, it was the constantly facepalm Thank you

dpsutton13:09:24

user> 
(def foo (atom 1))
#'user/foo
user> (def f (constantly @foo))
#'user/f
user> (f)
1
user> (reset! foo 300)
300
user> (f)
1

dharrigan13:09:03

I have a transducer (pipeline) that goes something like this (into {} xform a-thing-that-returns-results-as-a-list-of-containing-maps). Inside the xform, I have this (as one of the steps) (map #(into {} (filter (comp some? val) %))) - in order to remove nil values from the map. I'm just wondering, is there a different way of removing nil values from the map as part of a transducer pipeline?

manutter5113:09:09

Check out keep

manutter5114:09:35

(keep identity) gives you a transducer that will strip out all nil values.

efraimmaugusto14:09:51

Anyone with experience with the Luminus framework can help with some issues?

Chase16:09:03

What function should I use to get true if any item in a collection is true for the given predicate and false otherwise? some gives me nil instead of false. (not (not-any? pred coll)) works but I feel like I'm not seeing the obvious core function on the cheat sheet that is probably there.

schmee16:09:18

you can use (boolean (some ...))

Chase16:09:29

ahhh. I like that. ty!

Mario C.17:09:55

If I run the command "clear" on my terminal it works as normal. But when I run the command in the boot-clj script it does not work. Any way to clear the screen in boot-clj script?

Mario C.17:09:58

Or is there way I can call a function and prevent any console output that it might produce?

Mario C.17:09:01

I am calling it with (shell/sh "bash" "-c" "clear")

Mario C.17:09:22

[clojure.java.shell :as shell]

Mario C.17:09:05

I am guessing what is happening is that when I am running that command its not executing in the current process I am running the script from so I am not seeing anything but I am not sure

seancorfield17:09:18

@mario.cordova.862 Right, it's clearing the shell it is running in -- which is not the same shell process that you are running boot in.

David Omar21:09:29

Hi! I just began using Clojure today.

David Omar21:09:55

I've been trying to write some functions, but I want to write some function specifications right in the code. Like what every function expects to receive, what it'll return, and some example uses.

David Omar21:09:43

For JS I've used JSDoc, which allows for something like this:

/**
 * This is a function.
 *
 * @param {string} n - A string param
 * @return {string} A good string
 *
 * @example
 *
 *     foo('hello')
 */

function foo(n) { return n }

David Omar21:09:42

Is there a similar "comment syntax" for Clojure?

andy.fingerhut21:09:41

I am not aware of anything that has widespread use or is any kind of de facto standard there, although Javadoc syntax is used by a few projects, I believe.

andy.fingerhut21:09:59

Yeah, Clojure spec is the other thing I was about to mention. It gives executable specifications for such things, without any natural language other than what you put in comments, again with no special syntax in wide use.

walterl21:09:52

Is there any special convention or meaning in the use of the & character in identifiers, or is it just like other punctuation marks (`-`, !, ?, etc.)?

walterl21:09:03

E.g. is d&d a good var name?

hiredman21:09:41

most commonly & is not part of an identifier(although it can be), but an indicator of varargs

hiredman21:09:13

user=> ((fn [& x] x) 1 2 3 4)
(1 2 3 4)
user=>

walterl21:09:41

Ah, right. So it's better to avoid it, to avoid confusion with varargs vars. Got it 👍

hiredman21:09:56

@davidomarfch depending on what you want, you might be happy enough with just docstrings

gerred21:09:16

yep I look for docstrings first.

gerred21:09:22

then specs

gerred21:09:35

then for rich comment blocks

gerred21:09:57

and then maybe read ; comments.

hiredman21:09:16

user=>
(defn foo
  "Takes an s, returns an s"
  [s]
  s)
#'user/foo
user=> (doc foo)
-------------------------
user/foo
([s])
  Takes an s, returns an s
nil
user=>

gerred21:09:18

depending on the project I may even look for the rich comment block first so I can actually run the forms.

David Omar21:09:34

I think I'll do that. I checked what you sent and it doesn't look like a "readability-oriented" thing. It may even be used for development and testing.

David Omar21:09:47

I'll stick with docstrings for now.

hiredman21:09:26

specs actually show up when you use doc if I recall

hiredman21:09:52

and serve a lot of purposes

David Omar22:09:09

I was originally worried that it isn't very readable, but I guess you eventually learn to grasp it with no trouble.

sova-soars-the-sora22:09:20

cljs.ajax .... i'm getting an atom from the server

sova-soars-the-sora22:09:45

i expect reset! would work on the cljs client

andy.fingerhut22:09:30

A cljs client can modify the state of an atom in the client, but cannot directly modify the state of an atom on the server.

andy.fingerhut22:09:47

Not sure if that is what you are trying to do, and maybe too obvious a thing to say...

sova-soars-the-sora22:09:56

the server is sending data to the client

sova-soars-the-sora22:09:06

i'm trying to update the clientside version of the atom with the ajax response

dpsutton22:09:21

> i'm getting an atom from the server is a very strange thing

andy.fingerhut22:09:38

Sure, but the server is either sending the value that is the contents of its atom to the client, or something else I don't understand.

andy.fingerhut22:09:09

The server can't send a thing to the client that the client can directly use to mutate the server's state via reset!. The client might have an atom local to it that it can reset!, but it cannot reset! the atom's server without sending an agreed-upon message to the server that causes the server to perform the reset!

sova-soars-the-sora22:09:01

i'm not trying to change the state of a serverside atom

sova-soars-the-sora22:09:18

i'm trying to change the state of the clientside atom via reset! on ajax response

sova-soars-the-sora22:09:42

client initiates an ajax POST and the server replies with the contents of an atom, like you suspected,

andy.fingerhut22:09:01

So is the server sending the vector of maps to the client?

andy.fingerhut22:09:11

And the client is then somehow storing that in a client-local atom?

sova-soars-the-sora22:09:55

what is ajax, is it a send or a receive? to me it's both, so the answer to your first question is yes. and yes to the 2nd question.

andy.fingerhut22:09:35

The client should be able to reset! its client-local atom all it wants, with no effect on the server's state.

andy.fingerhut22:09:24

Not directly that is. Someone could customize things so that reset! on the client side might have additional side effects, but I don't know if any client-side cljs libraries play those kinds of tricks.

sova-soars-the-sora22:09:43

i feel like i'm taking crazy pills

andy.fingerhut22:09:23

when you say "no go", what are you trying, and what do you observe afterwards that leads you to conclude "no go"?

sova-soars-the-sora22:09:00

i'm using rum which has a rum/react atom watcher that i expect to render the page once the atom is reset!

sova-soars-the-sora22:09:30

my console log print actually gives me the atom contents which is what i expect, but somewhere it is not being used in the clojurescript app. so i'm not really sure what's missing

andy.fingerhut22:09:50

Is it straightforward to modify the rum/react atom watcher code to log additional messages to show what it is doing?

sova-soars-the-sora22:09:52

because instead of rendering the divs with words from the atom, they are blank

sova-soars-the-sora22:09:29

hmm i dunno, that's a good question, i don't know what that looks like and have not come across it at all. probably somewhere in the rum source?

sova-soars-the-sora22:09:51

i expect it to 'react' to the atom's change

andy.fingerhut22:09:54

I haven't used rum, so do not know if there are easier ways to debug this.

sova-soars-the-sora22:09:08

right on. well i'll take a look again, i'm probably just missing something obvious

sova-soars-the-sora22:09:12

thanks for your help

andy.fingerhut22:09:33

Also of course, log messages before and after your reset! call, to ensure it is actually happening when you think it is.

andy.fingerhut22:09:46

And FYI, if the server is sending a vector of maps to the client, it is a little confusing for other developers when you say it is sending an atom to the client. An atom is a mutable container that can hold a value, not something one typically serializes and sends to a different process "over the wire".

andy.fingerhut22:09:12

If the server is storing that vector of maps inside an atom in its Clojure code, but deref's that atom and sends the contained value (which is a vector of maps), then that is notably different than trying to send an atom.

sova-soars-the-sora23:09:44

I started logging like you suggested and then did a lein clean, now it works 😄

andy.fingerhut23:09:17

Yeah, running code that does not match with what you are modifying in your editor is a reasonbly-common source of confusion.