Skip to content

Link type #227

@bvssvni

Description

@bvssvni

A link type is kind of like an array, but only stores primitive data types:

link = [ f64 | str | bool ]

Intrinsic functions:

fn head(link) -> opt[any] { ... }

fn tail(link) -> link { ... }

fn is_empty(link) -> bool { ... }

Links are cheap for linking together large amounts of data, using less memory than arrays. It is an immutable data structure, so you can't write to it. It contains no references, so there are no issues with lifetimes.

The link type is ideal for generating chains of data, for example for:

  • Indexing
  • Templates
  • Code generation
  • Pattern matching
  • Handling large amounts of data

link bracket

A link bracket takes primitive data types separated by optional whitespace:

a := link {"hi!: "name"\nage: "age}
a := str(a) // convert the link to a string

Memory representation

Link memory are stored in blocks of 124 items plus 2x64 bits to tell the types apart. This adds up to 1024 bytes of memory per block on 64 bit platforms. This gives 3.2% overhead compared to lists of same types in Rust.

2 bits per item tells the type:

  • 0 means empty slot in block
  • 1 means bool
  • 2 means f64
  • 3 means str

When two links share an block, they increase the reference counter to the same block, so that memory is only released when neither link use it any more.

Linking stuff together

The link bracket takes 1024 bytes of memory if it contains one item, so it takes 42 items to save the space that is wasted in an array:

a := link {
        0 1 2 3 4 5 6 7 8
        9 10 11 12 13 14 15 16
        17 18 19 20 21 22 23 24
        25 26 27 28 29 30 31 32
        33 34 35 36 37 38 39 40
        41 42
    }

Thumb rule: If you need to link stuff that exceeds a calendar month, then you might want to use a link bracket.

You can link single items to make better use of memory:

a := link {}
a += "hi"
a += 5
a += true

Two links can be linked together cheaply, but it might waste a little memory:

a := link { ... }
a += link { ... } // cheap, but wastes a little memory

You can link individual items from another link by putting it in the link bracket. This saves a little memory when the old link goes out of scope:

a := link { ... }
b := link { ... a } // links individual items from `a`

Two assignment operators can be used with links.

+= puts a link at the end:

a := link { 1 2 3 }
a += link { 4 5 6 }
println(a) // prints `123456`

-= puts it at front:

a := link { 1 2 3 }
a -= link { 4 5 6 }
println(a) // prints `456123`

+ can not be used with links, because it would waste a lot of memory and it is too easy to do by accident:

 --- ERROR --- 
In `source/test.dyon`:

Type mismatch: Binary operator can not be used with `link` and `link`
2,23:     a := link { 1 } + link { 2 }
2,23:                       ^

The preferred method is to either use += or put it inside the link bracket:

fn main() {
    a := link { 1 link { 2 } }
    println(a)
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions