This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-17
Channels
- # adventofcode (76)
- # announcements (6)
- # beginners (103)
- # boot (28)
- # calva (128)
- # cider (48)
- # cljs-dev (40)
- # clojure (268)
- # clojure-austin (2)
- # clojure-dev (2)
- # clojure-europe (47)
- # clojure-italy (10)
- # clojure-nl (17)
- # clojure-spec (2)
- # clojure-uk (15)
- # clojurescript (45)
- # code-reviews (14)
- # cursive (5)
- # data-science (2)
- # datascript (1)
- # datomic (52)
- # duct (4)
- # emacs (2)
- # figwheel (1)
- # figwheel-main (4)
- # fulcro (13)
- # hyperfiddle (51)
- # leiningen (19)
- # nrepl (40)
- # off-topic (45)
- # pathom (3)
- # pedestal (28)
- # portkey (7)
- # re-frame (25)
- # reagent (76)
- # reitit (7)
- # shadow-cljs (92)
- # slack-help (3)
- # specter (5)
- # timbre (2)
- # tools-deps (39)
- # unrepl (1)
- # vim (13)
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.
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 https://repository-projectodd.forge.cloudbees.com/release 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
If it is indeed dead, I'll see if I can get those artifacts deployed to maven central
yeah, Forge seems gone https://support.cloudbees.com/hc/en-us/articles/360008971551-DEV-cloud-End-of-Life#servicesimpacted
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 ⌛
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
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.
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...
@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.
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
I like the idea of using the clojure reader for this, but complecting code packages with data packages is a problem
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)
Can you give me an example of what the EDN should look like?
for me though there is a question of how/whether/when tools should indicate abbreviation of the data on disk
If the edn keyword namespaces are not aliased – which tooling layer do you mean this shoukd happen in?
Each tool needs to implement their own version of this?
Alternately, if the EDN is assumed to be stored in datomic rather than text files, datomic query could be the tool with the sugar
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
hmmi see
(I suppose you don't need to emit back to EDN, you can just call the real handlers in a tree walk)
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 🙂
it could
and not a value type
the attrs are already typed in datomic
presumably that is eventually open to extension
but all roads lead to any given edn blob needing to be interpreted relative to its spec
which opens the door back to aliasing mechansim, resolvers, etc
datomic datoms become the universal protocol
edn blob is isomorphic with datoms, it doesnt matter
assuming the allowed value types are open to extension
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?
user> (binding [*reader-resolver* (reify clojure.lang.LispReader$Resolver
(currentNS [_] (ns-name *ns*))
(resolveVar [_ sym])
(resolveAlias [_ sym]
('{blog
post }
sym))
(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...
thanks i hadn't
it’s possible to run a .clj script though that does anything you want
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]))
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.
@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.
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...
@jrychter with spec you can run into circular references pretty easily: https://old.reddit.com/r/Clojure/comments/8ousfs/namespaced_keywords_question/
@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
Right — but you lose the slightly nicer syntax, then. But I guess it's a reasonable price to pay.
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?
@trevor check out https://github.com/metosin/reitit. Works with ring, pedestal/interceptors and frontend.
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.
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
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.
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 clojure.java.jdbc... are any of you able to pull it up that way... is there a better approach? I might be misusing the package... dunno.
I found https://github.com/clojure/java.jdbc on the web.
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.
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
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
@alexmiller fyi, these still point to clojure 1.9 https://clojure.org/guides/getting_started#_installation_on_linux
I’m still working on the 1.10 clj release
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
brew pr is still pending for mac
Hi - my understanding is that Clojure 1.10 has been released. Does a release apply to brew upgrade clojure on a mac?
you don’t need an updated brew formula to use 1.10 though
just add org.clojure/clojure {:mvn/version "1.10.0"}
to your deps.edn to use it
pr is https://github.com/Homebrew/homebrew-core/pull/35199 - brew prs seem to be backed up at the moment
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 https://clojure.org/guides/deps_and_cli the best resource? Is there a tool that does something analogous to lein new myproject?
many deps tools at https://github.com/clojure/tools.deps.alpha/wiki/Tools
specifically clj-new
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 com.cognitect.aws… I haven’t experimented with deps.edn before however
cool, feel free to ask questions in #aws if you get stuck - David watches that
should
clj -Sdeps '{:deps
{seancorfield/clj-new
{:mvn/version "0.5.5"}}}' \
-m clj-new.create \
app \
myname/myapp
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
(sean)-(jobs:0)-(~/clojure)
(! 508)-> cd aaelony/
Mon Dec 17 15:17:10
(sean)-(jobs:0)-(~/clojure/aaelony)
(! 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
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.
Sounds like I need to connect to the server as a client and then inject the (rebel-readline/-main)
I found this but after trying it I noticed they weren’t really speaking to each other https://gist.github.com/jmingtan/3886fd0ad6da53100f6c59be651c755d
@andy.fingerhut - I literally just copy pasted the example from the “Getting Started” part of the readme
What OS are you using?
I’m on a mac. More detail at https://github.com/seancorfield/clj-new/issues/17
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
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.
There may be some versioning issues…
$ brew install clojure
Warning: clojure 1.9.0.397 is already installed and up-to-date
To reinstall 1.9.0.397, run `brew reinstall clojure
`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?
(! 510)-> which clj
/usr/local/bin/clj
Mon Dec 17 15:34:42
(sean)-(jobs:0)-(~/clojure/aaelony)
(! 511)-> which clojure
/usr/local/bin/clojure
Mon Dec 17 15:34:46
(sean)-(jobs:0)-(~/clojure/aaelony)
(! 512)-> which rlwrap
/opt/local/bin/rlwrap
interestingly,
brew remove clojure
brew install clojure
gives me a clj
exectuable that stacktraces Error building classpath. EOF while reading
$ which clj
/usr/local/bin/clj
What does clojure -Sdescribe
show?
(this is just checking whether it's just your clj
script that is broken or clojure
as well)
Folks in #tools-deps would probably be keen to help you debug this as it should all "Just Work".
What does anyone think about this?
user=> (defn send-rockets! [] (println "BOOM!"))
#'user/send-rockets!
user=> (comment {:a} (send-rockets!))
Syntax error reading source at (REPL:1:14).
Map literal must contain an even number of forms
BOOM!
nil
Syntax error reading source at (REPL:1:31).
Unmatched delimiter: )
but in generally it is going to be hard to define a repl that does the right thing there
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?
but basically, because the input is malformed, it isn't like there is an easy way to determine where the malformed "form" ends
CIDER, but I guess that doesn't depend on the client, it seems like a default "eval" op behavior
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.
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?")
c))
clojure.lang.ExceptionInfo:
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.ExceptionInfo:
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.ExceptionInfo:
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Unmatched delimiter: )
java.lang.RuntimeException: Unmatched delimiter: )
clojure.lang.ExceptionInfo:
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.
it didnt evaluate it, it parsed it
use ; comments if you dont want it to be parsed
it is a parse error, not a compile error
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.
it is not being executed, it is being read
REPL stands for Read Eval Print Loop. This is Read phase
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
File a ticket if you want
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.