-
-
Notifications
You must be signed in to change notification settings - Fork 19
Maintain original fn argument names when fn is def'ined #1222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maintain original fn argument names when fn is def'ined #1222
Conversation
|
Hi @chrisrink10, would be able to share your thoughts on this patch please or suggest alternative approaches I might consider? It's currently a show stopper for using Python libraries that depend on function argument names, and there doesn't appear to be a suitable workaround in Basilisp. Thanks |
The Python code generated by Basilisp for that inline (with your proposed change) is here: @runtime_24._basilisp_fn(arities=(1,))
def __lisp_fn_105(seq):
return seq(
concat(
list_(sym_27.symbol("first", ns="basilisp.lang.runtime", meta=None)),
list_(seq),
)
)
Var_31.find_safe(sym_27.symbol("first", ns="basilisp.core")).alter_meta(
assoc, kw_16.keyword_from_hash(8006032063624964968, "inline"), __lisp_fn_105
)Note how the parameter name is I have an idea about how to solve this but I need to do a bit more investigation first. |
|
I still have some doubts about whether allowing this as the global default is the right thing to do because of cases like the above I have not been able to fully consider or test. My preference is towards having a metadata option that enables non-uniquified argument names (something like FastAPI is a particularly painful case, but I doubt this happens in enough libraries to be the global default. Furthermore, even in the examples you give in the linked ticket, using FastAPI directly with Basilisp isn't especially convenient right now: (defn root {:async true
:decorators [(.get app "/")]}
[]
{"message" "Hi there"})It seems like someone should make a little wrapper macro which enables doing something like this automatically: (defn hello {:async true
:decorators [(.get app "/hello/{name}")]}
[^f/Request r]
(let [nm (aget (.-path-params r) "name")]
{"hello" nm}))
;; Could be something like
(defroute ^:async hello
{:route "/hello/{name}" :app app}
[name]
{"hello" name})However, if we want to make it the default, we would need to add the opposite metadata key which could be applied (call it |
I've introduced the
There is indeed a workaround for FastAPI using a
I'm fine with the new thanks |
|
It is done for increasing performance, see inlining.
It currently applies only to single-arity functions for simplicity, to support interop with Python libraries that depend on function parameter names being preserved, and does not disable inlining. Multiarity is a Basilisp-specific feature and outside the scope of the original issue, but I’ll reconsider supporting it if a real use case arises. Ideally, as discussed above, argument names should be preserved in all cases, but there are technical challenges to consider first with inline functions. |
|
Multi-arity functions are those functions which support multiple discrete numbers of arguments. For instance keyword defines two distinct arities: |
It isn't that a function has The function I showed here is the |
|
I would consider this feature to be provisional or experimental until the correct solution emerges. |
Hi,
Can you please consider a patch to preserve function argument names when a single-arity function is defined using
def? It partially addresses #1212.As mentioned in the original feature request, an increasing number of Python libraries rely on the exact parameter names of decorated functions being preserved when defined with
def. Some libraries, likeFastAPI, offer alternative interfaces to bypass this requirement, but others, such as Anthropic's MCP server's resources API, do not, making them incompatible with Basilisp.This patch aims to preserve the argument names of single-arity functions defined with
defin Basilisp, preventing them from becoming globally unique. The originalmunge'd names will be retained.Given that this is a major blocking issue for Python interop, I kindly ask you to consider this patch or suggest alternative solutions.
I have added a test to verify the new behavior, and the codebase passing provides a strong level of confidence in the solution.
Alternative options considered
remove global uniqueness of arguments
As described in the feature request, it’s not immediately clear why global uniqueness is required for function parameter names. However, when attempting to preserve the names for all function definitions (not just those who are defined with
def, as in this patch), thebasilisp.corenamespace fails to compile. Therefore, this patch is a targeted solution that only maintains original argument names fordef-defined functions.The issue causing the failure in the
basilisp.corenamespace stems from theinline'ing of thefirstfunction incore.lpy. Any calls to(first coll)will returnnil:Thus, it appears there may be a requirement for global uniqueness in parameter names when
inline'ing function names. While I wasn’t able to fully understand the underlying cause, I’m mentioning this in case you might know more and possibly offer a more complete solution to remove the global uniqueness requirement for all function definitions.Thanks