Comments (18)
Just a check on understanding. Represented here means can be implemented , that is, computations can be done with them? Also, it means, that combinators are not first-class in miser but composed of some number of building blocks.
I do not like macros (Python lacks them for good), but one powerful feature seems to be missing from miser, and I guess it's not even in the frugal-1: named reusable entities.
For example, even with assembler language I can call routines by some names to reuse or I can put makefiles to different files and call by name. This is very powerful organizational technique, which is outside of scope for miser (this is fine), but does it mean it's up to implementation and computation environment or are there some blueprints that way? For example, obs "global" identity can become and issue I see.
I believe in technical systems evolving in a more or less predictable way (ref to TRIZ here again), and in computing especially sub/supersystems are usually very fast to appear. So I tend to think on 2-3 supersystems' layers habitually (sometimes hard to stay inside a box).
But the question was very practical: if I want to play with combinators in my playground, is there any standard way to call and reuse them at frugal-1 level or should I just invent something to go forward?
from miser.
@rnd0101 Just a check on understanding. Represented here means can be implemented , that is, computations can be done with them?
Representation is a bit broader than that. In this context there is a weird relationship between representation and interpretation. My technical usage is that the act of representation is arriving at an expression that achieves a particular interpretation in some context. This is broader than the technical use of applicative interpretation with respect to oMiser, as in Question #2.
For the inquiry into combinator representation, the idea is finding obs having computational interpretations that satisfy essential characteristics of combinators.
The diagram expresses the pattern I am offering for representation/interpretation. We will see how a chosen interpretation as combinators fits into that picture. There is more discussion of this under the topic "Computation as Performance" on the Facebook-page sketch I've been working on.
@rnd0101 Also, it means, that combinators are not first-class in miser but composed of some number of building blocks.
That's correct. Combinators are not first-class in oMiser. The only first-class entities in oMiser are obs.
My hypothesis is that taking/providing combinators as first-class is a mistake. My concern, as a theoretical matter, is that the Church-Rosser condition is a negative result. How that matters, and where it impacts oMiser, remains to be explored in a definitive manner.
from miser.
@rnd0101 I do not like macros (Python lacks them for good), but one powerful feature seems to be missing from miser, and I guess it's not even in the frugal-1: named reusable entities.
That's correct about oMiser. There is no storage and identification of reusable assets. If you look at "The Software Project" diagram and description, it should be clear that oFrugal has that task.
My thinking at the moment has been inspired by the SML/NJ REPL where the same problem is addressed.
Update Based on recent experience of @rnd0101 in attempting a REPL, as reported in comments below, I have expanded (1-7, here) for what is intended as the eventual complete Read-Eval-Print operation of oFrugal.
Update 2018-02-09 with further adjustments to an intended concrete syntax.
-
Statements always begin on a fresh line and continue until there is an ending ";". The use of "\" for escapes follows the rules used by the SML REPL. The prompt should indicate when the reader is expecting more input to complete a multi-line "statement."
-
Statement include "file-reference;" is for loading an oFrugal text-notation script. The loaded file can have all of (1-6).
-
(* ... *) for comments, because they allow nested comments and an easy way to block out code when testing.
-
Statement ob-exp yields, as an ob, the result of evaluation of the ob-exp. The result is presented as an ob-exp Canonical Ob form that, if entered as a statement, evaluates to the identical canonical ob. The input ob-exp text can contain bound-oFrugal references that will be expanded as stipulated in (6, below).
-
Statement ob ^name = ob-exp yields immediate evaluation of ob-exp as in (4), binding the resulting ob to the binding name ^name. The name part must be alphanumeric and can begin with a digit. The binding does not exist until the statement is completed. Any ^name references in the ob-exp text refers to the most recent prior binding to ^name. It is an error for there to be no such binding in effect.
-
^name is the notation used, anywhere in an ob-exp for immediate in-place substitution of the named ob, all during evaluation of the ob-exp.
-
It is desirable that statement sequence
ob ^name = ob-exp;
^name;
yield the same output ob-exp text form as that for the single statement
ob-exp
NOTE Keep in mind we are at 0.0.n in the early definition of oMiser and oFrugal software. Breaking changes must be considered likely. That's why mockups are exploratory and not the yet-to-be-introduced mainline source-code and its development/deployment. Experiments at this preliminary level is priceless and the willingness of such early exploration earns much appreciation and gratitude.
from miser.
Interesting, that now that I have implemented interactive frugal shell (with auto-completion and saving history), I see that certain things are a matter of taste. For example, I am using "forlindies"
, not just plain text (this probably comes from my irritation of languages such as bash shell, where commands are not quite hygienically intermingled with variables.
So for example if I were to design it, I't simply used plain identifiers for variables:
x = .A :: .B (* not evaluated, structural alias *)
y = x :: .C (* not evaluated *)
z := x :: .NIL (* evaluated *)
y (* evaluated *)
And used them also without any additional syntax.
For multilines I'd just added open "(" and the line can continue as long as there is no closing ")".
Right now I've added cS
and cK
to miser module - so they can be used as .cS
and .cK
in the shell. Less typing.
from miser.
Said that, there is good idea in APL (IIRC) - workspace. The whole workspace can be stored/loaded.
And APL has )command
syntax (or is it from some other language?)
from miser.
My concern, as a theoretical matter, is that the Church-Rosser condition is a negative result. How that matters, and where it impacts oMiser, remains to be explored in a definitive manner.
So oMiser is not confluent? I have noticed, that when I forget to enclose combinator S, it is evaluated to some shorter form, which does not work as expected. Is it that my frugal/miser implementation still somewhat buggy or true behavior?
from miser.
I've found one surprising result:
oMiser> (.D ("x" `("y" "z")) ("x" ("y" "z"))) ("eq" "neq")
INPUT: ((.D :: (("x" :: `(("y" :: "z"))) :: ("x" :: ("y" :: "z")))) :: ("eq" :: "neq"))
ev (.SELF) (.ARG) ("x") -> "x"
ev (.SELF) (.ARG) (`(("y" :: "z"))) -> ("y" :: "z")
ap ("x") (("y" :: "z")) -> ("x" :: ("y" :: "z"))
ev (.SELF) (.ARG) (("x" :: `(("y" :: "z")))) -> ("x" :: ("y" :: "z"))
ev (.SELF) (.ARG) ("x") -> "x"
ev (.SELF) (.ARG) ("y") -> "y"
ev (.SELF) (.ARG) ("z") -> "z"
ap ("y") ("z") -> ("y" :: "z")
ev (.SELF) (.ARG) (("y" :: "z")) -> ("y" :: "z")
ap ("x") (("y" :: "z")) -> ("x" :: ("y" :: "z"))
ev (.SELF) (.ARG) (("x" :: ("y" :: "z"))) -> ("x" :: ("y" :: "z"))
ev (.SELF) (.ARG) ((.D :: (("x" :: `(("y" :: "z"))) :: ("x" :: ("y" :: "z"))))) -> .A
ev (.SELF) (.ARG) ("eq") -> "eq"
ev (.SELF) (.ARG) ("neq") -> "neq"
ap ("eq") ("neq") -> ("eq" :: "neq")
ev (.SELF) (.ARG) (("eq" :: "neq")) -> ("eq" :: "neq")
ap (.A) (("eq" :: "neq")) -> "eq"
ev (.SELF) (.ARG) (((.D :: (("x" :: `(("y" :: "z"))) :: ("x" :: ("y" :: "z")))) :: ("eq" :: "neq"))) -> "eq"
OUTPUT: "eq"
Does this match the proper comparison semantics or is it a defect in my miser implementation that enclosure does not affect comparison?
Update: I guess, I am not using precedence axiom.
from miser.
And another one also bothers me:
oMiser> ((.A .D .B) "x" "x") ("eq" "neq")
INPUT: (((.A :: (.D :: .B)) :: ("x" :: "x")) :: ("eq" :: "neq"))
OUTPUT: .B
oMiser> .A .D .B
INPUT: (.A :: (.D :: .B))
OUTPUT: .D
oMiser> (.D "x" "x") ("eq" "neq")
INPUT: ((.D :: ("x" :: "x")) :: ("eq" :: "neq"))
OUTPUT: "eq"
It is surprising, that something is evaluated to .D
, but that .D
does not work in the same fashion as direct .D
..?
These are some other calculations with constructions from above:
oMiser> ((`.A .D .B) "x" "x")
INPUT: ((`(.A) :: (.D :: .B)) :: ("x" :: "x"))
OUTPUT: (.D :: (`(("x" :: "x")) :: .ARG))
oMiser> (.D :: (`(("x" :: "x")) :: .ARG))
INPUT: (.D :: (`(("x" :: "x")) :: .ARG))
OUTPUT: .B
oMiser> (.D :: (`(("x" :: "x")) :: .ARG)) ("eq" "neq")
INPUT: ((.D :: (`(("x" :: "x")) :: .ARG)) :: ("eq" :: "neq"))
OUTPUT: "neq" (* we've got a negation! *)
oMiser>
Unless it's some bug in my implementation, this may be a sign of pair's ev
going too deep. For me this means, that it is hard to rely on denotational semantics where semantics of the whole is composition of said semantics of the parts. That is, breaks compositionality.
from miser.
Does this match the proper comparison semantics or is it a defect in my miser implementation that enclosure does not affect comparison?
I think you are running into a pure-lindy-trace problem and some application-ordering matters also. When using lindies as application operator scripts, it is important to avoid premature determination of a pure-lindy-trace.
oMiser> (.D ("x" `("y" "z")) ("x" ("y" "z"))) ("eq" "neq")
Here, the ("x" ‵("y" "z"))
will eval to ap("x"
, "y" :: "z"
) = x" :: "y" :: "z"
= eval(("x" ("y" "z"))
)
So the unexpected result, "eq"
is correct. Enclosures do matter in comparison, but you have to watch for cases where eval(‵x) = eval(x), as when x is any singleton. In the above example, the pure-lindy-trace rule also kicked in on ap("x"
, "y" :: "z"
) for both sides of the comparison.
Given all of that, I think the way to get what you want, is with
oMiser> (.D ‵("x" ‵("y" "z")) ‵("x" ("y" "z"))) ("eq" "neq")
using literal operands to the comparison and avoiding any automatic trace creation when it is the ob you want to use, not its applicative interpretation.
from miser.
That last of course gives the result, but raises the question of how miser can process complex ob structures of lindies?
One more strange case, related:
oMiser> .D (````"x") (```"x")
INPUT: (.D :: (`(`(`(`("x")))) :: `(`(`("x")))))
ev (.SELF) (.ARG) (`(`(`(`("x"))))) -> `(`(`("x")))
ev (.SELF) (.ARG) (`(`(`("x")))) -> `(`("x"))
ev (.SELF) (.ARG) ((.D :: (`(`(`(`("x")))) :: `(`(`("x")))))) -> .A
OUTPUT: .A
oMiser> .D (````"x") (``````"x")
INPUT: (.D :: (`(`(`(`("x")))) :: `(`(`(`(`(`("x"))))))))
ev (.SELF) (.ARG) (`(`(`(`("x"))))) -> `(`(`("x")))
ev (.SELF) (.ARG) (`(`(`(`(`(`("x"))))))) -> `(`(`(`(`("x")))))
ev (.SELF) (.ARG) ((.D :: (`(`(`(`("x")))) :: `(`(`(`(`(`("x"))))))))) -> .B
OUTPUT: .B
comparison depends on which operand has more enclosures.
from miser.
It is surprising, that something is evaluated to
.D
, but that.D
does not work in the same fashion as direct.D
?
Let's take it apart.
oMiser> (.D "x" "x") ("eq" "neq")
produces the expected and correct result.
oMiser> .A .D .B
evaluates as ob.a(eval(.D .B
)) = ob.a(.D ‵.B .ARG
) = .D
oMiser> ((.A .D .B) "x" "x") ("eq" "neq")
has a few problems.
First, as a practice I would use ‵("eq" "neq")
to have that be taken as the ob, and not the applicative-interpretation. Always quote the surround of what you want to be taken as data in further evaluation. Don't rely on the pure-lindy-trace rule when an applicative expression is not intended.
Secondly, (.A .D .B) "x" "x")
should eval as (.A (.D .B))( "x"( "x")))
= ap(.D
, "x" :: "x"
).
Ahah!
So the above application produces .D :: ‵("x" :: "x") :: .ARG
and that applied to "eq" :: "neq"
is going to produce .B
because "x" :: "x"
is not equal to "eq" :: "neq"
.
from miser.
comparison depends on which operand has more enclosures.
oMiser> .D (````"x") (```"x")
INPUT: (.D :: (`(`(`(`("x")))) :: `(`(`("x")))))
There's something I don't understand about this. It looks like a parsing problem. There's an extra "(" in front of the first "x"
. The matching ")" is beyond the second "x"
.
Oh! This is failing to detect the special form eval(.D :: x :: y
) immediately as ob.d(eval(x
), eval(y
)). The same rule should also apply for eval(.C :: x :: y
) = ob.c(eval(x
), eval(y
)).
This seems to have worked properly in your evaluation of ap(ap(ap(cS,x),y),z) so I am not clear what happened. Oh, wait. I understand. You are using the functional sugaring, so it is interpreted as .D(...)
.
Try .D (````"x") :: (```"x")
or fall back to pure-applicative notation, (.D (````"x")) (```"x")
which should work properly. I have no idea about the difference based on order of the operands.
Note. Without adding an infix "=" another way to handle the pure applicative approach is by writing .D(x,y)
or .D(x) y
which both evaluate the same as (.D x) y)
. I don't think I got into that in describing the applicative-expression sugaring. Having an infix "=" just like the infix "::" is probably a good idea. Precedence rules will have to keep things tidy. More thought required.
from miser.
I promise things should not get any messier. You have found all of the idiosyncrasies, as far as I can tell.
from miser.
I do not like macros (Python lacks them for good),
I don't know a better term. These are little "source"-level plug-in that are of partial scripts useful in writing common idioms that will arise. Let's revisit this question when there are some of those.
from miser.
Thank you for this effort. It is showing me places where the informal description needs more care. Also, I see some speed-bumps that need to be resolved by the care taken to specify the REPL functions, the input syntax, and the two-stage read-then-eval arrangement. I'll provide more over where we have been discussing that.
from miser.
What I've tried to convey with this example
oMiser> ((.A .D .B) "x" "x") ("eq" "neq")
is that I assumed the (.A .D .B)
thing evaluates to .D
, so the result should be equivalent to the (.D "x" "x") ("eq" "neq")
, because it's in the brackets. The analysis of ".D :: ‵("x" :: "x") :: .ARG and that applied to "eq" :: "neq" is going to produce .B" is correct, my point is it very surprising to a programmer, because usually (I do not go into cases found by Rudolf Carnap here) one can substitute evaluated term with the result. For example, imaging 2 + 3 x 5
is not equal to 2 + 15
: This raises a question: is 2 + 15
equal to 17
?
Of course, I understand, that sometimes evaluation needs to be guarded from happening (that is what is my understanding of backtick, which is QUOTE in LISP, if I remember correctly.). But I do not understand how can I introduce expression, which produces .D
into expression, so it will work?
Again, I do not know how faithful my Python implementation is.
from miser.
I've changed implementation of equality in my Python's miser, introducing "state": pairs and enclosures are represented in state as tuples of subelements states, primitives and lindies' state is their name. Python automatically compares such structures, so hopefully this is desired comparison semantics for miser.
Revisiting the above with more minimal examples:
oMiser> .D ("x") ("x")
INPUT: (.D :: ("x" :: "x"))
ev (.SELF) (.ARG) ("x") -> "x"
ev (.SELF) (.ARG) ("x") -> "x"
ev (.SELF) (.ARG) ((.D :: ("x" :: "x"))) -> .A
OUTPUT: .A
oMiser> .D ("x") (`"x")
INPUT: (.D :: ("x" :: `("x")))
ev (.SELF) (.ARG) ("x") -> "x"
ev (.SELF) (.ARG) (`("x")) -> "x"
ev (.SELF) (.ARG) ((.D :: ("x" :: `("x")))) -> .A
OUTPUT: .A
oMiser> .D (`"x") ("x")
INPUT: (.D :: (`("x") :: "x"))
ev (.SELF) (.ARG) (`("x")) -> "x"
ev (.SELF) (.ARG) ("x") -> "x"
ev (.SELF) (.ARG) ((.D :: (`("x") :: "x"))) -> .A
OUTPUT: .A
oMiser> .D (`"x") (`"x")
INPUT: (.D :: (`("x") :: `("x")))
ev (.SELF) (.ARG) (`("x")) -> "x"
ev (.SELF) (.ARG) (`("x")) -> "x"
ev (.SELF) (.ARG) ((.D :: (`("x") :: `("x")))) -> .A
OUTPUT: .A
oMiser> .D (``"x") (`"x")
INPUT: (.D :: (`(`("x")) :: `("x")))
ev (.SELF) (.ARG) (`(`("x"))) -> `("x")
ev (.SELF) (.ARG) (`("x")) -> "x"
ev (.SELF) (.ARG) ((.D :: (`(`("x")) :: `("x")))) -> .B
OUTPUT: .B
oMiser> .D (``"x") (``"x")
INPUT: (.D :: (`(`("x")) :: `(`("x"))))
ev (.SELF) (.ARG) (`(`("x"))) -> `("x")
ev (.SELF) (.ARG) (`(`("x"))) -> `("x")
ev (.SELF) (.ARG) ((.D :: (`(`("x")) :: `(`("x"))))) -> .A
OUTPUT: .A
oMiser> .D (`"x") (``"x")
INPUT: (.D :: (`("x") :: `(`("x"))))
ev (.SELF) (.ARG) (`("x")) -> "x"
ev (.SELF) (.ARG) (`(`("x"))) -> `("x")
ev (.SELF) (.ARG) ((.D :: (`("x") :: `(`("x"))))) -> .B
OUTPUT: .B
Now the picture is clear: both operands are evaluated, so single tick cant be distinguished from a lindy.
(introducing state also gives a way to quickly pickle / unpickle obs to storage in Python, eg, to save / restore workspace)
from miser.
I think, the equivalence of single quotations is understandable and is not an issue. I will open new issue for the .A .D .B
case, as I think it's important.
Here: #10
from miser.
Related Issues (20)
- Imperative/Interactive Behavior and "Compute Expressions" HOT 2
- Persistent Namings: Libraries and Distributed Access HOT 1
- Need intensional printing HOT 2
- Need for On Ramp and Guard Rails
- Change master branch name to main branch name
- Convert Appropriate Issues to Discussions HOT 1
- Split oMiser and oFrugal grammars HOT 1
- Define the look-up process for oFrugal binding resolution HOT 1
- Correct repo links from oMiser/ob-exp.txt to oFrugal/ob-exp.txt
- Change Internet/docs/blogs references from oMiser/ob-exp to oFrugal/op-exp
- Split out CFob grammar from other round-tripping
- Move ob-exp.txt from oMiser to oFrugal.
- Adjust obaptheory to allow some singletons in traps
- Confirm movement of miser-theory images/ and /readings from nfoCentrale HOT 1
- Explain what has the expression of combinators be interpretation-preserving HOT 1
- Explain how the carrying of state is accomplished thanks to enclosures, cK, and obap.self
- Move the introduction of Lindies to obtheory.txt HOT 1
- Replicate orcmid/readings and miser/readings in orcmid.github.io/bib for consolidation of bibliographic material
- Bring the Ground Truth and Narrative to docs/
- Move lindies to obtheory from obaptheory
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from miser.