Fork me on GitHub

Could someone explain to me how do I tell that this function takes in 3 inputs? 😮

(require '[clojure.string :as string])

(def greetings
  (fnil string/replace "Nothing to replace" "Morning" "Evening"))

(greetings "Good Morning!" "Morning" "Evening") ;
;; "Good Evening!"
(greetings nil "Morning" "Evening")
;; "Nothing to replace"
(greetings "Good Morning!" nil "Evening")
;; "Good Evening!"

Ruy Valle03:08:15

The short answer is string/replace takes three inputs, and therefore greetings takes three inputs. fnil wraps the function it is given (in your case string/replace), returning a new function. This new function will pass along its arguments to the wrapped function, except it will replace nils in the first three arguments by the values provided when calling fnil. The function returned by fnil can take 2 or more inputs, but in your case it will fail if you give it any number of inputs other than 3, because string/replace takes exactly three arguments.

Ruy Valle03:08:12

user=> (greetings)
Execution error (ArityException) at user/eval9 (REPL:1).
Wrong number of args (0) passed to: clojure.core/fnil/fn--6902

user=> (greetings "a")
Execution error (ArityException) at user/eval11 (REPL:1).
Wrong number of args (1) passed to: clojure.core/fnil/fn--6902

user=> (greetings "a" "b")
Execution error (ArityException) at user/eval13 (REPL:1).
Wrong number of args (2) passed to: clojure.string/replace

user=> (greetings "Hello" "e" "u")
user=> (greetings "a" "b" "c" "d")
Execution error (ArityException) at user/eval20 (REPL:1).
Wrong number of args (4) passed to: clojure.string/replace

Ruy Valle03:08:48

notice Wrong number of args (…) passed to: clojure.core/fnil/fn--6902 (an anonymous function produced by fnil) vs. … passed to: clojure.string/replace


@zackteo Although Ruy already answered at length, one thing to remember is that you can (nearly) always see the source for library functions so you can see what is going on under the hood:

user=> (source fnil)
(defn fnil
... (shorter arities omitted)
  ([f x y z] ; <- this is how fnil is invoked in greetings...
   (fn ; ...and it returns a function of 2-or-more arguments:
     ([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
     ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c)))
     ([a b c & ds] (apply f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c) ds)))))
So we can see that greetings effectively has 2-arity, 3-arity, and 4+ arity implementations that will each call string/replace


As Ruy pointed out, if you try to call greetings with 0, 1, 2, or 4+ arguments, it will call the anonymous function returned by fnil, so for the 0 and 1 arity calls, it will fail because the returned function does not have that arity; for the 2, 3, and 4+ arities it will call f (i.e., string/replace) with the same number of arguments.

Pragyan Tripathi06:08:48

Hey Guys, I am trying send application configuration as an HTTP API response. In my case it looks like following:

