clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2021-03-19T06:30:01.148200Z

What would be nice is also to support :keys for sequential destructuring everywhere (not just on the vararg rest)

(let [{:keys [a b]} [:a 1 :b 2]] [a b])
;;> [1 2]

2021-03-19T06:30:48.149Z

Then it would make sense that an attempt at associative destructuring also attempts to coerce the seq into a map

2021-03-19T06:32:41.151Z

I'm imagining any attempt at an associative destructuring of a sequence would be like calling (apply hash-map [:a 1 :b 2]) on it first and then destructuring it as a map.

alexmiller 2021-03-19T06:35:09.151700Z

it is supported everywhere - you just need (let [[& {:keys [a b]}] [:a 1 :b 2]] [a b])

4๐Ÿคฏ
alexmiller 2021-03-19T06:37:22.152500Z

could the former be sugar for the latter? dunno, haven't thought about that

2021-03-19T06:41:08.152600Z

Well it would make everything consistent with:

(let [{:keys [a b]}
      (list :a 1 :b 2)]
 [a b])
;;> [1 2]

2021-03-19T06:43:27.152800Z

Does this no longer works in 1.11?

(let [{:keys [a b]}
      (list :a 1 :b 2)]
 [a b])
;;> [1 2]

alexmiller 2021-03-19T06:45:45.153Z

vectors though are both associative and sequential so gets tricky

alexmiller 2021-03-19T06:46:51.153200Z

user=> (let [{a 0} [:hi :there]] a)
:hi

1๐Ÿคฏ
2021-03-19T06:50:55.153400Z

Hum... That's true. Never thought about that, and I guess this kind of makes sense why it works for sequences and not for vectors. Though in practice seems not as useful. But I never thought of doing [& {a :a}] and now that I know, it's not a big deal, and allows both form if.you ever want to destructure the vector by its index or instead as a key/value pair map.

alexmiller 2021-03-19T06:56:26.153700Z

I mean, that's not new, it's always worked liked that :)

alexmiller 2021-03-19T06:58:36.153900Z

well, since 1.2

2021-03-19T06:59:24.154100Z

Haha ya, but for some reason I just never really thought about it lol. I think I assumed & was like only for function varargs, but it makes sense since I think function args are just destructured as if they were a vector.

2021-03-19T07:04:14.154300Z

Ok, so this is logical actually I believe. Vectors are associatives as well. So if you say destructure associative as m and use m you get back the associative as-is. But sequence are not associative, and when destructured as an associative they are coerced into one. So #3 used to throw because it doesn't have an even number of key/value pairs for the coercion. While in #4 it does so you get a map where the first element in the seq is the key and the second is the value. And with 1.11, sequence of a single or trailing map destructure as an associative of that map. So now in #3 you get single map back.

2021-03-19T07:12:13.155700Z

Though I'm curious, what happens in 1.11 for:

(let [{a :a}
      (list :a 1 :b {:a 2})]
  a)

arohner 2021-03-19T09:47:22.157600Z

Can anyone recommend any books on designing Erlang systems? Iโ€™ve built a large clojure โ€œmicroservicesโ€ system in Kafka+Datomic that is starting to feel very Erlang-y in terms of actors and message passing, so now Iโ€™d like to understand how Erlang and Beam handle those kinds of problems

vemv 2021-03-21T13:11:02.284900Z

Not a direct answer, but when having a "message-passey" system there's likely a pure-functional system hidden underneath (which is obviously a good thing) Many production :clj: codebases aren't pure-functional. If yours doesn't happen to be, perhaps you'd have it reasonably easy to make it so. The benefit being: you can create test suites that exercise failure scenarios comprehensively/generatively and instantly. This is very different to hand-crafting failure scenarios that run slowly (because they have to run kafka, datomic, spin up an aws instance, w/e)

mpenet 2021-03-19T10:02:26.157700Z

Designing for Scalability with Erlang/OTP is a good one

mpenet 2021-03-19T10:02:59.157900Z

it's full of little insights useful in non erlang contexts. I quite enjoyed reading it

kulminaator 2021-03-19T11:05:41.159800Z

Can anyone suggest a comfortable lexer or tokenizer to parse sql like syntax?

kulminaator 2021-03-19T11:07:34.159900Z

I will add a sample

kulminaator 2021-03-19T11:07:50.160100Z

table public."this""is stupid": INSERT: id[integer]:5 sometext[text]:'tere2' somedate[timestamp with time zone]:'2021-03-19 12:13:07.609859+02'

slipset 2021-03-19T11:08:50.160500Z

instaparse?

kulminaator 2021-03-19T11:08:52.160700Z

This is output from postgres test_decoding plugin and i'm trying to avoid reinventing a lot if wheels when parsing this.

kulminaator 2021-03-19T11:09:49.160900Z

It has funny oddities "" meaning an escaped double quote

kulminaator 2021-03-19T11:15:19.161100Z

Instaparse looks good, will check it out

nilern 2021-03-19T11:15:51.161300Z

Uhh https://calcite.apache.org/?

arohner 2021-03-19T11:31:27.161500Z

thanks!

borkdude 2021-03-19T11:39:52.161700Z

found some instaparse grammar here: https://github.com/untangled-web/sql-datomic/blob/master/resources/sql-92.instaparse.bnf

kulminaator 2021-03-19T12:36:39.162100Z

Calcite probably won't do as the syntax is just similar to sql semantics, not sql itself

mpenet 2021-03-19T12:38:48.162300Z

oh I forgot that one: https://www.erlang-in-anger.com/ Fred Hebert is a good writter and the bits about flow control are excellent

mpenet 2021-03-19T12:38:53.162500Z

and it's free...

mpenet 2021-03-19T12:39:34.162700Z

but it's way more erlang centric, I guess with that one you could cherry pick parts to read

2021-03-19T13:14:35.163500Z

it does work

1๐ŸŽ‰
Linus Ericsson 2021-03-19T13:34:12.164200Z

otplike could be of interest https://github.com/suprematic/otplike

viesti 2021-03-19T13:46:22.164600Z

I wonder if there's a json plugin for the wal/logical decoding

viesti 2021-03-19T13:47:38.165Z

wal2json? https://wiki.postgresql.org/wiki/Logical_Decoding_Plugins

NoahTheDuke 2021-03-19T13:59:15.168400Z

i have a function that caches the return value (with an atom). I would like to skip the cache during development so I don't have to (reset! cache {}) when I make changes. is there a preferred idiom for this kind of thing?

2021-03-19T14:01:29.168500Z

I would think just have a *cache-results?* var that gets set to true for prod?

2021-03-19T14:01:47.168700Z

Iโ€™m not super experienced yet but have seen that idiom in a few different projects

nilern 2021-03-19T14:11:13.169100Z

Dynamic vars are slow and the thread locality can bite you

nilern 2021-03-19T14:13:30.169300Z

You could put the cache or a config flag in an Integrant (or Component or...) system but it might be a bit heavyweight

nilern 2021-03-19T14:14:50.169500Z

Also the Reloaded workflow with e.g. Integrant can reset the cache along with everything else

kulminaator 2021-03-19T15:09:36.169900Z

I can not rely on being able to install plugins on source postgres database

kulminaator 2021-03-19T15:10:55.170100Z

Source can be hosted postgres like rds, i can not install anything there.

ghadi 2021-03-19T15:13:36.170300Z

+1 instaparse

viesti 2021-03-19T15:56:36.170600Z

ah, thought that wal2json was present on rds (https://aws.amazon.com/blogs/database/stream-changes-from-amazon-rds-for-postgresql-using-amazon-kinesis-data-streams-and-aws-lambda/), but yeah +1 instaparse

seancorfield 2021-03-19T16:47:41.171100Z

(! 893)-> clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.11.0-alpha1"}}}'
Clojure 1.11.0-alpha1
user=> (let [{a :a}
      (list :a 1 :b {:a 2})]
  a)
1

emccue 2021-03-19T19:09:06.171800Z

> It is obvious that due to JVM limitations otplike cannot replace Erlang/OTP and otplike willย `NEVER`ย be seen as Erlang/OTP alternative.

emccue 2021-03-19T19:09:39.172Z

other than the threading model - which might get patched before wet bulb temperatures kill us all - i wonder what else is a limitation

2021-03-19T19:20:57.174900Z

I have a library function where I have two things that have a property that is required to be numeric, and I return the absolute value between them, I'm guessing I should avoid Math/abs and copy something like https://github.com/clojure/math.numeric-tower/blob/e8387dfac1757701e842a65c52b2b5596d1c9607/src/main/clojure/clojure/math/numeric_tower.clj#L104 so that it works with bigdec, etc. This question kind of answers itself, but it feels a bit wrong still to bring in that function just to get an absolute value in one spot

seancorfield 2021-03-19T19:38:43.176Z

@jjttjj Would it be a reasonable restriction on your code to only support long/double? Or do you need to support big integer/big decimal?

seancorfield 2021-03-19T19:40:12.176700Z

(I suspect thereโ€™s a lot of โ€œnumericโ€ code out there that doesnโ€™t work properly with the โ€œbigโ€ variants in all cases)

2021-03-19T19:42:32.178200Z

Technically it's extensible in a way that it might be need to support the big variants, but I suppose it's probably unlikely they'd be needed so maybe I should add the restriction

quoll 2021-03-20T19:41:07.270300Z

Maybe could just use:

(defn abs [n] (if (neg? n) (-' n) n))
That goes through all the appropriate Clojure machinery and captures the edge cases (such as (abs Long/MIN_VALUE)) Itโ€™s also reasonably close to what math-tower is doing.

1๐Ÿ‘
mpenet 2021-03-19T19:52:29.178300Z

Per process gc/stack/heap, so isolation is quite extreme and allows some patterns hard to replicate on the jvm

mpenet 2021-03-19T19:56:17.178500Z

It's also full of tricks internally to allow this share nothing approach without being wastful when operating on the same host. Also message passing works across the network natively... etc etc. I really like erlang (used it professionally) but I think it might not be a good idea to try to replicate this kind of stuff on the jvm

mpenet 2021-03-19T19:57:46.178700Z

At least not now

2021-03-19T20:00:53.179600Z

So anything else new in 1.11 appart from keyword args accepting a map as well?

borkdude 2021-03-19T20:12:18.180200Z

spec2......? ๐Ÿ™

2021-03-19T20:12:30.180300Z

Personally I'm hoping for any ergonomic improvements to qualified keyword usage (https://clojure.atlassian.net/browse/CLJ-2123?filter=10021)

seancorfield 2021-03-19T20:13:31.180700Z

@didibus Thatโ€™s the only feature in 1.11 Alpha 1.

seancorfield 2021-03-19T20:14:10.181800Z

But there are lots of things in JIRA marked for possible inclusion in 1.11 I believe. Including, possibly, map-vals and map-keys? Iโ€™ve seen those mentioned a few times.

borkdude 2021-03-19T20:14:29.182100Z

btw, alpha1 does simplify function specs for kwarg functions, you can now just spec them as a map I guess. or was this just as easy before? can't remember.

alexmiller 2021-03-19T20:20:08.183900Z

we still have a pending enhancement to extend keys*

seancorfield 2021-03-19T20:20:49.184500Z

Looks like 31 vetted tickets marked for consideration in 1.11โ€ฆ including tap-> (yay!), java.util.functions interface support, #clojure/var tagged literal, lighter-weight aliasing on keywords (to help with qualified Spec names), DCL for prepl (yay!)โ€ฆ those are my โ€œfavoritesโ€โ€ฆ

alexmiller 2021-03-19T20:21:01.184800Z

you should not put any belief that those are meaningful

alexmiller 2021-03-19T20:22:51.185700Z

consider things marked 1.11 as "top of mind" for one reason or another (some are really things possibly for 1.11, some are "important", some just had been in late consideration in the past and have been dragged along)

seancorfield 2021-03-19T20:24:31.186900Z

I donโ€™t think that list includes https://clojure.atlassian.net/browse/CLJ-1959 which has been mentioned a couple of times? map-keys/`map-vals`

alexmiller 2021-03-19T20:24:52.187600Z

like I said that list likely bears little relation to what will end up in 1.11

seancorfield 2021-03-19T20:24:58.187900Z

I have no expectations that all of those 31 would make 1.11. I do hope tap-> makes it in though.

alexmiller 2021-03-19T20:25:42.189Z

feature-ish wise, we've done design and some impl work on new thing related to keyword aliasing, don't really want to get into details, would rather do that when it's ready

alexmiller 2021-03-19T20:26:11.189800Z

and have done more looking at java function interop, no conclusion yet on where that will end up

seancorfield 2021-03-19T20:26:24.190200Z

I would guess 1.11 is 6-12 months out still at this point?

alexmiller 2021-03-19T20:26:38.190400Z

ยฏ\(ใƒ„)/ยฏ

seancorfield 2021-03-19T20:26:49.190800Z

Hahaโ€ฆ Youโ€™re a lot of help! ๐Ÿ˜†

alexmiller 2021-03-19T20:27:02.191Z

we haven't decided what's in it so ... hard to estimate

seancorfield 2021-03-19T20:27:27.191500Z

Fair enough. I was a bit surprised to get an alpha so soon. Esp. with a single feature in it.

alexmiller 2021-03-19T20:27:42.191600Z

that is probably the thing next most farthest along

2๐Ÿ‘1
alexmiller 2021-03-19T20:28:15.192400Z

feedback!

seancorfield 2021-03-19T20:28:26.192800Z

For now Iโ€™m using (doto tap>) anywhere I would otherwise want tap-> so I guess thatโ€™s not really โ€œimportantโ€.

alexmiller 2021-03-19T20:29:01.193600Z

generally, we prefer to do bigger things first (alphas), more bug/small things next (betas), then clean up

alexmiller 2021-03-19T20:29:27.194300Z

so while tap-> is likely, you may not see it till later

seancorfield 2021-03-19T20:29:41.194600Z

DCL for socket REPL and prepl would mean I could clean up my dot-clojure deps.edn file, although I take care of that in my dev.clj file now. Iโ€™m more excited about tools.build TBH than 1.11 overall ๐Ÿ™‚

dpsutton 2021-03-19T20:29:58.194900Z

what's DCL?

alexmiller 2021-03-19T20:30:14.195300Z

I have a patch for that but on first review it raised more questions and got a bit bigger

alexmiller 2021-03-19T20:30:20.195600Z

but yes, of interest for sure

alexmiller 2021-03-19T20:30:40.195800Z

https://clojure.atlassian.net/browse/CLJ-2540

1๐Ÿ‘
seancorfield 2021-03-19T20:34:26.196300Z

DynamicClassLoader @dpsutton

2๐Ÿ‘
seancorfield 2021-03-19T20:34:43.196800Z

A normal REPL has that context, but socket REPL and prepl donโ€™t.

seancorfield 2021-03-19T20:35:04.197400Z

Which means you canโ€™t use add-libs in them unless you do a little DCL dance at startupโ€ฆ

seancorfield 2021-03-19T20:35:24.197600Z

Hence: https://github.com/seancorfield/dot-clojure/blob/develop/deps.edn#L178

dpsutton 2021-03-19T20:36:39.199200Z

ah fair. i stay away from that kind of stuff and just restart my repl. in practice i don't add deps very often so the invitation to classloader issues is a problem without a large payoff for its complexity

2โž•
seancorfield 2021-03-19T20:38:06.200300Z

@alexmiller Yeah, that comment from Stu makes perfect sense. Not sure what to suggest. I took that approach in my dev.clj file โ€” setting up the DCL before I start Socket/Rebel/Reveal etc: https://github.com/seancorfield/dot-clojure/blob/develop/dev.clj#L182-L188

seancorfield 2021-03-19T20:39:04.201400Z

@dpsutton My HoneySQL REPL has been running since Jan 31st. I just restarted my work REPL today to switch from JDK 15 / Clojure 1.10.3 to JDK 16 / Clojure 1.11.0 Alpha 1 but it had been running since Feb 26th.

kulminaator 2021-03-19T20:39:13.201500Z

instaparse working like a champ, thanks ๐Ÿ™‚

2021-03-19T20:40:18.201700Z

That comment from Stu? On https://clojure.atlassian.net/browse/CLJ-2540 or somewhere else?

Max 2021-03-19T20:48:40.202Z

Recently Iโ€™ve been hurting for a map-kv. (map (fn [[k v]] (โ€ฆ))) works fine, but itโ€™d be nice to be able to use a #() with %1 == k, %2 == v instead

seancorfield 2021-03-19T21:18:00.202700Z

Yes, on that issue.

seancorfield 2021-03-19T21:20:06.202900Z

I donโ€™t like #(..) with multiple arguments โ€” Iโ€™ll use (fn [..] ..) as soon as there are multiple arguments. I almost never map over a hash map โ€” I use reduce-kv for that.

2021-03-19T21:50:09.203200Z

Hum, seems a bit frivolous compared to just (map + (keys foo))

2021-03-19T21:50:26.203400Z

But why not

2021-03-19T21:51:27.203600Z

Java.util.functions support that would be really great

borkdude 2021-03-19T21:51:27.203800Z

What is DCL?

seancorfield 2021-03-19T21:52:43.204Z

DynamicClassLoader. Needed for add-libs.

borkdude 2021-03-19T21:53:02.204200Z

oh I thought Dead Code ... but what does the L stand for? ;)

2021-03-19T22:04:04.204600Z

I always have a case where I started a repo and forgot some lib

2021-03-19T22:04:20.204800Z

I think it be an awesome feature for exploration and experimentation

2021-03-19T22:16:21.212100Z

I can't really think of anything major I would want from 1.11, honestly pretty content with most of Clojure 1.10. But I didn't know I wanted keyword args to work on maps before and now I really want it ๐Ÿ˜‚ Definitely interested in spec2, function interface interop, and I'm intrigued by tools.build though I also don't feel I'm not getting what I need from current build tooling. Other then that I'm more into the upcoming JVM changes, project loom would be big, native image to support more code, value objects (the Jep for it even mentions Rich Hickey haha), etc. I think the overarching themes the survey often asks for, better error messages, faster startup, better performance, well I'd never say no to that. But can't really think of much beyond that in the language itself, the ergonomics, like it's all pretty damn good already ๐Ÿ˜‚ Oh... I do hope one day to see a form of HEREDOC support.

alexmiller 2021-03-19T22:25:22.218900Z

Not happening

1๐Ÿ˜–
alexmiller 2021-03-19T22:26:14.219100Z

:)

imre 2021-03-19T22:26:45.219200Z

I no longer wish for these since I got comfortable with transducers and came across cgrand's xforms. They could benefit libraries though

vlaaad 2021-03-19T22:27:19.219400Z

I want more runtime introspection, e.g. metrics/watchers for stuff like core.async, multimethods, namespaces

2021-03-19T22:29:04.219500Z

I'll keep dreaming ๐Ÿ˜

alexmiller 2021-03-19T22:30:48.220800Z

A great place to describe a problem you are trying to solve and see if others have it too is on https://ask.clojure.org

alexmiller 2021-03-19T22:31:25.221900Z

If many people have the same problem, then the core team becomes interested :)

2021-03-19T22:47:30.222200Z

Actually, having more transducers in core would be nice.

2021-03-19T22:49:26.223100Z

I see why keyword alias and function interface are being looked at for 1.11 then haha. https://ask.clojure.org/index.php/questions?sort=votes

2021-03-19T22:55:27.226900Z

On that topic, I have found it harder since the move to ask.clojure to vote on things, because feature requests and bug fixes are hidden in the noise of generic questions.

lilactown 2021-03-19T23:01:02.227Z

(map + (keys foo)) doesn't return a map; I would appreciate a (map-keys + foo) that produced a new map with the keys updated

borkdude 2021-03-19T23:01:22.227400Z

@didibus what's HEREDOC support, you mean multiline strings?

1
henrik42 2021-03-20T12:09:41.259700Z

I once did this https://github.com/henrik42/extended-lisp-reader as an experiment. Won't run anymore I guess.

danielneal 2021-03-20T14:39:56.260100Z

like the js template literals

borkdude 2021-03-19T23:04:01.228200Z

Just sexprs and pr-str can get you pretty far ;)

2021-03-19T23:05:31.229200Z

Multiline string that doesn't need to be escaped.

seancorfield 2021-03-19T23:06:25.229700Z

One of the problems with heredoc as typically implemented is that this is currently legal Clojure:

dev=> (def foo ["""
 #_=> this is a heredoc
 #_=> """])
#'dev/foo
dev=> foo
["" "\nthis is a heredoc\n" ""]
(edited to be a better example)

2021-03-19T23:07:14.230400Z

#text DELIMITER
Here I can now write whatever I want including with " : \ \ / / (foo)
All kind of error character.
DELIMITER

seancorfield 2021-03-19T23:08:50.232300Z

๐Ÿ™‚

seancorfield 2021-03-19T23:09:26.232400Z

That would be horrible syntax in Clojure thoโ€™โ€ฆ

2021-03-19T23:11:04.232600Z

When I last thought of it, I thought a new tag reader would be best:

#text end
Whatever multiline string here.
end
So after the reader #text is encountered, you'd give a symbol which is the delimeter for the string that follows.

seancorfield 2021-03-19T23:11:36.232800Z

Reader tags still require legal Clojure forms though.

2021-03-19T23:12:08.233Z

Sorry, not a tagged literal, like an additional reader form

2021-03-19T23:12:12.233200Z

More like #()

2021-03-19T23:12:39.233400Z

Which lets you pick the delimiter the reader will use on the next form for strings.

borkdude 2021-03-19T23:12:42.233600Z

reader dispatch

2021-03-19T23:13:14.233800Z

Ya, so you tell the reader the following string is delimited by this symbol.

seancorfield 2021-03-19T23:13:50.234Z

I would suggest you try actually implementing it in a fork of Clojure and see what problems you run into. I think youโ€™ll find it far harder than it looks (and I still think it would be horrible syntax).

borkdude 2021-03-19T23:14:10.234200Z

e.g.:

#+
Yolo!
+
But now you would need to escape + in your text.

2021-03-19T23:14:42.234400Z

How about

#__ 
Multi
Line
Comments!
__#
๐Ÿ™‚

seancorfield 2021-03-19T23:14:49.234600Z

Heโ€™s suggesting something like #" sym unconstrained arbitrary text sym I think.

seancorfield 2021-03-19T23:15:42.234800Z

(presumably with required newlines after the first sym and before the second one to make it a bit more tractable?)

borkdude 2021-03-19T23:15:50.235Z

#+EOT
yolo! "string!"
EOT

2021-03-19T23:15:52.235200Z

Well I don't want it for comments ๐Ÿ˜‚, it's basically for embedding other languages into Clojure or for templating.

borkdude 2021-03-19T23:16:12.235400Z

I think that is doable

2021-03-19T23:16:31.235600Z

Ohhh I see

borkdude 2021-03-19T23:16:33.235800Z

This is quite easy to hack into https://github.com/borkdude/edamame or tools.reader in the dispatch table

2021-03-19T23:17:23.236200Z

Ya, the user picks the delimiter, it's a bit like how as-> has you pick the name of the symbol to bind. That way the user can choose a delimeter they know their string won't contain and so they won't need to escape.

dpsutton 2021-03-19T23:17:36.236400Z

perhaps the hardest part of this would be updating all the tooling that needs to know how to move over forms

1โ˜๏ธ
dpsutton 2021-03-19T23:18:24.236600Z

lots of code in tooling would need to be updated and it might be quite tricky

borkdude 2021-03-19T23:18:43.236800Z

this is always the case with adding new dispatches to the reader table

2021-03-19T23:18:43.236900Z

Most tooling relies on tools.reader though

dpsutton 2021-03-19T23:19:44.237400Z

CIDER certainly does not and that's about 40% marketshare

2021-03-19T23:19:45.237600Z

But ya, it is one downsides. It also secretly open the door to things much closer to reader macros. Because tagged literal can now accept arbitrary text and parse and interpret it.

borkdude 2021-03-19T23:19:46.237800Z

