Fork me on GitHub
#clojure
<
2021-10-12
>
kwladyka13:10:24

Do we have easy to use library to detect objects on screens (visual representation of image) and click mouse then? I am thinking about hobby software to solve specific puzzles on screen simulating human clicking mouse based on what see on the screen. But only and only if it will be not a rocket since to make it. Like if there is a library which can do the job about “parsing” a screen to know where to click 🙂 (this is NOT in web browser)

p-himik13:10:40

OpenCV would be my go-to solution in this case. It's been quite some time but IIRC you can even feed it an image of a thing you want to find, and it will be able to do that.

👍 1
kwladyka14:10:15

sounds good

Colin P. Hill14:10:27

Jargon question: if I’ve got a directory structure like

src/
  foo/
    bar.clj
    baz.clj
such that foo is a conceptual grouping of namespaces, but is not technically a namespace in itself (because there is no foo.clj)…what do we call foo, and how do we describe the relationship it has to the namespaces inside it? Java is happy to talk about “subpackages”, but I don’t know if I’ve ever seen this relationship described as “subnamespaces”

Alex Miller (Clojure team)14:10:49

it's not a thing in Clojure

Alex Miller (Clojure team)14:10:55

if anything you would describe "foo" as a "part" of the namespace name

Colin P. Hill15:10:17

I guess if I’m looking for something terse to say in documentation I could just say something like “namespace prefix”

Colin P. Hill15:10:45

The problem to be solved here is documenting the way the namespaces of an application are structured

didibus16:10:27

It's up to each application or library to come up with their own scheme for code organization and namespace organization. I would say generally the idiom, but that's purely a convention, is that you'd indicate some hierarchy using . as a separator. So you'll see things like: • reverse-domain.project-name.functionality-grouping-1 • reverse-domain.project-name.functionality-grouping-1-impl

didibus16:10:49

And you'll have as many of that as you need combination of functionality groups. Sometimes the -impl namespace is ommited if it's not needed, either in favor of private Vars, or maybe you don't need to pseudo-hide anything if the namespace is simple enough.

didibus16:10:30

I recommend reading this thread as well, and this describes what I often do personally: https://clojureverse.org/t/organizing-clojure-code-a-real-problem/7567/15?u=didibus

Colin P. Hill17:10:59

I think you have misunderstood what the question is. I am aware of the conventions around hierarchical organization. I have described a hypothetical hierarchical structure and asked about what terminology to use to describe it in documentation.

didibus03:10:30

Ah I see, just a naming issue. Could you use something similar to what I just did?

<reverse-domain>.<project-name>.<functionality-grouping>.<functionality-subgrouping>

Colin P. Hill13:10:08

??? no, that’s still not the issue. At this point I think I have to just encourage you to scroll up and reread what I’ve said, because I don’t know how else to frame the question.

Joshua Suskalo15:10:27

So for a little clarity, while the file structure that's used to represent namespaces is hierarchical, namespaces themselves are not. There is not required to be any relationship between foo.bar and foo.baz, and if you added a new namespace foo.bar.quux it doesn't need to be related to foo.bar. If you want to document how namespaces are structured, then maybe talk about "namespace name prefixes". e.g. "namespaces beginning with foo.bar are related to the bar component of the project foo"

Muhammad Hamza Chippa15:10:49

how to convert it into the form of [:ping "sasds"]

kwladyka15:10:01

(vals {:foo 1}) (first [1 2 3 4) (second [ 1 2 3 4]) :ping is first {: "fsdf"} is second and from second use vals for example, but how did you get such ugly data?

p-himik15:10:05

user=> {(keyword "") "abc"}
{: "abc"}

p-himik15:10:23

Of course, keyword should not be used in such scenarios.

Muhammad Hamza Chippa15:10:19

I am sending it as parameter it to the endpoint in such a way

Muhammad Hamza Chippa15:10:42

and dereferencing it at the end point where the endpoint is define like this

Muhammad Hamza Chippa15:10:14

(defn pong "Implementation of the /api/ping endpoint." [request] (response/ok {:ping (request :params)}))

p-himik15:10:01

And what does the ::pong event handler do?

Muhammad Hamza Chippa15:10:07

(rf/reg-event-db
 ::pong
 (fn [db [_ result]]
   (assoc db ::pong result)))
it is just registering the entry in database I guess

p-himik15:10:21

Not sure how that {:ping ...} became [:ping ...] - seems like you just expanded the map in the re-frame-10x viewer. Suggestion for the future - don't overzealously crop your screenshots. It's alright to send a few more pixels here and there, they can easily be important, like in this case. It seems that (request :params) just returns {"" "sasads"}. Why - I don't know. Probably something's not right with the way you send the request. Check the URL, check all the intermediate values.

Muhammad Hamza Chippa15:10:20

thank you brother let me work on it

Muhammad Hamza Chippa20:10:07

is there any way to integrate sql lite with clojure ?

Lennart Buit20:10:52

sure; you can use it with something like next.jdbc: https://github.com/seancorfield/next-jdbc

😀 1
dpsutton20:10:23

is there a good URI or URL class on the jvm that is a bit less strict about protocol? Parsing markdown and commonly people may use without a protocol. But a URI class considers "http://www.google.com" to be a relative link because there is no protocol. It would be nice if there was a class that could understand this even in the absence of a protocol

lukasz20:10:48

crazy idea: add it yourself? it's very unlikely would refer to anything but http right?

lukasz20:10:13

(I have to deal with stuff like that in our production code and that was the workaround, if protocol is missing we assume https)

dpsutton20:10:32

yeah i thought about that, but then i'm not technically sure if i should be adding https, adding http and hoping they have a rewrite rule, etc.

dpsutton20:10:59

and if i assume https, it is possible that that link fails

dpsutton20:10:26

so ideally i can let these links pass through without a protocol in the html generated from the markdown

dpsutton20:10:02

context: parsing markdown into html. need to add host when links are relative since these are emailed out.

lukasz20:10:38

Yeah, that depends on the context - we can always assume https in our applications, in your case.... given how the internet is changing and TLS is more and more widely available perhaps it's safe to assume that to be the default?

dpsutton20:10:11

i'm not sure

p-himik20:10:55

Links in HTML without a protocol will still be relative links. Even if they start with . Adding // in front will make them use the same protocol the main page uses.

dpsutton21:10:09

ah, well that works for me

vemv23:10:53

> is there a good URI or URL class on the jvm that is a bit less strict about protocol? https://github.com/michaelklishin/urly might help

qqq20:10:42

Besides Emacs/Cider, is there any open source project that rivals IntelliJ/Cursive ?

cfleming20:10:08

VSCode/Calva

👍 2
dpsutton21:10:11

I think clojure-lsp has to be mentioned here. It offers an open source version of the static analysis that makes Cursive so good.

cfleming21:10:46

Right, that basically underpins Calva if I understand correctly. I think there’s also a vim extension using it?

cfleming21:10:55

No, it doesn’t.

cfleming21:10:11

At least, I don’t think so, I haven’t actually tried it.

dpsutton21:10:14

ah good point. Calva was originally just cider's nrepl features in vs-code and they have integrated lsp really well. i forgot about that

cfleming21:10:26

I’m actually not sure if they’ve totally switched from cider to lsp, or if there’s still a bit of both, or if you can choose?

cfleming21:10:44

But I also think that lsp uses cider’s Orchard, right?

dpsutton21:10:05

no lsp does not use orchard. that's the smart bits of CIDER extracted for other client reuse

dpsutton21:10:00

lsp's guts are clj-kondo and clj-rewrite

qqq21:10:58

Is there any open source Intellij/* that uses either Clojure-LSP or Orchard ?

dpsutton21:10:48

can you restate that question? i'm not sure i follow

borkdude21:10:12

The static analysis in #lsp is provided by clj-kondo. The project supporting the refactorings is #rewrite-clj

qqq21:10:53

Is there any Clojure plugin for IntelliJ which uses either Clojure-LSP or Orchard as the backend ?

dpsutton21:10:06

not that i'm aware of

borkdude21:10:15

@U3JURM9B6 There are some people that have reported success with clojure-lsp in IntelliJ via the gtache lsp plugin (which doesn't seem to be maintained)

borkdude21:10:01

And you can also use clj-kondo separately via the file-watcher API or as an LSP server also via the gtache plugin

dpsutton21:10:21

there is a free or community tier of Cursive if you are interested. It's also quite worth its price tag if you find it useful and need to work on commercial products (i forget what the community license allows and disallows)?

qqq21:10:17

Interesting, intellij-lsp is only a few thousand lines of Scala / Java.

borkdude21:10:31

I think some people are doing this with Cursive and run clj-kondo separately inside of it. Btw @U0567Q30W if you ever want to offer people a way to integrate clj-kondo in Cursive itself (if that makes sense at all), my door is open :)

cfleming21:10:54

> i forget what the community license allows and disallows Disallows being paid for the work you’re doing, basically.

cfleming21:10:05

But the whole system is basically an honesty box.

cfleming21:10:24

I’ve thought about integrating clj-kondo in Cursive, but it’s tricky because the internal representations are so different. I’ll probably have to reimplement the checks as IntelliJ inspections. But I definitely think there’s scope for sharing documented logic, and perhaps tests.

borkdude21:10:12

One can use clj-kondo as a JVM library, run it over the currently edited file and it spits out findings with rows/cols that can just be rendered on the screen (I don't know the internal API of IntelliJ, I think this is just how the file watcher stuff works): I don't think there has to be a shared AST model.

borkdude21:10:29

We can discuss this in another thread if you'd like, I don't want to hijack the conversation more than I did already.

cfleming21:10:46

Right, but that doesn’t work very well with IntelliJ’s internals. Basically, there’s not much to be gained by doing it that way over just using LSP.

cfleming21:10:50

Good idea 🙂

qqq21:10:19

I started this thread; this is interesting discussion; I give you permission to hijack the thread to IntelliJ / clj-kondo refactorings.

borkdude21:10:47

ok, to clarify: clj-kondo just gives diagnostics and static analysis. lsp renders these diagnostics and uses the static analysis to provide navigation and refactoring features. it also does a bunch more: it will pass the entire project classpath to clj-kondo on the project startup so clj-kondo will analyze all dependencies. So the combination of these two becomes more user friendly, more like how you would expect things to work in e.g. Cursive

borkdude21:10:17

Navigation around Java classes is pretty much non-existent in clojure-lsp at this point, but being considered. IntelliJ + Cursive is a far better choice if you are interested in that aspect.

cfleming21:10:34

Ok, there might be scope to make that easier, yeah. There’s a thing called External Annotators in IntelliJ designed for this use case (running an external linting thing). I can investigate that and see if it would work.

❤️ 1
🙏 1
qqq21:10:13

Not to belittle clj-kondo's work, so it's basically an ultra smart linter + catch dumb 'static-type' errors (i.e. errors that a basic static type system would catch) ?

qqq21:10:20

Interesting, so IntelliJ itself provides great "jump to def of this JAVA function / class" -- the other missing piece, clojure-lsp provides "jump to def of this CLOJURE function / class" ?

qqq21:10:09

Ah, cool, I can now see how IntelliJ + paredit + clojure-lsp + clj-kondo provides the basics of a clojure IDE.

borkdude21:10:59

This is basically what Calva is for VSCode

borkdude21:10:27

(not to belittle Calva since it provides a bunch more)

qqq21:10:50

It frustrates me to no end that IntelliJ just doesn't have better Clojure-repl-scripting support (like Emacs/ELisp). I suspect a huge hurdle to entry right now is just the boiler plate required to setup an IntelliJ plugin.

cfleming22:10:41

I mean, you can set up a new IntelliJ plugin in literally 2 seconds these days using Gradle.

cfleming22:10:28

That’s not the hurdle - the hurdle is that IntelliJ is enormous, and figuring out how it all works is very hard. It’s getting better, but it’s not something you’ll just knock up in a weekend.

☝️ 1
dpsutton22:10:34

and its far nicer to give $100 to someone who has been creating such a lovely experience for years 🙂

❤️ 2
💯 2
cfleming22:10:49

It’s less work, certainly 🙂

👏 1
didibus16:10:20

@U3JURM9B6 To add to what others have said. I think we need to first talk about the REPL and Clojure's runtime introspection features. Using only a REPL and Clojure's introspection, you can figure out all functions in a namespace, their doc-string, their source, the arity and parameters to a function, the Vars in a namespace, the row/col of each form in the source, and other things like that. No IDE needed yet. This means Clojure on its own already provides IDE like features. Cider leverages that, by simply connecting a text editor to a Clojure REPL, and it just builds a UI on top of all this Clojure runtime introspection. The Orchard is a set of libraries that make connecting an editor to a REPL to leverage all this introspection features easier. It is used by Cider and Calva (and I think some others as well). So with only the standard Clojure features, you can add to your editor things like auto-complete, jump to definition, show doc, run tests, jump to error, macroexpand, list namespace vars/fns, etc. And since the editor connects to a REPL to get all this, it also allows you to integrate the REPL in the editor, and eval code from your editor into the REPL. But, because all of this depends on runtime introspection, it means that the source code must be loaded into the REPL for it to work. That means if your code does not compile, or has not been loaded in the REPL yet, those features won't work. This is the downside of using the Orchard, or basically leveraging Clojure itself for IDE features. This is where Cursive and clj-kondo differentiate themselves. They do not leverage the Clojure runtime introspection features. They instead analyze the source code themselves to try and provide similar features of code introspection, like what are all the vars and fns in a namespace, the doc-string, the row/col, etc. Thus they don't need the code to compile or be loaded into a REPL. Cursive and clojure-lsp or (plugging myself Anakondo) then leverage this static analysis inside an editor (or lsp server), to provide IDE features like auto-complete, jump to definition, etc. Cursive uses its own static analysis, while clojure-lsp and anakondo leverages the analysis of clj-kondo. clj-kondo can provide this analysis, but it can also lint the source for common errors or mistakes.

didibus16:10:36

> Ah, cool, I can now see how IntelliJ + paredit + clojure-lsp + clj-kondo provides the basics of a clojure IDE So to come back to this, actually, all you need to provide Clojure IDE features is Clojure itself, and by calling into a REPL from your editor, you can get all the runtime analysis you need for most IDE features. This is what Cider does for example. And it is also what Calva does (though Calva also uses clojure-lsp). It's simple, straightforward, and plays well into REPL-driven-development. If you don't want to rely on a repl workflow for your IDE features, then all you need is clj-kondo for basic clojure IDE features. It gives you all the analysis you need to do the same using static source code.

cfleming03:10:56

> by calling into a REPL from your editor, you can get all the runtime analysis you need for most IDE features. This isn’t really true. You can’t easily get any sort of Find Usages functionality without some sort of indexing, and without that you don’t get any related functionality such as global rename.

qqq05:10:13

@U0K064KQV: Thanks for the detailed write up on the IDE-like features that Clojure provides 'merely' by making the runtime introspective.

qqq05:10:43

@U0K064KQV Kind of funny, I was just thinking about smalltalk earlier today, and smallktalk basically takes this 'IDE' by making runtime introspective to the very extreme ?

didibus18:10:25

@U0567Q30W You got me! 😛 That's one of the feature not included in "most IDE features". You can still do a lot though with only a REPL, I think it qualifies as "most", I feel 2/3rd of all features can be implemented with only a REPL, but I guess it depends how many features you can think of haha

didibus18:10:37

@U3JURM9B6 I've never used Smalltalk, though always wanted to try, so I can't say how it compares with Clojure. I think one difference is that Smalltalk comes with its own IDE no? So I guess you could think of it as a REPL that would have a full GUI with file editing features inside maybe? That's just speculation on my part though. Assuming that's what Smalltalk does, there is something a little like this in Clojure: https://sekao.net/nightlight/

didibus18:10:17

And seems there's a new one based on VIM here: https://sekao.net/paravim/clj/

qqq21:10:53

Is there something like nrepl, but controls a cluster of machines instead of a single machine ?

val_waeselynck01:10:24

What would be the semantics of that? When evaluating an expression, on what machine would the result be computed, and the effects applied?

qqq02:10:45

You would manually specify the machine, something like (fun machine-id (fn [...] { ... }))

john15:10:31

You can achieve something like that with https://github.com/johnmn3/tau.alpha, via websockets, with some updates. Like (on client3 (println "hi from client 3"))

john15:10:07

Right now it just talks over webworker connections, but they use the same interface as websockets/postMessage.

john15:10:52

well, tau.alpha's current version uses SABs to communicate, but all the guts for pure postMessage comms is still in the guts of it