Objects, namespaces, dictionaries, and hashes

DRAFT IN PROGRESS

Discussion thread here.

I hope to “finish” the proposal this weekend before we begin ripping it apart. Feel free to look at it and get a feel for what I've tried to compile.

Variables/Scope

Memory

The LOLCode language so far has either had only static variables, or required the use of a garbage collector. This proposal formally specifies a Garbage Collection Strategy. All variable are merely refernces to locations in memory. It is assumed that when a variable is no longer referenced, that variable's allocated space will be freed sometime in the future, or on program exit.

Declaration

Here's a few changes to how Declaring variables works.

I HAS A <variable> ITZ <value> 

This instantiates and initializes a variable. If the value is a literal, the variable is initialized to the appropriate object type (YARN, TROOF, NOOB, NUMBR, NUMBAR). If the value is an identifier or expression, the variable is initialized to the resulting expression.

I HAS A <variable> ITZ A <type>

This instatiates a variable, and initializes it to a default value.

Built-In default values:

  • YARN - ””
  • TROOF - FAIL
  • NUMBR - 0
  • NUMBAR - 0.0
  • NOOB - NOOB
I HAS A <variable>

This instatiates a variable and initializes it to NOOB. It is shorthand for I HAS A <variable> ITZ NOOB

Function types are declared/initialized using the HOW DUZ I / IF U SAY SO blocks, however they behave the same as variables. For example:

HOW DUZ I var YR stuff
	BTW implement
IF U SAY SO

I HAS A var ITZ 0  BTW Throws an error AS var is already taken

var R 0 BTW FUNIKSHUN var no longer exists, it's now NUMBR-0

Deallocation

 <variable> R NOOB 

This above code ensures that a variable no longer references anything. The reference still exists on the current scope and still requires a small amount of memory. If this was the last reference to an object, it will be garbage collected in the future.

 NERF <variable> 

Is a command that will remove the reference from the current scope. If this was the last reference to an object, it will be garbage collected in the future.

Primitive Types

All primitive types are considered Immutable. All built in operations return new objects instead of references to old objects. The exceptions to this rule are WIN, FAIL and NOOB. Every TROOF reference is either the WIN or FAIL object. Every NOOB reference is ot the NOOB instance.

SRsBiZnUs Cast

The SRS BIZNUS operation can be used to interpret a YARN (or something castable to a YARN) as an identifier.

 SRS BIZNUS <expression> MKAY 

Example:

 I HAS A var ITZ 0 

Is the same as:

 I HAS A name ITZ "var"
I HAS A  SRS BIZNUS name MKAY ITZ 0

FUNKSHUNS

Functions have a new function call syntax to ensure appropriate gramatical parsing:

 I IZ <funkshun> (WIF  <argument> (AN <argument>) *   MKAY) ? 

The I parameter is used to distingish a function call on the current namespace vs. a function call on a bukkit (defined below).

BUKKITs

BUKKITs are the container type. They may hold NUMBRs, NUMBARs, TROOFs, YARNs, functions (FUNKSHUN), and other BUKKITS. Each entity within a BUKKIT may be indexed by a NUMBR or a YARN. These indices, whether NUMBRs or YARNs, referring to functions, variables, or other BUKKITs, are generically called “slots”.

Introduction

To create an empty object within the current object's scope:

I HAS A <object> ITZ A BUKKIT

This object will have the default behavior of all bukkits.

Slot Creation / Assignment

One of the most obvious thing to do with a bukkit it place something in a slot.

 <object> HAS A <slotname> ITZ <expression> 

A slot may be declared/initialized more than once, however doing so only changes the value the slot references.

This places the value returned from expression (could be another object) into the slot identified by slotname. The slot name may be any identifier (or SRS BIZNUS cast). Note: This identifier may be a function. Example:

HOW DUZ I blog YR stuff
	VISIBLE blog
IF U SAY SO

<object> HAS A blog ITZ blog
Functions

