Created
June 22, 2010 02:16
-
-
Save ELLIOTTCABLE/447828 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Paws tutorial outline | |
===================== | |
- Overview | |
- Conceptually simplistic object-space; everything appears as a “list” | |
- Extremely extensible syntax and semantics, Unicode-friendly | |
- Everything is completely asynchronous in nature; synchronicity is the exception, not the rule. | |
- Even though asynchronicity practically implied by the medium, it isn’t obtuse to use | |
- Provides easy, safe concurrency throughout your code | |
- if the implementation chooses to implement concurrency | |
- Operates in a distributed nature across multiple interpreters and systems | |
- including web-client (browser) and web-server | |
- Theory | |
- overall design goal is a robust and lovely-to-use language with which to power a new kind of web framework | |
- to that end, we’re building *three* programming languages, each of which builds upon the last: | |
- Paws | |
- absolutely minimalistic | |
- the *actual language* as interpreted by Paws implementations | |
- at every stage of design, striving to remove everything we possibly can and *move* it into Paws’ Core | |
- is not intended to be particularly usable on its own | |
- provides the lowest-level “building blocks” to implement Paws’ Core, nothing more | |
- Paws’ Core | |
- still minimal, but not as ascetically Spartan as Paws itself | |
- is a sort of minimal “standard library,” while also being its own *language* | |
- implemented entirely in Paws | |
- thus, any compliant Paws implementation can also handle Paws’ Core | |
- while still not a language that end-users are expected to often use, will be more friendly than Paws | |
- since Fullness is intended to be layered and iteratively teardown-friendly, Paws’ Core is the | |
“language” in which others (who want to design their own linguistic alternatives to Fullness) will be | |
working when they’ve torn enough of Fullness out of their environment | |
- Paws’ Fullness | |
- the final language, as *I* (elliottcable) envision it | |
- is very opinionated, not intended to suit everybody | |
- very layered, intended to be “torn apart” by those using it, and gradually replaced with idioms more to | |
their individiual, personal style | |
- no two people will be using the same “language,” if they’re applying Paws as it was intended to be used | |
- everyone will gradually build their own language and ecology, to some extent, as they work in Paws | |
- is much more lavish and sybaritic than either of the above; the vast majority of user-facing friendly | |
linguistic features will be implemented at this level | |
- heavy on the abstractions and visual nicities, as some examples: | |
- infix operator support | |
- unitization, such as `$` for dollars or `″` for inches | |
- convenience routines for most core Paws concepts | |
- Paws can be utilized without Fullness, or even Core (though you’d have to be insane!) | |
- **this document *only* covers Paws, and ocassional bits of Paws’ Core!** | |
- Fullness is too far in the future, and too nebulous, to specify at the moment | |
- Syntax | |
- extremely simple core syntax | |
- called ‘cPaws’ or “canonical Paws” | |
- every implementation required to parse | |
- words and sentences seperated by whitespace: `foo bar` | |
- a ‘word’ can be any series of non-space and non-parenthesis/brace Unicode codepoints: | |
- `foo`, `foo.bar`, `42`, `!@#$%^&*` are all valid words | |
- a ‘sentence’ is *any* series of characters within balanced Unicode double-quotes | |
- “foo foo.bar 42 !@#$%^&*” | |
- may not contain unbalanced closing-double-quote | |
- things surrounded by parenthesis are a list-literal | |
- `(foo bar)` creates a new list containing the value of of `foo bar` | |
- things surrounded by brackets are a routine-literal | |
- `{foo bar}` creates a new routine with the portion of the AST containing `foo bar` | |
- any of the above elements, followed by another element, constitutes a “space operator” | |
- the space operator *usually* consists of a “lookup” (see below) | |
- can be overridden to mean other things | |
- on `routine`s, could cause the `routine` to be run | |
- on `list` literals, could cause a multi-lookup | |
- at the end of a statement, a “terminator” call is made, allowing more complex lookup chains | |
- extensible via pre-compilation stage | |
- is optional for implementations | |
- output can be serialized to cPaws for transmission to non-pre-compilative implementations | |
- during normal execution, the AST of a document is opaque | |
- this is to enable bytecode compilation at a later date: an AST isn’t required to exist anymore or even | |
have any useful meaning at runtime; the structure of the program is statuc | |
- a document (when pre-compilation is turned on) is not just executed a single time | |
- is executed two or more times | |
- as precompilation instructions are executed, execution may prematurely terminate and begin ‘from the top’ | |
while applying the newly-acquired precompilation instructions | |
- during pre-compilation stage, AST is exposed to libspace | |
- a new API is made available, to interact with the AST attached to `routine` objects | |
- during pre-compilation, all forms of I/O or interaction with the external world are inaccessible | |
- this ensures that the pre-compiler can execute the code as many times as it wants to, without any adverse | |
side effects | |
- programs can thus modify their own structure, introducing new elements of meaningful syntax, such as infix | |
operators, new forms of data literals, or really, anything imaginable to the mind | |
- precompilation instructions | |
- are not like the CPP | |
- are written *in Paws* | |
- are even included anywhere in your own code | |
- as long as the precompiler can “reach” them without “going through” a portion of code that requires | |
I/O, because branches of the code applying I/O will be entirely non-functional during pre-compilation | |
- have your full object-system and libraries at their behest | |
- such as Fullness, with inheritance and the like | |
- are simply `routine`s registered with the precompilation API | |
- will be executed against new documents’ ASTs, once registered | |
- libraries can build build precompilation instructions and provide them to things that use those libraries | |
- for instance, Fullness will define many useful operators | |
- can even define “meta-instructions” that control *other* precompilation instructions | |
- again, Fullness: will provide tools for defining new infix operators and negotiating their precedence | |
- is optional | |
- you can include external libraries’ precompilation instructions *without* enabling the precompilation | |
stage for your own document, if you’re afraid of the precompiler executing your code at compiletime | |
- Paws’ “core API” | |
- is not exposed by any form of inheritance, Paws itself defines none | |
- is disturbingly C-like, only with namespaces | |
- revolves around “routine bags” for each core datatype, including primitives | |
- `infrastructure` is simply a `list` exposed by the interpreter | |
- `infrastructure routine` is another `list`, stored on the previous list | |
- `infrastructure routine run`, as an example, would be a natively-implemented routine | |
- you would theoretically call the core APIs as if they were root-level functions, not as “methods”: | |
`infrastructure routine run(a_routine)` | |
- exposes hooks into ‘creation’ of types; “constructors” | |
- are not like constructors of old, have nothing to do with inheritance | |
- are automatically called when the interpreter has to create new object, such as through a literal | |
- object systems utilize to apply their magic to new objects | |
- globally defined (`infrastructure list allocate()`) | |
- can be overridden per-routine (`a.routine _ list allocate()`) | |
- must be overridden on some of the constructors themselves, to prevent infinite recursion | |
- bags are ugly, by design: it avoids having to do anything to newly created objects to “prepare” them | |
- such “preperation” is left up to object systems, which are written *in Paws* (such as Core) | |
- Paws’ Core implements very rudimentary “prototypal inheritance,” utilizing the constructors (see below) | |
- within Paws’ Core, the basic routines described throughout this document are often available as “methods” | |
instead of having to work through the crude “routine bags” provided by the interpreter | |
- ‘Object’ system | |
- `list` | |
- primary datatype of the language | |
- 1 indexed | |
- naughty | |
- are often *treated* as associative arrays, by way of `assocation`s (see below) | |
- `list`s-as-forks | |
- `list`s are not just a data storage type, conceptually | |
- can be more productively considered ase either: | |
- a first-class “‘fork’ in program execution” | |
- a first-class “data ‘pipeline’ between multiple locations in program execution” | |
- however, all together, `list`s are not simply any of the above, they’re a more powerful and generalized | |
hybrid, as you can fork against all future *and* past contents | |
- forking happens via `ramify()` | |
- can be ‘forwards,’ ‘backwards,’ or both | |
- ‘backwards’-only forking is `fork()`, only forks on the elements present when you call `fork()` | |
- ‘forwards’-only forking is `listen()`, only forks when elements are added in the future | |
- bidirectional forking is cruicial; a bidirectional fork is *temporally deterministic*, as the actual | |
forking of the program will proceed identically no matter *when* you fork: is best practice | |
- forking is core to our asynchronous design | |
- primitives datatypes | |
- all opaque | |
- all appear the same as ‘lists’ libside | |
- all store elements in a ‘list’ portion of their storage, just like a ‘list’ | |
- so, all are also associative arrays from libside POV | |
- `string` | |
- characters are opaque | |
- immutable, not like Ruby’s `String` or Cocoa’s `NSMutableString` | |
- interned, like `Symbol` | |
- globally unique | |
- used primarily to quickly test for equality, as a ‘name’ | |
- encoding is static, always matches encoding of Unit it was created | |
- i.e. encoding of the document the string-literal was typed in | |
- can be up-converted to `soup` | |
- `soup` | |
- is a “character soup” (think ‘alphabet soup’), or, more accurately, “codepoint soup” | |
- characters still opaque | |
- mutable | |
- native routines provided to manipulate: concatenating, appending, inserting, and removing, etc chars | |
- attributed | |
- like NSMutableAttributedString, can have objects associated with ranges of characters | |
- those objects might represent styles for printing, for instance | |
- the ranges are updated as mutations are preformed, ensuring attributions consist throughout mutation | |
- encoded | |
- is aware of encoding it was created with | |
- can be implicitly converted to another encoding as necessary | |
- implicit conversion can be disabled if information loss would be critical | |
- `numeric` | |
- not well defined; design on hold | |
- math stacks… **MORE** | |
- `routine` | |
- very simple, just represents “a bit of code” | |
- AST is opaque | |
- `execution`: opaque pointer into AST of every `routine` it touches | |
↩ | |
- common non-primitive datatypes | |
- these are not primitives | |
- they’re all implemented on top of `list`, in libspace, not natively | |
- they’re still very common, and low-level: not part of Fullness, instead, ‘Paws Core’ | |
- since we don’t have inheritance or actual “types” built into the core language, these are all only | |
differentiated by the “routine bags” utilized to manipulate them | |
- Paws’ Core’s inheritance provides faux-primitives of these “types” | |
- `assocation` | |
- contains two initial elements, a key, and a value | |
- key can be *anything*, but is usually a `string` | |
- can contain other associations or elements, as with any other `list` | |
- often has “attributes” in the form of other associations on it, such as: | |
- `locked` might cause the holder of the `asociation` to reject changes | |
- `unique` to avoid overriding of the `association` with a new one | |
- are generally, themselves, transparent to lookups (see below) | |
- `scope` | |
- not “lexical scope”, nor “dynamic scope” or “static scope” | |
- what I call “objective scope” | |
- scope is just an object, a `scope` | |
- on a `scope` is a `locals` slot that points, recursively, to itself | |
- all lookups go through `locals` | |
- `locals` can be replaced with another object | |
- “variables” are simply `association`s | |
- this means our “variables” can be passed around, they’re first-class | |
- also means “variables” can have attributes, just like any other `association` | |
- `ghost` | |
- is what most asynchronous `routine`s (that is, *most `routine`s*) ‘return’ | |
- said `routine`s will generally “materialize” the `ghost` over time, by filling it up with ‘results’ | |
- this is how most asynchronous routines give their results to consumers | |
- are ‘blocking,’ and proxy all operations through all of their children by `ramify()` | |
- this means that preforming essentailly *any* operation on a `ghost` will fork your program | |
- the actual operations, through `ramify()`, will instead be preformed upon the children of the `ghost` | |
- are generally ignored by lookups (see below) | |
- lookups | |
- semantically, describe a ‘message to an object,’ asking it to give you something | |
- don’t necessarily mean giving you something from the contents of the list, though it often does | |
- default implementation: | |
- reverse-iterate elements of the `list`, looking for an `association` whose key is identical to the | |
argument to the `lookup` | |
- are commonly overloaded | |
- provide nearly ever feature of the Paws object system, from libside: | |
- inheritance | |
- scope, closure | |
- routines as “methods” | |
- cloning | |
- could also implement such non-trivial things as: | |
- HTTP requests | |
- database queries | |
- since every datatype in the Paws ecosystem *looks* like a `list`, every datatype responds to lookups | |
- “a lookup” may be attributed with intent to ‘ignore’ particular objects | |
- by default (in Paws’ Core), lookups will ignore `association`s | |
- since most lookups *result in* an association, it’s essential to chaining lookups that you be able to | |
introspect the value of the association instead of the association itself | |
- for instance, if `foo bar` returns an association such as `(, ‘foo’, 123)`, you would want the `add` | |
in `foo bar add(4)` to be looked up and executed on `123`, not the `association` containing `123` | |
- the same is true for `ghost`s, because asynchronous `routine`s return `ghost`s, but you often want to | |
operate on the actual results of the `routine`, not the `ghost` | |
- strings and numerics are created via lookups from ‘literals’ | |
- appropriate-looking `string`, such as `23` or `“abc”` falls to the undefined handler | |
? (if strings cannot be created at run-time, how do we create `“foo”` from `““foo””`?) | |
- handler recognizes it and returns a new `string` or `numeric` instead | |
- `routine` | |
- **MORE** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment