clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
jumar 2021-02-22T05:36:35.021800Z

Is there a way to make Clojure/REPL automatically recognize tagged data literals like joda time DateTime objects? I have a collection of maps like this which I can dump in stdout and want to copy paste and read elsewhere (e.g. in my unit tests).

[{:started-at #object[org.joda.time.DateTime 0x45879b4a "2021-02-19T04:55:14.000Z"],
  :ended-at #object[org.joda.time.DateTime 0x5f60296a "2021-02-19T06:25:26.000Z"]}
  ,,,]

2021-02-22T10:23:23.024100Z

fyi here is a lib to do this for java.time objects https://github.com/henryw374/time-literals

👍 1
jumar 2021-02-22T10:59:26.024500Z

@henryw374 Cool, thanks!

jumar 2021-02-22T05:38:35.021900Z

Currently it fails with No reader function for tag object . It would be great if it could automatically read those objects ad DateTime instances since joda-time is on classpath.

2021-02-22T05:40:51.022100Z

What I would do is install a print-method for kids time dates to print as #inst literals

jumar 2021-02-22T05:50:02.022500Z

Perfect, thanks!

alexmiller 2021-02-22T06:00:03.022700Z

you can actually do better than that if you like

alexmiller 2021-02-22T06:00:38.022900Z

oh nvm, you've got all the pieces there

alexmiller 2021-02-22T06:01:34.023100Z

the one thing you might also want is to extend the Inst protocol to these types

alexmiller 2021-02-22T06:02:09.023300Z

that would make inst? and inst-ms work for them too

👍 2
lambdam 2021-02-22T13:44:11.029Z

Hello, I'm trying to pretty print the report of a Datomic transaction but the :tx-data entry prints on a single line :

{:db-before datomic.db.Db@a151f72f,
 :db-after datomic.db.Db@9d6a8eca,
 :tx-data
 [#datom[13194139564015 50 #inst "2021-02-22T13:40:49.287-00:00" 13194139564015 true] #datom[17592186072237 106 "Foo BAR" 13194139564015 true] #datom[17592186072237 106 "Old name" 13194139564015 false]],
 :tempids {}}
When I convert every datom into a string, it wraps correctly:
{:db-before datomic.db.Db@a151f72f,
 :db-after datomic.db.Db@eb370c84,
 :tx-data
 ["#datom[13194139564015 50 #inst \"2021-02-22T13:21:08.348-00:00\" 13194139564015 true]"
  "#datom[17592186072237 106 \"Foo BAR\" 13194139564015 true]"
  "#datom[17592186072237 106 \"Old name\" 13194139564015 false]"],
 :tempids {}}
I digged into the source code of pprint but it is quite hard to understand. Is there a simple way to make pprint wrap lines for datoms (or any class)? Thanks

ghadi 2021-02-22T13:54:07.029100Z

what are you calling to pretty print?

lambdam 2021-02-22T14:29:15.029300Z

I tried

(clojure.pprint/write tx-data :stream nil)
and
(-> tx-data clojure.pprint/pprint with-out-str)

Ramon Rios 2021-02-22T18:02:06.032Z

Did someone recomends a lib to deal with responses pagination?

jumar 2021-02-24T04:57:06.112700Z

I noticed that there's CollReduce protocol but the functions use IReduceInit - I guess the main reason is performance? https://groups.google.com/u/1/g/clojure-dev/c/SNGLEJ4POnw

2021-02-24T05:16:33.112900Z

There are some java odds and ends (I think particular the implementation of range) that need to supply a custom reduce

2021-02-24T05:18:30.113100Z

CollReduce being a protocol, it does generate an interface, but in the clojure build process the java bits are compiled first, so it is kind of a bootstrapping issue

👍 1
2021-02-22T18:11:02.033200Z

if you mean unpaginating api responses, this is the basic pattern I use https://gist.github.com/hiredman/022e617e37f9c5622e1a943a5c34afe5#file-scratch-clj-L1-L18 I've written a lot of different versions of that. that particular unfold doesn't create a lazy seq

pez 2021-02-22T18:11:25.033500Z

Is it correct to describe a predicate like so? > a function that takes one argument, treating it as an expression to test for truth

pez 2021-02-22T18:12:02.033600Z

(I’m writing a Clojure tutorial and don’t want to be spreading lies.)

2021-02-22T18:12:07.033800Z

there is also a ticket to add similar functionality to core https://clojure.atlassian.net/browse/CLJ-2555 which supersedes an older ticket with more of a write up and commentary on it https://clojure.atlassian.net/browse/CLJ-1906

2021-02-22T18:14:16.034500Z

a predicate is a function whose result you can use if to do case analysis on

pez 2021-02-22T18:14:53.034600Z

Assuming it is an OK description, what do we call functions that takes predicates and returning booleans themselves? (Like every?)

pez 2021-02-22T18:17:01.034800Z

@hiredman: > a predicate is a function whose result you can use `if` to do case analysis on That would make every? a predicate too, but you can’t send that to function which advertise that they take a predicate as an argument, can you?

2021-02-22T18:17:21.035Z

why not?

seancorfield 2021-02-22T18:18:38.035200Z

It may perhaps be important to distinguish between "functions that can be used as predicates" (anything that returns truthy/falsey) and the stricter sense of predicate: "functions, whose name ends in ?, that return either true or false". (the Clojure core folks have been pretty careful to ensure that distinction in the "standard" functions)

seancorfield 2021-02-22T18:19:04.035400Z

But I think it is reasonable to consider "predicates" restricted to a single argument that they test, yes.

seancorfield 2021-02-22T18:20:36.035600Z

every? is a function that returns strictly true or false but I would not consider it a predicate directly, since it takes two arguments. But this does make me wonder whether http://clojure.org has something specific to say about this...

2021-02-22T18:20:52.035800Z

the term predicate comes to programming from logic, where the number of arguments passed is not restricted to one, although it may be more common to call predicates in logic that have multiple inputs relations (but outside of logic programming no one in programming calls those relations)

pez 2021-02-22T18:22:00.036Z

I’m not writing a logic tutorial, though. 😃

seancorfield 2021-02-22T18:23:17.036200Z

"The contains? function is a predicate for checking containment." -- that's in the hashed_colls guide -- so that consider a two-argument function a predicate 👀

pez 2021-02-22T18:23:55.036400Z

And the docstring for filter does not say that it takes a predicate, but rather (pred item)….

seancorfield 2021-02-22T18:25:40.036700Z

The contrib how to (style guide) says pred - a predicate closure is a common short name for an argument.

dpsutton 2021-02-22T18:25:55.036900Z

this feels like a place where being really "correct" would be quite the detriment to the beginner readers of your article

seancorfield 2021-02-22T18:26:10.037100Z

The lisps page on http://clojure.org refers to = as "the equality predicate"

dpsutton 2021-02-22T18:26:23.037300Z

most domains aren't "technically correct" for quite a while (if ever) and still build up teaching and predicting models

pez 2021-02-22T18:26:30.037500Z

@dpsutton Yeah, I am actually aiming for not being full out incorrect. 😃

seancorfield 2021-02-22T18:26:31.037700Z

So there's definitely precedent there for a predicate not being just a unary function.

dpsutton 2021-02-22T18:26:41.037900Z

chemistry, mathematics, etc. lots of incorrect stuff at the beginning that helps people with their day to day stuff

2021-02-22T18:26:49.038100Z

there are really two different definitions of predicates, there is one that people think of when they are "writing a predicate", which is the true/false ends in ?, single argument one

2021-02-22T18:27:30.038300Z

and there is the one that you use when using predicates, which I think is what I described, basically whatever can have its result passed to if

dpsutton 2021-02-22T18:28:42.038500Z

i'd go with the truthy version that hiredman is talking about. truthy is quite easy in clojure. nil, false otherwise truthy.

2021-02-22T19:39:40.041400Z

I fat fingered with compose-keys turned on, and accidentally discovered that if the ns name in the ns form has an em-dash instead of a dash, require returns without error but it creates a broken namespace. of course the answer is "don't use em-dash in the namespace symbol", but I wonder if there's a linter that checks for things like that

jcburley 2021-02-25T05:28:37.166400Z

Interesting idea! https://github.com/candid82/joker/discussions/444

borkdude 2021-02-25T07:54:24.178900Z

I missed this. We actually had an issue in the analysis export when we had invalid keywords (that could not be roundtripped) and I already thought of a linter for this, will post an issue

jcburley 2021-02-26T02:15:46.262Z

https://github.com/candid82/joker/pull/445

borkdude 2021-02-26T08:14:36.269400Z

Here's the clj-kondo issue: https://github.com/clj-kondo/clj-kondo/issues/1179 :)

jcburley 2021-02-28T14:27:31.333900Z

Well, I’ve really gone done the rabbit hole on this one. Didja know Clojure allows (lexically speaking) symbol names beginning with control characters (including NUL)? Pretty much any character not specifically allocated for some other token/purpose can be the first/subsequent character in a Symbol. ClojureScript isn’t quite that permissive…but why would any modern language permit any non-printables (at the very most) in symbol/keyword names, if not their source files entirely? What’s the reasoning there: the ability to support radically obfuscated source code? I’ll probably gist-ize the various little .cljc files I’ve created with wacky ASCII, Latin1, and Unicode characters.

2021-02-28T15:27:12.334400Z

I doubt it was a conscious decision to allow weird control characters. Here is the JVM regular expression for what Clojure/JVM allows as a symbol: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L66

2021-02-28T15:27:53.334700Z

\D matches a "non-digit [^0-9]" according to the Java doc page: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

2021-02-28T15:30:09.334900Z

It would be too English-centric to disallow letters from other alphabets. Perhaps there is an obvious brief replacement for \D that matches a smaller subset of Unicode code points that better represents "an alphabetic character from any language's alphabet, but not a digit".

2021-02-22T19:40:56.042500Z

usually (doto foo.bar-baz (require :reload) in-ns) is safe because if the ns is broken I won't land my repl in that ns

2021-02-22T20:29:55.042600Z

borkdude enhancing clj-kondo in 5... 4... 3... 2... 🙂

2021-02-22T20:30:44.042800Z

Certainly sounds like a linter that checks for strict ASCII subset (for some fraction of developers), or a larger set that includes other alphabets could find this quickly.

vemv 2021-02-22T20:58:21.046100Z

Is there such a thing as "print x's stacktrace very concisely"? Perhaps some lib has made an attempt at it? Background: sometimes a dev process can experience stacktraces and needs to print them accordingly to my IDE. More often than not the actual errors will be pretty trivial so it seems like the stacktraces (otherwise annoyingly large) could be compressed to between 1-3 lines

dpsutton 2021-02-22T21:01:19.046700Z

(clojure.repl/pst *e) is quite nice. and a template for anything else you might want to do

dpsutton 2021-02-22T21:01:49.047100Z

if in CIDER there's a project-only option that might be up your alley as well

vemv 2021-02-22T21:06:42.049200Z

> (clojure.repl/pst *e) magic! it's quite shorter :) thanks, I wasn't aware of the difference (vs. (-> e .printStacktrace)). I think it's good beginning, perhaps I could use AvisoNovate/pretty as it further trims clojure stacktraces (although, IIRC it doesn't do a specific attempt at shortening the stacktrace, in a repl-oriented manner)

alexmiller 2021-02-22T21:11:50.050500Z

pst will only print the root exception trace (which is usually the one you care about), and it also elides some top frames related to the exception throwing itself, and limits to depth of 12 by default (but you can limit that even more if needed)

🙌 1
vemv 2021-02-22T22:25:07.053100Z

In a similar vein to my previous question, how can I make the single line IllegalArgumentException No single method: xxxxxxxxxxxxxxxxx of interface: yyyyyyyyyy found for function: zzzzzzzzzz of protocol: aaaaaa fit into e.g. 80 columns? I have the string at hand, I just need to process that string (i.e. it's easier than whole-stacktrace manipulation) (this is called sometimes "fill-column" style I think)

vemv 2021-02-22T22:25:38.053200Z

one simple heuristic is "every two spaces, insert a newline" but I'm open to fancier solutions :)

2021-02-22T22:28:37.053400Z

this is actually two problems, one is you have to parse it into some kind of structure, the second it pretty printing the structure

2021-02-22T22:29:39.053600Z

turning it into a vector where each element was separated from the next by two spaces, is an example of a very naive parse

2021-02-22T22:29:54.053800Z

which is why it gives you very poor pretty printing

2021-02-22T22:32:49.054Z

so come up with a grammar, parse the messages, and then you can use something like http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf (a naive, but nice enough pretty printer algorithm and interface) to print it

👍 1
vemv 2021-02-22T22:53:33.054200Z

Pretty-printing sounds like a good idea, I hadn't immediately thought of clojure.pprint Splitting by " " seems sensible (as these messages tend to be expressed in English), then I could try using pprint with a width of my choice