Replies: 15 comments 53 replies
-
Good idea - just curious why doesn't Mojo use present tense in its keywords, e.g. |
Beta Was this translation helpful? Give feedback.
-
Thanks for this proposal! I'm very happy with it. |
Beta Was this translation helpful? Give feedback.
-
Let's give the feature/proposal a better name. It's really about introducing "inferred only parameter". |
Beta Was this translation helpful? Give feedback.
-
Although keword parameter is more verbose, we can probably start with that and avoid having a new inferred keyword? For me personally, |
Beta Was this translation helpful? Give feedback.
-
How would this work in situations where the type to return can't directly be inferred? Example 1Suppose I were to write a function that returns the last element of a heterogeneous list: alias het_list = [1, True, "Hello", (2, 3, 4)]
fn last_element[inferred T: ??, input_list: ListLiteral]() -> T:
return input_list[-1] How can I infer the data type of the last element of Example 2This example is much more practical: Inspired by the from functools import reduce
def pipeline(data, func1, func2, /, *funcs):
def apply(arg, func):
return func(arg)
return reduce(apply, (func1, func2, *funcs), data)
# Example usage
pipeline(range(100),
lambda x: map(lambda n: n * 3, x),
lambda y: filter(lambda m: m % 2 == 0, y),
tuple,
print) It's pretty ugly in Python, but I think with some syntax sugar (extension methods and Scala lambda placeholders), it'll look really nice: extension AnyType:
fn pipeline[inferred T1: AnyType, inferred T2: Anytype, func1: fn(Self) -> T1, func2: fn(T1) -> T2, /, *funcs: ??]() -> ??:
# Similar to Python
# Same Example
range(100)
.pipeline[
_.map(_ * 3).filter(_ % 2 == 0),
tuple,
print,
]() Assuming that not all functions/constructors will be callable as methods (here I assumed that The problem is, again, how do I annotate this function to be type-safe? Using P.S. I'm not the first one to want this in Python or the first one to implement it:
P.P.S. I don't want to resort to specifying the return types of my functions as |
Beta Was this translation helpful? Give feedback.
-
Are inferred only parameters unordered? How do they interact with overload resolution? Are the following considered redefinitions (I think, yes)? fn f[inferred A: T, inferred B: S, a: A, b: B](): ...
fn f[inferred B: S, inferred A: T, a: A, b: B](): ... |
Beta Was this translation helpful? Give feedback.
-
Can/should we have a method to specify them explicitly? It would still be useful to sometimes specialise the generic functions to a certain set of fixed parameters. Syntax wise, we could write |
Beta Was this translation helpful? Give feedback.
-
How does it interplay with automatic parameterisation? It seems we have to choose between simplifying the definition or the call site: fn f(s: SIMD, ...) -> ...
# VS
fn f[inferred dt: DType, inferred w: Int, ...](s: SIMD[dt, w], ...) -> ... So thinking out loud, maybe also: |
Beta Was this translation helpful? Give feedback.
-
Should Mojo warn about uninferrable |
Beta Was this translation helpful? Give feedback.
-
I have a counter-proposal which I think is compelling. I'll post it tomorrow. |
Beta Was this translation helpful? Give feedback.
-
Okay, here's my counter-proposal. Problem statementAs I understand it, the problem to be solved is that one wants to be able to declare a parameter (e.g. The solution proposed by @MogballThe proposed solution is to introduce a keyword The main issue I have with this proposed language feature is that its utility seems quite narrow. I would suspect that ≥99% of Mojo function signatures won't benefit from this feature—except within applications/libraries that use metaprogramming extensively. I suspect we all agree that language features that have broad utility are much more easily justified than those that are useful only rarely. In my counter-proposal below, I propose a pair of widely-applicable language features (syntactic sugars) that can subsume I have a few other concerns with
My counter-proposalI propose two syntactic sugars:
These features can be individually motivated, and they work well together. Motivating
|
Beta Was this translation helpful? Give feedback.
-
Curly braces are another syntax worth considering:
This syntax could also be used to enumerate the variables that a closure captures by-reference, since captured variables are conceptually similar to inferred arguments. (In both cases, the variable doesn't need to be provided at the call site.) |
Beta Was this translation helpful? Give feedback.
-
It's also worth considering whether the proposed syntax extends cleanly to inferred arguments, on the assumption that Mojo will support them at some point (e.g. if/when types can be passed around at runtime):
Combining this syntax with a
But I suppose there's no reason for the proposal to be blocked on this. We'd just need to be willing to change the syntax in the future, as necessary. |
Beta Was this translation helpful? Give feedback.
-
I've thought of another kind of "inferred thing" that Mojo might eventually have: trait instances. It might be good to have this use-case in the back of our minds when considering the design of (Apologies for the length of this post. I expected this to be a short comment. 😅) What constitutes a "good" semantics for traits is incredibly subtle. Rust and Swift model traits/protocols in a somewhat flawed/hyper-restrictive way. To guarantee soundness, both languages require every type to implement a trait at most once within an application plus all of its dependencies.
The purpose of these restrictions is avoid various bizarre and subtle bugs wherein a value is operated on using conformance A in one context, and conformance B in another context, and those conformances conflict. A common example is a hashed data structure, e.g. IMO, a promising solution to this problem would be to model implementations of traits as values, and have them appear as
This statically enforces that a hash set can only use a single trait implementation over its lifetime. This also means that the trait implementation will be propagated throughout all functions and variables that operate on hash sets derived from the original set. Some notes:
This approach isn't novel. Scala does something similar. Long story short: the above example demonstrates a potential use of Note: to respect left-to-right reading, the inferred parameter needs to appear at the end, which is not permitted under the OP's proposal. This is all just "future work" of course. There's no reason to block an initial implementation of |
Beta Was this translation helpful? Give feedback.
-
I've come up with another potential alternative to |
Beta Was this translation helpful? Give feedback.
-
Hi all, this feature request: #1245 came up during the first Mojo language committee meeting, and @Mogball has put forward a proposal to enable this with an
inferred
keyword:The full proposal is here
We'd love to hear from the Mojo community before going ahead with the implementation, any comments or questions are welcome!
Beta Was this translation helpful? Give feedback.
All reactions