2018 002 Additional slice operations

John Reppy edited this page Sep 2, 2018 · 3 revisions

Proposal 2018-002

Additional slice operations

Author: John Reppy
Last revised: September 2, 2018
Status: proposed
Discussion: issue #25


This proposal adds operations to the vector and array slice strutures.

Synopsis

signature MONO_VECTOR_SLICE =
  sig
    ...
    val triml : int -> slice -> slice
    val trimr : int -> slice -> slice
    val splitAt : slice * int -> slice * slice
    val getVec : slice * int -> (vector * slice) option
  end

signature MONO_ARRAY_SLICE =
  sig
    ...
    val triml : int -> slice -> slice
    val trimr : int -> slice -> slice
    val splitAt : slice * int -> slice * slice
    val getVec : slice * int -> (vector * slice) option
  end

signature VECTOR_SLICE =
  sig
    ...
    val triml : int -> 'a slice -> 'a slice
    val trimr : int -> 'a slice -> 'a slice
    val splitAt : 'a slice * int -> 'a slice * 'a slice
    val getVec : 'a slice * int -> ('a vector * 'a slice) option
  end

signature ARRAY_SLICE =
  sig
    ...
    val triml : int -> 'a slice -> 'a slice
    val trimr : int -> 'a slice -> 'a slice
    val splitAt : 'a slice * int -> 'a slice * 'a slice
    val getVec : 'a slice * int -> ('a vector * 'a slice) option
  end

Description

The semantics of these operations is independent of the underlying slice and vector types, so we give a generic description.

  • triml n slice

removes `n` elements from the left end of the slice `s`. If `n` is greater than the number of elements in the slice, then the empty slice is returned.
  • trimr n slice

removes `n` elements from the right end of the slice `s`. If `n` is greater than the number of elements in the slice, then the empty slice is returned.
  • splitAt (slice, i)

returns the pair of slices `(slice1, slice2)`, where `slice1` contains the first `i` elements of `slice1` and `slice2` contains the rest of the elements. If `i` is negative or greater than the number of elements in the slice, then `Subscript` is raised. The underlying vector (or array) of `slice`, `slice1`, and `slice2` will be the same.
  • getVec (slice, n)

returns `SOME(v, rest)`, where `v` is a vector of the first `n` elements of `slice` and `rest` is the slice containing the remaining elements, assuming that `slice` has at least `n` elements. Otherwise, `NONE` is returned.

Discussion

These additional operations make manipulation of slices more convenient. They can be directly defined in terms of existing operations as follows:

fun triml n s = if (n < length s)
      then subslice(s, n, NONE)
      else subslice(s, length s, NONE)

fun trimr n s = if (n < length s)
      then subslice(s, 0, SOME(length s - n))
      else subslice(s, 0, SOME 0)

fun splitAt (s, i) = (subslice(s, 0, SOME i), subslice(s, i, NONE))

fun getVec (s, n) = if (n < length s)
      then let
        val (s1, s2) = splitAt (s, n)
        in
          SOME(vector s1, s2)
        end
      else NONE

Impact

This propsal adds new variables to existing basis modules. Most code should be unaffected, but there are a few uncommon situations where existing code will break. These situations include

  • code that opens an extended structure in a context where the new identifiers are already bound.

  • code that includes an extended signature in a context where the new identifiers are already bound.

  • structures that match the old signature, but do not include an implementation of the new operations.

Rationale

Currently, the processing of slices in a chunk-wise fashion is difficult; addition of these operations would make it more convenient (and slightly more efficient). The first three of these operations already exist in the Substring structure and the getVec operation is a natural generalization of getElem, so these operations are a natural extension to the slice structures.


History

  • [2018-09-02] Original proposal.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.