The function definition syntax has changed as well. To declare a function inside a bukkit's slot

HOW DUZ <object> <slot> (YR <argument>)*
( <statements> )*
IF U SAY SO

So, the above code becomes

 HOW DUZ <object> blog YR stuff
	VISIBLE blog
IF U SAY SO
Me, myself and I

Functions operate differently in the context of bukkits. When a function is called from an object, some scope rules and variable resolution change.

When an identifier is used in a function, the variable is looked up in the following manner:

  • The function namespace
  • The calling object's namespace (if called from object)
  • The “global” namespace

IT is always looked up from global namespace

The function namespace is made up of all arguments and any variable declared using the identifier “I” it resides within the function's namespace.

HOW DUZ I foo YR bar
     BTW bar is on function namespace
     I HAS A bar2
     BTW bar2 is on the function namespace
IF U SAY SO

ME is an identifer used to access the calling object of a function. If there is no calling object, access to ME throws an exception. Define This exception

Declaring a variable on the calling objects namespace is done as follows:

HOW DUZ I foo YR bar
    ME HAS A bar2
    BTW bar2 is now a slot on calling object
IF U SAY SO

ME can also be used to explicitly use a slot variable vs. a function namespace variable.

HOW DUZ I foo YR bar
     ME-bar R bar
     BTW sets calling object's bar slot to bar value
IF U SAY SO

Alternate Syntax

There is an alternate way to define a new object/bukkit

O HAI IM <object> [IM LIEK <parent>]
  <code-block>
KTHX

Anything “I” inside the codeblock actually refers to <object>. This can simplify syntax, eg:

O HAI IM pokeman
	I HAS A name ITZ "pikachu"
	HOW DUZ I pikachu YR face
		BTW DEFINE
	IF U SAY SO
KTHX

Identifiers within the O HAI block are looked up via slot-access first. If they are not found, the global scope is then searched. If that fails, then an error is thrown.

Slot Access

Bukkit slots are accessed using the slot operator ”-”.

 <object> - <slotname> 

or indirectly using the Srs Biznus operator

 <object> - SRS BIZNUS <expression> MKAY 

Slot access is very important to function calls. The new function call syntax is as follows.

To call a function on an object:

 
<object> IZ <slotname> (WIF <variable> (AN <variable)*)? MKAY

combined with the SrsBinuz operator allows the following:

HOW DUZ I get YR object AN YR varName
	I HAS A funcName ITZ SMOOSH "get" AN varName MKAY
	FOUND YR object IZ SRS BIZNUS funcName MKAY MKAY
IF U SAY SO

This will call get<varName> on object.

Special Slots

Every bukkit contains a few slots that have special meaning

  • parent
  • zomg

TODO - Figure out what else may be needed

parent refers to a bukkit's “parent” object and is described below.

zomg refers to a function that is called when slot access fails. This function should return a variable (that will be placed in the unknown slot) or throw an exception. The default implementation of zomg is to always throw an exception.

Inheritance / Prototyping

To create an object based upon an existing object:

I HAS A <object> ITZ LIEK A <parent>

Behavior of this sort of inheritance is described further below.

To define inheritance using alternate syntax, do the following.

O HAI IM <object> [IM LIEK <parent>]
  <code block>
KTHX

Inheritance implies a few things, one of which is inheritance of slots (described below). Another thing inheritance does is automatically create a “parent” slot on the new object. The “parent” slot refers to the object that this object was inherited from, or its prototype. The parent slot is treated specially by the Bukkit. An interesting side effect of this is that a Bukkit may change its “parent”/“prototype” by changing its parent slot. More on this later.

Inheritance of slots

Declaring a variable within the current object adds that variable to the object.

Accessing a variable from within the current object looks for that variable within the current object. If it is not found, it searches for the variable within the parent object (using the parent slot), and on up the chain of parents until it reaches an object where the parent slot is NOOB or it reaches a parent object is has already searched before.

