This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-02
Channels
- # beginners (29)
- # cider (41)
- # clara (1)
- # cljs-dev (17)
- # cljsrn (1)
- # clojure (158)
- # clojure-dev (2)
- # clojure-dusseldorf (2)
- # clojure-italy (8)
- # clojure-mexico (1)
- # clojure-russia (2)
- # clojure-spec (43)
- # clojure-uk (1)
- # clojurescript (44)
- # community-development (98)
- # cursive (9)
- # data-science (8)
- # datascript (4)
- # datomic (30)
- # emacs (6)
- # fulcro (11)
- # graphql (6)
- # jobs (1)
- # jobs-discuss (27)
- # lein-figwheel (5)
- # luminus (13)
- # lumo (4)
- # off-topic (28)
- # onyx (9)
- # parinfer (12)
- # perun (2)
- # portkey (5)
- # re-frame (48)
- # ring (2)
- # shadow-cljs (52)
- # spacemacs (29)
- # tools-deps (15)
- # unrepl (9)
- # vim (7)
- # yada (3)
Bing suggests it's part of CounterClockWise...
Looking at RT.var, I think I can just replaced it with "clojure.core" (i.e. it wants a string that encodes a namespace)
Yes, it's just Java code calling Clojure's old API (via clojure.lang.RT
).
So it's (clojure.core/require ...)
and whatever the INITIALISE_NS_SYMBOL stuff is
Hmm, not CCW. It's ClojureUtils namespace doesn't have that constant.
1. I am trying to learn how to add a Clojure nrepl to an existing java application. 2. I created a blank Java app in IntelliJ. I added the Clojure 1.9.0 jar dependency from https://repo1.maven.org/maven2/org/clojure/clojure/1.9.0/ (by the way auto completion works, jar added successfully) 3. I have an application of the form:
package com.example;
import clojure.java.api.Clojure;
import clojure.lang.IFn;
public class MyRepl {
public static void main(String[] args) {
System.out.println("Hello World");
IFn require = Clojure.var("clojure.core", "require");
}
}
4. The above application, before the "IFN require" line, runs fine -- i.e. I got the "Hello World"
5. Now, when I try to run it with the "IFn require" line, I get an error concerning
Caused by: java.io.FileNotFoundException: Could not locate clojure/spec/alpha__init.class or clojure/spec/alpha.clj on classpath.
at clojure.lang.RT.load(RT.java:463)
at clojure.lang.RT.load(RT.java:426)
at clojure.core$load$fn__6548.invoke(core.clj:6046)
at clojure.core$load.invokeStatic(core.clj:6045)
What is going on here? I'm not using clojure spec. Is spec not part of the jar? Do I need to add another jar?Hmm, adding https://mvnrepository.com/artifact/org.clojure/spec.alpha/0.1.143 appears to have fixed it.
Normally if you have a build system (like Gradle), it’ll pull in those transitive dependencies.
@qqq According to http://search.maven.org/#artifactdetails%7Corg.clojure%7Cclojure%7C1.9.0%7Cjar you'll also need org.clojure/core.specs.alpha 0.1.24
(hopefully Gradle will pull that in too automatically)
@mv How are you starting Clojure?
Oh, wait, it's clojure.spec.alpha
(it was clojure.spec
very briefly when it was first introduced, but it's been clojure.spec.alpha
for a long time)
Well, 0.9.2
(and earlier) were based on prerelease builds of Clojure 1.9.0 so I expect that's where the clojure.spec
reference came from.
I suspect you need to do lein clean
@mv to clean up old dependencies
@seancorfield anything beyond lein clean
?
My deps:
[org.clojure/clojure "1.9.0"]
[io.pedestal/pedestal.service "0.5.3"]
[com.cognitect/pedestal.vase "0.9.3"]
Does anything in your code base require
clojure.spec
?
Looks like it’s already been updated in the template https://github.com/cognitect-labs/vase/blob/master/template/src/leiningen/new/vase/vase_service.edn
Hello, one question: how can I create a variable accesible on the whole file that is not computed at compile time ? Something like a http client that I provide credentials to instantiate an instance ?
@rdanielo write a function and call it when you need it? 🙂
That is what I do for most of the things, but I want the function to retain some defaults. Something like an instance on java or a closure on javascript
unless i’m misunderstanding you .. (defn make-thing [] (let [default 1] (Ctor. default)))
Works on clojurescript too ?
I'll check it out
Thanks
So, can I use this for creating some namespace-global defs that I can use across the entire file ?
Any examples ? The documentation is a bit... succinct
(def lazy-const (delay (expensive-work)))
… (do-something-with @lazy-const)
expensive-work
will only happen once, when lazy-const
is first deref’ed; @
is shorthand for (deref …)
.
Thank you. Is this the preferred way of doing this kind of stuff ?
For example, if you want to load some configs from a file, would you declare the fetched variables as delayed ?
is normal on clojure-land to return a map containing functions to be used ?
Clojure functions are first-class constructs. it's no stranger to return a map of functions than a map of strings or integers 🙂
Hello! Do any of you have advice on when it is best to use metadata over “explicit” data in a system? I find metadata a very tempting approach to track some things about how expressions flow through my system, but I am not sure whether it’s sensible
(I do realise my question is very project-specific, so you could interpret it as “have you used metadata to track X in your system, and how was your experience?“)
IMO, metadata should be used for "information about the program", ie. line and column numbers, which source file... IIRC tools.namespace uses it to track what has been reloaded
I get this error:
null
java.lang.ExceptionInInitializerError
at clojure.lang.Namespace.<init>(Namespace.java:34)
at clojure.lang.Namespace.findOrCreate(Namespace.java:176)
at clojure.lang.Var.intern(Var.java:148)
at clojure.java.api.Clojure.var(Clojure.java:82)
at clojure.java.api.Clojure.<clinit>(Clojure.java:96)
at MyRepl.actionPerformed(MyRepl.java:13)
at com.intellij.openapi.actionSystem.ex.ActionUtil$1.run(ActionUtil.java:220)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:237)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.lambda$actionPerformed$0(ActionMenuItem.java:301)
at com.intellij.openapi.wm.impl.FocusManagerImpl.runOnOwnContext(FocusManagerImpl.java:307)
at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.runOnOwnContext(IdeFocusManagerImpl.java:104)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.actionPerformed(ActionMenuItem.java:291)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem.lambda$fireActionPerformed$0(ActionMenuItem.java:111)
at com.intellij.openapi.application.TransactionGuardImpl.runSyncTransaction(TransactionGuardImpl.java:88)
at com.intellij.openapi.application.TransactionGuardImpl.lambda$submitTransaction$1(TransactionGuardImpl.java:111)
at com.intellij.openapi.application.TransactionGuardImpl.submitTransaction(TransactionGuardImpl.java:120)
when I try to load a clojure nrepl in an IntelliJ plugin action via:
import clojure.java.api.Clojure;
import clojure.lang.IFn;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
public class MyRepl extends AnAction {
public MyRepl() {
super ("Hello");
}
public void actionPerformed(AnActionEvent event) {
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("clojure.tools.nrepl.server"));
IFn server = Clojure.var("clojure.tools.nrepl.server", "start-server");
server.invoke(Clojure.read(":port"), Clojure.read("5555"));
}
}
This appears to be an issue with the way I'm trying to call Clojure from Java. Any idea what I am doing wrong?I'm writing a guide to teach new Clojurians how to deal with objects from Java-land, and am looking for accessible, dependency-free examples. Do you have examples of Java objects that have a completely obscure printed representation in the Clojure REPL? Preferably Java classes which purpose is easy to understand, and which are available in the JDK by default (no additional deps)
Best one have come up with so far is InputStream.
you can have the reader draw stuff in Graphics2D to show the interactions, and I'm pretty sure it comes with all JDK installations
java.awt.Color
java.util.TimeZone
java.util.Currency
@alexmiller the problem with all of those is that their .toString()
is still somewhat informative (e.g "java.awt.Point[x=12,y=23]"
- I'm really looking for a situation where the user gets nothing but the class name).
most “data” classes in Java will print some subset of their fields in the toString()
user=> (def pb (ProcessBuilder. ["ls"]))
#'user/pb
user=> (def p (.start pb))
#'user/p
user=> p
#object[java.lang.UNIXProcess 0x2eee3069 "[email protected]"]
many of the Java colls have print writers installed in Clojure so they will print like Clojure collections
if you don't mind non-objects, how about primitive int array? (it uses something like type descriptor which is pretty cryptic to the uninitiated)
that’s a good idea re printing, but probably bad if you subsequently want to show invoking methods / fields on it
Indeed
(def person {:name "Tom" :weight 120.1}) (def same-person {:name "Tom" :weight 120.1M}) (= person same-person) ;;yields false, because 120.1M is BigDecimal and 120.1 is a Double Does a macro, function, or special form already exist that compares maps and ignore value type for individual keys that are numeric?
although I guess that’s not deep
so, no :)
generally, I find any time you are trying to redefine deep equality, your path will end in sadness :)
better to avoid needing that in the first place
(reduce and (map = [1 2] [1 2 3 4]))
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and
@achikin try (every? identity (map ...))
No and
is a macro, and so it can't be used as a function
replacing and
with (fn [a b] (and a b))
would also work
@tbaldridge thank you!
is there a way to get clojure.tools.reader to run in "tokenization" mode instead of reading? so for example, suppose the string is (+ :a :b :c)
if we run the reader, we get back (+ :a :b :c)
as one sexp
what I want instead, is to get back, six different calls, of:
(
+
:a
:b
:c
)
I don't want to read the sexp and then call flatten; I want something that reads one token at a time
you want a lexer
not a reader
I know there are some out there in antlr or javacc
https://github.com/antlr/grammars-v4/blob/master/clojure/Clojure.g4 is one, not sure how complete it is
@alexmiller: I might try to repurpose ./tools.reader/src/main/clojure/clojure/tools/reader.clj:(defn- ^String read-token
@qqq there are parts of Clojure's syntax that are context sensitive. You're going to run into problems with that trying to write a tokenizer. It could be done, but you'd probably have to rewrite the entire parser from scratch.
But what's the point in doing this?
Hi everyone! I have a simple question: Are there any built-in solution to generate only the required keys of a map based on its spec or i always have to use custom generators with s/keys for this purpose?
nothing built-in
you could separate the req and opt parts of your spec though and use the full spec as the s/merge of those two sub specs with the generator from just the req spec
Does Clojure need the equivalent of CL packages? NS require clause juggling during new development is making me old. Just sayin.
Thank you Mr. Miller!
@hiskennyness how so? Some editors like Cursive do a lot of management for you. I can type str/starts-with?
and the IDE adds in the require for clojure.string
to my ns macro.
That's not hardcoded either, it works for user namespaces as well, sometimes with an additional tooltip prompt to make sure it pulls in the ns you want.
@tbaldridge how does it know that str
is short for clojure.string
?
For the clojure stuff I think it's hardcoded, at least it seems to be. For user namespaces it learns by looking at the rest of your code. So if you did [myapp.foo :as foo]
it will assume that naming in other parts of the app
Another good reason to not use core
as a namespace name 😄
cool that does work. what a neat feature. i’d love something that maintains my :refer
lists. i don’t think it does that.
Yeah, I wouldn't mind a go-lang-esque linter that sorts the :requires in a namespace
namespacing is a necessary feature but in some sense it’s a waste of life because 99.9% of the time there are no conflicts
@tbaldridge @lee.justin.m With cider + clj-refactor, I can do a cljr-sort-namespace
I think cursive will look at which namespaces provide e.g. starts-with?
function and then propose those and adds the require with the alias you used in code, (sdfsdfsdf/starts-with? ...)
should add [clojure.string :as sdfsdfsdf]
(but I didn't test this)
@lee.justin.m less namespaces perhaps? I think people split stuff up too much. I don't mind a files with > 2000 loc
< 200 loc in a file and it becomes a pain to manage
but a lot of that also depends on how modular the code is
yes @juhoteperi that’s interesting (and would be a good idea even if that’s not what it’s doing). the fact that cursive can just kind of figure it out is only possible because namespacing isn’t really necessary most of the time, and at most there are just a couple of choices
@tbaldridge yea agreed. i love having all my related react components in one file. i used to have a billion small files in javascript
@lee.justin.m no, I'd say it's because we very rarely rename namespaces differently across files, or have conflicts in short names. We'll more often do [my.app.core :as mac]
instead of [my.app.core :as core]
So if you index all the :as X
symbols there's only ever one or two back-refs.
that’s true, but I think it is likely also true that there’s only one starts-with?
in your code base
maybe? but that approach would be more error prone.
A lot of this also works with keywords, so if I do :my.app.foo/bar
and later refer to that namespace as :foo
it will suggest ::foo/bar
in other parts of the app.
That's something I don't think is possible at all with dynamic introspection repls, perhaps if you hooked into Clojure's KW registry?
hi all, I'm happy to announce Walkable, a new SQL library for Clojure: queries with Datomic pull syntax and pure Clojure filtering, configuration driven
please check it out, the README covers quite a few examples https://github.com/walkable-server/walkable
for those who've known about walkable: version 1.0.0-beta2 has just been deployed to clojars with the ability to use pseudo columns in filters
is there any way to perform a classpath-seq, much like file-seq? The only examples I'm finding seem to be assuming classpath locations are always on the fs, which isn't true.
It's always been a pain / haphazard to do this even in Java land ... the JDK doesn't provide this functionality, so you have to cobble it together from guesses and assumptions.
@tbaldridge Well, in a multi-file situation I am effectively redefining a package in every source. If we could bundle all that up as a package in one place I would be all set. Then in CLJS, I do not have :refer :all, so I really have to work. Minor gripe, mind you. Just doing a lot of new code the past week. Btw, yes, Cursive is nice when I need a new require altogether.
I'm glad you like it 🙂
@lee.justin.m @tbaldridge @hiskennyness Right, Cursive does that by looking at existing aliases in the code. There are no built-in defaults for core nses, but the examples also come from library code so someone always has clojure.string :as str
in there somewhere.
Also general ns
rewriting, although I’d like it to be general and cljc makes it hard.
@alexmiller @tbaldridge: so I'm implementing a new paredit-like editor. Now, suppose || = cursor, and we have
... ) || some-other-stuff
and we do a "word left" -- then I want the cursor to move left "by one tokeh" (i.e. a string, a number, a symbol, a regex, or a keyword)
for this and other things, if possible, I'd prefer to use tools.reader as a tokenizer instead of rolling my own regex
also, how is https://github.com/clojure/tools.reader/blob/3912dd1b13b842c31cd5c3b0d8f345da9e11ca20/src/main/clojure/clojure/tools/reader.clj#L51 context sensitive ?
well, that's how the reader is context sensitive (one way). probably not actually that function sorry
@qqq sure, that gives you tokens, but you don't know what those tokens mean. foo#
means something different inside a syntax quote.
It's a fairly well known issue, regexes are for "regular" languages (hence the name), Lisp is not a "regular" language
Same issue with XML, search for "parsing XML with regex" and you'll see a whole ton of articles talking about it (and how it's not possible)
@bfabry @tbaldridge: I think your argument is "this is not perfect" whereas my issue is "to implement apredit-like, I need some type of string -> ast, and using tools.reader seems better than regex"
no, my point is it won't work at all
tbh I was just saying "this is how the reader is context sensitive". I didn't read the context
esp if you want anything beyond highly mechanical formatting, and that's a problem since Clojure's indent rules are not even close to machine understandable, lol
and you're saying "ast", and that implies a context aware parser
@tbaldridge: in your definition of "won't work at all?", does emacs/paredit fall under "won't work at all" ? if yes ==> many people use it in practice if not ==> what do they do right?
looks like clojure mode builds context aware code on top of a text buffer
So I go back to my original statement, a token stream will get you tokens, but you'll have to rewrite most of the reader to do any sort of processing on that token stream
so it's probably much better to just write the whole thing from scratch. The Clojure reader isn't that bad, although it got 10x worse with reader conditionals, lol
or just run tools.reader on the entire file instead of one token at a time, but then there's issues of "what to do if the file is (due to editing) temporarily invalid clj"
yep, and that sort of parser is completely different
I can't find it now, but the Roslyn devs did a talk about that around 8 years ago, how a compiler parser and an editor parser are completely different and can't really be the same thing.