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

[Feature request] a unified trait is needed for various Views #341

Open
shamiao opened this issue Apr 28, 2024 · 1 comment
Open

[Feature request] a unified trait is needed for various Views #341

shamiao opened this issue Apr 28, 2024 · 1 comment

Comments

@shamiao
Copy link

shamiao commented Apr 28, 2024

As I saw in the current core, a concrete VecView can be obtained by op_as_view(start_including, end_excluding) operator. Although not yet implemented, similar viewing logic may be applied to other linear containers like Array or List.

I suggest adding View[T] built-in trait as an abstraction of a minimum subset of methods for any View. A suggested definition is:

/// View[T] is a logical contiguous sequence of T with random access by index. (Not guaranteed to be contiguous in memory)
pub trait[T] View[T] {    // <- not supported by compiler yet
    length[T](Self) -> Int
    op_get[T](Self, Int) -> T
    as_iter[T](Self) -> Iter[T]
}

This allows Char, String and Bytes related methods work for various data sources, without bloating the numbers of methods at the same time.

// before
let a = Buffer::make(256);
a.write_string("DEV")
a.write_sub_string("ELOPEZZZ", 0, 5)
a.write_char('R')
println(a.to_string())  // -> DEVELOPER

// after - assuming exists: 
//   fn write[Char](self: Buffer, view: impl View[Char]) -> Unit
//   fn view(self: Char) -> impl View[Char]
//   fn view(self: String) -> impl View[Char]
//   fn subview(self: String, start: Int, end: Int) -> impl View[Char]
let a = Buffer::make(256);
a.write("DEV".view())
a.write("ELOPEZZZ".subview(0, 1))
a.write('R'.view())
println(a.to_string())  // -> DEVELOPER
// before
let moon = Bytes::of_string("MOON")
let mo = Bytes::[0x6d, 0x00, 0x6f, 0x00, 0x7a, 0x00]
moon.blit(0, mo, 0, 4)
moon.blit_from_string(4, "on", 0, 2)
println(moon.to_string()) // -> moon

// after - assuming exists:
//   fn blit(self: Bytes, source: impl View[Byte]) -> Unit
//   fn op_as_view(self: Bytes, start: Int, end: Int) -> impl View[Byte]
//   fn view_bytes(self: String) -> impl View[Byte]
let moon = Bytes::of_string("MOON")
let mo = Bytes::[0x6d, 0x00, 0x6f, 0x00, 0x7a, 0x00]
moon.blit(0, mo[0..4])
moon.blit(4, "on".view_bytes())
println(moon.to_string()) // -> moon

This feature cannot be completed by a simple PR, since it requires generic traits to be implemented by the compiler first.

This request is directly inspired by the std::slice of Rust language. Very rough, polishment & discussion required.

@fantix
Copy link
Contributor

fantix commented Apr 28, 2024

I did something similar to unify Bytes and BytesView: Loadable and Storable. They are used in a way like this:

pub fn copy(dst : Storable, src : Loadable, len : Int) -> Unit {
  for i = 0; i < len; i = i + 1 {
    dst[i] = src[i]
  }
}

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