Value and Reference
By definition, pass by value means you are making a copy in memory of the actual parameter's value that is passed in, a copy of the contents of the actual parameter. Use pass by value when you are only "using" the parameter for some computation, not changing it for the client program.

In pass by reference (also called pass by address), a copy of the address of the actual parameter is stored. Use pass by reference when you are changing the parameter passed in by the client program.
In Dart, as in many other object oriented programming languages, objects are always pass-by-value. But you can still pass pointers to objects and arrays by value.
Technically, all languages use pointers. When you create an instance of an object in Java or C# or Javascript and pass it to a method you are actually passing a pointer to the piece of memory that contains that object by which you will manipulate the data on that piece of memory.

Because Go is the language supporting pointers, it will be of core focus in this lesson.

Let's declare two variables i and j, then we acess and manipulate them using a pointer p that holds the memory address of the value assigned to them at a particular session of the program.
go
package main

import "fmt"

func main() {
  i, j := 42, 2701

  p := &i         // point to i
  fmt.Println(*p) // read i through the pointer
  *p = 21         // set i through the pointer
  fmt.Println(i)  // see the new value of i

  p = &j         // point to j
  *p = *p / 37   // divide j through the pointer
  fmt.Println(j) // see the new value of j
}
            [Golang]$ go run test.go 
42
21
73
[Golang]$
          
Pointers to structs
Struct fields can be accessed through a struct pointer.

To access the field X of a struct when we have the struct pointer p we could write (*p).X. However, that notation is cumbersome, so the language permits us instead to write just p.X, without the explicit dereference
go
package main

import "fmt"

type Vertex struct {
  X, Y int
}

func main() {
  v := Vertex{3, 7}
  p := &v

  fmt.Println("Cumbersome way:", (*p).X)
  fmt.Println("Permitted way:", p.X)
  // Changing the value of x
  p.X = 24
  fmt.Println("Printing v:", v)
}
            [Golang]$ go run test.go
Cumbersome way: 3
Permitted way: 3
Printing v: {24 7}
[Golang]$
          
Slices
An array has a fixed size. A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array. In practice, slices are much more common than arrays.
Slices are always pass by reference as changing them changes the value of the base array.
go
js
dart
python
julia
package main

import "fmt"

func main() {
  primes := [6]int{2, 3, 5, 7, 11, 13}

  var s []int = primes[1:4]
  fmt.Println("Base array: ", primes)
  fmt.Println("Slice:",s)
  
  // Change value in slice
  s[0] = 39
  fmt.Println("Base array: ", primes)
  fmt.Println("Slice:",s)
}
let primes: number[] = [2, 3, 5, 7, 11, 13]

// For JS, it does a copy of the slice and hence 
// changing the value of s does not affect the 
// base array
let s = primes.slice(1, 4)
console.log("Base array:", primes)
console.log("Slice:", s)

// Change value in slice
s[0] = 39
console.log("Base array:", primes)
console.log("Slice:", s)
void main() {
    var primes = [2, 3, 5, 7, 11, 13];

    /* The sublist creates a new list from the subset
    of the base array, so changing s cannot in any way change the base array*/
    var s = primes.sublist(1, 4);
    print("Base array: $s");
    print("Slice: $s");

    // Change value in slice
    s[0] = 39;
    print("Base array: $primes");
    print("Slice: $s");
}
a = [2, 3, 5, 7, 11, 13]
s = a[1:4]

print(f"Base array: {a}")
print(f"Slice: {s}")

s[0] = 39

print(f"Base array: {a}")
print(f"Slice: {s}")
module Fourier

a = [2, 3, 5, 7, 11, 13]
s = a[2:4]
println("Base array: $(a)")
println("Slice: $(s)")
s[1] = 39
println("Base array: $(a)")
println("Slice: $(s)")

end
go
js
dart
python
julia
            [Golang]$ go run test.go 
Base array:  [2 3 5 7 11 13]
Slice: [3 5 7]
Base array:  [2 39 5 7 11 13]
Slice: [39 5 7]
[Golang]$
          
From the codebase and the terminal results above, we see that only Go slices have reference to the base array.

In Golang, a slice does not store any data, it just describes a section of an underlying array. Changing the elements of a slice modifies the corresponding elements of its underlying array. Other slices that share the same underlying array will see those changes.