Hi, is it possible to create a user-defined function much like what inc does: in-place parameter substitution, or is this only available for built-in functions?
Where do newLISPers hangout? Is there a #newlisp IRC channel somewhere?
In-place parameter substitution
Re: In-place parameter substitution
There is a chapter about this on this page:
http://www.newlisp.org/index.cgi?Closures
look for "Stateful functions using in-place modification: at the end.
http://www.newlisp.org/index.cgi?Closures
look for "Stateful functions using in-place modification: at the end.
Re: In-place parameter substitution
Let me clarify my question:
Is it possible to create my version of inc, my-inc?
My gut instinct tells me in order to have a self-modifying code like the above, my-inc must have a reference to the enclosing lambda list. How do I go about creating my-inc ? Is this possible?
Is it possible to create my version of inc, my-inc?
Code: Select all
(define (sum (x 0)) (my-inc 0 x))
(sum 1) ;=> 1
(sum 2) ;=> 3
sum ;=> (lambda ((x 0)) (my-inc 3 x))
-
- Posts: 388
- Joined: Thu May 08, 2008 1:24 am
- Location: Croatia
- Contact:
Re: In-place parameter substitution
How about this one for beginning:
(define-macro (myinc p0)(set p0 (+ (eval p0) 1)))
(define-macro (myinc p0)(set p0 (+ (eval p0) 1)))
Re: In-place parameter substitution
The above fails with the following error when called through my sum function above:Kazimir Majorinc wrote:How about this one for beginning:
(define-macro (my-inc p0)(set p0 (+ (eval p0) 1)))
ERR: symbol expected in function set : p0
What I'm interested is having a function/macro/fexpr that can modify its arguments in-place, exactly like what inc does: i.e., it works even with literal numbers. Is this possible or do built-ins like inc and dec can only be implemented by the underlaying newLISP C implementation?
Re: In-place parameter substitution
Any destructive primitive could be used to do this, when there is a way to reference the currently executing lambda expression:
A user-defined function has no way to reference the function it was invoked from, except when it has previous knowledge of it:
Code: Select all
> (define (selfmod x) (setf (last selfmod) (+ (last selfmod) 1)) 0)
(lambda (x) (setf (last selfmod) (+ (last selfmod) 1)) 0)
> (selfmod)
1
> (selfmod)
2
> (selfmod)
3
> selfmod
(lambda (x) (setf (last selfmod) (+ (last selfmod) 1)) 3)
Code: Select all
> (define (selfinc x) (myinc x) 0)
(lambda (x) (myinc x) 0)
> (define (myinc x) (inc (last selfinc) x))
(lambda (x) (inc (last selfinc) x))
> (selfinc 1)
1
> (selfinc 2)
3
> (selfinc 3)
6
> selfinc
(lambda (x) (myinc x) 6)
>
-
- Posts: 388
- Joined: Thu May 08, 2008 1:24 am
- Location: Croatia
- Contact:
Re: In-place parameter substitution
It would be nice to have some function that returns list of the caller functions, similarly like (sys-info 3) returns the level of recursion. Although it sounds quite 'dangerous' it can actually provide some debugging facilities, i.e. functions could react if called by someone they do not appreciate.
Re: In-place parameter substitution
The Io language has this. I think it's built it at rather a low level, though.Kazimir Majorinc wrote:It would be nice to have some function that returns list of the caller functions, similarly like (sys-info 3) returns the level of recursion. Although it sounds quite 'dangerous' it can actually provide some debugging facilities, i.e. functions could react if called by someone they do not appreciate.
Re: In-place parameter substitution
Code: Select all
(define (callers)
(catch (0) 'error)
(slice (map sym (find-all "function (\\w+)" error $1 0)) 3)
)
(define (foo) (bar))
(define (bar) (baz))
(define (baz) (callers))
(foo) => (baz bar foo)
I had this function coded natively a while back for experimentation, but couldn't really find any good use for it. Similar to 'estack', which was even shipped - undocumented - for a for a few versions and returned the variable environment stack. These functions seem interesting too me too, but I cannot see useful applications, it is just overhead nobody ever uses. When you really have a situation, where a function needs to know the caller, just make it a parameter of the function call.
Above code is not the only way to implement this. A while back Cormullion showed how you could redefine 'define' to include debugging code. In the current case, it would mean pushing the function symbol on a 'callers' stack as first statement of each function.