Edits to the 'about' webpage

Started by noah, July 09, 2006, 12:35:52 AM

Previous topic - Next topic

noah

#15
Hi, Lutz.



Thank you for your helpful reply. I understand that you'd like the Difference page to read well for educated LISPers.



Your example of granular argument evaluation shows CL and Scheme coders what you mean, without requiring additional explanatory text, so it would fit in well, if you want to add it.



Here's my proposal for an edit that includes your example and does not add explanatory text:



---------------
In newLISP macros work like normal functions, but without evaluating their arguments. This way functions can be built, which look like built-in newLISP primitives. In newLISP a built-in function 'expand' can be used to initiate variable expansion in macros or anywhere else explicitely:

 (define (raise-to power)
    (expand (fn (base) (pow base power)) 'power))

 (define square (raise-to 2))
 (define cube (raise-to 3))

 (square 5) => 25
 (cube 5)   => 125

Separating evaluation and expansion of parameters offers more detailed control.
---------------

+++++++++++++++
In newLISP, macros don't evaluate their arguments. As a result, newLISP macros can work like built-in newLISP primitives:

(define-macro (my-setq x y) (set x (eval y)))

;; or the same avoiding variable capture

(define-macro (my-setq) (set (args 0) (eval (args 1))))

newLISP offers better control over parameter evaluation than Common Lisp and Scheme do. In newLISP, a built-in function 'expand' can be used to initiate variable expansion explicitly:

 (define (raise-to power)
    (expand (fn (base) (pow base power)) 'power))

 (define square (raise-to 2))
 (define cube (raise-to 3))

 (square 5) => 25
 (cube 5)   => 125

++++++++++++++



-Noah

noah

#16
Hi, Lutz.



Here's a proposed edit.  This one includes corrections to my last proposed edit.



-Noah



newLISP compared to Common Lisp and Scheme

Last updated July 12th, 2006


This page clarifies some differences between newLISP and the older standards Common Lisp and Scheme. Read the About page to find out more about newLISP's unique approach to LISP.

   1. Unlike Common Lisp, newLISP and Scheme evaluate the operator part of an expression before applying the operator to its arguments.

   2. In newLISP, lambda expressions evaluate to themselves. They are a subtype of the list data type, a first-class data object that can be manipulated like any other list.  In Common Lisp and Scheme, lambda expressions, when evaluated, return a special 'function' data type with its free variables binding to the current environment and forming a lexical closure.

In newLISP, binding of variables in lambda expressions takes place during application of the lambda expression.  In other LISPs, lambda expressions are used to realize static variables and content via lexical closures.

      Static variables are a precondition for a programming language to allow object-oriented programming in that language.  In newLISP, lexically closed contexts (namespaces) are used for prototype-based object-oriented programming. Like lambda expressions, contexts in newLISP are first-class objects. Contexts can be created and destroyed during runtime, passed as parameters, and referred to by symbols.


   3. In newLISP and Scheme, variables, primitives, and user-defined functions share the same symbol space. In Common Lisp, function symbols and variable symbols each use a dedicated symbol space. This is why Common LISP function symbols  sometimes must be prefixed with the sharp quote #'.


   4. In newLISP, all variables are dynamically scoped by default. However, by defining a function in its own context, static/lexical scoping can be achieved and variable capture can be avoided. In newLISP, functions and data can share a namespace. Common Lisp and Scheme are lexically scoped by default and use lambda expressions as the closure mechanism. Common Lisp also offers 'special variables' for dynamic scoping.

   5. In Common Lisp and Scheme, the 'cdr' part of the lisp cell can be used to contain another data object, in which case we have a dotted pair. In newLISP, there are no dotted pairs. Instead, each newLISP cell contains one object and a pointer to another object if the cell is part of a list. As a result, 'cons' behaves differently in newLISP than in other LISPs.

       ;; Common Lisp and Scheme
       (cons 'a 'b) => (a . b)   ; a dotted pair

       [a | b]

       ;; newLISP
       (cons 'a 'b) => (a b)     ; a list

       ;; LISP cells in newLISP
       (+ 2 3 (* 4 3))

       [ ]
       
        [+] -> [2] -> [3] -> [ ]
                             
                              [*] -> [4] -> [3]

   6. In newLISP, all arguments to a user-defined function are optional.  Unassigned argument variables will assume the value 'nil' inside their function.
   
   7. Logically, there are no unbound or non-existing symbols in newLISP.  Any unbound or non-existing symbol is bound to 'nil' in the current namespace when it is first used.

   8. 'nil' and 'true' are Boolean constants in newLISP. In Common Lisp, 'nil' has an additional role as a list terminator:

       ;; Common Lisp
       (cons 'x nil) => (x)

       ;; newLISP
       (cons 'x nil) => (x nil)

      Scheme has the two Boolean constants '#t' and '#f' for true and false.


   9. In newLISP, every object is only referenced once (ORO), with the exception of symbols, contexts, and context objects. newLISP's ORO rule allows automatic, stack-based, 'on the go' memory management without the traditional garbage collection algorithms used in Common Lisp and Scheme. newLISP passes parameters by value and stores intermediate results on a 'result stack' where their memory gets recycled after function return. Only under error conditions will newLISP employ a classic mark-and-sweep algorithm to reclaim unreferenced memory.

newLISP's automatic memory management is fully transparent to the programmer but faster and lighter on resource requirements when compared to classic garbage collection algorithms. Because ORO memory management is synchronous, newLISP code has constant and repeatable execution time. The combination of newLISP's value-passing style and unique memory management make it the fastest interactive (non-compiled) LISP available and one of the fastest scripting languages available in general.  

10. In newLISP, macros don't evaluate their arguments. As a result, newLISP macros can work like built-in newLISP primitives:

(define-macro (my-setq x y) (set x (eval y)))

;; or the same avoiding variable capture

(define-macro (my-setq) (set (args 0) (eval (args 1))))

newLISP offers better control over parameter evaluation than Common Lisp and Scheme offer. In newLISP, a built-in function 'expand' can be used to initiate variable expansion explicitly:

 (define (raise-to power)
    (expand (fn (base) (pow base power)) 'power))

 (define square (raise-to 2))
 (define cube (raise-to 3))

 (square 5) => 25
 (cube 5)   => 125

  11. newLISP only requires the equal sign '=' to test for equality. This is a consequence of newLISP's value-passing style. Common Lisp requires 'eq', 'eql', 'equal', 'equalp', '=', 'string=', 'string-equal', 'char=', and 'char-eq', for equality tests of expressions, data types, identical objects, and referenced objects.

  12. newLISP features implicit indexing. This is a logical extension of LISP evaluation rules overloading lists or numbers with the indexing functionality available from built-in list and string functions like nth, rest or slice, i.e.:

       (set 'myList '(a b c (d e) f g))

       ; using nth
       (nth 2 myList) => c
       (nth 3 1 myList) => e
       (nth -3 0 myList) => d

       ; using implicit indexing
       (myList 2) => c
       (myList 3 1) => e
       (myList -3 0) => d

       ; implicit rest, slice
       (1 myList) => (b c (d e) f g)
       (-3 myList) => ((d e) f g)
       (1 2 myList) => (b c)

      Using implicit indexing is optional, but in many instances it speeds up coding and increases readability.