newLISP Fan Club

Forum => Anything else we might add? => Topic started by: dukester on July 25, 2007, 06:09:58 PM

Title: REPL behavior
Post by: dukester on July 25, 2007, 06:09:58 PM
i'm new to newlisp! Currently reading "newlisp in 21 minutes" as an intro.



(println "Hello World!")



prints twice at the newlisp console because:



REPL prints it  once

println prints it a second time



Is this a correct interpretation of whats going on? TIA...

--

dukester
Title:
Post by: m i c h a e l on July 25, 2007, 07:15:41 PM
Hi dukester!


QuoteREPL prints it once

println prints it a second time


Yes, but you have them in the wrong order: first, println prints the result, then REPL displays the return value of the last expression (in this case, the string "Hello World!").



Welcome to the wonderful world of newLISP!



m i c h a e l
Title:
Post by: HPW on July 25, 2007, 10:13:18 PM
When you do not want to have the return:



(silent(println "Hello World!"))
Title:
Post by: cormullion on July 26, 2007, 01:40:20 AM
You could think of the display of characters as merely a side-effect to the real business of the evaluation and returning of a value to the surrounding code.



I found this confusing for a while, probably because I usually run code from an editor rather than the interpreter:


(for (i 1 4)
(print i))


gives this when I run in an editor:



1234



but this when run in the newLISP interpreter



12344



That final 4 is - I think - the value returned by the entire 'for' function call, which it got from the final 'print' function call which returned 4 (and also printed it).
Title:
Post by: Jeff on July 26, 2007, 05:01:58 AM
That's exactly right.  Anything printed will have the additional side effect of printing the value of the expression entered.  READ-EVAL-PRINT-LOOP means that the expression is read, evaluated, the value is printed, and then then started over.  Printing a statement returns the text printed, so (println "Hello world") both prints "Hello world" and then evaluates to "Hello world", so the repl will print out the value in the course of evaluating the expression, and then display the result of that expression.  If you were to type (upper-case (println "hello world")), it would first print "hello world", then print the value of the entire expression, "HELLO WORLD".
Title:
Post by: dukester on July 26, 2007, 06:57:29 PM
Quote from: "Jeff"That's exactly right.  Anything printed will have the additional side effect of printing the value of the expression entered.  READ-EVAL-PRINT-LOOP means that the expression is read, evaluated, the value is printed, and then then started over.  Printing a statement returns the text printed, so (println "Hello world") both prints "Hello world" and then evaluates to "Hello world", so the repl will print out the value in the course of evaluating the expression, and then display the result of that expression.  If you were to type (upper-case (println "hello world")), it would first print "hello world", then print the value of the entire expression, "HELLO WORLD".


Let's see if I'm getting this:



(upper-case (println "hello world"))



is a list of 2 functions and some data... correct?



1st-- println  function does its thing and displays the data

2nd-- upper-case function does _its_ thing on the data

3rd-- REPL displays the last item in the list



Am I close?
Title:
Post by: cormullion on July 27, 2007, 01:20:44 AM
Quote from: "dukester"Let's see if I'm getting this:



(upper-case (println "hello world"))



is a list of 2 functions and some data... correct?



1st-- println  function does its thing and displays the data

2nd-- upper-case function does _its_ thing on the data

3rd-- REPL displays the last item in the list



Am I close?

Yes! :-)



To put it another way, (upper-case (println "hello world")) is a list in which the argument to the 'upper-case' function is another list which contains a function call and an argument (or data as you call it).



1 - A println function call in a list returns a value. As a useful and pleasant side effect , it displays some string data somewhere and adds a newline to it too as it does so.



2 - upper-case now has a chance to do its 'thing' with the string that it's handed by the inner list. It doesn't 'know' where the string has come from, or what it originally looked like before it was procesed, and knows nothing of standard output or displays either. It sees a string - that's good enough, and all it needs to know.



3 - The result of the evaluation of the 'upper-case' function is displayed by the newLISP interpreter. This isn't the original data, but the value of the 'upper-case' function call, which in turn depended on the value of the 'println' function call.



So - can you predict how the following is evaluated?


(upper-case (reverse (lower-case "ABC")))

Look at the innermost list first.



hope this helps!
Title:
Post by: Jeff on July 27, 2007, 05:20:39 AM
When visually parsing a lisp list, evaluate from the inside out.  After learning to do this, lisp's syntax will become so much easier to visualize than imperative programming, because with lisp you are, basically, writing the actual internal structure of the program, rather than a more declarative syntax that would get parsed and turned into something resembling the lisp structure.



When writing a lisp program, write from the bottom-up.  It's all about abstraction.  First, you write the most primitive elements your program will need.  Then, you write other functions that will use those functions in order to abstract the more low-level stuff.  In the end, you write a much smaller set of functions/macros that will be the api to the program.  These have convenient syntax and build on the lower level elements of the program.
Title:
Post by: dukester on July 27, 2007, 06:53:07 AM
Quote from: "cormullion"
Quote from: "dukester"Let's see if I'm getting this:



(upper-case (println "hello world"))



is a list of 2 functions and some data... correct?



1st-- println  function does its thing and displays the data

2nd-- upper-case function does _its_ thing on the data

3rd-- REPL displays the last item in the list



Am I close?

Yes! :-)



To put it another way, (upper-case (println "hello world")) is a list in which the argument to the 'upper-case' function is another list which contains a function call and an argument (or data as you call it).



1 - A println function call in a list returns a value. As a useful and pleasant side effect , it displays some string data somewhere and adds a newline to it too as it does so.



2 - upper-case now has a chance to do its 'thing' with the string that it's handed by the inner list. It doesn't 'know' where the string has come from, or what it originally looked like before it was procesed, and knows nothing of standard output or displays either. It sees a string - that's good enough, and all it needs to know.



3 - The result of the evaluation of the 'upper-case' function is displayed by the newLISP interpreter. This isn't the original data, but the value of the 'upper-case' function call, which in turn depended on the value of the 'println' function call.



So - can you predict how the following is evaluated?


(upper-case (reverse (lower-case "ABC")))

Look at the innermost list first.



hope this helps!


You bet it helps!



I'm familiar with nested function calls from Perl, PHP and Euphoria. The above code is an excellent newlisp example IMHO.



I was getting hung up on the REPL behavior of diaplaying the last element of a list when I was using "println" from the newlisp console. Thanks again!
Title:
Post by: dukester on July 27, 2007, 06:56:13 AM
Quote from: "Jeff"When visually parsing a lisp list, evaluate from the inside out.  After learning to do this, lisp's syntax will become so much easier to visualize than imperative programming, because with lisp you are, basically, writing the actual internal structure of the program, rather than a more declarative syntax that would get parsed and turned into something resembling the lisp structure.



When writing a lisp program, write from the bottom-up.  It's all about abstraction.  First, you write the most primitive elements your program will need.  Then, you write other functions that will use those functions in order to abstract the more low-level stuff.  In the end, you write a much smaller set of functions/macros that will be the api to the program.  These have convenient syntax and build on the lower level elements of the program.


Sounds a bit like Forth methodology: design top-down; develop bottom-up. I never gave Forth a fair chance though. However, I'm finding newlisp more intuitive and way simpler to learn. Thanks!
Title:
Post by: Ryon on July 27, 2007, 09:46:53 AM
Too bad about Forth not attracting more interest. I've never understood why. It is so much cleaner and easier to visualize then infix and prefix.