Fork me on GitHub

I feel like im missing something that would explain this behaviour


(satisfies? B "foo")


yep that was it


(extends? B String)


How does the special form var resolve private symbols? Is something else used for resolving symbols that are used directly?


When you call functions or refer to global definitions normally (like (somefn a b c)), the compiler first resolves them to Vars and then emits proper invocation code. And in the compiler there is a check that the function/variable being used is not private.


When you do (var somefn) it indeed resolves differently, and on that path there is no such check.


Okay. Both of the mechanisms have to use namespace objects to do the resolution right?


Either the symbol being resolved is namespace-qualified (then, that it will be looked up in that namespace), otherwise *ns* will be used.


var resolves everything you give to it, including private symbols.


I have an old project that has a transitive dependency (via Immutant) that seems to have disappeared from the internet in the past few days: org.projectodd:polyglot-cache:jar:1.20.0


looks like it may have been hosted at which is now 404 ... anyone else seen this?


@taylor I used to work on Immutant. I'll ping my old team to see if that cloudbees account has been shut down


awesome, thanks!


If it is indeed dead, I'll see if I can get those artifacts deployed to maven central


thanks for your help


I looked at deploying polyglot to central, but the polyglot build depends on artifacts that were in that cloudbees forge :(


I'm currently tracking down and uploading all the missing deps to an internal repo. Looks like there were several missing deps besides polyglot too. FWIW this project is on Immutant 1.1.4


just got my build passing again. Thanks for looking into this again


Glad you got it figured out. Would you be willing to share a list of all of the artifacts you had to track down?


org/projectodd/polyglot-cache/1.20.0 (POM + JAR)
org/projectodd/polyglot-modules-parent/1.20.0 (POM only)
org/projectodd/polyglot/1.20.0 (POM only)
org/jboss/as/jboss-as-parent/7.2.x.slim.incremental.16/ (POM only)


Thanks! 7.2.x.slim.incremental.16 is what is preventing polyglot 1.20.0 from building for me

👍 4
Alex Miller (Clojure team)17:12:43

cloudbees just eol’ed some of their products this past weekend


I'm pondering the use of single-segment namespaces. In general, I know they are to be avoided. But as I'm moving to ns-qualified keys in all my data structures and as I'd like to use the :: reader syntax sugar, the keys in my data structures must correspond to namespaces. And I'm beginning to worry about the overhead — many extra characters per key are being stored in a database, exported, imported, moved over the wire, etc. I came here to listen for sage advice on the subject.

Dustin Getz20:12:10

My advice is to give up on auto-qualified data keywords. Basically, clojure package namespaces are for dependency tree-shaking, and data is global. So my current belief is that we cannot be using require and/or ns for data namespaces as there is no dependency graph. And unfortunately the auto-qualified keyword sugar is complected with these concerns, so we cannot use it from our data. This area I hope gets some design work in a future version of Clojure. Also note that the EDN reader doesn't understand auto-qualified symbols. Nor does Datomic


if you can find a design where there is some other context for keyword namespace aliases -- besides the Clojure ns -- maybe you could change the readers somehow...


I am starting to think that this context belongs at the RE{P,B}L


(don't change EDN, don't change clojure reader, just change the tools?)


@U09K620SG If you use spec (I do), you will still need to make sure the specs for your keywords are defined when you'd like to check them. A 1:1 mapping between data namespaces and Clojure namespaces helps with that.

Dustin Getz21:12:49

There are deeper issues in play, for example, namespaced keywords are universal (quoting conv with rich after the ions talk in nyc). That means a namespaced keyword is as good as a UUID and can be merged into a hashmap from some other universe without fear of collision. For this to be true, we would need some sort of resolution mechanism to route :db/ident's namespace :db to com.cognitect.datomic - e.g. a deps.edn for data


in my current fantasy, datomic would be patched to accept com.cognitect.datomic.db (or whatever), my files would contain that full namespace, but my tools would show me an abbreviation

Dustin Getz21:12:19

I like the idea of using the clojure reader for this, but complecting code packages with data packages is a problem


(though, I can still fantasize about tools without datomic being patched)


doing it in the reader seems wrong to me, after thinking about rich's message for 5 years 🙂


I considered the concept of a "nameplace" which we can declare and which collects namespace aliases, among other things. Then a Clojure ns has an associated nameplace, but this is just a special case. And some reader literal tag or something can be used to say "this data should be interpreted in that nameplace" (to deal with "object-at-a-time" in EDN)


but "nameplace" is not a word 🙂

Dustin Getz21:12:36

Can you give me an example of what the EDN should look like?


it shouldn't


that is wrong 🙂


for me though there is a question of how/whether/when tools should indicate abbreviation of the data on disk

Dustin Getz21:12:42

If the edn keyword namespaces are not aliased – which tooling layer do you mean this shoukd happen in?


editor, repl, etc

Dustin Getz21:12:17

Each tool needs to implement their own version of this?


there should be a convention for describing how to abbreviate by a data structure

Dustin Getz21:12:00

Alternately, if the EDN is assumed to be stored in datomic rather than text files, datomic query could be the tool with the sugar


hopefully parts of the code for actually doing it can be shared


I dunno, maybe there is something here the readers can do


if you have people writing .edn files in notepad who don't know they're using aliases, you have to do some weird things to be able to read anything while using aliases anywhere


e.g. read the edn with no handlers, walk the tree (and TaggedLiteral wrappers) doing the name translation you want, emit back to edn, read again with actual handlers


but I don't use notepad 🙂


(I suppose you don't need to emit back to EDN, you can just call the real handlers in a tree walk)

Dustin Getz22:12:41

this is crazy, but if all edn is stored in datomic, that means all edn has a schema. Lets also assume that spec and datomic schema are unified. Now any eav needs to be interpreted within the context of it's schema/spec, which means we need a registry from namespace to spec


I'm not sure what you mean about this because datomic doesn't even have an EDN value type 🙂

Dustin Getz22:12:27

and not a value type

Dustin Getz22:12:39

the attrs are already typed in datomic

Dustin Getz22:12:55

presumably that is eventually open to extension

Dustin Getz22:12:36

but all roads lead to any given edn blob needing to be interpreted relative to its spec

Dustin Getz22:12:55

which opens the door back to aliasing mechansim, resolvers, etc


datomic stores values/datoms/txs, not edn blobs


EDN is useful when we work with disks and wires for example

Dustin Getz22:12:34

datomic datoms become the universal protocol

Dustin Getz22:12:07

edn blob is isomorphic with datoms, it doesnt matter

Dustin Getz22:12:53

assuming the allowed value types are open to extension

Dustin Getz23:12:24

So you're kind of saying that, EDN is information and information is different from representation. It's the text/filesystem representation that needs sugar, which should be provided by the tool that renders the representation. In the pure form of data, the essence of it is always fully qualified and never ambiguous. That's why it belongs in the tooling layer. Do I understand?


I guess 🙂


btw, have you seen the reader resolver?


user> (binding [*reader-resolver* (reify clojure.lang.LispReader$Resolver
                                    (currentNS [_] (ns-name *ns*))
                                    (resolveVar [_ sym])
                                    (resolveAlias [_ sym]
                                         post }
                                    (resolveClass [_ sym]))]
        (read-string "#::blog{:posts [#::post{:title \"post1\"} #::post{:title \"post2\"}]}"))
#:{:posts [#:{:title "post1"} #:{:title "post2"}]}


however it only resolves aliases in symbols when it needs to, when syntax quote is used...

Dustin Getz17:12:01

thanks i hadn't

eccentric J17:12:32

Is it possible to invoke the clj CLI with multiple -m args?

Alex Miller (Clojure team)17:12:32

it’s possible to run a .clj script though that does anything you want

eccentric J18:12:22

Ah thanks! In theory, I should be able to make a library that launches an nrepl server, setups up rebl-nrepl middleware, cider, and maybe rebel-readline and reference that library in deps.edn with a :main-opts to run it succinctly right?


Did anything change between 1.10-RC5 and 1.10?


Excellent thank you


@jrychter both type of namespaces have separate concerns in my experience: whereas a ‘code namespace’ should never clash with any other library, data namespaces mostly don’t need that: {:video/id "YR5WdGrpoug"} is better than {:id "YR5WdGrpoug"}. I’ve also heard experiences that using :: turns renaming a namespace into a nightmare.


there are a lot of assumptions in the question about how data is going to be stored and transported as well


We’ve been using 1.10 in production for sometime now with the cognitect/aws-api and it’s been working great so far. Solved some illegal reflective access warnings on our upgrade to Java 11 from 8. Only thing that we had to change in our code were Java import statements (:import [java.util Date])) instead of (:import [java.util.Date]))

Alex Miller (Clojure team)17:12:59

yeah, the latter has never done anything and was never intended to be valid


Not a problem, was a simple fix for us. Better to be correct.


the "overhead" of keys in a database is largely going to depend on your database choice, and if you storing blobs of data in the database, or actually storing data in a way that the database can see


a sql database for example, usually already provides facilities for namespacing names (tables, schemas, etc)


(on top of the fact, of course, that sql databases don't store column names repeatedly like that anyway)


The overhead gets accumulated all over the place, and I'm beginning to get worried. Think of things like memory consumption on the ClojureScript side. It can be mitigated in some places (transit helps on the wire, for example), but overall it feels silly to add additional 9 characters to every key everywhere, unless there is a very good reason.


keywords(in clojure, and likely in clojurescript) are interned


@eval2020 Hmm, I'm not sure if using separate data namespaces is practical. I'd need to try it to be sure, but all spec examples assume your code namespaces correspond to your data namespaces and use the :: syntax.


:x/f is always an identical object to :x/f regardless of the source


using :: in examples is strictly to keep examples short, not because it is good practice


Hmm. The renaming effort is huge anyway, so I guess I might as well use separate "fictional" data namespaces and stop using the :: notation...


@eval2020 Yes, I did run into that. In most cases it turned out to be a signal for the need for code refactoring, but in certain cases it's unresolvable.


not only is it not required for keyword namespace names to match code namespace names, I think it is bad for them to do so


e.g. you don't name a database table after the code that touches it


data is data independent of the code that manipulates it


Right — but you lose the slightly nicer syntax, then. But I guess it's a reasonable price to pay.


the nicer syntax leads to brittle code too


you copy and paste code from one namespace to another then boom


I agree with hiredman: detach data ns-es from code.


Thank you for your time and advice — I am now looking at this closely and trying it out. Well, trying will take 2-3 days with the size of my codebase.


What's the landscape look like in 2018 if I want to develop a REST API using spec? I've seen compojure-api but are there any other libraries?


BTW, it doesn't have to be ring/compojure based


@trevor check out Works with ring, pedestal/interceptors and frontend.

👍 4

What would the difference be between reitit and compojure-api since I see a lot of similarities between the two


compojure-api is a concise, opinionated and monolithic macro-based dsl for the backend, #reitit is a data-driven, modular and open tool for end2end routing. Reitit has mostly all the features of c-api (and more). Concise vs Composable.


Been playing a little with Reitit to get to know it and been impressed.

eccentric J20:12:44

I wrote a small luminus web app with +reitit +re-frame for work. It was a really enjoyable experience once the concept of data-driven routing clicked. Especially when you see the same routing library used in cljs as clj and knowing you could easily share routes between them.


I'm definitely for anything that's data based especially routing. I guess I'll need to do some small prototypes to see which routing library best fits my needs

eccentric J18:12:36

How would one transform the string "#'user/msg" to the unevaluated literal #'user/msg?

eccentric J18:12:27

(read-string "#'user/msg") -> (var user/msg) which is not quite what I want


your repl is just being weird


(var user/msg) is a synonym for #'user/msg


(I assum you meant var there not val)

eccentric J18:12:23

Oh, good catch. Also I’ll try it but I’m working on some tooling middleware for nrepl so being able to show it as the target is actually important.


you are using clojure.edn/read-string


and the synonym of var and #' is only after evaluation

eccentric J18:12:11

Wait sorry, this is a moot problem now. The issue corrects itself when switching from nrepl “0.4.5” to “0.5.3". 😓


I use clojars in emacs to find deps ( M-x clojars), sometimes, but don't always find what I'm looking for... in the current moment are any of you able to pull it up that way... is there a better approach? I might be misusing the package... dunno.


all of the clojure contrib libraries are deployed to Maven Central, not Clojars


ah ok... so is there a way to find them from emacs? got used to the M-x clojars approach... or... how do you do it?


I also have seen several tools for adding the most recent dep version numbers if you type type the base name into your project.clj... but I usually get mixed up about when to use dot and / separators and have to look them up. #maybe-being-just-too-lazy


ok... the maven central site is pretty slick... that will work (although something from an editor would rock).


I feel like it would be great if we had an npm style tool you could search and add things to project.clj... as it is I flounder around on clojars, maven, etc and am never sure if I have a current version or not and it's a bit of a buzzkill when you're trying out deps. I'm sure it's all part of the adaptability of clojure which I may need to understand more.


I remember lein plz... I'll give that a go.


compojure-api is a concise, opinionated and monolithic macro-based dsl for the backend, #reitit is a data-driven, modular and open tool for end2end routing. Reitit has mostly all the features of c-api (and more). Concise vs Composable.


there’s also ataraxy if you like data-driven routing


Hi guys! I comming back to clojure and I would like to know if is there a good alternative to Intelij IDE?


many people are happy with emacs + CIDER or VS code + calva, in addition to the cursive plugin for Intellij

👍 4

no problem. there are channels for each if you have questions


#calva-dev #cider

Dustin Getz20:12:10

My advice is to give up on auto-qualified data keywords. Basically, clojure package namespaces are for dependency tree-shaking, and data is global. So my current belief is that we cannot be using require and/or ns for data namespaces as there is no dependency graph. And unfortunately the auto-qualified keyword sugar is complected with these concerns, so we cannot use it from our data. This area I hope gets some design work in a future version of Clojure. Also note that the EDN reader doesn't understand auto-qualified symbols. Nor does Datomic

Alex Miller (Clojure team)21:12:48

I’m still working on the 1.10 clj release

Alex Miller (Clojure team)21:12:31

technically, you can use any Clojure version, including 1.10, with the current version of clj, so it’s not really that important - it just affects your default if you don’t have a deps.edn


ok, I was just about to update our docker images where we use the linux installer to install the default version and noticed this

Alex Miller (Clojure team)21:12:08

brew pr is still pending for mac


thank you, much appreciated

eccentric J21:12:43

Awesome, thanks!


Hi - my understanding is that Clojure 1.10 has been released. Does a release apply to brew upgrade clojure on a mac?


$ brew upgrade clojure
Error: clojure already installed


@aaelony from above. it is pending


ah - thank-you.

Alex Miller (Clojure team)22:12:35

you don’t need an updated brew formula to use 1.10 though



Alex Miller (Clojure team)22:12:52

just add org.clojure/clojure {:mvn/version "1.10.0"} to your deps.edn to use it

Alex Miller (Clojure team)22:12:34

often takes 12-24 hrs to go through anyways


related question… I’m am very familiar with lein new myproject but about to try the deps.edn approach for the first time. Is the best resource? Is there a tool that does something analogous to lein new myproject?


awesome, I’ll read through it. Thank-you

Alex Miller (Clojure team)22:12:40

although the “template” for a deps.edn project involves almost nothing, so I do not find it to be necessary


my goal is to migrate off an amazonica project to… I haven’t experimented with deps.edn before however

Alex Miller (Clojure team)22:12:16

cool, feel free to ask questions in #aws if you get stuck - David watches that


excellent. thanks



clj -Sdeps '{:deps
                {:mvn/version "0.5.5"}}}' \
  -m clj-new.create \
  app \
just work out-of-the-box? I get a long stacktrace with no “caused by” clause


@aaelony It should just work, yes:

(! 507)-> mkdir aaelony

Mon Dec 17 15:17:08
(! 508)-> cd aaelony/

Mon Dec 17 15:17:10
(! 509)-> clj -Sdeps '{:deps
>               {seancorfield/clj-new
>                 {:mvn/version "0.5.5"}}}' \
>   -m clj-new.create \
>   app \
>   myname/myapp 
Downloading: seancorfield/clj-new/0.5.5/clj-new-0.5.5.pom from 
Downloading: seancorfield/clj-new/0.5.5/clj-new-0.5.5.jar from 
Generating a project called myapp based on the 'app' template.


@seancorfield, I filed a ticket. It doesn’t work as above for me


I don't know if it matters, but you have backslash at the end of most of the lines, but not the first two

eccentric J23:12:48

As of yet, there is no means to attach rebel-readline to an nrepl server right?


attaching it to an nrepl server doesn't make sense

eccentric J23:12:54

Could you please explain why?


readline is a user interaction facility


nrepl is client/server


Rebel could be a client.


the server doesn't interact with users


I disagree, I think it does make sense.


the server interacts with clients


Why couldn't rebel be a client?


then it would be just another client speaking the nrepl protocol


Yes, and...? 😁

eccentric J23:12:52

Then that means it could be run within a client?


It would convert user interaction to client?


nrepl server <-> nrepl client <-> readline

eccentric J23:12:13

Ok, thanks for breaking it down. Say I’m writing a small util to automate my repl experience. I’ve started an nrepl server and would like to start an interactive repl with it.

eccentric J23:12:50

Sounds like I need to connect to the server as a client and then inject the (rebel-readline/-main)


For now, yes


Rebel is extensible though. A nrepl client is feasible

eccentric J23:12:41

Ok, thanks for clarifying.

eccentric J23:12:06

I found this but after trying it I noticed they weren’t really speaking to each other

eccentric J00:12:07

Wait, I was wrong. They are speaking to each other!


@andy.fingerhut - I literally just copy pasted the example from the “Getting Started” part of the readme


What OS are you using?


got it. Looks like Sean may have diagnosed the root cause there.


It's an error in one of your existing deps.edn files.


I have no deps.edn… I’m seeking a skeleton like lein new myproject that yields a skeleton from nothing


you you run clj and get a repl?


check clj -Sdescribe


The stacktrace shows that tools.deps hits EOF while trying to read your existing deps.edn files. Either your system deps.edn file (unlikely) or your ~/.clojure/deps.edn file -- likely, if you've edited it.


looks like my clj is no longer working. It had been working before via brew


There may be some versioning issues…

$ brew install clojure
Warning: clojure is already installed and up-to-date
To reinstall, run `brew reinstall clojure


yeah - clojure installs fine via brew, but the clj command just stacktraces


Does rlwrap work at the command line? That should be the only difference between clojure and clj.


Also, check that the clj command you're picking up actually is the one from the CLI install -- you might have an old, unrelated clj command on your path?


first time trying to use clj


(! 510)-> which clj

Mon Dec 17 15:34:42
(! 511)-> which clojure

Mon Dec 17 15:34:46
(! 512)-> which rlwrap


I am removing it and re-starting with brew install



brew remove clojure
brew install clojure 
gives me a clj exectuable that stacktraces
Error building classpath. EOF while reading 
$ which clj


macOS High Sierra Version 10.13.6


back to lein for now…


What does clojure -Sdescribe show?


a long stacktrace


(this is just checking whether it's just your clj script that is broken or clojure as well)


not sure… is there a way to be sure all artifacts are gone (nothing cached) ?


Folks in #tools-deps would probably be keen to help you debug this as it should all "Just Work".


all in one line doesn’t appear to help


What does anyone think about this?

user=> (defn send-rockets! [] (println "BOOM!"))
user=> (comment {:a} (send-rockets!))
Syntax error reading source at (REPL:1:14).
Map literal must contain an even number of forms
Syntax error reading source at (REPL:1:31).
Unmatched delimiter: )


that behavior will depend on your repl


but in generally it is going to be hard to define a repl that does the right thing there


what repl are you using?


Figured as much. Would you say that such behavior is not set in stone, and custom REPLs are free to choose different behavior in such case?


that behavior is due to treating the input as a stream


This works the same in clj, rebel-readline, and nREPL


I am surprised that it does that in nrepl, what nrepl client?


but basically, because the input is malformed, it isn't like there is an easy way to determine where the malformed "form" ends


so it isn't like you can just skip past it in the stream


CIDER, but I guess that doesn't depend on the client, it seems like a default "eval" op behavior


it would depend on the nrepl client


because nrepl isn't stream based


Yep, so the form is sent in one message wholesale


hrrm, yeah, even from nrepl it would be tricky


the "right" thing there would be to skip all that input, but doing that is tricky


because the case for processing input is like a combination of completed form and newline


What's even more jarring is that this makes it harder to debug a stray odd-element map in the code since the actual cause gets obscured by totally weird and unrelated errors.


so don't use (comment ...)


and don't have top level effects


comment was just an example how a syntax error causes Clojure REPL to go execute things it had no business executing at that particular invocation; and it also produces alien error messages.

(defn foo [a b]
  (let [c {:a a :bb}]
    (println "Inside defn, why would I be called during compilation?")

clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Map literal must contain an even number of forms
             java.lang.RuntimeException: Map literal must contain an even number of forms
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Unmatched delimiter: ]
             java.lang.RuntimeException: Unmatched delimiter: ]
Inside defn, why would I be called during compilation?
clojure.lang.Compiler$CompilerException: Syntax error compiling at (script.clj:246:1).
             java.lang.RuntimeException: Unable to resolve symbol: c in this context
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Unmatched delimiter: )
             java.lang.RuntimeException: Unmatched delimiter: )
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Unmatched delimiter: )
             java.lang.RuntimeException: Unmatched delimiter: )


I get how this is a limitation of stream-based REPLs, but in the different case I'd say this should be avoided.

Dustin Getz23:12:28

it didnt evaluate it, it parsed it

Dustin Getz23:12:53

use ; comments if you dont want it to be parsed


> Inside defn, why would I be called during compilation?

Dustin Getz23:12:12

it is a parse error, not a compile error

Dustin Getz23:12:29

it is an invalid s expression in clojure


... which means it's perfectly reasonable to execute random parts of that invalid S-expression? I don't get what you trying to say.

Dustin Getz23:12:58

it is not being executed, it is being read

Dustin Getz23:12:09

REPL stands for Read Eval Print Loop. This is Read phase


it is being executed


No, it is being executed, because println triggers.


what is happening is the parser throws an error


the error is reported


then the repl goes back to the top of the repl loop


and reads from the input stream again

Dustin Getz23:12:05

oh, isee, that is wild, i am wrong


and the input stream's state is pointing at to the place just after where the error occurred


but a strategy to pass over malformed input is really hard, because by definition it is malformed

Dustin Getz23:12:15

File a ticket if you want

Alex Miller (Clojure team)23:12:28

No, don’t as this isn’t going change


@alexmiller Yup, I get that. Just trying to figure out if it makes sense to try to push such change to nREPL since it's message-oriented, and it seems easier to skip over the invalid input there.


Thanks for everyone's response, I will brew it in my head for a while longer.