I bet I could hack the above idea in edamame within an hour or so, but since it will never be in Clojure, I won't even bother

1๐Ÿ˜
2021-03-19T23:20:23.238100Z

With what else I've seen you do, I'm sure you could haha.

dpsutton 2021-03-19T23:20:35.238300Z

i would be surprised in Cursive used tools reader for its structural movements and such

dpsutton 2021-03-19T23:21:22.238500Z

and obviously calva/conjure/Chlorine and others don't use tools reader as well

borkdude 2021-03-19T23:21:31.238700Z

Cursive probably uses something more along the lines of rewrite-clj since editors / linters etc need something more precise than s-expressions

2021-03-19T23:21:31.238900Z

Well if people think it be a nice to have, go upvote: https://ask.clojure.org/index.php/8520/text-block-literal-string-literal-unsescaped-string-literal ๐Ÿ˜œ

borkdude 2021-03-19T23:22:14.239300Z

calva uses clojure-lsp which uses rewrite-clj / clj-kondo (which is also based on rewrite-clj)

borkdude 2021-03-19T23:22:29.239500Z

and rewrite-clj uses tools.reader but not in the way you typically do

seancorfield 2021-03-19T23:22:38.239700Z

I think thatโ€™s one of the few things on ask that Iโ€™ve downvoted ๐Ÿ™‚

2021-03-19T23:23:19.240Z

It was.you!! :rolling_on_the_floor_laughing:

2021-03-19T23:25:46.240200Z

I've had two times where I really wish Clojure had it. For scripting, it is quite nice if you need to generate some file, you can template things easily with this, without needing a seperate file, which when you have a script you don't really want resources along with it and all that. And for embedding JavaScript inside Hiccup for simple server side rendered websites.

borkdude 2021-03-19T23:25:47.240400Z

Early on Clojure considered XML literals I think I read somewhere once

dpsutton 2021-03-19T23:25:53.240600Z

does it use that kind of stuff for movements? not analysis but for moving to the next form; for determining what "the last form" is when sending the last form

borkdude 2021-03-19T23:26:35.240800Z

define "it"?

seancorfield 2021-03-19T23:26:42.241Z

Part of what drew me to Scala was XML literals. After I used them in a project, I felt they were a terrible idea! ๐Ÿ™‚

borkdude 2021-03-19T23:28:30.241200Z

@dpsutton if you want to offer any kind of refactoring, you have to know locations and preserve whitespace, exactly what rewrite-clj is for, but I assume Cursive has its own variant of this, possibly written in Java or part of some proprietary IntelliJ API

dpsutton 2021-03-19T23:29:20.241400Z

i mean, if you put your caret at a paren and say "send this form to the repl", the determination of what the last form is is certainly in a js implementation of paredit or parinfer right?

dpsutton 2021-03-19T23:29:46.241600Z

and this multiline string allowing arbitrarily unmatched delimiters would wreak havoc on that stuff

dpsutton 2021-03-19T23:30:19.241800Z

its not impossible, but i'm just thinking of all the paredits and parinfers that would have to be updated to handle this

borkdude 2021-03-19T23:30:40.242Z

paredits also handle ;; with arbitrary text?

dpsutton 2021-03-19T23:30:41.242200Z

and yes i'm not talking about analysis which will likely use tools.reader

dpsutton 2021-03-19T23:30:51.242400Z

yeah that's fair

2021-03-19T23:31:10.242600Z

I like your twist to it borkdude.

#+SYM
Here's the big string.
SYM
Then you could build tagged literals like:
#my/xml #+END
<xml>
  <foo bar="wtv">
<\xml>
END

borkdude 2021-03-19T23:31:40.242800Z

yep

borkdude 2021-03-19T23:33:10.243Z

and docstrings without escaped strings as well.

2021-03-19T23:34:21.243200Z

True:

(defn foo
  #+DOC
  This function does bla
  Example:
   (foo "value" 1)
   ;;> "value1"
  DOC
[a b]
...)

alexmiller 2021-03-19T23:37:32.243700Z

Me too :)

p-himik 2021-03-19T23:38:03.243900Z

