Shouldn't Clojure have some reader macro to requiring-resolve symbols? That way we wouldn't have to use resolve-fn
s like in clojure.core.server for every function that might be invoked both from code and from clj -X:alias
We’ve slowly working towards making vars effectively do this
So if you read a var quote it would resolve locally and be invokable. We now do this for serialization of vars but haven’t yet made the reader change but I have it prepped in a ticket somewhere
ah, that’s wonderful
A very slow motion plan, maybe will come to fruition in 1.11 :)
Ah, they are read by edn, macro wouldn't work
Problem statement: clj -X:alias
puts a requirement on entry-point functions to be able to accept only edn-read data, thus making their use both from code and from entry point clunky if they are designed to accept non-data as arguments.
What do you mean by non-data? A resolved symbol (var or class or static field)? I think it’s a niche usage and you can work around it by having your own generic caller -X:call
that will perform any resolution you wish before calling your actual target.
functions, for example
I think it’s super common to configure functions with other functions. It would be nice if I didn’t have to invent 2 different APIs for the same thing because one useful context of invoking my code has no way to pass a function
For example, -X
(both in deps.edn
and on the command line) could use reader tag val
that does (comp deref requiring-resolve)
… That would not compromise on simplicity — it’s still just edn data — and will help library authors to not complect their code with resolve-fn
-s
What is "non-data" @vlaaad? I'm not sure that even makes sense...
And these are not "main" functions. -main
accepts a sequence of strings. -X
is for regular Clojure functions, which, last I checked, accept regular Clojure data... which is what you get from reading EDN... what am I missing?
I want to create a function for people to use both as main and from code
Why? What problem are you trying to solve with that?
You can already invoke -main
functions via the -m
argument to clojure
.
-X
is a way to invoke additional functions -- non-main functions.
-m
lets you invoke -main
functions with strings. -X
lets you invoke non-main functions with data.
Yeah, I've read it. Several times.
-X is entry point
it's a main
No. Not a "main".
a different kind of main
No.
okay, we have slightly different definitions of main
let's stick to entry point
-X
lets you invoke any function -- even private ones -- with data.
both -X and main are entry points
No. You're wrong.
You think there's a problem here because you're starting from an incorrect set of assumptions.
why -X is not an entry point?
Alex's post literally says that...
"entry point" just means you can call any function. You're ascribing too much significance to that.
-main
!= "entry point" in this case.
Also bear in mind that -X
allows you to call your -main
function with strings from the command line (with appropriate quoting) -- this is a more general feature, based on Clojure-is-about-functions-and-data. -main
is the old-school world of command-lines-are-strings thinking.
(it's 1 am here -- I'm off to bed!)
no, -X
does not allow to call -main
, because it will pass it a map, when -main
expects a seq of strings
good night 🙂
Oh yeah... It's almost a superset. It's certainly a more general feature tho'...
And good night.
So you could call -main
if you only want to pass a single string 🙂
Although I’m not surprised this works, I would expect it to be undefined behavior that we shouldn’t rely on :D
That is an interesting question -- is this defined/supported behavior. Hopefully @alexmiller can comment on that tomorrow.
Disagree on the top here -X should pass only 1 map to a function (that this works here is a bug)
It’s a bug -X should only invoke functions of 1 map
It’s not a superset of clojure.main
I suppose ":arg" is a more appropriate name, with there only being one
Well the idea is that it is a map of args
Kv args, not positional
Thanks for the clarification @alexmiller -- but if it's really "Kv args" as opposed to positional, shouldn't it be calling the function like (f :k 42 :foo "bar")
? If you want to make it clear that it really is intended to pass a single argument :arg
would make more sense than :args
(I agree with @dominicm on that).
And given the intent is to call the function with just a single hash map, you probably want to enforce that before people start abusing it (exactly as I was doing, apparently, and in particular by using it to call -main
with a single string argument)...
Oh, I will :)
And to @vlaaad: I was wrong and I apologize. We still disagree on "main function" as a definition I think but we agree on "entry point" and now it seems that they are disjoint features since you're not supposed to be able to use -X
to call -main
with a single string.
The other place, I can think of, where Clojure already uses :fn
/ :args
is for function specs and :args
there is explicitly a sequence of arguments (it catches beginners out that even for single-argument functions you need s/cat
) -- so I really do think the singular :arg
would be better here (or something more indicative of this being a single hash map argument). But I know we can often bikeshed on names so I'll leave it at that.
yeah, I am unswayed, not going to change
No problem! It's hard to admit mistakes — you are a good strong person :)
I didn't want to call -main from -X btw, just tried to come up with an api for my function that is accessible from both these entry points... And from code... All at the same time
Yeah, now Alex has clarified the intent of -X
it's clear they are disjoint entry points which is both good and bad. I think it means you're stuck with your cli in 10 lines
approach to -main
to allow calling into a common function.
I'm currently at 5 lines already :rolling_on_the_floor_laughing:
Gave up to simplicity of just edn
At work we have a similar entry point -main
in our <http://worldsingles.jobs|worldsingles.jobs>
namespace: we pass in the fully-qualified name of a function to call and positional string arguments that are then packaged into a single hash map in -main
which then calls the fq function. Although we parse the string arguments and use them are configuration to start a system Component usually, and those fq functions accept a system map -- they can't quite be called via -X
at this point.
Deleting lines is always good 🙂