Fork me on GitHub
#beginners
<
2018-05-12
>
dpsutton00:05:13

The easiest to shadow is name and then key for me. And I've been bitten by it

mikerod02:05:45

Lisp-2 seem to have way too complex of rules with all these symbol name spacing rules. I don’t see how that would be preferred to a lisp-1. Shadowing is a minor annoyance in comparison. In my own opinion of course. 😬

mikerod02:05:58

“Common Lisp has 7 namespaces” immediately strikes me as a problem. Hah

mikerod02:05:20

I’m just surprised it is preferred by people.

itsalitee02:05:02

I am trying to find the index of non-zero elements in my matrix but I cannot doing that using the clojure matrix core function non-zero-indices as it gives me the indices in this format #object[[I 0x7956f93a [I@7956f93a]]]. Does anyone have a suggestion for this? Thanks beforehand!

seancorfield03:05:34

@ali417 That looks like an array type... can you call seq on it?

itsalitee16:05:28

I did and got nothing back

Chris08:05:40

Is there a way to run another JVM a la lein trampoline with boot? I have a project that I run with trampoline because otherwise the shutdown hook doesn’t fire (I think lein intercepts the C-c or something). I’d like to port this to boot, but am not sure what the equivalent functionality is

Caio Guedes12:05:43

Guys! I'm very difficult to understand what is the Component and why I need use it. Could you help me with some articles or videos about it? thanks 😊

gklijs14:05:04

This, https://github.com/stuartsierra/component should probably help. It’s basically about breaking up your code in components. It takes a bit of work to setup right, but you get a lot back from it. For example it’s easy to use one database connection across different components, you can easily reload components, you can make a visual of how your system works, which is always up to date.

sveri17:05:39

@caio.cesar.g.souza Also its worth noting that a component in the libraries context is something that has a start / stop lifecycle like a webserver, a websocket connection, a scheduler. It can be used for other stuff too, but thats its main point.

Caio Guedes17:05:10

@sveri thanks, this is a easy way to see when use it.

bringe20:05:14

Questions: I have a function signature like this:

(defn create-websocket-connection
  [product_ids callbacks channels auth-params])
I want product_ids and callbacks to be mandatory, but channels to be optional as it will have a default value, and auth-params to be optional, as a non-authenticated connection is possible. Should I leave this as it is, or combine channels and auth-params into one map (`options`), in case someone wants to pass no channels (use default), but need to pass auth-params? That way they don't have to call it with nil in place of channels.

bringe20:05:49

Logically, I don't feel that channels and auth-params need to be grouped together into one map, but with them both being optional, I'm not sure what is best here.

mfikes20:05:47

@brandon.ringe A common pattern is to include a opts parameter that takes a map value, so

(defn create-websocket-connection
  [product_ids callbacks opts])

bringe20:05:58

@mfikes thanks, wasn't sure if something like that was standard, but common patterns are good, so I'll do that.

sundarj21:05:58

just for completeness, you can do default values for regular parameters by using arity overloading, like so:

=> (defn f
     ([a b] (f a b :default nil))
     ([a b c] (f a b c nil))
     ([a b c d] [a b c d]))
#'boot.user/f
=> (f 1 2)
[1 2 :default nil]
=> (f 1 2 3)
[1 2 3 nil]
=> (f 1 2 3 4)
[1 2 3 4]

bringe22:05:38

Thanks for the info. Btw I've read using variable arity is bad:

(defn create-websocket-connection
  [product_ids & [opts]]

bringe22:05:50

What do you think?

bringe22:05:42

Would it be better to require opts passed as an empty map if no options need to be specified?

bringe22:05:00

That seems like a code smell to me

sundarj22:05:01

there's nothing wrong with having a function have multiple arities - many core functions do. that's different from variable arity, which means that it accepts any number of arguments

sundarj22:05:40

so you could define the function that takes the opts map to have an additional arity that passes the empty map for the function caller

sundarj22:05:03

=> (defn f ([] (f {})) ([opts] opts))
#'boot.user/f
=> (f)
{}
=> (f {:a 2})
{:a 2}
=> (f {:a 2} :wrong)

clojure.lang.ArityException: Wrong number of args (2) passed to: user/f

sundarj22:05:34

in this case, the function accepts either 0 or 1 arguments

sundarj22:05:59

if passed 0, it calls itself with an empty map as its 1st argument

sundarj22:05:49

try doing (source symbol) or (source +) for examples of core functions that have multiple arities

mg23:05:56

@brandon.ringe so that article is saying that it's a bad idea to use varargs (when you see & in a signature) for optional args. Varargs means something a bit different than multiple arity. You can pass any number of arguments to varargs. Multiple arity functions have multiple, but fixed, numbers of args

mg23:05:31

The guideline is to use multiple arity to express optional arguments, not varargs

8
bringe23:05:04

Yes I understand the difference, I was specifically asking about varargs, sorry for not being clear. I see what you mean. Thanks! Refactor time...

mg23:05:34

Looking back at your original question, you could also use kwargs for that

mg23:05:53

Since you have two independent optional params

mg23:05:47

So the signature there might look something like, (defn create-websocket-connection [product-ids callbacks & [{:keys [channels auth-params] :or {channels your-default-channels}}])

bringe23:05:44

Is that not also functioning as varargs though with that ampersand there? So it's varargs but just destructuring the first arg?

mg00:05:01

It would be called like, (create-websocket-connection product-ids callbacks :auth-params auth :channels some-channels) and you could omit either or both of the kwargs

👍 4
mg00:05:25

Crap I gave the wrong declaration. It should be like this, (defn create-websocket-connection [product-ids callbacks & {:keys [channels auth-params] :or {channels your-default-channels}})

mg00:05:23

I'm on a phone, mistake-prone ;)

bringe01:05:07

Oh yeah I thought so lol