In-place parameter substitution

Pondering the philosophy behind the language

In-place parameter substitution

Postby genghis » Thu Apr 12, 2012 4:10 pm

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?
genghis
 
Posts: 4
Joined: Thu Apr 12, 2012 3:55 pm

Re: In-place parameter substitution

Postby Lutz » Thu Apr 12, 2012 4:45 pm

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.
Lutz
 
Posts: 5279
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California

Re: In-place parameter substitution

Postby genghis » Thu Apr 12, 2012 5:08 pm

Let me clarify my question:

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))

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?
genghis
 
Posts: 4
Joined: Thu Apr 12, 2012 3:55 pm

Re: In-place parameter substitution

Postby Kazimir Majorinc » Sat Apr 14, 2012 12:43 am

How about this one for beginning:

(define-macro (myinc p0)(set p0 (+ (eval p0) 1)))
Kazimir Majorinc
 
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia

Re: In-place parameter substitution

Postby genghis » Sat Apr 14, 2012 6:49 am

Kazimir Majorinc wrote:How about this one for beginning:

(define-macro (my-inc p0)(set p0 (+ (eval p0) 1)))

The above fails with the following error when called through my sum function above:
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?
genghis
 
Posts: 4
Joined: Thu Apr 12, 2012 3:55 pm

Re: In-place parameter substitution

Postby Lutz » Sat Apr 14, 2012 2:29 pm

Any destructive primitive could be used to do this, when there is a way to reference the currently executing lambda expression:

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)


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 (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)
>
Lutz
 
Posts: 5279
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California

Re: In-place parameter substitution

Postby Kazimir Majorinc » Sat Apr 14, 2012 3:19 pm

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.
Kazimir Majorinc
 
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia

Re: In-place parameter substitution

Postby tumble » Sun Apr 15, 2012 8:21 am

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.


The Io language has this. I think it's built it at rather a low level, though.
tumble
 
Posts: 8
Joined: Wed Dec 28, 2011 4:17 pm

Re: In-place parameter substitution

Postby Lutz » Sun Apr 15, 2012 2:43 pm

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)


Instead of 3 in the last statement of 'callers' put 4 to exclude the current function.

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.
Lutz
 
Posts: 5279
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California


Return to Whither newLISP?

Who is online

Users browsing this forum: No registered users and 0 guests

cron