kadena-io/pact

Modrefs refSpec: storage in tables AND typed variable binding

CryptoPascal31 opened this issue · 3 comments

Issue description

When storing a modref into a typed variable or a table, the interfaces (refSpec) list should be "sanitized".

I mean: redact unused interfaces, and reorder them following the target type specification.

As always, the better is to provide an example:

Steps to reproduce

; Two simple interfaces
(interface genius
  (defconst SOMETHING:bool true)
)

(interface girl
  (defconst SOMETHING:bool true)
)


; Let's create a genius repository
; Allows to store and get geniuses.
(module genius-collection G
  (defcap G () true)
  
  (defschema entry
    person:module{genius}
  )
  (deftable tbl:{entry})

  (defun add:string (name:string x:module{genius})
    (insert tbl name {'person:x}))

  (defun get:module{genius} (name:string)
    (with-read tbl name {'person:=x}
      x))
)
(create-table tbl)

; Let's create Emily
(module emily G
  (implements genius)
  (implements girl)
  (defcap G () true)
)
(genius-collection.add "Emily-A" emily)
(genius-collection.add "Emily-B" emily)

; Sanity check => OK
(expect "Both Emily modrefs are the same" true (= (genius-collection.get "Emily-A")
                                                  (genius-collection.get "Emily-B")))

; Redeploy Emily but reverse interfaces
(module emily G
  (implements girl)
  (implements genius)
  (defcap G () true)
)
(genius-collection.add "Emily-C" emily)

; !!! THIS DOESN'T WORK BUT SHOULD !!!!
(expect "Both Emily modrefs are the same" true (= (genius-collection.get "Emily-A")
                                                  (genius-collection.get "Emily-C")))

; Redeploy Emily but forget the girl property
(module emily G
  (implements genius)
  (defcap G () true)
)
(genius-collection.add "Emily-NOT-GIRL" emily)

; !!! THIS DOESN'T WORK BUT SHOULD =>  from a genius point of view: modrefs are still the same
(expect "Both Emily modrefs are the same" true (= (genius-collection.get "Emily-A")
                                                  (genius-collection.get "Emily-NOT-GIRL")))

; Redeploy Emily and restore the girl property
(module emily G
  (implements girl)
  (implements genius)
  (defcap G () true)
)

; Try another example with "let" variables typing
(let ((emily-genius-first:module{genius, girl} emily)
      (emily-girl-first:module{girl, genius} emily)
      (emily-genius-only:module{genius} emily)
      (emily-girl-only:module{girl} emily))

    ; !!! THIS DOESN'T WORK .... THEY ARE EQUAL BUT SHOULDN'T BE => DIFFERENT TYPES
    (expect "Modrefs types differ => Should be different" false (= emily-genius-first emily-girl-first))

    ; !!! THIS DOESN'T WORK .... THEY ARE EQUAL BUT SHOULDN'T BE => DIFFERENT TYPES
    (expect "Modrefs types differ => Should be different" false (= emily-genius-first emily-genius-only))

    ; !!! THIS DOESN'T WORK .... THEY ARE EQUAL BUT SHOULDN'T BE => DIFFERENT TYPES
    (expect "Modrefs types differ => Should be different" false (= emily-girl-only emily-genius-only))
)

I mean: redact unused interfaces, and reorder them following the target type specification.

I actually disagree and it doesn't make sense to redact unused interfaces for that reason. If we treat the list of interfaces as a set rather than a list, your entire some of the bug goes away.

In short: this is an implementation bug, I'll look into to address it going forward.

edit
Actually, I had only read half the issue when I responded, so now I see the other half of the problem.

To recap:

  • Any module reference interface implementation ordering bugs can be addressed by a Set, that's a straightforward fix.
  • Despite the {genius} and {girl} type refinements, module references are actually dynamic pointers to a module. In the case of the last set of tests, they both point to emily, so it's not surpising that they're type-equal.

It's hard to say it makes sense for the last set of tests to fail. Under static typing, they should, but if we talk about run-time values, they both definitely point to the same module.

On another note, I'm going to go ahead and close this issue. Please re-file it without the references to Emily, this is not appropriate.

I do not want a precedent for this in pact. Emily is a great coworker and very smart, but I'm sure you can express your semantic issue without the genius, girl and emily. I'm not closing discourse, we can still talk about this, but refrain from these sort of things in the future when filing issues.

Definitively, I'm so sorry if I offended somebody.

As Emily is already present in many places in the code. I wanted to do a little humor.

And I thought that associating emily girl and genius would be seen as kind. Didn't want to offend or insult, just wanted to have more relaxed atmosphere.

I'm going to refill and change the examples.