Fork me on GitHub

In Simple made easy, Rich talks about "artifacts". I'm not certain what he means by that, and how it relates to constructs. These terms are a little too abstract for me to relate them to concrete things. I can't figure out what a construct is in Clojure, and what it's artifacts are. My brain goes to, e.g. map as a construct, but what's the artifact of that? If programs/systems are artifacts, then how does that relate to the constructs? I think we are trying to optimize for simple artifacts based on the talk, so I think this is quite important.


artifacts are maven jars


> There are a bunch of constructs that have complex artifacts that are very succinctly described. So what's a complex artifact? Are maven jars complex?


I suppose a complex artifacts is when you have lot of dรฉpendency in it


Afaik that was how I understood it when I saw the video but I might miss the context ๐Ÿ˜


Dependencies don't necessarily make complexity though. They make you bloated.


I think you could reference the minutes of the video


So we could have rรฉfรฉrence to look at.

dominicm07:08:32 the talk transcript might be easier? > And so if we want to look for simple things, we want to look for things that have sort of one of something. They do, they have one role. They fulfill one task or job. They're about accomplishing sort of one objective. They might be about one concept like security. So you could have a mega-jar pulling in password hashing, and csrf, and all sorts of other simple things, to create a simple thing focused on security.

๐Ÿ‘ 8

I think this could be a useful topic for Clojureverse and/or AskClojure


That's a good idea


I was a bit shy about asking in this channel, the talk is largely clojure agnostic.


Tools.reader has log-source which attaches the source as metadata to a read value. But what if I also want to attach the line and column number?


I think I asked this (or something similar) a while ago about the edn reader, and was told I could send a patch but it should be an optional flag.


Yeah, I want exactly the same behavior as rewrite-clj but for normal EDN values


I guess I can just use a fork


@alexmiller @andy.fingerhut is part of the public API?I guess not right?


this is the public API

Alex Miller (Clojure team)13:08:15

You can use it through the read or read-string functions. What are you looking to use?


I want to add metadata to code I'm reading so when processing I can generate an error message with the correct line and col.


right now I'm rolling my own thing, but wonder if there's something off the shelf

Alex Miller (Clojure team)15:08:17

In what way does read not suffice?


I don't get the metadata attached of which line and col it's reading? but I can fix that myself using an indexed reader

Alex Miller (Clojure team)16:08:59

Clojure itself uses the reader to read code, which attaches line/col metadata, and uses it to report errors

Alex Miller (Clojure team)16:08:51

you need to pass it a LineNumberingPushbackReader while reading though

Alex Miller (Clojure team)16:08:25

user=> (-> "(+ x 1)" clojure.lang.LineNumberingPushbackReader. read meta)
{:line 1, :column 1}


oh that's nice! do you perhaps know if tools.reader also supports this? 'cause it's portable to CLJS too

Alex Miller (Clojure team)16:08:59

that line/col info is only going to be added on forms basically though, so you won't see on other colls or obviously on things without meta


ah, I think then it's good that I wrote some custom code on top of tools.reader EDN which is also more safe to use


Is there a select-keys that lets me easily rename the resulting keys?


@st3fan check clojure.set/rename-keys


or the (let [{sym-a :a-key sym-b :b-key} m] ...) destructuring form


Oh wonderful ๐Ÿ™‚



ClojureScript 1.10.520
cljs.user=> (identical? ::eof ::eof)

Clojure 1.10.1
user=> (identical? ::eof ::eof)


apparently there is:

cljs.user=> (keyword-identical? ::eof ::eof)


because ClojureScript is doing something weird?


@dominicm I've got something portable now (.cljc):

ClojureScript 1.10.520
cljs.user=> (require '[sci.impl.parser :as p] :reload)
cljs.user=> (p/read-string "[{:a 1} {:b 2}]")
[{:a 1} {:b 2}]
cljs.user=> (map meta (p/read-string "[{:a 1} {:b 2}]"))
({:row 1, :col 2} {:row 1, :col 9})


Do tagged literals have meta too?


cljs.user=> (map meta (p/read-string "[^:cool {:a 1} {:b 2}]"))
({:cool true, :row 1, :col 2} {:row 1, :col 16})


can you give an example of tagged literals?


(i.e. did you mean the above example perhaps?)


Ah those tagged literals

Lone Ranger17:08:32

okay semi-serious question that I've never heard addressed. As in, I've never heard Mr. Hickey (or any other other big names in Clojure) ever even mention Python as a potential host language for Clojure. Now, I'm a very experienced Python developer -- substantially moreso than I am at Clojure -- I am very much aware of all the performance tradeoffs that would come with using Python as the host language -- but I must be overlooking something. Has there ever been a stated reason for it?


There is at least one project, pixie, with a goal of creating Clojure hosted on Python. There may be others. It was developed by Timothy Baldridge, and I have never used it, but have half a recollection that it isn't considered "complete":


Rich Hickey wrote implementations of Clojure on Java, C#, and JavaScript. I don't think he needs to publish reasons not to write another Clojure implementation.


I would guess targets were languages he was most familiar with

Lone Ranger17:08:17

That makes sense to me, too. I suppose personally I think it would be an easy win, which is what surprises me. It feels like such a natural choice that I feel like the must be a reason, stated or otherwise, why it hasn't happened.


It always surprised me pixie didn't target interop more aggressively.

Lone Ranger17:08:51

Did ClojureScript start as an official project of the core team or was it adopted and officially sanctioned side-project at some point?


It was official


having no interest in going to a significant effort is the reason most things that require significant effort do not happen ๐Ÿ™‚

Lone Ranger17:08:13

I understand that, but, it's not that much effort. They've already figured out all the hard parts

Lone Ranger17:08:37

Porting the compiler to Python is trivial compared to the work that went into the language design


I mean, anyone can do it, right? It doesn't have to be the ones who wrote Clojure.


I would guess that the areas where python is novel (ai, science) haven't been of interest to rich.


@goomba please go for it. ๐Ÿ˜

Lone Ranger17:08:01

lol I've done a few partial ports already, I don't have the insight or the access to finish though


interesting that data.xml does a trick that ztellman did in potemkin


(export-api node/element* node/element node/cdata node/xml-comment node/element?
            prxml/sexp-as-element prxml/sexps-as-fragment event/element-nss
            name/alias-uri name/parse-qname name/qname-uri
            name/qname-local name/qname name/as-qname name/uri-symbol name/symbol-uri
            name/uri-file name/print-uri-file-command!
            process/find-xmlns process/aggregate-xmlns)

Lone Ranger17:08:21

Right. The data structures that Mr. Hickey and his team have come up with are powerful, novel, and very difficult. Porting them is not a technical challenge but there's no way I'd be able to reinvent them

Lone Ranger17:08:31

and I don't have access to the source code


Of the python port you did?


Eclipse Public Licensed to you and the world.

Lone Ranger17:08:56

Of the clojure source code?

Lone Ranger17:08:04

I thought it was proprietary?


Fully open source


how do you not have access to the Clojure source code?

Lone Ranger17:08:31

facepalm I seriously thought it was proprietary

๐Ÿ˜„ 4
๐Ÿ˜‚ 4

ClojureScript, Clojure on the CLR, Clojure on Java, all open source.

Lone Ranger17:08:15

Well then the real reason is because I don't know how to look things up


Pixie linked above, also open source.

Lone Ranger17:08:36

I'm wondering if another reason, though, is one of the major differences between Python and Java which is concurrency support


Well, Pixie I would have to check more carefully. I assume it is, but haven't looked at the source myself.

Lone Ranger17:08:59

A Python port of Clojure would be a strange mix of ClojureScript and Clojure in terms of performance


The concurrency features have turned out to be less useful than expected. Outside of atoms.

Lone Ranger17:08:38

@alexmiller hy is interesting but it's more of a toy project

Lone Ranger17:08:05

(in my opinion). They didn't even bother to work out let statements. Said it was too hard.

Lone Ranger17:08:45

??? the concurrency features of Clojure?? less useful??

Lone Ranger17:08:02

Do you even core.async? ๐Ÿ˜ฎ


Perhaps he was referring to refs and transactions in dosync, which tend not to be used often.

๐Ÿ‘ 4
Lone Ranger17:08:06

Well the async abilities on Python are much more akin to the model in ClojureScript than Clojure, and I feel like there might be some false expectations set in terms of performance there ... that's a legitimate complaint

Lone Ranger17:08:30

I don't know if that's the real deal killer or not though


Even core async, while useful, is not prevalent. I would have to check, but I'm certain that it wasn't intended to be the root approach to async. It was for wiring callbacks up.


Same with any performance thing, measure and then fix the bad parts.

Lone Ranger17:08:23

I'd have to disagree there... core.async is wickedly powerful


The fast parts of python are C anyway

Lone Ranger17:08:18

The whole thing is C, but the the stack machine is consumed by a ~3000 LOC switch statement, which, while super optimized, is still a really big switch statement ...


Pixie has no python interop btw, it's a clojure like lang impl on pypy. Also abandonware

Lone Ranger18:08:23

mhm. It's still just an archaeological mystery to me. ClojureScript makes perfect sense -- ported to the most widely used language. Python is a strong contender for #2 and it's fairly easy to work with, which is why I find it so interesting that it hasn't even been mentioned

Lone Ranger18:08:27

I suspect the bottom line is it's just not worth it.


I think it would be worthwhile. It would open up a lot of valuable libraries in that space. I'd use it, and wrap django with a data driven api. I'd probably finally play with some ML.


Although Graalvm might make it a little redundant.


@goomba I'd say the JVM is a more attractive target than Python in the enterprise but there are certainly spaces where Python seems ubiquitous so a port of Clojure to Python may be interesting to folks in those spaces.


Personally, I've worked entirely on the JVM for 22 years now so I'm not much interested in a non-JVM implementation of a language ๐Ÿ™‚ I've learned a bunch of non-JVM languages, for self-improvement, but work has been JVM only in that time. Well, there was a bit of C++ at the beginning of those decades since that's what I'd been doing for the decade before I adopted JVM languages ๐Ÿ™‚


Sorry if this is off-topic but, I've been trying to justify Clojure in my (largely Python) org where there's a lot of skepticism about Java. How can I demonstrate the difference b/w Java the platform (JVM, JDK...) and Java the language? How do I compare the artifacts produced by Python and Clojure as opposed to the constructs (artifacts and constructs in the "Simple made Easy" sense) Please ignore if noise.


Python (and Ruby) orgs are often biased against the JVM, not just Java, because they view it as a big, lumbering, "Enterprise" beast. You'll see a lot of people dismiss Clojure simply because of the JVM requirement -- and there are quite a few people in the Clojure community who grumble all the time about having to use the JVM. I think you'll have a nearly impossible time convincing such orgs to use Clojure since they are used to how they manage dev/test/deployment without a JVM and don't want to deal with it.

๐Ÿ˜” 4

(this was also why I worked with Frege on the JVM rather than Haskell natively during one of my many "let's try to learn Haskell again" periods!)

Lone Ranger18:08:00

haha that makes sense to me! I think one of the issues may be that ... well, the success of Python largely comes from the fact that it is designed to be "readable" at the expense of obfuscating a lot of the computer science behind it.

Lone Ranger18:08:12

Now it would be fantastic for a lot of senior dev folks who want a sane language while taking advantage of a vast array of tools


Python 3 is a very nice language. And it's good for beginners. Do any other languages target the Python VM?

Lone Ranger18:08:17

not that I'm aware of

Lone Ranger18:08:58

It's excellent for beginners, and for technical non-developers like scientists and mathematicians. It can be madness for career software developers though

Lone Ranger18:08:30

plus... c'mon... repl driven development

Lone Ranger18:08:45

I'd trade in 75% of Python's speed for a REPL

Lone Ranger18:08:08

True, but it wouldn't be necessary to compile to byte-code


Clojure's REPL -- and the ability to run it inside remote production processes -- is extremely powerful, I agree.

Lone Ranger18:08:25

You could transpile and then compile that to byte-code


Who is this "You could..."? ๐Ÿ™‚

Lone Ranger18:08:52

"One" could lol.

Lone Ranger18:08:16

Much like how ClojureScript running on node.js doesn't require advanced optimizations


If you wanted, you @goomba could start with the ClojureScript source and create a version that generated Python instead of JS I guess...

๐Ÿ™‚ 4

I think the first versions of clojure generated java source. That's my memory.

Lone Ranger18:08:03

Well, I've been considering it @seancorfield... but I'm concerned that I'm overlooking something obvious. It's like the old joke... an economist and his friend are walking down the street. Economist walks past a 20 dollar bill. Friend says, "why didn't you pick that up?". Economist says, "That's impossible. Law of efficient markets says someone would've picked up the 20 already, therefore it doesn't exist"

Lone Ranger18:08:26

I feel like if it was a good idea it would've at least been mentioned by the core team, but I feel like there's some unspoken reason they haven't even mentioned it

Lone Ranger18:08:24

and it would be a bit of a fool's errand to embark on a journey that could be killed by a single member of the core team later on saying it's a bad idea ๐Ÿ˜ฌ


I don't understand why you think it could be killed by a member of the core team saying it's a bad idea. I also see no reason why they would ever try to stop someone from doing such a thing. They would protect the trademark on the name Clojure that Rich Hickey owns, but you can call it anything else that isn't trademarked by someone else.


There is also recent work making for easier interaction between a Python engine and Clojure. Will find a link in a bit.

andy.fingerhut19:08:31 There is a group of Clojure enthusiasts, looking to create new libraries/code that make Clojure a better choice for machine learning / data science, by taking advantage of Python libraries more easily.

Lone Ranger18:08:45

so that's why I'm asking ๐Ÿ˜ฌ


I don't think anyone in the core team would ever call it bad idea.


Back in the day, in my PhD work, I started by writing a Lisp subset interpreter in Pascal, then I designed and implemented an ML-family language (which was to be the subject of my research, along with GC implementation stuff), that transpiled to Lisp in order to run on the interpreter. A couple of times since I got into Clojure back in 2010 I've toyed with the idea of resurrecting that ML-family research language with a transpiler on top of Clojure... and then I'm like "Welp, Clojure is just more fun to use so why bother porting SURE?" ๐Ÿ™‚

๐Ÿ’ฏ 4
Lone Ranger18:08:42

the real secret reason I want this language is because I love Clojure but there's so much money in Python right now >.<


The core team won't care if folks create new implementations of Clojure targeting different VMs etc. They just won't be interested in it (beyond a general curiosity).


No one is going to kill your project. And I expect it would be a great learning experience.

๐Ÿ‘ 4
Lone Ranger18:08:23

the most challenging thing to port I've found so far is the for macro. That is really, really difficult and clever


So I think everyone is encouraging you -- but also cautioning that you'll likely be the only use for it ๐Ÿ™‚


FWIW, I'd totally use it! At least until management caught me.

Lone Ranger18:08:12

but now that I know the source code is available it might be easier! ๐Ÿ˜…


You might open clojure up to a whole new segment :) I think clojure is very enterprise.


Since for is a macro that produces Clojure code, you could just implement the lower-level functions and that for macro will work as-is.

Lone Ranger18:08:52

yep, that's a much better idea, since they already did all the hard work

Lone Ranger18:08:19

Is the clojurescript repl completely different than the clojure repl?


Different how?

Lone Ranger18:08:46

like, is it written in JavaScript ...?


Go read the source code on GitHub ๐Ÿ™‚

Lone Ranger18:08:12

bwahaha... is it part of the core code or is it something else?


ClojureScript's compiler is written in Java/Clojure and runs on the JVM.

Lone Ranger18:08:19

I guess that would be tools-deps code?


But there are other cljs implementations written in other languages I think? Lumo, Plank... (I don't touch cljs so I'm not familiar)


No, the clojure/clojurescript repo


Those are just building on top of the same compiler and embedding them into different JavaScript runtimes.

seancorfield18:08:47 has over 80 repositories containing a wide variety of projects @goomba


@dominicm Cool. I wasn't sure how much of the core clj/cljs stuff they actually reused.


100%, the novelty of these tools is clever tricks with the runtime. Lumo has a start-up time boost from a v8 memory copy feature

Lone Ranger18:08:01

:thinking_face: have some reading to do. Oy... I wish I could convince my employer to give me a couple of years to just focus on this


Rich burned through his retirement savings to do it. It's a big investment!

Lone Ranger18:08:33

Yeah. His wife is awesome for letting him do that. May he get paid back 1000 times over.


The most familiar Clojure not written in Clojure(Script) is probably joker (to me at least)


It's written in Go


> The use of keyword arguments has fallen in and out of fashion in the Clojure community over the years.


Trying to figure out if I should go with (create-task "something" :optional-setting true) or (create-task "something" {:optional-setting true})


iโ€™ve seen both being used, the latter more i think?


The latter is favored by some because it makes it more straightforward to call such a function after using all of Clojure's built-in machinery to create such a map, if desired.


For the implementer of such a function, it also means they can merely do merge or assoc to add more things to the map before calling additional functions that use the options map.

Alex Miller (Clojure team)19:08:27

we've got a new syntactic improvement in discussion that might actually make these the same

Alex Miller (Clojure team)19:08:37

given a function with map-destructured varargs, you could invoke it with a trailing map and get the same effect

โค๏ธ 20
Alex Miller (Clojure team)19:08:19

which would remove some of the current points of friction

Lone Ranger19:08:36

For what it's worth, @st3fan, I've found the former better for "public" APIs and the latter better for both public and "private" APIs, especially if you're doing a lot of map transformations, simple reason being that if I have a function signature like

(defn foo [& {:keys [a b]}] (+ a b))

;; simple to use directly but if 
(foo :a 1 :b 2)

;; passing in a map isn't so pretty
(apply foo  (flatten  (seq {:a 1 :b 2})))

Lone Ranger19:08:04

the problem becomes substantially exacerbated when you're using transducers

Lone Ranger19:08:38

so, although I tend to find the keyword style a prettier API, I think the map-style argument reduces the amount of adapter code required when composing fns


@st3fan FWIW, When I took over it was all keyword arguments everywhere and as I refactored it, that became a real pain to work with since top-level functions were always having to be apply'd to other functions instead of just calling them directly. Over time, I changed all of the API to use option maps and that made the library much easier to work with (although the migration was a bit painful for everyone involved). next.jdbc only supports option maps, not keyword arguments, because of my experience with,jdbc.

โ˜๏ธ 20

I honestly never understood the appeal. Itโ€™s a difference of a single keystroke (with editor paren handling).


Itโ€™s actually only ever gotten in my way. I have to constantly ask, โ€œIs this option map a real map or a fake map?โ€


The appeal of not making it a map? Or the appeal of making it a map?