Skip to content

Instantly share code, notes, and snippets.

@krolaw
Last active August 18, 2019 02:45
Show Gist options
  • Save krolaw/000a8bfb72483880a691dcbd00ae4919 to your computer and use it in GitHub Desktop.
Save krolaw/000a8bfb72483880a691dcbd00ae4919 to your computer and use it in GitHub Desktop.
V safe and easy

Simple rules for V safety

Goal is to be as safe as rust but without the complexity. This document may be totally naive, so please give constructive feedback.

Concurrency

  1. Once a mutable variable is passed to a coroutine function or channel it can no longer be used.
  2. Variables received by coroutine closures must be immutable
  3. Channels are considered immutable

If you need the variable back, it needs to be passed back, i.e. by channel. This prevents reading and writing to the same variables on different threads. Locks are unnecessary.

Example 1 - Coroutine with closure

x := 3
mut y := 7
y++ // y == 8
go fn() {
  for i := 0 ; i < x ; i++ { // a.o.k, x is immutable
    println(x) // a.o.k
    println(y) // compile error, var not immutable
  }
}

Example 2 - Channels

jobs := make_chan<int>(0)
routines := 5
jobsPerRoutine := 10
waitGroup := make_chan<none>(0)

for i := 0 ; i < routines ; i++ {
  go fn(i) {
    for j := 0 ; j < jobsPerRoutine ; j++ {
      jobs <- j
    }
    waitGroup <- none
  }
}

go fn() {
  mut count := 0
  for _ in waitGroup {
    count++
    if count == routines {
      jobs.close()
      break
    }
  }
}

for i in jobs {
  println(i)
}
mut x := 7
x++
y := x // copy of x before passing to coroutine
go fn(mut i) {
  i++
  print(i)
}(mut x) // if mut missing, compiler error (needs to be obvious at both ends what is happening)

z := x // Compiler error, x sent to coroutine - use y the copy instead
x = 9 // Compiler error, x sent to coroutine.

mut b := 7
c <- b
z := b // Compiler error!

This means you can pass mutable data around over channels etc, but you can't touch it once it's sent. It needs to be sent back to you if you want to reuse it, otherwise take a copy before sending it on.

Mutability and Immutability syntax (no pointers)

Immutable by default

a := 1 // a is immutable
mut b := a // b is mutable, b == 1, a == 1
b++ // b == 2, a == 1

Deferences pointers by default

mut a := 1 // a is mutable, a == 1
mut b := &a // b is a mutable reference and points to a
mut c := b // c is mutable, c == 1 (c is a value and does NOT reference a or b)
mut d := &b // d is a mutable reference and also points to a (where b points to)
mut e := &&b // reference to reference, not high on implementation priorities and only allowed in code marked unsafe.

References cannot reference immutable objects (use a value)

a := 1 // a is immutable
mut b := &a // totally illegal
mut c := a // c == 1

Thanks for your time.

@krolaw
Copy link
Author

krolaw commented Aug 5, 2019

@grd

But this also shows how hard it is to comply with things that you( don't) want.

I don't understand. What are the hard things to comply with?

The solution would be to do it like this:

Sorry, I don't understand that there is a problem, yet alone what your solution is doing.

That would be the answer that we are looking for.

Sorry, I don't know what the question/problem is.

It ain't perfect but still it would be a lot better than what we have today.

Please expand on both what the problem is and how your solution solves it. I'm not aware of an issue, but I'm happy to have it explained to me.

@grd
Copy link

grd commented Aug 5, 2019

You are not the guy who is in charge of this, so do it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment