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

Clarification questions about pointers and struct immutability #40

Closed
CanyonTurtle opened this issue Mar 22, 2019 · 7 comments
Closed
Labels
Bug This tag is applied to issues which reports bugs.

Comments

@CanyonTurtle
Copy link

CanyonTurtle commented Mar 22, 2019

Firstly, I think that v looks very promising and succinct!

I have 2 clarification questions, one about pointers and the other about struct immutability.

  1. The documentation has one example with pointers. This example shows that pointers get declared and initialized along with the struct they are pointing to. Is this the only way to make pointers, or is it possible to do declare and initialize pointers so that they refer to pre-existing structs? This is the section I am referring to in the docs, from the Structs subsection:
// & prefix returns a pointer to the struct value.  
	// It's allocated on the heap and automatically cleaned up
	// by V at the end of the function, since it doesn't escape.  
	pointer := &Point{10,10} 
	println(pointer.x, pointer.y) // Pointers have the same syntax for accessing fields  

For instance, is it possible to do the following?

	p := Point{10,10}
	pointer := &p
	println(pointer.x, pointer.y)
  1. Why is it that a struct that is declared and initialized without the mut keyword can be passed into a receiver which will modify the fields of that struct? For instance, the user struct here isn't declared with mut, and yet its fields get modified by the register() method. So then, how would one guarantee that the fields of user do not get modified by any methods? In other words, how is it possible for structs to be "immutable by default:?" Or, am I misunderstanding something about "deep immutability" versus "shallow immutability" here?
struct User {
	is_registered bool 
} 

fn (u mut User) register() {
	u.is_registered = true 
} 

fn main() {
	user := User{} 
	println(user.is_registered) // ==> "false"  
	user.register() 
	// TODO: Maybe force marking methods that modify the receiver with `!`
	// user.register()!  
	println(user.is_registered) // ==> "true"  
} 

Thanks for reading!

@medvednikov
Copy link
Member

For instance, is it possible to do the following?

p := Point{10,10}
pointer := &p
println(pointer.x, pointer.y)

Yes

Why is it that a struct that is declared and initialized without the mut keyword can be passed into a receiver which will modify the fields of that struct?

This is a mistake in the docs. Fixed. Thanks :)

@ntrel
Copy link
Contributor

ntrel commented Mar 22, 2019

Yes

OK, so V must prevent pointers to stack allocated structs from escaping when passed to a function. Is there an attribute e.g. @escape for marking function parameters as escapable (i.e. assigned to a receiver)?

struct S1 { s2 S2*}
fn (mut S1 s1) set_field(s2 @escape S2*) {s1.s2 = s2}

@medvednikov
Copy link
Member

medvednikov commented Mar 22, 2019 via email

@ntrel
Copy link
Contributor

ntrel commented Mar 22, 2019

@medvednikov I presume you mean you don't want an @escape attribute, and all function parameters can't escape. This seems to work against the nice feature of immutable data that it can be referenced in multiple places (and even across threads) because it doesn't change. But I suppose that requires garbage collection or reference counting for heap allocated immutable data.

@medvednikov
Copy link
Member

medvednikov commented Mar 22, 2019 via email

@ntrel
Copy link
Contributor

ntrel commented Mar 22, 2019

I think V should prevent escapes for now, then later the restriction could be relaxed in certain cases if necessary. Otherwise it will be hard to go the other way and allow escaping now, then break code by imposing a restriction later. I guess the workaround for forcing escapes (that the programmer knows are memory safe) would be to drop into C #s1->s2 = s2.

@medvednikov
Copy link
Member

Closing because the original questions were answered.

Escaping structs were discussed in another issue. Basically they will behave like in Go.

@medvednikov medvednikov added the Bug This tag is applied to issues which reports bugs. label Jul 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs.
Projects
None yet
Development

No branches or pull requests

3 participants