Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

BOFH excuse #395: Redundant ACLs.


comp / comp.lang.lisp / Re: .Re: A simple lisp problem.

SubjectAuthor
* .Re: A simple lisp problem.B. Pym
+- Tail call recursion macro with named-let in Emacs Lisp (was: A simple lisp problAxel Reichert
`* Re: .Re: A simple lisp problem.HenHanna
 `- diff1p? -------- A simple lisp problemHenHanna

1
Subject: .Re: A simple lisp problem.
From: B. Pym
Newsgroups: comp.lang.lisp
Organization: A noiseless patient Spider
Date: Sat, 15 Jun 2024 03:45 UTC
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: No_spamming@noWhere_7073.org (B. Pym)
Newsgroups: comp.lang.lisp
Subject: .Re: A simple lisp problem.
Date: Sat, 15 Jun 2024 03:45:39 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 40
Message-ID: <v4j2p1$3a0lu$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Injection-Date: Sat, 15 Jun 2024 05:45:40 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="14b864f2885e341cc55dd1b97ca84b7c";
logging-data="3474110"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/+3L1YqXC7m8OXi/827dAw"
User-Agent: XanaNews/1.18.1.6
Cancel-Lock: sha1:9duSjKewJxXHEMr78GMzma4MR6w=
View all headers

Frank Schwieterman wrote:

> >I am Lisp beginner and I am doing a simple execise on lisp. I was asked
> >to write a lisp program , by using either recursion or do, to return
> >true if the difference between each successive pair of the them is 1.
> >
> >ie:
> >
> >>(difference '(2 1))
> >T
> >>(difference'(3 4 5 6 5 4))
> >T
> >>(differnce '(3 4 5 3))
> >NIL
....
>
> (defun difference (param)
> (if (> (length param) 1)
> (if (<= (abs (- (first param) (first (rest param)))) 1 )
> (difference (rest param))
> nil
> )
> T
> )
> )

Gauche Scheme

(define (diff1? xs)
(every
(lambda (a b) (= 1 (abs (- a b))))
xs
(cdr xs)))

(diff1? '(2 3 4 3 4 5 6 7 8 9 8))
===>
#t
(diff1? '(2 3 4 3 4 5 6 7 8 9 8 0))
===>
#f

Subject: Tail call recursion macro with named-let in Emacs Lisp (was: A simple lisp problem.)
From: Axel Reichert
Newsgroups: comp.lang.lisp
Organization: A noiseless patient Spider
Date: Sat, 15 Jun 2024 10:17 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: mail@axel-reichert.de (Axel Reichert)
Newsgroups: comp.lang.lisp
Subject: Tail call recursion macro with named-let in Emacs Lisp (was: A simple lisp problem.)
Date: Sat, 15 Jun 2024 12:17:42 +0200
Organization: A noiseless patient Spider
Lines: 107
Message-ID: <87o782h5mh.fsf@axel-reichert.de>
References: <v4j2p1$3a0lu$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Date: Sat, 15 Jun 2024 12:17:45 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="ecc537ebfc5213417124a7d49f80461d";
logging-data="3599724"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+7OHUeTZeUZhFwtl3sheiI2hxOgdBb2rM="
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux)
Cancel-Lock: sha1:EUzXnOCANkfSpnPRn7tT+1oIZQ0=
sha1:3HsDE+X2aP56zMsPdpTBfA5uypM=
View all headers

"B. Pym" <No_spamming@noWhere_7073.org> writes:

> Frank Schwieterman wrote:
>
>> (defun difference (param)
>> (if (> (length param) 1)
>> (if (<= (abs (- (first param) (first (rest param)))) 1 )
>> (difference (rest param))
>> nil
>> )
>> T
>> )
>> )
>
> Gauche Scheme
>
> (define (diff1? xs)
> (every
> (lambda (a b) (= 1 (abs (- a b))))
> xs
> (cdr xs)))
>
> (diff1? '(2 3 4 3 4 5 6 7 8 9 8))
> ===>
> #t
> (diff1? '(2 3 4 3 4 5 6 7 8 9 8 0))
> ===>
> #f

A nice, recursive solution in Emacs Lisp would be

(defun single-step-p (xs)
(cond ((null (cdr xs)) t)
((= 1 (abs (- (car xs) (cadr xs)))) (single-step-p (cdr xs)))
(t nil)))

but it fails for longer lists such as

(single-step-p (number-sequence 1 1000))

because Emacs Lisp does not have proper tail call elimination. There is
an exception, though, "named-let", see here:

https://www.gnu.org/software/emacs/manual/html_node/elisp/Local-Variables.html

So I rewrote the function to

(defun single-step-p (xs)
(named-let single-step-p ((xs xs))
(cond ((null (cdr xs)) t)
((= 1 (abs (- (car xs) (cadr xs)))) (single-step-p (cdr xs)))
(t nil))))

which work fine also for

(single-step-p (number-sequence 1 1000000))

but of course looks a bit redundant compared to the "normal" use of
"named-let" for helper functions such as accumulating results etc.

So I wrote a small macro doing the wrapping in a "named-let" for me:

(defmacro defun-tco-1 (name args body)
`(defun ,name ,args
(named-let ,name (,args ,args)
,body)))

Now

(defun-tco-1 single-step-p (xs)
(cond ((null (cdr xs)) t)
((= 1 (abs (- (car xs) (cadr xs)))) (single-step-p (cdr xs)))
(t nil)))

works, but the macro of course fails for a different number of
arguments, as can be seen with

(macroexpand-1 '(defun-tco-1 foo (a b) (+ a b)))

which gives

(defun foo (a b) (named-let foo ((a b) (a b)) (+ a b)))

and of course also wrong results (14 instead of 10) for

(foo 3 7)

So I needed to loop through the args of the macro and construct the
proper bindings for the "named-let":

(defmacro defun-tco (name args body)
(let ((bindings (mapcar #'(lambda (arg) (list arg arg)) args)))
`(defun ,name ,args
(named-let ,name ,bindings
,body))))

Is this fine from the point of the experts here (in fact, it is my first
macro that is unrelated to any macro tutorials/book, but rather came
from my own needs)? I am quite sure that I could suffer from variable
capture and perhaps also from multiple evaluation, but this would be the
second step for me after a first, general criticism here.

Many thank for any comments!

Best regards

Axel

Subject: Re: .Re: A simple lisp problem.
From: HenHanna
Newsgroups: comp.lang.lisp
Organization: A noiseless patient Spider
Date: Sat, 15 Jun 2024 20:08 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: HenHanna@devnull.tb (HenHanna)
Newsgroups: comp.lang.lisp
Subject: Re: .Re: A simple lisp problem.
Date: Sat, 15 Jun 2024 13:08:40 -0700
Organization: A noiseless patient Spider
Lines: 73
Message-ID: <v4ksc9$3k354$1@dont-email.me>
References: <v4j2p1$3a0lu$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 15 Jun 2024 22:08:42 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="5a9d7d343de3468ada1fe8423f653db7";
logging-data="3804324"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18IcyMs7JkF8D6srKZ4uRWAz9LXBbO872w="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:qZgV4tCU4O7/mvIc9jfFel98Gbo=
In-Reply-To: <v4j2p1$3a0lu$1@dont-email.me>
Content-Language: en-US
View all headers

On 6/14/2024 8:45 PM, B. Pym wrote:
> Frank Schwieterman wrote:
>
>>> I am Lisp beginner and I am doing a simple execise on lisp. I was asked
>>> to write a lisp program , by using either recursion or do, to return
>>> true if the difference between each successive pair of the them is 1.
>>>
>>> ie:
>>>
>>>> (difference '(2 1))
>>> T
>>>> (difference'(3 4 5 6 5 4))
>>> T
>>>> (differnce '(3 4 5 3))
>>> NIL
> ....
>>
>> (defun difference (param)
>> (if (> (length param) 1)
>> (if (<= (abs (- (first param) (first (rest param)))) 1 )
>> (difference (rest param))
>> nil
>> )
>> T
>> )
>> )

(define (diff1p? x)
(or (null? x)
(null? (cdr x))
(and (= 1 (abs (- (car x) (cadr x)) ))
(diff1p? (cdr x)) )))

>
> Gauche Scheme
>
> (define (diff1? xs)
> (every
> (lambda (a b) (= 1 (abs (- a b))))
> xs
> (cdr xs)))
>
> (diff1? '(2 3 4 3 4 5 6 7 8 9 8)) ===> #t

> (diff1? '(2 3 4 3 4 5 6 7 8 9 8 0)) ===> #f

__________________________
find
find-tail
any
every
count

every pred clist1 clist2 . . . [Function]

[R7RS list] Applies pred across each element of clists, and returns
#f as soon as pred returns #f. If all application of pred
return a non-false value, [every] returns the last result of the
applications.

it sounds like it expands to a big (OR ........ )

______________________________ Not

(define (every? predicate lst) (and (map predicate lst)))

Subject: diff1p? -------- A simple lisp problem
From: HenHanna
Newsgroups: comp.lang.lisp
Organization: A noiseless patient Spider
Date: Sun, 16 Jun 2024 00:20 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: HenHanna@devnull.tb (HenHanna)
Newsgroups: comp.lang.lisp
Subject: diff1p? -------- A simple lisp problem
Date: Sat, 15 Jun 2024 17:20:31 -0700
Organization: A noiseless patient Spider
Lines: 63
Message-ID: <v4lb4g$3mt2j$2@dont-email.me>
References: <v4j2p1$3a0lu$1@dont-email.me> <v4ksc9$3k354$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 16 Jun 2024 02:20:32 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="35c3840a03f107b42fbf945be62926e9";
logging-data="3896403"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18ziv7sEoHtAM+pHDwQuYzzsDH0c4FVTEk="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:xyTzXgMHdkZX5wKpnMLq+j4FZV4=
Content-Language: en-US
In-Reply-To: <v4ksc9$3k354$1@dont-email.me>
View all headers

On 6/15/2024 1:08 PM, HenHanna wrote:
> On 6/14/2024 8:45 PM, B. Pym wrote:
>> Frank Schwieterman wrote:
>>
>>>> I am Lisp beginner and I am doing a simple execise on lisp. I was asked
>>>> to write a lisp program , by using either recursion or do, to return
>>>> true if the difference between each successive pair of the them is 1. (or LESS)
>>>>
>>>> ie:
>>>>
>>>>> (difference '(2 1))
>>>> T
>>>>> (difference'(3 4 5 6 5 4))
>>>> T
>>>>> (differnce '(3 4 5 3))
>>>> NIL
>>   ....
>>>
>>> (defun difference (param)
>>>       (if (> (length param) 1)
>>>          (if (<= (abs (- (first param) (first (rest param)))) 1 )
>>>             (difference (rest param))
>>>             nil
>>>             )
>>>          T
>>>          )
>>>       )

looks good. except for CADR (second) and ) ) )

>
>
> (define (diff1p?  x)
>   (or (null? x)
>       (null? (cdr x))
>       (and (= 1 (abs (- (car x) (cadr x)) ))
>            (diff1p? (cdr x)) )))
>
>
>>
>> Gauche Scheme
>>
>> (define (diff1? xs)
>>    (every
>>      (lambda (a b) (= 1 (abs (- a b))))
>>      xs
>>      (cdr xs)))
>>
>> (diff1? '(2 3 4 3 4 5 6 7 8 9 8))     ===>  #t
>
>> (diff1? '(2 3 4 3 4 5 6 7 8 9 8 0))   ===>  #f

in Scheme (Gauche), is there a way to write it more like this ?

def diff1(x):
return all( abs(x[i] - x[i+1]) == 1 for i in range(len(x)-1) )

1

rocksolid light 0.9.8
clearnet tor