(GET "/apps" []
      {:body {:com.vadelabs.bridge.profile/base
              {:com.vadelabs.bridge/project-ns '
               [#block/block []
                #block/block []]
              :com.vadelabs.bridge.profile/dev {}
              :com.vadelabs.bridge.profile/local {}
              :com.vadelabs.bridge.profile/prod {}
              :com.vadelabs.bridge.server/rest {}
              :com.vadelabs.bridge/logger {}}})
Now as soon as I added tagged literal #block/block The application starts failing with following error:
; Syntax error reading source at (com/vadelabs/studio/handler.clj:19:68).
; No reader function for tag block/block
Is there a way I can send these tagged literal to the client, The client would read it as per it’s implementation.


Hmmm... What are you trying to do? You may find it useful to use a templating thing like Selmer.

Anefu Favour09:08:37

Hello everyone, I'm trying to start a cljs project using shadow-cljs, but I keep getting Undertow Request Failed and OutOfMemory errors. I get the errors after I run npx shadow-cljs watch app, when I try to connect to the running server. Thank you!


if you don't get a response, you might also try #shadow-cljs


Thanks @seancorfield thanks - actually I thought for a moment you meant I could do something like (source greetings) thanks @ruyvalle too! Actually my mainly confusion was the six arguments. Like how this came to be ...

(greetings "Good Morning!" nil "Evening")
;; "Good Evening!"
But then I finally got why I was confused. I was thinking "Nothing to replace" "Morning" "Evening" were already arguments to string/replace but in actuality (greetings "Good Morning!" nil "Evening") just became (string/replace "Good Morning!" "Morning" "Evening") that was the part I was confused about. I understood what fnil was supposed to replace stuff when nil but it didn't click when I saw what I thought was 6 arguments with string/replace Thanks for your help!


Hi guys, I started to write a blog about my Clojure journey. More about it and the first post - about IDEs - here on reddit:

👍 6

Edit: SOLVED. Hey, I am newbie in clojure. I've installed OpenJDK 8 and clojure, leiningen. But when I run command lein repl and I've got this errors:

Could not find artifact nrepl:nrepl:jar:0.7.0 in central ()
Could not transfer artifact nrepl:nrepl:jar:0.7.0 from/to clojars (): 
Could not find artifact clojure-complete:clojure-complete:jar:0.2.5 in central ()
Could not transfer artifact clojure-complete:clojure-complete:jar:0.2.5 from/to clojars (): 
Failed to read artifact descriptor for nrepl:nrepl:jar:0.7.0
Failed to read artifact descriptor for clojure-complete:clojure-complete:jar:0.2.5
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
Could not resolve dependencies
Help me, please!

👍 3

What do you have in ~/.clojure/deps.edn ? 😮


;; The deps.edn file describes the information needed to build a classpath.
;; When using the `clojure` or `clj` script, there are several deps.edn files
;; that are combined:
;; - install-level
;; - user level (this file)
;; - project level (current directory when invoked)
;; For all attributes other than :paths, these config files are merged left to right.
;; Only the last :paths is kept and others are dropped.

  ;; Paths
  ;;   Directories in the current project to include in the classpath

  ;; :paths ["src"]

  ;; External dependencies
  ;; :deps {
  ;;   org.clojure/clojure {:mvn/version "1.10.1"}
  ;; }

  ;; Aliases
	;;   resolve-deps aliases (-R) affect dependency resolution, options:
	;;     :extra-deps - specifies extra deps to add to :deps
	;;     :override-deps - specifies a coordinate to use instead of that in :deps
	;;     :default-deps - specifies a coordinate to use for a lib if one isn't found
	;;   make-classpath aliases (-C) affect the classpath generation, options:
	;;     :extra-paths - vector of additional paths to add to the classpath
	;;     :classpath-overrides - map of lib to path that overrides the result of resolving deps

  ;; :aliases {
  ;;   :deps {:extra-deps {org.clojure/tools.deps.alpha {:mvn/version "0.8.677"}}}
  ;;   :test {:extra-paths ["test"]}
  ;; }

  ;; Provider attributes

  ;; :mvn/repos {
  ;;   "central" {:url ""}
  ;;   "clojars" {:url ""}
  ;; }


I'm not too sure about this exactly :x


What I see is that nrepl/nrepl 0.7.0 IS on clojars. So, not sure why lein is not able to pull it. FWIW, 0.8.0 seems to be the latest, but that does not appear to be your issue. Do you have a project.clj file? If so, can you share the contents? Is there a particular book or article you are trying to follow? It's Saturday morning in the US, there may be fewer folks around that can help.


And, clojure-complete version 0.2.5 is also on clojars. Oh, also do you have a ~/.lein/profiles.clj? If so, please share its contents as well.


@U0AT6MBUL No, I don't have ~/.lein/profiles.clj


@U0AT6MBUL I am following Getting Clojure, Russ Olsen book. P.S Also, I checked lein repl in created project (with lein app) and there are the same errors.


Looking at the errors messages a bit more closely, it says that it found nrepl, but could not transfer it from clojars. And same for clojure-complete.


So, maybe there is something preventing the transfer.


I don't know, it is useful info or not. OS: Ubuntu 20.04 Clojure: 1.10.1 Java: openjdk version "11.0.8" 2020-07-14 OpenJDK Runtime Environment (build 11.0.8+10-post-Ubuntu-0ubuntu120.04) OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)


It's been a while since I used lein so trying to remember if there is a verbose mode that would provide some more debugging info as to why the transfer is failing.


Also, what does lein version show?


Thanks for the system info.


lein version: Leiningen 2.9.4 on Java 11.0.8 OpenJDK 64-Bit Server VM


That looks up-to-date.


Also I tried on Java 8 and the same errors


I am guessing you have some permissions or connectivity issue.


Is there any way to give permits for lein?


Not sure what you mean. lein, by itself, does not need permissions.


Just trying some experiments myself here (on ubuntu 19.10)


What happens if you try clj? Or clj -Sverbose at the Ubuntu prompt?


This is just using the installed Clojure CLI, not lein, but just wanted to see if we can get that to work.


I got this message Please install rlwrap for command editing or use "clojure" instead. But, clojure works well.


Try sudo apt install rlwrap


Good that clojure works.


I did, clj works as clojure .


Okay. Now try the following


clj -Sdeps '{:deps {nrepl {:mvn/version "0.70"}}}'


At the ubuntu prompt.


Sorry. That was wrong.


clj -Sdeps '{:deps {nrepl {:mvn/version "0.7.0"}}}'


Does that download the nrepl library?


No, got errors.


Please share.


Error building classpath. Failed to read artifact descriptor for nrepl:nrepl:jar:0.7.0
org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for nrepl:nrepl:jar:0.7.0
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(
	at org.eclipse.aether.internal.impl.DefaultRepositorySystem.readArtifactDescriptor(
	at clojure.lang.MultiFn.invoke(
	at java.base/
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(
	at java.base/java.util.concurrent.ThreadPoolExecutor$
	at java.base/
Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact nrepl:nrepl:pom:0.7.0 from/to clojars (): : Temporary failure in name resolution
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(
	... 11 more
Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact nrepl:nrepl:pom:0.7.0 from/to clojars (): : Temporary failure in name resolution
	at org.eclipse.aether.connector.basic.ArtifactTransportListener.transferFailed(
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector$
	at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector$DirectExecutor.execute(
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector.get(
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(
	... 14 more
Caused by: : Temporary failure in name resolution
	at java.base/ Method)
	at java.base/$PlatformNameService.lookupAllHostAddr(
	at java.base/
	at java.base/$NameServiceAddresses.get(
	at java.base/
	at java.base/
	at java.base/
	at org.apache.http.impl.conn.SystemDefaultDnsResolver.resolve(
	at org.apache.http.impl.conn.DefaultClientConnectionOperator.resolveHostname(
	at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(
	at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(
	at org.apache.http.impl.client.DefaultRequestDirector.execute(
	at org.apache.http.impl.client.AbstractHttpClient.doExecute(
	at org.apache.http.impl.client.CloseableHttpClient.execute(
	at org.apache.http.impl.client.CloseableHttpClient.execute(
	at org.apache.http.impl.client.DecompressingHttpClient.execute(
	at org.eclipse.aether.transport.http.HttpTransporter.execute(
	at org.eclipse.aether.transport.http.HttpTransporter.implGet(
	at org.eclipse.aether.spi.connector.transport.AbstractTransporter.get(
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector$GetTaskRunner.runTask(
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector$
	... 19 more


Okay. That is a bit more infor : Temporary failure in name resolution


Can you get to via a web browser from that Ubuntu machine?


seems like your machine cannot resolve the name .


Yeah, exactly. I can't get to .


Can you get to some other well-known host (say ).


Yes I can. I did try use VPN in browser to get and now I can get it.


You seem to have a networking issue then.


Hmm... My internet provider blocks


That would explain things.


I am a bit surprised that the ISP is blocking clojars. Perhaps it is blocking http or https?


You said you used an VPN. Is that VPN on the browser or the Ubuntu host?


VPN on the browser


If you can set up a VPN on the Ubuntu host to get around the ISP block, you might be able to get it to work. Unfortunately, VPN on the browser will not help.


I guess, the only solution is use VPN on terminal.


Do you have access to an external http/https proxy that your ISP does not block?


No, I don't have access


Anyway, @U0AT6MBUL thanks a lot for helping me. Now, I see issue clearly.


Welcome. I will have to leave soon.


Hope you can get the VPN working.


Or convince your ISP to remove the clojars block.


Out of curiosity, how did you install clojure and lein? Via apt?


Can you get to github? If so, an option might be to download the nrepl (and clojure-complete) repos and then install locally into your ~/.m2/repository.


Sorry, I have to go now. Hope you can get the connection working.


SOLVED: It was internet issue, my Internet Provider blocks , so I used OpenVPN on Ubuntu and solved this issue. @U0AT6MBUL thanks a lot again.


Now I can start a journey in clojure world!

👏 6

So weird that clojars is being blocked by your ISP. Sorry I wasn't much help. But glad you got it working!

Alexander G13:08:00

Hello everyone! I want to write application that will handle many events, so I wanted to use vertx for that, but I see that vertx dropped clojure support after vertx2. What do you think, current ring infrastructure (with undertow beneath, maybe) can handle such type of load efficiently? Or maybe better to use java interop here and write with vertx?

Shuai Lin01:08:49

What's the scale of your application, and have you confirmed that a thread pool based solution (e.g. jetty) really won't make it?

Alexander G11:08:41

Is it really depends on a scale? I cant predict a scale upfront for this app, but I thought it is better to pick the right tool from the start, and to not rewrite after