@seancorfield Could you elaborate a bit on why you felt that way? What do you think about JSX that's rampant in the frontend world right now?

seancorfield 2021-03-19T23:38:16.244100Z

I hate that too ๐Ÿ™‚

2021-03-19T23:39:13.244300Z

What about ERB like templates?

seancorfield 2021-03-19T23:40:02.244500Z

Scala is already fairly punctuation heavy so allowing arbitrary blocks of text full of < and > just makes for very distracting-looking code.

seancorfield 2021-03-19T23:41:07.244700Z

Iโ€™ll be honest, I find large blocks of SQL embedded as strings in Clojure to be distracting too. Although we have plenty of that at work. Where weโ€™re not using HoneySQL, that is.

borkdude 2021-03-19T23:41:12.244900Z

This is why Scala chose [] for generics ;)

p-himik 2021-03-19T23:41:14.245100Z

Hmm, right, I can see that. A cognitive load creep. :)

seancorfield 2021-03-19T23:41:27.245300Z

Templates of any stripe are fine outside the code.

seancorfield 2021-03-19T23:42:17.245500Z

Scala was trying to learn from C++โ€™s mistake with < > for templates because of the contextual lexing issue of >>.

2021-03-19T23:42:57.245700Z

Well I guess if a code base started using this for all strings. But I expect it be for rare instances. Like a quick on-click JS function inside Hiccup, or in a script where you need to create some config file from and want to quickly template it without setting up resources, and all. And for doc-strings it actually looks much cleaner to me. Seeing all the escape characters in them is distracting.

borkdude 2021-03-19T23:44:55.246Z

how do literate programming tools solve this - they must have a solution for this. do they start with foo.template.clj or so?

2021-03-19T23:45:01.246200Z

I don't know, any Rubyist or Perlers? Do heredoc end up polluting things?

seancorfield 2021-03-19T23:46:19.246400Z

(it will likely be unsurprising to hear that Iโ€™m no fan of literate programming either โ€” for similar reasons)

1๐Ÿ™ƒ
2021-03-19T23:47:37.246600Z

Oh, is that the idea of map-keys ? I see I see. Though reduce-kv is pretty damn close, but ya I can see it being a bit more convenient. Then I would actually like a map-kv that returned a map.

seancorfield 2021-03-19T23:49:47.246900Z

https://clojure.atlassian.net/browse/CLJ-1959

borkdude 2021-03-19T23:50:24.247100Z

Then why do I see you face in the contributors here: https://github.com/gdeer81/marginalia/tree/master/test/marginalia/test

borkdude 2021-03-19T23:50:27.247300Z

=)

seancorfield 2021-03-19T23:51:38.247500Z

https://gist.github.com/seancorfield/6e8dd10799e9cc7527da5510c739e52f โ€” using a gist via deps.edn to get map-keys / map-vals

2021-03-19T23:51:43.247700Z

Well it seems heredoc is quite controversial. My idea was one day when I'm bored I'd make an Emacs unescape plugin instead. Where it visually unescapes things inside Clojure strings, and automatically escapes them as I type/paste (but visually won't show the escapes. Maybe this already exists actually...

borkdude 2021-03-19T23:54:10.247900Z

it seems marginalia just uses comments and strings, no special stuff

seancorfield 2021-03-19T23:54:35.248100Z

@borkdude Because I wanted to give it a fair whip โ€” and used it to build an entire project at work. This came up on ClojureVerse recently, BTW.

borkdude 2021-03-19T23:56:47.248700Z

cool. I have made some diagrams with http://draw.io which works on all platforms. it's not as as good as omnigraffle but it works and it's free

borkdude 2021-03-19T23:57:18.248900Z

they have a desktop app too. I'm off now, g'nite.

2021-03-19T23:57:50.249100Z

I see. Ya, I don't know... I expect every Clojure dev to have their own "my-extra-utils" library, and this seems it could go there, amongst a bunch of other conveniences. I don't know which one are used so often that it makes sense to promote them to core or not. I wouldn't mind anyways. Though the name instinctively made it feel to me like it's mapping over the keys, not that it would become a non-lazy type preserving function.