Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Pony-esque recover blocks for constructing immutables? #6398

Closed
shelby3 opened this issue Sep 17, 2020 · 5 comments
Closed

Pony-esque recover blocks for constructing immutables? #6398

shelby3 opened this issue Sep 17, 2020 · 5 comments
Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.

Comments

@shelby3
Copy link

shelby3 commented Sep 17, 2020

I posited in issue #3814 that immutability is essential for implementing concurrency safely:

As I explained herein and in the companion thread #1868 there are shared data paradigms which are provably safe at compile-time such as immutable shared data. The Vlang compiler could enforce it by for example only allowing threads to share references to immutable shared data.

Vlang’s type system can enforce immutability, but I don’t see any means to initialize an immutable other than from literals or extant runtime values.

Thus how to initialize some complex immutable objects dynamically; for example initializing an array in a loop before declaring it to be immutable from that point forward? Also we’d like to be able to extract immutables safely from complex mutable code because of the fact that “immutable data structures have a logarithm performance penalty for algorithms that require random access writes.”

We could imagine a constructor function which is allowed to mutate (i.e. initialize) an immutable object. If any pointers (to other object) will be initialized then that constructor function must obey certain rules in order for the immutability invariant to be valid.

Specifically those rules are Pony’s recover block. Any inputs to the constructor (including any variables in the outer lexical scope if Vlang supports closures?) must not contain any non-sendable pointers; which in Pony’s parlance means they must be capable of conversion (aka being consumed) to an immutable (aka val).

But Pony’s multifarious reference capabilities model is quite complex, c.f. also. And sending a mutable iso to another thread seems to violate the “future proofing” via sharing only immutables that I wrote about. So perhaps isn’t desirable to adopt all of Pony’s model? To simplify if you’re only going to support recover then afaics you’ll only need mutables and immutables. So thus the only sendables would be the immutables.

This proposal wouldn’t eliminate the ability to guarantee that circular references don’t exist in immutables. The recover blocks mustn’t accept as input any references to soon-to-be, immutable objects who initialization (via another constructor recover block) has not yet completed. I wrote in #1868:

Note as you may know, immutable data structures have the advantage that they can’t contain circular references, which is important if employing ARC instead of a tracing GC, because ARC can’t collect circular references (although there exist probabilistic designs which attempt to do some localized tracing along with ARC).

@shelby3 shelby3 added the Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one. label Sep 17, 2020
@ntrel
Copy link
Contributor

ntrel commented Sep 17, 2020

recover
  var s = String((prec + 1).max(width.max(31)))
  ...
  _extend_digits(s, prec')
  s.append(typestring)
  s.append(prestring)
  _pad(s, width, align, fill)
  s
end

Unfortunately V doesn't support appending to strings. Anyhow, it's planned to allow a block to produce a value. I think this would be equivalent:

str := {
  mut s := create_string ()
  process_string (mut s)
  s
}

str would be immutable.

Edit: Although references to s could outlive the block.

@shelby3
Copy link
Author

shelby3 commented Sep 20, 2020

I suggest reading also my Pony’s Design Compared.

@medvednikov
Copy link
Member

medvednikov commented Sep 20, 2020

Right now you can use functions for that. For example consts are initialized like this all the time:

const (
  ids = init_ids()
)

Unfortunately V doesn't support appending to strings.

Immutable strings are great, so I'd use fortunately there :)

@cristian-ilies-vasile
Copy link

cristian-ilies-vasile commented Sep 20, 2020

FYI
A Comparison of the Capability Systems of Encore, Pony and Rust
http://uu.diva-portal.org/smash/get/diva2:1363822/FULLTEXT01.pdf

@shelby3
Copy link
Author

shelby3 commented Sep 22, 2020

Right now you can use functions for that. For example consts are initialized like this all the time:

const (
  ids = init_ids()
)

How would a mutable be assigned to a pointer to an immutable without also allowing mutables from the lexical (i.e. external, closure context) to be so assigned?

One of the requirements in my OP was about this. I don’t see how you can accomplish it without the rules enforced on recover blocks per what I wrote in the OP.

@vlang vlang locked and limited conversation to collaborators Sep 22, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants