development release newLISP v.9.3.3

Started by Lutz, March 07, 2008, 07:57:51 AM

Previous topic - Next topic

Lutz

• new options for 'bind' and 'search'

• compiles again on Solaris

• bugfixes



files and changes notes: http://www.newlisp.org/downloads/development/">http://www.newlisp.org/downloads/development/

Jeff

#1
Um... read was the one we asked for that would return us the quote lisp expression from a string, yes?  Why in heaven's name did you remove that?  That was useful.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Lutz

#2
After playing around with it for some time, I didn't find it any useful. Almost anything practical you can do with it, you can do using 'define-macro' and redefining 'define'. Just found it to be one of those functions, which looks interesting at first, but nobody is ever using it.



I could change my mind, if somebody can show me a real practical application of it.



For me the 'read-expr' (as I wanted to rename it), is along the lines of tail-recursion-optimization: something useful and interesting on theoretical grounds, but not really improving the practicality of newLISP when writing applications, as tail-recursion is functional equivalent to iteration.


Quotewould return us the quote lisp expression from a string


if this is what you want to do, you still can do this:


(set 's "(define (double x) (+ x x))")
(eval-string (append "'" s))
=>
(define (double x)
 (+ x x))

cormullion

#3
I wondered whether it would be good for reading newLISP source code to replace my tokenizer which I don't think is good enough, even though it only took a hour or so to write.  Although it was good that read/read-expr kept comments, I couldn't really get it to do what I wanted.

Jeff

#4
Uses:

  1. Preprocessing

  2. Creating a "sandboxed" environment to execute in

  3. Writing your own interpreter



A language does not stay useful by limiting its utility.  Trust users to find uses for these kinds of functions.  Your lack of need for the function does not mean another developer won't find it useful.  It's like private methods in Java.  Hiding the internal functionality of a class is fine.  Keeping other developers from being able to hack a module because you are worried they will do it wrong is not.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Lutz

#5
Quotereplace my tokenizer which I don't think is good enough


'read-expr' was not changing the tokenizer, source-code would still have to be well-formed as of newLISP, to pass through 'read-expr' even if 'read-expr' is uses in the string returning mode. 'read-expr' did not have any influence on the tokenizing process, offerring this newLISP would be much more complex.


QuotePreprocessing


Use a custom 'define' along the lines Cormullion has shown on unbalanced-parentheses injecting debugging code.


QuoteCreating a "sandboxed" environment to execute in


You can either create custom 'define's, or write you own eval-print or evaluator taking either a quoted string or expression. For example you could write a custom 'my-eval', which takes a quoted expression and evaluates, similar as shown by McCarthy (and translated into CL by P. Graham). When not trying to write an 'eval' only based on 7 primitives, this could probably done in less than a page of code. Just a big cond-switch branching on atom? lambda? primitive? etc.


QuoteWriting your own interpreter


You still can do that, see previous point. newLISP is a usable language-lab environment just like Scheme.

Jeff

#6
Did it actually hurt the language to keep the function?  I could write my own cond using if, but you still keep cond in the language.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Jeff

#7
Here's another use:  I start a second newlisp instance as a process.  Using pipes, I send and expression the process.  read-buffer returns a string.  I don't want to eval it (it might just return a list of values).  I just want the string to be imported into the current process.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

cormullion

#8
Quote from: "Lutz"
Quote from: "cormullion"replace my tokenizer which I don't think is good enough


'read-expr' was not changing the tokenizer, source-code would still have to be well-formed as of newLISP, to pass through 'read-expr' even if 'read-expr' is uses in the string returning mode. 'read-expr' did not have any influence on the tokenizing process, offerring this newLISP would be much more complex.


Yes - I think I actually wanted a version of parse that would reliably split source code into its distinct components, rather than a read-expr.

Lutz

#9
QuoteI start a second newlisp instance as a process. Using pipes, I send and expression the process. read-buffer returns a string. I don't want to eval it (it might just return a list of values).


As shown earlier: quote the received buffer then evaluate it, e.g: you have sent to the other process "(list 'a 'b)" for evaluation. The process sends back "(a b)" you quote it and evaluate it to get the unevaluated translated expression:


buff => "(a b)" ; received from other process
(eval-string (append "'" buff)) => (a b)


This is actually the way 'net-eval' works internally. Prepending the quote protects the expression from evaluation but forces a translation from the string into s-expressions.

HPW

#10
For interested TK users on WIN I bind the last TK-IDE with the changes for >9.3.X with freewrap 5.5 based on TCL/TK 8.4.1



http://hpwsoft.de/anmeldung/html1/newLISP/newlisp-tk.zip">http://hpwsoft.de/anmeldung/html1/newLI ... isp-tk.zip">http://hpwsoft.de/anmeldung/html1/newLISP/newlisp-tk.zip



In the zip is the EX file which must be renamed to EXE.

(Since it is a ZIP file itself WINZIP does not offer a ZIP again)
Hans-Peter

Cyril

#11
Quote from: "Lutz"This is actually the way 'net-eval' works internally. Prepending the quote protects the expression from evaluation but forces a translation from the string into s-expressions.


(setq buffer "(decent-expression) (nasty-hack)")
(eval-string (append "'" buffer))
With newLISP you can grow your lists from the right side!

Lutz

#12
Yes, you should only return one expression. If traffic between your nodes/processes is exposed, traffic should be encrypted, but this is a risk for any communications between nodes in a networked environment.

Cyril

#13
Quote from: "Lutz"If traffic between your nodes/processes is exposed, traffic should be encrypted.


Yes, if you have the control over both sides. But there is the very reason why we need read in one form or another: to read some data encoded in the form of lisp s-expressions and analyze them without risk that something evil will be executed. The current practice of storing configuration as a set of '(set ...)' expressions and then loading them by 'load' is acceptable if you are in full control of your environment, but the ability to store and/or transfer data and be sure that it is not code is important.
With newLISP you can grow your lists from the right side!

Lutz

#14
The critical difference between (eval-string (append "'" source)) and (read-expr source callback) seems to be, that 'read-expr' reads only one expression at the time, which than can be analyzed in the callback function in source or translated form. Another difference is the fact, that 'read-expr' also passes all comments before and embedded in the expression source, which make it better usable for specialized front-ends and editors.



So, as requested by Jeff and Cyril the function is back in 9.3.4 :-)