Fork me on GitHub
#beginners
<
2021-02-11
>
hswick03:02:34

I'm using deps.edn, trying to require a library into the repl and it results in Execution error (FileNotFoundException) at user/eval3 (REPL:1).

hswick03:02:16

Tried with a few different libraries and the same thing, running on linux. Using different clojure versions doesnt make a difference. Am I missing something?

alexmiller03:02:25

Can you post your deps.edn and what you’re doing in the repl

hswick03:02:28

{:deps {selmer {:mvn/version "1.12.33"}}}

hswick03:02:53

(require '[selmer.parse :as sp])

dpsutton03:02:11

i think you want selmer.parser with a trailing r

hswick03:02:20

oof i wasnt certainly missing something, thank you for reaffirming my sanity

dpsutton03:02:13

no worries. i went to the github page and saw what namespaces were there. and saw the easy to make typo

Rowan Barnard04:02:53

Hi guys, I'm using the clj command line tools and REPL from Powershell commandline in Windows with Clojure 1.10.1 and I've typed (doc clojure.set/intersection) into the REPL and it just returns nil with no documentation. The only thing I've required into the default user namespace is clojure.specs.alpha aliased as s. Any ideas what's going on?

seancorfield04:02:11

@flyingpython You'll need to require clojure.set first

seancorfield04:02:16

It isn't loaded by default.

Rowan Barnard04:02:30

Oh and I've just found out Clojure can't find clojure.set when I tried to run the intersection function: Execution error (ClassNotFoundException) at .URLClassLoader/findClass (URLClassLoader.java:471). clojure.set

Rowan Barnard04:02:44

I'm not sure why it can't find it; I opened clj from a Powershell terminal in a folder I created for practising from the Programming Clojure book

seancorfield04:02:22

[email protected]:~/clojure$ clj
Clojure 1.10.2
user=> (doc clojure.set/intersection)
nil
user=> (clojure.set/intersection #{:a :b} #{:a :c})
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:435).
clojure.set
user=> (require 'clojure.set)
nil
user=> (doc clojure.set/intersection)
-------------------------
clojure.set/intersection
([s1] [s1 s2] [s1 s2 & sets])
  Return a set that is the intersection of the input sets
nil
user=> (clojure.set/intersection #{:a :b} #{:a :c})
#{:a}
user=>
^ @flyingpython

seancorfield04:02:39

Like I said, you need to require clojure.set first. It is not loaded by default.

Rowan Barnard04:02:27

OK I didn't realise I thought it would find it if you qualified it with the namespace

Rowan Barnard04:02:42

Thanks Sean 🙂

seancorfield04:02:52

No. That happens to work for a few of the core namespaces but you should never rely on it.

Rowan Barnard04:02:28

Ah OK that is what was confusing me probably because was pretty sure that usually worked

seancorfield04:02:27

Here's what is currently loaded by default in a REPL:

[email protected]:~/clojure$ clj
Clojure 1.10.2
user=> (->> (all-ns) (map str) (sort))
("clojure.core" "clojure.core.protocols" "clojure.core.server" "clojure.core.specs.alpha" "clojure.edn" "clojure.instant" "clojure.java.browse" "" "clojure.java.javadoc" "clojure.java.shell" "clojure.main" "clojure.pprint" "clojure.repl" "clojure.spec.alpha" "clojure.spec.gen.alpha" "clojure.string" "clojure.uuid" "clojure.walk" "user")
user=>
(but don't rely on that)

Rowan Barnard04:02:45

That is all the ones that you can use without explicitly loading them?

Rowan Barnard04:02:23

Oh sorry didn't read your first line

seancorfield04:02:28

That is the ones that you can coincidently use without requiring them. But don't. It could easily change at any time.

Rowan Barnard04:02:41

OK thank you very much Sean 🙂

seancorfield04:02:44

It's always better to explicitly require a namespace and give it an alias and use the alias.

pez06:02:06

Why is it better to alias?

seancorfield16:02:17

Better than using the full namespace name in qualifiers everywhere? Makes the code easier to read. Better than referring a name into your current namespace? Gives a clear indication at the point of use that a name comes from another namespace. Explicitly requiring all the namespaces you use (and giving them aliases) in your ns form? Provides a straightforward checklist of all your dependencies in one place at the top of the file.

pez17:02:16

Thanks. It was the “always” that intrigued me. I tend to most often alias things, but with some of the clojure ones I don’t. I get confused with aliases like [clojure.string :as str] and [clojure.set :as set], so I require them w/o aliases. In code bases where I am the one making the call, at least. I also refer in some stuff. Not sure what my criteria are, but anyway. 😃

seancorfield17:02:46

I will :refer in a handful of symbols that work better as syntax (like >! etc from core.async) and we've adopted a set of standard aliases for many of the namespaces we used (enforced by clj-kondo`). In tests, I tend to refer in all the parts of clojure.test that I use so there's less "distraction" in the test code. Overall though, I still start from the position that every namespace should be required and aliased -- so, yes, there are exceptions (as there are to every "rule") -- but knowing when to break the rules comes with experience.

pez17:02:00

Shu-ha-ri

Rowan Barnard04:02:00

OK will remember this 🙂

Audrius10:02:28

I wonder is there a predicate opposite to nil? something like not-nil? or something like that...

lassemaatta10:02:35

some?

4
💪 4
mbjarland10:02:41

quick question about core async, assuming I have a coll and want to push the values to a channel, is the idiomatic way (map #(async/>!! ch %) coll)or is there something more concise?

alexmiller13:02:35

Look at the to-chan / onto-chan stuff in the core.async api

alexmiller13:02:02

Here, I think you want onto-chan!!

mbjarland15:02:42

yeah what I figured as well. Was hoping for a blocking variant but this works. Thanks!

alexmiller15:02:19

onto-chan!! will block?

alexmiller15:02:46

oh, I see what you mean

alexmiller15:02:07

can you get that by taking from the channel returned by onto-chan?

alexmiller15:02:33

seems like that's the return of the thread fn and all puts should be done by then

mbjarland19:02:52

Yeah, you can take from the returned channel, but at that point the conciseness vs map is starting to suffer. Anyways, thanks for sorting out the options. Looking at this I think i might stick with map for now.

alexmiller19:02:57

vs map, run! is probably preferred for this case btw

mbjarland09:02:17

Wow. Never ran across run! (ha!). Thanks! And yes, a better match when we don't care about the return values.

mbjarland10:02:31

I saw the onto-chan variants, but they all seem to involve concurrency (as in starting threads, go loops) which is not what I wanted here

emilaasa10:02:03

Is there a recommended way to use date/time in clojure on the JVM?

dharrigan10:02:29

Interop 🙂

dharrigan10:02:37

Esp if you are using Java 8 and above

dharrigan10:02:45

I should say, that's my perferred way 🙂

william12:02:02

is there a way to have an add-watch only on part of an atom? (Say an atom is a map, and I want to see when the value of a key changes, but I'm not concerned about other changes and would like to not do useless computation)

andy.fingerhut12:02:46

There is nothing like that built into Clojure that I can see. You can begin a watch function with the quickest code that determines whether it is an "interesting" change to you or not, and return as quickly as you can if it is uninteresting.

andy.fingerhut12:02:42

e.g. the body of the watch function could be something like (if-not (identical? (:foo old-val) (:foo new-val)). <useful code here>)

andy.fingerhut12:02:11

Or often you would care more about = than identical?

william12:02:51

thanks @U0CMVHBL2, I'll use this approach!

william12:02:59

I find myself repeatedly importing the same convenience namespaces (like [com.fulcrologic.guardrails.core :refer [>defn >def =>]]) in each namespace. Is there a way of doing that once and forall?

andy.fingerhut13:02:22

There might be some IDE hotkey thing that does something like that, but I suspect that most folks probably just copy and paste those from another existing namespace, when creating a new namespace.

Mno13:02:41

Good ol copy and paste, works every time.

caumond13:02:16

Yes a snippet is possible in most ide. It is what i done for test namespace as it is often the same code...

william13:02:55

thanks, I can set a snippet in emacs, it's probably a good idea

Eric Le Goff13:02:14

What function would you use to transform a vector like

[:a :b :c :d :e]
into a list of the consecutive pairs , like
[(:a :b) (:b :c) (:c :d) (:d :e)]
? While it is simple to apply functions I already know , on my learning curve I am currently struggling with inferring which core function I could use to solve specific use cases...

tvirolai13:02:01

(vec (partition 2 1 v))

👍 4
tvirolai13:02:10

Where v is the input.

Eric Le Goff13:02:40

I knew about partition [n coll] but overlooked partition [n step coll], thanks a lot :)

tws15:02:12

@U7ESL5ANN this fits my style, YMMV, but I found it very useful to read and understand every function here when I was getting started: https://clojure.org/api/cheatsheet

👍 4
tomd14:02:03

Hello, I have a question about automatically restarting agents. clojuredocs shows that restart-agent needs to be called in a separate thread, so shows it being called in a future in the :error-handler. Before I stumbled across this, I tried supplying this error-handler: (fn [ag ex] (send ag (constantly foo))) (where foo is the initial state of the agent), which seems to work fine. Is there any reason to prefer calling restart-agent in a future to my approach?

alexmiller14:02:14

have you looked at just using (set-error-mode! ag :continue) ?

tomd14:02:39

I have, but that results in the agent keeping the state it had before the error

tomd14:02:11

In my case, I want to throw the towel in and revert the agent to how it was at the beginning, I think

alexmiller14:02:53

ok, seems fine to me

tomd14:02:06

thanks 🙂

ivar18:02:32

I'm an ex-Rails dev looking at adding user auth & roles to a clojure webapp. In rails I'd just use Devise and basically be done with it. I've poked around a bit and found https://github.com/funcool/buddy and https://github.com/cemerick/friend, but neither seems fully featured (though buddy is closer, it still has a lot in the TODO section of the readme) Is there a recommended library for Devise-like functionality that I'm missing or is the standard practice to roll your own?

clyfe18:02:03

Nothing like Devise, to my knowledge. Do manual atop buddy.

chrisblom18:02:24

i'm not aware of a Devise-like library, but it has been some time since i looked

chrisblom18:02:15

i prefer buddy over friend

ivar18:02:47

thanks for the replies @chrisblom & @claudius.nicolae - both of you prefer buddy over friend - could you say why ?

chrisblom18:02:11

i found buddy easier to use

chrisblom18:02:36

it has some pre-built middleware that was easy to integrate: https://github.com/funcool/buddy-auth

clyfe18:02:45

I prefer buddy because I'm cargoculting.

clyfe18:02:18

But it's also newer (so it had the opportunity to consider what can be improved in friend), and more modular - piece-wise.

clyfe18:02:19

Something Devise-like could be implemented as a https://github.com/duct-framework/duct module (with buddy for warden, and ring for rack).

ivar18:02:25

thanks for the pointers you two.. much appreciated. I need some hammock time to process 😛 hammock

hammock 15
javahippie18:02:32

friend is not really maintained anymore, and was forked and updated by clj-commons to fix a CVE in a dependency: https://github.com/clj-commons/friend