orcmid / miser

The Miser Project is practical demonstration of computation-theoretical aspects of software
https://orcmid.github.io/miser/
Apache License 2.0
3 stars 1 forks source link

Introduce the obapx.PROC/obapx.DEF Extension #22

Closed orcmid closed 3 years ago

orcmid commented 4 years ago

[updated 2020-06-14T15:42Z to connect related issues.] [updated 2020-05-25T25:43Z to clarify further and express commitment to having it.] [updated 2020-05-21T22:20Z to clarify a bit more on the value of .proc.] [updated 2020-01-15T15:43Z to add the ¶ condition and tidy up a bit.]

Although it is premature until the implementation and definitions are more-advanced, I have a few extensions in mind. This one is about scripts made into individuals.

proc Extension

There are two new primitives, obapx.PROC and obapx.DEF.

obapx.ap(obapx.PROC, p) determines an individual, standing for the script that p is. Designate that individual by proc(p). The computation model obapx has everything that obap does, along with identified obapx primitives and their computational interpretation.

proc(p) = proc(q) ⇔ p = q

q = proc(p) ⇒ qp

obapx.ap(proc(p), x) = ev(p, x, p) = obapx.ap(p, x).

obap.apx(obapx.DEF, q) yields p for which q = proc(p) and yields q otherwise.

From this, it is the case that when obapx.ap(obapx.DEF, q) ≠ q, q is a proc.

An ob that is not a proc is not equal to any proc.

Since ob p is essentially the unique identifier of proc(p), the canonical form for proc(p) is the expression obapx.PROC(cfp) which can be written .proc(cfp) for short with cfp the canonical form of p.

Why?

Discussion

I did not originally consider having obapx.DEF, except there needed to be a canonical form, and oFrugal had to have a way to produce it. There is to be a serialized form of obs for retention in files and interchange, and that needs to be able to convey procs also.

Although I am not a fan of reflection in object-oriented programming systems, I see how it is compelled in the case of oMiser once any kind of procedural encapsulation is employed.

I had wondered about an alternative formulation, using

obap.ap(proc(p), x) = ev(proc(p), x, p)

as a way of having some sort of purity around the definition and use of procs. Unfortunately, this breaks the guarantee about equivalence to obap.ap(p, x) and then requires that p require

.def :: .self

to access its own code as data.

The reliance on extensional equality for the proc(p) perpetuates a very strong condition applied in oMiser. It seems appropriate that all obs be "comparable," even at this elementary level. Work on deduction will address how to take this further in appropriate contexts.

It may well be that the proc(x) approach is a solution looking for a problem to solve. I submit that the Capsule Hack (issue #23) is additional evidence that proc is invaluable in the creation of semblances akin to programming-language objects and their interfaces.

orcmid commented 4 years ago

Provision of this feature requires a number of steps.

  1. There needs to be a an obapxtheory.txt covering this extension and any related ones, such as potential need for an obapx.tail operator. The Capsule Hack (#23) and establishment of a specific convention for stateful entities is also important. Of particular interest is handling of "compute expressions" in the F# sense.

  2. The grammar must reflect the case of .proc(exp), not because it is needed, but because there must be a kind of meta- approach to producing it in canonical forms.

  3. Procedures for output of obs by oFrugal must present case (2) and any pretty-printing needs to treat it.

  4. The serialization of obs for persistent storage and reloading must express and accept the form.

This (3-4) follows from the insistence on extensional identity for oMiser. That will not be abandoned lightly. It is a basis for accelerators (#26), with need for higher-order deductions to simulate and expose anything richer. It is a purpose of the oMiser project to reveal such consideration.