Assigning a variable within the object first searches for it within the current object. If it has been declared within the current object, then it is set. If that fails, it attempts to access it within the parent object. Search continues in up the chain of parents. If the variable name is found up the inheritance chain, then that variable is declared and created within the current object (where the search started), and the value is set. If the variable search fails and the variable was never previously assigned, then it's a declaration error.

In this way, a child object has all of the values and methods of its ancestors, unless it replaces them within itself.

Functions and Inheritance

No matter where a FUNKSHUN is stored in a slot, during a Slot-Access Function call, the Function obtains variables from the object it was accessed from.

TODO - This needs to be reworded

 <object> IZ <functionSlotName> MKAY 

In this case, the function will pull variables from <object>.

SO:


HOW DUZ I funk YR shun ?
	VISIBLE SMOOSH prefix AN shun MKAY
IF U SAY SO

O HAI IM parentClass
	I HAS A prefix ITZ "parentClass-"
	I HAS A funk ITZ funk    BTW Pulls funk from global scope
KTHX


O HAI IM testClass IM LIEK parentClass
	I HAS A prefix ITZ "testClass-"
KTHX

parentClass IZ funk WIF "HAI" MKAY        BTW parentClass-HAI
testClass IZ funk WIF "HAI" MKAY            BTW testClass-HAI

Mixin Inheritance

LOLCode supports a form of multiple-inheritance (I'm calling mixin-inheritance) via a new use of the SMOOSH operator.

I HAS A <object> ITZ A <parent> SMOOSH <mixin> (AN <mixin>)* 

or

 O HAI IM <object> IM LIEK <parent> SMOOSH <mixin> (AN <mixin>)*
    <statement-block>
KTHX

A mixin may be any bukkit type. When declaring a new object using mixins, All slots defined on the mixin are copied into the newly construct bukkit in reverse order of declaration. So

 I HAS A ZipFileRiver ITZ A River SMOOSH FileStuffz AN ZipStuffz

This copies all slots from ZipStuffz into ZipFileRiver, then all slots from FileStuffz into ZipFileRiver, then replaces the parent slot with a reference to River.

Mixin-Inheritance is static. It can only pull in slots that are defined when the mixin takes place. If the FileStuffz or ZipStuffz objects change after the ZipFileRiver object is defined, the ZipFileRiver class does not see the change.

Here's a method of performing Mixin-Inheritance after a bukkit has been created.

Example:

BTW burger is on the stack

I HAS A cheezburger ITZ A burger SMOOSH cheeze


BTW Let's do the same thing, but assume cheezburger2 already exists

BTW Makes sure all of cheeze and its parent slots are copied into slice
I HAS A slice ITZ A bukkit SMOOSH cheeze

slice-parent R burger-parent
BTW slice & burger are now commons sub-classes

cheezburger2-parent R slice
BTW cheezburger2 now has same functionality as cheezburger


LOLCode Standard Library

These classes represent ideas for an LOLCode standard library of classes for use when Bukkits are first implement. These classes represent functionality and reference implementation and are by no means what should be distributed with LOLCode runtimes.

PileZ (Stacks)

${standlibdir}/collections/pilez.lol


O HAI IM pile
     I HAS A length IZ 0

     HOW DUZ I push YR item
          ME HAS A SRS BIZNUS length MKAY ITZ item
          length R SUM OF length AN 1
     IF U SAY SO

     HOW DUZ I pop
          length R DIFF OF length AN 1
          BTW Do bounds checking...
          I HAS A mom ITZ ME-length
          NERF ME-SRS BIZNUS length MKAY
          FOUND YR mom
     IF U SAY SO
KTHX

Usage:

RiverZ (Streams)

${standlibdir}/collections/riverz.lol


O HAI IM River

KTHX

Usage:

proposals/1.3/bukkit2.txt · Last modified: 2007/09/22 02:45 by joshsuereth
Recent changes RSS feed Creative Commons License Donate Driven by DokuWiki