This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
There are some examples of numbered capture groups using re-find
on this page: https://clojuredocs.org/clojure.core/re-find
If you are trying to match things like "<some_string><other_thing><some_string>" where the second <some_string> is an identical sequence of characters as the first, that is a semi-special extension to regexes that some regex engines have, but others do not.
It is not a regular expression in the computer science automata theory class sense of a regular expression, which is one of the reasons it is a semi-special extension. I do not recall if the Java regex engine can do that or not, as I never venture that far from automata theory regexes.
If you find that the Java regex engine cannot do it, a parser for a larger kind of languages can be parsed using other libraries, like Instaparse: https://github.com/Engelberg/instaparse
According to the Java regex page https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html there is something called "Backreferences" that looks like it might be what you want.
Search on that page for both of "back references" and "backreferences" (with and without the space) to find all occurrences where it is mentioned
I have never used those before, so can't speak to their effectiveness in Java's regex engine.
And it looks like there are named capture groups
Which I have no idea what those do if you try to use one with Clojure's re-find
From a quick experiment at the REPL, it seems like re-find
returns the same thing on a match for named or unnamed capture groups:
user=> (re-find #"(?<foo>\S+)\s+(?<bar>\S+)" "the quick brown fox")
["the quick" "the" "quick"]
But the names might be nice if you have a complex enough regex that you want to use named back references and not have to keep count of them.
Cool. Sounds like you are off to the races, then.
Yeah, once you get outside of concatenation, alternation/or using |
, and +
and *
, not a whole lot is portable between different regex engines in different libraries/languages.
but most of them support a whole lot more than that, if you are willing to write them non-portably.
I'm trying to use https://github.com/HCADatalab/powderkeg #powderkeg because I like the design of it a lot, but it hasn't been maintained in a while, and I'm struggling even to get a fork to compile. I'm kind of a beginner, so I may just be missing something. the issues are all concerning this module "ouroboros", and I'm getting everything from "namespace not found" to complicated errors involving (proxy) overriding things it apparently shouldn't be, as well as "illegal reflective access operation". I don't know enough about Java interop and (proxy) to figure it out. Has anyone here had any similar issues? Is there a gotcha that I'm hitting? I'd really like to use this library, I love the way it uses transducers so it doesn't have to reimplement all of Spark.
Is "namespace not found" just lein repl's way of saying "something went wrong"?
"illegal reflective access operation" might be something you can ignore, assuming you are using JDK 9 or later, if they are warning messages: https://clojure.org/guides/faq#illegal_access
I'm using OpenJDK 13...
If you have easy access to OpenJDK 8, I have no idea if that would work better for the issues you are facing, but you should not get those particular warnings, and in general that version of the JDK is perhaps closer to the most commonly used one when that Clojure library was last actively maintained. Just a shot in the dark on my part there.
e.g. AdoptOpenJDK 8 is available for multiple OS's here: https://adoptopenjdk.net
They are likely to be only warnings that aren't the root cause of other issues, though.
I will try that. Something else of note: I'm now using io.aviso/pretty so I have a better error message: "java.lang.UnsupportedClassVersionError: powderkeg/Agent has been compiled by a more recent version of the Java Runtime (class file version 57.0), this version of the Java Runtime only recognizes class file versions up to 55.0"
55 is java 11, 57 is java 13, so I'll try Java 11
Although I don't understand where the inconsistency is coming from in the first place... still new to this.
I don't get this error in the lein REPL, only in the Cursive REPL
If a project uses Leiningen, the command lein clean
should remove any cached .class files that might contribute to that error, if you are switching between different JDK versions in your experiments.
If you still see it after doing lein clean
it is possible that perhaps some library you are using, or depending upon transitively through other projects, has precompiled .class files in it.
Looks like the problem was that Cursive was set up to use 11 and I had 13 installed.
io.aviso/pretty is a life saver ❤️
thanks for your help.
also yeah I did have to switch to 8.
no problem
Is there any kind of short circuit logic for comp
? e.g (comp int :number)
that would return nil instead of throw NPE when number does not exist on object?
What I’ve thought is to wrap the int coercer to allow & return nil in a custom int*
fn
Why do I get two zeros in a vector here? Is it because of the spec/and?
hmm no because:
Is there a way to log an argument which is a function? Printing it gives something like #object[user$square 0x4f20a5e0 "[email protected]"]
. I want the source instead.
In a REPL session, (source
will show the source code, if it was loaded from a file (i.e. not entered in the REPL)
I haven't tried that for logging, but you could give it a go and see what happens in a small experiment.
The short answer to the question above is, no
If you have a function object, that’s an opaque compiled function instance that is invoke Le but not much else
It is possible to demunge the class name of the instance and make something readable (demunge will not working in every case, but most)
https://clojure.github.io/clojure/clojure.repl-api.html#clojure.repl/demunge
If you want the actual expression that was compiled into the function instance you have, you can’t get that
I need to prepare some JSON files for my clojure app. They're loaded when the app starts and used as a in-memory database of sorts. Currently I created a Bash script that downloads a csv, converts to json, handles it with jq and does a couple more things with the data in a folder I called scripts
on my lein project root.
If I change it to a clj script, still in the scripts
folder i.e. not in the src
path, can I run it as a script like clj myscript.clj
or will my external libraries/dependencies not be loaded because I'm not using lein?
If you have a deps.edn file (or provide its contents on the clj
command line), you can specify directories to put on its class path, and what dependencies the program needs. Providing that on the clj
command line means that its contents can override/merge-with a deps.edn file in the directory where you run the clj
command.
is this good practice though? I would be using lein
and deps.edn
in the same project
If you and the people that use it can keep it straight how it works, and update it/fix things when needed, then I don't see a problem. A mention in a README for the project somewhere that "the main project uses Leiningen with the project.clj file, but this tools in scripts/foo uses this scripts/deps.edn file and must be run when your current directory is 'scripts'" (or whatever rules/conventions you want to establish that might be different than that merely-an-example-text), seem reasonable to me.
Leiningen will never read the deps.edn file (until and unless someone makes some special plug-in/add-on that does so), and clj
will ignore the contents of the project.clj file.
ok cool, thanks @U0CMVHBL2
Wow. This whole, “We’re going to fix your editor so that you don’t have to think about matching parens anymore” thing takes a bit of getting used to, but then it’s pretty awesome.
There are varying levels of editor behavior for that -- some like parinfer style things, others prefer merely showing matching parens, but you still type them yourself. I am in the latter camp, personally.
Yeah, it borders on the hostile but I’m going with it for now.
‘What do you mean you wont let me delete this paren!?!!?’
It doesn't bother me, if I can disable it in my editor 🙂
I’m also a big fan of stuff like black (for Python).
Some people would like to create something similar for Clojure, but I don't recall if they produced something that runs yet.
I find strict parens modes quite helpful. After getting used to it of course. For example, if I want to delete a line where all the paren endings are piled up, I can just do d d
(Emacs with evil, this will delete the whole line normally), the pile of parens are moved to the previous line.
Paredit takes some getting used to, but is really beneficial IMHO. You start thinking about your code structurally. Beware, writing non-LISPs may feel like smashing rocks together after this.
Hi, what does this mean? Reflection warning: ... 87:7 all to java.lang.Integer ctor can't be resolved.
?
Are you familiar with reflection warnings in Clojure in general, and are confused about this particular one? Or new to the idea of a reflection warning in general?
If new to reflection warnings in general, basically the Clojure compiler, when it sees Java interop forms, tries at compile time to determine what Java method or field is involved. Because Java allows one to define multiple methods with the same number of parameters, but different types of arguments, sometimes it cannot distinguish between multiple methods from what is in the program.
In this case, it will emit "reflection" code, meaning it uses the Java reflection API to find all matching methods at run time, look up the actual types of the arguments at run time, and pick which method to call, each time that call occurs during run time, which is much slower than if it could narrow it down to one possible method at compile time.
The message is a warning that performance may be bad for that call. It is not a correctness warning.
In many cases, there are ways to add "type hints" in Clojure source code that give the compiler enough clues to narrow down the number of possible methods to 1.
Thank you that is very helpful and clear. I am simply trying to convert a string to an integer.
it is proving quite problematic
Thanks! Your explanation helped me greatly and i was able to resolve the issue.
@sova Don’t use the Integer constructors, they’re deprecated in Java: use Integer/parseInt
Thank you @U050ECB92
@sova Don’t use the Integer constructors, they’re deprecated in Java: use Integer/parseInt
What's a good process for tracing/debugging code in a dependency? In Python, I could just go into my site-packages
directory where pip
installs packages and I could make edits to dependencies to add print
s and breakpoints. Is there a similar way to hack around in dependencies in Clojure/ClojureScript?
@ericihli If you're running your code from inside the REPL, with your editor connected, then you can edit the code in the dependencies (assuming you've cloned them locally), and evaluate it into the running REPL, with your debugging changes in place.
> assuming you've cloned them locally
Right now all my dependencies are as .jar files in an m2/repository
directory. I'm trying to figure out how to point to a dependency that is a local directory, like a git repo.
In the scenario I described, you don't need the dependencies changed from the JARs. You just edit the source (elsewhere) and eval it into the running program.
It's the same as editing code and eval'ing it into a live, running, production process 🙂 No need to restart the process or anything. The changes only hold while the process is running.