-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Declare input and output types of commands #6796
Conversation
this looks very cool. nice work dan! can't wait to play with it. |
It's clearly known that this is not complete yet but I was trying it out and saw that it was puking on plugins so I wanted to add it to the list of TODOs
|
I think this is a good information to add to the help table. My main concern is the table becomes very big. An alternative might be to add it to Also, the input/output types should be shown in the help text itself when you type |
How might this work out when you have a command which has multiple possible outputs? |
Thanks @kubouch. I agree that we don't want the table to get too big. I think that the input and output type of a command is the most important information after
Definitely, will do that as part of this work. |
Thanks for thinking about this @merelymyself;
I would like to suggest that, if we go with this PR, we make return type consistent for a single command, i.e. we no longer permit flags and positional args to alter the return type of a command (some discussion in discord). So in the case of I do agree with the discussion between you and @extemporalgenome in #6616 which points out that it's even worse for the return type to alter according to the value (as opposed to presence) of a positional. E.g. the way that Related to that, I am not convinced that we want to retain the way that some commands automatically map over their input, e.g.
The language provides I think that there are lots of advantages to having the return type remain consistent regardless of flags/positionals, as well as input value. The most important might be that it gives us a natural definition of what a nushell command is: it's something that transform this type of input into that type of output. So the rule I'm proposing will answer the question of whether functionality should be exposed as one command vs two separate commands, and help prevent commands from becoming complex and obscure to understand, like One remaining thing that needs to be solved in this PR is how to handle "column paths". These are special positionals that, contrary to the proposed rule, exist specifically for the purpose of altering the output type. So the rule I'm imagining we introduce would be something like:
For anyone who's not familiar with column paths (e.g. me until very recently), they behave like this for the commands that support them:
So concretely, what this PR needs to do, is detect when examples are using a column path, and alter the output type expectation accordingly. Or should the language have a more explicit way of distinguishing column paths from other positional arguments? |
I'm not sold on this idea yet but one vote for it is that I'm betting startup would be a little bit faster. I could be wrong but I think |
We talked about this PR in our team meeting today. We'd like to move forward with this PR and like the direction it's going. Thanks for your help. I think there are a few things left to do but once we get there we'll land this. |
Thanks for the PR! I noticed that after this change, we would be tracking both types and shapes: pub input_type: Type,
pub output_type: Type,
pub input_shape: SyntaxShape,
pub output_shape: SyntaxShape, Aside: What's the difference between shapes and types?Types are more specific than shapes (thanks Dan for the reminder). For example, the "Record" type includes field names+types:
Shapes are more general; you can say that something has the shape of a record without specifying exactly which fields it has. OK, back to this PRI would like to understand whether we need to track both type and shape. This may come down the intended uses. Input+output types are currently used for enabling command overloading (like how we have 2 I'm less clear on how shapes will be used (primarily as a UX/documentation improvement?) and unsure whether both shapes+types are needed. |
@rgwood We also have another type called FlatShapes that are used in syntax highlighting in the repl. (see syntax_highlighting.rs). So, I wonder if all 3 of these are really necessary? |
I'm also wondering about the inverse of this; does this approach rule out commands with multiple possible input types? I guess those would need to be |
The way I'm thinking about this is that we can divide this question up into:
I'm not sure yet how to handle (1). Putting that aside temporarily, what are examples of (2)? Do we even want (2)? As I mentioned above, I'm aware of
and I'm not convinced that it should behave like this since mapping over input is provided by |
I think there must be several commands that do this because I recall a
maybe these
|
Sort is a bit different -- it works on However, it does also seem to accept an integer or a string, but it's not immediately obvious to me why it accepts those since it doesn't sort them in any sense:
|
Problem I just found with this PR: |
After giving this more thought, I think this redundancy will be temporary and doesn't need to be addressed in this PR. We haven't decided on the future of command overloading, but:
|
94f147a
to
3403d0c
Compare
@rgwood I think that the "cell paths" feature in nushell is a form of command overloading, so in that sense we won't remove command overloading. Would you agree with that? |
The current approach I'm taking here is:
|
42ba0e5
to
4ca8c68
Compare
I’m not sure I understand, can you give an example? |
I didn't really follow how |
AIUI "command overloading" means that the "same command" exists in a number of variant forms which differ in the number and types of inputs they accept, and in the type of output that a given input signature produces. So if we take
This form has the type But as with many nushell commands there is a second variant:
Here 'k1' is a "cell path". This form has the type So, it seems that the cell path feature is a form of command overloading. And cell-paths actually give rise to a third variant
Incidentally, there also another form which many nushell commands have:
I'm thinking that all these polymorphisms are examples of "command overloading". If so, then since cell paths seem well established in the language, it seems that command overloading isn't going away. And the cell paths are very useful I think -- addressing and operating on deeply nested cells is not something all languages make easy. The vectorization behavior also seems well-established, but it's less obvious that it should be since nushell also has Incidentally, I've suggested an alternative way that we could expose cell paths:
This would also be command overloading: the variant of
or maybe
|
@fdncred This sounds like a good catch. I haven't done anything about it yet (would anyone be up for doing that?) |
Let's wait to land until after this week's release. That hopefully gives us time to fix the plugins and then we can land it with a few weeks to test it until the next release. |
c975f60
to
15b2e83
Compare
@rgwood thanks I've rebase on |
I was going to try this morning too but can't. Maybe there's something wonky with
Update: I used the "Github Pull Requests and Issues" plugin and was able to check it out. Apparently it works differently than |
I force-push to feature branches, so I'm guessing you'll need the
Otherwise just the usual vanilla git routine, e.g.
|
Ah sorry that screenshot dates from an initial draft version. The current version of the PR doesn't add them to the |
I've pushed a commit that adds the signatures in a simple way to the |
IMO, the input/output type doesn't belong in I think it just adds confusion. However, I absolutely think the input/output should be part of the |
@dandavison I just noticed this issue with our nu_plugin_custom_values plugin. I think 🤔 it's related to this PR. Any thoughts on how to fix it if it is?
|
@fdncred I haven't started using plugins myself but from the error message it looks like some serialized plugin state needs to be regenerated -- can you blow it away and reinstall the plugin? |
I did that, rebuilt everything, got the same error registering it but it registered somehow. And I can execute the plugin. I have no idea what's going on. Oh, it just occurred to me that when the signature changes we have to delete the $nu.plugin-path file. I think your PR changed the signature. I'll try that tomorrow and report back. |
This PR adds
input_output_types: Vec<(Type, Type)>
to the commandSignature
struct. This is a collection of all the different input-output type signature variants.The declared input and output types (shapes) are enforced by the test suite: they are checked when executing every example.
There are two main commits:
3b5a6cb sets things up so that we can declare input-output type signatures and verifies them in the tests of examples
f47ba52 is a big commit that adds signatures to all commands that have automatically-tested examples (and adds/changes command examples along the way so that they cause the tests to pass)
The bottom line is that once this merges, we'll have the following rule:
Subsequently, we can add this information to the
help commands
and$nu.scope.commands
tables, so that users can query nushell commands by their input and output types.We can also use this to add signatures to the text help pages, peraps like #6754.
Being able to query commands by type will also provide a way to study the way that builtin commands are named, to check that we're keeping things reasonably consistent (e.g. to help with things like #6744).