nushell/crates
Doru dacf80f34a
Feature: Userland LazyRecords (#8332)
# Description
Despite the innocent-looking title, this PR involves quite a few backend
changes as the existing LazyRecord trait was not at all friendly towards
the idea of these values being generated on the fly from Nu code.

In particular, here are a few changes involved:
- The LazyRecord trait now involves a lifetime `'a`, and this lifetime
is used in the return value of `get_column_names`. This means it no
longer returns `'static str`s (but implementations still can return
these). This is more stringent on the consumption side.
- The LazyRecord trait now must be able to clone itself via a new
`clone_value` method (as requiring `Clone` is not object safe). This
pattern is borrowed from `Value::CustomValue`.
- LazyRecord no longer requires being serde serializable and
deserializable.

These, in hand, allow for the following:
- LazyRecord can now clone itself, which means that they don't have to
be collected into a Record when being cloned.
- This is especially useful in Stack, which is cloned on each repl line
and in a few other cases. This would mean that _every_ LazyRecord
instance stored in a variable would be collected in its entirety and
cloned, which can be catastrophic for performance. See: `let nulol =
$nu`.
- LazyRecord's columns don't have to be static, they can have the same
lifetime of the struct itself, so different instances of the same
LazyRecord type can have different columns and values (like the new
`NuLazyRecord`)
- Serialization and deserialization are no longer meaningless, they are
simply less.

I would consider this PR very "drafty", but everything works. It
probably requires some cleanup and testing, though, but I'd like some
eyes and pointers first.

# User-Facing Changes
New command. New restrictions are largely internal. Maybe there are some
plugins affected?

Example of new command's usage:
```
lazy make --columns [a b c] --get-value { |name| print $"getting ($name)"; $name | str upcase }
```

You can also trivially implement something like `lazy make record` to
take a record of closures and turn it into a getter-like lazy struct:
```
def "lazy make record" [
    record: record
] {
    let columns = ($record | columns)

    lazy make --columns $columns --get-value { |col| do ($record | get $col) }
}
```

Open to bikeshedding. `lazy make` is similar to `error make` which is
also in the core commands. I didn't like `make lazy` since it sounded
like some transformation was going on.

# Tour for reviewers
Take a look at LazyMake's examples. They have `None` as the results, as
such they aren't _really_ correct and aren't being tested at all. I
didn't do this because creating the Value::LazyRecord is a little tricky
and didn't want to risk messing it up, especially as the necessary
variables aren't available when creating the examples (like stack and
engine state).

Also take a look at NuLazyRecord's get_value implementation, or in
general. It uses an Arc<Mutex<_>> for the stack, which must be accessed
mutably for eval_block but get_value only provides us with a `&self`.
This is a sad state of affairs, but I don't know if there's a better
way.

On the same code path, we also have pipeline handling, and any pipeline
that isn't a Pipeline::Value will return Value::nothing. I believe
returning a Value::Error is probably better, or maybe some other
handling. Couldn't decide on which ShellError to settle with for that
branch.

The "unfortunate casualty" in the columns.rs file. I'm not sure just how
bad that is, though, I simply had to fight a little with the borrow
checker.

A few leftover comments like derives, comments about the now
non-existing serde requirements, and impls. I'll definitely get around
to those eventually but they're in atm

Should NuLazyRecord implement caching? I'm leaning heavily towards
**yes**, this was one of the main reasons not to use a record of
closures (besides convenience), but maybe it could be opt-out. I'd
wonder about its implementation too, but a simple way would be to move a
HashMap into the mutex state and keep cached values there.
2023-05-17 18:35:22 -05:00
..
nu_plugin_custom_values bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu_plugin_example bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu_plugin_formats bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu_plugin_gstat bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu_plugin_inc bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu_plugin_python update nu_plugin_python due to signature changes (#8107) 2023-02-18 13:27:24 +00:00
nu_plugin_query bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-cli Avoid blocking when o+e> redirects too much stderr message (#8784) 2023-05-17 17:47:03 -05:00
nu-cmd-lang Feature: Userland LazyRecords (#8332) 2023-05-17 18:35:22 -05:00
nu-color-config bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-command Feature: Userland LazyRecords (#8332) 2023-05-17 18:35:22 -05:00
nu-engine Feature: Userland LazyRecords (#8332) 2023-05-17 18:35:22 -05:00
nu-explore bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-glob bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-json bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-parser Avoid blocking when o+e> redirects too much stderr message (#8784) 2023-05-17 17:47:03 -05:00
nu-path bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-plugin bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-pretty-hex bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-protocol Feature: Userland LazyRecords (#8332) 2023-05-17 18:35:22 -05:00
nu-std fix spurious 'item not found' error in std help (#9197) 2023-05-17 20:02:23 +02:00
nu-system bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-table bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-term-grid bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-test-support bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
nu-utils bump nushell from release version to development version (#9215) 2023-05-17 07:59:01 -05:00
README.md Remove old nushell/merge engine-q 2022-02-07 14:54:06 -05:00

Nushell core libraries and plugins

These sub-crates form both the foundation for Nu and a set of plugins which extend Nu with additional functionality.

Foundational libraries are split into two kinds of crates:

  • Core crates - those crates that work together to build the Nushell language engine
  • Support crates - a set of crates that support the engine with additional features like JSON support, ANSI support, and more.

Plugins are likewise also split into two types:

  • Core plugins - plugins that provide part of the default experience of Nu, including access to the system properties, processes, and web-connectivity features.
  • Extra plugins - these plugins run a wide range of different capabilities like working with different file types, charting, viewing binary data, and more.