Skip to content

Allow slicing of tuples #4625

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

Open
alexnask opened this issue Mar 4, 2020 · 6 comments
Open

Allow slicing of tuples #4625

alexnask opened this issue Mar 4, 2020 · 6 comments
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@alexnask
Copy link
Contributor

alexnask commented Mar 4, 2020

This, along with the multiplication and concatenation operators would make it much easier to write code that manipulates tuples.

@daurnimator daurnimator added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Mar 4, 2020
@andrewrk andrewrk added this to the 0.7.0 milestone Mar 7, 2020
@andrewrk
Copy link
Member

andrewrk commented Mar 7, 2020

Interesting. So the start and end indexes would both have to be comptime known, and it would produce a new tuple type as a result. Sort of the "tuple version" of #863.

@andrewrk andrewrk added the accepted This proposal is planned. label Mar 7, 2020
@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 9, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 May 19, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 Nov 20, 2021
@andrewrk andrewrk modified the milestones: 0.10.0, 0.11.0 Apr 16, 2022
@andrewrk andrewrk modified the milestones: 0.11.0, 0.12.0 Apr 9, 2023
@andrewrk andrewrk modified the milestones: 0.13.0, 0.12.0 Jun 29, 2023
@ok-ryoko
Copy link
Contributor

ok-ryoko commented Apr 3, 2024

Since tuples can contain heterogeneously typed fields, it does seem natural for slicing such a tuple to yield another tuple. This is consistent with the fact that concatenating and multiplying tuples always yields a tuple even when the fields of the tuple operands are typed homogeneously.

However, this would mean special-casing the behavior of slicing, which today always yields a value of either type *[N]T (for compile time-known indices) or []T (for run time-known indices).

Would users be astonished if tuples comprising homogeneously typed fields did not slice the same way that any other currently sliceable type slices, given that such tuples are already permitted to coerce to arrays?

Aside: Would this proposal also allow for the slicing of tuple pointers?

@tgirod
Copy link

tgirod commented May 8, 2024

For what it's worth, I have a use case that would benefit a lot from this.

To make it short, my project defines a computation graph at compile time - each node of the graph has a eval(Input) Output method, where Input and Output are tuples. Then I have special nodes to combine other nodes in various ways. For those, I have to mangle tuples quite extensively, in order to route the right inputs to the right node - so mostly merging and splitting.

It is doable with a few helper functions, but beeing able to use the slicing syntax on tuples would clarify the code a lot.

For reference here are my helper functions

// extracting a list of field types from a tuple. essentially the inverse of std.meta.Tuple
fn fieldTypes(T: type) [std.meta.fields(T).len]type {
    const fields = std.meta.fields(T);
    var types: [fields.len]type = undefined;
    for (fields, 0..) |*f, i| {
        types[i] = f.*.type;
    }
    return types;
}

// return type of the split function
fn Split(T: type, comptime pivot: usize) type {
    // TODO check A is tuple
    const types = fieldTypes(T);
    return struct {
        Tuple(types[0..pivot]),
        Tuple(types[pivot..]),
    };
}

// split a tuple at pivot
fn split(tuple: anytype, comptime pivot: usize) Split(@TypeOf(tuple), pivot) {
    var result: Split(@TypeOf(tuple), pivot) = undefined;
    inline for (tuple, 0..) |value, i| {
        if (i < pivot) {
            result[0][i] = value;
        } else {
            result[1][i - pivot] = value;
        }
    }
    return result;
}

@tgirod
Copy link

tgirod commented May 16, 2024

Also, would it make sense to do the same to manipulate tuple types?

const T = struct{ f32, bool, u8};
T[0]; // f32
T[1]; // bool
T[0..2]; // struct{f32, bool};

But maybe that would count as another proposal...

@Inve1951
Copy link
Contributor

Also, would it make sense to do the same to manipulate tuple types?

TFW tuple types are tuples themselves. Massive inception gigabrain moment... 😆
Maybe this comes for free.

@theantagonist9509
Copy link

Slicing has typically meant getting a reference to the original memory of the thing being sliced. If the proposal merely wants functionality to copy portions of a tuple, then I doubt slicing would be the correct syntax or nomenclature for it. In that case, helper functions in the standard library would suffice.

@andrewrk andrewrk modified the milestones: 0.14.0, 0.15.0 Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

7 participants