Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> comp.databases.theory -> Re: Storing data and code in a Db with LISP-like interface

Re: Storing data and code in a Db with LISP-like interface

From: Neo <neo55592_at_hotmail.com>
Date: 30 Mar 2006 23:21:23 -0800
Message-ID: <1143789683.163768.33380@e56g2000cwe.googlegroups.com>

>> (create (it) symbol (create 'c' 'a' 'r'))
>
> I will gnaw my legs off before I will write code like that to earn a living!

:) Yes, I agree the "beauty" of the above simple but highly recursive syntax "(func param1 param2 ...)" where any element itself can be (func param1 ...) and so on until eternity is difficult to appreciate.

> (And at this point I don't care what benefits you imagine it confers, > so I don't mind that you haven't bothered to explain.)

I will try to explain with an analogy (realizing that each analogy can be bended to any end). Imagine a mechanic with fixed-size wrenches of sizes from 1 to 10. Nearly all the nuts he has to deal with are sizes between 1 to 10. An odd size comes up once in a blue moon, but for the most part his tool set is nearly perfect for his universe of tasks. Now another mechanic comes along with a prototype of an adjustable wrench and it supposedly can handle any nut size from 0.1 to 20. Upon initial inspection of the new tool, the first mechanic says, I will gnaw my legs off before using this new fangled tool. I don't see any benefit to it. It is heavier and takes longer to setup and use. An that is exactly true for nut sizes 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10. But now I offer you a nut that is an off size of 12.34. I would like you (or other mechanics) to use their current tools to create a function that can find the root, given any specified hierarchy and given any specific thing in that hierarchy. An important things is, the function should work not only for data entered before writing the function, but also for data (new hierarchies and things) entered after the function is created. Below example demos this scenario.

// This example creates a number of persons
// and puts them in a bi-directional parent/child hierarchy.
// Then it creates a function (stored in db)
// that finds the root (in either direction)
// given a heirarchy and a person as parameters.
// Next the same persons are put in second boss/empolye hierarchy.
// The same function created earlier, without modification,
// finds the root of new hierarchies.
// While not necessary, the function uses recursion to find root.

// Create a type named person.
(create type instance (new))
(create (it) name (findElseAdd name instance 'person'))

// Create a person named god.
(create person instance (new))
(create (it) name (findElseAdd name instance 'god'))

// Create a person named adam.
(create person instance (new))
(create (it) name (findElseAdd name instance 'adam'))

// Create a person named eve.
(create person instance (new))
(create (it) name (findElseAdd name instance 'eve'))

// Create a person named abraham.
(create person instance (new))
(create (it) name (findElseAdd name instance 'abraham'))

// Create a person named issac.
(create person instance (new))
(create (it) name (findElseAdd name instance 'issac'))

// Create a person named ishmael.
(create person instance (new))
(create (it) name (findElseAdd name instance 'ishmael'))

// Note: the verbs parent/child are not created // as they already exist in a default database.

// Create following parent/child hierarchy:
// god (root parent)
//   adam & eve
//     abraham
//       issace & ishmael

(create god child adam)
(create adam parent god)

(create god child eve)
(create eve parent god)

(create adam child abraham)
(create abraham parent adam)

(create eve child abraham)
(create abraham parent eve)

(create abraham child issac)
(create issac parent abraham)

(create abraham child ishmael)
(create ishmael parent abraham)

// Create a function named getRoot with 2 parameters.
// Param1 indicates a hierarchy.
// Param2 indicate a person.
// Note: the function recurses.

(create function instance (new))
(create (it) name (findElseAdd name instance 'getRoot'))
(create (it) parameter 'hierarchy')
(create (it) parameter 'person')

// Switch to save script in db mode via GUI.
(getRoot

    code
    (block

       (createVar 'higherPerson')
       (create (getVar 'higherPerson')
               refersTo
               (firstNode (select (getVarVal 'person')
                                  (getVarVal 'hierarchy')
                                  *
                          )
               )
       )
       (if (getVarVal 'higherPerson')
           // Then
           (return (getRoot (getVarVal 'hierarchy')
                            (getVarVal 'higherPerson')
                   )
           )
           // Else
           (return (firstNode (getVarVal 'person')
                   )
           )
       )

    )
)

// Switch back to execute script mode via GUI.

// Get root parent of various persons.
// Displays god.
(msgbox (getRoot parent god))
(msgbox (getRoot parent adam))
(msgbox (getRoot parent eve))
(msgbox (getRoot parent abraham))
(msgbox (getRoot parent issac))
(msgbox (getRoot parent ishmael))

// Get root child of various persons.
// Displays issac.
// Note: Should also display ishmael, but simple function doesn't.

(msgbox (getRoot child issac))
(msgbox (getRoot child abraham))
(msgbox (getRoot child eve))
(msgbox (getRoot child adam))
(msgbox (getRoot child god))

// Place above persons in a new boss/employe hierarchy. // Create a verb named boss.
(create verb instance (new))
(create (it) name (findElseAdd name instance 'boss'))

// Create a verb named employe.
(create verb instance (new))
(create (it) name (findElseAdd name instance 'employe'))

// Create following boss/employe hierarchy:
// issac & ishmael (root boss)
//   abraham
//     adam
//       eve

(create issac employe abraham)
(create abraham boss issac)

(create ishmael employe abraham)
(create abraham boss ishmael)

(create abraham employe adam)
(create adam boss abraham)

(create adam employe eve)
(create eve boss adam)

// Get root boss for various persons using function created earlier.
// Displays issac.
// Note: Should also display ishmael, but simple function doesn't.

(msgbox (getRoot boss issac))
(msgbox (getRoot boss abraham))
(msgbox (getRoot boss adam))
(msgbox (getRoot boss eve))

// Get root employe for various persons. // Displays eve.
(msgbox (getRoot employe eve))
(msgbox (getRoot employe adam))
(msgbox (getRoot employe abraham))
(msgbox (getRoot employe issac))
(msgbox (getRoot employe ishmael))

// EXPERIMENTAL DB DESCRIPTION ----------------------------------------
The experimental db can store both data and code. Unlike typical databases, data is not stored using a table/record methodology, but via nodes where each node can connect to any other node in a manner similar to neurons in the human brain.

The experimental db has a LISP-like interface. In general each expression
starts with "(" and ends with ")". Within the parentheses there can be any number of elements which are typically seperated by a space. The first element is the function.
The remaining elements are function parameters. Expression elements can themselves be a sub expression and elements of the sub expression can
also be a sub expression and so on forever (theoretically).

Thus, a typical expression might be:
(func1 param1 param2 param3 ...)

where any element be a sub expression, ie:
(func1 (func2 param1 param2 ...) param2 param3 ...)

and so on:
(func1 (func2 param1 (func3 param1 ...)) param2 param3 ...)

also can be rearranged as:
(func1 (func2 param1

              (func3 param1
                     ...
              )
              ...
       )
       param2
       param3
       ...

)

Because of the number of parentheses,
script can be made more legibile by
1) using fixed font
2) lining up corresponding parentheses.

Note, that the db's "schema" is such that anything can have 0 to many names.
And a name can have 0 to many representations such as a string of ascii symbols, chinese symbols, phonetics, etc
(only ascii symbols are implemented currently).

Functions can create local variables which are stored on a "stack" which is also in the db and functions (system or user-defined) are re-entrant.

// CONVENTIONS, SHORTCUTS, COMMON FUNCTIONS


In scripts, comments begin with two forward slashes "//" (as in C/C++).

(new) create a new node to represent something.

(it) refers to the thing created by last (new) in current scope.

When a script containing 'xyz' is processed, str 'xyz' is created it in db, even if it does not exist.
This is done to reduce length/complexity of scripts.

// An element enclosed by single quote is equivalent to: 'xyz' => (select 'x' 'y' 'z')

// An element not enclosed by quotes (ie xyz) is equivalent to // finding the first thing whose first name's first symbols string is as specified (ie 'xyz).
xyz =>
  (firstNode (select *

                     name
                     (firstNode (and (select name instance *)
                                     (select * symbol 'xyz')
                                )
                     )
             )

  )

// Function findElseAdd finds the instance of specified class // whose name has the specified symbol string.
(findElseAdd name instance 'bob') =>

  (if (and (select name instance *)

           (select * symbol 'bob')
      )

      // Then
      (return (select * symbol 'bob'))

      // Else
      (block
        (create name instance (new))
        (create (it) symbol (create 'b' 'o' 'b'))
        (return (it))
      )

  )

// Function createVar creates a variable (on the stack in current scope).
// whose name's has the specified symbol string.
(createVar 'var1') =>

  (block

     (create (new) name (findElseAdd name instance 'var1'))
     (create (select stackPtr refersTo *) variable (it))
  )

// Function getVar selects a variable (on the stack in current scope) // whose name's has the specified symbol string.
(getVar 'var1') =>

  (and (select (select stackPtr refersTo *) variable *)

       (select * name (select * symbol 'var1'))   )

// Function getVarVal selects the "value" of a variable
// (on the stack in current scope)
// whose name's has the specified symbol string.

(getVarVal 'var1') =>

  (select (getVar 'var1') refersTo *) Received on Fri Mar 31 2006 - 01:21:23 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US