REPL behavior

Started by dukester, July 25, 2007, 06:09:58 PM

Previous topic - Next topic

dukester

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
duke

m i c h a e l

#1
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

HPW

#2
When you do not want to have the return:



(silent(println "Hello World!"))
Hans-Peter

cormullion

#3
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).

Jeff

#4
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".
Jeff

=====

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



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

dukester

#5
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?
duke

cormullion

#6
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!

Jeff

#7
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.
Jeff

=====

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



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

dukester

#8
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!
duke

dukester

#9
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!
duke

Ryon

#10
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.
\"Give me a Kaypro 64 and a dial tone, and I can do anything!\"