Skip to content
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

[WIP] nim needs a slice type analag to D's T[] dynamic array #8256

Closed
timotheecour opened this issue Jul 10, 2018 · 1 comment
Closed

[WIP] nim needs a slice type analag to D's T[] dynamic array #8256

timotheecour opened this issue Jul 10, 2018 · 1 comment

Comments

@timotheecour
Copy link
Member

timotheecour commented Jul 10, 2018

[Closing until I flesh out more details]
TODO: maybe move to a repo so other can contribute to proposal

motivation

  • efficiency: with slices (aka views), there is less copying being done

use cases

  • string manipulation with 0 allocations
  • image processing (eg in C++ cv::Mat allows returning sub-matrices of a matrix with 0 allocation)
  • FFI: foreign function interface with 0 allocation: slice from input pointer + length

exists in other languages

leads to cleaner / leaner / more orthogonal and composable API's

  • eg: ospaths.searchExtPos wouldn't be needed with splitExt ; a ton more examples

syntax and semantics

Should follow semantics of D dynamic arrays, cf https://dlang.org/spec/arrays.html ; only difference is that the nim GC is thread-local unlike D's GC

Conceptually, a slice is:

type slice*[T] = object #TODO: slice or Slice? I prefer Capital for types but we have seq[T]...
  pointer: prt T #CHECKME
  length: int # can have a proc `len` that retrieves this `length`
type T = int # for eg
let n = 10
let a = newSlice[T](n) # allocates
assert type(a) is slice[T]
let b = a[3 .. 6] # no allocation
assert b.ptr == a.ptr + 3
assert b.len == 4
b[0] = 100
assert a[3] = 100 # original slice is affected

## create a slice from ptr + len (no allocation)
let b2 = initSlice(b.ptr, b.len) #TODO: not sure what's the best syntax here
assert type(b2) is slice[T]
assert b2 == b # does element-wise comparison

# TODO: show .dup, .array, setting .len, assignment

what about openArray

there's lack of clarity on what openArray is; eg https://github.com/nim-lang/Nim/issues/6528 argues it should be a concept; but others don't, eg:

OpenArrays are just a proc parameter type that accept arrays and seqs

I want to keep openArray and turn it into borrowed array slices. The borrowing aspect is hard to achieve with a concept. The better way to do it is to simply patch the stdlib to use a concept where it makes sense

openArray is not the same thing as Slice, it's a concept suitable for interfaces, and most analog to D's random access range trait, see https://dlang.org/library/std/range/primitives/is_random_access_range.html

  • not first class citizen, cf ICE's and bugs with openarray #8259 : some issues are fixable but some seem less so, eg: "Error: invalid type: 'openarray[int]' for var"

  • can't be defined from arbitrary pointer (eg provided by a C foreign function call)

How to accomodate slice in standard library?

The value of that would be ability to make standard library work regardless of types (otherwise a large number of standard library features may not be available to slices);

Could Nim seq be implemented in terms of slice?

Maybe impossible, because would break too many programs, eg assignment copies for seq, but not slice

Could Nim string be implemented in terms of slice, as in D?

Maybe impossible, because would break too many programs, eg assignment copies for seq, but not slice
Note: lessons learned from D: auto-decoding is bad, and shouldn't be reproduced in Nim

related discussions

@timotheecour timotheecour changed the title [WIP] nim needs a slice type analag to D's T[] array [WIP] nim needs a slice type analag to D's T[] dynamic array Jul 10, 2018
@yglukhov
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants