Software Development
Blogs and Discussion
developer.*
Books Articles Blogs Subscribe d.* Gear About Home

The spinoza Programming Language

If I succeed in living for less in Thailand I am looking at three months of leisure and I need to use that time well. Major goals outside of software are learning Buddhist meditation and upping my running from 20 miles a week to 30.

Software-wise, I was working on a base object which would demonstrate in the form of an article my idea of the "core, stateful" object as a base .Net object.

However, in working on this I realized that what I first need to do is accomplish a long term dream, which is developing a new language and compiler ex nihilo, because in my view, a true stateful object would have base procedures for executing macros, in which a series of its procedures would be executed with conditional and looping logic.

The spinoza compiler, interpreter and GUI shall be developed first as a VB.Net system. I really should use Java but I am impatient that spinoza just exist.

Spinoza will steal without discrimination the syntax of C and the indentation of python. It shall be OO all the way down.

Spinoza shall proudly implement Begin and End so that any list of distinct statements may be a complete statement. Begin shall not be left curley brace: it shall be the word Begin as seen in Algol and Pascal, because this is more visible and more assertive: like wise for End. An optional tag may be added to begin and end for help in untangling nested blocks.

Objects will be created at Begin block startup and be destroyed at block end or when a drop statement is executed because it has long irritated me that I cannot reveal the TRUE scope of a variable by clearly DROPping it in an instruction to the system that the variable should be (or may be destroyed).

A feature of the architecture of the compiler and interpreter shall infect in a benign fashion the overall philosophy of spinoza, for the compiler and interpreter shall obsessively cache.

The compiler will be single pass and included in the interpreter (with nonetheless clear separation of function) as well as the lexxer. Let me explain.

When a classical compiler is presented with code it "passes over" the code to scan for tokens, it then "passes over" the code to parse (and create a parse tree), it "walks through" the parse tree while emitting code, often for an interpreter which then interprets. All this pacing about is tiresome.

Spinoza will instead proceed left to right. When it needs a token it shall form the token from the raw input while building a true token array in a lookaside fashion for later use as I'll describe.

This token will be passed up through a parse tree of code similar to the parse-tree-of-code found in Build Your Own .Net Language and Compiler, but during the parse any expression that CAN be evaluated WILL be evaluated, and its value (as well as the object code needed to recalculate the value) heaped in the spinoza heap indexed by the expression's string form, with specific information as to context.

Suppose spinoza encounters the expression (a+1). Since it is in parentheses, the expression recognizer which is also called for a main expression will be called.

This recognizer will check the heap for a+1 qualified with the scoping level of a+1, which is the scope of the variable in the expression declared at the deepest Begin End block.

If it finds it the heap entry will be an object of type spinozaClass (corresponding to the code for the expression) or spinozaObject (the value of the expression). If when a+1 was evaluated it had constant type (such that a was declared without scope and with a constant value) then an object will exist in the heap with the value of a+1.

Usually, however, the value of a is not known, but here, there are two possibilities. The code may still be in the scope of a (more precisely the scope of the expression a+1 considered as the scope of the lowest variable, ranked by scope): in this case, we can use the cached object code for a+1 to recalculate a+1.

But failing this, a+1 will ALWAYS have the same lexical analysis and we can reuse this!

