newLISPtm v.10.0 Release Notes September 22nd, 2008
The current development release v9.9.4 is a precursor to version 10.0, which will be released in the last quarter of 2008.
newLISP version 10.0 marks a new generation of newLISP with new abilities and some incompatibilities with the previous official release v.9.4.x series released in August of 2008. Any production source running on the new generation of newLISP should be carefully checked against this release notes.
Version 10.0 gives newLISP abilities like reference returns, which are usual in other programming languages, and make learning newLISP even easier for newcomers.
Reference returns
Any built-in function returning a list, array or string or a an element of a list, array o string, will return a reference and not a copy if the list or array is bound to a symbol. Destructive function can now work on the return value of other function modifying the original list, array or string. The new setf can be used to modify an element of a list, array or string referencing it via one of the many available list, array and string accessors:
(set 'lst '(a b c)) (setf (first lst) 99) lst → (99 b c) (setf (lst -1) 'C) lst $rarr; (99 b C) (set 'A '((a 1) (b 2) (c 3))) (push 'z (assoc 'c A)) A → ((a 1) (b 2) (z c 3)) (set 'L '(a b (c d e f g))) (= (replace 'f (nth (+ 1 1) L) 'z) '(c d e z g)) (= L '(a b (c d e z g))) (setq s "abc") (setf (s -1) "C") (setf (nth 1 s) "B") (setf (first s) "The A") s → "The ABC"The following functions return a reference to the list, array or string or element of a list or array, which can be modified by other functions. Previously these functions returned a copy (with exception of set):
assoc, first, last, lookup, ntn, replace, reverse, rotate, set, setf setq, set-ref, set-ref-all, sort, swapAll control structures without local variables maintain reference for the last return value in the statement block if that value is tied directly or indirectly to a symbol:
begin, if, if-not, when, unless>/tt>, while, until, do-while, do-until, cond and case.In none of these the assumption can be made, that a copy is returned. To force the return of a copy instead of a reference enclose an expresion in a simple copy lambda function:
(define (copy x) x)Normally there are few circumstances in program code relying on copied return. On the contrary is seems that the new possibility to work directly on returned references will give many opportunities to write terser and speedier code.
The new setf function
setf is a new introduced function working not only on symbol references like setq but also on any reference returned from an expression. setq and the new setf both point to the same internal code and are interchangeable. It is recommended to use setq for setting symbol variables and use setf whenever a sublist, sub array or substring is referenced, Note that any list, array or string changed must be anchored in a symbol referencing it. If no reference is found an error message is returned:
(setq l1 '(a b c)) (setq l2 '(d e f)) (setf 1 (append l1 l2) 99) ERR: no symbol reference found in function setfAllthough the partial lists are anchored in l1 and l2 the return value from the append fuction is not referenced and cannot be used by setf
Anaphoric system variable $it
The new system variable $it is used when doing self referential assginments in setf and hashes. It can also be used in many cases as an alternative choice where the system variable $0 is used.
(setq lst '(1 2 3 4)) (setf (lst 2) (* $it 10)) lst → (1 2 30 4) (setq str "abc") (setf (str -1) (dup $it)) str → "abcc" (MyHash "var" "hello") (MyHash "var" (upper-case $it)) (MyHash → "HELLO")The functions find-all, replace, set-ref and set-ref-all use $it as an alternative choice to $0.
The difference between $it and $0 is, that $it will not retain the value beyond the evaluation of the expression it is part of, while $0 retains the value until used in another expression. $it is read-only, while $0 is also user settable. Neither $it nor $0 - $15 are reentrant. Another subexpression using these variables will change them too.
Removed functions
The changes make many of the involved functions faster. It also obsoletes the functions set-assoc, assoc-set, set-nth, nth-set and ref-set. These functions have been removed. The last chapter or this release notes shows examples of conversions from old to new functions or different usage of old functions.
Changed functions
The parenthesized syntax for assoc nth ref set-ref and set-ref-all has been eliminated. Only the traditional flat syntax is allowed. Note that the parentheses syntax should not be confused with the syntax used in implicit indexing. In the deprected parenthesized syntax, the parentheses were syntactical sugar similar to parentheses used in the dotimes or for forms. The following example illustrates this:
(nth (theList idx)) ; parenthesized syntax (setf (theList idx) value) ; implicit indexing syntaxIn the first line the inner parentheses are part of a special form syntax. In the second example all parentheses are part of s-expressions.
When multiple indices or keys are used, a list is specified instead of a single index or key:
(nth i myList) ; single index, flat form (myList i) ; single index implicit index form (nth idxList myList) ; multiple indices, flat form (myList idx1 idx2 ... ) ; multiple indices, implicit index, flat indices (myList idxList) ; multiple indices, inplicit index, index vector (assoc key aList) ; single key (assoc list-of-keys aList) ; multiple keyIndex list vectors are the same as returned by ref and ref-all. Index vectors have been supported by pop and push for several years. Index vectors tie together nth, ref, ref-all, push and pop. Using index vectors in the syntax of 'nth', give 'nth' a uniform parameter arity regardless of the number of indices involved.
Other changes
- env when given without any parameters, now returns ans association list. Before a flat list of environment strings, e.g. "KEY=value" was returned.
- eval-string has reversed the order of the context and error-handler parameters. The error-handler is now thr last optional parameter.
- lookup now can take multiple keys similar to assoc.
- (nth str 0) and (nth str -1) will return the empty string "" is str is the empty string "". Before a i index too returned the empty list. Now a out-of-bounds error will be thrown.
- read-expr has a revised syntax identical now to the syntax pattern of eva-string. The workings of read-expr has changed too (see reference manual for details).
- set and setq will not allow a missing value argument as was tolerated in previous versions.
- unless is reintroduced working like (when (not ...) ...) with no else clause.
- Several new file extensions and media MIME types have been added to the HTTPD mode of newLISP in server mode. See the Users manual for details.
- The initialization file in either $HOME/.init.lsp or $USERPROFILE/.init.lsp or $DOCUMENT_ROOT/.init is loaded if it exists, else if $NEWLISPDIR/init.lsp exists, it is loaded.
Changed Lisp source files
Although all old code should be thoroughly investigated for incompatibilities many newLISP source files will be compatible with version 10.0 without any changes. In 55 lisp source files shipped with newLISP only 4 files needed minor changes.
modules/stat.lsp module for statistics functions modules/xmlrpc-client.lsp XML RPC client module guiserver/newlisp-edit.lsp The editor in newLISP-GS guiserver/pinballs-demo.lsp A demo file in newLISP-GS Conversion of eliminated and changed functions
set-nth, nth-set, set-assoc, assoc-set all have to be replaced by a combination of the new setf and nth, assoc.
(nth-set (data idx) value) (nth-set idx data value) (set-nth (data idx) value) (set-nth idx data value) ; change to one of the following (setf (nth idx data) value) (setf (data idx) value) (set-assoc (aList key) value) ; change to (setf (assoc key aList) value)data is either a list or array or a string.
Mulitple indices have to be put in a vector, and or implicit indexing is used:
(nth i j k data) (nth (data i j k)) ; change to on of the following (nth (list i j k) data) (data (list i j k)) (data i j k)data is either a list or an array, because strings are one-dimensional.
The conversion of eliminated functions will typically not be overlooked, because programs will throw errors when running ito undefined functions. More subtle are the following changes which could escape detection is code is not tested carefully
Nested expressions of built-in destructive functions must not rely on functions to return a copy. E.g. in previous versions (pop (sort myList)), myList was sorted but the pop of the first element happened on a copy:
(set 'myList '(b d c a)) ; in 9.4.5 and earlier (pop (sort myList)) myList → (a b c d) ; in 9.9.2 and later (pop (sort myList)) myList → (b c d)The new behavior leads to faster and more efficiently coded programs. It is also the behavior , what newcomers to newLISP coming from other programming languages would intuitively expect.
env without any parameters now returns and association list. to get the old behavior use (exec "env") returning a flat list of environment strings.
eval-string has swapped the order of the error-handler and context parameter:
; in 9.4.5 and earlier (eval-string theString error-handler the-context) ; in 9.9.4 and later change to (eval-string theString the-context error-handler)Both, the error-handler and context parameter are optional.
read-expr has changed order of parameters and also changed functionality. Please consult the reference manual for details.
unless has lost the else clause. If an else was not existing in the first place, conversion is not necessary, but all unless containing an else clause should be converted to if-not, which was introduced in version 9.4.5.
The order of loading $HOME/.init.lsp and $NEWLISPDIR/init.lsp has changed. The new version will look first for $HOME/.init.lsp and not load $NEWLISPDIR/init.lsp if $HOME/.init.lsp could be loaded. $NEWLISPDIR/init.lsp is only loaded is $HOME/.init.lsp does not exist.
∂