Fork me on GitHub
#clojure
<
2020-02-13
>
roninhacker03:02:36

is there a way to list the signatures of a protocol?

vemv05:02:49

(:sigs MyProtocol)

šŸ’Æ 8
Ahmed Hassan06:02:51

What are signatures in protocol?

emccue05:02:21

Does anyone know of a short reference for all the java concurrency tools

emccue05:02:03

types of queues, countdown latches, etc?

vemv05:02:01

wdyt of the JCIP book?

andy.fingerhut06:02:20

Maybe not what some people would call "short", but very useful.

andy.fingerhut06:02:39

Here is a fun quote from Rich Hickey's talk in 2008 "Clojure Concurrency": "So that is the first: hard to understand, test, and reason about. But if you put concurrency in the mix, there is no doubt about it. Mutable objects are a disaster. They are a complete catastrophe, and I am going to show you exactly why. But I want you to understand that you do not have to believe me. I even carried a book this whole way. I just drove, so I did not actually carry it. But has anybody read this book? "Java Concurrency in Practice". How many people have read this book? Oh, boy, and all of these people are programming in Java. You have to read this book, because it is a fantastic book. And it is a book that will scare you to death, because what it basically says is: this is impossibly hard. It is just so difficult to get right."

leonoel07:02:03

@U3JH98J4R the javadoc for package java.util.concurrent is a good start

pbaille08:02:43

Hello, Iā€™m probably missing something here, any idea ?

(refer 'clojure.core :exclude '(val))
=> nil
(def val 1)
WARNING: val already refers to: #'clojure.core/val in namespace: user, being replaced by: #'user/val
=> #'user/val
I should not have this warning ??

p-himik08:02:11

I think when you start REPL, clojure.core is included by default, so that refer statement doesn't have any effect.

p-himik08:02:02

If you'd use a proper ns form, you could use (:refer-clojure :exclude [val]).

pbaille09:02:51

thank you @U2FRKM4TW , iā€™m aware of the possibility to exclude from an ns form, here the beginning of the referdocstring

refers to all public vars of ns, subject to filters.
  filters can include at most one each of:

  :exclude list-of-symbols
  :only list-of-symbols
  :rename map-of-fromsymbol-tosymbol
Maybe there is an exception for clojure.core + :exclude

p-himik09:02:38

As I said, when you execute REPL, clojure.core is already there - refer'ing it again does nothing. You can try combining it with in-ns because it will not load clojure.core in that new ns.

p-himik09:02:18

$ clj -r
Clojure 1.10.1
user=> val
#object[clojure.core$val 0x2375b321 "clojure.core$val@2375b321"]
user=> (in-ns 'test)
#object[clojure.lang.Namespace 0x736ac09a "test"]
test=> (clojure.core/refer-clojure :exclude '[val])
nil
test=> val
Syntax error compiling at (REPL:0:0).
Unable to resolve symbol: val in this context

pbaille17:02:47

thank you for the idea @U2FRKM4TW

Andreas S.09:02:21

Hello ! I'm runnig windows 10 and cygwin, I wanted to use : https://github.com/clj-python/libpython-clj

Andreas S.09:02:38

so my first step was : clone repo then : lein install

Andreas S.09:02:29

but this gives me an error: http://java.io.IOException: Cannot run program "clojure" (in directory...

sogaiu09:02:42

@andreas.scheinert if you don't get answers here, there's a #libpython-clj -- also the data science folks are pretty active over at zulipchat

Andreas S.09:02:05

thank you sogaiu

Andreas S.09:02:50

for the time beeing , maybe I took a wrong step to begin with, I'm used to lein and project.clj files , but carin meiers examples use deps.edn

Andreas S.09:02:21

could you point me to a tutorial or something howi turn her deps.edn example project to a lein project.clj one?

sogaiu09:02:46

@andreas.scheinert i don't have a tutorial like that on hand, but perhaps this sample from the libpython-clj creator that uses project.clj might be of some help? https://github.com/cnuernber/facial-rec

Andreas S.09:02:58

@sogaiu thank you I try this one!

šŸ‘ 4
Andreas S.09:02:36

thats so simple I wonder why its not included in the "official" example. It worked thanks @sogaiu!

šŸ™‚ 4
flowthing10:02:21

https://clojure.atlassian.net/browse/CLJ-2056 (efficient alternative for (first (filter pred coll))) was rejected on the grounds that linear search leads to poor performance. However, I often find myself in a situation where I need to do it, especially when dealing with data from external sources. Is my best bet to just keep doing some variant of (first (filter pred coll)), or is there an alternative way to approach this problem?

Rutvik Patel10:02:03

I was looking at a jar file created using lein uberjar, and to my astonishment, it contains clj files as it is. How does java command handle it? Where can I find more information on it? Or am I looking at wrong place for .class files?

Ivan Koz10:02:30

main idea is that in basic case clojure code compiiles on runtime

Rutvik Patel10:02:05

Nooooooo šŸ˜®

Rutvik Patel10:02:53

It means, compilation phase includes "reader" as well?

Rutvik Patel10:02:34

I definitely need to watch it, it's been recommended second time in last few days. šŸ˜„

Ivan Koz10:02:37

also it's good to know that clojure's minimal compilation unit is a top level s-expression\form, but there is some AOT functionality present like gen-class, usually for calling clojure from java.

Rutvik Patel10:02:07

What is "a top level s-expression\form"? If you could elaborate..

Ivan Koz10:02:05

it's the most outward expression or single value

Ivan Koz10:02:59

take a look at any clj source file you will see that there is a sequence of top level forms separated by new line (ns ...) (defn ....) "string" 5

Ivan Koz10:02:04

it's kind of the root of the expression

Rutvik Patel10:02:32

Oh okay. That makes sense. Thanks!

grounded_sage11:02:17

Iā€™m trying to follow this tutorial for using Docker and Postgresql but Iā€™m getting this error when I follow the steps. https://circleci.com/blog/package-a-clojure-web-application-using-docker/

user=> (dev)
CompilerException java.lang.IllegalArgumentException: Must hint overloaded method: toArray, compiling:(clojure/core/rrb_vector/rrbt.clj:282:1)

p-himik12:02:26

Seems like you have an old version of rrb-vector with JDK 11 or newer. Try adding [org.clojure/core.rrb-vector "0.0.13"] to your dependencies.

yannvahalewyn11:02:49

Is (seq big-lazy-seq) lazy? We use this pattern often: (when (seq x) (process x)). Weā€™ve been having Java Heap memory errors in a job that processes a big lazy sequence in batches (~1M records, 4 jobs in parrallel). Removing the (seq records) solves our problem. Memory usage would keep growing and GC would fallback on old-gen. These are our jvm opts:

-Xmx${max_heap_size} \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=100 \
  -XX:-OmitStackTraceInFastThrow \
  -XX:+HeapDumpOnOutOfMemoryError \
  -Duser.timezone=UTC \
  -Duser.country= \
  -Duser.language=en \
  -Djava.rmi.server.hostname=localhost \
And here is a JMX screenshot of running the job with and without it. Our understanding was that this was the recommended way to check if an iterable is empty, is that still valid / is there something else going on here?

jumar13:02:10

How big is that ā€œlazy seqā€ and how exactly do you process it in parallel?

jumar13:02:42

Could also help to clarify (show code) how exactly itā€™s created

Ivan Koz11:02:47

@yannvahalewyn as far as i can see, seq is not lazy, it will realize LazySeq into a Cons seq

Object ls = sv;
		sv = null;
		while(ls instanceof LazySeq)
			{
			ls = ((LazySeq)ls).sval();
			}
		s = RT.seq(ls);
		}
	return s;

Ivan Koz11:02:18

and each ls.sval() calls invoke() on a function wrapped by lazy-seq

yannvahalewyn11:02:52

Hmm, thanks for replying. Iā€™m pretty confident seq will and should stay lazy though.

(defn my-inc [x] (println x) (inc x))
(take 10 (seq (map my-inc (range 200))))
;; prints out 0-31

Ivan Koz11:02:12

take returns lazy seq

Ivan Koz11:02:21

map will be realized

Ivan Koz11:02:51

let me see just to be sure

yannvahalewyn11:02:10

(do (seq (map my-inc (range 200))) nil)
Same behavior though

yannvahalewyn11:02:22

Thanks @nxtk for thinking along! We have the same issue if we do (when (first records)). The thing that confuses me is that next we (partition-all 500 records) and that causes no issues whatshowever. This indicates there must be an issue upstream of some sort, but Iā€™m not sure what I am looking for. Does anybody have some ideas what may cause this behavior?

Ivan Koz11:02:35

too demonstrate

(defn my-inc [x] (println x) (inc x))
=> #'sicp.core/my-inc
(def xs (map my-inc (range 5)))
=> #'sicp.core/xs
(realized? xs)
=> false
(def ts2 (take 5 (seq xs)))
0
1
2
3
4
=> #'sicp.core/ts2
(realized? xs)
=> true

yannvahalewyn11:02:58

well it will realize up to 32 elements, for memory optimisations

yannvahalewyn11:02:09

my repl is broken šŸ˜… , can you try with 100?

Ivan Koz11:02:52

ok you are actually right ^_^

Ivan Koz11:02:59

let's dig deeper then

Ivan Koz11:02:20

i totally forgot about chunking

yannvahalewyn11:02:17

So weā€™re looking for something wrong that makes it so that using (for [batch (partition-all 500 x)] ...) wonā€™t blow my laptop up, but (when (seq x) (long-process x)) and even (when (first x) (long-process x)) will :thinking_face:

yannvahalewyn11:02:59

where long-process is the batch loop being wrapped by the when clause

yannvahalewyn12:02:50

and x is a lazy seq which comes from a streamed json from s3. To be clear and avoid XY problems, all streaming works without issues without those when clauses. And what we need is to see if there is something to process, and that is essential (itā€™s a sync job, old data gets deleted and replaced).

Ivan Koz12:02:20

as a wild guess does it output something, where xs is your big-lazy-seq

(filter (comp (partial not= LazySeq) second)
        (map-indexed #(vector %1 (type %2)) 
                     (filter seq (take 1000 (iterate rest xs)))))

Ivan Koz13:02:49

@yannvahalewyn (import clojure.lang.LazySeq)

Ivan Koz13:02:19

can it be that your lazy seq is not really lazy at some point?

yannvahalewyn13:02:42

Wel it is a clojure.lang.LazySeq

Ivan Koz13:02:56

that means that first node is lazyseq

yannvahalewyn13:02:30

But it appears that something is making it unlazy, removing the seq keeps it lazy which is still boggling my mind

yannvahalewyn13:02:36

but we solved it in another way though

Ivan Koz13:02:38

what if node n inside chunking range is not lazy?

yannvahalewyn13:02:43

now itā€™s more about curiosity šŸ™‚

yannvahalewyn13:02:10

Iā€™m not sure what you mean, can you elaborate?

Ivan Koz13:02:29

lazy-seq is a chain of LazySeq objects

Ivan Koz13:02:14

at one point you can have something like that

(def xs (lazy-seq (cons 1 (cons 2 (lazy-seq (cons 3 (cons 4 nil)))))))

Ivan Koz13:02:45

above code should tell you which nodes of the seq are not Lazy, if there is any

yannvahalewyn13:02:58

yes, all objects are from the same source, and there is not cons or concat upstream. Itā€™s an all or nothing thing in this case. youā€™re never sure ofc, but the source is one big json array being streamed and parsed from s3

Ivan Koz13:02:36

yeah thats why i proposed to run above code

(filter (comp (partial not= LazySeq) second)
        (map-indexed #(vector %1 (type %2)) 
                     (filter seq (take 1000 (iterate rest xs)))))
=> ([1 clojure.lang.Cons] [3 clojure.lang.PersistentList])

Ivan Koz13:02:45

just a wild guess

yannvahalewyn13:02:47

I actually already did this šŸ™‚

yannvahalewyn13:02:57

Nothing came up sadly

Ivan Koz13:02:06

i see, gonna watch star trek and continue to think about that

Ivan Koz13:02:10

keep me posted

yannvahalewyn13:02:14

Thanks for helping!

yannvahalewyn13:02:45

We solved it by counting the imported objects at the end of the transaction before persisting, and skipping out if it was empty though. So Iā€™m gonna keep on with my other work now šŸ˜‰ . Thanks again!

šŸ‘ 4
Ivar Refsdal22:02:32

Could it be that (when (seq x) ... creates a local variable and that using (seq x) makes the code hold onto the head of x (and cached values)? Just my guess after some googling. Edit2: This is not the case.

(defn process [x]
  (count (second x)))

(defn doit [x]
  (when (seq x)
    (process x)
    #_(first x))) ; uncomment this to create OutOfMemoryError

(comment
  (doit (split-with #(< % 12) (range 1e8))))
From this I think we can conclude that seq in itself is not the problem. Ref: https://clojure.org/reference/lazy#_dont_hang_onto_your_head https://stackoverflow.com/questions/15994316/clojure-head-retention

Ivar Refsdal22:02:50

Interesting discussion šŸ™‚

Andreas S.12:02:36

hello! it seems to me that I have a problem with my clojure installation, currently I only have lein installed and when I try to run "lein repl" on this repo ( https://github.com/clj-python/clj-template) I get: http://java.io.IOException: Cannot run program "clojure" ...

p-himik15:02:02

Have you tried installing Clojure?

Andreas S.15:02:50

I did and it claimed success

p-himik15:02:26

So, can you run clojure in a fresh terminal session?

Andreas S.15:02:25

yes that gave me:

Andreas S.15:02:25

clojure Error: Could not find or load main class clojure.main Caused by: java.lang.ClassNotFoundException: clojure.main

p-himik15:02:37

There's a million things here that could go wrong to cause such an error. Without being actually able to look around in your environment, I'd recommend just removing anything that you can find on clojure in your PATH and installing it again.

Andreas S.15:02:47

Maybe I try tomorrow, thank you for your help!

pinkfrog15:02:03

is there a succinct way of writing assoc the k-v if k doesnot exist in the map?

vemv16:02:40

assoc-some can be handy https://github.com/weavejester/medley/blob/a4e5fb5383f5c0d83cb2d005181a35b76d8a136d/src/medley/core.cljc#L38 Generally I find it a tight lib, with genuinely 'missing' stuff

bronsa15:02:32

if you don't care about the not-present/nil distinction then update

bronsa15:02:33

user=> (update {} :foo (fn [v] (or v 1)))
{:foo 1}
user=> (update {:foo 2} :foo (fn [v] (or v 1)))
{:foo 2}

bronsa15:02:12

otherwise no, you have to use contains?

p-himik15:02:39

Also, (fn [v] (or v 1)) is the same as (fnil identity 1). Assuming you don't care about false values.

šŸ‘ 4
pinkfrog16:02:25

Given a macro: user=> (defmacro m [x] #_=> `(prn ~@x))

pinkfrog16:02:55

(m (list 1 a)) works. But

pinkfrog16:02:05

(def b [1 2]) (m b) failed.

pinkfrog16:02:43

why cannot the macro accept a symbol, but is allowed to accept a function result?

Daniel Stephens16:02:01

~@ can only act on a sequence, the symbol b is not a sequence (even if its runtime value is), '(list 1 a) is a sequence of 3 things, the symbol list 1 and the symbol a

pinkfrog16:02:10

so it has nothing to the function list, itā€™s just ā€™() is the list.

Daniel Stephens16:02:45

yep, that's as I understand it

Daniel Stephens16:02:12

one thing I find quite helpful for understanding macros that you might not have seen is macroexpand, running for example: (note the backtick before the expression)

(macroexpand `(m (list 1 a)))
produces:
(clojure.core/prn clojure.core/list 1 user/a)

grounded_sage17:02:46

Is there a simple hello world example of using tools.deps with docker?

borkdude17:02:53

do you mean install it inside a docker container? specify "with"?

grounded_sage17:02:47

I canā€™t seem to run clj with this docker image. https://hub.docker.com/_/clojure

grounded_sage17:02:29

And there is no clear examples of getting up and going with docker that I can find.

grounded_sage17:02:12

I thought I would be able to get going quickly but seems I will need to learn docker before I can get going

lukasz17:02:43

It would be helpful to understand why do you want to run Clojure in docker - is for shipping production workloads? Working locally? By default clojure image ships with Leiningen, you can start it with docker --rm -it clojure lein repl

grounded_sage17:02:11

im using tools deps

grounded_sage17:02:04

I need to use docker because thatā€™s how everything is deployed at work and they want it that way for consistency. Iā€™m unfamiliar with this area as I am coming from front end.

lukasz17:02:07

That still doesn't answer the question - do you have some sort of backend written in clojure that you need to run locally via Docker (totally doable)? Do you want to work on a Clojure project and use Docker to develop a Clojure application (AFAIR not doable ergonomically)?

grounded_sage17:02:34

Ah sorry @lukaszkorecki I see what you mean. I have to develop against a Postgresql database locally and deploy it to AWS, likely several microservices all doing very much the same thing. The purpose is data preprocessing for data scientists.

seancorfield17:02:36

@grounded_sage Why not develop in the most convenient way for you and then package the apps as uberjar files and run them inside Docker with java -jar ...?

seancorfield17:02:03

Then you don't need anything inside the container except a JVM.

grounded_sage18:02:29

Iā€™m unsure how all of this works so I canā€™t really comment. All I know is they want me using docker and pretty much every google search for docker and clojure results in. ā€¢ Donā€™t use docker ā€¢ We use docker but are not sharing how we did it - ( for whatever reason that may be, which is okay but somewhat frustrating compared to other lang ecosystems )

lukasz18:02:53

Usually Docker is used for packaging and deploying things, or running things like databases or already built services/apps

lukasz18:02:12

I'm not sure if you can develop in Docker, at least because of the file synchronization issues

grounded_sage18:02:50

Is there simple examples of a deploy?

lukasz18:02:08

That's a whole different can of worms, out of Clojure's scope really - do you have many hosts? one? Where are you deploying (aws? google?) - can you actually deploy etc etc etc

seancorfield18:02:12

If you produce an uberjar from each of your Clojure apps, all you care about is "deploying Java apps with Docker"

šŸ‘ 4
grounded_sage18:02:29

Yea this seems like itā€™s going to be the best option. I think I just need to learn Docker more because trying to copy/adapt what I find online is simply not working

andy.fingerhut18:02:57

Whoever the "they" is in your statement "they want me using docker", if they do it, they should have working examples for what they already do, I would think.

andy.fingerhut18:02:53

But there are plenty of jobs where knowing something about docker is essential.

grounded_sage19:02:05

Well itā€™s the CTO of where I work. At present I am the only Clojure dev amongst all python devs. So my challenge is integrating into a unified way to work with their system and show the value of Clojure

seancorfield18:02:43

https://dzone.com/articles/run-simple-jar-application-in-docker-container-1 -- from the part about adding HelloWorld.jar to Docker

šŸ‘ 4
seancorfield18:02:52

You'd want whatever base Java Docker image your company is using but it's effectively as simple as develop in Clojure locally, build an uberjar (using whatever build process you prefer: lein, boot, CLI/`deps.edn`) and then create a basic DockerFile that adds your JAR file to a Java-based docker image.

grounded_sage18:02:14

Yea this is starting to make sense. Docker is just meant to be a container for deployment after all

ghadi18:02:12

I run Clojure in ECS Fargate, and I donā€™t even bake my uberjar into the image. Instead I use two containers, one that downloads the jar from S3 into a place accessible to the other container. The other container is a plain openjdk container with zero modifications

šŸ‘ 12
ghadi18:02:48

Fargate calls these container dependencies, K8S calls it ā€œinit containersā€

ghadi18:02:22

The jar pulling container only pulls the jar then dies with exit code 0

ghadi18:02:27

Whatever you do, just use java not lein/`boot` to start your app

āž• 12
kulminaator18:02:28

my install method for java apps is similar, a freshly booted instance will figure out by itself what it needs to pull from s3 and run

kulminaator18:02:10

and obviously asg iam roles guarantee access to the s3 objects accordingly per app

ghadi18:02:14

I do this because I have no need to add anything to the java docker image besides my jar, and complicating my CI with docker build/push isnā€™t worth it

grounded_sage18:02:06

Does a postgresql db being included increase the benefit of Docker?

ghadi18:02:27

I donā€™t understand the q

grounded_sage19:02:40

All good. I am a design/front end developer turned back end. I donā€™t know enough to know the right questions :)

ghadi19:02:32

Generally containers should do one thing

ghadi19:02:47

Run java, Run a database, not both

grounded_sage19:02:45

I guess I am tripped up because I see all these dockerfiles downloading dependencies and building the apps

seancorfield19:02:22

Yeah, I've no idea why all the tutorials seem to be so complicated. Hopefully that one I linked you to on DZone is simpler?

ā¤ļø 4
grounded_sage10:02:14

Was exactly what I was looking for @seancorfield thank you!

lilactown19:02:35

A common way to develop services is to have postgres and other non-Clojure services running in separate docker containers, because that way you can quickly start them up without installing them and ensure you have the same version and similar configuration as when it is deployed, etc. However, the clojure service you are developing is not run inside a docker container because itā€™s much easier to start a REPL. When deployed, you might want to run your Clojure service inside of docker container to standardize and version the deployment environment, or use services like kubernetes / ECS / etc. It will typically talk to databases and other services that are outside of its container, though

grounded_sage19:02:48

Thanks @lilactown thatā€™s a very clear response.

seancorfield19:02:09

At work, I have Docker running MySQL (Percona 5.7), Elastic Search, and Redis -- docker-compose up i I need to get a dev env up and running -- then do all my Clojure dev directly via the REPL from my editor (including running tests etc), with occasional more complete test suite runs via the terminal/command-line. Then we build (uber) JAR files for each process and that's run via java -jar in production (we run on servers but it would be identical in Docker really) and all the database/search services are all running elsewhere in production (on a mixture of private and public cloud).

lukasz20:02:54

Our setup is somewhat similar: locally compose manages databases, rabbitmq etc and also can run our services streight from docker. In production we use managed services as much as possible, and deployments are just ansible runs pulling new versions of the container and restarting them. Our Dockerfile for Clojure uses multi stage builds with lein doing uberjarring and final container being just the JDK running the uberjar

grounded_sage20:02:48

@lukaszkorecki Iā€™m curious as to what the multistage builds side of things are. Though it seems that most people using a docket file with build commands are using lein

kwladyka20:02:49

https://github.com/kwladyka/fy-stock/blob/master/Dockerfile here is good example how you can use multi stages

kwladyka20:02:51

other example I have not in public repositories

MatthewLisp21:02:22

Can i see via REPL which protocols a Record is implementing ?

seancorfield21:02:02

@matthewlisp (ancestors RecordName)

seancorfield21:02:26

That will show all the types the record implements including protocols.

seancorfield21:02:27

user=> (defprotocol Foo (bar [x]))
Foo
user=> (defrecord Quux [y] Foo (bar [_] y))
user.Quux
user=> (sort-by str (ancestors Quux))
(java.lang.Object clojure.lang.Associative clojure.lang.Counted clojure.lang.IHashEq clojure.lang.IKeywordLookup clojure.lang.ILookup clojure.lang.IMeta clojure.lang.IObj clojure.lang.IPersistentCollection clojure.lang.IPersistentMap clojure.lang.IRecord clojure.lang.Seqable .Serializable java.lang.Iterable java.util.Map user.Foo)
user=> 
See user.Foo in the ancestors list?

Ivan Koz21:02:58

@seancorfield ancestors is a superset of supers?

MatthewLisp21:02:04

i think i wasn't clear about what i want

MatthewLisp21:02:23

i want to know what protocols an INSTANCE of a record implements

MatthewLisp21:02:29

if that's even possible

MatthewLisp21:02:00

and if the output come along with this huge list, it won't be of much use to me šŸ˜ž

seancorfield21:02:04

(ancestors (type instance))

MatthewLisp21:02:14

i wanted only what i've written

seancorfield21:02:34

It's a set, you could easily remove the standard ones that all records implement.

seancorfield21:02:43

@nxtk ancestors is a superset of supers, yes. I've never actually used supers -- I had to doc it in the REPL and then look at the source of ancestors to see it calls supers if it is passed a class instead of a tag .

seancorfield21:02:39

user=> (defrecord base [])
user.base
user=> (def base-types (supers base))
#'user/base-types
user=> (apply disj (supers (type (->Quux 42))) base-types)
#{user.Foo}
user=> 
^ @matthewlisp

seancorfield21:02:55

"It's just data" šŸ™‚

šŸ“æ 4
MatthewLisp21:02:26

so beautiful....

Alex Miller (Clojure team)21:02:38

note this won't tell you if someone has installed a protocol externally for a record

Alex Miller (Clojure team)21:02:12

and because that's an open set, there is no way to answer the general question (although you could answer it for specific protocols)

MatthewLisp21:02:39

it's just for local protocols defined by myself

seancorfield21:02:11

True. Now you can extend protocols via metadata on objects, that changes the game a bit.

MatthewLisp21:02:57

i'm making a little guide for my team-mate, we use Integrant lib at work

MatthewLisp21:02:07

turns out we use Records + Protocols combo, and i was searching a way to dynamically find out which is the protocol that a Component in the system is implementing, so this way he can found it's "methods"

MatthewLisp21:02:37

could be better if i could print out the name of the function(s) the protocol is specifying

MatthewLisp21:02:41

but that's enough for now

Alex Miller (Clojure team)22:02:06

protocols are maps that have a map of methods in them

šŸ˜€ 4
Alex Miller (Clojure team)22:02:18

user=> (defprotocol P (a [_]) (b [_]))
P
user=> (:sigs P)
{:a {:name a, :arglists ([_]), :doc nil}, :b {:name b, :arglists ([_]), :doc nil}}

markaddleman22:02:07

Do protocols and spec play nice together? I have spec predicate

(partial satisfies? protocol/ToHoney)
When I'm conforming a larger document which contains a record that satisfies the protocol, I get the following exception:
java.lang.UnsupportedOperationException: Can't create empty: pyze.query_generator.pql.HoneyLiteral
	at pyze.query_generator.pql.HoneyLiteral.empty(pql.clj:70)
	at clojure.core$empty.invokeStatic(core.clj:5247)
	at clojure.core$empty.invoke(core.clj:5241)
	at clojure.spec.alpha$every_impl$cfns__2235$fn__2241.invoke(alpha.clj:1277)
	at clojure.spec.alpha$every_impl$reify__2254.conform_STAR_(alpha.clj:1291)
	at clojure.spec.alpha$or_spec_impl$fn__2115.invoke(alpha.clj:1089)
	at clojure.spec.alpha$or_spec_impl$reify__2118.conform_STAR_(alpha.clj:1100)
	at clojure.spec.alpha$or_spec_impl$fn__2111.invoke(alpha.clj:1065)
	at clojure.spec.alpha$or_spec_impl$reify__2118.conform_STAR_(alpha.clj:1100)
	at clojure.spec.alpha$conform.invokeStatic(alpha.clj:164)
	at clojure.spec.alpha$conform.invoke(alpha.clj:160)

markaddleman22:02:16

Spelunking a bit into spec source, it looks like this condition is triggered by including the protocol spec within an s/or

Alex Miller (Clojure team)23:02:34

I think there is actually a ticket about this problem

Alex Miller (Clojure team)23:02:58

it's a bug, and I've spent some time working on it in the past. it does not have an easy solution.

Alex Miller (Clojure team)23:02:36

it's not the protocols, it's the data being passed in I believe

markaddleman23:02:38

oh ok. look like you already have a repro case but let me know if there's something i can do to help

zilti23:02:17

Anyone knows what's up with core.typed? I thought I'd look what its state is, and to my surprise, the repo seems to get regular, frequent updates. But to my disappointment, the documentation hasn't been updated in years and is completely useless...

Alex Miller (Clojure team)23:02:30

Ambrose just started working on it again recently and has been re-merging previously split libraries

Alex Miller (Clojure team)23:02:41

I am not sure he's at a point where the docs can be regenerated yet

Alex Miller (Clojure team)23:02:08

so I think you've just caught it at a particularly bad time

zilti23:02:14

Ah, I see.