In summary: Spinoza knows that for any expression, we can have its (1) constant value, or failing this (2) its object code or failing this (3) its lexical analysis or failing this (for a new expression (4) nothing at all, in which case Spinoza must lexically analyze, parse and evaluate the expression.

The obvious objection is that needed data structures may very well be defined only to the right of the expression and that a modern programming language MUST not require definition to the left of use.

The answer is that given an OO design, Null is never ambiguous, as it is on many legacy platforms, with regards to values including zero and the null string and that we know what to do when calculating with Null: return Null in the sense of a report that "this expression is very nice: here is its lexical analysis, in fact: here also is the object code which calculates its value."

"But at this time I lack full information to actually execute the expression."

In other words: many programs in fact define before use and Spinoza should be able to execute them in source form while storing their compiled object code and lexical analysis in a left to right scan. Programs which do not shall cause Spinoza to stop executing but it will continue to scan and compile, and then resume execution if the compilation has successfully resolved all symbols.

My final target will be a spinoza that will always be learning. For each distinct expression (there are no statements in spinoza, only expressions, including expressions with side effects including a C-like assignment) the lexical analysis and IF POSSIBLE the object code and IF POSSIBLE the value of the expression will be stored and on Windows the GUI will persist that storage to the Windows Registry.

Meaning that spinoza will lexically analyze the common statement i+1 only once over the period of its useful life in a single installation, determine the value of 5*8 only once, and determine the object code for hello world only once. I am making a wild guess that this would save time.

Here is the tentative BNF of spinoza, probably with errors:

    expression := seqFactor [ seqRHS ] * 

addFactor := mulFactor [ mulRHS ] *
addRHS := addOp addFactor
andFactor := relFactor [ relRHS ] *
andRHS := "&&" andFactor
assignmentFactor := inFactor [ inRHS ] *
assignmentRHS := "<-" assignmentFactor
block := BEGIN expression END
boundListRHS := "," boundList
caseFunction := SELECT LP expression RP
complexIdentifier := IDENTIFIER [ complexIdentifierRHS ] *
complexIdentifierRHS = "." IDENTIFIER
concatFactor := addFactor [ addRHS ] *
ctlFunction := ifFunction | caseFunction | whileFunction |
forFunction | FORK LP RP | EXIT LP RP |
STOP LP RP | return
declaration := DCL LP IDENTIFIER [ LP parameterList RP ] ":"
"lng" | "sgl" | "dbl" | "str" | "col" |
expression |
predefinedType [ LP expression RP ] RP
dropclaration := DROP LP IDENTIFIER RP
function := ctlFunction | userFunction
ifFunction := "?" LP seqFactor "," seqFactor "," seqFactor RP
inFactor := orFactor [ orRHS ] *
inRHS := "@" inFactor
lValue := scalar | reference
mulFactor := operand | LP expression RP
mulRHS := mulOp mulFactor
operand := STRING | scalar | NUMBER | function | block |
declaration | dropclaration
orFactor := andFactor [ andRHS ] *
orRHS := "||" orFactor
reference := "{" expression "}"
relFactor := concatFactor [ concatRHS ] *
relRHS := relOp relFactor
return := RETURN LP expression RP
scalar = complexIdentifier [ "(" subscriptList ")" ]
scalarType := "boo" | "byt" | "shr" | "int" |
seqFactor := lValue [ assignmentRHS ] *
seqRHS := "," seqFactor
userFunction := complexIdentifier LP expression RP
utilityOp := utility LP IDENTIFIER utilityOpArgList RP
whileFunction := WHILE LP expression RP

In the above:

LP is the left parenthesis or a newline followed by a line which
contains more leading blanks than the preceding line: RP is the right parenthesis or a newline followed by a line which contains fewer leading blanks.

This allows the spinoza programmer to code in Python style or to code one line macros using ordinary parentheses.

Most of the remaining all upper case symbols represent their literal values.

Readers of this blog will of course have first crack with beta Spinoza.

The development of spinoza will answer the question, what if a programming framework stored, as much as possible, the results of compilation and interpretation. Just how lazy can we be if we apply a fine-grained object-oriented paradigm in which it is clear at all times how to package results for easy retrieval?

As of this evening, I have complete the top down design of spinoza and it appears to contain these major classes.

spinoza is the spinoza main engine: spinoza.evaluate() runs the spinoza program

spinozaClass represents a spinoza class and seems to be a natural place to put the class lexical analysis and pcode. Note that since I'm implementing spinozaClass it will be able to faithfully expose core procedures if stateful. It will be taggable as not usable for situations where the class knows it contains a bug. It will provide automatic Reflection in the form of a list of its procedures as well as the ability to cast a class to an object, as long as I get around to it, because I am biased towards environments where code is accessible as a first-class object.

spinozaContext is a simple class which tracks unique block context as a Dewey decimal number structure: for example the third child block of the second child block of the main expression has context 1.2.3. We need to associate class with object code (spinozaPCode) to show the scope of the lowest declared vatable in the spinoza p code so we can reuse the pcode as needed.

spinozaObject represents an instance of a spinoza class.

spinozaHeap is the heap, keyed by expressions and expression scopes, which will function both as a classic heap (where the expression is a variable) and as a cache for expressions...containing their spinozaClass with their lexical analysis and pCode, and/or their constant value.

Etc.

Spinoza's motivation is disgust with the way in which so many computers around the world whir and click and spin their wheels redetermining that which has been determined already, while in front of them sits, in a perverted vigil, the weary human being in whose name all this nonsense began.

Spinoza runs against the grain of deconstruction insofar as deconstruction at all celebrates iteration and the deferral, for Spinoza wants to determine "as much as possible once and for all".

Consider 1+1. Now, I understand full well that it doesn't have a fixed meaning in some languages. I suppose you could, in some languages, redefine the number 1: an early compiler by mistake allowed assignments to constants and its programmers, merry pranksters that they were, used this feature to change the meaning of constants.

But in Spinoza, 1 means 1, and + cannot be overloaded as in C++. Therefore it shall be evaluated but once.

In the far more common case, common sequences will be lexically analyzed or compiled. I predict at this time that as a result a Spinoza installation will gradually improve as it evolves.

Earth, of course, to Major Tom. To have each and every expression cached in the persistent heap I'd have to call cache, not JUST when the grammar symbol expression is evaluated but when ANY subexpression grammar symbol was evaluated. This is not the plan at this time. The plan now is such that only expressions are cached, meaning that all the Spinoza programmer has to do, to cache the lexical analysis, pcode, or constant value of an expression is to surround it by parentheses, because when the recursive descent spinoza parser encounters a left parenthesis when searching for a factor of a multiplication, it will call expression.

The model of using the heap as a persistent cache will be, if it works out in the basics, extensible to storing other material with expressions including .Net CLR code. Here, my disinterest in deep .Net CLR unfortunately asserts itself because here, I focus first on my own pCode interpreter in place of generating CLR code. This created some criticism of the rather superficial chapter in Build Your Own on the CLR: by the time I got around to generating code for the CLR my page budget was close to be exhausted, and not being able to search for a job, I was pawning my laptop.

As in the story The Nine Billion Names of God, I am perhaps in thrall like the monks to the idea of making ALL AND ONLY necessary calculations.

Or maybe not.

I am working on Spinoza while packing for an exit from Red China. WilCan says it will store my extra things but only if I have an official Chinese export license. I have sent this Hong Kong storage firm an email stating like a lawyer that this is not necessary since all I want to store are the sorts of things I brought into China through Lo Wu.

But I may leave half my library and an old Presario laptop in China. I know the laptop will be useful in China, for recycling comes natural to people making pennies a day. The books (which I have read) are another matter and I shall feel guilty if I leave them.

At the same time, I need to be able to carry my worldly goods up and down MTR stairs in the summer's heat. I do not have a permanent home unless I count my ex-wife's condo (she doesn't) and I migrate between hotels at this time.

The On-On Hotel in Phuket, as described in Lonely Planet, sounds OK at about 5.00 per night but we shall have to see. I can't stay long in Hong Kong: even the YMCA (the hotel-like four star Salisbury in Kowloon) is 75.00 a night.

As to paid employment I am thinking of changing careers to teaching computer science and English in China since I enjoy teaching and because of increasing frustration with the way in which technical people no longer drive the process: my experience is that you're listened to in inverse relationship to the depth of your analysis.

"Why do you ask for so much? Why not ask for more?" - Leonard Cohen, Bird on a Wire

Categories: 

cool

super cool!

Excellent article

That was really a nice article. Can you refer me some more coding examples for the same. Basically I am a Php Programmer and have done C, C++ nad Java also. I would love to work on this language also.

You can send your comments in here or on this page.
http://www.technotrendz.net/php_mysql_programmer_phuket_thailand.htm

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Recent comments

User login

About our advertising.

Atom Feed

developer.* Blogs also has an Atom feed, located at this url.

Click here for more information about Atom.

A Jolt Award Finalist
Software Creativity 2.0
Foreword by Tom DeMarco

Recent Posters

Based on most recent 60 days, sorted by # of posts and name.

Google
Web developer.*

Who's online

There are currently 0 users and 25 guests online.

Syndicate

Syndicate content
All views expressed by authors, bloggers, and commentors are their own and do not necessarily reflect the views of developer.* or its proprietors.
Click to read the Copyright Notice.

All content copyright ©2000-2005 by the individual specified authors (and where not specified, copyright by Read Media, LLC). Reprint or redistribute only with written permission from the author and/or developer.*.

www.developerdotstar.com