This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-29
Channels
- # announcements (10)
- # babashka (18)
- # beginners (136)
- # calva (9)
- # cider (14)
- # clara (12)
- # clj-kondo (32)
- # cljsrn (3)
- # clojure (133)
- # clojure-europe (21)
- # clojure-nl (4)
- # clojure-uk (15)
- # clojurescript (60)
- # conjure (40)
- # cursive (12)
- # datomic (6)
- # emacs (2)
- # fulcro (19)
- # jackdaw (25)
- # jobs-discuss (3)
- # kaocha (3)
- # leiningen (5)
- # off-topic (99)
- # pedestal (1)
- # re-frame (49)
- # reagent (4)
- # ring (5)
- # rum (5)
- # shadow-cljs (53)
- # spacemacs (2)
- # sql (13)
- # timbre (2)
- # tools-deps (23)
- # vim (11)
- # xtdb (7)
I have a project setup with deps.edn
. I have an alias for nrepl (from Sean Corfield’s guide). I can start the nrepl with clj -A:nrepl
, how do I get it to auto-load my project like lein repl
does?
If you are starting a REPL on the command line and include nREPL, then I assume you are going to connect to that REPL from an editor. So once the editor has connected, evaluate the source code file that defines your main namespace and that loads your project. Unless you need to start a REPL on the command line, starting the REPL from within the editor is recommended practice. This ensures the right version of dependencies are included for the editor to connect to the REPL that is started by the tool the editor launches to start the REPL (clojure cli, leiningen, etc)
If you definitely want to load in a namespace each time you start the REPL, then a common approach is to use a user.clj
file with an (ns user)
namespace, which will be loaded when starting a REPL.
When using a deps.edn project, using a :dev
alias is recommended so that a choice can be made whether to start the REPL with the additional code in the project user
namespace.
https://practicalli.github.io/clojure/clojure-tools/configure-repl-startup.html
@ryan072 Do you mean the "main" ns that lein repl
loads and starts you in?
If you were starting a regular Clojure CLI REPL, you could use -e "(require 'my.main)" -e "(in-ns 'my.main)" -r
and it would run those commands and then present a REPL.
But the :nrepl
alias uses :main-opts
and they do not combine across aliases so I'm not sure if that will work...
I guess what’s your recommendation for “loading” my project into the nrepl?
just go execute the “main” manually file and have it load everything else?
I never type into the REPL. When I evaluate forms from the editor, it auto-selects the correct ns for the evaluation.
when you fire up your repl, is your project “loaded” already, or do you load it yourself?
loaded/parsed/whatever the term is
evaluated
The "project" isn't loaded. Each namespace is loaded/compiled when it is required.
and you do that yourself? (as in you personally evaluated the what you need to get started). unless i”m crazy, doesn’t lein repl
already evaluated your entire project?
not that I need it to be like lein repl
just want to make sure I’m not setting stuff up incorrectly?
I haven't used lein
for years so I don't really remember how it works. I don't use nREPL either.
what do you use?
The Clojure CLI. And a plain Socket REPL.
What editor do you use?
vscode/calva
OK, so you start an nREPL server, then you connect Calva to it...
Then you evaluate the current file into the REPL? Load file?
typically just eval a form
and it switches ns and does it correctly
just felt like the project should be ‘pre-evaled’
This can be set up by adding a startup form that does so. The annoying thing about this option being on by default (as in lein) is when you have a single broken namespace it can leave you in an inconvenient space in terms of what clojure thinks is loaded already via require
and which vars are in fact defined
on startup
I wouldn't want the REPL to load stuff on its own.
I would want control over what gets loaded.
I work with a large project that has many main entry points -- there's no single namespace that could be required at startup to load "everything".
makes sense
I really hadn't given any thought to the idea of a namespace being auto-required at startup, since the editor always uses the right ns for evaluation. The only caveat is that you have to eval the ns
form first in order to have all the other nses compiled that your namespace uses.
Or you could just "load file" whatever that is for your editor.
I have ctrl-; f
bound to "load file" and ctrl-; B
for "eval top-level form" (and ctrl-; b
for "eval current form").
If I'm not mistaken, lein repl
only evaluates whatever namespace you put in :main
on the project.clj
file. On most projects, that main namespace's requires will eventually load all/most of your code, unless it's a big project with multiple entry points.
Yeah, that sounds likely. I suppose it saves a keystroke on small projects when you're first starting your REPL. My REPL tends to run for days, sometimes weeks, so it's not much of a saving.
thanks for the responses @seancorfield!
glad to know that I’m not missing something obvious too
I guess it's another one of those ways that lein
makes things "easy" (without being "simple") 🙂
(after paying attention to how I work for a few minutes, apparently I've gotten into the habit of hitting ctrl-; f
pretty much every time I open a file... and since my REPL doesn't have a prompt I don't even see what ns it is in...)
Just joined. Enjoying Clojure so far. I’m working in an ML class, and thought Clojure would be a good way to explore some ML in the Java world. I didn’t find any Clojure specific ML libraries, so I ended up using SMILE which has some Clojure bindings. Did I miss anything during my Google searches? Are there more interesting libraries than SMILE for data analysis/ML in Clojure? I’m running clojupyter and it’s pretty good. Not as well integrated as Python of course, but overall it’s pretty handy, and Oz/Vega-Lite is producing decent graphs.
You'll probably also find this guy's stuff interesting https://dragan.rocks/
I have. It looks interesting, and I really like the GPU components, but I was looking for something similar to scikit-learn for Python, which Smile does a good job. Fastmath looks like it wraps smile and other libraries fairly well, so I’m going to look at that more in-depth. Thanks.
There's a #data-science channel here as well (although I think a lot of the data science folks are more active on the Clojurians Zulip chat setup?)
I'd recommend asking in #data-science This is also a good resource: https://scicloj.github.io/pages/libraries/
Oo. That page looks interesting. Fastmath in particular looks good, and it uses smile as its backend for a lot of items.
@ryan072 check out https://calva.io/try-first/ , if you haven't. Note that it starts out by the user loading the current namespace. It could seem silly you have to do this yourself, but as @seancorfield points out, you should be in control of what is being evaluated, when. (Calva could be a bit more helpful in reminding you about evaluating forms and files, but anyway.)
Question on Clojure installation om MacOS (unsure if there is a better channel). Installed with Homebrew a while back and now get warnings like: “Warning: Calling 'devel' blocks in formulae is deprecated!...”.
Not sure if this is the correct way to ask this question, but here it goes: Within the Java API is it possible to compile a Clojure program from a string?
Haven't done this myself but this might help: https://clojure.org/reference/java_interop#_calling_clojure_from_java This is a guess but you could try something like:
IFn eval = Clojure.var("clojure.core", "eval");
eval.invoke(Clojure.read("your string"));
Actually think you might be able to skip the IFn step and just use eval directly from the compiler clojure.lang.Compiler.eval(clojure.java.api.Clojure.read("(do (println \"hello world\" {:a :b}) 123M)"))
We used your first suggestion, and it is working great. I really appreciate the help @ULNRSUK8C 🙏:skin-tone-3:
Glad it worked out 🙂 have fun!
I have converted a js
object to clj
using (js->clj obj)
. This is what I get back: {"foo" nil, "bar" #object[com$core$test]}
. How do I get the value of foo
and bar
?
Can someone suggest me a good Mark Down Editor which can be easily integrated with cljs? If possible can you give me some examples also about how to use it. A bit new to Clojure.
IntelliJ/Cursive is tightly integrated with markdown. If you type the following for example: >
clojure
> (contains? x)
>
It will show you usage error highlighting and even allows you to jump to the function definition.I want to create a spec that validates variable length vectors with different predicates based on their first element. These vectors are commands expressed as data What would be the best way to define these specs?
(fake) example:
• [:add 1 2]
would have a spec that validates that values at index > 0 with int?
• [:print "Hello world"]
would validate with string?
(and perhaps assert only one value)
use an s/multi-spec keyed off the first element of the vector
I've done similar things a few times, works well
b/c it's based on a multimethod, it's also open to later extension (which was the whole point behind s/multi-spec)
hm nifty, I've only used multimethods with maps, not vectors, but I suppose a multimethod like
(defmulti command-type first)
would work here?Really cool, this works great. Thanks @alexmiller
Is there a spec shorthand to match a literal keyword? (s/tuple #(= % :add) int? int?
works, but is a little verbose?
enumerated set as a function
doh, of course, one of the first things you learn with spec. I guess I haven't matched literal values that often
NB that works for all values but false, nil, and NaN
false and nil because match returns falsey, NaN because it won't match
What's the recommended Clojure stack for a CRUD web app? I'm looking to create a site which allows people to add location data to an API map, track the locations the user added, and allow other users to see the locations
all else being equal, I recommend the stack used by "Web Development In Clojure" https://pragprog.com/titles/dswdcloj3/
because that way you can learn from the book, which is very good
and unlike many books, it uses tools that are actually widespread and up to date in the community
This looks perfect, The getting Clojure book from that series has been a huge help
Hi guys, I'm trying to test some functions that are implementation of a protocol while stubbing other functions of the same protocol. The scenario is like the following:
(ns my.app.protocol.service)
(defprotocol Service
(foo? [service args]) ;; Predicate function.
(bar [service args]))
(ns my.app.impl.service)
(defrecord ServiceImpl [,,,]
(foo? [service args] (return-true-or-false))
(bar [service args]
(if (foo? service args)
(do-something-if-true)
(do-something-if-false))))
How can I stub foo?
while testing bar
? I've tried reify
ing foo?
and using with-redefs
but didn't manage to make it work. Any ideas? Thank you.Clojure 1.10.1
(defprotocol Foo
(pred [_])
(action [_ options]))
Foo
(action
(reify Foo
(pred [_ ] true)
(action [this options]
(if (pred this) :i-said-yes :i-said-no)))
{:dummy :options})
:i-said-yes
user=>
It almost did the trick for me. But I still need to call the actual action
, like this:
Foo
(action
(reify Foo
(pred [_ ] true)
(action [this options]
(actual-call-to-action options)
{:dummy :options})
since it is the function I want to test.@yokoyama.km This is why it is common practice to wrap protocol functions so that you can stub the wrapper instead. You cannot instrument
a protocol function either, so you have to use a wrapper function in order to leverage instrument
.
See, for example, https://github.com/seancorfield/next-jdbc/blob/develop/src/next/jdbc.clj where the API is all wrapper functions around calls to protocol functions -- a common pattern in Clojure.
Yes, you've already mentioned that, I'm sorry I didn't connect the dots. I'll try it. Thank you, @seancorfield
If you don't mind answering some questions:
1) For example, transact
is the wrapper around the -transact
function of the Transactable
protocol, right?
In tests I can then stub transact
by passing a reified transactable
(and I can even add instrumentation to transact
).
2) The clients that currently use the protocol's function directly (by passing it any valid implementation of the protocol) would switch
to use the wrapper instead, is it right?
No client code should use the protocol directly. The API is the wrapper functions (not the protocol).
You don't need to reify anything. You simply use with-redefs
on the wrapper, just as you would call instrument
on the wrapper.
In other words, the protocol becomes just an implementation detail: the wrapper function is all you should care about.
Any client that extends the protocol will still call it via the API (the wrapper).
In this particular case, you can make a proxy of sorts. Say you have an x
satisfying Service
, you can create a function taking that x
and reifying Service
and forwards all calls to x
but the ones you wish to stub. Not to undermine the advice Sean already gave you ^^
You say something like this?
(let [x (map->Service {})
stub (reify Service
(foo? [service args] true)
(bar [_ args] (protocol/bar x args)))])
Yes, something along those lines yeah
But when bar
of x
executes, it uses x
's implementation of foo?
not the one reified, right?
Uh right, yeah, my bad
Thank you anyway! 😄
can I pass a conditional into a threaded macro? I'm trying to do this:
->> data
(if (= "something" "something")
function-a
function-b)
print
I get the error Too many arguments to if
Are you trying to pass data
to function-a
and function-b
?
I think macroexpand
is your friend when you want to know what really happens in a macro:
user=> (macroexpand
macroexpand macroexpand-1
user=> (macroexpand '(->> data
#_=> (if (= "something" "something")
#_=> function-a
#_=> function-b)
#_=> print))
(print (if (= "something" "something") function-a function-b data))
ah I'm trying to pass data
to function-a
or function-b
, based on the conditional
good tip, thanks @UU9PM3M88 lemme poke around, yeah the result I want here is:
(print (if (= "something" "something") (function-a data) (function-b data))
Take a look at cond->
, maybe it can help
thank you, will do
But you can enclose your original if
form in another pair of parentheses and it will do the job (though it will be confusing):
(->>
{:a 1 :c 2}
((if true
(fn [d] (:a d))
(fn [d] (:b d))))) ;;=> 1
ended up with this:
->> data
(#(if (= "something" "something")
(function-a %)
(function-b %))
print
which seems to work, though I'm not sure if this is bad practice or not 😛this seems cleaner actually:
->> data
transform
print
and just put the conditional inside transform
(defn transform [x]
(if (= "something" "something")
(function-a x)
(function-b x)))
Much nicer! Well done. Yes, you can put ifs inline like you did but the mantra is "don't make me think"
Hello, I have a question about how to cleanly structure code in clojure coming from a Object Oriented background. Let's say I have two function f1 and f2. > f1 uses f1_auxA and f1_auxB. f1 is the only one to use them > f2 uses f2_auxA and f2_auxB. As for f1, f2 is the only one that uses f2_auxA and f2_auxB From what I understand I have to define all these functions in the same file. That's okay for me as long as there are not that many functions. However is there a way to structure the code so I can easilly know that f1_auxA and f2_auxB are only related to f1 and the same thing for f2? I understand I can put them in different files/namespaces, but it might lead to a lot of files for a big project. In OO I would just group related functions in the same class. Are other good practices that you use for this kind of purpose? Thank you for your feedbacks Rabie
there is no requirement of having things in the same file
you can use letfn
to make them only available in the parent function - (this is literally an inner class if you have heard of those, on the implementation end)
I would think of a namespace as equivalent to a package (this is how they compile, when you don't use the :gen-class
directive in the ns form)
the normal way of doing things in a lisp is to group functions by domain, and define them to use standard off the shelf data structures (like lists, vectors, sets, hash-maps)
also, the conventional wisdom is that privacy / data hiding is much less needed when all your values are immutable
our VM is OO, and implementation wise, literally speaking:
• functions are classes implementing clojure.lang.IFn which is "callable" via its .invoke
method. This is pretty much never done as the clojure compiler creates that invocation for you.
• our data structures are classes implementing java.lang.Collection with various interfaces providing extra features (java.util.Map, java.util.List, etc.)
• we don't use concrete inheritance unless forced to by someone else's API, we use interfaces to define code that can extend existing functions by implementing the methods they use
Oh great thanks for the detailed answer. I gues letfn is the answer to what I need because I need structuring but not to the extent of a package. If I understand correctly letfn it is a sort of local function the same way we define local variable with let. Right?
it defines 0 or more local functions that can mutually call one another
(this is important because normally in clojure bindings can't forward-reference things you have not defined yet)
there's also defn-
for functions that should have ns scope but are not meant to be used (and can't be used conventionally) outside the ns where they are defined
If you do not need earlier local functions to call later ones, you can also simply use let
Is there a channel to discuss clojure videos?
I am not aware of a channel specifically for discussing videos. I think it is reasonable to ask questions about the contents of Clojure videos in an otherwise appropriate channel for the topic.
e.g. if the Clojure video you want to discuss is about Clojure the language, and not-terribly-beginner-focused, then #clojure. If beginner-friendly, #beginners. If focused on some IDE or similar dev environment, then most of those have dedicated channels, e.g. #emacs #cursive #calva #chlorine
I've been looking without much luck for discussion about the suggestion in the docstring for empty?
:
dev=> (source empty?)
(defn empty?
"Returns true if coll has no items - same as (not (seq coll)).
Please use the idiom (seq x) rather than (not (empty? x))"
{:added "1.0"
:static true}
[coll] (not (seq coll)))
I understand why (seq x)
works, I've just found that it's easier to read (and thus easier for me to continue pushing adoption at work) to use some form of (empty? x)
. I see that using empty?
results in an additional call to not
, but are there any other reasons to prefer this idiom?the idiom of seq returning a falsey result for an empty input is considered core to the language
it enables direct translation of common-lisp code where an empty list compares false
so to some degree it could be called "historical reasons" from lisp history, but regardless, it's a lot easier to understand clojure if you internalize seq returning falsey for empty input
it's a similar to the reason behind a similar idiom in python, https://stackoverflow.com/questions/53513/how-do-i-check-if-a-list-is-empty
basically, what noisesmith said. seqs are core to clojure and conveying idiomatic usage and behavior of core parts of the language is useful
Sure, I am on board with that in principle. I'm choosing some battles in terms of style in order to make code approachable and this is one I'm willing to cede on, but wanted to make sure there wasn't some other reason behind it
imo, if using (not (empty? x))
helps you to sneak clojure in the door, then I'm all for it
@robertfrederickwarner nb. you can use not-empty
to get falsey on empty like seq gives, but not changing the data type if non-empty
(ins)user=> (seq "hi")
(\h \i)
(ins)user=> (defn foo [c] (or (not-empty c) :default))
#'user/foo
(ins)user=> (foo "hi")
"hi"
(cmd)user=> (foo "")
:default