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

Distinct constructor required for every receiver capability #334

Closed
shelby3 opened this issue Dec 4, 2018 · 6 comments
Closed

Distinct constructor required for every receiver capability #334

shelby3 opened this issue Dec 4, 2018 · 6 comments

Comments

@shelby3
Copy link

shelby3 commented Dec 4, 2018

It would be less boilerplate (thus less chance for errors due to failing to maintain redundant copies of code the compiler should be able to manage and more concise, elegant code) if the receiver type of the constructor could be instead inferred from the capability type that the constructor’s return value is assigned to.

This is the only way I could find to make this work in Playground:

class Foo
  var _c: String val

  new ref create(c: String val) =>
    _c = c

  new val create_val(c: String val) =>
    _c = c

  fun get(): String val => _c

  fun ref set(c: String val) => _c = c

actor Main
  new create(env:Env) =>
    let a: Foo ref = Foo(recover val String end)
    env.out.print(a.get().string())
    a.set(recover val String end)
    let b: Foo val = Foo.create_val(recover val String end)
    env.out.print(b.get().string())
// illegal    b.set(recover val String end)

Is there some more elegant way to accomplish this?

Note the class val String default mentioned in the tutorial doesn’t seem to have any effect in this case. I’m confused as to what it does if constructor receiver capability must be hard-coded?

@EpicEric
Copy link
Contributor

EpicEric commented Dec 4, 2018

One option would be to recover from ref^ to iso^. It can then be subtyped to any reference capability:

class Foo
  var _c: String val

  new ref create(c: String val) =>
    _c = c

  fun get(): String val => _c

  fun ref set(c: String val) => _c = c

actor Main
  new create(env:Env) =>
    let a: Foo ref = Foo("Hello")
    env.out.print(a.get())
    a.set("Pony")
    env.out.print(a.get())
    let b: Foo val = recover Foo("World") end // or recover iso Foo.create("World") end
    env.out.print(b.get())

@SeanTAllen
Copy link
Member

class val String has no impact on the constructor.

It has an impact for what something like

let a: String means.

that would be

let a: String val

rather than the default

let a: String ref

@SeanTAllen
Copy link
Member

@shelby3 your question is really something for the mailing list. It's not something that is actionable for the tutorial so I'm going to close this.

Please note the more idiomatic way to do

let b: Foo val = Foo.create_val(recover val String end)

what @EpicEric suggests.

@shelby3
Copy link
Author

shelby3 commented Dec 5, 2018

One option would be to recover from ref^ to iso^. It can then be subtyped to any reference capability:

let b: Foo val = recover Foo("World") end // or recover iso Foo.create("World") end

Darn it. I had tried that conceptually (enclosing in a recover block) and my specific code case didn’t compile. I didn’t pay close enough attention to the specific error messages because I was trying many different combinations rapidly. Apparently I must have put val on the get method and wasn’t coercing (i.e. no : Foo val on let b) so then probably had the error Foo val: iso! is not a subcap of val. The compiler also gives this hint which I can’t yet understand, this would be possible if the subcap were more ephemeral: new create(c: String val) =>.

But frankly that is going to be confusing for newbies and if we don’t have to do it that way, it would be one less complexity confronting those just starting to learn the language. Also those recover blocks are noisy code.

If every capability of a constructor can be recovered as any capability when all the inputs are sendable, then why can’t the compiler do that automatically? C.f. also.

If that idea is valid and ever adopted, then I suppose the documentation for it should appear both in the Automatic receiver recovery section and any new section for documenting receiver capabilities of constructors.

Also why not allow constraints as the receiver type of a constructor so that it can proven which types are coercible without requiring the arguments to be sendable? This is a different case from (method) functions because the constructed instance didn’t exist before so the receiver type has no prior lineage restrictions.

class val String has no impact on the constructor.

It has an impact for what something like

let a: String means.

that would be

let a: String val

rather than the default

let a: String ref

Indeed I understood that from the section I linked to. What I didn’t realize when I wrote the OP is how it could have any effect if the constructor is determining the constructed receiver type. After further thought, I guess there are defaults which would be supertypes of all or some of the constructed capability types. So I understand now it’s an orthogonal degree-of-freedom.

Complex this stuff (but I’m presuming probably easier than Rust). A lot to think about for those accustomed to coding for example in JavaScript, Java, or Python (although Java has a lot of hidden complexity for threading, fighting with the GC and optimizing around boxing, but newbies can ease into Java). But you already recognize that the unfamiliarity and learning curve is one of the challenges for wider adoption. I’m also thinking about that and if there are any ways to ease newbies in.

your question is really something for the mailing list. It's not something that is actionable for the tutorial so I'm going to close this.

Okay apologies I didn’t know there is a mailing list. I should have thought of checking for one.

My experience with discussion lists (the linked issues repository is being used as a discussion forum) is that everything gets lost in a sea of discussion and not acted upon. There’s no list newbies can refer to of issues which are searchable (and they never re-read all the past voluminous discussions). I recently had to re-read 746 comments in the Concurrency thread to condense into Message-based concurrency (and parallelism).

I recognize that issues can be discussed first on the mailing list before deciding whether to file an issue. Will do.

I will try to[did] open a thread of discussion at the mailing list and then can re-open if any of my points in this reply are valid and accepted there.

@SeanTAllen
Copy link
Member

This is a repository for the tutorial. Not for discussion of language features. Its for discussion of the explanation of language features as they relate to the tutorial.

@shelby3
Copy link
Author

shelby3 commented Dec 6, 2018

@SeanTAllen, indeed it had been some months since I posted a few issues about the tutorial on this repositories’ issues, and apparently when I returned recently to post another tutorial issue, then I clicked to the same issues at the top of the page when I proceeded to post this issue. I forgot that I had been posting to repository that was only for the tutorial.

Perhaps you can move this issue to the correct repository if Github offers such a feature? If you do, if it is possible to leave a forwarding link on this thread page, I would appreciate that.

Again apologies for my lapses with this thread. 🤕

These lapses can be attributed to human error (i.e. multitasking and not frequently contributing to many repositories on Github thus being accustomed to just accessing the issues from the top of the thread’s page) or more likely in my case I tend to completely zone out because of my NAFLD (complication from the Tuberculosis which I had for 5+ years misdiagnosed and thus not cured until 2017) which causes me to have such low energy that I’m trying to fight through delirium sometimes while working. Also the past few days I launched into a strict (< 20g carbs) ketogenic diet to try to battle this and this caused my energy level to plummet and fighting dizziness sometimes throughout my waking hours. 😵

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants