What is the Clojure equivalent of Python’s Iterable? For example say I wanted to implement “paging” in a REST API client. So that the next result set is loaded once you are at the end of a page?
Maybe I'm not familiar with Python, and think that its iterables and other stuff cames from the point, that we prefer ORM than raw database queries? F.e. we have just simple sql queries with limit&offset, and make next http (and therefore sql) query on each page. Why it needed to do some more complex than it?
clojure.core/lazy-seq
or clojure.core/iterate
are decent options for implementing such a thing. ghadi also wrote a patch to add a function called iteration
that might make it into clojure.core some day
Thank you
Lazy seqs are sort of the classic approach people have used for that kind of thing since the initial release of clojure, but lazy seqs have inherent problems managing things like connection state
https://ce2144dc-f7c9-4f54-8fb6-7321a4c318db.s3.amazonaws.com/reducers.html is a at this point dated screed about using reduce based things instead, specifically there reducers, but there are core protocols and interfaces for defining reducible things
https://gist.github.com/hiredman/4d8bf007ba7897f11594 unfold or something like it is what I like for this kind of thing, and it is a similar kind of thing that what those patches might add to core some day
Wait, @hiredman. I didn’t know we were only one degree apart! I worked w/ Joe Gallo at Elastic for a minute.
A lot of the "past and present co-workers" from the time that was written ended up at elastic after sonian
that’s what I hear 🙂
@st3fan java.lang.Iterable and java.lang.Iterator, basically. lazy-seqs and whatnot are a convenient way to implement those interfaces, but have drawbacks around chunking and resources that might end up "closed" when you leave the context the lazy-seq was created in. You can always reify an Iterator directly with whatever internal state you need if those drawbacks apply to you. Something that isn't equivalent, but can accomplish the same goal would be reducible things. Defining and using a reducible would probably lead to more idiomatic code, depending on what you are doing. https://juxt.pro/blog/ontheflycollections-with-reducible
Hi how do we remove table name from jdbc responses? I am using postgres.
accounts/email: "email",
accounts/created_on: "2020-09-20T09:33:23Z",
accounts/last_login: "2020-09-20T09:33:23Z"
I want to just get
email: "email",
created_on: "2020-09-20T09:33:23Z",
last_login: "2020-09-20T09:33:23Z"
what library are you using? next.jdbc?
Hi there !! I have recently written a clojure app using lein + compojure + clj-http and created an uberjar. Now wondering if i can enable the nrepl on the built jar file? Something like - having an api endpoint to start/stop nrepl inside the uberjar. That will help me debug issue in the built jar file when it interacts with test data. P.S.: I am doing this in my UAT environment debugging and Production will be getting rid of this (security concerns).
Yes, by adding code to your app that starts an nrepl server when you hit your api endpoint and then connecting to that nrepl server with your local client. https://nrepl.org/nrepl/usage/server.html#embedding-nrepl
thanks @rutledgepaulv i am trying that only currently.
it is stuck in compiling while running lein uberjar
Is it possible to use something like with-redefs
except swapping out entire namespace definitions?
following is how code looks like - one route added to call the start-nrepl method
Hi! Is there something like add-watch
on the namespace level, so that I can subscribe to when vars on a namespace are added / changed, etc?
cljsrn seems abandoned
anyone can point me to a more updated resource on making ios apps with clojure?
Follow-up: Can I watch for redefinitions with (def ...)
? add-watch
seems to pick up only redefinitions with alter-var-root
. I assume that's because def creates a new var instead of changing the previous var.
@danieltanfh95 perhaps Krell: https://github.com/vouch-opensource/krell
found the silly mistake in my code (calling (start-server server)
and (defonce server)
also contained the same command 😞 . Fixed it now and able to do it.
@teodorlu it works! 🎉
Great!
spend way too much time finding one that works
thanks!
1. I do lein new test-project
, create a file src/user.clj
with content
(ns user
(:require [clojure.java.shell :refer [sh]]))
(sh "ls")
2. Now when I do lein repl
, it hangs on the sh
call. If I remove the call and just do (sh "ls")
in the repl, it works fine. Why?3. If the :init-ns
is set to user2
and the file above is changed to be user2
ns, it doesn't hang anymore.
I tried reproducing the hanging behavior following the steps you gave above, but do not get any hanging behavior. Nor does it load that namespace named user
, either, when I do lein repl
. I am using this version of Leiningen and JDK, in case that might make any difference:
$ lein version
Leiningen 2.9.3 on Java 1.8.0_192 Java HotSpot(TM) 64-Bit Server VM
Actually, I guess it does load that namespace named user
, but it is not obvious because (sh "ls")
does not print anything. If I change it to (println (sh "ls"))
, then run lein repl
, it does print the return value before starting the REPL.
Updating clojure from 1.10.0 to 1.10.1 fixed this!
Hmm. I was testing with Clojure 1.10.1. There were some changes in Clojure 1.10.1 to fix some bad performance issues with loading user.clj
with some JDK versions: https://github.com/clojure/clojure/blob/master/changes.md#11-workaround-java-performance-regression-when-loading-userclj
I am using OpenJDK 14, which is not mentioned there. I also had a problem before with cognitect's aws library where it would hang if loaded from the namespace, but worked ok if loaded from a function after startup, I guess that's the same problem.
Hey folks, is it possible to generatively define functions in a given namespace? For example, I have a function (defn createNode [type props] ...dostuff...)
and for a known set of types, I would like to create aliases in my namespace. That is, I might write (createNode "myNode" {:hi "bye"})
, but I would like to alias (myproj/myNode {:hi "bye"})
to invoke the previous form. I have a list of these types... "myNode, myOtherNode, coolNode," etc
Sketching out what I'm imagining...
(doseq [i ["myNode" "myOtherNode" "coolNode"]]
(make-alias i (fn [props] (createNode i props))))
I imagine a macro could do this?
If a change from Clojure 1.10.0 to 1.10.1 makes a difference, and it is is code in a file named user.clj in your classpath, then likely it is the performance issue I linked to. JDK 14 wasn't explicitly mentioned there at the text I linked to, probably because it wasn't released yet at the time the note was written. I would expect that if the issue exists in JDK 11, 12, and 13, it is likely to be common JDK code that interacts poorly with Clojure 1.10.0 that continues on into JDK 14 and probably later versions, too.
Yeah, makes sense.
Thank you!
I think you are looking for intern
: https://clojuredocs.org/clojure.core/intern
It should be (intern 'myproj (symbol i) (fn [props] ...))
.
Found thanks to hugsql, it generates functions from an sql-like file, and fills a namespace with them. https://github.com/layerware/hugsql/blob/master/hugsql-core/src/hugsql/core.clj#L500
yesss thanks @posobin!
@posobin you should try babashka maybe.
This interop with sh is not my primary goal, one of the libraries I am using was preventing the repl from starting and I tried to find the reason why.
Hello everyone, started learning clojure a few weeks ago, can I pick someone's mind on a project I'm working on?
@emccue are you familiar with the Magic: the Gathering TCG?
yep
(more into yugioh, but I've played magic a few times)
so, I'm building a MTG compiler
it reads through the card text and generates clojure code to be executed later by a rules engine
i have a parser that reads though the text and generates a Parse tree
then I traverse that parse tree to generate code
each node of the parse tree is represented by an object of class Parser$<RuleName>
so I created a "visit" multimethod that dispatches on the class of the node being visited
created a few convenience macros as well
for example, here's the part that generates code for an effect that applies to a game object
(defrules
effectObjectEffect `(~@(visit-rule objectEffect) ~(visit-rule object)))
my plan is to then later either AOT compile the generated code
or have it interpreted by the game engine
(or both, that will probably be the case)
hmm
so, generally speaking you will have a better time if you design a data structure to represent the parsed effects
and then have a function interpreret that data structure
than generating code in macro
its usually an antipattern to do a defthing macro
there are a lot of side benefits - being able to test your code and maybe even persist parsed rules to a file
but generally speaking "data structure describing complex behavior" is preferred over "object which encapsulates complex behavior"
well, in this case I wanted to take advantage of the "code = data" property of lisps
the code itself is a data structure that represents the parsed effect
and the interpreter is the JVM itself
how is that different from outputting maps (for example) and having an interpreter execute that
also why would this approach prevent me from doing any of the things you said (testing, persisting rules)?
I know it might sound like I made up my mind already, but I really want to understand if and why I might be looking at this the wrong way
maybe I didn't explain myself correctly
I'm not outputting the game engine logic itself
for example, if an effect is "Destroy target creature" the generated code might be something like (destroy (target {:type :creature}))
then in my game engine I'll implement the destroy
and target
functions that do their thing on the game state
also another advantage is that I'm able to get some static analysis on the generated code because I'm referencing functions from the game engine
also code suggestion/documentation in the IDE
Hmm, so for the testing bit (sorry for the late response)
if your rules are just a data structure, you can test your parsing logic via just (is (= (parse-card text) {:destroy {:target {:type :creature}}}
you can reasonably macro expand and test code is what you expect as well, but its harder to test a "slice" of it, partially by the linked-listedness of generated code but also because it can be pretty fragile to changes
you are right that you can potentially generate, dump, and load+eval code though - I didn't consider that seriously enough
so if security isn't an issue then it would probably work - it just is a large surface area for code injection
yup its next.jdbc