Page 1 of 1

(define ...) inside a default value

PostPosted: Fri Jul 25, 2014 4:31 am
by Zabolekar
I have no reason to use something like that in real code, so this is just pure curiosity. Nevertheless, I would like to understand why this piece of code does what it does.

In newLisp, the following code

Code: Select all
(define (f a (b (define (f a) "D"))) a)
(println (f "A" 1) (f "B") (f "C"))


will print AnilD. I don't quite understand where nil comes from. I would expect either ABD or, less intuitive but still understandable, ABC. It gets even more confusing. When I do

Code: Select all
(define (f a (b (define (f a) "D"))) (println "") a)
(f "A")


the interpreter tells me:

Code: Select all
--- cannot execute: restart shell ---


And, indeed, in this case I have to restart the shell to make it work again.

In Common Lisp, Clojure and Ruby the following pieces of code seem to be equivalent:

Code: Select all
(defun f (a &optional (b (defun f (a) "D"))) a)
(format t "~a~a~a" (f "A" 1) (f "B") (f "C"))


Code: Select all
(defn f ([a] (defn f [a] "D") a) ([a b] a))
(println (str (f "A" 1) (f "B") (f "C")))


Code: Select all
def f(a, b = def f(a); "D"; end); a; end
p f("A", 1) + f("B") + f("C")


All of them print ABD.

Re: (define ...) inside a default value

PostPosted: Fri Jul 25, 2014 1:21 pm
by Lutz
It does literally what you tell it to do. newLISP is a fully self reflective language which can introspect or modify itself at run-time. In your example the function f is redefining itself while executing. The old discarded definition is collected by memory management and execution runs into invalid memory causing unexpected results or crashing.

When functions modify themselves, care must be taken to not replace code parts executing at the same moment.

See about self-modifying code in newLISP on this page: http://www.newlisp.org/index.cgi?Closures the paragraphs Introspection and Stateful functions using in-place modification.

Re: (define ...) inside a default value

PostPosted: Fri Jul 25, 2014 2:03 pm
by Zabolekar
Thanks for the answer! So the old function definition is collected right after we redefine the function? That makes sense for me. Then, as far as I understand, modifying the function without actually redefining it should be safe (is it?):

Code: Select all
(define (f a (b (setf (nth 1 f) "D"))) a)
(println (f "A" 1) (f "B") (f "C"))


It prints ADD, as expected.

Is there a way to self-modify a function so that the changes only take place after the function returns?

Re: (define ...) inside a default value

PostPosted: Sat Jul 26, 2014 1:44 pm
by Lutz
Some functions in newLISP delay memory cleanup, but not applicable in this case.

Re: (define ...) inside a default value

PostPosted: Sat Jul 26, 2014 5:54 pm
by Zabolekar
Thanks.