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

Link type #227

Closed
bvssvni opened this issue May 25, 2016 · 0 comments · Fixed by #230
Closed

Link type #227

bvssvni opened this issue May 25, 2016 · 0 comments · Fixed by #230
Assignees

Comments

@bvssvni
Copy link
Member

bvssvni commented May 25, 2016

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)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant