Closed EvanKirshenbaum closed 10 months ago
This issue was referenced by the following commit before migration:
Okay, a bit of a kludge, but it appears to work, although it only supports a single injectable position.
CallableType
now has
injectable_pos: Final[Optional[int]]
as_injection: Final[Optional[CallableType]]
injectable_pos
tells the system where to put the delayed parameter, and as_injection
is the resulting type signature.
In order to make this work, I also had to munge things so that as_injection
's with_self_sig
has the full type, not the resulting type. So, __init__()
and find()
take an optional as_self
parameter. Note that this means that when computing as_injection
, we don't call find()
, because we don't want the munged type being returned in the future. I also changed the way the find()
cache works. It now keys on both the Signature
and the optional injectable position.
The actual value that's created is a new subclass of CallableValue
that remembers the bound arguments, the injection point, and the full CallableValue
:
lass BoundInjectionValue(CallableValue):
bound_args: Final[tuple[Any, ...]]
full_callable: Final[CallableValue]
injection_pos: Final[int]
def __init__(self, full_type: CallableType, full: CallableValue,
*args: Any) -> None:
as_injection = not_None(full_type.as_injection)
super().__init__(as_injection.sig)
self.bound_args = args
self.full_callable = full
self.injection_pos = not_None(full_type.injectable_pos)
def __str__(self) -> str:
return f"({self.full_callable})({', '.join(str(a) for a in self.bound_args)})"
def apply(self, args:Sequence[Any]) -> Delayed[Any]:
assert len(args)==1
full_args = list(self.bound_args)
full_args.insert(self.injection_pos, args[0])
return self.full_callable.apply(full_args)
I had intended that this would be implemented as part of adding support for general overloaded functions (#288), but that's turning out to be trickier than I had thought (partially due to COVID brain), and the OSU folks are going to want this sooner rather than later, so I think I'm going to try a somewhat kludgier approach for the short term.
When mocking up a macro for them, since there isn't support for general paths yet (#282), I found myself writing
The notion is that we have a two-argument function
walk_circle()
, but we want to be able to sayBy marking the
drop
parameter asinjectable
, when the compiler seeswalk_circle(north)
, instead of complaining that an incorrect number of arguments have been supplied, it would remember the arguments passed in and return a new function that took one argument, spliced it into the correct position in the list, and then called the function.I think that I should be able to do this pretty straightforwardly by adding the injectable positions to
CallableType
.Note, that, unlike the approach I have been taking with #288, this would not result in
walk_circle
being treated asdir -> (drop -> no_val)
, although I guess I could probably make it work inCallableType._find_conversion_to()
.Migrated from internal repository. Originally created by @EvanKirshenbaum on Aug 02, 2023 at 12:13 PM PDT. Closed on Aug 02, 2023 at 4:22 PM PDT.