clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
Jack Arrington 2020-11-13T00:05:47.408600Z

If I have a custom list type that I've implemented with deftype, and I want to make it so that I can call (map) on it, what do I have to do? Implement ISeq, ISeqable, both?

2020-11-13T00:15:55.408800Z

ISeqable I think is all you need

👍 1
1
cursande 2020-11-13T00:55:22.411200Z

Hi 👋 Bit of a crapshoot, but anyone had success instrumenting async web requests with newrelic and netty server running via clojure? I'm looking to add in newrelic instrumentation on specific endpoints for a netty server run via aleph. I'm following this old guide from sean https://corfield.org/blog/2013/05/01/instrumenting-clojure-for-new-relic-monitoring/, and this lib https://github.com/TheClimateCorporation/clj-newrelic implements the same approach and works great for us when instrumenting code running on clojure services running jetty. Following the newrelic docs on async I get either transactions with incorrect times (as deferred value is returned immediately I assume) or I can see in logs transactions are not created despite adding :dispatcher and :async to true on the method annotation.

seancorfield 2020-11-13T00:57:20.412500Z

@adfarries No, unfortunately. Our Jetty-based services are monitored just fine via New Relic, but our one Netty-based service shows almost nothing useful.

seancorfield 2020-11-13T00:58:51.414100Z

We've used New Relic's "metrics publish" library (I think you can d/l the source from their GitHub repo and build it yourself), and the NR agent to allow us to write plugins that send all sorts of specific metrics to New Relic -- they don't show up in APM, only under Plugins, but you have a lot of control over what you publish.

👍 1
seancorfield 2020-11-13T00:59:47.414600Z

https://github.com/newrelic/metrics_publish_java -- I see V2 is archived, we're on V1 from ages ago.

seancorfield 2020-11-13T01:00:16.415200Z

(I suspect, at some point, we'll have to revisit/update all our plugins)

cursande 2020-11-13T01:05:06.417900Z

@seancorfield thanks. I was hopeful that updating to latest agent, agent-api etc. and following NR's docs on custom async instrumentation would get me there, but unfortunately I'm just not seeing much of value. Segments 'work' in a very naive sense but make no sense in the transaction context

cursande 2020-11-13T01:06:00.418800Z

will keep chipping away + try with plugins, if I find a sensible solution I might post it up somewhere

rgm 2020-11-13T01:55:21.423500Z

I have a core.cache question (I think, or at least I’m musing about implementing something with core.cache): I want to generate on-disk temp PDF files and have them disappear after say, an hour. The cache holds an identifier and a path to the file, to be fed out of a jetty server with the identifier in the request URL. It’s fine if the URL 404's after an hour. I got to thinking: would a TTL cache be able to handle this use case? I’m trying to figure out if I could directly supply a function that unlinks the on-disk PDF on eviction, or if this is best done by implementing a custom version of the TTL cache with CacheProtocol evict wrapped?

2020-11-13T14:32:08.461Z

https://github.com/ben-manes/caffeine looked extremely promising to me

🙏 1
phronmophobic 2020-11-13T01:59:11.423600Z

does the pdf have to be written to disk or could it be cached in memory?

rgm 2020-11-13T01:59:39.423900Z

I wasn’t excited about keeping them in memory; they’re running about 200-300kb each.

rgm 2020-11-13T01:59:48.424100Z

but not impossible, I suppose.

phronmophobic 2020-11-13T02:00:04.424300Z

that's fair.

phronmophobic 2020-11-13T02:00:36.424500Z

another option I might consider is to have a temporary folder and have a background process that runs every hour and deletes any files older than an hour

phronmophobic 2020-11-13T02:01:36.424900Z

it makes worrying about "what happens if the server crashes or restarts" type of issues less of a problem

rgm 2020-11-13T02:01:54.425200Z

Yeah, that’s probably OK too… just yank the existing keys out of the cache as a set and if it’s not in the set, farewell PDF.

rgm 2020-11-13T02:02:38.425600Z

I was also considering stealing from https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/multipart_params/temp_file.clj

👍 1
2020-11-13T02:06:20.426Z

I would not recommend core.cache for that kind of thing, look at guava's caches

💯 1
🙏 1
2020-11-13T02:07:18.426200Z

core.cache is built around the idea of immutable caches as value

rgm 2020-11-13T02:08:58.426400Z

/ looks at https://github.com/google/guava/wiki, expires from unexpectedly broadened horizons /

rgm 2020-11-13T02:12:10.426700Z

yeah, I had just got to thinking an evict callback would let me be lazier but it sounds like I should probably think this through a little better.

seancorfield 2020-11-13T03:20:37.426900Z

Yeah, as the maintainer of core.cache, I would agree with @hiredman on this @rgm -- I don't think it's a great match for what you're trying to do.

🙏 1
dominicm 2020-11-13T03:42:45.427100Z

I felt bad when I saw your edits to my jira, because I'd done such a poor job. Not sure if there's a template feature, but I'd fill this out without forgetting if it was there by default!

danielglauser 2020-11-13T04:50:58.429500Z

I used to really enjoy using New Relic. We wrote some code to send statsd metrics to DataDog, that seems to be working well.

seancorfield 2020-11-13T05:19:41.429800Z

We're very heavily in bed with NR at this point, both front end and back end. It would take a seismic shift for us to switch to a different metrics solution I think...

seancorfield 2020-11-13T05:20:23.430Z

Not to say NR is "perfect" (it's not!) but it's "good enough" and easy for everyone to use, from backend to frontend to product management etc...

1
2020-11-13T13:21:44.431500Z

what is a current library for CLojure for building REST APIs ? And does anyone have any decent documentation ?

2020-11-13T13:30:42.432900Z

My stack is ring+jetty (aleph at work but I think jetty is enough for most use cases), https://github.com/exoscale/interceptor for the request lifecycle and https://github.com/exoscale/ex for error handling. For routing I use https://github.com/juxt/bidi

2020-11-13T13:32:12.433100Z

thank you! I'll take a look at those

borkdude 2020-11-13T13:35:48.433400Z

@qmstuart I like yada

2020-11-13T13:36:44.434Z

I worry when I goto github page for yada and no check ins in years, or does this jsut mean its pretty stable / finished ?

st3fan 2020-11-13T13:37:03.434300Z

that is the case with most clojure packages i am using right now 🙂

lukas.rychtecky 2020-11-13T13:37:13.434600Z

Consider https://github.com/metosin/muuntaja for data coercion and for routing https://github.com/metosin/reitit

st3fan 2020-11-13T13:37:14.434800Z

being new to clojure, not sure what to think of that yet

alexmiller 2020-11-13T13:40:50.436Z

why does everyone only trust software that changes all the time? seems counter-intuitive... :)

👍 4
2020-11-13T13:41:15.436500Z

not used to using libraries that arent full of bugs... and need constant patching 😄

😂 2
st3fan 2020-11-13T13:41:58.437Z

@alexmiller there is a difference between ‘all the time’ and ‘not updated in 9 years’ 😉

st3fan 2020-11-13T13:44:30.438700Z

in any case - i read the source and very often libraries that look like abandonware are just simple enough to not be worried

☝️ 1
Jonathan Doane 2020-11-13T13:45:38.439200Z

I think that there is a difference between not being updated because it’s been abandoned and not being updated because it’s stable.

st3fan 2020-11-13T13:47:12.440700Z

the world is not stable 🙂

Jonathan Doane 2020-11-13T13:47:20.440800Z

There are libraries that were written for 1.3 that still work with 1.10, so why update it if it isn’t broken and it works?

Jonathan Doane 2020-11-13T13:47:59.441300Z

The world might not be stable, but Clojure seems pretty solid.

👍 1
lukas.rychtecky 2020-11-13T13:49:12.442700Z

@st3fan I would say that in Clojure ecosystem it’s common that a library is not being updated for years and it’s still compatible with the latest Clojure and etc.

Jonathan Doane 2020-11-13T13:50:23.443700Z

Cognitect has been very good about not breaking backwards compatibility.

borkdude 2020-11-13T13:50:58.444600Z

@qmstuart We have been using yada for years. It's powering https://covid-search.doctorevidence.com/.

2020-11-13T13:51:29.445900Z

cool, i only need this api to be dead simple. It wont be public, it will be running on a machine and only taking a single POST request from that same machine.

st3fan 2020-11-13T13:51:40.446300Z

i think where it gets tricky is with libraries depend on Java packages or have to interact with the outside world - as an example, I was just looking at clj-yml, which wraps a 8 year old version of SnakeYAML - it is entirely possible that it has security issues

borkdude 2020-11-13T13:51:42.446500Z

fyi, the company behind yada is working on another framework (apex) but that's not production ready

borkdude 2020-11-13T13:52:32.447700Z

@st3fan you should be looking at https://github.com/clj-commons/clj-yaml for the most recent version which has a recent version of SnakeYAML (also available in bb)

borkdude 2020-11-13T13:53:09.448900Z

@qmstuart for something super basic, ring jetty + compojure is probably the "easiest"

👍 1
st3fan 2020-11-13T13:53:12.449Z

@borkdude i just pulled in snakeyaml and wrote a 3 line parse .. that is also another great option IMO - do not pull in massicve deps if your needs are simple

borkdude 2020-11-13T13:54:43.450300Z

@qmstuart Actually, babashka will let you create a ring app with it's built-in http server. if it's not performance critical, that might be the "cheapest" option in terms of project setup, etc: you only need one file

st3fan 2020-11-13T13:55:09.451Z

@qmstuart the thing i am working on only has one endpoint do i did not even bother with a router .. i am just using ring+jetty

2020-11-13T13:55:45.452100Z

yeah, we have a bash script / ps script on windows. It collects data and just want it to go to our local api, which can do some processing locally and fire it off to our rabbitmq queue

st3fan 2020-11-13T13:56:06.452600Z

if i add another endpoint i may just add a mini dispatcher myself, because a few lines of code is much simpler than new DSLs 🙂

borkdude 2020-11-13T13:56:44.453900Z

babashka doesn't even have a router at the moment. Just use (:uri request) and (:method request) and write your own thing ;)

👍 1
2020-11-13T13:56:52.454300Z

@borkdude, single small file would be nice. Current alternative is to write it all in Go (to get single small file), but I hate Go

st3fan 2020-11-13T13:56:53.454400Z

(where mini-dispatcher could very well be a defmulti dispatching on the path .. clojure has enough on board to do a lot of things very easily)

borkdude 2020-11-13T13:58:17.455300Z

This is the shortest example: https://github.com/borkdude/babashka/blob/master/examples/httpkit_server.clj

st3fan 2020-11-13T13:58:17.455500Z

i’m rewriting a GitHub app from Go to Clojure .. I love Go, but I’m currently at 50% functionality converted to Clojure in like 10% of code 🙂 🙂 🙂

2020-11-13T13:59:05.456400Z

using Go, after using things like C#, F#, clojure just feels like i'm missing so many features. Stuff that in those languages is easy feels really complicated in go when all you have is for loops and ifs

2020-11-13T13:59:51.457100Z

maybe getting used to higher level features has dumbed me down

borkdude 2020-11-13T13:59:55.457400Z

I know a project that uses Go but generates the Go code in Clojure: https://github.com/tzzh/pod-tzzh-aws

st3fan 2020-11-13T14:00:00.457600Z

lol

borkdude 2020-11-13T14:01:05.458200Z

@qmstuart So this would be a small web-app with instant startup.

borkdude 2020-11-13T14:01:29.458400Z

One caveat: I don't know if babashka can talk to your RabbitMQ. It doesn't have a built-in library specifically for that.

2020-11-13T14:01:39.458600Z

thanks, i'll have a look. bb seems a great alternative to trying to get graal native stuff working

dominicm 2020-11-13T14:58:28.461400Z

And also spin

dominicm 2020-11-13T14:59:20.461600Z

This is an active research area for Malcolm, but I've also been backporting pieces into yada where possible (e.g.I got reap working, and fixed a few bugs)

Vladislav 2020-11-13T15:10:52.461800Z

https://github.com/metosin/compojure-api

mpenet 2020-11-13T15:12:12.462100Z

is it the one using vertx?

mpenet 2020-11-13T15:12:56.462400Z

we also have a lab thing that wraps vertx server (it's called helix internally), I guess there could be crossed interests here

2020-11-13T15:17:01.462600Z

I’m curious what features you feel like you’re missing in clojure.

2020-11-13T15:17:34.462800Z

I dont feel missing any features in Clojure. I mean I feel a lot of things I use regularly in Clojure, C# and F# are missing from Golang 🙂

2020-11-13T15:17:51.463Z

ah gotcha

2020-11-13T15:17:56.463200Z

yeah, same

2020-11-13T15:18:19.463400Z

and it feels like every other line is if err != nil { }

👆 1
dominicm 2020-11-13T15:25:40.463700Z

I think so, yeah. Although I think (personally) that vertx isn't too interesting in the bigger picture. Just as a precedent for guiding the design of ring2's web sockets and such.

mpenet 2020-11-13T15:28:36.463900Z

right, not in apex context specifically

borkdude 2020-11-13T15:30:16.464200Z

I think it would be great if apex could be bigger than just juxt, so I would welcome this co-operation from a community perspective

borkdude 2020-11-13T15:30:47.464400Z

also the work that is happening in malli seems to co-incide with all the json schema stuff maybe

borkdude 2020-11-13T15:31:11.464600Z

so maybe a metosin / exoscale / juxt backed framework, could be great :)

👍 1
alpox 2020-11-13T16:51:32.465100Z

Im in the same boat. Also: working with dynamic datastructures in Golang is such a pain. Reflect much? 😬

fenton 2020-11-13T17:54:28.466900Z

can I do: #:person{name "joe"} instead of {:person/name "joe"} without having a valid namespace persondefined? Seems to work sometimes, but not others.

fenton 2020-11-13T17:55:11.467100Z

Warning :undeclared-ns in app/client.cljs at 17:1 `No such namespace: person, could not locate person.cljs, person.cljc, or JavaScript source providing "person"`

dpsutton 2020-11-13T17:55:37.467400Z

are you using #::person when that error happens?

fenton 2020-11-13T17:56:13.467600Z

{:person/id [#:person {id 1 name "Fenton" age 40}]}

fenton 2020-11-13T17:56:28.467800Z

shoot missed the second colon.

fenton 2020-11-13T17:56:37.468Z

sorry/thanks.

fenton 2020-11-13T17:57:19.468200Z

{:person/id [#:person {:id 1 :name "Fenton" :age 40}]}

dpsutton 2020-11-13T18:00:09.468800Z

hard to tell. is everything clear now or have you found the example that errors that you don't understand? also this might be better served in #beginners as its related to a bit of syntax

👍 1
hoynk 2020-11-13T18:08:17.471200Z

Is there any profiling lib that can easily point me to the slowest functions on the code? I am using ptaoussanis/tufte which is almost what I want, except I have to manually instrument my code.

2020-11-13T18:09:04.471800Z

there's nothing easy in my experience - laziness can move the cost of expensive calculations around at runtime

2020-11-13T18:09:35.472500Z

but a proper profiler (yourkit, visualvm) can help you find hot spots, once you get past the ways clojure breaks java assumptions

alexmiller 2020-11-13T18:21:27.473100Z

https://github.com/clojure-goes-fast/clj-async-profiler flame graphs are often a good quick check

jacklombard 2020-11-13T18:48:15.474200Z

Facing this possible memory leak in one of our Clojure apps, has anyone come across something similar before?

hoynk 2020-11-13T18:49:37.474500Z

Yup, I know, But I am used to sprinkle some doall's around for those times 🙂

2020-11-13T18:52:13.474700Z

it looks like something is creating a lot of nio channels and never closing them http://www.docjar.com/docs/api/java/nio/channels/SelectionKey.html

2020-11-13T18:54:07.474900Z

perhaps you have a global value holding connections to clients?

jacklombard 2020-11-13T18:56:32.475100Z

Can’t really tell, its a pretty big app but this has started happening in the last month.

jacklombard 2020-11-13T18:57:33.475300Z

I’ll read the docs

2020-11-13T18:58:50.475500Z

the clojure libs that would use nio channels would be eg. ring implementations, websocket libs

2020-11-13T18:59:12.475700Z

or maybe someone started doing prematurely optimized file IO and isn't closing the files

jacklombard 2020-11-13T19:00:16.475900Z

Is there a pattern of code that I can look for? Those channels being stored in some var?

2020-11-13T19:00:51.476100Z

the first place to look would be something that holds onto io handles so they can't be collected

2020-11-13T19:01:44.476300Z

but with nio you could well have some internal state that isn't cleaned up and closed on gc, so you'd want to look for file / network handles that get created but never get closed

2020-11-13T19:02:54.476500Z

also check if you have some process that accepts connections or watches files, that would be a likely culprit for creating all the io handles

jacklombard 2020-11-13T19:04:55.476700Z

Thanks for the pointers, going to have an interesting weekend hunting this

2020-11-13T19:16:35.477100Z

also, yourkit / visualvm have a graph view of who allocates / holds objects by type, so you could look for the owners of those objects

2020-11-13T19:17:01.477300Z

(likely that will be some internal of a lib like netty, and then you figure out who is using that lib's api etc.)

jacklombard 2020-11-13T19:31:05.477500Z

Right, but we haven’t enabled visual vm in prod and so can’t set it up any time soon. Would be really hard to pin point the culprit in local. But I think I already sort of know where the problem might be

mafcocinco 2020-11-13T19:32:58.479700Z

Is there a reason the clojure.set/intersection does not have zero-arity version which returns an empty set? This would make it usable in combination with reduce to find values that appear in every entry of a sequence. I’m guessing it is because returning the empty set is not always something one would want to do (i.e. there is some ambiguity in what the behavior of the zero-arity version would be).

2020-11-13T19:35:54.481400Z

user=> (reduce set/intersection [#{:a :b :c} #{:b :c :d} #{:a :b :d}])
#{:b}
I don't see a problem here

2020-11-13T19:36:16.481900Z

one of the few cases where implicitly using the first item in coll as the accumulator is a win

2020-11-13T19:37:07.482200Z

oh, right

(reduce set/intersection [])
Execution error (ArityException) at user/eval176 (REPL:1).
Wrong number of args (0) passed to: clojure.set/intersection

😪 1
Derek Passen 2020-11-13T19:38:11.482800Z

The intersection of an empty set and a populated set is an empty set

borkdude 2020-11-13T19:38:13.482900Z

@noisesmith https://github.com/borkdude/clj-kondo/issues/1064 ;)

2020-11-13T19:39:09.484300Z

but if set/intersection actually behaved correctly for zero args, requiring an init arg would make things worse

2020-11-13T19:39:21.484600Z

having implicit first arg acc actually fixes it

2020-11-13T19:39:57.485300Z

I guess your init acc could be "the set of all possible clojure values", but we have no way to represent it currently :D

borkdude 2020-11-13T19:40:04.485600Z

hmm good point :)

mafcocinco 2020-11-13T19:40:07.485800Z

@noisesmith exactly. @dpassen1 That is true but I’m not sure it is relevant for this discussion. The 1-arity version of intersection returns the set you pass in. The zero arity (which would be called when the sequence to reduce is empty) would correctly return the empty set.

borkdude 2020-11-13T19:40:49.486800Z

I guess the identity function is the set of all elements

2020-11-13T19:41:17.487500Z

@mafcocinco the hacky evil way to do this would be to reify the right interfaces so as to create an object that acts like it contains all values

2020-11-13T19:41:26.487800Z

the right fix is an improved set/intersection :D

borkdude 2020-11-13T19:42:32.489200Z

or use (when (seq ...) (apply set/intersection ...))

mafcocinco 2020-11-13T19:43:07.489700Z

Yeah. I solved it by creating a local intersects function with the proper arity as it is internal code. Just struck me as odd and I suppose it is good sign of how well clojure was put together that I assumed there was some logical reason vs. an oversight/mistake.

borkdude 2020-11-13T19:43:54.490500Z

@mafcocinco The usual reason is that in many cases there is no obvious identity element. E.g. - has no identity element, so (-) doesn't work. intersection is similar

mafcocinco 2020-11-13T19:44:39.491200Z

is it wrong that the (intersection) is #{}?

2020-11-13T19:44:55.491800Z

haha, my hack idea (never a good one in the first place), won't work because it wants to walk the first arg

mafcocinco 2020-11-13T19:45:42.493700Z

perhaps mathematically it is but I’m interested in what the pragmatic reason is for not doing it.

dpsutton 2020-11-13T19:45:45.494100Z

usually the return of that is the identity element. (+) is 0 because x + 0 = 0 + x = x for all x

dpsutton 2020-11-13T19:46:06.495Z

#{} is a zero element, not an identity under intersection

2020-11-13T19:46:14.495300Z

oh right, #{} isn't the identity, just a fixed point

mafcocinco 2020-11-13T19:46:41.496100Z

right. That makes sense. So in order to support (intersection) we would need a set-of-everything.

💯 2
2020-11-13T19:46:44.496300Z

the identity would be my above (impossible) set of all possible clojure values

borkdude 2020-11-13T19:47:07.496800Z

if intersection supported functions in addition to set objects, identity would be the set of all things

borkdude 2020-11-13T19:48:18.497800Z

but that is not really how it works

borkdude 2020-11-13T19:48:53.498700Z

btw, using apply is sometimes better than reduce since reduce will use the 0 or 2 arg of the function, while in many cases the varargs version is optimized.

borkdude 2020-11-13T19:49:20.499400Z

e.g. in the case of the set functions it will usually begin with the set that is of optimal size

mafcocinco 2020-11-13T19:49:50.499600Z

Good to know. thanks!

borkdude 2020-11-13T19:50:26.000200Z

similar for str: when you use reduce I think you will have many StringBuilders under the hood, but with apply only one

2020-11-13T19:51:50.001300Z

yeah, reduce would create a new StringBuilder for each arg

dpsutton 2020-11-13T19:51:56.001700Z

reduce str is almost always wrong

2020-11-13T19:52:47.003Z

and (reduce str [x]) wouldn't even make a string

mpenet 2020-11-13T19:52:56.003200Z

It's also quite easy to write a reducing fn for turning things into a stringbuilder in a single pass. Then you can transduce with it

2020-11-13T19:53:47.003800Z

(ins)user=> (reduce str [42])
42
(ins)user=>  (apply str [42])
"42"

dpsutton 2020-11-13T19:55:32.004700Z

i always felt like clojure.string/join would be more optimized but now i see it just delegates to (apply str coll) lol

borkdude 2020-11-13T19:55:45.004900Z

but str is optimized

dpsutton 2020-11-13T19:57:34.006800Z

i've never actually looked at the source until now to be honest

2020-11-13T23:44:26.008300Z

Hum, so you can't do?:

(create-ns 'foo.bar)
(require 'foo.bar)

2020-11-13T23:46:48.008600Z

what would the require do?

2020-11-13T23:47:05.009Z

or would you be running it for :as

➕ 1
2020-11-13T23:47:36.009600Z

use alias, that's what :asdoes under the hood

2020-11-13T23:48:07.010100Z

Fair enough, I just thought it was strange.

2020-11-13T23:48:33.010600Z

clojure uses a mutable database internally to keep track of what's been loaded

2020-11-13T23:48:43.010900Z

just creating the ns doesn't update the db

2020-11-13T23:49:32.011800Z

What's weird though is that create-ns will look it up and return the existing ns if there is one, or create a new one. So I'd have assume if creating a new one, it be added as well

2020-11-13T23:50:54.012500Z

Also, something doesn't add up, because: (alias 'foo 'foo.bar) fails if you don't first call (create-ns 'foo.bar)

2020-11-13T23:51:07.012900Z

alias needs the ns to exist

2020-11-13T23:51:17.013200Z

So clearly create-ns adds it to some global collection of namespaces

2020-11-13T23:51:27.013400Z

no, that's not what alias is using

2020-11-13T23:51:30.013700Z

$ clj
Clojure 1.10.1
(cmd)user=> (contains? (loaded-libs) 'clojure.set)
false
(ins)user=> (require 'clojure.set)
nil
(cmd)user=> (contains? (loaded-libs) 'clojure.set)
true
(ins)user=> (create-ns 'foo.bar)
#object[clojure.lang.Namespace 0x2bffa76d "foo.bar"]
(ins)user=> (contains? (loaded-libs) 'foo.bar)
false

2020-11-13T23:51:46.014100Z

well, it's not using the one loaded-libs provides, at the very least

2020-11-13T23:52:17.014900Z

Right, so it means there are two different collections of namespaces. I guess one for loaded and one for not loaded ?

2020-11-13T23:52:17.015Z

it's likely using the list returned by all-ns

2020-11-13T23:52:49.015500Z

all-ns is all namespaces, only some are considered loaded

2020-11-13T23:53:11.016100Z

but all-ns is a list of namespace objects, it's not keyed for lookup

2020-11-13T23:53:11.016200Z

Those would only be the ones created with create-ns 😛

2020-11-13T23:53:33.016700Z

it is all the namespaces period, no matter how you create them

2020-11-13T23:53:55.017100Z

But what other scenario is a namespace created but not loaded?

2020-11-13T23:55:20.018100Z

wait, by "those" in "those would only be the ones created by create-ns" what do you mean?

2020-11-13T23:55:30.018600Z

because all-ns contains every namespace object period

2020-11-13T23:55:37.019Z

Like, I'd expect that I can: create-ns which creates the ns, and then load it with require, but it seems you can't

alexmiller 2020-11-13T23:56:08.019800Z

require is about load

💯 1
alexmiller 2020-11-13T23:56:23.020400Z

create-ns is about in memory

alexmiller 2020-11-13T23:56:41.020800Z

Which happens as a side effect of load

2020-11-13T23:57:17.021200Z

But ns can create a namespace in memory, and then let you require it?

alexmiller 2020-11-13T23:57:40.022Z

But require is about load and there is nothing to load

2020-11-13T23:57:57.022600Z

What is there to load with ns ?

alexmiller 2020-11-13T23:58:01.022900Z

Or do you mean with ns

2020-11-13T23:58:31.024100Z

;; At repl:
(ns foo.bar)
(in-ns 'some-other)
(require 'foo.bar)

alexmiller 2020-11-13T23:58:51.025Z

If it’s already loaded, the load is short circuited

2020-11-13T23:58:52.025100Z

@didibus things like :as and :refer etc. in require are conveniences, and that usage of require is a no-op

2020-11-13T23:59:22.025600Z

So (ns foo.bar) will create the namespace and load it?

2020-11-13T23:59:28.025800Z

right

2020-11-13T23:59:45.026500Z

and put you in it too